brintos

brintos / linux-shallow public Read only

0
0
Text · 52.5 KiB · d58fa1c Raw
1959 lines · c
1/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */2/*3 * cec - HDMI Consumer Electronics Control message functions4 *5 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.6 */7 8#ifndef _CEC_UAPI_FUNCS_H9#define _CEC_UAPI_FUNCS_H10 11#include <linux/cec.h>12 13/* One Touch Play Feature */14static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr)15{16	msg->len = 4;17	msg->msg[0] |= 0xf; /* broadcast */18	msg->msg[1] = CEC_MSG_ACTIVE_SOURCE;19	msg->msg[2] = phys_addr >> 8;20	msg->msg[3] = phys_addr & 0xff;21}22 23static inline void cec_ops_active_source(const struct cec_msg *msg,24					 __u16 *phys_addr)25{26	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];27}28 29static inline void cec_msg_image_view_on(struct cec_msg *msg)30{31	msg->len = 2;32	msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON;33}34 35static inline void cec_msg_text_view_on(struct cec_msg *msg)36{37	msg->len = 2;38	msg->msg[1] = CEC_MSG_TEXT_VIEW_ON;39}40 41 42/* Routing Control Feature */43static inline void cec_msg_inactive_source(struct cec_msg *msg,44					   __u16 phys_addr)45{46	msg->len = 4;47	msg->msg[1] = CEC_MSG_INACTIVE_SOURCE;48	msg->msg[2] = phys_addr >> 8;49	msg->msg[3] = phys_addr & 0xff;50}51 52static inline void cec_ops_inactive_source(const struct cec_msg *msg,53					   __u16 *phys_addr)54{55	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];56}57 58static inline void cec_msg_request_active_source(struct cec_msg *msg,59						 int reply)60{61	msg->len = 2;62	msg->msg[0] |= 0xf; /* broadcast */63	msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE;64	msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0;65}66 67static inline void cec_msg_routing_information(struct cec_msg *msg,68					       __u16 phys_addr)69{70	msg->len = 4;71	msg->msg[0] |= 0xf; /* broadcast */72	msg->msg[1] = CEC_MSG_ROUTING_INFORMATION;73	msg->msg[2] = phys_addr >> 8;74	msg->msg[3] = phys_addr & 0xff;75}76 77static inline void cec_ops_routing_information(const struct cec_msg *msg,78					       __u16 *phys_addr)79{80	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];81}82 83static inline void cec_msg_routing_change(struct cec_msg *msg,84					  int reply,85					  __u16 orig_phys_addr,86					  __u16 new_phys_addr)87{88	msg->len = 6;89	msg->msg[0] |= 0xf; /* broadcast */90	msg->msg[1] = CEC_MSG_ROUTING_CHANGE;91	msg->msg[2] = orig_phys_addr >> 8;92	msg->msg[3] = orig_phys_addr & 0xff;93	msg->msg[4] = new_phys_addr >> 8;94	msg->msg[5] = new_phys_addr & 0xff;95	msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0;96}97 98static inline void cec_ops_routing_change(const struct cec_msg *msg,99					  __u16 *orig_phys_addr,100					  __u16 *new_phys_addr)101{102	*orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3];103	*new_phys_addr = (msg->msg[4] << 8) | msg->msg[5];104}105 106static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr)107{108	msg->len = 4;109	msg->msg[0] |= 0xf; /* broadcast */110	msg->msg[1] = CEC_MSG_SET_STREAM_PATH;111	msg->msg[2] = phys_addr >> 8;112	msg->msg[3] = phys_addr & 0xff;113}114 115static inline void cec_ops_set_stream_path(const struct cec_msg *msg,116					   __u16 *phys_addr)117{118	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];119}120 121 122/* Standby Feature */123static inline void cec_msg_standby(struct cec_msg *msg)124{125	msg->len = 2;126	msg->msg[1] = CEC_MSG_STANDBY;127}128 129 130/* One Touch Record Feature */131static inline void cec_msg_record_off(struct cec_msg *msg, int reply)132{133	msg->len = 2;134	msg->msg[1] = CEC_MSG_RECORD_OFF;135	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;136}137 138struct cec_op_arib_data {139	__u16 transport_id;140	__u16 service_id;141	__u16 orig_network_id;142};143 144struct cec_op_atsc_data {145	__u16 transport_id;146	__u16 program_number;147};148 149struct cec_op_dvb_data {150	__u16 transport_id;151	__u16 service_id;152	__u16 orig_network_id;153};154 155struct cec_op_channel_data {156	__u8 channel_number_fmt;157	__u16 major;158	__u16 minor;159};160 161struct cec_op_digital_service_id {162	__u8 service_id_method;163	__u8 dig_bcast_system;164	union {165		struct cec_op_arib_data arib;166		struct cec_op_atsc_data atsc;167		struct cec_op_dvb_data dvb;168		struct cec_op_channel_data channel;169	};170};171 172struct cec_op_record_src {173	__u8 type;174	union {175		struct cec_op_digital_service_id digital;176		struct {177			__u8 ana_bcast_type;178			__u16 ana_freq;179			__u8 bcast_system;180		} analog;181		struct {182			__u8 plug;183		} ext_plug;184		struct {185			__u16 phys_addr;186		} ext_phys_addr;187	};188};189 190static inline void cec_set_digital_service_id(__u8 *msg,191	      const struct cec_op_digital_service_id *digital)192{193	*msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system;194	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {195		*msg++ = (digital->channel.channel_number_fmt << 2) |196			 (digital->channel.major >> 8);197		*msg++ = digital->channel.major & 0xff;198		*msg++ = digital->channel.minor >> 8;199		*msg++ = digital->channel.minor & 0xff;200		*msg++ = 0;201		*msg++ = 0;202		return;203	}204	switch (digital->dig_bcast_system) {205	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:206	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:207	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:208	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:209		*msg++ = digital->atsc.transport_id >> 8;210		*msg++ = digital->atsc.transport_id & 0xff;211		*msg++ = digital->atsc.program_number >> 8;212		*msg++ = digital->atsc.program_number & 0xff;213		*msg++ = 0;214		*msg++ = 0;215		break;216	default:217		*msg++ = digital->dvb.transport_id >> 8;218		*msg++ = digital->dvb.transport_id & 0xff;219		*msg++ = digital->dvb.service_id >> 8;220		*msg++ = digital->dvb.service_id & 0xff;221		*msg++ = digital->dvb.orig_network_id >> 8;222		*msg++ = digital->dvb.orig_network_id & 0xff;223		break;224	}225}226 227static inline void cec_get_digital_service_id(const __u8 *msg,228	      struct cec_op_digital_service_id *digital)229{230	digital->service_id_method = msg[0] >> 7;231	digital->dig_bcast_system = msg[0] & 0x7f;232	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {233		digital->channel.channel_number_fmt = msg[1] >> 2;234		digital->channel.major = ((msg[1] & 3) << 6) | msg[2];235		digital->channel.minor = (msg[3] << 8) | msg[4];236		return;237	}238	digital->dvb.transport_id = (msg[1] << 8) | msg[2];239	digital->dvb.service_id = (msg[3] << 8) | msg[4];240	digital->dvb.orig_network_id = (msg[5] << 8) | msg[6];241}242 243static inline void cec_msg_record_on_own(struct cec_msg *msg)244{245	msg->len = 3;246	msg->msg[1] = CEC_MSG_RECORD_ON;247	msg->msg[2] = CEC_OP_RECORD_SRC_OWN;248}249 250static inline void cec_msg_record_on_digital(struct cec_msg *msg,251			     const struct cec_op_digital_service_id *digital)252{253	msg->len = 10;254	msg->msg[1] = CEC_MSG_RECORD_ON;255	msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL;256	cec_set_digital_service_id(msg->msg + 3, digital);257}258 259static inline void cec_msg_record_on_analog(struct cec_msg *msg,260					    __u8 ana_bcast_type,261					    __u16 ana_freq,262					    __u8 bcast_system)263{264	msg->len = 7;265	msg->msg[1] = CEC_MSG_RECORD_ON;266	msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG;267	msg->msg[3] = ana_bcast_type;268	msg->msg[4] = ana_freq >> 8;269	msg->msg[5] = ana_freq & 0xff;270	msg->msg[6] = bcast_system;271}272 273static inline void cec_msg_record_on_plug(struct cec_msg *msg,274					  __u8 plug)275{276	msg->len = 4;277	msg->msg[1] = CEC_MSG_RECORD_ON;278	msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG;279	msg->msg[3] = plug;280}281 282static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg,283					       __u16 phys_addr)284{285	msg->len = 5;286	msg->msg[1] = CEC_MSG_RECORD_ON;287	msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR;288	msg->msg[3] = phys_addr >> 8;289	msg->msg[4] = phys_addr & 0xff;290}291 292static inline void cec_msg_record_on(struct cec_msg *msg,293				     int reply,294				     const struct cec_op_record_src *rec_src)295{296	switch (rec_src->type) {297	case CEC_OP_RECORD_SRC_OWN:298		cec_msg_record_on_own(msg);299		break;300	case CEC_OP_RECORD_SRC_DIGITAL:301		cec_msg_record_on_digital(msg, &rec_src->digital);302		break;303	case CEC_OP_RECORD_SRC_ANALOG:304		cec_msg_record_on_analog(msg,305					 rec_src->analog.ana_bcast_type,306					 rec_src->analog.ana_freq,307					 rec_src->analog.bcast_system);308		break;309	case CEC_OP_RECORD_SRC_EXT_PLUG:310		cec_msg_record_on_plug(msg, rec_src->ext_plug.plug);311		break;312	case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:313		cec_msg_record_on_phys_addr(msg,314					    rec_src->ext_phys_addr.phys_addr);315		break;316	}317	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;318}319 320static inline void cec_ops_record_on(const struct cec_msg *msg,321				     struct cec_op_record_src *rec_src)322{323	rec_src->type = msg->msg[2];324	switch (rec_src->type) {325	case CEC_OP_RECORD_SRC_OWN:326		break;327	case CEC_OP_RECORD_SRC_DIGITAL:328		cec_get_digital_service_id(msg->msg + 3, &rec_src->digital);329		break;330	case CEC_OP_RECORD_SRC_ANALOG:331		rec_src->analog.ana_bcast_type = msg->msg[3];332		rec_src->analog.ana_freq =333			(msg->msg[4] << 8) | msg->msg[5];334		rec_src->analog.bcast_system = msg->msg[6];335		break;336	case CEC_OP_RECORD_SRC_EXT_PLUG:337		rec_src->ext_plug.plug = msg->msg[3];338		break;339	case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:340		rec_src->ext_phys_addr.phys_addr =341			(msg->msg[3] << 8) | msg->msg[4];342		break;343	}344}345 346static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status)347{348	msg->len = 3;349	msg->msg[1] = CEC_MSG_RECORD_STATUS;350	msg->msg[2] = rec_status;351}352 353static inline void cec_ops_record_status(const struct cec_msg *msg,354					 __u8 *rec_status)355{356	*rec_status = msg->msg[2];357}358 359static inline void cec_msg_record_tv_screen(struct cec_msg *msg,360					    int reply)361{362	msg->len = 2;363	msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN;364	msg->reply = reply ? CEC_MSG_RECORD_ON : 0;365}366 367 368/* Timer Programming Feature */369static inline void cec_msg_timer_status(struct cec_msg *msg,370					__u8 timer_overlap_warning,371					__u8 media_info,372					__u8 prog_info,373					__u8 prog_error,374					__u8 duration_hr,375					__u8 duration_min)376{377	msg->len = 3;378	msg->msg[1] = CEC_MSG_TIMER_STATUS;379	msg->msg[2] = (timer_overlap_warning << 7) |380		(media_info << 5) |381		(prog_info ? 0x10 : 0) |382		(prog_info ? prog_info : prog_error);383	if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||384	    prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||385	    prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {386		msg->len += 2;387		msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10);388		msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10);389	}390}391 392static inline void cec_ops_timer_status(const struct cec_msg *msg,393					__u8 *timer_overlap_warning,394					__u8 *media_info,395					__u8 *prog_info,396					__u8 *prog_error,397					__u8 *duration_hr,398					__u8 *duration_min)399{400	*timer_overlap_warning = msg->msg[2] >> 7;401	*media_info = (msg->msg[2] >> 5) & 3;402	if (msg->msg[2] & 0x10) {403		*prog_info = msg->msg[2] & 0xf;404		*prog_error = 0;405	} else {406		*prog_info = 0;407		*prog_error = msg->msg[2] & 0xf;408	}409	if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||410	    *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||411	    *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {412		*duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf);413		*duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);414	} else {415		*duration_hr = *duration_min = 0;416	}417}418 419static inline void cec_msg_timer_cleared_status(struct cec_msg *msg,420						__u8 timer_cleared_status)421{422	msg->len = 3;423	msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS;424	msg->msg[2] = timer_cleared_status;425}426 427static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg,428						__u8 *timer_cleared_status)429{430	*timer_cleared_status = msg->msg[2];431}432 433static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg,434						int reply,435						__u8 day,436						__u8 month,437						__u8 start_hr,438						__u8 start_min,439						__u8 duration_hr,440						__u8 duration_min,441						__u8 recording_seq,442						__u8 ana_bcast_type,443						__u16 ana_freq,444						__u8 bcast_system)445{446	msg->len = 13;447	msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER;448	msg->msg[2] = day;449	msg->msg[3] = month;450	/* Hours and minutes are in BCD format */451	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);452	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);453	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);454	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);455	msg->msg[8] = recording_seq;456	msg->msg[9] = ana_bcast_type;457	msg->msg[10] = ana_freq >> 8;458	msg->msg[11] = ana_freq & 0xff;459	msg->msg[12] = bcast_system;460	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;461}462 463static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg,464						__u8 *day,465						__u8 *month,466						__u8 *start_hr,467						__u8 *start_min,468						__u8 *duration_hr,469						__u8 *duration_min,470						__u8 *recording_seq,471						__u8 *ana_bcast_type,472						__u16 *ana_freq,473						__u8 *bcast_system)474{475	*day = msg->msg[2];476	*month = msg->msg[3];477	/* Hours and minutes are in BCD format */478	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);479	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);480	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);481	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);482	*recording_seq = msg->msg[8];483	*ana_bcast_type = msg->msg[9];484	*ana_freq = (msg->msg[10] << 8) | msg->msg[11];485	*bcast_system = msg->msg[12];486}487 488static inline void cec_msg_clear_digital_timer(struct cec_msg *msg,489				int reply,490				__u8 day,491				__u8 month,492				__u8 start_hr,493				__u8 start_min,494				__u8 duration_hr,495				__u8 duration_min,496				__u8 recording_seq,497				const struct cec_op_digital_service_id *digital)498{499	msg->len = 16;500	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;501	msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER;502	msg->msg[2] = day;503	msg->msg[3] = month;504	/* Hours and minutes are in BCD format */505	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);506	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);507	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);508	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);509	msg->msg[8] = recording_seq;510	cec_set_digital_service_id(msg->msg + 9, digital);511}512 513static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg,514				__u8 *day,515				__u8 *month,516				__u8 *start_hr,517				__u8 *start_min,518				__u8 *duration_hr,519				__u8 *duration_min,520				__u8 *recording_seq,521				struct cec_op_digital_service_id *digital)522{523	*day = msg->msg[2];524	*month = msg->msg[3];525	/* Hours and minutes are in BCD format */526	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);527	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);528	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);529	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);530	*recording_seq = msg->msg[8];531	cec_get_digital_service_id(msg->msg + 9, digital);532}533 534static inline void cec_msg_clear_ext_timer(struct cec_msg *msg,535					   int reply,536					   __u8 day,537					   __u8 month,538					   __u8 start_hr,539					   __u8 start_min,540					   __u8 duration_hr,541					   __u8 duration_min,542					   __u8 recording_seq,543					   __u8 ext_src_spec,544					   __u8 plug,545					   __u16 phys_addr)546{547	msg->len = 13;548	msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER;549	msg->msg[2] = day;550	msg->msg[3] = month;551	/* Hours and minutes are in BCD format */552	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);553	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);554	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);555	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);556	msg->msg[8] = recording_seq;557	msg->msg[9] = ext_src_spec;558	msg->msg[10] = plug;559	msg->msg[11] = phys_addr >> 8;560	msg->msg[12] = phys_addr & 0xff;561	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;562}563 564static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg,565					   __u8 *day,566					   __u8 *month,567					   __u8 *start_hr,568					   __u8 *start_min,569					   __u8 *duration_hr,570					   __u8 *duration_min,571					   __u8 *recording_seq,572					   __u8 *ext_src_spec,573					   __u8 *plug,574					   __u16 *phys_addr)575{576	*day = msg->msg[2];577	*month = msg->msg[3];578	/* Hours and minutes are in BCD format */579	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);580	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);581	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);582	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);583	*recording_seq = msg->msg[8];584	*ext_src_spec = msg->msg[9];585	*plug = msg->msg[10];586	*phys_addr = (msg->msg[11] << 8) | msg->msg[12];587}588 589static inline void cec_msg_set_analogue_timer(struct cec_msg *msg,590					      int reply,591					      __u8 day,592					      __u8 month,593					      __u8 start_hr,594					      __u8 start_min,595					      __u8 duration_hr,596					      __u8 duration_min,597					      __u8 recording_seq,598					      __u8 ana_bcast_type,599					      __u16 ana_freq,600					      __u8 bcast_system)601{602	msg->len = 13;603	msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER;604	msg->msg[2] = day;605	msg->msg[3] = month;606	/* Hours and minutes are in BCD format */607	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);608	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);609	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);610	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);611	msg->msg[8] = recording_seq;612	msg->msg[9] = ana_bcast_type;613	msg->msg[10] = ana_freq >> 8;614	msg->msg[11] = ana_freq & 0xff;615	msg->msg[12] = bcast_system;616	msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;617}618 619static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg,620					      __u8 *day,621					      __u8 *month,622					      __u8 *start_hr,623					      __u8 *start_min,624					      __u8 *duration_hr,625					      __u8 *duration_min,626					      __u8 *recording_seq,627					      __u8 *ana_bcast_type,628					      __u16 *ana_freq,629					      __u8 *bcast_system)630{631	*day = msg->msg[2];632	*month = msg->msg[3];633	/* Hours and minutes are in BCD format */634	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);635	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);636	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);637	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);638	*recording_seq = msg->msg[8];639	*ana_bcast_type = msg->msg[9];640	*ana_freq = (msg->msg[10] << 8) | msg->msg[11];641	*bcast_system = msg->msg[12];642}643 644static inline void cec_msg_set_digital_timer(struct cec_msg *msg,645			int reply,646			__u8 day,647			__u8 month,648			__u8 start_hr,649			__u8 start_min,650			__u8 duration_hr,651			__u8 duration_min,652			__u8 recording_seq,653			const struct cec_op_digital_service_id *digital)654{655	msg->len = 16;656	msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;657	msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER;658	msg->msg[2] = day;659	msg->msg[3] = month;660	/* Hours and minutes are in BCD format */661	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);662	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);663	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);664	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);665	msg->msg[8] = recording_seq;666	cec_set_digital_service_id(msg->msg + 9, digital);667}668 669static inline void cec_ops_set_digital_timer(const struct cec_msg *msg,670			__u8 *day,671			__u8 *month,672			__u8 *start_hr,673			__u8 *start_min,674			__u8 *duration_hr,675			__u8 *duration_min,676			__u8 *recording_seq,677			struct cec_op_digital_service_id *digital)678{679	*day = msg->msg[2];680	*month = msg->msg[3];681	/* Hours and minutes are in BCD format */682	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);683	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);684	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);685	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);686	*recording_seq = msg->msg[8];687	cec_get_digital_service_id(msg->msg + 9, digital);688}689 690static inline void cec_msg_set_ext_timer(struct cec_msg *msg,691					 int reply,692					 __u8 day,693					 __u8 month,694					 __u8 start_hr,695					 __u8 start_min,696					 __u8 duration_hr,697					 __u8 duration_min,698					 __u8 recording_seq,699					 __u8 ext_src_spec,700					 __u8 plug,701					 __u16 phys_addr)702{703	msg->len = 13;704	msg->msg[1] = CEC_MSG_SET_EXT_TIMER;705	msg->msg[2] = day;706	msg->msg[3] = month;707	/* Hours and minutes are in BCD format */708	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);709	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);710	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);711	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);712	msg->msg[8] = recording_seq;713	msg->msg[9] = ext_src_spec;714	msg->msg[10] = plug;715	msg->msg[11] = phys_addr >> 8;716	msg->msg[12] = phys_addr & 0xff;717	msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;718}719 720static inline void cec_ops_set_ext_timer(const struct cec_msg *msg,721					 __u8 *day,722					 __u8 *month,723					 __u8 *start_hr,724					 __u8 *start_min,725					 __u8 *duration_hr,726					 __u8 *duration_min,727					 __u8 *recording_seq,728					 __u8 *ext_src_spec,729					 __u8 *plug,730					 __u16 *phys_addr)731{732	*day = msg->msg[2];733	*month = msg->msg[3];734	/* Hours and minutes are in BCD format */735	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);736	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);737	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);738	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);739	*recording_seq = msg->msg[8];740	*ext_src_spec = msg->msg[9];741	*plug = msg->msg[10];742	*phys_addr = (msg->msg[11] << 8) | msg->msg[12];743}744 745static inline void cec_msg_set_timer_program_title(struct cec_msg *msg,746						   const char *prog_title)747{748	unsigned int len = strlen(prog_title);749 750	if (len > 14)751		len = 14;752	msg->len = 2 + len;753	msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE;754	memcpy(msg->msg + 2, prog_title, len);755}756 757static inline void cec_ops_set_timer_program_title(const struct cec_msg *msg,758						   char *prog_title)759{760	unsigned int len = msg->len > 2 ? msg->len - 2 : 0;761 762	if (len > 14)763		len = 14;764	memcpy(prog_title, msg->msg + 2, len);765	prog_title[len] = '\0';766}767 768/* System Information Feature */769static inline void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version)770{771	msg->len = 3;772	msg->msg[1] = CEC_MSG_CEC_VERSION;773	msg->msg[2] = cec_version;774}775 776static inline void cec_ops_cec_version(const struct cec_msg *msg,777				       __u8 *cec_version)778{779	*cec_version = msg->msg[2];780}781 782static inline void cec_msg_get_cec_version(struct cec_msg *msg,783					   int reply)784{785	msg->len = 2;786	msg->msg[1] = CEC_MSG_GET_CEC_VERSION;787	msg->reply = reply ? CEC_MSG_CEC_VERSION : 0;788}789 790static inline void cec_msg_report_physical_addr(struct cec_msg *msg,791					__u16 phys_addr, __u8 prim_devtype)792{793	msg->len = 5;794	msg->msg[0] |= 0xf; /* broadcast */795	msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR;796	msg->msg[2] = phys_addr >> 8;797	msg->msg[3] = phys_addr & 0xff;798	msg->msg[4] = prim_devtype;799}800 801static inline void cec_ops_report_physical_addr(const struct cec_msg *msg,802					__u16 *phys_addr, __u8 *prim_devtype)803{804	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];805	*prim_devtype = msg->msg[4];806}807 808static inline void cec_msg_give_physical_addr(struct cec_msg *msg,809					      int reply)810{811	msg->len = 2;812	msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR;813	msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0;814}815 816static inline void cec_msg_set_menu_language(struct cec_msg *msg,817					     const char *language)818{819	msg->len = 5;820	msg->msg[0] |= 0xf; /* broadcast */821	msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE;822	memcpy(msg->msg + 2, language, 3);823}824 825static inline void cec_ops_set_menu_language(const struct cec_msg *msg,826					     char *language)827{828	memcpy(language, msg->msg + 2, 3);829	language[3] = '\0';830}831 832static inline void cec_msg_get_menu_language(struct cec_msg *msg,833					     int reply)834{835	msg->len = 2;836	msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE;837	msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0;838}839 840/*841 * Assumes a single RC Profile byte and a single Device Features byte,842 * i.e. no extended features are supported by this helper function.843 *844 * As of CEC 2.0 no extended features are defined, should those be added845 * in the future, then this function needs to be adapted or a new function846 * should be added.847 */848static inline void cec_msg_report_features(struct cec_msg *msg,849				__u8 cec_version, __u8 all_device_types,850				__u8 rc_profile, __u8 dev_features)851{852	msg->len = 6;853	msg->msg[0] |= 0xf; /* broadcast */854	msg->msg[1] = CEC_MSG_REPORT_FEATURES;855	msg->msg[2] = cec_version;856	msg->msg[3] = all_device_types;857	msg->msg[4] = rc_profile;858	msg->msg[5] = dev_features;859}860 861static inline void cec_ops_report_features(const struct cec_msg *msg,862			__u8 *cec_version, __u8 *all_device_types,863			const __u8 **rc_profile, const __u8 **dev_features)864{865	const __u8 *p = &msg->msg[4];866 867	*cec_version = msg->msg[2];868	*all_device_types = msg->msg[3];869	*rc_profile = p;870	*dev_features = NULL;871	while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT))872		p++;873	if (!(*p & CEC_OP_FEAT_EXT)) {874		*dev_features = p + 1;875		while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT))876			p++;877	}878	if (*p & CEC_OP_FEAT_EXT)879		*rc_profile = *dev_features = NULL;880}881 882static inline void cec_msg_give_features(struct cec_msg *msg,883					 int reply)884{885	msg->len = 2;886	msg->msg[1] = CEC_MSG_GIVE_FEATURES;887	msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0;888}889 890/* Deck Control Feature */891static inline void cec_msg_deck_control(struct cec_msg *msg,892					__u8 deck_control_mode)893{894	msg->len = 3;895	msg->msg[1] = CEC_MSG_DECK_CONTROL;896	msg->msg[2] = deck_control_mode;897}898 899static inline void cec_ops_deck_control(const struct cec_msg *msg,900					__u8 *deck_control_mode)901{902	*deck_control_mode = msg->msg[2];903}904 905static inline void cec_msg_deck_status(struct cec_msg *msg,906				       __u8 deck_info)907{908	msg->len = 3;909	msg->msg[1] = CEC_MSG_DECK_STATUS;910	msg->msg[2] = deck_info;911}912 913static inline void cec_ops_deck_status(const struct cec_msg *msg,914				       __u8 *deck_info)915{916	*deck_info = msg->msg[2];917}918 919static inline void cec_msg_give_deck_status(struct cec_msg *msg,920					    int reply,921					    __u8 status_req)922{923	msg->len = 3;924	msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS;925	msg->msg[2] = status_req;926	msg->reply = (reply && status_req != CEC_OP_STATUS_REQ_OFF) ?927				CEC_MSG_DECK_STATUS : 0;928}929 930static inline void cec_ops_give_deck_status(const struct cec_msg *msg,931					    __u8 *status_req)932{933	*status_req = msg->msg[2];934}935 936static inline void cec_msg_play(struct cec_msg *msg,937				__u8 play_mode)938{939	msg->len = 3;940	msg->msg[1] = CEC_MSG_PLAY;941	msg->msg[2] = play_mode;942}943 944static inline void cec_ops_play(const struct cec_msg *msg,945				__u8 *play_mode)946{947	*play_mode = msg->msg[2];948}949 950 951/* Tuner Control Feature */952struct cec_op_tuner_device_info {953	__u8 rec_flag;954	__u8 tuner_display_info;955	__u8 is_analog;956	union {957		struct cec_op_digital_service_id digital;958		struct {959			__u8 ana_bcast_type;960			__u16 ana_freq;961			__u8 bcast_system;962		} analog;963	};964};965 966static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg,967						      __u8 rec_flag,968						      __u8 tuner_display_info,969						      __u8 ana_bcast_type,970						      __u16 ana_freq,971						      __u8 bcast_system)972{973	msg->len = 7;974	msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;975	msg->msg[2] = (rec_flag << 7) | tuner_display_info;976	msg->msg[3] = ana_bcast_type;977	msg->msg[4] = ana_freq >> 8;978	msg->msg[5] = ana_freq & 0xff;979	msg->msg[6] = bcast_system;980}981 982static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg,983		   __u8 rec_flag, __u8 tuner_display_info,984		   const struct cec_op_digital_service_id *digital)985{986	msg->len = 10;987	msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;988	msg->msg[2] = (rec_flag << 7) | tuner_display_info;989	cec_set_digital_service_id(msg->msg + 3, digital);990}991 992static inline void cec_msg_tuner_device_status(struct cec_msg *msg,993			const struct cec_op_tuner_device_info *tuner_dev_info)994{995	if (tuner_dev_info->is_analog)996		cec_msg_tuner_device_status_analog(msg,997			tuner_dev_info->rec_flag,998			tuner_dev_info->tuner_display_info,999			tuner_dev_info->analog.ana_bcast_type,1000			tuner_dev_info->analog.ana_freq,1001			tuner_dev_info->analog.bcast_system);1002	else1003		cec_msg_tuner_device_status_digital(msg,1004			tuner_dev_info->rec_flag,1005			tuner_dev_info->tuner_display_info,1006			&tuner_dev_info->digital);1007}1008 1009static inline void cec_ops_tuner_device_status(const struct cec_msg *msg,1010				struct cec_op_tuner_device_info *tuner_dev_info)1011{1012	tuner_dev_info->is_analog = msg->len < 10;1013	tuner_dev_info->rec_flag = msg->msg[2] >> 7;1014	tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f;1015	if (tuner_dev_info->is_analog) {1016		tuner_dev_info->analog.ana_bcast_type = msg->msg[3];1017		tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5];1018		tuner_dev_info->analog.bcast_system = msg->msg[6];1019		return;1020	}1021	cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital);1022}1023 1024static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg,1025						    int reply,1026						    __u8 status_req)1027{1028	msg->len = 3;1029	msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS;1030	msg->msg[2] = status_req;1031	msg->reply = (reply && status_req != CEC_OP_STATUS_REQ_OFF) ?1032				CEC_MSG_TUNER_DEVICE_STATUS : 0;1033}1034 1035static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg,1036						    __u8 *status_req)1037{1038	*status_req = msg->msg[2];1039}1040 1041static inline void cec_msg_select_analogue_service(struct cec_msg *msg,1042						   __u8 ana_bcast_type,1043						   __u16 ana_freq,1044						   __u8 bcast_system)1045{1046	msg->len = 6;1047	msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE;1048	msg->msg[2] = ana_bcast_type;1049	msg->msg[3] = ana_freq >> 8;1050	msg->msg[4] = ana_freq & 0xff;1051	msg->msg[5] = bcast_system;1052}1053 1054static inline void cec_ops_select_analogue_service(const struct cec_msg *msg,1055						   __u8 *ana_bcast_type,1056						   __u16 *ana_freq,1057						   __u8 *bcast_system)1058{1059	*ana_bcast_type = msg->msg[2];1060	*ana_freq = (msg->msg[3] << 8) | msg->msg[4];1061	*bcast_system = msg->msg[5];1062}1063 1064static inline void cec_msg_select_digital_service(struct cec_msg *msg,1065				const struct cec_op_digital_service_id *digital)1066{1067	msg->len = 9;1068	msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE;1069	cec_set_digital_service_id(msg->msg + 2, digital);1070}1071 1072static inline void cec_ops_select_digital_service(const struct cec_msg *msg,1073				struct cec_op_digital_service_id *digital)1074{1075	cec_get_digital_service_id(msg->msg + 2, digital);1076}1077 1078static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg)1079{1080	msg->len = 2;1081	msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT;1082}1083 1084static inline void cec_msg_tuner_step_increment(struct cec_msg *msg)1085{1086	msg->len = 2;1087	msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT;1088}1089 1090 1091/* Vendor Specific Commands Feature */1092static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id)1093{1094	msg->len = 5;1095	msg->msg[0] |= 0xf; /* broadcast */1096	msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID;1097	msg->msg[2] = vendor_id >> 16;1098	msg->msg[3] = (vendor_id >> 8) & 0xff;1099	msg->msg[4] = vendor_id & 0xff;1100}1101 1102static inline void cec_ops_device_vendor_id(const struct cec_msg *msg,1103					    __u32 *vendor_id)1104{1105	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];1106}1107 1108static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg,1109						 int reply)1110{1111	msg->len = 2;1112	msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID;1113	msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0;1114}1115 1116static inline void cec_msg_vendor_command(struct cec_msg *msg,1117					  __u8 size, const __u8 *vendor_cmd)1118{1119	if (size > 14)1120		size = 14;1121	msg->len = 2 + size;1122	msg->msg[1] = CEC_MSG_VENDOR_COMMAND;1123	memcpy(msg->msg + 2, vendor_cmd, size);1124}1125 1126static inline void cec_ops_vendor_command(const struct cec_msg *msg,1127					  __u8 *size,1128					  const __u8 **vendor_cmd)1129{1130	*size = msg->len - 2;1131 1132	if (*size > 14)1133		*size = 14;1134	*vendor_cmd = msg->msg + 2;1135}1136 1137static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg,1138						  __u32 vendor_id, __u8 size,1139						  const __u8 *vendor_cmd)1140{1141	if (size > 11)1142		size = 11;1143	msg->len = 5 + size;1144	msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID;1145	msg->msg[2] = vendor_id >> 16;1146	msg->msg[3] = (vendor_id >> 8) & 0xff;1147	msg->msg[4] = vendor_id & 0xff;1148	memcpy(msg->msg + 5, vendor_cmd, size);1149}1150 1151static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg,1152						  __u32 *vendor_id,  __u8 *size,1153						  const __u8 **vendor_cmd)1154{1155	*size = msg->len - 5;1156 1157	if (*size > 11)1158		*size = 11;1159	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];1160	*vendor_cmd = msg->msg + 5;1161}1162 1163static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg,1164						     __u8 size,1165						     const __u8 *rc_code)1166{1167	if (size > 14)1168		size = 14;1169	msg->len = 2 + size;1170	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN;1171	memcpy(msg->msg + 2, rc_code, size);1172}1173 1174static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg,1175						     __u8 *size,1176						     const __u8 **rc_code)1177{1178	*size = msg->len - 2;1179 1180	if (*size > 14)1181		*size = 14;1182	*rc_code = msg->msg + 2;1183}1184 1185static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg)1186{1187	msg->len = 2;1188	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP;1189}1190 1191 1192/* OSD Display Feature */1193static inline void cec_msg_set_osd_string(struct cec_msg *msg,1194					  __u8 disp_ctl,1195					  const char *osd)1196{1197	unsigned int len = strlen(osd);1198 1199	if (len > 13)1200		len = 13;1201	msg->len = 3 + len;1202	msg->msg[1] = CEC_MSG_SET_OSD_STRING;1203	msg->msg[2] = disp_ctl;1204	memcpy(msg->msg + 3, osd, len);1205}1206 1207static inline void cec_ops_set_osd_string(const struct cec_msg *msg,1208					  __u8 *disp_ctl,1209					  char *osd)1210{1211	unsigned int len = msg->len > 3 ? msg->len - 3 : 0;1212 1213	*disp_ctl = msg->msg[2];1214	if (len > 13)1215		len = 13;1216	memcpy(osd, msg->msg + 3, len);1217	osd[len] = '\0';1218}1219 1220 1221/* Device OSD Transfer Feature */1222static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name)1223{1224	unsigned int len = strlen(name);1225 1226	if (len > 14)1227		len = 14;1228	msg->len = 2 + len;1229	msg->msg[1] = CEC_MSG_SET_OSD_NAME;1230	memcpy(msg->msg + 2, name, len);1231}1232 1233static inline void cec_ops_set_osd_name(const struct cec_msg *msg,1234					char *name)1235{1236	unsigned int len = msg->len > 2 ? msg->len - 2 : 0;1237 1238	if (len > 14)1239		len = 14;1240	memcpy(name, msg->msg + 2, len);1241	name[len] = '\0';1242}1243 1244static inline void cec_msg_give_osd_name(struct cec_msg *msg,1245					 int reply)1246{1247	msg->len = 2;1248	msg->msg[1] = CEC_MSG_GIVE_OSD_NAME;1249	msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0;1250}1251 1252 1253/* Device Menu Control Feature */1254static inline void cec_msg_menu_status(struct cec_msg *msg,1255				       __u8 menu_state)1256{1257	msg->len = 3;1258	msg->msg[1] = CEC_MSG_MENU_STATUS;1259	msg->msg[2] = menu_state;1260}1261 1262static inline void cec_ops_menu_status(const struct cec_msg *msg,1263				       __u8 *menu_state)1264{1265	*menu_state = msg->msg[2];1266}1267 1268static inline void cec_msg_menu_request(struct cec_msg *msg,1269					int reply,1270					__u8 menu_req)1271{1272	msg->len = 3;1273	msg->msg[1] = CEC_MSG_MENU_REQUEST;1274	msg->msg[2] = menu_req;1275	msg->reply = reply ? CEC_MSG_MENU_STATUS : 0;1276}1277 1278static inline void cec_ops_menu_request(const struct cec_msg *msg,1279					__u8 *menu_req)1280{1281	*menu_req = msg->msg[2];1282}1283 1284struct cec_op_ui_command {1285	__u8 ui_cmd;1286	__u8 has_opt_arg;1287	union {1288		struct cec_op_channel_data channel_identifier;1289		__u8 ui_broadcast_type;1290		__u8 ui_sound_presentation_control;1291		__u8 play_mode;1292		__u8 ui_function_media;1293		__u8 ui_function_select_av_input;1294		__u8 ui_function_select_audio_input;1295	};1296};1297 1298static inline void cec_msg_user_control_pressed(struct cec_msg *msg,1299					const struct cec_op_ui_command *ui_cmd)1300{1301	msg->len = 3;1302	msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED;1303	msg->msg[2] = ui_cmd->ui_cmd;1304	if (!ui_cmd->has_opt_arg)1305		return;1306	switch (ui_cmd->ui_cmd) {1307	case CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE:1308	case CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION:1309	case CEC_OP_UI_CMD_PLAY_FUNCTION:1310	case CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION:1311	case CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION:1312	case CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION:1313		/* The optional operand is one byte for all these ui commands */1314		msg->len++;1315		msg->msg[3] = ui_cmd->play_mode;1316		break;1317	case CEC_OP_UI_CMD_TUNE_FUNCTION:1318		msg->len += 4;1319		msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) |1320			      (ui_cmd->channel_identifier.major >> 8);1321		msg->msg[4] = ui_cmd->channel_identifier.major & 0xff;1322		msg->msg[5] = ui_cmd->channel_identifier.minor >> 8;1323		msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff;1324		break;1325	}1326}1327 1328static inline void cec_ops_user_control_pressed(const struct cec_msg *msg,1329						struct cec_op_ui_command *ui_cmd)1330{1331	ui_cmd->ui_cmd = msg->msg[2];1332	ui_cmd->has_opt_arg = 0;1333	if (msg->len == 3)1334		return;1335	switch (ui_cmd->ui_cmd) {1336	case CEC_OP_UI_CMD_SELECT_BROADCAST_TYPE:1337	case CEC_OP_UI_CMD_SELECT_SOUND_PRESENTATION:1338	case CEC_OP_UI_CMD_PLAY_FUNCTION:1339	case CEC_OP_UI_CMD_SELECT_MEDIA_FUNCTION:1340	case CEC_OP_UI_CMD_SELECT_AV_INPUT_FUNCTION:1341	case CEC_OP_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION:1342		/* The optional operand is one byte for all these ui commands */1343		ui_cmd->play_mode = msg->msg[3];1344		ui_cmd->has_opt_arg = 1;1345		break;1346	case CEC_OP_UI_CMD_TUNE_FUNCTION:1347		if (msg->len < 7)1348			break;1349		ui_cmd->has_opt_arg = 1;1350		ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2;1351		ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4];1352		ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6];1353		break;1354	}1355}1356 1357static inline void cec_msg_user_control_released(struct cec_msg *msg)1358{1359	msg->len = 2;1360	msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED;1361}1362 1363/* Remote Control Passthrough Feature */1364 1365/* Power Status Feature */1366static inline void cec_msg_report_power_status(struct cec_msg *msg,1367					       __u8 pwr_state)1368{1369	msg->len = 3;1370	msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS;1371	msg->msg[2] = pwr_state;1372}1373 1374static inline void cec_ops_report_power_status(const struct cec_msg *msg,1375					       __u8 *pwr_state)1376{1377	*pwr_state = msg->msg[2];1378}1379 1380static inline void cec_msg_give_device_power_status(struct cec_msg *msg,1381						    int reply)1382{1383	msg->len = 2;1384	msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS;1385	msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0;1386}1387 1388/* General Protocol Messages */1389static inline void cec_msg_feature_abort(struct cec_msg *msg,1390					 __u8 abort_msg, __u8 reason)1391{1392	msg->len = 4;1393	msg->msg[1] = CEC_MSG_FEATURE_ABORT;1394	msg->msg[2] = abort_msg;1395	msg->msg[3] = reason;1396}1397 1398static inline void cec_ops_feature_abort(const struct cec_msg *msg,1399					 __u8 *abort_msg, __u8 *reason)1400{1401	*abort_msg = msg->msg[2];1402	*reason = msg->msg[3];1403}1404 1405/* This changes the current message into a feature abort message */1406static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason)1407{1408	cec_msg_set_reply_to(msg, msg);1409	msg->len = 4;1410	msg->msg[2] = msg->msg[1];1411	msg->msg[3] = reason;1412	msg->msg[1] = CEC_MSG_FEATURE_ABORT;1413}1414 1415static inline void cec_msg_abort(struct cec_msg *msg)1416{1417	msg->len = 2;1418	msg->msg[1] = CEC_MSG_ABORT;1419}1420 1421 1422/* System Audio Control Feature */1423static inline void cec_msg_report_audio_status(struct cec_msg *msg,1424					       __u8 aud_mute_status,1425					       __u8 aud_vol_status)1426{1427	msg->len = 3;1428	msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS;1429	msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f);1430}1431 1432static inline void cec_ops_report_audio_status(const struct cec_msg *msg,1433					       __u8 *aud_mute_status,1434					       __u8 *aud_vol_status)1435{1436	*aud_mute_status = msg->msg[2] >> 7;1437	*aud_vol_status = msg->msg[2] & 0x7f;1438}1439 1440static inline void cec_msg_give_audio_status(struct cec_msg *msg,1441					     int reply)1442{1443	msg->len = 2;1444	msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS;1445	msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0;1446}1447 1448static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg,1449						 __u8 sys_aud_status)1450{1451	msg->len = 3;1452	msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE;1453	msg->msg[2] = sys_aud_status;1454}1455 1456static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg,1457						 __u8 *sys_aud_status)1458{1459	*sys_aud_status = msg->msg[2];1460}1461 1462static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg,1463						     int reply,1464						     __u16 phys_addr)1465{1466	msg->len = phys_addr == 0xffff ? 2 : 4;1467	msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST;1468	msg->msg[2] = phys_addr >> 8;1469	msg->msg[3] = phys_addr & 0xff;1470	msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0;1471 1472}1473 1474static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg,1475						     __u16 *phys_addr)1476{1477	if (msg->len < 4)1478		*phys_addr = 0xffff;1479	else1480		*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1481}1482 1483static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg,1484						    __u8 sys_aud_status)1485{1486	msg->len = 3;1487	msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS;1488	msg->msg[2] = sys_aud_status;1489}1490 1491static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg,1492						    __u8 *sys_aud_status)1493{1494	*sys_aud_status = msg->msg[2];1495}1496 1497static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg,1498							 int reply)1499{1500	msg->len = 2;1501	msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS;1502	msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0;1503}1504 1505static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg,1506					__u8 num_descriptors,1507					const __u32 *descriptors)1508{1509	unsigned int i;1510 1511	if (num_descriptors > 4)1512		num_descriptors = 4;1513	msg->len = 2 + num_descriptors * 3;1514	msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR;1515	for (i = 0; i < num_descriptors; i++) {1516		msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff;1517		msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff;1518		msg->msg[4 + i * 3] = descriptors[i] & 0xff;1519	}1520}1521 1522static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg,1523							 __u8 *num_descriptors,1524							 __u32 *descriptors)1525{1526	unsigned int i;1527 1528	*num_descriptors = (msg->len - 2) / 3;1529	if (*num_descriptors > 4)1530		*num_descriptors = 4;1531	for (i = 0; i < *num_descriptors; i++)1532		descriptors[i] = (msg->msg[2 + i * 3] << 16) |1533			(msg->msg[3 + i * 3] << 8) |1534			msg->msg[4 + i * 3];1535}1536 1537static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg,1538					int reply,1539					__u8 num_descriptors,1540					const __u8 *audio_format_id,1541					const __u8 *audio_format_code)1542{1543	unsigned int i;1544 1545	if (num_descriptors > 4)1546		num_descriptors = 4;1547	msg->len = 2 + num_descriptors;1548	msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR;1549	msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0;1550	for (i = 0; i < num_descriptors; i++)1551		msg->msg[2 + i] = (audio_format_id[i] << 6) |1552				  (audio_format_code[i] & 0x3f);1553}1554 1555static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg,1556					__u8 *num_descriptors,1557					__u8 *audio_format_id,1558					__u8 *audio_format_code)1559{1560	unsigned int i;1561 1562	*num_descriptors = msg->len - 2;1563	if (*num_descriptors > 4)1564		*num_descriptors = 4;1565	for (i = 0; i < *num_descriptors; i++) {1566		audio_format_id[i] = msg->msg[2 + i] >> 6;1567		audio_format_code[i] = msg->msg[2 + i] & 0x3f;1568	}1569}1570 1571static inline void cec_msg_set_audio_volume_level(struct cec_msg *msg,1572						  __u8 audio_volume_level)1573{1574	msg->len = 3;1575	msg->msg[1] = CEC_MSG_SET_AUDIO_VOLUME_LEVEL;1576	msg->msg[2] = audio_volume_level;1577}1578 1579static inline void cec_ops_set_audio_volume_level(const struct cec_msg *msg,1580						  __u8 *audio_volume_level)1581{1582	*audio_volume_level = msg->msg[2];1583}1584 1585 1586/* Audio Rate Control Feature */1587static inline void cec_msg_set_audio_rate(struct cec_msg *msg,1588					  __u8 audio_rate)1589{1590	msg->len = 3;1591	msg->msg[1] = CEC_MSG_SET_AUDIO_RATE;1592	msg->msg[2] = audio_rate;1593}1594 1595static inline void cec_ops_set_audio_rate(const struct cec_msg *msg,1596					  __u8 *audio_rate)1597{1598	*audio_rate = msg->msg[2];1599}1600 1601 1602/* Audio Return Channel Control Feature */1603static inline void cec_msg_report_arc_initiated(struct cec_msg *msg)1604{1605	msg->len = 2;1606	msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED;1607}1608 1609static inline void cec_msg_initiate_arc(struct cec_msg *msg,1610					int reply)1611{1612	msg->len = 2;1613	msg->msg[1] = CEC_MSG_INITIATE_ARC;1614	msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0;1615}1616 1617static inline void cec_msg_request_arc_initiation(struct cec_msg *msg,1618						  int reply)1619{1620	msg->len = 2;1621	msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION;1622	msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0;1623}1624 1625static inline void cec_msg_report_arc_terminated(struct cec_msg *msg)1626{1627	msg->len = 2;1628	msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED;1629}1630 1631static inline void cec_msg_terminate_arc(struct cec_msg *msg,1632					 int reply)1633{1634	msg->len = 2;1635	msg->msg[1] = CEC_MSG_TERMINATE_ARC;1636	msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0;1637}1638 1639static inline void cec_msg_request_arc_termination(struct cec_msg *msg,1640						   int reply)1641{1642	msg->len = 2;1643	msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION;1644	msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0;1645}1646 1647 1648/* Dynamic Audio Lipsync Feature */1649/* Only for CEC 2.0 and up */1650static inline void cec_msg_report_current_latency(struct cec_msg *msg,1651						  __u16 phys_addr,1652						  __u8 video_latency,1653						  __u8 low_latency_mode,1654						  __u8 audio_out_compensated,1655						  __u8 audio_out_delay)1656{1657	msg->len = 6;1658	msg->msg[0] |= 0xf; /* broadcast */1659	msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY;1660	msg->msg[2] = phys_addr >> 8;1661	msg->msg[3] = phys_addr & 0xff;1662	msg->msg[4] = video_latency;1663	msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated;1664	if (audio_out_compensated == 3)1665		msg->msg[msg->len++] = audio_out_delay;1666}1667 1668static inline void cec_ops_report_current_latency(const struct cec_msg *msg,1669						  __u16 *phys_addr,1670						  __u8 *video_latency,1671						  __u8 *low_latency_mode,1672						  __u8 *audio_out_compensated,1673						  __u8 *audio_out_delay)1674{1675	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1676	*video_latency = msg->msg[4];1677	*low_latency_mode = (msg->msg[5] >> 2) & 1;1678	*audio_out_compensated = msg->msg[5] & 3;1679	if (*audio_out_compensated == 3 && msg->len >= 7)1680		*audio_out_delay = msg->msg[6];1681	else1682		*audio_out_delay = 1;1683}1684 1685static inline void cec_msg_request_current_latency(struct cec_msg *msg,1686						   int reply,1687						   __u16 phys_addr)1688{1689	msg->len = 4;1690	msg->msg[0] |= 0xf; /* broadcast */1691	msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY;1692	msg->msg[2] = phys_addr >> 8;1693	msg->msg[3] = phys_addr & 0xff;1694	msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0;1695}1696 1697static inline void cec_ops_request_current_latency(const struct cec_msg *msg,1698						   __u16 *phys_addr)1699{1700	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1701}1702 1703 1704/* Capability Discovery and Control Feature */1705static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg,1706						 __u16 phys_addr1,1707						 __u16 phys_addr2)1708{1709	msg->len = 9;1710	msg->msg[0] |= 0xf; /* broadcast */1711	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1712	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1713	msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;1714	msg->msg[5] = phys_addr1 >> 8;1715	msg->msg[6] = phys_addr1 & 0xff;1716	msg->msg[7] = phys_addr2 >> 8;1717	msg->msg[8] = phys_addr2 & 0xff;1718}1719 1720static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg,1721						 __u16 *phys_addr,1722						 __u16 *phys_addr1,1723						 __u16 *phys_addr2)1724{1725	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1726	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];1727	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];1728}1729 1730static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg,1731						__u16 target_phys_addr,1732						__u8 hec_func_state,1733						__u8 host_func_state,1734						__u8 enc_func_state,1735						__u8 cdc_errcode,1736						__u8 has_field,1737						__u16 hec_field)1738{1739	msg->len = has_field ? 10 : 8;1740	msg->msg[0] |= 0xf; /* broadcast */1741	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1742	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1743	msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE;1744	msg->msg[5] = target_phys_addr >> 8;1745	msg->msg[6] = target_phys_addr & 0xff;1746	msg->msg[7] = (hec_func_state << 6) |1747		      (host_func_state << 4) |1748		      (enc_func_state << 2) |1749		      cdc_errcode;1750	if (has_field) {1751		msg->msg[8] = hec_field >> 8;1752		msg->msg[9] = hec_field & 0xff;1753	}1754}1755 1756static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg,1757						__u16 *phys_addr,1758						__u16 *target_phys_addr,1759						__u8 *hec_func_state,1760						__u8 *host_func_state,1761						__u8 *enc_func_state,1762						__u8 *cdc_errcode,1763						__u8 *has_field,1764						__u16 *hec_field)1765{1766	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1767	*target_phys_addr = (msg->msg[5] << 8) | msg->msg[6];1768	*hec_func_state = msg->msg[7] >> 6;1769	*host_func_state = (msg->msg[7] >> 4) & 3;1770	*enc_func_state = (msg->msg[7] >> 4) & 3;1771	*cdc_errcode = msg->msg[7] & 3;1772	*has_field = msg->len >= 10;1773	*hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0;1774}1775 1776static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg,1777					     __u16 phys_addr1,1778					     __u16 phys_addr2,1779					     __u8 hec_set_state,1780					     __u16 phys_addr3,1781					     __u16 phys_addr4,1782					     __u16 phys_addr5)1783{1784	msg->len = 10;1785	msg->msg[0] |= 0xf; /* broadcast */1786	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1787	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1788	msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;1789	msg->msg[5] = phys_addr1 >> 8;1790	msg->msg[6] = phys_addr1 & 0xff;1791	msg->msg[7] = phys_addr2 >> 8;1792	msg->msg[8] = phys_addr2 & 0xff;1793	msg->msg[9] = hec_set_state;1794	if (phys_addr3 != CEC_PHYS_ADDR_INVALID) {1795		msg->msg[msg->len++] = phys_addr3 >> 8;1796		msg->msg[msg->len++] = phys_addr3 & 0xff;1797		if (phys_addr4 != CEC_PHYS_ADDR_INVALID) {1798			msg->msg[msg->len++] = phys_addr4 >> 8;1799			msg->msg[msg->len++] = phys_addr4 & 0xff;1800			if (phys_addr5 != CEC_PHYS_ADDR_INVALID) {1801				msg->msg[msg->len++] = phys_addr5 >> 8;1802				msg->msg[msg->len++] = phys_addr5 & 0xff;1803			}1804		}1805	}1806}1807 1808static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg,1809					     __u16 *phys_addr,1810					     __u16 *phys_addr1,1811					     __u16 *phys_addr2,1812					     __u8 *hec_set_state,1813					     __u16 *phys_addr3,1814					     __u16 *phys_addr4,1815					     __u16 *phys_addr5)1816{1817	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1818	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];1819	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];1820	*hec_set_state = msg->msg[9];1821	*phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID;1822	if (msg->len >= 12)1823		*phys_addr3 = (msg->msg[10] << 8) | msg->msg[11];1824	if (msg->len >= 14)1825		*phys_addr4 = (msg->msg[12] << 8) | msg->msg[13];1826	if (msg->len >= 16)1827		*phys_addr5 = (msg->msg[14] << 8) | msg->msg[15];1828}1829 1830static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg,1831						      __u16 phys_addr1,1832						      __u8 hec_set_state)1833{1834	msg->len = 8;1835	msg->msg[0] |= 0xf; /* broadcast */1836	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1837	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1838	msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT;1839	msg->msg[5] = phys_addr1 >> 8;1840	msg->msg[6] = phys_addr1 & 0xff;1841	msg->msg[7] = hec_set_state;1842}1843 1844static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg,1845						      __u16 *phys_addr,1846						      __u16 *phys_addr1,1847						      __u8 *hec_set_state)1848{1849	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1850	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];1851	*hec_set_state = msg->msg[7];1852}1853 1854static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg,1855							__u16 phys_addr1,1856							__u16 phys_addr2,1857							__u16 phys_addr3)1858{1859	msg->len = 11;1860	msg->msg[0] |= 0xf; /* broadcast */1861	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1862	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1863	msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION;1864	msg->msg[5] = phys_addr1 >> 8;1865	msg->msg[6] = phys_addr1 & 0xff;1866	msg->msg[7] = phys_addr2 >> 8;1867	msg->msg[8] = phys_addr2 & 0xff;1868	msg->msg[9] = phys_addr3 >> 8;1869	msg->msg[10] = phys_addr3 & 0xff;1870}1871 1872static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg,1873							__u16 *phys_addr,1874							__u16 *phys_addr1,1875							__u16 *phys_addr2,1876							__u16 *phys_addr3)1877{1878	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1879	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];1880	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];1881	*phys_addr3 = (msg->msg[9] << 8) | msg->msg[10];1882}1883 1884static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg)1885{1886	msg->len = 5;1887	msg->msg[0] |= 0xf; /* broadcast */1888	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1889	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1890	msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE;1891}1892 1893static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg,1894						__u16 *phys_addr)1895{1896	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1897}1898 1899static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg)1900{1901	msg->len = 5;1902	msg->msg[0] |= 0xf; /* broadcast */1903	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1904	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1905	msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER;1906}1907 1908static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg,1909					    __u16 *phys_addr)1910{1911	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1912}1913 1914static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg,1915					     __u8 input_port,1916					     __u8 hpd_state)1917{1918	msg->len = 6;1919	msg->msg[0] |= 0xf; /* broadcast */1920	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1921	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1922	msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE;1923	msg->msg[5] = (input_port << 4) | hpd_state;1924}1925 1926static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg,1927					    __u16 *phys_addr,1928					    __u8 *input_port,1929					    __u8 *hpd_state)1930{1931	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1932	*input_port = msg->msg[5] >> 4;1933	*hpd_state = msg->msg[5] & 0xf;1934}1935 1936static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg,1937						__u8 hpd_state,1938						__u8 hpd_error)1939{1940	msg->len = 6;1941	msg->msg[0] |= 0xf; /* broadcast */1942	msg->msg[1] = CEC_MSG_CDC_MESSAGE;1943	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */1944	msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE;1945	msg->msg[5] = (hpd_state << 4) | hpd_error;1946}1947 1948static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg,1949						__u16 *phys_addr,1950						__u8 *hpd_state,1951						__u8 *hpd_error)1952{1953	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];1954	*hpd_state = msg->msg[5] >> 4;1955	*hpd_error = msg->msg[5] & 0xf;1956}1957 1958#endif1959