@@ -786,6 +786,18 @@ struct input_keymap_entry {
#define KEY_KBDINPUTASSIST_ACCEPT 0x264
#define KEY_KBDINPUTASSIST_CANCEL 0x265
+#define KEY_RIGHT_UP 0x266
+#define KEY_RIGHT_DOWN 0x267
+#define KEY_LEFT_UP 0x268
+#define KEY_LEFT_DOWN 0x269
+
+#define KEY_NEXT_FAVORITE 0x270
+#define KEY_STOP_RECORD 0x271
+#define KEY_PAUSE_RECORD 0x272
+#define KEY_VOD 0x273
+#define KEY_UNMUTE 0x274
+#define KEY_DVB 0x275
+
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
@@ -1006,6 +1018,7 @@ struct input_keymap_entry {
#define BUS_GSC 0x1A
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C
+#define BUS_CEC 0x1D
/*
* MT_TOOL types
new file mode 100644
@@ -0,0 +1,1516 @@
+#ifndef _CEC_FUNCS_H
+#define _CEC_FUNCS_H
+
+#include <linux/cec.h>
+
+/* One Touch Play Feature */
+static __inline__ void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_ACTIVE_SOURCE;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static __inline__ void cec_ops_active_source(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static __inline__ void cec_msg_image_view_on(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON;
+}
+
+static __inline__ void cec_msg_text_view_on(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TEXT_VIEW_ON;
+}
+
+
+/* Routing Control Feature */
+static __inline__ void cec_msg_inactive_source(struct cec_msg *msg,
+ __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_INACTIVE_SOURCE;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static __inline__ void cec_ops_inactive_source(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static __inline__ void cec_msg_request_active_source(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE;
+ msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0;
+}
+
+static __inline__ void cec_msg_routing_information(struct cec_msg *msg,
+ __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_ROUTING_INFORMATION;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static __inline__ void cec_ops_routing_information(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static __inline__ void cec_msg_routing_change(struct cec_msg *msg,
+ bool reply,
+ __u16 orig_phys_addr,
+ __u16 new_phys_addr)
+{
+ msg->len = 6;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_ROUTING_CHANGE;
+ msg->msg[2] = orig_phys_addr >> 8;
+ msg->msg[3] = orig_phys_addr & 0xff;
+ msg->msg[4] = new_phys_addr >> 8;
+ msg->msg[5] = new_phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0;
+}
+
+static __inline__ void cec_ops_routing_change(const struct cec_msg *msg,
+ __u16 *orig_phys_addr,
+ __u16 *new_phys_addr)
+{
+ *orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *new_phys_addr = (msg->msg[4] << 8) | msg->msg[5];
+}
+
+static __inline__ void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_SET_STREAM_PATH;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static __inline__ void cec_ops_set_stream_path(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+
+/* Standby Feature */
+static __inline__ void cec_msg_standby(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_STANDBY;
+}
+
+
+/* One Touch Record Feature */
+static __inline__ void cec_msg_record_off(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_RECORD_OFF;
+}
+
+struct cec_op_arib_data {
+ __u16 transport_id;
+ __u16 service_id;
+ __u16 orig_network_id;
+};
+
+struct cec_op_atsc_data {
+ __u16 transport_id;
+ __u16 program_number;
+};
+
+struct cec_op_dvb_data {
+ __u16 transport_id;
+ __u16 service_id;
+ __u16 orig_network_id;
+};
+
+struct cec_op_channel_data {
+ __u8 channel_number_fmt;
+ __u16 major;
+ __u16 minor;
+};
+
+struct cec_op_digital_service_id {
+ __u8 service_id_method;
+ __u8 dig_bcast_system;
+ union {
+ struct cec_op_arib_data arib;
+ struct cec_op_atsc_data atsc;
+ struct cec_op_dvb_data dvb;
+ struct cec_op_channel_data channel;
+ };
+};
+
+struct cec_op_record_src {
+ __u8 type;
+ union {
+ struct cec_op_digital_service_id digital;
+ struct {
+ __u8 ana_bcast_type;
+ __u16 ana_freq;
+ __u8 bcast_system;
+ } analog;
+ struct {
+ __u8 plug;
+ } ext_plug;
+ struct {
+ __u16 phys_addr;
+ } ext_phys_addr;
+ };
+};
+
+static __inline__ void cec_set_digital_service_id(__u8 *msg,
+ const struct cec_op_digital_service_id *digital)
+{
+ *msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system;
+ if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
+ *msg++ = (digital->channel.channel_number_fmt << 2) |
+ (digital->channel.major >> 8);
+ *msg++ = digital->channel.major && 0xff;
+ *msg++ = digital->channel.minor >> 8;
+ *msg++ = digital->channel.minor & 0xff;
+ *msg++ = 0;
+ *msg++ = 0;
+ return;
+ }
+ switch (digital->dig_bcast_system) {
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:
+ *msg++ = digital->atsc.transport_id >> 8;
+ *msg++ = digital->atsc.transport_id & 0xff;
+ *msg++ = digital->atsc.program_number >> 8;
+ *msg++ = digital->atsc.program_number & 0xff;
+ *msg++ = 0;
+ *msg++ = 0;
+ break;
+ default:
+ *msg++ = digital->dvb.transport_id >> 8;
+ *msg++ = digital->dvb.transport_id & 0xff;
+ *msg++ = digital->dvb.service_id >> 8;
+ *msg++ = digital->dvb.service_id & 0xff;
+ *msg++ = digital->dvb.orig_network_id >> 8;
+ *msg++ = digital->dvb.orig_network_id & 0xff;
+ break;
+ }
+}
+
+static __inline__ void cec_get_digital_service_id(const __u8 *msg,
+ struct cec_op_digital_service_id *digital)
+{
+ digital->service_id_method = msg[0] >> 7;
+ digital->dig_bcast_system = msg[0] & 0x7f;
+ if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
+ digital->channel.channel_number_fmt = msg[1] >> 2;
+ digital->channel.major = ((msg[1] & 3) << 6) | msg[2];
+ digital->channel.minor = (msg[3] << 8) | msg[4];
+ return;
+ }
+ digital->dvb.transport_id = (msg[1] << 8) | msg[2];
+ digital->dvb.service_id = (msg[3] << 8) | msg[4];
+ digital->dvb.orig_network_id = (msg[5] << 8) | msg[6];
+}
+
+static __inline__ void cec_msg_record_on_own(struct cec_msg *msg)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_OWN;
+}
+
+static __inline__ void cec_msg_record_on_digital(struct cec_msg *msg,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 10;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL;
+ cec_set_digital_service_id(msg->msg + 3, digital);
+}
+
+static __inline__ void cec_msg_record_on_analog(struct cec_msg *msg,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 7;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG;
+ msg->msg[3] = ana_bcast_type;
+ msg->msg[4] = ana_freq >> 8;
+ msg->msg[5] = ana_freq & 0xff;
+ msg->msg[6] = bcast_system;
+}
+
+static __inline__ void cec_msg_record_on_plug(struct cec_msg *msg,
+ __u8 plug)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG;
+ msg->msg[3] = plug;
+}
+
+static __inline__ void cec_msg_record_on_phys_addr(struct cec_msg *msg,
+ __u16 phys_addr)
+{
+ msg->len = 5;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR;
+ msg->msg[3] = phys_addr >> 8;
+ msg->msg[4] = phys_addr & 0xff;
+}
+
+static __inline__ void cec_msg_record_on(struct cec_msg *msg,
+ const struct cec_op_record_src *rec_src)
+{
+ switch (rec_src->type) {
+ case CEC_OP_RECORD_SRC_OWN:
+ cec_msg_record_on_own(msg);
+ break;
+ case CEC_OP_RECORD_SRC_DIGITAL:
+ cec_msg_record_on_digital(msg, &rec_src->digital);
+ break;
+ case CEC_OP_RECORD_SRC_ANALOG:
+ cec_msg_record_on_analog(msg,
+ rec_src->analog.ana_bcast_type,
+ rec_src->analog.ana_freq,
+ rec_src->analog.bcast_system);
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PLUG:
+ cec_msg_record_on_plug(msg, rec_src->ext_plug.plug);
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
+ cec_msg_record_on_phys_addr(msg,
+ rec_src->ext_phys_addr.phys_addr);
+ break;
+ }
+}
+
+static __inline__ void cec_ops_record_on(const struct cec_msg *msg,
+ struct cec_op_record_src *rec_src)
+{
+ rec_src->type = msg->msg[2];
+ switch (rec_src->type) {
+ case CEC_OP_RECORD_SRC_OWN:
+ break;
+ case CEC_OP_RECORD_SRC_DIGITAL:
+ cec_get_digital_service_id(msg->msg + 3, &rec_src->digital);
+ break;
+ case CEC_OP_RECORD_SRC_ANALOG:
+ rec_src->analog.ana_bcast_type = msg->msg[3];
+ rec_src->analog.ana_freq =
+ (msg->msg[4] << 8) | msg->msg[5];
+ rec_src->analog.bcast_system = msg->msg[6];
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PLUG:
+ rec_src->ext_plug.plug = msg->msg[3];
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
+ rec_src->ext_phys_addr.phys_addr =
+ (msg->msg[3] << 8) | msg->msg[4];
+ break;
+ }
+}
+
+static __inline__ void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_RECORD_STATUS;
+ msg->msg[2] = rec_status;
+}
+
+static __inline__ void cec_ops_record_status(const struct cec_msg *msg,
+ __u8 *rec_status)
+{
+ *rec_status = msg->msg[2];
+}
+
+static __inline__ void cec_msg_record_tv_screen(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN;
+ msg->reply = reply ? CEC_MSG_RECORD_ON : 0;
+}
+
+
+/* Timer Programming Feature */
+static __inline__ void cec_msg_timer_status(struct cec_msg *msg,
+ __u8 timer_overlap_warning,
+ __u8 media_info,
+ __u8 prog_info,
+ __u8 prog_error,
+ __u8 duration_hr,
+ __u8 duration_min)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_TIMER_STATUS;
+ msg->msg[2] = (timer_overlap_warning << 7) |
+ (media_info << 5) |
+ (prog_info ? 0x10 : 0) |
+ (prog_info ? prog_info : prog_error);
+ if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||
+ prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||
+ prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {
+ msg->len += 2;
+ msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10);
+ }
+}
+
+static __inline__ void cec_ops_timer_status(struct cec_msg *msg,
+ __u8 *timer_overlap_warning,
+ __u8 *media_info,
+ __u8 *prog_info,
+ __u8 *prog_error,
+ __u8 *duration_hr,
+ __u8 *duration_min)
+{
+ *timer_overlap_warning = msg->msg[2] >> 7;
+ *media_info = (msg->msg[2] >> 5) & 3;
+ if (msg->msg[2] & 0x10) {
+ *prog_info = msg->msg[2] & 0xf;
+ *prog_error = 0;
+ } else {
+ *prog_info = 0;
+ *prog_error = msg->msg[2] & 0xf;
+ }
+ if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||
+ *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||
+ *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {
+ *duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf);
+ *duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ } else {
+ *duration_hr = *duration_min = 0;
+ }
+}
+
+static __inline__ void cec_msg_timer_cleared_status(struct cec_msg *msg,
+ __u8 timer_cleared_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS;
+ msg->msg[2] = timer_cleared_status;
+}
+
+static __inline__ void cec_ops_timer_cleared_status(struct cec_msg *msg,
+ __u8 *timer_cleared_status)
+{
+ *timer_cleared_status = msg->msg[2];
+}
+
+static __inline__ void cec_msg_clear_analogue_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ana_bcast_type;
+ msg->msg[10] = ana_freq >> 8;
+ msg->msg[11] = ana_freq & 0xff;
+ msg->msg[12] = bcast_system;
+ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
+}
+
+static __inline__ void cec_ops_clear_analogue_timer(struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ana_bcast_type,
+ __u16 *ana_freq,
+ __u8 *bcast_system)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ana_bcast_type = msg->msg[9];
+ *ana_freq = (msg->msg[10] << 8) | msg->msg[11];
+ *bcast_system = msg->msg[12];
+}
+
+static __inline__ void cec_msg_clear_digital_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 16;
+ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
+ msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ cec_set_digital_service_id(msg->msg + 9, digital);
+}
+
+static __inline__ void cec_ops_clear_digital_timer(struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ struct cec_op_digital_service_id *digital)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ cec_get_digital_service_id(msg->msg + 9, digital);
+}
+
+static __inline__ void cec_msg_clear_ext_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ext_src_spec,
+ __u8 plug,
+ __u16 phys_addr)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ext_src_spec;
+ msg->msg[10] = plug;
+ msg->msg[11] = phys_addr >> 8;
+ msg->msg[12] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
+}
+
+static __inline__ void cec_ops_clear_ext_timer(struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ext_src_spec,
+ __u8 *plug,
+ __u16 *phys_addr)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ext_src_spec = msg->msg[9];
+ *plug = msg->msg[10];
+ *phys_addr = (msg->msg[11] << 8) | msg->msg[12];
+}
+
+static __inline__ void cec_msg_set_analogue_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ana_bcast_type;
+ msg->msg[10] = ana_freq >> 8;
+ msg->msg[11] = ana_freq & 0xff;
+ msg->msg[12] = bcast_system;
+ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
+}
+
+static __inline__ void cec_ops_set_analogue_timer(struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ana_bcast_type,
+ __u16 *ana_freq,
+ __u8 *bcast_system)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ana_bcast_type = msg->msg[9];
+ *ana_freq = (msg->msg[10] << 8) | msg->msg[11];
+ *bcast_system = msg->msg[12];
+}
+
+static __inline__ void cec_msg_set_digital_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 16;
+ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
+ msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ cec_set_digital_service_id(msg->msg + 9, digital);
+}
+
+static __inline__ void cec_ops_set_digital_timer(struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ struct cec_op_digital_service_id *digital)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ cec_get_digital_service_id(msg->msg + 9, digital);
+}
+
+static __inline__ void cec_msg_set_ext_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ext_src_spec,
+ __u8 plug,
+ __u16 phys_addr)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_SET_EXT_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ext_src_spec;
+ msg->msg[10] = plug;
+ msg->msg[11] = phys_addr >> 8;
+ msg->msg[12] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
+}
+
+static __inline__ void cec_ops_set_ext_timer(struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ext_src_spec,
+ __u8 *plug,
+ __u16 *phys_addr)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ext_src_spec = msg->msg[9];
+ *plug = msg->msg[10];
+ *phys_addr = (msg->msg[11] << 8) | msg->msg[12];
+}
+
+static __inline__ void cec_msg_set_timer_program_title(struct cec_msg *msg,
+ const char *prog_title)
+{
+ unsigned len = strlen(prog_title);
+
+ if (len > 14)
+ len = 14;
+ msg->len = 2 + len;
+ msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE;
+ memcpy(msg->msg + 2, prog_title, len);
+}
+
+static __inline__ void cec_ops_set_timer_program_title(const struct cec_msg *msg,
+ char *prog_title)
+{
+ unsigned len = msg->len - 2;
+
+ if (len > 14)
+ len = 14;
+ memcpy(prog_title, msg->msg + 2, len);
+ prog_title[len] = '\0';
+}
+
+/* System Information Feature */
+static __inline__ void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_CEC_VERSION;
+ msg->msg[2] = cec_version;
+}
+
+static __inline__ void cec_ops_cec_version(const struct cec_msg *msg,
+ __u8 *cec_version)
+{
+ *cec_version = msg->msg[2];
+}
+
+static __inline__ void cec_msg_get_cec_version(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GET_CEC_VERSION;
+ msg->reply = reply ? CEC_MSG_CEC_VERSION : 0;
+}
+
+static __inline__ void cec_msg_report_physical_addr(struct cec_msg *msg,
+ __u16 phys_addr, __u8 prim_devtype)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->msg[4] = prim_devtype;
+}
+
+static __inline__ void cec_ops_report_physical_addr(const struct cec_msg *msg,
+ __u16 *phys_addr, __u8 *prim_devtype)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *prim_devtype = msg->msg[4];
+}
+
+static __inline__ void cec_msg_give_physical_addr(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR;
+ msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0;
+}
+
+static __inline__ void cec_msg_set_menu_language(struct cec_msg *msg,
+ const char *language)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE;
+ memcpy(msg->msg + 2, language, 3);
+}
+
+static __inline__ void cec_ops_set_menu_language(struct cec_msg *msg,
+ char *language)
+{
+ memcpy(language, msg->msg + 2, 3);
+}
+
+static __inline__ void cec_msg_get_menu_language(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE;
+ msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0;
+}
+
+/*
+ * Assumes a single RC Profile byte and a single Device Features byte,
+ * i.e. no extended features are supported by this helper function.
+ */
+static __inline__ void cec_msg_report_features(struct cec_msg *msg,
+ __u8 cec_version, __u8 all_device_types,
+ __u8 rc_profile, __u8 dev_features)
+{
+ msg->len = 6;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REPORT_FEATURES;
+ msg->msg[2] = cec_version;
+ msg->msg[3] = all_device_types;
+ msg->msg[4] = rc_profile;
+ msg->msg[5] = dev_features;
+}
+
+static __inline__ void cec_ops_report_features(const struct cec_msg *msg,
+ __u8 *cec_version, __u8 *all_device_types,
+ const __u8 **rc_profile, const __u8 **dev_features)
+{
+ const __u8 *p = &msg->msg[4];
+
+ *cec_version = msg->msg[2];
+ *all_device_types = msg->msg[3];
+ *rc_profile = p;
+ while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT))
+ p++;
+ if (!(*p & CEC_OP_FEAT_EXT)) {
+ *dev_features = p + 1;
+ while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT))
+ p++;
+ }
+ if (*p & CEC_OP_FEAT_EXT)
+ *rc_profile = *dev_features = NULL;
+}
+
+static __inline__ void cec_msg_give_features(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_FEATURES;
+ msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0;
+}
+
+/* Deck Control Feature */
+static __inline__ void cec_msg_deck_control(struct cec_msg *msg,
+ __u8 deck_control_mode)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_DECK_CONTROL;
+ msg->msg[2] = deck_control_mode;
+}
+
+static __inline__ void cec_ops_deck_control(struct cec_msg *msg,
+ __u8 *deck_control_mode)
+{
+ *deck_control_mode = msg->msg[2];
+}
+
+static __inline__ void cec_msg_deck_status(struct cec_msg *msg,
+ __u8 deck_info)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_DECK_STATUS;
+ msg->msg[2] = deck_info;
+}
+
+static __inline__ void cec_ops_deck_status(struct cec_msg *msg,
+ __u8 *deck_info)
+{
+ *deck_info = msg->msg[2];
+}
+
+static __inline__ void cec_msg_give_deck_status(struct cec_msg *msg,
+ bool reply,
+ __u8 status_req)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS;
+ msg->msg[2] = status_req;
+ msg->reply = reply ? CEC_MSG_DECK_STATUS : 0;
+}
+
+static __inline__ void cec_ops_give_deck_status(struct cec_msg *msg,
+ __u8 *status_req)
+{
+ *status_req = msg->msg[2];
+}
+
+static __inline__ void cec_msg_play(struct cec_msg *msg,
+ __u8 play_mode)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_PLAY;
+ msg->msg[2] = play_mode;
+}
+
+static __inline__ void cec_ops_play(struct cec_msg *msg,
+ __u8 *play_mode)
+{
+ *play_mode = msg->msg[2];
+}
+
+
+/* Tuner Control Feature */
+struct cec_op_tuner_device_info {
+ __u8 rec_flag;
+ __u8 tuner_display_info;
+ bool is_analog;
+ union {
+ struct cec_op_digital_service_id digital;
+ struct {
+ __u8 ana_bcast_type;
+ __u16 ana_freq;
+ __u8 bcast_system;
+ } analog;
+ };
+};
+
+static __inline__ void cec_msg_tuner_device_status_analog(struct cec_msg *msg,
+ __u8 rec_flag,
+ __u8 tuner_display_info,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 7;
+ msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
+ msg->msg[2] = (rec_flag << 7) | tuner_display_info;
+ msg->msg[3] = ana_bcast_type;
+ msg->msg[4] = ana_freq >> 8;
+ msg->msg[5] = ana_freq & 0xff;
+ msg->msg[6] = bcast_system;
+}
+
+static __inline__ void cec_msg_tuner_device_status_digital(struct cec_msg *msg,
+ __u8 rec_flag, __u8 tuner_display_info,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 10;
+ msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
+ msg->msg[2] = (rec_flag << 7) | tuner_display_info;
+ cec_set_digital_service_id(msg->msg + 3, digital);
+}
+
+static __inline__ void cec_msg_tuner_device_status(struct cec_msg *msg,
+ const struct cec_op_tuner_device_info *tuner_dev_info)
+{
+ if (tuner_dev_info->is_analog)
+ cec_msg_tuner_device_status_analog(msg,
+ tuner_dev_info->rec_flag,
+ tuner_dev_info->tuner_display_info,
+ tuner_dev_info->analog.ana_bcast_type,
+ tuner_dev_info->analog.ana_freq,
+ tuner_dev_info->analog.bcast_system);
+ else
+ cec_msg_tuner_device_status_digital(msg,
+ tuner_dev_info->rec_flag,
+ tuner_dev_info->tuner_display_info,
+ &tuner_dev_info->digital);
+}
+
+static __inline__ void cec_ops_tuner_device_status(struct cec_msg *msg,
+ struct cec_op_tuner_device_info *tuner_dev_info)
+{
+ tuner_dev_info->is_analog = msg->len < 10;
+ tuner_dev_info->rec_flag = msg->msg[2] >> 7;
+ tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f;
+ if (tuner_dev_info->is_analog) {
+ tuner_dev_info->analog.ana_bcast_type = msg->msg[3];
+ tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5];
+ tuner_dev_info->analog.bcast_system = msg->msg[6];
+ return;
+ }
+ cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital);
+}
+
+static __inline__ void cec_msg_give_tuner_device_status(struct cec_msg *msg,
+ bool reply,
+ __u8 status_req)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS;
+ msg->msg[2] = status_req;
+ msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0;
+}
+
+static __inline__ void cec_ops_give_tuner_device_status(struct cec_msg *msg,
+ __u8 *status_req)
+{
+ *status_req = msg->msg[2];
+}
+
+static __inline__ void cec_msg_select_analogue_service(struct cec_msg *msg,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 6;
+ msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE;
+ msg->msg[2] = ana_bcast_type;
+ msg->msg[3] = ana_freq >> 8;
+ msg->msg[4] = ana_freq & 0xff;
+ msg->msg[5] = bcast_system;
+}
+
+static __inline__ void cec_ops_select_analogue_service(struct cec_msg *msg,
+ __u8 *ana_bcast_type,
+ __u16 *ana_freq,
+ __u8 *bcast_system)
+{
+ *ana_bcast_type = msg->msg[2];
+ *ana_freq = (msg->msg[3] << 8) | msg->msg[4];
+ *bcast_system = msg->msg[5];
+}
+
+static __inline__ void cec_msg_select_digital_service(struct cec_msg *msg,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 9;
+ msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE;
+ cec_set_digital_service_id(msg->msg + 2, digital);
+}
+
+static __inline__ void cec_ops_select_digital_service(struct cec_msg *msg,
+ struct cec_op_digital_service_id *digital)
+{
+ cec_get_digital_service_id(msg->msg + 2, digital);
+}
+
+static __inline__ void cec_msg_tuner_step_decrement(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT;
+}
+
+static __inline__ void cec_msg_tuner_step_increment(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT;
+}
+
+
+/* Vendor Specific Commands Feature */
+static __inline__ void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID;
+ msg->msg[2] = vendor_id >> 16;
+ msg->msg[3] = (vendor_id >> 8) & 0xff;
+ msg->msg[4] = vendor_id & 0xff;
+}
+
+static __inline__ void cec_ops_device_vendor_id(const struct cec_msg *msg,
+ __u32 *vendor_id)
+{
+ *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
+}
+
+static __inline__ void cec_msg_give_device_vendor_id(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID;
+ msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0;
+}
+
+static __inline__ void cec_msg_vendor_remote_button_up(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP;
+}
+
+
+/* OSD Display Feature */
+static __inline__ void cec_msg_set_osd_string(struct cec_msg *msg,
+ __u8 disp_ctl,
+ const char *osd)
+{
+ unsigned len = strlen(osd);
+
+ if (len > 13)
+ len = 13;
+ msg->len = 3 + len;
+ msg->msg[1] = CEC_MSG_SET_OSD_STRING;
+ msg->msg[2] = disp_ctl;
+ memcpy(msg->msg + 3, osd, len);
+}
+
+static __inline__ void cec_ops_set_osd_string(const struct cec_msg *msg,
+ __u8 *disp_ctl,
+ char *osd)
+{
+ unsigned len = msg->len - 3;
+
+ *disp_ctl = msg->msg[2];
+ if (len > 13)
+ len = 13;
+ memcpy(osd, msg->msg + 3, len);
+ osd[len] = '\0';
+}
+
+
+/* Device OSD Transfer Feature */
+static __inline__ void cec_msg_set_osd_name(struct cec_msg *msg, const char *name)
+{
+ unsigned len = strlen(name);
+
+ if (len > 14)
+ len = 14;
+ msg->len = 2 + len;
+ msg->msg[1] = CEC_MSG_SET_OSD_NAME;
+ memcpy(msg->msg + 2, name, len);
+}
+
+static __inline__ void cec_ops_set_osd_name(const struct cec_msg *msg,
+ char *name)
+{
+ unsigned len = msg->len - 2;
+
+ if (len > 14)
+ len = 14;
+ memcpy(name, msg->msg + 2, len);
+ name[len] = '\0';
+}
+
+static __inline__ void cec_msg_give_osd_name(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_OSD_NAME;
+ msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0;
+}
+
+
+/* Device Menu Control Feature */
+static __inline__ void cec_msg_menu_status(struct cec_msg *msg,
+ __u8 menu_state)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_MENU_STATUS;
+ msg->msg[2] = menu_state;
+}
+
+static __inline__ void cec_ops_menu_status(struct cec_msg *msg,
+ __u8 *menu_state)
+{
+ *menu_state = msg->msg[2];
+}
+
+static __inline__ void cec_msg_menu_request(struct cec_msg *msg,
+ bool reply,
+ __u8 menu_req)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_MENU_REQUEST;
+ msg->msg[2] = menu_req;
+ msg->reply = reply ? CEC_MSG_MENU_STATUS : 0;
+}
+
+static __inline__ void cec_ops_menu_request(struct cec_msg *msg,
+ __u8 *menu_req)
+{
+ *menu_req = msg->msg[2];
+}
+
+static __inline__ void cec_msg_user_control_pressed(struct cec_msg *msg,
+ __u8 ui_cmd)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED;
+ msg->msg[2] = ui_cmd;
+}
+
+static __inline__ void cec_ops_user_control_pressed(struct cec_msg *msg,
+ __u8 *ui_cmd)
+{
+ *ui_cmd = msg->msg[2];
+}
+
+static __inline__ void cec_msg_user_control_released(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED;
+}
+
+/* Remote Control Passthrough Feature */
+
+/* Power Status Feature */
+static __inline__ void cec_msg_report_power_status(struct cec_msg *msg,
+ __u8 pwr_state)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS;
+ msg->msg[2] = pwr_state;
+}
+
+static __inline__ void cec_ops_report_power_status(const struct cec_msg *msg,
+ __u8 *pwr_state)
+{
+ *pwr_state = msg->msg[2];
+}
+
+static __inline__ void cec_msg_give_device_power_status(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS;
+ msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0;
+}
+
+/* General Protocol Messages */
+static __inline__ void cec_msg_feature_abort(struct cec_msg *msg,
+ __u8 abort_msg, __u8 reason)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_FEATURE_ABORT;
+ msg->msg[2] = abort_msg;
+ msg->msg[3] = reason;
+}
+
+static __inline__ void cec_ops_feature_abort(const struct cec_msg *msg,
+ __u8 *abort_msg, __u8 *reason)
+{
+ *abort_msg = msg->msg[2];
+ *reason = msg->msg[3];
+}
+
+/* This changes the current message into an abort message */
+static __inline__ void cec_msg_reply_abort(struct cec_msg *msg, __u8 reason)
+{
+ cec_msg_set_reply_to(msg, msg);
+ msg->len = 4;
+ msg->msg[2] = msg->msg[1];
+ msg->msg[3] = reason;
+ msg->msg[1] = CEC_MSG_FEATURE_ABORT;
+}
+
+static __inline__ void cec_msg_abort(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_ABORT;
+}
+
+
+/* System Audio Control Feature */
+static __inline__ void cec_msg_report_audio_status(struct cec_msg *msg,
+ __u8 aud_mute_status,
+ __u8 aud_vol_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS;
+ msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f);
+}
+
+static __inline__ void cec_ops_report_audio_status(const struct cec_msg *msg,
+ __u8 *aud_mute_status,
+ __u8 *aud_vol_status)
+{
+ *aud_mute_status = msg->msg[2] >> 7;
+ *aud_vol_status = msg->msg[2] & 0x7f;
+}
+
+static __inline__ void cec_msg_give_audio_status(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS;
+ msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0;
+}
+
+static __inline__ void cec_msg_set_system_audio_mode(struct cec_msg *msg,
+ __u8 sys_aud_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE;
+ msg->msg[2] = sys_aud_status;
+}
+
+static __inline__ void cec_ops_set_system_audio_mode(const struct cec_msg *msg,
+ __u8 *sys_aud_status)
+{
+ *sys_aud_status = msg->msg[2];
+}
+
+static __inline__ void cec_msg_system_audio_mode_request(struct cec_msg *msg,
+ bool reply,
+ __u16 phys_addr)
+{
+ msg->len = phys_addr == 0xffff ? 2 : 4;
+ msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0;
+
+}
+
+static __inline__ void cec_ops_system_audio_mode_request(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ if (msg->len < 4)
+ *phys_addr = 0xffff;
+ else
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static __inline__ void cec_msg_system_audio_mode_status(struct cec_msg *msg,
+ __u8 sys_aud_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS;
+ msg->msg[2] = sys_aud_status;
+}
+
+static __inline__ void cec_ops_system_audio_mode_status(const struct cec_msg *msg,
+ __u8 *sys_aud_status)
+{
+ *sys_aud_status = msg->msg[2];
+}
+
+static __inline__ void cec_msg_give_system_audio_mode_status(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS;
+ msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0;
+}
+
+static __inline__ void cec_msg_report_short_audio_descriptor(struct cec_msg *msg,
+ __u8 num_descriptors,
+ const __u32 *descriptors)
+{
+ unsigned i;
+
+ msg->len = 2 + num_descriptors * 3;
+ msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR;
+ for (i = 0; i < num_descriptors; i++) {
+ msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff;
+ msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff;
+ msg->msg[4 + i * 3] = descriptors[i] & 0xff;
+ }
+}
+
+static __inline__ void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg,
+ __u8 *num_descriptors,
+ __u32 *descriptors)
+{
+ unsigned i;
+
+ *num_descriptors = (msg->len - 2) / 3;
+ for (i = 0; i < *num_descriptors; i++)
+ descriptors[i] = (msg->msg[2 + i * 3] << 16) |
+ (msg->msg[3 + i * 3] << 8) |
+ msg->msg[4 + i * 3];
+}
+
+static __inline__ void cec_msg_request_short_audio_descriptor(struct cec_msg *msg,
+ __u8 audio_format_id,
+ __u8 audio_format_code)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR;
+ msg->msg[2] = (audio_format_id << 6) | (audio_format_code & 0x3f);
+}
+
+static __inline__ void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg,
+ __u8 *audio_format_id,
+ __u8 *audio_format_code)
+{
+ *audio_format_id = msg->msg[2] >> 6;
+ *audio_format_code = msg->msg[2] & 0x3f;
+}
+
+
+/* Audio Rate Control Feature */
+static __inline__ void cec_msg_set_audio_rate(struct cec_msg *msg,
+ __u8 audio_rate)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_SET_AUDIO_RATE;
+ msg->msg[2] = audio_rate;
+}
+
+static __inline__ void cec_ops_set_audio_rate(const struct cec_msg *msg,
+ __u8 *audio_rate)
+{
+ *audio_rate = msg->msg[2];
+}
+
+
+/* Audio Return Channel Control Feature */
+static __inline__ void cec_msg_report_arc_initiated(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED;
+}
+
+static __inline__ void cec_msg_initiate_arc(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_INITIATE_ARC;
+ msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0;
+}
+
+static __inline__ void cec_msg_request_arc_initiation(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION;
+ msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0;
+}
+
+static __inline__ void cec_msg_report_arc_terminated(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED;
+}
+
+static __inline__ void cec_msg_terminate_arc(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TERMINATE_ARC;
+ msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0;
+}
+
+static __inline__ void cec_msg_request_arc_termination(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION;
+ msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0;
+}
+
+
+/* Dynamic Audio Lipsync Feature */
+/* Only for CEC 2.0 and up */
+static __inline__ void cec_msg_report_current_latency(struct cec_msg *msg,
+ __u16 phys_addr,
+ __u8 video_latency,
+ __u8 low_latency_mode,
+ __u8 audio_out_compensated,
+ __u8 audio_out_delay)
+{
+ msg->len = 7;
+ msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->msg[4] = video_latency;
+ msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated;
+ msg->msg[6] = audio_out_delay;
+}
+
+static __inline__ void cec_ops_report_current_latency(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u8 *video_latency,
+ __u8 *low_latency_mode,
+ __u8 *audio_out_compensated,
+ __u8 *audio_out_delay)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *video_latency = msg->msg[4];
+ *low_latency_mode = (msg->msg[5] >> 2) & 1;
+ *audio_out_compensated = msg->msg[5] & 3;
+ *audio_out_delay = msg->msg[6];
+}
+
+static __inline__ void cec_msg_request_current_latency(struct cec_msg *msg,
+ bool reply,
+ __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0;
+}
+
+static __inline__ void cec_ops_request_current_latency(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+#endif
new file mode 100644
@@ -0,0 +1,709 @@
+#ifndef _CEC_H
+#define _CEC_H
+
+#include <linux/types.h>
+
+struct cec_msg {
+ __u64 ts;
+ __u32 len;
+ __u32 status;
+ /*
+ * timeout (in ms) is used to timeout CEC_RECEIVE.
+ * Set to 0 if you want to wait forever.
+ */
+ __u32 timeout;
+ /*
+ * The framework assigns a sequence number to messages that are sent.
+ * This can be used to track replies to previously sent messages.
+ */
+ __u32 sequence;
+ __u8 msg[16];
+ /*
+ * If non-zero, then wait for a reply with this opcode.
+ * If there was an error when sending the msg or FeatureAbort
+ * was returned, then reply is set to 0.
+ * If reply is non-zero upon return, then len/msg are set to
+ * the received message.
+ * If reply is zero upon return and status has the
+ * CEC_TX_STATUS_FEATURE_ABORT bit set, then len/msg are set to the
+ * received feature abort message.
+ * If reply is zero upon return and status has the
+ * CEC_TX_STATUS_REPLY_TIMEOUT
+ * bit set, then no reply was seen at all.
+ * This field is ignored with CEC_RECEIVE.
+ * If reply is non-zero for CEC_TRANSMIT and the message is a broadcast,
+ * then -EINVAL is returned.
+ * if reply is non-zero, then timeout is set to 1000 (the required
+ * maximum response time).
+ */
+ __u8 reply;
+ __u8 reserved[35];
+};
+
+static __inline__ __u8 cec_msg_initiator(const struct cec_msg *msg)
+{
+ return msg->msg[0] >> 4;
+}
+
+static __inline__ __u8 cec_msg_destination(const struct cec_msg *msg)
+{
+ return msg->msg[0] & 0xf;
+}
+
+static __inline__ bool cec_msg_is_broadcast(const struct cec_msg *msg)
+{
+ return (msg->msg[0] & 0xf) == 0xf;
+}
+
+static __inline__ void cec_msg_init(struct cec_msg *msg,
+ __u8 initiator, __u8 destination)
+{
+ memset(msg, 0, sizeof(*msg));
+ msg->msg[0] = (initiator << 4) | destination;
+}
+
+/*
+ * Set the msg destination to the orig initiator and the msg initiator to the
+ * orig destination. Note that msg and orig may be the same pointer, in which
+ * case the change is done in place.
+ */
+static __inline__ void cec_msg_set_reply_to(struct cec_msg *msg, struct cec_msg *orig)
+{
+ /* The destination becomes the initiator and vice versa */
+ msg->msg[0] = (cec_msg_destination(orig) << 4) | cec_msg_initiator(orig);
+}
+
+/* cec status field */
+#define CEC_TX_STATUS_OK (0)
+#define CEC_TX_STATUS_ARB_LOST (1 << 0)
+#define CEC_TX_STATUS_RETRY_TIMEOUT (1 << 1)
+#define CEC_TX_STATUS_FEATURE_ABORT (1 << 2)
+#define CEC_TX_STATUS_REPLY_TIMEOUT (1 << 3)
+#define CEC_RX_STATUS_READY (0)
+
+#define CEC_LOG_ADDR_INVALID 0xff
+
+/* The maximum number of logical addresses one device can be assigned to.
+ * The CEC 2.0 spec allows for only 2 logical addresses at the moment. The
+ * Analog Devices CEC hardware supports 3. So let's go wild and go for 4. */
+#define CEC_MAX_LOG_ADDRS 4
+
+/* The "All Device Types" flags (CEC 2.0) */
+#define CEC_FL_ALL_DEVTYPE_TV (1 << 7)
+#define CEC_FL_ALL_DEVTYPE_RECORD (1 << 6)
+#define CEC_FL_ALL_DEVTYPE_TUNER (1 << 5)
+#define CEC_FL_ALL_DEVTYPE_PLAYBACK (1 << 4)
+#define CEC_FL_ALL_DEVTYPE_AUDIOSYSTEM (1 << 3)
+#define CEC_FL_ALL_DEVTYPE_SWITCH (1 << 2)
+/* And if you wondering what happened to PROCESSOR devices: those should
+ * be mapped to a SWITCH. */
+
+/* The logical address types that the CEC device wants to claim */
+#define CEC_LOG_ADDR_TYPE_TV 0
+#define CEC_LOG_ADDR_TYPE_RECORD 1
+#define CEC_LOG_ADDR_TYPE_TUNER 2
+#define CEC_LOG_ADDR_TYPE_PLAYBACK 3
+#define CEC_LOG_ADDR_TYPE_AUDIOSYSTEM 4
+#define CEC_LOG_ADDR_TYPE_SPECIFIC 5
+#define CEC_LOG_ADDR_TYPE_UNREGISTERED 6
+/* Switches should use UNREGISTERED.
+ * Processors should use SPECIFIC. */
+
+/*
+ * Use this if there is no vendor ID (CEC_G_VENDOR_ID) or if the vendor ID
+ * should be disabled (CEC_S_VENDOR_ID)
+ */
+#define CEC_VENDOR_ID_NONE 0xffffffff
+
+struct cec_event {
+ __u64 ts;
+ __u32 event;
+ __u32 sequence;
+ __u8 reserved[8];
+};
+
+/* The CEC state */
+#define CEC_STATE_DISABLED 0
+#define CEC_STATE_ENABLED 1
+
+/* The passthrough mode state */
+#define CEC_PASSTHROUGH_DISABLED 0
+#define CEC_PASSTHROUGH_ENABLED 1
+
+/* Userspace has to configure the adapter state (enable/disable) */
+#define CEC_CAP_STATE (1 << 0)
+/* Userspace has to configure the physical address */
+#define CEC_CAP_PHYS_ADDR (1 << 1)
+/* Userspace has to configure the logical addresses */
+#define CEC_CAP_LOG_ADDRS (1 << 2)
+/* Userspace can transmit messages */
+#define CEC_CAP_TRANSMIT (1 << 3)
+/* Userspace can receive messages */
+#define CEC_CAP_RECEIVE (1 << 4)
+/* Userspace has to configure the vendor id */
+#define CEC_CAP_VENDOR_ID (1 << 5)
+/* The hardware has the possibility to work in the passthrough */
+#define CEC_CAP_PASSTHROUGH (1 << 6)
+/* Supports remote control */
+#define CEC_CAP_RC (1 << 7)
+/* Supports ARC */
+#define CEC_CAP_ARC (1 << 8)
+/* Supports CDC */
+#define CEC_CAP_CDC (1 << 9)
+
+struct cec_caps {
+ __u32 available_log_addrs;
+ __u32 capabilities;
+ __u8 reserved[40];
+};
+
+#define CEC_LOG_ADDRS_FL_HANDLE_MSGS (1 << 0)
+
+struct cec_log_addrs {
+ __u8 cec_version;
+ __u8 num_log_addrs;
+ __u8 primary_device_type[CEC_MAX_LOG_ADDRS];
+ __u8 log_addr_type[CEC_MAX_LOG_ADDRS];
+ __u8 log_addr[CEC_MAX_LOG_ADDRS];
+ __u8 flags[CEC_MAX_LOG_ADDRS];
+ char osd_name[15];
+
+ /* CEC 2.0 */
+ __u8 all_device_types[CEC_MAX_LOG_ADDRS];
+ __u8 features[CEC_MAX_LOG_ADDRS][12];
+
+ __u8 reserved[63];
+};
+
+/* Commands */
+
+/* One Touch Play Feature */
+#define CEC_MSG_ACTIVE_SOURCE 0x82
+#define CEC_MSG_IMAGE_VIEW_ON 0x04
+#define CEC_MSG_TEXT_VIEW_ON 0x0d
+
+
+/* Routing Control Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_ACTIVE_SOURCE
+ */
+
+#define CEC_MSG_INACTIVE_SOURCE 0x9d
+#define CEC_MSG_REQUEST_ACTIVE_SOURCE 0x85
+#define CEC_MSG_ROUTING_CHANGE 0x80
+#define CEC_MSG_ROUTING_INFORMATION 0x81
+#define CEC_MSG_SET_STREAM_PATH 0x86
+
+
+/* Standby Feature */
+#define CEC_MSG_STANDBY 0x36
+
+
+/* One Touch Record Feature */
+#define CEC_MSG_RECORD_OFF 0x0b
+#define CEC_MSG_RECORD_ON 0x09
+/* Record Source Type Operand (rec_src_type) */
+#define CEC_OP_RECORD_SRC_OWN 0x01
+#define CEC_OP_RECORD_SRC_DIGITAL 0x02
+#define CEC_OP_RECORD_SRC_ANALOG 0x03
+#define CEC_OP_RECORD_SRC_EXT_PLUG 0x04
+#define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR 0x05
+/* Service Identification Method Operand (service_id_method) */
+#define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID 0x00
+#define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL 0x01
+/* Digital Service Broadcast System Operand (dig_bcast_system) */
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN 0x00
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN 0x01
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN 0x02
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS 0x08
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS 0x09
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T 0x0a
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE 0x10
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT 0x11
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T 0x12
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C 0x18
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S 0x19
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2 0x1a
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T 0x1b
+/* Analogue Broadcast Type Operand (ana_bcast_type) */
+#define CEC_OP_ANA_BCAST_TYPE_CABLE 0x00
+#define CEC_OP_ANA_BCAST_TYPE_SATELLITE 0x01
+#define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL 0x02
+/* Broadcast System Operand (bcast_system) */
+#define CEC_OP_BCAST_SYSTEM_PAL_BG 0x00
+#define CEC_OP_BCAST_SYSTEM_SECAM_LQ 0x01 /* SECAM L' */
+#define CEC_OP_BCAST_SYSTEM_PAL_M 0x02
+#define CEC_OP_BCAST_SYSTEM_NTSC_M 0x03
+#define CEC_OP_BCAST_SYSTEM_PAL_I 0x04
+#define CEC_OP_BCAST_SYSTEM_SECAM_DK 0x05
+#define CEC_OP_BCAST_SYSTEM_SECAM_BG 0x06
+#define CEC_OP_BCAST_SYSTEM_SECAM_L 0x07
+#define CEC_OP_BCAST_SYSTEM_PAL_DK 0x08
+#define CEC_OP_BCAST_SYSTEM_OTHER 0x1f
+/* Channel Number Format Operand (channel_number_fmt) */
+#define CEC_OP_CHANNEL_NUMBER_FMT_1_PART 0x01
+#define CEC_OP_CHANNEL_NUMBER_FMT_2_PART 0x02
+
+#define CEC_MSG_RECORD_STATUS 0x0a
+/* Record Status Operand (rec_status) */
+#define CEC_OP_RECORD_STATUS_CUR_SRC 0x01
+#define CEC_OP_RECORD_STATUS_DIG_SERVICE 0x02
+#define CEC_OP_RECORD_STATUS_ANA_SERVICE 0x03
+#define CEC_OP_RECORD_STATUS_EXT_INPUT 0x04
+#define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE 0x05
+#define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE 0x06
+#define CEC_OP_RECORD_STATUS_NO_SERVICE 0x07
+#define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG 0x09
+#define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR 0x0a
+#define CEC_OP_RECORD_STATUS_UNSUP_CA 0x0b
+#define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS 0x0c
+#define CEC_OP_RECORD_STATUS_CANT_COPY_SRC 0x0d
+#define CEC_OP_RECORD_STATUS_NO_MORE_COPIES 0x0e
+#define CEC_OP_RECORD_STATUS_NO_MEDIA 0x10
+#define CEC_OP_RECORD_STATUS_PLAYING 0x11
+#define CEC_OP_RECORD_STATUS_ALREADY_RECORDING 0x12
+#define CEC_OP_RECORD_STATUS_MEDIA_PROT 0x13
+#define CEC_OP_RECORD_STATUS_NO_SIGNAL 0x14
+#define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM 0x15
+#define CEC_OP_RECORD_STATUS_NO_SPACE 0x16
+#define CEC_OP_RECORD_STATUS_PARENTAL_LOCK 0x17
+#define CEC_OP_RECORD_STATUS_TERMINATED_OK 0x1a
+#define CEC_OP_RECORD_STATUS_ALREADY_TERM 0x1b
+#define CEC_OP_RECORD_STATUS_OTHER 0x1f
+
+#define CEC_MSG_RECORD_TV_SCREEN 0x0f
+
+
+/* Timer Programming Feature */
+#define CEC_MSG_CLEAR_ANALOGUE_TIMER 0x33
+/* Recording Sequence Operand (recording_seq) */
+#define CEC_OP_REC_SEQ_SUNDAY 0x01
+#define CEC_OP_REC_SEQ_MONDAY 0x02
+#define CEC_OP_REC_SEQ_TUESDAY 0x04
+#define CEC_OP_REC_SEQ_WEDNESDAY 0x08
+#define CEC_OP_REC_SEQ_THURSDAY 0x10
+#define CEC_OP_REC_SEQ_FRIDAY 0x20
+#define CEC_OP_REC_SEQ_SATERDAY 0x40
+#define CEC_OP_REC_SEQ_ONCE_ONLY 0x00
+
+#define CEC_MSG_CLEAR_DIGITAL_TIMER 0x99
+
+#define CEC_MSG_CLEAR_EXT_TIMER 0xa1
+/* External Source Specifier Operand (ext_src_spec) */
+#define CEC_OP_EXT_SRC_PLUG 0x04
+#define CEC_OP_EXT_SRC_PHYS_ADDR 0x05
+
+#define CEC_MSG_SET_ANALOGUE_TIMER 0x34
+#define CEC_MSG_SET_DIGITAL_TIMER 0x97
+#define CEC_MSG_SET_EXT_TIMER 0xa2
+
+#define CEC_MSG_SET_TIMER_PROGRAM_TITLE 0x67
+#define CEC_MSG_TIMER_CLEARED_STATUS 0x43
+/* Timer Cleared Status Data Operand (timer_cleared_status) */
+#define CEC_OP_TIMER_CLR_STAT_RECORDING 0x00
+#define CEC_OP_TIMER_CLR_STAT_NO_MATCHING 0x01
+#define CEC_OP_TIMER_CLR_STAT_NO_INFO 0x02
+#define CEC_OP_TIMER_CLR_STAT_CLEARED 0x80
+
+#define CEC_MSG_TIMER_STATUS 0x35
+/* Timer Overlap Warning Operand (timer_overlap_warning) */
+#define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP 0x00
+#define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP 0x01
+/* Media Info Operand (media_info) */
+#define CEC_OP_MEDIA_INFO_UNPROT_MEDIA 0x00
+#define CEC_OP_MEDIA_INFO_PROT_MEDIA 0x01
+#define CEC_OP_MEDIA_INFO_NO_MEDIA 0x02
+/* Programmed Indicator Operand (prog_indicator) */
+#define CEC_OP_PROG_IND_NOT_PROGRAMMED 0x00
+#define CEC_OP_PROG_IND_PROGRAMMED 0x01
+/* Programmed Info Operand (prog_info) */
+#define CEC_OP_PROG_INFO_ENOUGH_SPACE 0x08
+#define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE 0x09
+#define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE 0x0b
+#define CEC_OP_PROG_INFO_NONE_AVAILABLE 0x0a
+/* Not Programmed Error Info Operand (prog_error) */
+#define CEC_OP_PROG_ERROR_NO_FREE_TIMER 0x01
+#define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE 0x02
+#define CEC_OP_PROG_ERROR_REC_SEQ_ERROR 0x03
+#define CEC_OP_PROG_ERROR_INV_EXT_PLUG 0x04
+#define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR 0x05
+#define CEC_OP_PROG_ERROR_CA_UNSUPP 0x06
+#define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS 0x07
+#define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP 0x08
+#define CEC_OP_PROG_ERROR_PARENTAL_LOCK 0x09
+#define CEC_OP_PROG_ERROR_CLOCK_FAILURE 0x0a
+#define CEC_OP_PROG_ERROR_DUPLICATE 0x0e
+
+
+/* System Information Feature */
+#define CEC_MSG_CEC_VERSION 0x9e
+/* CEC Version Operand (cec_version) */
+#define CEC_OP_CEC_VERSION_1_3A 4
+#define CEC_OP_CEC_VERSION_1_4 5
+#define CEC_OP_CEC_VERSION_2_0 6
+
+#define CEC_MSG_GET_CEC_VERSION 0x9f
+#define CEC_MSG_GIVE_PHYSICAL_ADDR 0x83
+#define CEC_MSG_GET_MENU_LANGUAGE 0x91
+#define CEC_MSG_REPORT_PHYSICAL_ADDR 0x84
+/* Primary Device Type Operand (prim_devtype) */
+#define CEC_OP_PRIM_DEVTYPE_TV 0
+#define CEC_OP_PRIM_DEVTYPE_RECORD 1
+#define CEC_OP_PRIM_DEVTYPE_TUNER 3
+#define CEC_OP_PRIM_DEVTYPE_PLAYBACK 4
+#define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM 5
+#define CEC_OP_PRIM_DEVTYPE_SWITCH 6
+#define CEC_OP_PRIM_DEVTYPE_PROCESSOR 7
+
+#define CEC_MSG_SET_MENU_LANGUAGE 0x32
+#define CEC_MSG_REPORT_FEATURES 0xa6 /* HDMI 2.0 */
+/* Valid for RC Profile and Device Feature operands */
+#define CEC_OP_FEAT_EXT 0x80 /* Extension bit */
+/* RC Profile Operand (rc_profile) */
+#define CEC_OP_FEAT_RC_TV_PROFILE_NONE 0x00
+#define CEC_OP_FEAT_RC_TV_PROFILE_1 0x02
+#define CEC_OP_FEAT_RC_TV_PROFILE_2 0x06
+#define CEC_OP_FEAT_RC_TV_PROFILE_3 0x0a
+#define CEC_OP_FEAT_RC_TV_PROFILE_4 0x0e
+#define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU 0x50
+#define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU 0x48
+#define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU 0x44
+#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU 0x42
+#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU 0x41
+/* Device Feature Operand (dev_features) */
+#define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN 0x40
+#define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING 0x20
+#define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL 0x10
+#define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 0x08
+#define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 0x04
+#define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 0x02
+
+#define CEC_MSG_GIVE_FEATURES 0xa5 /* HDMI 2.0 */
+
+
+/* Deck Control Feature */
+#define CEC_MSG_DECK_CONTROL 0x42
+/* Deck Control Mode Operand (deck_control_mode) */
+#define CEC_OP_DECK_CTL_MODE_SKIP_FWD 0x01
+#define CEC_OP_DECK_CTL_MODE_SKIP_REV 0x02
+#define CEC_OP_DECK_CTL_MODE_STOP 0x03
+#define CEC_OP_DECK_CTL_MODE_EJECT 0x04
+
+#define CEC_MSG_DECK_STATUS 0x1b
+/* Deck Info Operand (deck_info) */
+#define CEC_OP_DECK_INFO_PLAY 0x11
+#define CEC_OP_DECK_INFO_RECORD 0x12
+#define CEC_OP_DECK_INFO_PLAY_REV 0x13
+#define CEC_OP_DECK_INFO_STILL 0x14
+#define CEC_OP_DECK_INFO_SLOW 0x15
+#define CEC_OP_DECK_INFO_SLOW_REV 0x16
+#define CEC_OP_DECK_INFO_FAST_FWD 0x17
+#define CEC_OP_DECK_INFO_FAST_REV 0x18
+#define CEC_OP_DECK_INFO_NO_MEDIA 0x19
+#define CEC_OP_DECK_INFO_STOP 0x1a
+#define CEC_OP_DECK_INFO_SKIP_FWD 0x1b
+#define CEC_OP_DECK_INFO_SKIP_REV 0x1c
+#define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD 0x1d
+#define CEC_OP_DECK_INFO_INDEX_SEARCH_REV 0x1e
+#define CEC_OP_DECK_INFO_OTHER 0x1f
+
+#define CEC_MSG_GIVE_DECK_STATUS 0x1a
+/* Status Request Operand (status_req) */
+#define CEC_OP_STATUS_REQ_ON 0x01
+#define CEC_OP_STATUS_REQ_OFF 0x02
+#define CEC_OP_STATUS_REQ_ONCE 0x03
+
+#define CEC_MSG_PLAY 0x41
+/* Play Mode Operand (play_mode) */
+#define CEC_OP_PLAY_MODE_PLAY_FWD 0x24
+#define CEC_OP_PLAY_MODE_PLAY_REV 0x20
+#define CEC_OP_PLAY_MODE_PLAY_STILL 0x25
+#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN 0x05
+#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED 0x06
+#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX 0x07
+#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN 0x09
+#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED 0x0a
+#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX 0x0b
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN 0x15
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED 0x16
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX 0x17
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN 0x19
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED 0x1a
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX 0x1b
+
+
+/* Tuner Control Feature */
+#define CEC_MSG_GIVE_TUNER_DEVICE_STATUS 0x08
+#define CEC_MSG_SELECT_ANALOGUE_SERVICE 0x92
+#define CEC_MSG_SELECT_DIGITAL_SERVICE 0x93
+#define CEC_MSG_TUNER_DEVICE_STATUS 0x07
+/* Recording Flag Operand (rec_flag) */
+#define CEC_OP_REC_FLAG_USED 0x00
+#define CEC_OP_REC_FLAG_NOT_USED 0x01
+/* Tuner Display Info Operand (tuner_display_info) */
+#define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL 0x00
+#define CEC_OP_TUNER_DISPLAY_INFO_NONE 0x01
+#define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE 0x02
+
+#define CEC_MSG_TUNER_STEP_DECREMENT 0x06
+#define CEC_MSG_TUNER_STEP_INCREMENT 0x05
+
+
+/* Vendor Specific Commands Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_CEC_VERSION
+ * CEC_MSG_GET_CEC_VERSION
+ */
+#define CEC_MSG_DEVICE_VENDOR_ID 0x87
+#define CEC_MSG_GIVE_DEVICE_VENDOR_ID 0x8c
+#define CEC_MSG_VENDOR_COMMAND 0x89
+#define CEC_MSG_VENDOR_COMMAND_WITH_ID 0xa0
+#define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN 0x8a
+#define CEC_MSG_VENDOR_REMOTE_BUTTON_UP 0x8b
+
+
+/* OSD Display Feature */
+#define CEC_MSG_SET_OSD_STRING 0x64
+/* Display Control Operand (disp_ctl) */
+#define CEC_OP_DISP_CTL_DEFAULT 0x00
+#define CEC_OP_DISP_CTL_UNTIL_CLEARED 0x40
+#define CEC_OP_DISP_CTL_CLEAR 0x80
+
+
+/* Device OSD Transfer Feature */
+#define CEC_MSG_GIVE_OSD_NAME 0x46
+#define CEC_MSG_SET_OSD_NAME 0x47
+
+
+/* Device Menu Control Feature */
+#define CEC_MSG_MENU_REQUEST 0x8d
+/* Menu Request Type Operand (menu_req) */
+#define CEC_OP_MENU_REQUEST_ACTIVATE 0x00
+#define CEC_OP_MENU_REQUEST_DEACTIVATE 0x01
+#define CEC_OP_MENU_REQUEST_QUERY 0x02
+
+#define CEC_MSG_MENU_STATUS 0x8e
+/* Menu State Operand (menu_state) */
+#define CEC_OP_MENU_STATE_ACTIVATED 0x00
+#define CEC_OP_MENU_STATE_DEACTIVATED 0x01
+
+#define CEC_MSG_USER_CONTROL_PRESSED 0x44
+/* UI Broadcast Type Operand (ui_bcast_type) */
+#define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL 0x00
+#define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA 0x01
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE 0x10
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T 0x20
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE 0x30
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT 0x40
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL 0x50
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_T 0x60
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE 0x70
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT 0x80
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT 0x90
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2 0x91
+#define CEC_OP_UI_BCAST_TYPE_IP 0xa0
+/* UI Sound Presentation Control Operand (ui_snd_pres_ctl) */
+#define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO 0x10
+#define CEC_OP_UI_SND_PRES_CTL_KARAOKE 0x20
+#define CEC_OP_UI_SND_PRES_CTL_DOWNMIX 0x80
+#define CEC_OP_UI_SND_PRES_CTL_REVERB 0x90
+#define CEC_OP_UI_SND_PRES_CTL_EQUALIZER 0xa0
+#define CEC_OP_UI_SND_PRES_CTL_BASS_UP 0xb1
+#define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL 0xb2
+#define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN 0xb3
+#define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP 0xc1
+#define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL 0xc2
+#define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN 0xc3
+
+#define CEC_MSG_USER_CONTROL_RELEASED 0x45
+
+
+/* Remote Control Passthrough Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_USER_CONTROL_PRESSED
+ * CEC_MSG_USER_CONTROL_RELEASED
+ */
+
+
+/* Power Status Feature */
+#define CEC_MSG_GIVE_DEVICE_POWER_STATUS 0x8f
+#define CEC_MSG_REPORT_POWER_STATUS 0x90
+/* Power Status Operand (pwr_state) */
+#define CEC_OP_POWER_STATUS_ON 0x00
+#define CEC_OP_POWER_STATUS_STANDBY 0x01
+#define CEC_OP_POWER_STATUS_TO_ON 0x02
+#define CEC_OP_POWER_STATUS_TO_STANDBY 0x03
+
+
+/* General Protocol Messages */
+#define CEC_MSG_FEATURE_ABORT 0x00
+/* Abort Reason Operand (reason) */
+#define CEC_OP_ABORT_UNRECOGNIZED_OP 0
+#define CEC_OP_ABORT_INCORRECT_MODE 1
+#define CEC_OP_ABORT_NO_SOURCE 2
+#define CEC_OP_ABORT_INVALID_OP 3
+#define CEC_OP_ABORT_REFUSED 4
+#define CEC_OP_ABORT_UNDETERMINED 5
+
+#define CEC_MSG_ABORT 0xff
+
+
+/* System Audio Control Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_USER_CONTROL_PRESSED
+ * CEC_MSG_USER_CONTROL_RELEASED
+ */
+#define CEC_MSG_GIVE_AUDIO_STATUS 0x71
+#define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7d
+#define CEC_MSG_REPORT_AUDIO_STATUS 0x7a
+/* Audio Mute Status Operand (aud_mute_status) */
+#define CEC_OP_AUD_MUTE_STATUS_OFF 0x00
+#define CEC_OP_AUD_MUTE_STATUS_ON 0x01
+
+#define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR 0xa3
+#define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR 0xa4
+#define CEC_MSG_SET_SYSTEM_AUDIO_MODE 0x72
+/* System Audio Status Operand (sys_aud_status) */
+#define CEC_OP_SYS_AUD_STATUS_OFF 0x00
+#define CEC_OP_SYS_AUD_STATUS_ON 0x01
+
+#define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST 0x70
+#define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS 0x7e
+/* Audio Format ID Operand (audio_format_id) */
+#define CEC_OP_AUD_FMT_ID_CEA861 0x00
+#define CEC_OP_AUD_FMT_ID_CEA861_CXT 0x01
+
+
+/* Audio Rate Control Feature */
+#define CEC_MSG_SET_AUDIO_RATE 0x9a
+/* Audio Rate Operand (audio_rate) */
+#define CEC_OP_AUD_RATE_OFF 0x00
+#define CEC_OP_AUD_RATE_WIDE_STD 0x01
+#define CEC_OP_AUD_RATE_WIDE_FAST 0x02
+#define CEC_OP_AUD_RATE_WIDE_SLOW 0x03
+#define CEC_OP_AUD_RATE_NARROW_STD 0x04
+#define CEC_OP_AUD_RATE_NARROW_FAST 0x05
+#define CEC_OP_AUD_RATE_NARROW_SLOW 0x06
+
+
+/* Audio Return Channel Control Feature */
+#define CEC_MSG_INITIATE_ARC 0xc0
+#define CEC_MSG_REPORT_ARC_INITIATED 0xc1
+#define CEC_MSG_REPORT_ARC_TERMINATED 0xc2
+#define CEC_MSG_REQUEST_ARC_INITIATION 0xc3
+#define CEC_MSG_REQUEST_ARC_TERMINATION 0xc4
+#define CEC_MSG_TERMINATE_ARC 0xc5
+
+
+/* Dynamic Audio Lipsync Feature */
+/* Only for CEC 2.0 and up */
+#define CEC_MSG_REQUEST_CURRENT_LATENCY 0xa7
+#define CEC_MSG_REPORT_CURRENT_LATENCY 0xa8
+/* Low Latency Mode Operand (low_latency_mode) */
+#define CEC_OP_LOW_LATENCY_MODE_OFF 0x00
+#define CEC_OP_LOW_LATENCY_MODE_ON 0x01
+/* Audio Output Compensated Operand (audio_out_compensated) */
+#define CEC_OP_AUD_OUT_COMPENSATED_NA 0x00
+#define CEC_OP_AUD_OUT_COMPENSATED_DELAY 0x01
+#define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY 0x02
+#define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY 0x03
+
+
+/* Capability Discovery and Control Feature */
+#define CEC_MSG_CDC_MESSAGE 0xf8
+/* Ethernet-over-HDMI: nobody ever does this... */
+#define CEC_MSG_CDC_HEC_INQUIRE_STATE 0x00
+#define CEC_MSG_CDC_HEC_REPORT_STATE 0x01
+#define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT 0x02
+#define CEC_MSG_CDC_HEC_SET_STATE 0x03
+#define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION 0x04
+#define CEC_MSG_CDC_HEC_NOTIFY_ALIVE 0x05
+#define CEC_MSG_CDC_HEC_DISCOVER 0x06
+/* Hotplug Detect messages */
+#define CEC_MSG_CDC_HPD_SET_STATE 0x10
+/* CDC HPD State Operand */
+#define CEC_OP_HPD_STATE_CP_EDID_DISABLE 0x00
+#define CEC_OP_HPD_STATE_CP_EDID_ENABLE 0x01
+#define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE 0x02
+#define CEC_OP_HPD_STATE_EDID_DISABLE 0x03
+#define CEC_OP_HPD_STATE_EDID_ENABLE 0x04
+#define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE 0x05
+#define CEC_MSG_CDC_HPD_REPORT_STATE 0x11
+/* CDC HPD Error Code Operand */
+#define CEC_OP_HPD_ERROR_NONE 0x00
+#define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE 0x01
+#define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE 0x02
+#define CEC_OP_HPD_ERROR_OTHER 0x03
+#define CEC_OP_HPD_ERROR_NONE_NO_VIDEO 0x04
+
+/* Events */
+/* Event that occurs when a cable is connected */
+#define CEC_EVENT_CONNECT 1
+/* Event that occurs when all logical addresses were claimed */
+#define CEC_EVENT_READY 2
+/* Event that is sent when the cable is disconnected */
+#define CEC_EVENT_DISCONNECT 3
+/* This event is sent when a reply to a message is received */
+#define CEC_EVENT_GOT_REPLY 4
+
+/* ioctls */
+
+/* issue a CEC command */
+#define CEC_G_CAPS _IOWR('a', 0, struct cec_caps)
+#define CEC_TRANSMIT _IOWR('a', 1, struct cec_msg)
+#define CEC_RECEIVE _IOWR('a', 2, struct cec_msg)
+
+/*
+ Configure the CEC adapter. It sets the device type and which
+ logical types it will try to claim. It will return which
+ logical addresses it could actually claim.
+ An error is returned if the adapter is disabled or if there
+ is no physical address assigned.
+ */
+
+#define CEC_G_ADAP_LOG_ADDRS _IOR('a', 3, struct cec_log_addrs)
+#define CEC_S_ADAP_LOG_ADDRS _IOWR('a', 4, struct cec_log_addrs)
+
+/*
+ Enable/disable the adapter. The Set state ioctl may not
+ be available if that is handled internally.
+ */
+#define CEC_G_ADAP_STATE _IOR('a', 5, __u32)
+#define CEC_S_ADAP_STATE _IOW('a', 6, __u32)
+
+/*
+ phys_addr is either 0 (if this is the CEC root device)
+ or a valid physical address obtained from the sink's EDID
+ as read by this CEC device (if this is a source device)
+ or a physical address obtained and modified from a sink
+ EDID and used for a sink CEC device.
+ If nothing is connected, then phys_addr is 0xffff.
+ See HDMI 1.4b, section 8.7 (Physical Address).
+
+ The Set ioctl may not be available if that is handled
+ internally.
+ */
+#define CEC_G_ADAP_PHYS_ADDR _IOR('a', 7, __u16)
+#define CEC_S_ADAP_PHYS_ADDR _IOW('a', 8, __u16)
+
+#define CEC_G_EVENT _IOWR('a', 9, struct cec_event)
+/*
+ Read and set the vendor ID of the CEC adapter.
+ */
+#define CEC_G_VENDOR_ID _IOR('a', 10, __u32)
+#define CEC_S_VENDOR_ID _IOW('a', 11, __u32)
+/*
+ Enable/disable the passthrough mode
+ */
+#define CEC_G_PASSTHROUGH _IOR('a', 12, __u32)
+#define CEC_S_PASSTHROUGH _IOW('a', 13, __u32)
+
+#endif
@@ -518,6 +518,16 @@ struct parse_event key_events[] = {
{"KEY_KBDINPUTASSIST_NEXTGROUP", 0x263},
{"KEY_KBDINPUTASSIST_ACCEPT", 0x264},
{"KEY_KBDINPUTASSIST_CANCEL", 0x265},
+ {"KEY_RIGHT_UP", 0x266},
+ {"KEY_RIGHT_DOWN", 0x267},
+ {"KEY_LEFT_UP", 0x268},
+ {"KEY_LEFT_DOWN", 0x269},
+ {"KEY_NEXT_FAVORITE", 0x270},
+ {"KEY_STOP_RECORD", 0x271},
+ {"KEY_PAUSE_RECORD", 0x272},
+ {"KEY_VOD", 0x273},
+ {"KEY_UNMUTE", 0x274},
+ {"KEY_DVB", 0x275},
{"BTN_TRIGGER_HAPPY", 0x2c0},
{"BTN_TRIGGER_HAPPY1", 0x2c0},
{"BTN_TRIGGER_HAPPY2", 0x2c1},
new file mode 100644
@@ -0,0 +1,77 @@
+# table cec, type: CEC
+0x00 KEY_OK
+0x01 KEY_UP
+0x02 KEY_DOWN
+0x03 KEY_LEFT
+0x04 KEY_RIGHT
+0x05 KEY_RIGHT_UP
+0x06 KEY_RIGHT_DOWN
+0x07 KEY_LEFT_UP
+0x08 KEY_LEFT_DOWN
+0x09 KEY_CONTEXT_MENU
+0x0a KEY_SETUP
+0x0b KEY_MENU
+0x0c KEY_FAVORITES
+0x0d KEY_EXIT
+0x20 KEY_NUMERIC_0
+0x21 KEY_NUMERIC_1
+0x22 KEY_NUMERIC_2
+0x23 KEY_NUMERIC_3
+0x24 KEY_NUMERIC_4
+0x25 KEY_NUMERIC_5
+0x26 KEY_NUMERIC_6
+0x27 KEY_NUMERIC_7
+0x28 KEY_NUMERIC_8
+0x29 KEY_NUMERIC_9
+0x2a KEY_DOT
+0x2b KEY_ENTER
+0x2c KEY_CLEAR
+0x2f KEY_NEXT_FAVORITE
+0x30 KEY_CHANNELUP
+0x31 KEY_CHANNELDOWN
+0x32 KEY_PREVIOUS
+0x33 KEY_SOUND
+0x34 KEY_VIDEO
+0x35 KEY_INFO
+0x36 KEY_HELP
+0x37 KEY_PAGEUP
+0x38 KEY_PAGEDOWN
+0x40 KEY_POWER
+0x41 KEY_VOLUMEUP
+0x42 KEY_VOLUMEDOWN
+0x43 KEY_MUTE
+0x44 KEY_PLAY
+0x45 KEY_STOP
+0x46 KEY_PAUSE
+0x47 KEY_RECORD
+0x48 KEY_REWIND
+0x49 KEY_FASTFORWARD
+0x4a KEY_EJECTCD
+0x4b KEY_FORWARD
+0x4c KEY_BACK
+0x4d KEY_STOP_RECORD
+0x4e KEY_PAUSE_RECORD
+0x50 KEY_ANGLE
+0x51 KEY_TV2
+0x52 KEY_VOD
+0x53 KEY_EPG
+0x54 KEY_TIME
+0x55 KEY_CONFIG
+0x60 KEY_PLAY
+0x6024 KEY_PLAY
+0x6020 KEY_PAUSE
+0x61 KEY_PLAYPAUSE
+0x62 KEY_RECORD
+0x63 KEY_PAUSE
+0x64 KEY_STOP
+0x65 KEY_MUTE
+0x66 KEY_UNMUTE
+0x6b KEY_POWER
+0x6c KEY_SLEEP
+0x6d KEY_WAKEUP
+0x71 KEY_BLUE
+0x72 KEY_RED
+0x73 KEY_GREEN
+0x74 KEY_YELLOW
+0x75 KEY_F5
+0x76 KEY_DVB
new file mode 100644
@@ -0,0 +1,34 @@
+# table technisat_ts35, type: UNKNOWN
+0x32 KEY_MUTE
+0x07 KEY_MEDIA
+0x1c KEY_AB
+0x33 KEY_POWER
+0x3e KEY_1
+0x3d KEY_2
+0x3c KEY_3
+0x3b KEY_4
+0x3a KEY_5
+0x39 KEY_6
+0x38 KEY_7
+0x37 KEY_8
+0x36 KEY_9
+0x3f KEY_0
+0x35 KEY_DIGITS
+0x2c KEY_TV
+0x20 KEY_INFO
+0x2d KEY_MENU
+0x1f KEY_UP
+0x1e KEY_DOWN
+0x2e KEY_LEFT
+0x2f KEY_RIGHT
+0x28 KEY_OK
+0x10 KEY_EPG
+0x1d KEY_BACK
+0x14 KEY_RED
+0x13 KEY_GREEN
+0x12 KEY_YELLOW
+0x11 KEY_BLUE
+0x09 KEY_SELECT
+0x03 KEY_TEXT
+0x16 KEY_STOP
+0x30 KEY_HELP
new file mode 100644
@@ -0,0 +1,49 @@
+# table terratec_cinergy_c_pci, type: UNKNOWN
+0x3e KEY_POWER
+0x3d KEY_1
+0x3c KEY_2
+0x3b KEY_3
+0x3a KEY_4
+0x39 KEY_5
+0x38 KEY_6
+0x37 KEY_7
+0x36 KEY_8
+0x35 KEY_9
+0x34 KEY_VIDEO_NEXT
+0x33 KEY_0
+0x32 KEY_REFRESH
+0x30 KEY_EPG
+0x2f KEY_UP
+0x2e KEY_LEFT
+0x2d KEY_OK
+0x2c KEY_RIGHT
+0x2b KEY_DOWN
+0x29 KEY_INFO
+0x28 KEY_RED
+0x27 KEY_GREEN
+0x26 KEY_YELLOW
+0x25 KEY_BLUE
+0x24 KEY_CHANNELUP
+0x23 KEY_VOLUMEUP
+0x22 KEY_MUTE
+0x21 KEY_VOLUMEDOWN
+0x20 KEY_CHANNELDOWN
+0x1f KEY_PAUSE
+0x1e KEY_HOME
+0x1d KEY_MENU
+0x1c KEY_SUBTITLE
+0x1b KEY_TEXT
+0x1a KEY_DELETE
+0x19 KEY_TV
+0x18 KEY_DVD
+0x17 KEY_STOP
+0x16 KEY_VIDEO
+0x15 KEY_AUDIO
+0x14 KEY_SCREEN
+0x13 KEY_PLAY
+0x12 KEY_BACK
+0x11 KEY_REWIND
+0x10 KEY_FASTFORWARD
+0x0b KEY_PREVIOUS
+0x07 KEY_RECORD
+0x03 KEY_NEXT
new file mode 100644
@@ -0,0 +1,49 @@
+# table terratec_cinergy_s2_hd, type: UNKNOWN
+0x03 KEY_NEXT
+0x07 KEY_RECORD
+0x0b KEY_PREVIOUS
+0x10 KEY_FASTFORWARD
+0x11 KEY_REWIND
+0x12 KEY_ESC
+0x13 KEY_PLAY
+0x14 KEY_IMAGES
+0x15 KEY_AUDIO
+0x16 KEY_MEDIA
+0x17 KEY_STOP
+0x18 KEY_DVD
+0x19 KEY_TV
+0x1a KEY_DELETE
+0x1b KEY_TEXT
+0x1c KEY_SUBTITLE
+0x1d KEY_MENU
+0x1e KEY_HOME
+0x1f KEY_PAUSE
+0x20 KEY_CHANNELDOWN
+0x21 KEY_VOLUMEDOWN
+0x22 KEY_MUTE
+0x23 KEY_VOLUMEUP
+0x24 KEY_CHANNELUP
+0x25 KEY_BLUE
+0x26 KEY_YELLOW
+0x27 KEY_GREEN
+0x28 KEY_RED
+0x29 KEY_INFO
+0x2b KEY_DOWN
+0x2c KEY_RIGHT
+0x2d KEY_OK
+0x2e KEY_LEFT
+0x2f KEY_UP
+0x30 KEY_EPG
+0x32 KEY_VIDEO
+0x33 KEY_0
+0x34 KEY_VCR
+0x35 KEY_9
+0x36 KEY_8
+0x37 KEY_7
+0x38 KEY_6
+0x39 KEY_5
+0x3a KEY_4
+0x3b KEY_3
+0x3c KEY_2
+0x3d KEY_1
+0x3e KEY_POWER
new file mode 100644
@@ -0,0 +1,54 @@
+# table twinhan_dtv_cab_ci, type: UNKNOWN
+0x29 KEY_POWER
+0x28 KEY_FAVORITES
+0x30 KEY_TEXT
+0x17 KEY_INFO
+0x23 KEY_EPG
+0x3b KEY_F22
+0x3c KEY_1
+0x3e KEY_2
+0x39 KEY_3
+0x36 KEY_4
+0x22 KEY_5
+0x20 KEY_6
+0x32 KEY_7
+0x26 KEY_8
+0x24 KEY_9
+0x2a KEY_0
+0x33 KEY_CANCEL
+0x2c KEY_BACK
+0x15 KEY_CLEAR
+0x3f KEY_TAB
+0x10 KEY_ENTER
+0x14 KEY_UP
+0x0d KEY_RIGHT
+0x0e KEY_DOWN
+0x11 KEY_LEFT
+0x21 KEY_VOLUMEUP
+0x35 KEY_VOLUMEDOWN
+0x3d KEY_CHANNELDOWN
+0x3a KEY_CHANNELUP
+0x2e KEY_RECORD
+0x2b KEY_PLAY
+0x13 KEY_PAUSE
+0x25 KEY_STOP
+0x1f KEY_REWIND
+0x2d KEY_FASTFORWARD
+0x1e KEY_PREVIOUS
+0x1d KEY_NEXT
+0x0b KEY_CAMERA
+0x0f KEY_LANGUAGE
+0x18 KEY_MODE
+0x12 KEY_ZOOM
+0x1c KEY_SUBTITLE
+0x2f KEY_MUTE
+0x16 KEY_F20
+0x38 KEY_F21
+0x37 KEY_SWITCHVIDEOMODE
+0x31 KEY_AGAIN
+0x1a KEY_KPPLUS
+0x19 KEY_KPMINUS
+0x27 KEY_RED
+0x0C KEY_GREEN
+0x01 KEY_YELLOW
+0x00 KEY_BLUE
@@ -50,6 +50,7 @@
* rc-behold-columbus behold_columbus
* rc-behold behold
* rc-budget-ci-old budget_ci_old
+* rc-cec cec
* rc-cinergy-1400 cinergy_1400
* rc-cinergy cinergy
* rc-delock-61959 delock_61959