/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) *//* * cec - HDMI Consumer Electronics Control message functions * * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. */ #ifndef _CEC_UAPI_FUNCS_H#define _CEC_UAPI_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, int 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, int 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, int reply){ msg->len = 2; msg->msg[1] = CEC_MSG_RECORD_OFF; msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;} 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, int reply, 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; } msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;} 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, int 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(const 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(const 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, int 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(const 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, int 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;Lines 1–500 of 1942. Load more
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * cec - HDMI Consumer Electronics Control message functions * * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. */ #ifndef _CEC_UAPI_FUNCS_H #define _CEC_UAPI_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, int 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, int 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, int reply) { msg->len = 2; msg->msg[1] = CEC_MSG_RECORD_OFF; msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; } 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, int reply, 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; } msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0; } 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, int 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(const 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(const 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, int 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(const 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, int 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;