xref: /openbmc/linux/include/uapi/linux/cec-funcs.h (revision 79bcd34c)
10dbacebeSHans Verkuil /*
20dbacebeSHans Verkuil  * cec - HDMI Consumer Electronics Control message functions
30dbacebeSHans Verkuil  *
40dbacebeSHans Verkuil  * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
50dbacebeSHans Verkuil  *
60dbacebeSHans Verkuil  * This program is free software; you may redistribute it and/or modify
70dbacebeSHans Verkuil  * it under the terms of the GNU General Public License as published by
80dbacebeSHans Verkuil  * the Free Software Foundation; version 2 of the License.
90dbacebeSHans Verkuil  *
100dbacebeSHans Verkuil  * Alternatively you can redistribute this file under the terms of the
110dbacebeSHans Verkuil  * BSD license as stated below:
120dbacebeSHans Verkuil  *
130dbacebeSHans Verkuil  * Redistribution and use in source and binary forms, with or without
140dbacebeSHans Verkuil  * modification, are permitted provided that the following conditions
150dbacebeSHans Verkuil  * are met:
160dbacebeSHans Verkuil  * 1. Redistributions of source code must retain the above copyright
170dbacebeSHans Verkuil  *    notice, this list of conditions and the following disclaimer.
180dbacebeSHans Verkuil  * 2. Redistributions in binary form must reproduce the above copyright
190dbacebeSHans Verkuil  *    notice, this list of conditions and the following disclaimer in
200dbacebeSHans Verkuil  *    the documentation and/or other materials provided with the
210dbacebeSHans Verkuil  *    distribution.
220dbacebeSHans Verkuil  * 3. The names of its contributors may not be used to endorse or promote
230dbacebeSHans Verkuil  *    products derived from this software without specific prior written
240dbacebeSHans Verkuil  *    permission.
250dbacebeSHans Verkuil  *
260dbacebeSHans Verkuil  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
270dbacebeSHans Verkuil  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
280dbacebeSHans Verkuil  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
290dbacebeSHans Verkuil  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
300dbacebeSHans Verkuil  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
310dbacebeSHans Verkuil  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
320dbacebeSHans Verkuil  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
330dbacebeSHans Verkuil  * SOFTWARE.
340dbacebeSHans Verkuil  */
350dbacebeSHans Verkuil 
360dbacebeSHans Verkuil #ifndef _CEC_UAPI_FUNCS_H
370dbacebeSHans Verkuil #define _CEC_UAPI_FUNCS_H
380dbacebeSHans Verkuil 
390dbacebeSHans Verkuil #include <linux/cec.h>
400dbacebeSHans Verkuil 
410dbacebeSHans Verkuil /* One Touch Play Feature */
420dbacebeSHans Verkuil static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr)
430dbacebeSHans Verkuil {
440dbacebeSHans Verkuil 	msg->len = 4;
450dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
460dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_ACTIVE_SOURCE;
470dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
480dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
490dbacebeSHans Verkuil }
500dbacebeSHans Verkuil 
510dbacebeSHans Verkuil static inline void cec_ops_active_source(const struct cec_msg *msg,
520dbacebeSHans Verkuil 					 __u16 *phys_addr)
530dbacebeSHans Verkuil {
540dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
550dbacebeSHans Verkuil }
560dbacebeSHans Verkuil 
570dbacebeSHans Verkuil static inline void cec_msg_image_view_on(struct cec_msg *msg)
580dbacebeSHans Verkuil {
590dbacebeSHans Verkuil 	msg->len = 2;
600dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON;
610dbacebeSHans Verkuil }
620dbacebeSHans Verkuil 
630dbacebeSHans Verkuil static inline void cec_msg_text_view_on(struct cec_msg *msg)
640dbacebeSHans Verkuil {
650dbacebeSHans Verkuil 	msg->len = 2;
660dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TEXT_VIEW_ON;
670dbacebeSHans Verkuil }
680dbacebeSHans Verkuil 
690dbacebeSHans Verkuil 
700dbacebeSHans Verkuil /* Routing Control Feature */
710dbacebeSHans Verkuil static inline void cec_msg_inactive_source(struct cec_msg *msg,
720dbacebeSHans Verkuil 					   __u16 phys_addr)
730dbacebeSHans Verkuil {
740dbacebeSHans Verkuil 	msg->len = 4;
750dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_INACTIVE_SOURCE;
760dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
770dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
780dbacebeSHans Verkuil }
790dbacebeSHans Verkuil 
800dbacebeSHans Verkuil static inline void cec_ops_inactive_source(const struct cec_msg *msg,
810dbacebeSHans Verkuil 					   __u16 *phys_addr)
820dbacebeSHans Verkuil {
830dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
840dbacebeSHans Verkuil }
850dbacebeSHans Verkuil 
860dbacebeSHans Verkuil static inline void cec_msg_request_active_source(struct cec_msg *msg,
873145c754SHans Verkuil 						 int reply)
880dbacebeSHans Verkuil {
890dbacebeSHans Verkuil 	msg->len = 2;
900dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
910dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE;
920dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0;
930dbacebeSHans Verkuil }
940dbacebeSHans Verkuil 
950dbacebeSHans Verkuil static inline void cec_msg_routing_information(struct cec_msg *msg,
960dbacebeSHans Verkuil 					       __u16 phys_addr)
970dbacebeSHans Verkuil {
980dbacebeSHans Verkuil 	msg->len = 4;
990dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
1000dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_ROUTING_INFORMATION;
1010dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
1020dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
1030dbacebeSHans Verkuil }
1040dbacebeSHans Verkuil 
1050dbacebeSHans Verkuil static inline void cec_ops_routing_information(const struct cec_msg *msg,
1060dbacebeSHans Verkuil 					       __u16 *phys_addr)
1070dbacebeSHans Verkuil {
1080dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
1090dbacebeSHans Verkuil }
1100dbacebeSHans Verkuil 
1110dbacebeSHans Verkuil static inline void cec_msg_routing_change(struct cec_msg *msg,
1123145c754SHans Verkuil 					  int reply,
1130dbacebeSHans Verkuil 					  __u16 orig_phys_addr,
1140dbacebeSHans Verkuil 					  __u16 new_phys_addr)
1150dbacebeSHans Verkuil {
1160dbacebeSHans Verkuil 	msg->len = 6;
1170dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
1180dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_ROUTING_CHANGE;
1190dbacebeSHans Verkuil 	msg->msg[2] = orig_phys_addr >> 8;
1200dbacebeSHans Verkuil 	msg->msg[3] = orig_phys_addr & 0xff;
1210dbacebeSHans Verkuil 	msg->msg[4] = new_phys_addr >> 8;
1220dbacebeSHans Verkuil 	msg->msg[5] = new_phys_addr & 0xff;
1230dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0;
1240dbacebeSHans Verkuil }
1250dbacebeSHans Verkuil 
1260dbacebeSHans Verkuil static inline void cec_ops_routing_change(const struct cec_msg *msg,
1270dbacebeSHans Verkuil 					  __u16 *orig_phys_addr,
1280dbacebeSHans Verkuil 					  __u16 *new_phys_addr)
1290dbacebeSHans Verkuil {
1300dbacebeSHans Verkuil 	*orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3];
1310dbacebeSHans Verkuil 	*new_phys_addr = (msg->msg[4] << 8) | msg->msg[5];
1320dbacebeSHans Verkuil }
1330dbacebeSHans Verkuil 
1340dbacebeSHans Verkuil static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr)
1350dbacebeSHans Verkuil {
1360dbacebeSHans Verkuil 	msg->len = 4;
1370dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
1380dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_STREAM_PATH;
1390dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
1400dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
1410dbacebeSHans Verkuil }
1420dbacebeSHans Verkuil 
1430dbacebeSHans Verkuil static inline void cec_ops_set_stream_path(const struct cec_msg *msg,
1440dbacebeSHans Verkuil 					   __u16 *phys_addr)
1450dbacebeSHans Verkuil {
1460dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
1470dbacebeSHans Verkuil }
1480dbacebeSHans Verkuil 
1490dbacebeSHans Verkuil 
1500dbacebeSHans Verkuil /* Standby Feature */
1510dbacebeSHans Verkuil static inline void cec_msg_standby(struct cec_msg *msg)
1520dbacebeSHans Verkuil {
1530dbacebeSHans Verkuil 	msg->len = 2;
1540dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_STANDBY;
1550dbacebeSHans Verkuil }
1560dbacebeSHans Verkuil 
1570dbacebeSHans Verkuil 
1580dbacebeSHans Verkuil /* One Touch Record Feature */
1593145c754SHans Verkuil static inline void cec_msg_record_off(struct cec_msg *msg, int reply)
1600dbacebeSHans Verkuil {
1610dbacebeSHans Verkuil 	msg->len = 2;
1620dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_OFF;
1630dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;
1640dbacebeSHans Verkuil }
1650dbacebeSHans Verkuil 
1660dbacebeSHans Verkuil struct cec_op_arib_data {
1670dbacebeSHans Verkuil 	__u16 transport_id;
1680dbacebeSHans Verkuil 	__u16 service_id;
1690dbacebeSHans Verkuil 	__u16 orig_network_id;
1700dbacebeSHans Verkuil };
1710dbacebeSHans Verkuil 
1720dbacebeSHans Verkuil struct cec_op_atsc_data {
1730dbacebeSHans Verkuil 	__u16 transport_id;
1740dbacebeSHans Verkuil 	__u16 program_number;
1750dbacebeSHans Verkuil };
1760dbacebeSHans Verkuil 
1770dbacebeSHans Verkuil struct cec_op_dvb_data {
1780dbacebeSHans Verkuil 	__u16 transport_id;
1790dbacebeSHans Verkuil 	__u16 service_id;
1800dbacebeSHans Verkuil 	__u16 orig_network_id;
1810dbacebeSHans Verkuil };
1820dbacebeSHans Verkuil 
1830dbacebeSHans Verkuil struct cec_op_channel_data {
1840dbacebeSHans Verkuil 	__u8 channel_number_fmt;
1850dbacebeSHans Verkuil 	__u16 major;
1860dbacebeSHans Verkuil 	__u16 minor;
1870dbacebeSHans Verkuil };
1880dbacebeSHans Verkuil 
1890dbacebeSHans Verkuil struct cec_op_digital_service_id {
1900dbacebeSHans Verkuil 	__u8 service_id_method;
1910dbacebeSHans Verkuil 	__u8 dig_bcast_system;
1920dbacebeSHans Verkuil 	union {
1930dbacebeSHans Verkuil 		struct cec_op_arib_data arib;
1940dbacebeSHans Verkuil 		struct cec_op_atsc_data atsc;
1950dbacebeSHans Verkuil 		struct cec_op_dvb_data dvb;
1960dbacebeSHans Verkuil 		struct cec_op_channel_data channel;
1970dbacebeSHans Verkuil 	};
1980dbacebeSHans Verkuil };
1990dbacebeSHans Verkuil 
2000dbacebeSHans Verkuil struct cec_op_record_src {
2010dbacebeSHans Verkuil 	__u8 type;
2020dbacebeSHans Verkuil 	union {
2030dbacebeSHans Verkuil 		struct cec_op_digital_service_id digital;
2040dbacebeSHans Verkuil 		struct {
2050dbacebeSHans Verkuil 			__u8 ana_bcast_type;
2060dbacebeSHans Verkuil 			__u16 ana_freq;
2070dbacebeSHans Verkuil 			__u8 bcast_system;
2080dbacebeSHans Verkuil 		} analog;
2090dbacebeSHans Verkuil 		struct {
2100dbacebeSHans Verkuil 			__u8 plug;
2110dbacebeSHans Verkuil 		} ext_plug;
2120dbacebeSHans Verkuil 		struct {
2130dbacebeSHans Verkuil 			__u16 phys_addr;
2140dbacebeSHans Verkuil 		} ext_phys_addr;
2150dbacebeSHans Verkuil 	};
2160dbacebeSHans Verkuil };
2170dbacebeSHans Verkuil 
2180dbacebeSHans Verkuil static inline void cec_set_digital_service_id(__u8 *msg,
2190dbacebeSHans Verkuil 	      const struct cec_op_digital_service_id *digital)
2200dbacebeSHans Verkuil {
2210dbacebeSHans Verkuil 	*msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system;
2220dbacebeSHans Verkuil 	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
2230dbacebeSHans Verkuil 		*msg++ = (digital->channel.channel_number_fmt << 2) |
2240dbacebeSHans Verkuil 			 (digital->channel.major >> 8);
2250dbacebeSHans Verkuil 		*msg++ = digital->channel.major & 0xff;
2260dbacebeSHans Verkuil 		*msg++ = digital->channel.minor >> 8;
2270dbacebeSHans Verkuil 		*msg++ = digital->channel.minor & 0xff;
2280dbacebeSHans Verkuil 		*msg++ = 0;
2290dbacebeSHans Verkuil 		*msg++ = 0;
2300dbacebeSHans Verkuil 		return;
2310dbacebeSHans Verkuil 	}
2320dbacebeSHans Verkuil 	switch (digital->dig_bcast_system) {
2330dbacebeSHans Verkuil 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
2340dbacebeSHans Verkuil 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
2350dbacebeSHans Verkuil 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
2360dbacebeSHans Verkuil 	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:
2370dbacebeSHans Verkuil 		*msg++ = digital->atsc.transport_id >> 8;
2380dbacebeSHans Verkuil 		*msg++ = digital->atsc.transport_id & 0xff;
2390dbacebeSHans Verkuil 		*msg++ = digital->atsc.program_number >> 8;
2400dbacebeSHans Verkuil 		*msg++ = digital->atsc.program_number & 0xff;
2410dbacebeSHans Verkuil 		*msg++ = 0;
2420dbacebeSHans Verkuil 		*msg++ = 0;
2430dbacebeSHans Verkuil 		break;
2440dbacebeSHans Verkuil 	default:
2450dbacebeSHans Verkuil 		*msg++ = digital->dvb.transport_id >> 8;
2460dbacebeSHans Verkuil 		*msg++ = digital->dvb.transport_id & 0xff;
2470dbacebeSHans Verkuil 		*msg++ = digital->dvb.service_id >> 8;
2480dbacebeSHans Verkuil 		*msg++ = digital->dvb.service_id & 0xff;
2490dbacebeSHans Verkuil 		*msg++ = digital->dvb.orig_network_id >> 8;
2500dbacebeSHans Verkuil 		*msg++ = digital->dvb.orig_network_id & 0xff;
2510dbacebeSHans Verkuil 		break;
2520dbacebeSHans Verkuil 	}
2530dbacebeSHans Verkuil }
2540dbacebeSHans Verkuil 
2550dbacebeSHans Verkuil static inline void cec_get_digital_service_id(const __u8 *msg,
2560dbacebeSHans Verkuil 	      struct cec_op_digital_service_id *digital)
2570dbacebeSHans Verkuil {
2580dbacebeSHans Verkuil 	digital->service_id_method = msg[0] >> 7;
2590dbacebeSHans Verkuil 	digital->dig_bcast_system = msg[0] & 0x7f;
2600dbacebeSHans Verkuil 	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
2610dbacebeSHans Verkuil 		digital->channel.channel_number_fmt = msg[1] >> 2;
2620dbacebeSHans Verkuil 		digital->channel.major = ((msg[1] & 3) << 6) | msg[2];
2630dbacebeSHans Verkuil 		digital->channel.minor = (msg[3] << 8) | msg[4];
2640dbacebeSHans Verkuil 		return;
2650dbacebeSHans Verkuil 	}
2660dbacebeSHans Verkuil 	digital->dvb.transport_id = (msg[1] << 8) | msg[2];
2670dbacebeSHans Verkuil 	digital->dvb.service_id = (msg[3] << 8) | msg[4];
2680dbacebeSHans Verkuil 	digital->dvb.orig_network_id = (msg[5] << 8) | msg[6];
2690dbacebeSHans Verkuil }
2700dbacebeSHans Verkuil 
2710dbacebeSHans Verkuil static inline void cec_msg_record_on_own(struct cec_msg *msg)
2720dbacebeSHans Verkuil {
2730dbacebeSHans Verkuil 	msg->len = 3;
2740dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_ON;
2750dbacebeSHans Verkuil 	msg->msg[2] = CEC_OP_RECORD_SRC_OWN;
2760dbacebeSHans Verkuil }
2770dbacebeSHans Verkuil 
2780dbacebeSHans Verkuil static inline void cec_msg_record_on_digital(struct cec_msg *msg,
2790dbacebeSHans Verkuil 			     const struct cec_op_digital_service_id *digital)
2800dbacebeSHans Verkuil {
2810dbacebeSHans Verkuil 	msg->len = 10;
2820dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_ON;
2830dbacebeSHans Verkuil 	msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL;
2840dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 3, digital);
2850dbacebeSHans Verkuil }
2860dbacebeSHans Verkuil 
2870dbacebeSHans Verkuil static inline void cec_msg_record_on_analog(struct cec_msg *msg,
2880dbacebeSHans Verkuil 					    __u8 ana_bcast_type,
2890dbacebeSHans Verkuil 					    __u16 ana_freq,
2900dbacebeSHans Verkuil 					    __u8 bcast_system)
2910dbacebeSHans Verkuil {
2920dbacebeSHans Verkuil 	msg->len = 7;
2930dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_ON;
2940dbacebeSHans Verkuil 	msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG;
2950dbacebeSHans Verkuil 	msg->msg[3] = ana_bcast_type;
2960dbacebeSHans Verkuil 	msg->msg[4] = ana_freq >> 8;
2970dbacebeSHans Verkuil 	msg->msg[5] = ana_freq & 0xff;
2980dbacebeSHans Verkuil 	msg->msg[6] = bcast_system;
2990dbacebeSHans Verkuil }
3000dbacebeSHans Verkuil 
3010dbacebeSHans Verkuil static inline void cec_msg_record_on_plug(struct cec_msg *msg,
3020dbacebeSHans Verkuil 					  __u8 plug)
3030dbacebeSHans Verkuil {
3040dbacebeSHans Verkuil 	msg->len = 4;
3050dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_ON;
3060dbacebeSHans Verkuil 	msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG;
3070dbacebeSHans Verkuil 	msg->msg[3] = plug;
3080dbacebeSHans Verkuil }
3090dbacebeSHans Verkuil 
3100dbacebeSHans Verkuil static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg,
3110dbacebeSHans Verkuil 					       __u16 phys_addr)
3120dbacebeSHans Verkuil {
3130dbacebeSHans Verkuil 	msg->len = 5;
3140dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_ON;
3150dbacebeSHans Verkuil 	msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR;
3160dbacebeSHans Verkuil 	msg->msg[3] = phys_addr >> 8;
3170dbacebeSHans Verkuil 	msg->msg[4] = phys_addr & 0xff;
3180dbacebeSHans Verkuil }
3190dbacebeSHans Verkuil 
3200dbacebeSHans Verkuil static inline void cec_msg_record_on(struct cec_msg *msg,
3213145c754SHans Verkuil 				     int reply,
3220dbacebeSHans Verkuil 				     const struct cec_op_record_src *rec_src)
3230dbacebeSHans Verkuil {
3240dbacebeSHans Verkuil 	switch (rec_src->type) {
3250dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_OWN:
3260dbacebeSHans Verkuil 		cec_msg_record_on_own(msg);
3270dbacebeSHans Verkuil 		break;
3280dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_DIGITAL:
3290dbacebeSHans Verkuil 		cec_msg_record_on_digital(msg, &rec_src->digital);
3300dbacebeSHans Verkuil 		break;
3310dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_ANALOG:
3320dbacebeSHans Verkuil 		cec_msg_record_on_analog(msg,
3330dbacebeSHans Verkuil 					 rec_src->analog.ana_bcast_type,
3340dbacebeSHans Verkuil 					 rec_src->analog.ana_freq,
3350dbacebeSHans Verkuil 					 rec_src->analog.bcast_system);
3360dbacebeSHans Verkuil 		break;
3370dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_EXT_PLUG:
3380dbacebeSHans Verkuil 		cec_msg_record_on_plug(msg, rec_src->ext_plug.plug);
3390dbacebeSHans Verkuil 		break;
3400dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
3410dbacebeSHans Verkuil 		cec_msg_record_on_phys_addr(msg,
3420dbacebeSHans Verkuil 					    rec_src->ext_phys_addr.phys_addr);
3430dbacebeSHans Verkuil 		break;
3440dbacebeSHans Verkuil 	}
3450dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;
3460dbacebeSHans Verkuil }
3470dbacebeSHans Verkuil 
3480dbacebeSHans Verkuil static inline void cec_ops_record_on(const struct cec_msg *msg,
3490dbacebeSHans Verkuil 				     struct cec_op_record_src *rec_src)
3500dbacebeSHans Verkuil {
3510dbacebeSHans Verkuil 	rec_src->type = msg->msg[2];
3520dbacebeSHans Verkuil 	switch (rec_src->type) {
3530dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_OWN:
3540dbacebeSHans Verkuil 		break;
3550dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_DIGITAL:
3560dbacebeSHans Verkuil 		cec_get_digital_service_id(msg->msg + 3, &rec_src->digital);
3570dbacebeSHans Verkuil 		break;
3580dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_ANALOG:
3590dbacebeSHans Verkuil 		rec_src->analog.ana_bcast_type = msg->msg[3];
3600dbacebeSHans Verkuil 		rec_src->analog.ana_freq =
3610dbacebeSHans Verkuil 			(msg->msg[4] << 8) | msg->msg[5];
3620dbacebeSHans Verkuil 		rec_src->analog.bcast_system = msg->msg[6];
3630dbacebeSHans Verkuil 		break;
3640dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_EXT_PLUG:
3650dbacebeSHans Verkuil 		rec_src->ext_plug.plug = msg->msg[3];
3660dbacebeSHans Verkuil 		break;
3670dbacebeSHans Verkuil 	case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
3680dbacebeSHans Verkuil 		rec_src->ext_phys_addr.phys_addr =
3690dbacebeSHans Verkuil 			(msg->msg[3] << 8) | msg->msg[4];
3700dbacebeSHans Verkuil 		break;
3710dbacebeSHans Verkuil 	}
3720dbacebeSHans Verkuil }
3730dbacebeSHans Verkuil 
3740dbacebeSHans Verkuil static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status)
3750dbacebeSHans Verkuil {
3760dbacebeSHans Verkuil 	msg->len = 3;
3770dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_STATUS;
3780dbacebeSHans Verkuil 	msg->msg[2] = rec_status;
3790dbacebeSHans Verkuil }
3800dbacebeSHans Verkuil 
3810dbacebeSHans Verkuil static inline void cec_ops_record_status(const struct cec_msg *msg,
3820dbacebeSHans Verkuil 					 __u8 *rec_status)
3830dbacebeSHans Verkuil {
3840dbacebeSHans Verkuil 	*rec_status = msg->msg[2];
3850dbacebeSHans Verkuil }
3860dbacebeSHans Verkuil 
3870dbacebeSHans Verkuil static inline void cec_msg_record_tv_screen(struct cec_msg *msg,
3883145c754SHans Verkuil 					    int reply)
3890dbacebeSHans Verkuil {
3900dbacebeSHans Verkuil 	msg->len = 2;
3910dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN;
3920dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_RECORD_ON : 0;
3930dbacebeSHans Verkuil }
3940dbacebeSHans Verkuil 
3950dbacebeSHans Verkuil 
3960dbacebeSHans Verkuil /* Timer Programming Feature */
3970dbacebeSHans Verkuil static inline void cec_msg_timer_status(struct cec_msg *msg,
3980dbacebeSHans Verkuil 					__u8 timer_overlap_warning,
3990dbacebeSHans Verkuil 					__u8 media_info,
4000dbacebeSHans Verkuil 					__u8 prog_info,
4010dbacebeSHans Verkuil 					__u8 prog_error,
4020dbacebeSHans Verkuil 					__u8 duration_hr,
4030dbacebeSHans Verkuil 					__u8 duration_min)
4040dbacebeSHans Verkuil {
4050dbacebeSHans Verkuil 	msg->len = 3;
4060dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TIMER_STATUS;
4070dbacebeSHans Verkuil 	msg->msg[2] = (timer_overlap_warning << 7) |
4080dbacebeSHans Verkuil 		(media_info << 5) |
4090dbacebeSHans Verkuil 		(prog_info ? 0x10 : 0) |
4100dbacebeSHans Verkuil 		(prog_info ? prog_info : prog_error);
4110dbacebeSHans Verkuil 	if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||
4120dbacebeSHans Verkuil 	    prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||
4130dbacebeSHans Verkuil 	    prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {
4140dbacebeSHans Verkuil 		msg->len += 2;
4150dbacebeSHans Verkuil 		msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10);
4160dbacebeSHans Verkuil 		msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10);
4170dbacebeSHans Verkuil 	}
4180dbacebeSHans Verkuil }
4190dbacebeSHans Verkuil 
4200dbacebeSHans Verkuil static inline void cec_ops_timer_status(const struct cec_msg *msg,
4210dbacebeSHans Verkuil 					__u8 *timer_overlap_warning,
4220dbacebeSHans Verkuil 					__u8 *media_info,
4230dbacebeSHans Verkuil 					__u8 *prog_info,
4240dbacebeSHans Verkuil 					__u8 *prog_error,
4250dbacebeSHans Verkuil 					__u8 *duration_hr,
4260dbacebeSHans Verkuil 					__u8 *duration_min)
4270dbacebeSHans Verkuil {
4280dbacebeSHans Verkuil 	*timer_overlap_warning = msg->msg[2] >> 7;
4290dbacebeSHans Verkuil 	*media_info = (msg->msg[2] >> 5) & 3;
4300dbacebeSHans Verkuil 	if (msg->msg[2] & 0x10) {
4310dbacebeSHans Verkuil 		*prog_info = msg->msg[2] & 0xf;
4320dbacebeSHans Verkuil 		*prog_error = 0;
4330dbacebeSHans Verkuil 	} else {
4340dbacebeSHans Verkuil 		*prog_info = 0;
4350dbacebeSHans Verkuil 		*prog_error = msg->msg[2] & 0xf;
4360dbacebeSHans Verkuil 	}
4370dbacebeSHans Verkuil 	if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||
4380dbacebeSHans Verkuil 	    *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||
4390dbacebeSHans Verkuil 	    *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {
4400dbacebeSHans Verkuil 		*duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf);
4410dbacebeSHans Verkuil 		*duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
4420dbacebeSHans Verkuil 	} else {
4430dbacebeSHans Verkuil 		*duration_hr = *duration_min = 0;
4440dbacebeSHans Verkuil 	}
4450dbacebeSHans Verkuil }
4460dbacebeSHans Verkuil 
4470dbacebeSHans Verkuil static inline void cec_msg_timer_cleared_status(struct cec_msg *msg,
4480dbacebeSHans Verkuil 						__u8 timer_cleared_status)
4490dbacebeSHans Verkuil {
4500dbacebeSHans Verkuil 	msg->len = 3;
4510dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS;
4520dbacebeSHans Verkuil 	msg->msg[2] = timer_cleared_status;
4530dbacebeSHans Verkuil }
4540dbacebeSHans Verkuil 
4550dbacebeSHans Verkuil static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg,
4560dbacebeSHans Verkuil 						__u8 *timer_cleared_status)
4570dbacebeSHans Verkuil {
4580dbacebeSHans Verkuil 	*timer_cleared_status = msg->msg[2];
4590dbacebeSHans Verkuil }
4600dbacebeSHans Verkuil 
4610dbacebeSHans Verkuil static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg,
4623145c754SHans Verkuil 						int reply,
4630dbacebeSHans Verkuil 						__u8 day,
4640dbacebeSHans Verkuil 						__u8 month,
4650dbacebeSHans Verkuil 						__u8 start_hr,
4660dbacebeSHans Verkuil 						__u8 start_min,
4670dbacebeSHans Verkuil 						__u8 duration_hr,
4680dbacebeSHans Verkuil 						__u8 duration_min,
4690dbacebeSHans Verkuil 						__u8 recording_seq,
4700dbacebeSHans Verkuil 						__u8 ana_bcast_type,
4710dbacebeSHans Verkuil 						__u16 ana_freq,
4720dbacebeSHans Verkuil 						__u8 bcast_system)
4730dbacebeSHans Verkuil {
4740dbacebeSHans Verkuil 	msg->len = 13;
4750dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER;
4760dbacebeSHans Verkuil 	msg->msg[2] = day;
4770dbacebeSHans Verkuil 	msg->msg[3] = month;
4780dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
4790dbacebeSHans Verkuil 	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
4800dbacebeSHans Verkuil 	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
4810dbacebeSHans Verkuil 	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
4820dbacebeSHans Verkuil 	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
4830dbacebeSHans Verkuil 	msg->msg[8] = recording_seq;
4840dbacebeSHans Verkuil 	msg->msg[9] = ana_bcast_type;
4850dbacebeSHans Verkuil 	msg->msg[10] = ana_freq >> 8;
4860dbacebeSHans Verkuil 	msg->msg[11] = ana_freq & 0xff;
4870dbacebeSHans Verkuil 	msg->msg[12] = bcast_system;
4880dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
4890dbacebeSHans Verkuil }
4900dbacebeSHans Verkuil 
4910dbacebeSHans Verkuil static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg,
4920dbacebeSHans Verkuil 						__u8 *day,
4930dbacebeSHans Verkuil 						__u8 *month,
4940dbacebeSHans Verkuil 						__u8 *start_hr,
4950dbacebeSHans Verkuil 						__u8 *start_min,
4960dbacebeSHans Verkuil 						__u8 *duration_hr,
4970dbacebeSHans Verkuil 						__u8 *duration_min,
4980dbacebeSHans Verkuil 						__u8 *recording_seq,
4990dbacebeSHans Verkuil 						__u8 *ana_bcast_type,
5000dbacebeSHans Verkuil 						__u16 *ana_freq,
5010dbacebeSHans Verkuil 						__u8 *bcast_system)
5020dbacebeSHans Verkuil {
5030dbacebeSHans Verkuil 	*day = msg->msg[2];
5040dbacebeSHans Verkuil 	*month = msg->msg[3];
5050dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
5060dbacebeSHans Verkuil 	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
5070dbacebeSHans Verkuil 	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
5080dbacebeSHans Verkuil 	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
5090dbacebeSHans Verkuil 	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
5100dbacebeSHans Verkuil 	*recording_seq = msg->msg[8];
5110dbacebeSHans Verkuil 	*ana_bcast_type = msg->msg[9];
5120dbacebeSHans Verkuil 	*ana_freq = (msg->msg[10] << 8) | msg->msg[11];
5130dbacebeSHans Verkuil 	*bcast_system = msg->msg[12];
5140dbacebeSHans Verkuil }
5150dbacebeSHans Verkuil 
5160dbacebeSHans Verkuil static inline void cec_msg_clear_digital_timer(struct cec_msg *msg,
5173145c754SHans Verkuil 				int reply,
5180dbacebeSHans Verkuil 				__u8 day,
5190dbacebeSHans Verkuil 				__u8 month,
5200dbacebeSHans Verkuil 				__u8 start_hr,
5210dbacebeSHans Verkuil 				__u8 start_min,
5220dbacebeSHans Verkuil 				__u8 duration_hr,
5230dbacebeSHans Verkuil 				__u8 duration_min,
5240dbacebeSHans Verkuil 				__u8 recording_seq,
5250dbacebeSHans Verkuil 				const struct cec_op_digital_service_id *digital)
5260dbacebeSHans Verkuil {
5270dbacebeSHans Verkuil 	msg->len = 16;
5280dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
5290dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER;
5300dbacebeSHans Verkuil 	msg->msg[2] = day;
5310dbacebeSHans Verkuil 	msg->msg[3] = month;
5320dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
5330dbacebeSHans Verkuil 	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
5340dbacebeSHans Verkuil 	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
5350dbacebeSHans Verkuil 	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
5360dbacebeSHans Verkuil 	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
5370dbacebeSHans Verkuil 	msg->msg[8] = recording_seq;
5380dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 9, digital);
5390dbacebeSHans Verkuil }
5400dbacebeSHans Verkuil 
5410dbacebeSHans Verkuil static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg,
5420dbacebeSHans Verkuil 				__u8 *day,
5430dbacebeSHans Verkuil 				__u8 *month,
5440dbacebeSHans Verkuil 				__u8 *start_hr,
5450dbacebeSHans Verkuil 				__u8 *start_min,
5460dbacebeSHans Verkuil 				__u8 *duration_hr,
5470dbacebeSHans Verkuil 				__u8 *duration_min,
5480dbacebeSHans Verkuil 				__u8 *recording_seq,
5490dbacebeSHans Verkuil 				struct cec_op_digital_service_id *digital)
5500dbacebeSHans Verkuil {
5510dbacebeSHans Verkuil 	*day = msg->msg[2];
5520dbacebeSHans Verkuil 	*month = msg->msg[3];
5530dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
5540dbacebeSHans Verkuil 	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
5550dbacebeSHans Verkuil 	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
5560dbacebeSHans Verkuil 	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
5570dbacebeSHans Verkuil 	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
5580dbacebeSHans Verkuil 	*recording_seq = msg->msg[8];
5590dbacebeSHans Verkuil 	cec_get_digital_service_id(msg->msg + 9, digital);
5600dbacebeSHans Verkuil }
5610dbacebeSHans Verkuil 
5620dbacebeSHans Verkuil static inline void cec_msg_clear_ext_timer(struct cec_msg *msg,
5633145c754SHans Verkuil 					   int reply,
5640dbacebeSHans Verkuil 					   __u8 day,
5650dbacebeSHans Verkuil 					   __u8 month,
5660dbacebeSHans Verkuil 					   __u8 start_hr,
5670dbacebeSHans Verkuil 					   __u8 start_min,
5680dbacebeSHans Verkuil 					   __u8 duration_hr,
5690dbacebeSHans Verkuil 					   __u8 duration_min,
5700dbacebeSHans Verkuil 					   __u8 recording_seq,
5710dbacebeSHans Verkuil 					   __u8 ext_src_spec,
5720dbacebeSHans Verkuil 					   __u8 plug,
5730dbacebeSHans Verkuil 					   __u16 phys_addr)
5740dbacebeSHans Verkuil {
5750dbacebeSHans Verkuil 	msg->len = 13;
5760dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER;
5770dbacebeSHans Verkuil 	msg->msg[2] = day;
5780dbacebeSHans Verkuil 	msg->msg[3] = month;
5790dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
5800dbacebeSHans Verkuil 	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
5810dbacebeSHans Verkuil 	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
5820dbacebeSHans Verkuil 	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
5830dbacebeSHans Verkuil 	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
5840dbacebeSHans Verkuil 	msg->msg[8] = recording_seq;
5850dbacebeSHans Verkuil 	msg->msg[9] = ext_src_spec;
5860dbacebeSHans Verkuil 	msg->msg[10] = plug;
5870dbacebeSHans Verkuil 	msg->msg[11] = phys_addr >> 8;
5880dbacebeSHans Verkuil 	msg->msg[12] = phys_addr & 0xff;
5890dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
5900dbacebeSHans Verkuil }
5910dbacebeSHans Verkuil 
5920dbacebeSHans Verkuil static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg,
5930dbacebeSHans Verkuil 					   __u8 *day,
5940dbacebeSHans Verkuil 					   __u8 *month,
5950dbacebeSHans Verkuil 					   __u8 *start_hr,
5960dbacebeSHans Verkuil 					   __u8 *start_min,
5970dbacebeSHans Verkuil 					   __u8 *duration_hr,
5980dbacebeSHans Verkuil 					   __u8 *duration_min,
5990dbacebeSHans Verkuil 					   __u8 *recording_seq,
6000dbacebeSHans Verkuil 					   __u8 *ext_src_spec,
6010dbacebeSHans Verkuil 					   __u8 *plug,
6020dbacebeSHans Verkuil 					   __u16 *phys_addr)
6030dbacebeSHans Verkuil {
6040dbacebeSHans Verkuil 	*day = msg->msg[2];
6050dbacebeSHans Verkuil 	*month = msg->msg[3];
6060dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
6070dbacebeSHans Verkuil 	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
6080dbacebeSHans Verkuil 	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
6090dbacebeSHans Verkuil 	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
6100dbacebeSHans Verkuil 	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
6110dbacebeSHans Verkuil 	*recording_seq = msg->msg[8];
6120dbacebeSHans Verkuil 	*ext_src_spec = msg->msg[9];
6130dbacebeSHans Verkuil 	*plug = msg->msg[10];
6140dbacebeSHans Verkuil 	*phys_addr = (msg->msg[11] << 8) | msg->msg[12];
6150dbacebeSHans Verkuil }
6160dbacebeSHans Verkuil 
6170dbacebeSHans Verkuil static inline void cec_msg_set_analogue_timer(struct cec_msg *msg,
6183145c754SHans Verkuil 					      int reply,
6190dbacebeSHans Verkuil 					      __u8 day,
6200dbacebeSHans Verkuil 					      __u8 month,
6210dbacebeSHans Verkuil 					      __u8 start_hr,
6220dbacebeSHans Verkuil 					      __u8 start_min,
6230dbacebeSHans Verkuil 					      __u8 duration_hr,
6240dbacebeSHans Verkuil 					      __u8 duration_min,
6250dbacebeSHans Verkuil 					      __u8 recording_seq,
6260dbacebeSHans Verkuil 					      __u8 ana_bcast_type,
6270dbacebeSHans Verkuil 					      __u16 ana_freq,
6280dbacebeSHans Verkuil 					      __u8 bcast_system)
6290dbacebeSHans Verkuil {
6300dbacebeSHans Verkuil 	msg->len = 13;
6310dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER;
6320dbacebeSHans Verkuil 	msg->msg[2] = day;
6330dbacebeSHans Verkuil 	msg->msg[3] = month;
6340dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
6350dbacebeSHans Verkuil 	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
6360dbacebeSHans Verkuil 	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
6370dbacebeSHans Verkuil 	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
6380dbacebeSHans Verkuil 	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
6390dbacebeSHans Verkuil 	msg->msg[8] = recording_seq;
6400dbacebeSHans Verkuil 	msg->msg[9] = ana_bcast_type;
6410dbacebeSHans Verkuil 	msg->msg[10] = ana_freq >> 8;
6420dbacebeSHans Verkuil 	msg->msg[11] = ana_freq & 0xff;
6430dbacebeSHans Verkuil 	msg->msg[12] = bcast_system;
6440dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
6450dbacebeSHans Verkuil }
6460dbacebeSHans Verkuil 
6470dbacebeSHans Verkuil static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg,
6480dbacebeSHans Verkuil 					      __u8 *day,
6490dbacebeSHans Verkuil 					      __u8 *month,
6500dbacebeSHans Verkuil 					      __u8 *start_hr,
6510dbacebeSHans Verkuil 					      __u8 *start_min,
6520dbacebeSHans Verkuil 					      __u8 *duration_hr,
6530dbacebeSHans Verkuil 					      __u8 *duration_min,
6540dbacebeSHans Verkuil 					      __u8 *recording_seq,
6550dbacebeSHans Verkuil 					      __u8 *ana_bcast_type,
6560dbacebeSHans Verkuil 					      __u16 *ana_freq,
6570dbacebeSHans Verkuil 					      __u8 *bcast_system)
6580dbacebeSHans Verkuil {
6590dbacebeSHans Verkuil 	*day = msg->msg[2];
6600dbacebeSHans Verkuil 	*month = msg->msg[3];
6610dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
6620dbacebeSHans Verkuil 	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
6630dbacebeSHans Verkuil 	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
6640dbacebeSHans Verkuil 	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
6650dbacebeSHans Verkuil 	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
6660dbacebeSHans Verkuil 	*recording_seq = msg->msg[8];
6670dbacebeSHans Verkuil 	*ana_bcast_type = msg->msg[9];
6680dbacebeSHans Verkuil 	*ana_freq = (msg->msg[10] << 8) | msg->msg[11];
6690dbacebeSHans Verkuil 	*bcast_system = msg->msg[12];
6700dbacebeSHans Verkuil }
6710dbacebeSHans Verkuil 
6720dbacebeSHans Verkuil static inline void cec_msg_set_digital_timer(struct cec_msg *msg,
6733145c754SHans Verkuil 			int reply,
6740dbacebeSHans Verkuil 			__u8 day,
6750dbacebeSHans Verkuil 			__u8 month,
6760dbacebeSHans Verkuil 			__u8 start_hr,
6770dbacebeSHans Verkuil 			__u8 start_min,
6780dbacebeSHans Verkuil 			__u8 duration_hr,
6790dbacebeSHans Verkuil 			__u8 duration_min,
6800dbacebeSHans Verkuil 			__u8 recording_seq,
6810dbacebeSHans Verkuil 			const struct cec_op_digital_service_id *digital)
6820dbacebeSHans Verkuil {
6830dbacebeSHans Verkuil 	msg->len = 16;
6840dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
6850dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER;
6860dbacebeSHans Verkuil 	msg->msg[2] = day;
6870dbacebeSHans Verkuil 	msg->msg[3] = month;
6880dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
6890dbacebeSHans Verkuil 	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
6900dbacebeSHans Verkuil 	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
6910dbacebeSHans Verkuil 	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
6920dbacebeSHans Verkuil 	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
6930dbacebeSHans Verkuil 	msg->msg[8] = recording_seq;
6940dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 9, digital);
6950dbacebeSHans Verkuil }
6960dbacebeSHans Verkuil 
6970dbacebeSHans Verkuil static inline void cec_ops_set_digital_timer(const struct cec_msg *msg,
6980dbacebeSHans Verkuil 			__u8 *day,
6990dbacebeSHans Verkuil 			__u8 *month,
7000dbacebeSHans Verkuil 			__u8 *start_hr,
7010dbacebeSHans Verkuil 			__u8 *start_min,
7020dbacebeSHans Verkuil 			__u8 *duration_hr,
7030dbacebeSHans Verkuil 			__u8 *duration_min,
7040dbacebeSHans Verkuil 			__u8 *recording_seq,
7050dbacebeSHans Verkuil 			struct cec_op_digital_service_id *digital)
7060dbacebeSHans Verkuil {
7070dbacebeSHans Verkuil 	*day = msg->msg[2];
7080dbacebeSHans Verkuil 	*month = msg->msg[3];
7090dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
7100dbacebeSHans Verkuil 	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
7110dbacebeSHans Verkuil 	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
7120dbacebeSHans Verkuil 	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
7130dbacebeSHans Verkuil 	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
7140dbacebeSHans Verkuil 	*recording_seq = msg->msg[8];
7150dbacebeSHans Verkuil 	cec_get_digital_service_id(msg->msg + 9, digital);
7160dbacebeSHans Verkuil }
7170dbacebeSHans Verkuil 
7180dbacebeSHans Verkuil static inline void cec_msg_set_ext_timer(struct cec_msg *msg,
7193145c754SHans Verkuil 					 int reply,
7200dbacebeSHans Verkuil 					 __u8 day,
7210dbacebeSHans Verkuil 					 __u8 month,
7220dbacebeSHans Verkuil 					 __u8 start_hr,
7230dbacebeSHans Verkuil 					 __u8 start_min,
7240dbacebeSHans Verkuil 					 __u8 duration_hr,
7250dbacebeSHans Verkuil 					 __u8 duration_min,
7260dbacebeSHans Verkuil 					 __u8 recording_seq,
7270dbacebeSHans Verkuil 					 __u8 ext_src_spec,
7280dbacebeSHans Verkuil 					 __u8 plug,
7290dbacebeSHans Verkuil 					 __u16 phys_addr)
7300dbacebeSHans Verkuil {
7310dbacebeSHans Verkuil 	msg->len = 13;
7320dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_EXT_TIMER;
7330dbacebeSHans Verkuil 	msg->msg[2] = day;
7340dbacebeSHans Verkuil 	msg->msg[3] = month;
7350dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
7360dbacebeSHans Verkuil 	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
7370dbacebeSHans Verkuil 	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
7380dbacebeSHans Verkuil 	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
7390dbacebeSHans Verkuil 	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
7400dbacebeSHans Verkuil 	msg->msg[8] = recording_seq;
7410dbacebeSHans Verkuil 	msg->msg[9] = ext_src_spec;
7420dbacebeSHans Verkuil 	msg->msg[10] = plug;
7430dbacebeSHans Verkuil 	msg->msg[11] = phys_addr >> 8;
7440dbacebeSHans Verkuil 	msg->msg[12] = phys_addr & 0xff;
7450dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
7460dbacebeSHans Verkuil }
7470dbacebeSHans Verkuil 
7480dbacebeSHans Verkuil static inline void cec_ops_set_ext_timer(const struct cec_msg *msg,
7490dbacebeSHans Verkuil 					 __u8 *day,
7500dbacebeSHans Verkuil 					 __u8 *month,
7510dbacebeSHans Verkuil 					 __u8 *start_hr,
7520dbacebeSHans Verkuil 					 __u8 *start_min,
7530dbacebeSHans Verkuil 					 __u8 *duration_hr,
7540dbacebeSHans Verkuil 					 __u8 *duration_min,
7550dbacebeSHans Verkuil 					 __u8 *recording_seq,
7560dbacebeSHans Verkuil 					 __u8 *ext_src_spec,
7570dbacebeSHans Verkuil 					 __u8 *plug,
7580dbacebeSHans Verkuil 					 __u16 *phys_addr)
7590dbacebeSHans Verkuil {
7600dbacebeSHans Verkuil 	*day = msg->msg[2];
7610dbacebeSHans Verkuil 	*month = msg->msg[3];
7620dbacebeSHans Verkuil 	/* Hours and minutes are in BCD format */
7630dbacebeSHans Verkuil 	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
7640dbacebeSHans Verkuil 	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
7650dbacebeSHans Verkuil 	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
7660dbacebeSHans Verkuil 	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
7670dbacebeSHans Verkuil 	*recording_seq = msg->msg[8];
7680dbacebeSHans Verkuil 	*ext_src_spec = msg->msg[9];
7690dbacebeSHans Verkuil 	*plug = msg->msg[10];
7700dbacebeSHans Verkuil 	*phys_addr = (msg->msg[11] << 8) | msg->msg[12];
7710dbacebeSHans Verkuil }
7720dbacebeSHans Verkuil 
7730dbacebeSHans Verkuil static inline void cec_msg_set_timer_program_title(struct cec_msg *msg,
7740dbacebeSHans Verkuil 						   const char *prog_title)
7750dbacebeSHans Verkuil {
7760dbacebeSHans Verkuil 	unsigned int len = strlen(prog_title);
7770dbacebeSHans Verkuil 
7780dbacebeSHans Verkuil 	if (len > 14)
7790dbacebeSHans Verkuil 		len = 14;
7800dbacebeSHans Verkuil 	msg->len = 2 + len;
7810dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE;
7820dbacebeSHans Verkuil 	memcpy(msg->msg + 2, prog_title, len);
7830dbacebeSHans Verkuil }
7840dbacebeSHans Verkuil 
7850dbacebeSHans Verkuil static inline void cec_ops_set_timer_program_title(const struct cec_msg *msg,
7860dbacebeSHans Verkuil 						   char *prog_title)
7870dbacebeSHans Verkuil {
7880dbacebeSHans Verkuil 	unsigned int len = msg->len > 2 ? msg->len - 2 : 0;
7890dbacebeSHans Verkuil 
7900dbacebeSHans Verkuil 	if (len > 14)
7910dbacebeSHans Verkuil 		len = 14;
7920dbacebeSHans Verkuil 	memcpy(prog_title, msg->msg + 2, len);
7930dbacebeSHans Verkuil 	prog_title[len] = '\0';
7940dbacebeSHans Verkuil }
7950dbacebeSHans Verkuil 
7960dbacebeSHans Verkuil /* System Information Feature */
7970dbacebeSHans Verkuil static inline void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version)
7980dbacebeSHans Verkuil {
7990dbacebeSHans Verkuil 	msg->len = 3;
8000dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CEC_VERSION;
8010dbacebeSHans Verkuil 	msg->msg[2] = cec_version;
8020dbacebeSHans Verkuil }
8030dbacebeSHans Verkuil 
8040dbacebeSHans Verkuil static inline void cec_ops_cec_version(const struct cec_msg *msg,
8050dbacebeSHans Verkuil 				       __u8 *cec_version)
8060dbacebeSHans Verkuil {
8070dbacebeSHans Verkuil 	*cec_version = msg->msg[2];
8080dbacebeSHans Verkuil }
8090dbacebeSHans Verkuil 
8100dbacebeSHans Verkuil static inline void cec_msg_get_cec_version(struct cec_msg *msg,
8113145c754SHans Verkuil 					   int reply)
8120dbacebeSHans Verkuil {
8130dbacebeSHans Verkuil 	msg->len = 2;
8140dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GET_CEC_VERSION;
8150dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_CEC_VERSION : 0;
8160dbacebeSHans Verkuil }
8170dbacebeSHans Verkuil 
8180dbacebeSHans Verkuil static inline void cec_msg_report_physical_addr(struct cec_msg *msg,
8190dbacebeSHans Verkuil 					__u16 phys_addr, __u8 prim_devtype)
8200dbacebeSHans Verkuil {
8210dbacebeSHans Verkuil 	msg->len = 5;
8220dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
8230dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR;
8240dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
8250dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
8260dbacebeSHans Verkuil 	msg->msg[4] = prim_devtype;
8270dbacebeSHans Verkuil }
8280dbacebeSHans Verkuil 
8290dbacebeSHans Verkuil static inline void cec_ops_report_physical_addr(const struct cec_msg *msg,
8300dbacebeSHans Verkuil 					__u16 *phys_addr, __u8 *prim_devtype)
8310dbacebeSHans Verkuil {
8320dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
8330dbacebeSHans Verkuil 	*prim_devtype = msg->msg[4];
8340dbacebeSHans Verkuil }
8350dbacebeSHans Verkuil 
8360dbacebeSHans Verkuil static inline void cec_msg_give_physical_addr(struct cec_msg *msg,
8373145c754SHans Verkuil 					      int reply)
8380dbacebeSHans Verkuil {
8390dbacebeSHans Verkuil 	msg->len = 2;
8400dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR;
8410dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0;
8420dbacebeSHans Verkuil }
8430dbacebeSHans Verkuil 
8440dbacebeSHans Verkuil static inline void cec_msg_set_menu_language(struct cec_msg *msg,
8450dbacebeSHans Verkuil 					     const char *language)
8460dbacebeSHans Verkuil {
8470dbacebeSHans Verkuil 	msg->len = 5;
8480dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
8490dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE;
8500dbacebeSHans Verkuil 	memcpy(msg->msg + 2, language, 3);
8510dbacebeSHans Verkuil }
8520dbacebeSHans Verkuil 
8530dbacebeSHans Verkuil static inline void cec_ops_set_menu_language(const struct cec_msg *msg,
8540dbacebeSHans Verkuil 					     char *language)
8550dbacebeSHans Verkuil {
8560dbacebeSHans Verkuil 	memcpy(language, msg->msg + 2, 3);
8570dbacebeSHans Verkuil 	language[3] = '\0';
8580dbacebeSHans Verkuil }
8590dbacebeSHans Verkuil 
8600dbacebeSHans Verkuil static inline void cec_msg_get_menu_language(struct cec_msg *msg,
8613145c754SHans Verkuil 					     int reply)
8620dbacebeSHans Verkuil {
8630dbacebeSHans Verkuil 	msg->len = 2;
8640dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE;
8650dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0;
8660dbacebeSHans Verkuil }
8670dbacebeSHans Verkuil 
8680dbacebeSHans Verkuil /*
8690dbacebeSHans Verkuil  * Assumes a single RC Profile byte and a single Device Features byte,
8700dbacebeSHans Verkuil  * i.e. no extended features are supported by this helper function.
8710dbacebeSHans Verkuil  *
8720dbacebeSHans Verkuil  * As of CEC 2.0 no extended features are defined, should those be added
8730dbacebeSHans Verkuil  * in the future, then this function needs to be adapted or a new function
8740dbacebeSHans Verkuil  * should be added.
8750dbacebeSHans Verkuil  */
8760dbacebeSHans Verkuil static inline void cec_msg_report_features(struct cec_msg *msg,
8770dbacebeSHans Verkuil 				__u8 cec_version, __u8 all_device_types,
8780dbacebeSHans Verkuil 				__u8 rc_profile, __u8 dev_features)
8790dbacebeSHans Verkuil {
8800dbacebeSHans Verkuil 	msg->len = 6;
8810dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
8820dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_FEATURES;
8830dbacebeSHans Verkuil 	msg->msg[2] = cec_version;
8840dbacebeSHans Verkuil 	msg->msg[3] = all_device_types;
8850dbacebeSHans Verkuil 	msg->msg[4] = rc_profile;
8860dbacebeSHans Verkuil 	msg->msg[5] = dev_features;
8870dbacebeSHans Verkuil }
8880dbacebeSHans Verkuil 
8890dbacebeSHans Verkuil static inline void cec_ops_report_features(const struct cec_msg *msg,
8900dbacebeSHans Verkuil 			__u8 *cec_version, __u8 *all_device_types,
8910dbacebeSHans Verkuil 			const __u8 **rc_profile, const __u8 **dev_features)
8920dbacebeSHans Verkuil {
8930dbacebeSHans Verkuil 	const __u8 *p = &msg->msg[4];
8940dbacebeSHans Verkuil 
8950dbacebeSHans Verkuil 	*cec_version = msg->msg[2];
8960dbacebeSHans Verkuil 	*all_device_types = msg->msg[3];
8970dbacebeSHans Verkuil 	*rc_profile = p;
89879bcd34cSHans Verkuil 	*dev_features = NULL;
8990dbacebeSHans Verkuil 	while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT))
9000dbacebeSHans Verkuil 		p++;
9010dbacebeSHans Verkuil 	if (!(*p & CEC_OP_FEAT_EXT)) {
9020dbacebeSHans Verkuil 		*dev_features = p + 1;
9030dbacebeSHans Verkuil 		while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT))
9040dbacebeSHans Verkuil 			p++;
9050dbacebeSHans Verkuil 	}
9060dbacebeSHans Verkuil 	if (*p & CEC_OP_FEAT_EXT)
9070dbacebeSHans Verkuil 		*rc_profile = *dev_features = NULL;
9080dbacebeSHans Verkuil }
9090dbacebeSHans Verkuil 
9100dbacebeSHans Verkuil static inline void cec_msg_give_features(struct cec_msg *msg,
9113145c754SHans Verkuil 					 int reply)
9120dbacebeSHans Verkuil {
9130dbacebeSHans Verkuil 	msg->len = 2;
9140dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_FEATURES;
9150dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0;
9160dbacebeSHans Verkuil }
9170dbacebeSHans Verkuil 
9180dbacebeSHans Verkuil /* Deck Control Feature */
9190dbacebeSHans Verkuil static inline void cec_msg_deck_control(struct cec_msg *msg,
9200dbacebeSHans Verkuil 					__u8 deck_control_mode)
9210dbacebeSHans Verkuil {
9220dbacebeSHans Verkuil 	msg->len = 3;
9230dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_DECK_CONTROL;
9240dbacebeSHans Verkuil 	msg->msg[2] = deck_control_mode;
9250dbacebeSHans Verkuil }
9260dbacebeSHans Verkuil 
9270dbacebeSHans Verkuil static inline void cec_ops_deck_control(const struct cec_msg *msg,
9280dbacebeSHans Verkuil 					__u8 *deck_control_mode)
9290dbacebeSHans Verkuil {
9300dbacebeSHans Verkuil 	*deck_control_mode = msg->msg[2];
9310dbacebeSHans Verkuil }
9320dbacebeSHans Verkuil 
9330dbacebeSHans Verkuil static inline void cec_msg_deck_status(struct cec_msg *msg,
9340dbacebeSHans Verkuil 				       __u8 deck_info)
9350dbacebeSHans Verkuil {
9360dbacebeSHans Verkuil 	msg->len = 3;
9370dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_DECK_STATUS;
9380dbacebeSHans Verkuil 	msg->msg[2] = deck_info;
9390dbacebeSHans Verkuil }
9400dbacebeSHans Verkuil 
9410dbacebeSHans Verkuil static inline void cec_ops_deck_status(const struct cec_msg *msg,
9420dbacebeSHans Verkuil 				       __u8 *deck_info)
9430dbacebeSHans Verkuil {
9440dbacebeSHans Verkuil 	*deck_info = msg->msg[2];
9450dbacebeSHans Verkuil }
9460dbacebeSHans Verkuil 
9470dbacebeSHans Verkuil static inline void cec_msg_give_deck_status(struct cec_msg *msg,
9483145c754SHans Verkuil 					    int reply,
9490dbacebeSHans Verkuil 					    __u8 status_req)
9500dbacebeSHans Verkuil {
9510dbacebeSHans Verkuil 	msg->len = 3;
9520dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS;
9530dbacebeSHans Verkuil 	msg->msg[2] = status_req;
9540dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_DECK_STATUS : 0;
9550dbacebeSHans Verkuil }
9560dbacebeSHans Verkuil 
9570dbacebeSHans Verkuil static inline void cec_ops_give_deck_status(const struct cec_msg *msg,
9580dbacebeSHans Verkuil 					    __u8 *status_req)
9590dbacebeSHans Verkuil {
9600dbacebeSHans Verkuil 	*status_req = msg->msg[2];
9610dbacebeSHans Verkuil }
9620dbacebeSHans Verkuil 
9630dbacebeSHans Verkuil static inline void cec_msg_play(struct cec_msg *msg,
9640dbacebeSHans Verkuil 				__u8 play_mode)
9650dbacebeSHans Verkuil {
9660dbacebeSHans Verkuil 	msg->len = 3;
9670dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_PLAY;
9680dbacebeSHans Verkuil 	msg->msg[2] = play_mode;
9690dbacebeSHans Verkuil }
9700dbacebeSHans Verkuil 
9710dbacebeSHans Verkuil static inline void cec_ops_play(const struct cec_msg *msg,
9720dbacebeSHans Verkuil 				__u8 *play_mode)
9730dbacebeSHans Verkuil {
9740dbacebeSHans Verkuil 	*play_mode = msg->msg[2];
9750dbacebeSHans Verkuil }
9760dbacebeSHans Verkuil 
9770dbacebeSHans Verkuil 
9780dbacebeSHans Verkuil /* Tuner Control Feature */
9790dbacebeSHans Verkuil struct cec_op_tuner_device_info {
9800dbacebeSHans Verkuil 	__u8 rec_flag;
9810dbacebeSHans Verkuil 	__u8 tuner_display_info;
9823145c754SHans Verkuil 	__u8 is_analog;
9830dbacebeSHans Verkuil 	union {
9840dbacebeSHans Verkuil 		struct cec_op_digital_service_id digital;
9850dbacebeSHans Verkuil 		struct {
9860dbacebeSHans Verkuil 			__u8 ana_bcast_type;
9870dbacebeSHans Verkuil 			__u16 ana_freq;
9880dbacebeSHans Verkuil 			__u8 bcast_system;
9890dbacebeSHans Verkuil 		} analog;
9900dbacebeSHans Verkuil 	};
9910dbacebeSHans Verkuil };
9920dbacebeSHans Verkuil 
9930dbacebeSHans Verkuil static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg,
9940dbacebeSHans Verkuil 						      __u8 rec_flag,
9950dbacebeSHans Verkuil 						      __u8 tuner_display_info,
9960dbacebeSHans Verkuil 						      __u8 ana_bcast_type,
9970dbacebeSHans Verkuil 						      __u16 ana_freq,
9980dbacebeSHans Verkuil 						      __u8 bcast_system)
9990dbacebeSHans Verkuil {
10000dbacebeSHans Verkuil 	msg->len = 7;
10010dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
10020dbacebeSHans Verkuil 	msg->msg[2] = (rec_flag << 7) | tuner_display_info;
10030dbacebeSHans Verkuil 	msg->msg[3] = ana_bcast_type;
10040dbacebeSHans Verkuil 	msg->msg[4] = ana_freq >> 8;
10050dbacebeSHans Verkuil 	msg->msg[5] = ana_freq & 0xff;
10060dbacebeSHans Verkuil 	msg->msg[6] = bcast_system;
10070dbacebeSHans Verkuil }
10080dbacebeSHans Verkuil 
10090dbacebeSHans Verkuil static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg,
10100dbacebeSHans Verkuil 		   __u8 rec_flag, __u8 tuner_display_info,
10110dbacebeSHans Verkuil 		   const struct cec_op_digital_service_id *digital)
10120dbacebeSHans Verkuil {
10130dbacebeSHans Verkuil 	msg->len = 10;
10140dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
10150dbacebeSHans Verkuil 	msg->msg[2] = (rec_flag << 7) | tuner_display_info;
10160dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 3, digital);
10170dbacebeSHans Verkuil }
10180dbacebeSHans Verkuil 
10190dbacebeSHans Verkuil static inline void cec_msg_tuner_device_status(struct cec_msg *msg,
10200dbacebeSHans Verkuil 			const struct cec_op_tuner_device_info *tuner_dev_info)
10210dbacebeSHans Verkuil {
10220dbacebeSHans Verkuil 	if (tuner_dev_info->is_analog)
10230dbacebeSHans Verkuil 		cec_msg_tuner_device_status_analog(msg,
10240dbacebeSHans Verkuil 			tuner_dev_info->rec_flag,
10250dbacebeSHans Verkuil 			tuner_dev_info->tuner_display_info,
10260dbacebeSHans Verkuil 			tuner_dev_info->analog.ana_bcast_type,
10270dbacebeSHans Verkuil 			tuner_dev_info->analog.ana_freq,
10280dbacebeSHans Verkuil 			tuner_dev_info->analog.bcast_system);
10290dbacebeSHans Verkuil 	else
10300dbacebeSHans Verkuil 		cec_msg_tuner_device_status_digital(msg,
10310dbacebeSHans Verkuil 			tuner_dev_info->rec_flag,
10320dbacebeSHans Verkuil 			tuner_dev_info->tuner_display_info,
10330dbacebeSHans Verkuil 			&tuner_dev_info->digital);
10340dbacebeSHans Verkuil }
10350dbacebeSHans Verkuil 
10360dbacebeSHans Verkuil static inline void cec_ops_tuner_device_status(const struct cec_msg *msg,
10370dbacebeSHans Verkuil 				struct cec_op_tuner_device_info *tuner_dev_info)
10380dbacebeSHans Verkuil {
10390dbacebeSHans Verkuil 	tuner_dev_info->is_analog = msg->len < 10;
10400dbacebeSHans Verkuil 	tuner_dev_info->rec_flag = msg->msg[2] >> 7;
10410dbacebeSHans Verkuil 	tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f;
10420dbacebeSHans Verkuil 	if (tuner_dev_info->is_analog) {
10430dbacebeSHans Verkuil 		tuner_dev_info->analog.ana_bcast_type = msg->msg[3];
10440dbacebeSHans Verkuil 		tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5];
10450dbacebeSHans Verkuil 		tuner_dev_info->analog.bcast_system = msg->msg[6];
10460dbacebeSHans Verkuil 		return;
10470dbacebeSHans Verkuil 	}
10480dbacebeSHans Verkuil 	cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital);
10490dbacebeSHans Verkuil }
10500dbacebeSHans Verkuil 
10510dbacebeSHans Verkuil static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg,
10523145c754SHans Verkuil 						    int reply,
10530dbacebeSHans Verkuil 						    __u8 status_req)
10540dbacebeSHans Verkuil {
10550dbacebeSHans Verkuil 	msg->len = 3;
10560dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS;
10570dbacebeSHans Verkuil 	msg->msg[2] = status_req;
10580dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0;
10590dbacebeSHans Verkuil }
10600dbacebeSHans Verkuil 
10610dbacebeSHans Verkuil static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg,
10620dbacebeSHans Verkuil 						    __u8 *status_req)
10630dbacebeSHans Verkuil {
10640dbacebeSHans Verkuil 	*status_req = msg->msg[2];
10650dbacebeSHans Verkuil }
10660dbacebeSHans Verkuil 
10670dbacebeSHans Verkuil static inline void cec_msg_select_analogue_service(struct cec_msg *msg,
10680dbacebeSHans Verkuil 						   __u8 ana_bcast_type,
10690dbacebeSHans Verkuil 						   __u16 ana_freq,
10700dbacebeSHans Verkuil 						   __u8 bcast_system)
10710dbacebeSHans Verkuil {
10720dbacebeSHans Verkuil 	msg->len = 6;
10730dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE;
10740dbacebeSHans Verkuil 	msg->msg[2] = ana_bcast_type;
10750dbacebeSHans Verkuil 	msg->msg[3] = ana_freq >> 8;
10760dbacebeSHans Verkuil 	msg->msg[4] = ana_freq & 0xff;
10770dbacebeSHans Verkuil 	msg->msg[5] = bcast_system;
10780dbacebeSHans Verkuil }
10790dbacebeSHans Verkuil 
10800dbacebeSHans Verkuil static inline void cec_ops_select_analogue_service(const struct cec_msg *msg,
10810dbacebeSHans Verkuil 						   __u8 *ana_bcast_type,
10820dbacebeSHans Verkuil 						   __u16 *ana_freq,
10830dbacebeSHans Verkuil 						   __u8 *bcast_system)
10840dbacebeSHans Verkuil {
10850dbacebeSHans Verkuil 	*ana_bcast_type = msg->msg[2];
10860dbacebeSHans Verkuil 	*ana_freq = (msg->msg[3] << 8) | msg->msg[4];
10870dbacebeSHans Verkuil 	*bcast_system = msg->msg[5];
10880dbacebeSHans Verkuil }
10890dbacebeSHans Verkuil 
10900dbacebeSHans Verkuil static inline void cec_msg_select_digital_service(struct cec_msg *msg,
10910dbacebeSHans Verkuil 				const struct cec_op_digital_service_id *digital)
10920dbacebeSHans Verkuil {
10930dbacebeSHans Verkuil 	msg->len = 9;
10940dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE;
10950dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 2, digital);
10960dbacebeSHans Verkuil }
10970dbacebeSHans Verkuil 
10980dbacebeSHans Verkuil static inline void cec_ops_select_digital_service(const struct cec_msg *msg,
10990dbacebeSHans Verkuil 				struct cec_op_digital_service_id *digital)
11000dbacebeSHans Verkuil {
11010dbacebeSHans Verkuil 	cec_get_digital_service_id(msg->msg + 2, digital);
11020dbacebeSHans Verkuil }
11030dbacebeSHans Verkuil 
11040dbacebeSHans Verkuil static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg)
11050dbacebeSHans Verkuil {
11060dbacebeSHans Verkuil 	msg->len = 2;
11070dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT;
11080dbacebeSHans Verkuil }
11090dbacebeSHans Verkuil 
11100dbacebeSHans Verkuil static inline void cec_msg_tuner_step_increment(struct cec_msg *msg)
11110dbacebeSHans Verkuil {
11120dbacebeSHans Verkuil 	msg->len = 2;
11130dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT;
11140dbacebeSHans Verkuil }
11150dbacebeSHans Verkuil 
11160dbacebeSHans Verkuil 
11170dbacebeSHans Verkuil /* Vendor Specific Commands Feature */
11180dbacebeSHans Verkuil static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id)
11190dbacebeSHans Verkuil {
11200dbacebeSHans Verkuil 	msg->len = 5;
11210dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
11220dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID;
11230dbacebeSHans Verkuil 	msg->msg[2] = vendor_id >> 16;
11240dbacebeSHans Verkuil 	msg->msg[3] = (vendor_id >> 8) & 0xff;
11250dbacebeSHans Verkuil 	msg->msg[4] = vendor_id & 0xff;
11260dbacebeSHans Verkuil }
11270dbacebeSHans Verkuil 
11280dbacebeSHans Verkuil static inline void cec_ops_device_vendor_id(const struct cec_msg *msg,
11290dbacebeSHans Verkuil 					    __u32 *vendor_id)
11300dbacebeSHans Verkuil {
11310dbacebeSHans Verkuil 	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
11320dbacebeSHans Verkuil }
11330dbacebeSHans Verkuil 
11340dbacebeSHans Verkuil static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg,
11353145c754SHans Verkuil 						 int reply)
11360dbacebeSHans Verkuil {
11370dbacebeSHans Verkuil 	msg->len = 2;
11380dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID;
11390dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0;
11400dbacebeSHans Verkuil }
11410dbacebeSHans Verkuil 
11420dbacebeSHans Verkuil static inline void cec_msg_vendor_command(struct cec_msg *msg,
11430dbacebeSHans Verkuil 					  __u8 size, const __u8 *vendor_cmd)
11440dbacebeSHans Verkuil {
11450dbacebeSHans Verkuil 	if (size > 14)
11460dbacebeSHans Verkuil 		size = 14;
11470dbacebeSHans Verkuil 	msg->len = 2 + size;
11480dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_COMMAND;
11490dbacebeSHans Verkuil 	memcpy(msg->msg + 2, vendor_cmd, size);
11500dbacebeSHans Verkuil }
11510dbacebeSHans Verkuil 
11520dbacebeSHans Verkuil static inline void cec_ops_vendor_command(const struct cec_msg *msg,
11530dbacebeSHans Verkuil 					  __u8 *size,
11540dbacebeSHans Verkuil 					  const __u8 **vendor_cmd)
11550dbacebeSHans Verkuil {
11560dbacebeSHans Verkuil 	*size = msg->len - 2;
11570dbacebeSHans Verkuil 
11580dbacebeSHans Verkuil 	if (*size > 14)
11590dbacebeSHans Verkuil 		*size = 14;
11600dbacebeSHans Verkuil 	*vendor_cmd = msg->msg + 2;
11610dbacebeSHans Verkuil }
11620dbacebeSHans Verkuil 
11630dbacebeSHans Verkuil static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg,
11640dbacebeSHans Verkuil 						  __u32 vendor_id, __u8 size,
11650dbacebeSHans Verkuil 						  const __u8 *vendor_cmd)
11660dbacebeSHans Verkuil {
11670dbacebeSHans Verkuil 	if (size > 11)
11680dbacebeSHans Verkuil 		size = 11;
11690dbacebeSHans Verkuil 	msg->len = 5 + size;
11700dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID;
11710dbacebeSHans Verkuil 	msg->msg[2] = vendor_id >> 16;
11720dbacebeSHans Verkuil 	msg->msg[3] = (vendor_id >> 8) & 0xff;
11730dbacebeSHans Verkuil 	msg->msg[4] = vendor_id & 0xff;
11740dbacebeSHans Verkuil 	memcpy(msg->msg + 5, vendor_cmd, size);
11750dbacebeSHans Verkuil }
11760dbacebeSHans Verkuil 
11770dbacebeSHans Verkuil static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg,
11780dbacebeSHans Verkuil 						  __u32 *vendor_id,  __u8 *size,
11790dbacebeSHans Verkuil 						  const __u8 **vendor_cmd)
11800dbacebeSHans Verkuil {
11810dbacebeSHans Verkuil 	*size = msg->len - 5;
11820dbacebeSHans Verkuil 
11830dbacebeSHans Verkuil 	if (*size > 11)
11840dbacebeSHans Verkuil 		*size = 11;
11850dbacebeSHans Verkuil 	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
11860dbacebeSHans Verkuil 	*vendor_cmd = msg->msg + 5;
11870dbacebeSHans Verkuil }
11880dbacebeSHans Verkuil 
11890dbacebeSHans Verkuil static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg,
11900dbacebeSHans Verkuil 						     __u8 size,
11910dbacebeSHans Verkuil 						     const __u8 *rc_code)
11920dbacebeSHans Verkuil {
11930dbacebeSHans Verkuil 	if (size > 14)
11940dbacebeSHans Verkuil 		size = 14;
11950dbacebeSHans Verkuil 	msg->len = 2 + size;
11960dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN;
11970dbacebeSHans Verkuil 	memcpy(msg->msg + 2, rc_code, size);
11980dbacebeSHans Verkuil }
11990dbacebeSHans Verkuil 
12000dbacebeSHans Verkuil static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg,
12010dbacebeSHans Verkuil 						     __u8 *size,
12020dbacebeSHans Verkuil 						     const __u8 **rc_code)
12030dbacebeSHans Verkuil {
12040dbacebeSHans Verkuil 	*size = msg->len - 2;
12050dbacebeSHans Verkuil 
12060dbacebeSHans Verkuil 	if (*size > 14)
12070dbacebeSHans Verkuil 		*size = 14;
12080dbacebeSHans Verkuil 	*rc_code = msg->msg + 2;
12090dbacebeSHans Verkuil }
12100dbacebeSHans Verkuil 
12110dbacebeSHans Verkuil static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg)
12120dbacebeSHans Verkuil {
12130dbacebeSHans Verkuil 	msg->len = 2;
12140dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP;
12150dbacebeSHans Verkuil }
12160dbacebeSHans Verkuil 
12170dbacebeSHans Verkuil 
12180dbacebeSHans Verkuil /* OSD Display Feature */
12190dbacebeSHans Verkuil static inline void cec_msg_set_osd_string(struct cec_msg *msg,
12200dbacebeSHans Verkuil 					  __u8 disp_ctl,
12210dbacebeSHans Verkuil 					  const char *osd)
12220dbacebeSHans Verkuil {
12230dbacebeSHans Verkuil 	unsigned int len = strlen(osd);
12240dbacebeSHans Verkuil 
12250dbacebeSHans Verkuil 	if (len > 13)
12260dbacebeSHans Verkuil 		len = 13;
12270dbacebeSHans Verkuil 	msg->len = 3 + len;
12280dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_OSD_STRING;
12290dbacebeSHans Verkuil 	msg->msg[2] = disp_ctl;
12300dbacebeSHans Verkuil 	memcpy(msg->msg + 3, osd, len);
12310dbacebeSHans Verkuil }
12320dbacebeSHans Verkuil 
12330dbacebeSHans Verkuil static inline void cec_ops_set_osd_string(const struct cec_msg *msg,
12340dbacebeSHans Verkuil 					  __u8 *disp_ctl,
12350dbacebeSHans Verkuil 					  char *osd)
12360dbacebeSHans Verkuil {
12370dbacebeSHans Verkuil 	unsigned int len = msg->len > 3 ? msg->len - 3 : 0;
12380dbacebeSHans Verkuil 
12390dbacebeSHans Verkuil 	*disp_ctl = msg->msg[2];
12400dbacebeSHans Verkuil 	if (len > 13)
12410dbacebeSHans Verkuil 		len = 13;
12420dbacebeSHans Verkuil 	memcpy(osd, msg->msg + 3, len);
12430dbacebeSHans Verkuil 	osd[len] = '\0';
12440dbacebeSHans Verkuil }
12450dbacebeSHans Verkuil 
12460dbacebeSHans Verkuil 
12470dbacebeSHans Verkuil /* Device OSD Transfer Feature */
12480dbacebeSHans Verkuil static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name)
12490dbacebeSHans Verkuil {
12500dbacebeSHans Verkuil 	unsigned int len = strlen(name);
12510dbacebeSHans Verkuil 
12520dbacebeSHans Verkuil 	if (len > 14)
12530dbacebeSHans Verkuil 		len = 14;
12540dbacebeSHans Verkuil 	msg->len = 2 + len;
12550dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_OSD_NAME;
12560dbacebeSHans Verkuil 	memcpy(msg->msg + 2, name, len);
12570dbacebeSHans Verkuil }
12580dbacebeSHans Verkuil 
12590dbacebeSHans Verkuil static inline void cec_ops_set_osd_name(const struct cec_msg *msg,
12600dbacebeSHans Verkuil 					char *name)
12610dbacebeSHans Verkuil {
12620dbacebeSHans Verkuil 	unsigned int len = msg->len > 2 ? msg->len - 2 : 0;
12630dbacebeSHans Verkuil 
12640dbacebeSHans Verkuil 	if (len > 14)
12650dbacebeSHans Verkuil 		len = 14;
12660dbacebeSHans Verkuil 	memcpy(name, msg->msg + 2, len);
12670dbacebeSHans Verkuil 	name[len] = '\0';
12680dbacebeSHans Verkuil }
12690dbacebeSHans Verkuil 
12700dbacebeSHans Verkuil static inline void cec_msg_give_osd_name(struct cec_msg *msg,
12713145c754SHans Verkuil 					 int reply)
12720dbacebeSHans Verkuil {
12730dbacebeSHans Verkuil 	msg->len = 2;
12740dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_OSD_NAME;
12750dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0;
12760dbacebeSHans Verkuil }
12770dbacebeSHans Verkuil 
12780dbacebeSHans Verkuil 
12790dbacebeSHans Verkuil /* Device Menu Control Feature */
12800dbacebeSHans Verkuil static inline void cec_msg_menu_status(struct cec_msg *msg,
12810dbacebeSHans Verkuil 				       __u8 menu_state)
12820dbacebeSHans Verkuil {
12830dbacebeSHans Verkuil 	msg->len = 3;
12840dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_MENU_STATUS;
12850dbacebeSHans Verkuil 	msg->msg[2] = menu_state;
12860dbacebeSHans Verkuil }
12870dbacebeSHans Verkuil 
12880dbacebeSHans Verkuil static inline void cec_ops_menu_status(const struct cec_msg *msg,
12890dbacebeSHans Verkuil 				       __u8 *menu_state)
12900dbacebeSHans Verkuil {
12910dbacebeSHans Verkuil 	*menu_state = msg->msg[2];
12920dbacebeSHans Verkuil }
12930dbacebeSHans Verkuil 
12940dbacebeSHans Verkuil static inline void cec_msg_menu_request(struct cec_msg *msg,
12953145c754SHans Verkuil 					int reply,
12960dbacebeSHans Verkuil 					__u8 menu_req)
12970dbacebeSHans Verkuil {
12980dbacebeSHans Verkuil 	msg->len = 3;
12990dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_MENU_REQUEST;
13000dbacebeSHans Verkuil 	msg->msg[2] = menu_req;
13010dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_MENU_STATUS : 0;
13020dbacebeSHans Verkuil }
13030dbacebeSHans Verkuil 
13040dbacebeSHans Verkuil static inline void cec_ops_menu_request(const struct cec_msg *msg,
13050dbacebeSHans Verkuil 					__u8 *menu_req)
13060dbacebeSHans Verkuil {
13070dbacebeSHans Verkuil 	*menu_req = msg->msg[2];
13080dbacebeSHans Verkuil }
13090dbacebeSHans Verkuil 
13100dbacebeSHans Verkuil struct cec_op_ui_command {
13110dbacebeSHans Verkuil 	__u8 ui_cmd;
13123145c754SHans Verkuil 	__u8 has_opt_arg;
13130dbacebeSHans Verkuil 	union {
13140dbacebeSHans Verkuil 		struct cec_op_channel_data channel_identifier;
13150dbacebeSHans Verkuil 		__u8 ui_broadcast_type;
13160dbacebeSHans Verkuil 		__u8 ui_sound_presentation_control;
13170dbacebeSHans Verkuil 		__u8 play_mode;
13180dbacebeSHans Verkuil 		__u8 ui_function_media;
13190dbacebeSHans Verkuil 		__u8 ui_function_select_av_input;
13200dbacebeSHans Verkuil 		__u8 ui_function_select_audio_input;
13210dbacebeSHans Verkuil 	};
13220dbacebeSHans Verkuil };
13230dbacebeSHans Verkuil 
13240dbacebeSHans Verkuil static inline void cec_msg_user_control_pressed(struct cec_msg *msg,
13250dbacebeSHans Verkuil 					const struct cec_op_ui_command *ui_cmd)
13260dbacebeSHans Verkuil {
13270dbacebeSHans Verkuil 	msg->len = 3;
13280dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED;
13290dbacebeSHans Verkuil 	msg->msg[2] = ui_cmd->ui_cmd;
13300dbacebeSHans Verkuil 	if (!ui_cmd->has_opt_arg)
13310dbacebeSHans Verkuil 		return;
13320dbacebeSHans Verkuil 	switch (ui_cmd->ui_cmd) {
13330dbacebeSHans Verkuil 	case 0x56:
13340dbacebeSHans Verkuil 	case 0x57:
13350dbacebeSHans Verkuil 	case 0x60:
13360dbacebeSHans Verkuil 	case 0x68:
13370dbacebeSHans Verkuil 	case 0x69:
13380dbacebeSHans Verkuil 	case 0x6a:
13390dbacebeSHans Verkuil 		/* The optional operand is one byte for all these ui commands */
13400dbacebeSHans Verkuil 		msg->len++;
13410dbacebeSHans Verkuil 		msg->msg[3] = ui_cmd->play_mode;
13420dbacebeSHans Verkuil 		break;
13430dbacebeSHans Verkuil 	case 0x67:
13440dbacebeSHans Verkuil 		msg->len += 4;
13450dbacebeSHans Verkuil 		msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) |
13460dbacebeSHans Verkuil 			      (ui_cmd->channel_identifier.major >> 8);
13470dbacebeSHans Verkuil 		msg->msg[4] = ui_cmd->channel_identifier.major & 0xff;
13480dbacebeSHans Verkuil 		msg->msg[5] = ui_cmd->channel_identifier.minor >> 8;
13490dbacebeSHans Verkuil 		msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff;
13500dbacebeSHans Verkuil 		break;
13510dbacebeSHans Verkuil 	}
13520dbacebeSHans Verkuil }
13530dbacebeSHans Verkuil 
13540dbacebeSHans Verkuil static inline void cec_ops_user_control_pressed(const struct cec_msg *msg,
13550dbacebeSHans Verkuil 						struct cec_op_ui_command *ui_cmd)
13560dbacebeSHans Verkuil {
13570dbacebeSHans Verkuil 	ui_cmd->ui_cmd = msg->msg[2];
13583145c754SHans Verkuil 	ui_cmd->has_opt_arg = 0;
13590dbacebeSHans Verkuil 	if (msg->len == 3)
13600dbacebeSHans Verkuil 		return;
13610dbacebeSHans Verkuil 	switch (ui_cmd->ui_cmd) {
13620dbacebeSHans Verkuil 	case 0x56:
13630dbacebeSHans Verkuil 	case 0x57:
13640dbacebeSHans Verkuil 	case 0x60:
13650dbacebeSHans Verkuil 	case 0x68:
13660dbacebeSHans Verkuil 	case 0x69:
13670dbacebeSHans Verkuil 	case 0x6a:
13680dbacebeSHans Verkuil 		/* The optional operand is one byte for all these ui commands */
13690dbacebeSHans Verkuil 		ui_cmd->play_mode = msg->msg[3];
13703145c754SHans Verkuil 		ui_cmd->has_opt_arg = 1;
13710dbacebeSHans Verkuil 		break;
13720dbacebeSHans Verkuil 	case 0x67:
13730dbacebeSHans Verkuil 		if (msg->len < 7)
13740dbacebeSHans Verkuil 			break;
13753145c754SHans Verkuil 		ui_cmd->has_opt_arg = 1;
13760dbacebeSHans Verkuil 		ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2;
13770dbacebeSHans Verkuil 		ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4];
13780dbacebeSHans Verkuil 		ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6];
13790dbacebeSHans Verkuil 		break;
13800dbacebeSHans Verkuil 	}
13810dbacebeSHans Verkuil }
13820dbacebeSHans Verkuil 
13830dbacebeSHans Verkuil static inline void cec_msg_user_control_released(struct cec_msg *msg)
13840dbacebeSHans Verkuil {
13850dbacebeSHans Verkuil 	msg->len = 2;
13860dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED;
13870dbacebeSHans Verkuil }
13880dbacebeSHans Verkuil 
13890dbacebeSHans Verkuil /* Remote Control Passthrough Feature */
13900dbacebeSHans Verkuil 
13910dbacebeSHans Verkuil /* Power Status Feature */
13920dbacebeSHans Verkuil static inline void cec_msg_report_power_status(struct cec_msg *msg,
13930dbacebeSHans Verkuil 					       __u8 pwr_state)
13940dbacebeSHans Verkuil {
13950dbacebeSHans Verkuil 	msg->len = 3;
13960dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS;
13970dbacebeSHans Verkuil 	msg->msg[2] = pwr_state;
13980dbacebeSHans Verkuil }
13990dbacebeSHans Verkuil 
14000dbacebeSHans Verkuil static inline void cec_ops_report_power_status(const struct cec_msg *msg,
14010dbacebeSHans Verkuil 					       __u8 *pwr_state)
14020dbacebeSHans Verkuil {
14030dbacebeSHans Verkuil 	*pwr_state = msg->msg[2];
14040dbacebeSHans Verkuil }
14050dbacebeSHans Verkuil 
14060dbacebeSHans Verkuil static inline void cec_msg_give_device_power_status(struct cec_msg *msg,
14073145c754SHans Verkuil 						    int reply)
14080dbacebeSHans Verkuil {
14090dbacebeSHans Verkuil 	msg->len = 2;
14100dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS;
14110dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0;
14120dbacebeSHans Verkuil }
14130dbacebeSHans Verkuil 
14140dbacebeSHans Verkuil /* General Protocol Messages */
14150dbacebeSHans Verkuil static inline void cec_msg_feature_abort(struct cec_msg *msg,
14160dbacebeSHans Verkuil 					 __u8 abort_msg, __u8 reason)
14170dbacebeSHans Verkuil {
14180dbacebeSHans Verkuil 	msg->len = 4;
14190dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_FEATURE_ABORT;
14200dbacebeSHans Verkuil 	msg->msg[2] = abort_msg;
14210dbacebeSHans Verkuil 	msg->msg[3] = reason;
14220dbacebeSHans Verkuil }
14230dbacebeSHans Verkuil 
14240dbacebeSHans Verkuil static inline void cec_ops_feature_abort(const struct cec_msg *msg,
14250dbacebeSHans Verkuil 					 __u8 *abort_msg, __u8 *reason)
14260dbacebeSHans Verkuil {
14270dbacebeSHans Verkuil 	*abort_msg = msg->msg[2];
14280dbacebeSHans Verkuil 	*reason = msg->msg[3];
14290dbacebeSHans Verkuil }
14300dbacebeSHans Verkuil 
14310dbacebeSHans Verkuil /* This changes the current message into a feature abort message */
14320dbacebeSHans Verkuil static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason)
14330dbacebeSHans Verkuil {
14340dbacebeSHans Verkuil 	cec_msg_set_reply_to(msg, msg);
14350dbacebeSHans Verkuil 	msg->len = 4;
14360dbacebeSHans Verkuil 	msg->msg[2] = msg->msg[1];
14370dbacebeSHans Verkuil 	msg->msg[3] = reason;
14380dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_FEATURE_ABORT;
14390dbacebeSHans Verkuil }
14400dbacebeSHans Verkuil 
14410dbacebeSHans Verkuil static inline void cec_msg_abort(struct cec_msg *msg)
14420dbacebeSHans Verkuil {
14430dbacebeSHans Verkuil 	msg->len = 2;
14440dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_ABORT;
14450dbacebeSHans Verkuil }
14460dbacebeSHans Verkuil 
14470dbacebeSHans Verkuil 
14480dbacebeSHans Verkuil /* System Audio Control Feature */
14490dbacebeSHans Verkuil static inline void cec_msg_report_audio_status(struct cec_msg *msg,
14500dbacebeSHans Verkuil 					       __u8 aud_mute_status,
14510dbacebeSHans Verkuil 					       __u8 aud_vol_status)
14520dbacebeSHans Verkuil {
14530dbacebeSHans Verkuil 	msg->len = 3;
14540dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS;
14550dbacebeSHans Verkuil 	msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f);
14560dbacebeSHans Verkuil }
14570dbacebeSHans Verkuil 
14580dbacebeSHans Verkuil static inline void cec_ops_report_audio_status(const struct cec_msg *msg,
14590dbacebeSHans Verkuil 					       __u8 *aud_mute_status,
14600dbacebeSHans Verkuil 					       __u8 *aud_vol_status)
14610dbacebeSHans Verkuil {
14620dbacebeSHans Verkuil 	*aud_mute_status = msg->msg[2] >> 7;
14630dbacebeSHans Verkuil 	*aud_vol_status = msg->msg[2] & 0x7f;
14640dbacebeSHans Verkuil }
14650dbacebeSHans Verkuil 
14660dbacebeSHans Verkuil static inline void cec_msg_give_audio_status(struct cec_msg *msg,
14673145c754SHans Verkuil 					     int reply)
14680dbacebeSHans Verkuil {
14690dbacebeSHans Verkuil 	msg->len = 2;
14700dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS;
14710dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0;
14720dbacebeSHans Verkuil }
14730dbacebeSHans Verkuil 
14740dbacebeSHans Verkuil static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg,
14750dbacebeSHans Verkuil 						 __u8 sys_aud_status)
14760dbacebeSHans Verkuil {
14770dbacebeSHans Verkuil 	msg->len = 3;
14780dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE;
14790dbacebeSHans Verkuil 	msg->msg[2] = sys_aud_status;
14800dbacebeSHans Verkuil }
14810dbacebeSHans Verkuil 
14820dbacebeSHans Verkuil static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg,
14830dbacebeSHans Verkuil 						 __u8 *sys_aud_status)
14840dbacebeSHans Verkuil {
14850dbacebeSHans Verkuil 	*sys_aud_status = msg->msg[2];
14860dbacebeSHans Verkuil }
14870dbacebeSHans Verkuil 
14880dbacebeSHans Verkuil static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg,
14893145c754SHans Verkuil 						     int reply,
14900dbacebeSHans Verkuil 						     __u16 phys_addr)
14910dbacebeSHans Verkuil {
14920dbacebeSHans Verkuil 	msg->len = phys_addr == 0xffff ? 2 : 4;
14930dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST;
14940dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
14950dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
14960dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0;
14970dbacebeSHans Verkuil 
14980dbacebeSHans Verkuil }
14990dbacebeSHans Verkuil 
15000dbacebeSHans Verkuil static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg,
15010dbacebeSHans Verkuil 						     __u16 *phys_addr)
15020dbacebeSHans Verkuil {
15030dbacebeSHans Verkuil 	if (msg->len < 4)
15040dbacebeSHans Verkuil 		*phys_addr = 0xffff;
15050dbacebeSHans Verkuil 	else
15060dbacebeSHans Verkuil 		*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
15070dbacebeSHans Verkuil }
15080dbacebeSHans Verkuil 
15090dbacebeSHans Verkuil static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg,
15100dbacebeSHans Verkuil 						    __u8 sys_aud_status)
15110dbacebeSHans Verkuil {
15120dbacebeSHans Verkuil 	msg->len = 3;
15130dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS;
15140dbacebeSHans Verkuil 	msg->msg[2] = sys_aud_status;
15150dbacebeSHans Verkuil }
15160dbacebeSHans Verkuil 
15170dbacebeSHans Verkuil static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg,
15180dbacebeSHans Verkuil 						    __u8 *sys_aud_status)
15190dbacebeSHans Verkuil {
15200dbacebeSHans Verkuil 	*sys_aud_status = msg->msg[2];
15210dbacebeSHans Verkuil }
15220dbacebeSHans Verkuil 
15230dbacebeSHans Verkuil static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg,
15243145c754SHans Verkuil 							 int reply)
15250dbacebeSHans Verkuil {
15260dbacebeSHans Verkuil 	msg->len = 2;
15270dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS;
15280dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0;
15290dbacebeSHans Verkuil }
15300dbacebeSHans Verkuil 
15310dbacebeSHans Verkuil static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg,
15320dbacebeSHans Verkuil 					__u8 num_descriptors,
15330dbacebeSHans Verkuil 					const __u32 *descriptors)
15340dbacebeSHans Verkuil {
15350dbacebeSHans Verkuil 	unsigned int i;
15360dbacebeSHans Verkuil 
15370dbacebeSHans Verkuil 	if (num_descriptors > 4)
15380dbacebeSHans Verkuil 		num_descriptors = 4;
15390dbacebeSHans Verkuil 	msg->len = 2 + num_descriptors * 3;
15400dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR;
15410dbacebeSHans Verkuil 	for (i = 0; i < num_descriptors; i++) {
15420dbacebeSHans Verkuil 		msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff;
15430dbacebeSHans Verkuil 		msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff;
15440dbacebeSHans Verkuil 		msg->msg[4 + i * 3] = descriptors[i] & 0xff;
15450dbacebeSHans Verkuil 	}
15460dbacebeSHans Verkuil }
15470dbacebeSHans Verkuil 
15480dbacebeSHans Verkuil static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg,
15490dbacebeSHans Verkuil 							 __u8 *num_descriptors,
15500dbacebeSHans Verkuil 							 __u32 *descriptors)
15510dbacebeSHans Verkuil {
15520dbacebeSHans Verkuil 	unsigned int i;
15530dbacebeSHans Verkuil 
15540dbacebeSHans Verkuil 	*num_descriptors = (msg->len - 2) / 3;
15550dbacebeSHans Verkuil 	if (*num_descriptors > 4)
15560dbacebeSHans Verkuil 		*num_descriptors = 4;
15570dbacebeSHans Verkuil 	for (i = 0; i < *num_descriptors; i++)
15580dbacebeSHans Verkuil 		descriptors[i] = (msg->msg[2 + i * 3] << 16) |
15590dbacebeSHans Verkuil 			(msg->msg[3 + i * 3] << 8) |
15600dbacebeSHans Verkuil 			msg->msg[4 + i * 3];
15610dbacebeSHans Verkuil }
15620dbacebeSHans Verkuil 
15630dbacebeSHans Verkuil static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg,
15643145c754SHans Verkuil 					int reply,
15650dbacebeSHans Verkuil 					__u8 num_descriptors,
15660dbacebeSHans Verkuil 					const __u8 *audio_format_id,
15670dbacebeSHans Verkuil 					const __u8 *audio_format_code)
15680dbacebeSHans Verkuil {
15690dbacebeSHans Verkuil 	unsigned int i;
15700dbacebeSHans Verkuil 
15710dbacebeSHans Verkuil 	if (num_descriptors > 4)
15720dbacebeSHans Verkuil 		num_descriptors = 4;
15730dbacebeSHans Verkuil 	msg->len = 2 + num_descriptors;
15740dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR;
15750dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0;
15760dbacebeSHans Verkuil 	for (i = 0; i < num_descriptors; i++)
15770dbacebeSHans Verkuil 		msg->msg[2 + i] = (audio_format_id[i] << 6) |
15780dbacebeSHans Verkuil 				  (audio_format_code[i] & 0x3f);
15790dbacebeSHans Verkuil }
15800dbacebeSHans Verkuil 
15810dbacebeSHans Verkuil static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg,
15820dbacebeSHans Verkuil 					__u8 *num_descriptors,
15830dbacebeSHans Verkuil 					__u8 *audio_format_id,
15840dbacebeSHans Verkuil 					__u8 *audio_format_code)
15850dbacebeSHans Verkuil {
15860dbacebeSHans Verkuil 	unsigned int i;
15870dbacebeSHans Verkuil 
15880dbacebeSHans Verkuil 	*num_descriptors = msg->len - 2;
15890dbacebeSHans Verkuil 	if (*num_descriptors > 4)
15900dbacebeSHans Verkuil 		*num_descriptors = 4;
15910dbacebeSHans Verkuil 	for (i = 0; i < *num_descriptors; i++) {
15920dbacebeSHans Verkuil 		audio_format_id[i] = msg->msg[2 + i] >> 6;
15930dbacebeSHans Verkuil 		audio_format_code[i] = msg->msg[2 + i] & 0x3f;
15940dbacebeSHans Verkuil 	}
15950dbacebeSHans Verkuil }
15960dbacebeSHans Verkuil 
15970dbacebeSHans Verkuil 
15980dbacebeSHans Verkuil /* Audio Rate Control Feature */
15990dbacebeSHans Verkuil static inline void cec_msg_set_audio_rate(struct cec_msg *msg,
16000dbacebeSHans Verkuil 					  __u8 audio_rate)
16010dbacebeSHans Verkuil {
16020dbacebeSHans Verkuil 	msg->len = 3;
16030dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_AUDIO_RATE;
16040dbacebeSHans Verkuil 	msg->msg[2] = audio_rate;
16050dbacebeSHans Verkuil }
16060dbacebeSHans Verkuil 
16070dbacebeSHans Verkuil static inline void cec_ops_set_audio_rate(const struct cec_msg *msg,
16080dbacebeSHans Verkuil 					  __u8 *audio_rate)
16090dbacebeSHans Verkuil {
16100dbacebeSHans Verkuil 	*audio_rate = msg->msg[2];
16110dbacebeSHans Verkuil }
16120dbacebeSHans Verkuil 
16130dbacebeSHans Verkuil 
16140dbacebeSHans Verkuil /* Audio Return Channel Control Feature */
16150dbacebeSHans Verkuil static inline void cec_msg_report_arc_initiated(struct cec_msg *msg)
16160dbacebeSHans Verkuil {
16170dbacebeSHans Verkuil 	msg->len = 2;
16180dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED;
16190dbacebeSHans Verkuil }
16200dbacebeSHans Verkuil 
16210dbacebeSHans Verkuil static inline void cec_msg_initiate_arc(struct cec_msg *msg,
16223145c754SHans Verkuil 					int reply)
16230dbacebeSHans Verkuil {
16240dbacebeSHans Verkuil 	msg->len = 2;
16250dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_INITIATE_ARC;
16260dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0;
16270dbacebeSHans Verkuil }
16280dbacebeSHans Verkuil 
16290dbacebeSHans Verkuil static inline void cec_msg_request_arc_initiation(struct cec_msg *msg,
16303145c754SHans Verkuil 						  int reply)
16310dbacebeSHans Verkuil {
16320dbacebeSHans Verkuil 	msg->len = 2;
16330dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION;
16340dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0;
16350dbacebeSHans Verkuil }
16360dbacebeSHans Verkuil 
16370dbacebeSHans Verkuil static inline void cec_msg_report_arc_terminated(struct cec_msg *msg)
16380dbacebeSHans Verkuil {
16390dbacebeSHans Verkuil 	msg->len = 2;
16400dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED;
16410dbacebeSHans Verkuil }
16420dbacebeSHans Verkuil 
16430dbacebeSHans Verkuil static inline void cec_msg_terminate_arc(struct cec_msg *msg,
16443145c754SHans Verkuil 					 int reply)
16450dbacebeSHans Verkuil {
16460dbacebeSHans Verkuil 	msg->len = 2;
16470dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TERMINATE_ARC;
16480dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0;
16490dbacebeSHans Verkuil }
16500dbacebeSHans Verkuil 
16510dbacebeSHans Verkuil static inline void cec_msg_request_arc_termination(struct cec_msg *msg,
16523145c754SHans Verkuil 						   int reply)
16530dbacebeSHans Verkuil {
16540dbacebeSHans Verkuil 	msg->len = 2;
16550dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION;
16560dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0;
16570dbacebeSHans Verkuil }
16580dbacebeSHans Verkuil 
16590dbacebeSHans Verkuil 
16600dbacebeSHans Verkuil /* Dynamic Audio Lipsync Feature */
16610dbacebeSHans Verkuil /* Only for CEC 2.0 and up */
16620dbacebeSHans Verkuil static inline void cec_msg_report_current_latency(struct cec_msg *msg,
16630dbacebeSHans Verkuil 						  __u16 phys_addr,
16640dbacebeSHans Verkuil 						  __u8 video_latency,
16650dbacebeSHans Verkuil 						  __u8 low_latency_mode,
16660dbacebeSHans Verkuil 						  __u8 audio_out_compensated,
16670dbacebeSHans Verkuil 						  __u8 audio_out_delay)
16680dbacebeSHans Verkuil {
1669f3854973SHans Verkuil 	msg->len = 6;
16700dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
16710dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY;
16720dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
16730dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
16740dbacebeSHans Verkuil 	msg->msg[4] = video_latency;
16750dbacebeSHans Verkuil 	msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated;
1676f3854973SHans Verkuil 	if (audio_out_compensated == 3)
1677f3854973SHans Verkuil 		msg->msg[msg->len++] = audio_out_delay;
16780dbacebeSHans Verkuil }
16790dbacebeSHans Verkuil 
16800dbacebeSHans Verkuil static inline void cec_ops_report_current_latency(const struct cec_msg *msg,
16810dbacebeSHans Verkuil 						  __u16 *phys_addr,
16820dbacebeSHans Verkuil 						  __u8 *video_latency,
16830dbacebeSHans Verkuil 						  __u8 *low_latency_mode,
16840dbacebeSHans Verkuil 						  __u8 *audio_out_compensated,
16850dbacebeSHans Verkuil 						  __u8 *audio_out_delay)
16860dbacebeSHans Verkuil {
16870dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
16880dbacebeSHans Verkuil 	*video_latency = msg->msg[4];
16890dbacebeSHans Verkuil 	*low_latency_mode = (msg->msg[5] >> 2) & 1;
16900dbacebeSHans Verkuil 	*audio_out_compensated = msg->msg[5] & 3;
1691f3854973SHans Verkuil 	if (*audio_out_compensated == 3 && msg->len >= 7)
16920dbacebeSHans Verkuil 		*audio_out_delay = msg->msg[6];
1693f3854973SHans Verkuil 	else
1694f3854973SHans Verkuil 		*audio_out_delay = 0;
16950dbacebeSHans Verkuil }
16960dbacebeSHans Verkuil 
16970dbacebeSHans Verkuil static inline void cec_msg_request_current_latency(struct cec_msg *msg,
16983145c754SHans Verkuil 						   int reply,
16990dbacebeSHans Verkuil 						   __u16 phys_addr)
17000dbacebeSHans Verkuil {
17010dbacebeSHans Verkuil 	msg->len = 4;
17020dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17030dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY;
17040dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
17050dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
17060dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0;
17070dbacebeSHans Verkuil }
17080dbacebeSHans Verkuil 
17090dbacebeSHans Verkuil static inline void cec_ops_request_current_latency(const struct cec_msg *msg,
17100dbacebeSHans Verkuil 						   __u16 *phys_addr)
17110dbacebeSHans Verkuil {
17120dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
17130dbacebeSHans Verkuil }
17140dbacebeSHans Verkuil 
17150dbacebeSHans Verkuil 
17160dbacebeSHans Verkuil /* Capability Discovery and Control Feature */
17170dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg,
17180dbacebeSHans Verkuil 						 __u16 phys_addr1,
17190dbacebeSHans Verkuil 						 __u16 phys_addr2)
17200dbacebeSHans Verkuil {
17210dbacebeSHans Verkuil 	msg->len = 9;
17220dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17230dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
17240dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
17250dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;
17260dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
17270dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
17280dbacebeSHans Verkuil 	msg->msg[7] = phys_addr2 >> 8;
17290dbacebeSHans Verkuil 	msg->msg[8] = phys_addr2 & 0xff;
17300dbacebeSHans Verkuil }
17310dbacebeSHans Verkuil 
17320dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg,
17330dbacebeSHans Verkuil 						 __u16 *phys_addr,
17340dbacebeSHans Verkuil 						 __u16 *phys_addr1,
17350dbacebeSHans Verkuil 						 __u16 *phys_addr2)
17360dbacebeSHans Verkuil {
17370dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
17380dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
17390dbacebeSHans Verkuil 	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
17400dbacebeSHans Verkuil }
17410dbacebeSHans Verkuil 
17420dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg,
17430dbacebeSHans Verkuil 						__u16 target_phys_addr,
17440dbacebeSHans Verkuil 						__u8 hec_func_state,
17450dbacebeSHans Verkuil 						__u8 host_func_state,
17460dbacebeSHans Verkuil 						__u8 enc_func_state,
17470dbacebeSHans Verkuil 						__u8 cdc_errcode,
17480dbacebeSHans Verkuil 						__u8 has_field,
17490dbacebeSHans Verkuil 						__u16 hec_field)
17500dbacebeSHans Verkuil {
17510dbacebeSHans Verkuil 	msg->len = has_field ? 10 : 8;
17520dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17530dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
17540dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
17550dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE;
17560dbacebeSHans Verkuil 	msg->msg[5] = target_phys_addr >> 8;
17570dbacebeSHans Verkuil 	msg->msg[6] = target_phys_addr & 0xff;
17580dbacebeSHans Verkuil 	msg->msg[7] = (hec_func_state << 6) |
17590dbacebeSHans Verkuil 		      (host_func_state << 4) |
17600dbacebeSHans Verkuil 		      (enc_func_state << 2) |
17610dbacebeSHans Verkuil 		      cdc_errcode;
17620dbacebeSHans Verkuil 	if (has_field) {
17630dbacebeSHans Verkuil 		msg->msg[8] = hec_field >> 8;
17640dbacebeSHans Verkuil 		msg->msg[9] = hec_field & 0xff;
17650dbacebeSHans Verkuil 	}
17660dbacebeSHans Verkuil }
17670dbacebeSHans Verkuil 
17680dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg,
17690dbacebeSHans Verkuil 						__u16 *phys_addr,
17700dbacebeSHans Verkuil 						__u16 *target_phys_addr,
17710dbacebeSHans Verkuil 						__u8 *hec_func_state,
17720dbacebeSHans Verkuil 						__u8 *host_func_state,
17730dbacebeSHans Verkuil 						__u8 *enc_func_state,
17740dbacebeSHans Verkuil 						__u8 *cdc_errcode,
17750dbacebeSHans Verkuil 						__u8 *has_field,
17760dbacebeSHans Verkuil 						__u16 *hec_field)
17770dbacebeSHans Verkuil {
17780dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
17790dbacebeSHans Verkuil 	*target_phys_addr = (msg->msg[5] << 8) | msg->msg[6];
17800dbacebeSHans Verkuil 	*hec_func_state = msg->msg[7] >> 6;
17810dbacebeSHans Verkuil 	*host_func_state = (msg->msg[7] >> 4) & 3;
17820dbacebeSHans Verkuil 	*enc_func_state = (msg->msg[7] >> 4) & 3;
17830dbacebeSHans Verkuil 	*cdc_errcode = msg->msg[7] & 3;
17840dbacebeSHans Verkuil 	*has_field = msg->len >= 10;
17850dbacebeSHans Verkuil 	*hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0;
17860dbacebeSHans Verkuil }
17870dbacebeSHans Verkuil 
17880dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg,
17890dbacebeSHans Verkuil 					     __u16 phys_addr1,
17900dbacebeSHans Verkuil 					     __u16 phys_addr2,
17910dbacebeSHans Verkuil 					     __u8 hec_set_state,
17920dbacebeSHans Verkuil 					     __u16 phys_addr3,
17930dbacebeSHans Verkuil 					     __u16 phys_addr4,
17940dbacebeSHans Verkuil 					     __u16 phys_addr5)
17950dbacebeSHans Verkuil {
17960dbacebeSHans Verkuil 	msg->len = 10;
17970dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17980dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
17990dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
18000dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;
18010dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
18020dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
18030dbacebeSHans Verkuil 	msg->msg[7] = phys_addr2 >> 8;
18040dbacebeSHans Verkuil 	msg->msg[8] = phys_addr2 & 0xff;
18050dbacebeSHans Verkuil 	msg->msg[9] = hec_set_state;
18060dbacebeSHans Verkuil 	if (phys_addr3 != CEC_PHYS_ADDR_INVALID) {
18070dbacebeSHans Verkuil 		msg->msg[msg->len++] = phys_addr3 >> 8;
18080dbacebeSHans Verkuil 		msg->msg[msg->len++] = phys_addr3 & 0xff;
18090dbacebeSHans Verkuil 		if (phys_addr4 != CEC_PHYS_ADDR_INVALID) {
18100dbacebeSHans Verkuil 			msg->msg[msg->len++] = phys_addr4 >> 8;
18110dbacebeSHans Verkuil 			msg->msg[msg->len++] = phys_addr4 & 0xff;
18120dbacebeSHans Verkuil 			if (phys_addr5 != CEC_PHYS_ADDR_INVALID) {
18130dbacebeSHans Verkuil 				msg->msg[msg->len++] = phys_addr5 >> 8;
18140dbacebeSHans Verkuil 				msg->msg[msg->len++] = phys_addr5 & 0xff;
18150dbacebeSHans Verkuil 			}
18160dbacebeSHans Verkuil 		}
18170dbacebeSHans Verkuil 	}
18180dbacebeSHans Verkuil }
18190dbacebeSHans Verkuil 
18200dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg,
18210dbacebeSHans Verkuil 					     __u16 *phys_addr,
18220dbacebeSHans Verkuil 					     __u16 *phys_addr1,
18230dbacebeSHans Verkuil 					     __u16 *phys_addr2,
18240dbacebeSHans Verkuil 					     __u8 *hec_set_state,
18250dbacebeSHans Verkuil 					     __u16 *phys_addr3,
18260dbacebeSHans Verkuil 					     __u16 *phys_addr4,
18270dbacebeSHans Verkuil 					     __u16 *phys_addr5)
18280dbacebeSHans Verkuil {
18290dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
18300dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
18310dbacebeSHans Verkuil 	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
18320dbacebeSHans Verkuil 	*hec_set_state = msg->msg[9];
18330dbacebeSHans Verkuil 	*phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID;
18340dbacebeSHans Verkuil 	if (msg->len >= 12)
18350dbacebeSHans Verkuil 		*phys_addr3 = (msg->msg[10] << 8) | msg->msg[11];
18360dbacebeSHans Verkuil 	if (msg->len >= 14)
18370dbacebeSHans Verkuil 		*phys_addr4 = (msg->msg[12] << 8) | msg->msg[13];
18380dbacebeSHans Verkuil 	if (msg->len >= 16)
18390dbacebeSHans Verkuil 		*phys_addr5 = (msg->msg[14] << 8) | msg->msg[15];
18400dbacebeSHans Verkuil }
18410dbacebeSHans Verkuil 
18420dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg,
18430dbacebeSHans Verkuil 						      __u16 phys_addr1,
18440dbacebeSHans Verkuil 						      __u8 hec_set_state)
18450dbacebeSHans Verkuil {
18460dbacebeSHans Verkuil 	msg->len = 8;
18470dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
18480dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
18490dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
18500dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT;
18510dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
18520dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
18530dbacebeSHans Verkuil 	msg->msg[7] = hec_set_state;
18540dbacebeSHans Verkuil }
18550dbacebeSHans Verkuil 
18560dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg,
18570dbacebeSHans Verkuil 						      __u16 *phys_addr,
18580dbacebeSHans Verkuil 						      __u16 *phys_addr1,
18590dbacebeSHans Verkuil 						      __u8 *hec_set_state)
18600dbacebeSHans Verkuil {
18610dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
18620dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
18630dbacebeSHans Verkuil 	*hec_set_state = msg->msg[7];
18640dbacebeSHans Verkuil }
18650dbacebeSHans Verkuil 
18660dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg,
18670dbacebeSHans Verkuil 							__u16 phys_addr1,
18680dbacebeSHans Verkuil 							__u16 phys_addr2,
18690dbacebeSHans Verkuil 							__u16 phys_addr3)
18700dbacebeSHans Verkuil {
18710dbacebeSHans Verkuil 	msg->len = 11;
18720dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
18730dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
18740dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
18750dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION;
18760dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
18770dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
18780dbacebeSHans Verkuil 	msg->msg[7] = phys_addr2 >> 8;
18790dbacebeSHans Verkuil 	msg->msg[8] = phys_addr2 & 0xff;
18800dbacebeSHans Verkuil 	msg->msg[9] = phys_addr3 >> 8;
18810dbacebeSHans Verkuil 	msg->msg[10] = phys_addr3 & 0xff;
18820dbacebeSHans Verkuil }
18830dbacebeSHans Verkuil 
18840dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg,
18850dbacebeSHans Verkuil 							__u16 *phys_addr,
18860dbacebeSHans Verkuil 							__u16 *phys_addr1,
18870dbacebeSHans Verkuil 							__u16 *phys_addr2,
18880dbacebeSHans Verkuil 							__u16 *phys_addr3)
18890dbacebeSHans Verkuil {
18900dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
18910dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
18920dbacebeSHans Verkuil 	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
18930dbacebeSHans Verkuil 	*phys_addr3 = (msg->msg[9] << 8) | msg->msg[10];
18940dbacebeSHans Verkuil }
18950dbacebeSHans Verkuil 
18960dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg)
18970dbacebeSHans Verkuil {
18980dbacebeSHans Verkuil 	msg->len = 5;
18990dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19000dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19010dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19020dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE;
19030dbacebeSHans Verkuil }
19040dbacebeSHans Verkuil 
19050dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg,
19060dbacebeSHans Verkuil 						__u16 *phys_addr)
19070dbacebeSHans Verkuil {
19080dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19090dbacebeSHans Verkuil }
19100dbacebeSHans Verkuil 
19110dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg)
19120dbacebeSHans Verkuil {
19130dbacebeSHans Verkuil 	msg->len = 5;
19140dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19150dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19160dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19170dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER;
19180dbacebeSHans Verkuil }
19190dbacebeSHans Verkuil 
19200dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg,
19210dbacebeSHans Verkuil 					    __u16 *phys_addr)
19220dbacebeSHans Verkuil {
19230dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19240dbacebeSHans Verkuil }
19250dbacebeSHans Verkuil 
19260dbacebeSHans Verkuil static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg,
19270dbacebeSHans Verkuil 					     __u8 input_port,
19280dbacebeSHans Verkuil 					     __u8 hpd_state)
19290dbacebeSHans Verkuil {
19300dbacebeSHans Verkuil 	msg->len = 6;
19310dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19320dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19330dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19340dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE;
19350dbacebeSHans Verkuil 	msg->msg[5] = (input_port << 4) | hpd_state;
19360dbacebeSHans Verkuil }
19370dbacebeSHans Verkuil 
19380dbacebeSHans Verkuil static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg,
19390dbacebeSHans Verkuil 					    __u16 *phys_addr,
19400dbacebeSHans Verkuil 					    __u8 *input_port,
19410dbacebeSHans Verkuil 					    __u8 *hpd_state)
19420dbacebeSHans Verkuil {
19430dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19440dbacebeSHans Verkuil 	*input_port = msg->msg[5] >> 4;
19450dbacebeSHans Verkuil 	*hpd_state = msg->msg[5] & 0xf;
19460dbacebeSHans Verkuil }
19470dbacebeSHans Verkuil 
19480dbacebeSHans Verkuil static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg,
19490dbacebeSHans Verkuil 						__u8 hpd_state,
19500dbacebeSHans Verkuil 						__u8 hpd_error)
19510dbacebeSHans Verkuil {
19520dbacebeSHans Verkuil 	msg->len = 6;
19530dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19540dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19550dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19560dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE;
19570dbacebeSHans Verkuil 	msg->msg[5] = (hpd_state << 4) | hpd_error;
19580dbacebeSHans Verkuil }
19590dbacebeSHans Verkuil 
19600dbacebeSHans Verkuil static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg,
19610dbacebeSHans Verkuil 						__u16 *phys_addr,
19620dbacebeSHans Verkuil 						__u8 *hpd_state,
19630dbacebeSHans Verkuil 						__u8 *hpd_error)
19640dbacebeSHans Verkuil {
19650dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19660dbacebeSHans Verkuil 	*hpd_state = msg->msg[5] >> 4;
19670dbacebeSHans Verkuil 	*hpd_error = msg->msg[5] & 0xf;
19680dbacebeSHans Verkuil }
19690dbacebeSHans Verkuil 
19700dbacebeSHans Verkuil #endif
1971