xref: /openbmc/linux/include/uapi/linux/cec-funcs.h (revision f3854973)
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;
8980dbacebeSHans Verkuil 	while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT))
8990dbacebeSHans Verkuil 		p++;
9000dbacebeSHans Verkuil 	if (!(*p & CEC_OP_FEAT_EXT)) {
9010dbacebeSHans Verkuil 		*dev_features = p + 1;
9020dbacebeSHans Verkuil 		while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT))
9030dbacebeSHans Verkuil 			p++;
9040dbacebeSHans Verkuil 	}
9050dbacebeSHans Verkuil 	if (*p & CEC_OP_FEAT_EXT)
9060dbacebeSHans Verkuil 		*rc_profile = *dev_features = NULL;
9070dbacebeSHans Verkuil }
9080dbacebeSHans Verkuil 
9090dbacebeSHans Verkuil static inline void cec_msg_give_features(struct cec_msg *msg,
9103145c754SHans Verkuil 					 int reply)
9110dbacebeSHans Verkuil {
9120dbacebeSHans Verkuil 	msg->len = 2;
9130dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_FEATURES;
9140dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0;
9150dbacebeSHans Verkuil }
9160dbacebeSHans Verkuil 
9170dbacebeSHans Verkuil /* Deck Control Feature */
9180dbacebeSHans Verkuil static inline void cec_msg_deck_control(struct cec_msg *msg,
9190dbacebeSHans Verkuil 					__u8 deck_control_mode)
9200dbacebeSHans Verkuil {
9210dbacebeSHans Verkuil 	msg->len = 3;
9220dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_DECK_CONTROL;
9230dbacebeSHans Verkuil 	msg->msg[2] = deck_control_mode;
9240dbacebeSHans Verkuil }
9250dbacebeSHans Verkuil 
9260dbacebeSHans Verkuil static inline void cec_ops_deck_control(const struct cec_msg *msg,
9270dbacebeSHans Verkuil 					__u8 *deck_control_mode)
9280dbacebeSHans Verkuil {
9290dbacebeSHans Verkuil 	*deck_control_mode = msg->msg[2];
9300dbacebeSHans Verkuil }
9310dbacebeSHans Verkuil 
9320dbacebeSHans Verkuil static inline void cec_msg_deck_status(struct cec_msg *msg,
9330dbacebeSHans Verkuil 				       __u8 deck_info)
9340dbacebeSHans Verkuil {
9350dbacebeSHans Verkuil 	msg->len = 3;
9360dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_DECK_STATUS;
9370dbacebeSHans Verkuil 	msg->msg[2] = deck_info;
9380dbacebeSHans Verkuil }
9390dbacebeSHans Verkuil 
9400dbacebeSHans Verkuil static inline void cec_ops_deck_status(const struct cec_msg *msg,
9410dbacebeSHans Verkuil 				       __u8 *deck_info)
9420dbacebeSHans Verkuil {
9430dbacebeSHans Verkuil 	*deck_info = msg->msg[2];
9440dbacebeSHans Verkuil }
9450dbacebeSHans Verkuil 
9460dbacebeSHans Verkuil static inline void cec_msg_give_deck_status(struct cec_msg *msg,
9473145c754SHans Verkuil 					    int reply,
9480dbacebeSHans Verkuil 					    __u8 status_req)
9490dbacebeSHans Verkuil {
9500dbacebeSHans Verkuil 	msg->len = 3;
9510dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS;
9520dbacebeSHans Verkuil 	msg->msg[2] = status_req;
9530dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_DECK_STATUS : 0;
9540dbacebeSHans Verkuil }
9550dbacebeSHans Verkuil 
9560dbacebeSHans Verkuil static inline void cec_ops_give_deck_status(const struct cec_msg *msg,
9570dbacebeSHans Verkuil 					    __u8 *status_req)
9580dbacebeSHans Verkuil {
9590dbacebeSHans Verkuil 	*status_req = msg->msg[2];
9600dbacebeSHans Verkuil }
9610dbacebeSHans Verkuil 
9620dbacebeSHans Verkuil static inline void cec_msg_play(struct cec_msg *msg,
9630dbacebeSHans Verkuil 				__u8 play_mode)
9640dbacebeSHans Verkuil {
9650dbacebeSHans Verkuil 	msg->len = 3;
9660dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_PLAY;
9670dbacebeSHans Verkuil 	msg->msg[2] = play_mode;
9680dbacebeSHans Verkuil }
9690dbacebeSHans Verkuil 
9700dbacebeSHans Verkuil static inline void cec_ops_play(const struct cec_msg *msg,
9710dbacebeSHans Verkuil 				__u8 *play_mode)
9720dbacebeSHans Verkuil {
9730dbacebeSHans Verkuil 	*play_mode = msg->msg[2];
9740dbacebeSHans Verkuil }
9750dbacebeSHans Verkuil 
9760dbacebeSHans Verkuil 
9770dbacebeSHans Verkuil /* Tuner Control Feature */
9780dbacebeSHans Verkuil struct cec_op_tuner_device_info {
9790dbacebeSHans Verkuil 	__u8 rec_flag;
9800dbacebeSHans Verkuil 	__u8 tuner_display_info;
9813145c754SHans Verkuil 	__u8 is_analog;
9820dbacebeSHans Verkuil 	union {
9830dbacebeSHans Verkuil 		struct cec_op_digital_service_id digital;
9840dbacebeSHans Verkuil 		struct {
9850dbacebeSHans Verkuil 			__u8 ana_bcast_type;
9860dbacebeSHans Verkuil 			__u16 ana_freq;
9870dbacebeSHans Verkuil 			__u8 bcast_system;
9880dbacebeSHans Verkuil 		} analog;
9890dbacebeSHans Verkuil 	};
9900dbacebeSHans Verkuil };
9910dbacebeSHans Verkuil 
9920dbacebeSHans Verkuil static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg,
9930dbacebeSHans Verkuil 						      __u8 rec_flag,
9940dbacebeSHans Verkuil 						      __u8 tuner_display_info,
9950dbacebeSHans Verkuil 						      __u8 ana_bcast_type,
9960dbacebeSHans Verkuil 						      __u16 ana_freq,
9970dbacebeSHans Verkuil 						      __u8 bcast_system)
9980dbacebeSHans Verkuil {
9990dbacebeSHans Verkuil 	msg->len = 7;
10000dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
10010dbacebeSHans Verkuil 	msg->msg[2] = (rec_flag << 7) | tuner_display_info;
10020dbacebeSHans Verkuil 	msg->msg[3] = ana_bcast_type;
10030dbacebeSHans Verkuil 	msg->msg[4] = ana_freq >> 8;
10040dbacebeSHans Verkuil 	msg->msg[5] = ana_freq & 0xff;
10050dbacebeSHans Verkuil 	msg->msg[6] = bcast_system;
10060dbacebeSHans Verkuil }
10070dbacebeSHans Verkuil 
10080dbacebeSHans Verkuil static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg,
10090dbacebeSHans Verkuil 		   __u8 rec_flag, __u8 tuner_display_info,
10100dbacebeSHans Verkuil 		   const struct cec_op_digital_service_id *digital)
10110dbacebeSHans Verkuil {
10120dbacebeSHans Verkuil 	msg->len = 10;
10130dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
10140dbacebeSHans Verkuil 	msg->msg[2] = (rec_flag << 7) | tuner_display_info;
10150dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 3, digital);
10160dbacebeSHans Verkuil }
10170dbacebeSHans Verkuil 
10180dbacebeSHans Verkuil static inline void cec_msg_tuner_device_status(struct cec_msg *msg,
10190dbacebeSHans Verkuil 			const struct cec_op_tuner_device_info *tuner_dev_info)
10200dbacebeSHans Verkuil {
10210dbacebeSHans Verkuil 	if (tuner_dev_info->is_analog)
10220dbacebeSHans Verkuil 		cec_msg_tuner_device_status_analog(msg,
10230dbacebeSHans Verkuil 			tuner_dev_info->rec_flag,
10240dbacebeSHans Verkuil 			tuner_dev_info->tuner_display_info,
10250dbacebeSHans Verkuil 			tuner_dev_info->analog.ana_bcast_type,
10260dbacebeSHans Verkuil 			tuner_dev_info->analog.ana_freq,
10270dbacebeSHans Verkuil 			tuner_dev_info->analog.bcast_system);
10280dbacebeSHans Verkuil 	else
10290dbacebeSHans Verkuil 		cec_msg_tuner_device_status_digital(msg,
10300dbacebeSHans Verkuil 			tuner_dev_info->rec_flag,
10310dbacebeSHans Verkuil 			tuner_dev_info->tuner_display_info,
10320dbacebeSHans Verkuil 			&tuner_dev_info->digital);
10330dbacebeSHans Verkuil }
10340dbacebeSHans Verkuil 
10350dbacebeSHans Verkuil static inline void cec_ops_tuner_device_status(const struct cec_msg *msg,
10360dbacebeSHans Verkuil 				struct cec_op_tuner_device_info *tuner_dev_info)
10370dbacebeSHans Verkuil {
10380dbacebeSHans Verkuil 	tuner_dev_info->is_analog = msg->len < 10;
10390dbacebeSHans Verkuil 	tuner_dev_info->rec_flag = msg->msg[2] >> 7;
10400dbacebeSHans Verkuil 	tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f;
10410dbacebeSHans Verkuil 	if (tuner_dev_info->is_analog) {
10420dbacebeSHans Verkuil 		tuner_dev_info->analog.ana_bcast_type = msg->msg[3];
10430dbacebeSHans Verkuil 		tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5];
10440dbacebeSHans Verkuil 		tuner_dev_info->analog.bcast_system = msg->msg[6];
10450dbacebeSHans Verkuil 		return;
10460dbacebeSHans Verkuil 	}
10470dbacebeSHans Verkuil 	cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital);
10480dbacebeSHans Verkuil }
10490dbacebeSHans Verkuil 
10500dbacebeSHans Verkuil static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg,
10513145c754SHans Verkuil 						    int reply,
10520dbacebeSHans Verkuil 						    __u8 status_req)
10530dbacebeSHans Verkuil {
10540dbacebeSHans Verkuil 	msg->len = 3;
10550dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS;
10560dbacebeSHans Verkuil 	msg->msg[2] = status_req;
10570dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0;
10580dbacebeSHans Verkuil }
10590dbacebeSHans Verkuil 
10600dbacebeSHans Verkuil static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg,
10610dbacebeSHans Verkuil 						    __u8 *status_req)
10620dbacebeSHans Verkuil {
10630dbacebeSHans Verkuil 	*status_req = msg->msg[2];
10640dbacebeSHans Verkuil }
10650dbacebeSHans Verkuil 
10660dbacebeSHans Verkuil static inline void cec_msg_select_analogue_service(struct cec_msg *msg,
10670dbacebeSHans Verkuil 						   __u8 ana_bcast_type,
10680dbacebeSHans Verkuil 						   __u16 ana_freq,
10690dbacebeSHans Verkuil 						   __u8 bcast_system)
10700dbacebeSHans Verkuil {
10710dbacebeSHans Verkuil 	msg->len = 6;
10720dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE;
10730dbacebeSHans Verkuil 	msg->msg[2] = ana_bcast_type;
10740dbacebeSHans Verkuil 	msg->msg[3] = ana_freq >> 8;
10750dbacebeSHans Verkuil 	msg->msg[4] = ana_freq & 0xff;
10760dbacebeSHans Verkuil 	msg->msg[5] = bcast_system;
10770dbacebeSHans Verkuil }
10780dbacebeSHans Verkuil 
10790dbacebeSHans Verkuil static inline void cec_ops_select_analogue_service(const struct cec_msg *msg,
10800dbacebeSHans Verkuil 						   __u8 *ana_bcast_type,
10810dbacebeSHans Verkuil 						   __u16 *ana_freq,
10820dbacebeSHans Verkuil 						   __u8 *bcast_system)
10830dbacebeSHans Verkuil {
10840dbacebeSHans Verkuil 	*ana_bcast_type = msg->msg[2];
10850dbacebeSHans Verkuil 	*ana_freq = (msg->msg[3] << 8) | msg->msg[4];
10860dbacebeSHans Verkuil 	*bcast_system = msg->msg[5];
10870dbacebeSHans Verkuil }
10880dbacebeSHans Verkuil 
10890dbacebeSHans Verkuil static inline void cec_msg_select_digital_service(struct cec_msg *msg,
10900dbacebeSHans Verkuil 				const struct cec_op_digital_service_id *digital)
10910dbacebeSHans Verkuil {
10920dbacebeSHans Verkuil 	msg->len = 9;
10930dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE;
10940dbacebeSHans Verkuil 	cec_set_digital_service_id(msg->msg + 2, digital);
10950dbacebeSHans Verkuil }
10960dbacebeSHans Verkuil 
10970dbacebeSHans Verkuil static inline void cec_ops_select_digital_service(const struct cec_msg *msg,
10980dbacebeSHans Verkuil 				struct cec_op_digital_service_id *digital)
10990dbacebeSHans Verkuil {
11000dbacebeSHans Verkuil 	cec_get_digital_service_id(msg->msg + 2, digital);
11010dbacebeSHans Verkuil }
11020dbacebeSHans Verkuil 
11030dbacebeSHans Verkuil static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg)
11040dbacebeSHans Verkuil {
11050dbacebeSHans Verkuil 	msg->len = 2;
11060dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT;
11070dbacebeSHans Verkuil }
11080dbacebeSHans Verkuil 
11090dbacebeSHans Verkuil static inline void cec_msg_tuner_step_increment(struct cec_msg *msg)
11100dbacebeSHans Verkuil {
11110dbacebeSHans Verkuil 	msg->len = 2;
11120dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT;
11130dbacebeSHans Verkuil }
11140dbacebeSHans Verkuil 
11150dbacebeSHans Verkuil 
11160dbacebeSHans Verkuil /* Vendor Specific Commands Feature */
11170dbacebeSHans Verkuil static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id)
11180dbacebeSHans Verkuil {
11190dbacebeSHans Verkuil 	msg->len = 5;
11200dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
11210dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID;
11220dbacebeSHans Verkuil 	msg->msg[2] = vendor_id >> 16;
11230dbacebeSHans Verkuil 	msg->msg[3] = (vendor_id >> 8) & 0xff;
11240dbacebeSHans Verkuil 	msg->msg[4] = vendor_id & 0xff;
11250dbacebeSHans Verkuil }
11260dbacebeSHans Verkuil 
11270dbacebeSHans Verkuil static inline void cec_ops_device_vendor_id(const struct cec_msg *msg,
11280dbacebeSHans Verkuil 					    __u32 *vendor_id)
11290dbacebeSHans Verkuil {
11300dbacebeSHans Verkuil 	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
11310dbacebeSHans Verkuil }
11320dbacebeSHans Verkuil 
11330dbacebeSHans Verkuil static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg,
11343145c754SHans Verkuil 						 int reply)
11350dbacebeSHans Verkuil {
11360dbacebeSHans Verkuil 	msg->len = 2;
11370dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID;
11380dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0;
11390dbacebeSHans Verkuil }
11400dbacebeSHans Verkuil 
11410dbacebeSHans Verkuil static inline void cec_msg_vendor_command(struct cec_msg *msg,
11420dbacebeSHans Verkuil 					  __u8 size, const __u8 *vendor_cmd)
11430dbacebeSHans Verkuil {
11440dbacebeSHans Verkuil 	if (size > 14)
11450dbacebeSHans Verkuil 		size = 14;
11460dbacebeSHans Verkuil 	msg->len = 2 + size;
11470dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_COMMAND;
11480dbacebeSHans Verkuil 	memcpy(msg->msg + 2, vendor_cmd, size);
11490dbacebeSHans Verkuil }
11500dbacebeSHans Verkuil 
11510dbacebeSHans Verkuil static inline void cec_ops_vendor_command(const struct cec_msg *msg,
11520dbacebeSHans Verkuil 					  __u8 *size,
11530dbacebeSHans Verkuil 					  const __u8 **vendor_cmd)
11540dbacebeSHans Verkuil {
11550dbacebeSHans Verkuil 	*size = msg->len - 2;
11560dbacebeSHans Verkuil 
11570dbacebeSHans Verkuil 	if (*size > 14)
11580dbacebeSHans Verkuil 		*size = 14;
11590dbacebeSHans Verkuil 	*vendor_cmd = msg->msg + 2;
11600dbacebeSHans Verkuil }
11610dbacebeSHans Verkuil 
11620dbacebeSHans Verkuil static inline void cec_msg_vendor_command_with_id(struct cec_msg *msg,
11630dbacebeSHans Verkuil 						  __u32 vendor_id, __u8 size,
11640dbacebeSHans Verkuil 						  const __u8 *vendor_cmd)
11650dbacebeSHans Verkuil {
11660dbacebeSHans Verkuil 	if (size > 11)
11670dbacebeSHans Verkuil 		size = 11;
11680dbacebeSHans Verkuil 	msg->len = 5 + size;
11690dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_COMMAND_WITH_ID;
11700dbacebeSHans Verkuil 	msg->msg[2] = vendor_id >> 16;
11710dbacebeSHans Verkuil 	msg->msg[3] = (vendor_id >> 8) & 0xff;
11720dbacebeSHans Verkuil 	msg->msg[4] = vendor_id & 0xff;
11730dbacebeSHans Verkuil 	memcpy(msg->msg + 5, vendor_cmd, size);
11740dbacebeSHans Verkuil }
11750dbacebeSHans Verkuil 
11760dbacebeSHans Verkuil static inline void cec_ops_vendor_command_with_id(const struct cec_msg *msg,
11770dbacebeSHans Verkuil 						  __u32 *vendor_id,  __u8 *size,
11780dbacebeSHans Verkuil 						  const __u8 **vendor_cmd)
11790dbacebeSHans Verkuil {
11800dbacebeSHans Verkuil 	*size = msg->len - 5;
11810dbacebeSHans Verkuil 
11820dbacebeSHans Verkuil 	if (*size > 11)
11830dbacebeSHans Verkuil 		*size = 11;
11840dbacebeSHans Verkuil 	*vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
11850dbacebeSHans Verkuil 	*vendor_cmd = msg->msg + 5;
11860dbacebeSHans Verkuil }
11870dbacebeSHans Verkuil 
11880dbacebeSHans Verkuil static inline void cec_msg_vendor_remote_button_down(struct cec_msg *msg,
11890dbacebeSHans Verkuil 						     __u8 size,
11900dbacebeSHans Verkuil 						     const __u8 *rc_code)
11910dbacebeSHans Verkuil {
11920dbacebeSHans Verkuil 	if (size > 14)
11930dbacebeSHans Verkuil 		size = 14;
11940dbacebeSHans Verkuil 	msg->len = 2 + size;
11950dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN;
11960dbacebeSHans Verkuil 	memcpy(msg->msg + 2, rc_code, size);
11970dbacebeSHans Verkuil }
11980dbacebeSHans Verkuil 
11990dbacebeSHans Verkuil static inline void cec_ops_vendor_remote_button_down(const struct cec_msg *msg,
12000dbacebeSHans Verkuil 						     __u8 *size,
12010dbacebeSHans Verkuil 						     const __u8 **rc_code)
12020dbacebeSHans Verkuil {
12030dbacebeSHans Verkuil 	*size = msg->len - 2;
12040dbacebeSHans Verkuil 
12050dbacebeSHans Verkuil 	if (*size > 14)
12060dbacebeSHans Verkuil 		*size = 14;
12070dbacebeSHans Verkuil 	*rc_code = msg->msg + 2;
12080dbacebeSHans Verkuil }
12090dbacebeSHans Verkuil 
12100dbacebeSHans Verkuil static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg)
12110dbacebeSHans Verkuil {
12120dbacebeSHans Verkuil 	msg->len = 2;
12130dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP;
12140dbacebeSHans Verkuil }
12150dbacebeSHans Verkuil 
12160dbacebeSHans Verkuil 
12170dbacebeSHans Verkuil /* OSD Display Feature */
12180dbacebeSHans Verkuil static inline void cec_msg_set_osd_string(struct cec_msg *msg,
12190dbacebeSHans Verkuil 					  __u8 disp_ctl,
12200dbacebeSHans Verkuil 					  const char *osd)
12210dbacebeSHans Verkuil {
12220dbacebeSHans Verkuil 	unsigned int len = strlen(osd);
12230dbacebeSHans Verkuil 
12240dbacebeSHans Verkuil 	if (len > 13)
12250dbacebeSHans Verkuil 		len = 13;
12260dbacebeSHans Verkuil 	msg->len = 3 + len;
12270dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_OSD_STRING;
12280dbacebeSHans Verkuil 	msg->msg[2] = disp_ctl;
12290dbacebeSHans Verkuil 	memcpy(msg->msg + 3, osd, len);
12300dbacebeSHans Verkuil }
12310dbacebeSHans Verkuil 
12320dbacebeSHans Verkuil static inline void cec_ops_set_osd_string(const struct cec_msg *msg,
12330dbacebeSHans Verkuil 					  __u8 *disp_ctl,
12340dbacebeSHans Verkuil 					  char *osd)
12350dbacebeSHans Verkuil {
12360dbacebeSHans Verkuil 	unsigned int len = msg->len > 3 ? msg->len - 3 : 0;
12370dbacebeSHans Verkuil 
12380dbacebeSHans Verkuil 	*disp_ctl = msg->msg[2];
12390dbacebeSHans Verkuil 	if (len > 13)
12400dbacebeSHans Verkuil 		len = 13;
12410dbacebeSHans Verkuil 	memcpy(osd, msg->msg + 3, len);
12420dbacebeSHans Verkuil 	osd[len] = '\0';
12430dbacebeSHans Verkuil }
12440dbacebeSHans Verkuil 
12450dbacebeSHans Verkuil 
12460dbacebeSHans Verkuil /* Device OSD Transfer Feature */
12470dbacebeSHans Verkuil static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name)
12480dbacebeSHans Verkuil {
12490dbacebeSHans Verkuil 	unsigned int len = strlen(name);
12500dbacebeSHans Verkuil 
12510dbacebeSHans Verkuil 	if (len > 14)
12520dbacebeSHans Verkuil 		len = 14;
12530dbacebeSHans Verkuil 	msg->len = 2 + len;
12540dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_OSD_NAME;
12550dbacebeSHans Verkuil 	memcpy(msg->msg + 2, name, len);
12560dbacebeSHans Verkuil }
12570dbacebeSHans Verkuil 
12580dbacebeSHans Verkuil static inline void cec_ops_set_osd_name(const struct cec_msg *msg,
12590dbacebeSHans Verkuil 					char *name)
12600dbacebeSHans Verkuil {
12610dbacebeSHans Verkuil 	unsigned int len = msg->len > 2 ? msg->len - 2 : 0;
12620dbacebeSHans Verkuil 
12630dbacebeSHans Verkuil 	if (len > 14)
12640dbacebeSHans Verkuil 		len = 14;
12650dbacebeSHans Verkuil 	memcpy(name, msg->msg + 2, len);
12660dbacebeSHans Verkuil 	name[len] = '\0';
12670dbacebeSHans Verkuil }
12680dbacebeSHans Verkuil 
12690dbacebeSHans Verkuil static inline void cec_msg_give_osd_name(struct cec_msg *msg,
12703145c754SHans Verkuil 					 int reply)
12710dbacebeSHans Verkuil {
12720dbacebeSHans Verkuil 	msg->len = 2;
12730dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_OSD_NAME;
12740dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0;
12750dbacebeSHans Verkuil }
12760dbacebeSHans Verkuil 
12770dbacebeSHans Verkuil 
12780dbacebeSHans Verkuil /* Device Menu Control Feature */
12790dbacebeSHans Verkuil static inline void cec_msg_menu_status(struct cec_msg *msg,
12800dbacebeSHans Verkuil 				       __u8 menu_state)
12810dbacebeSHans Verkuil {
12820dbacebeSHans Verkuil 	msg->len = 3;
12830dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_MENU_STATUS;
12840dbacebeSHans Verkuil 	msg->msg[2] = menu_state;
12850dbacebeSHans Verkuil }
12860dbacebeSHans Verkuil 
12870dbacebeSHans Verkuil static inline void cec_ops_menu_status(const struct cec_msg *msg,
12880dbacebeSHans Verkuil 				       __u8 *menu_state)
12890dbacebeSHans Verkuil {
12900dbacebeSHans Verkuil 	*menu_state = msg->msg[2];
12910dbacebeSHans Verkuil }
12920dbacebeSHans Verkuil 
12930dbacebeSHans Verkuil static inline void cec_msg_menu_request(struct cec_msg *msg,
12943145c754SHans Verkuil 					int reply,
12950dbacebeSHans Verkuil 					__u8 menu_req)
12960dbacebeSHans Verkuil {
12970dbacebeSHans Verkuil 	msg->len = 3;
12980dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_MENU_REQUEST;
12990dbacebeSHans Verkuil 	msg->msg[2] = menu_req;
13000dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_MENU_STATUS : 0;
13010dbacebeSHans Verkuil }
13020dbacebeSHans Verkuil 
13030dbacebeSHans Verkuil static inline void cec_ops_menu_request(const struct cec_msg *msg,
13040dbacebeSHans Verkuil 					__u8 *menu_req)
13050dbacebeSHans Verkuil {
13060dbacebeSHans Verkuil 	*menu_req = msg->msg[2];
13070dbacebeSHans Verkuil }
13080dbacebeSHans Verkuil 
13090dbacebeSHans Verkuil struct cec_op_ui_command {
13100dbacebeSHans Verkuil 	__u8 ui_cmd;
13113145c754SHans Verkuil 	__u8 has_opt_arg;
13120dbacebeSHans Verkuil 	union {
13130dbacebeSHans Verkuil 		struct cec_op_channel_data channel_identifier;
13140dbacebeSHans Verkuil 		__u8 ui_broadcast_type;
13150dbacebeSHans Verkuil 		__u8 ui_sound_presentation_control;
13160dbacebeSHans Verkuil 		__u8 play_mode;
13170dbacebeSHans Verkuil 		__u8 ui_function_media;
13180dbacebeSHans Verkuil 		__u8 ui_function_select_av_input;
13190dbacebeSHans Verkuil 		__u8 ui_function_select_audio_input;
13200dbacebeSHans Verkuil 	};
13210dbacebeSHans Verkuil };
13220dbacebeSHans Verkuil 
13230dbacebeSHans Verkuil static inline void cec_msg_user_control_pressed(struct cec_msg *msg,
13240dbacebeSHans Verkuil 					const struct cec_op_ui_command *ui_cmd)
13250dbacebeSHans Verkuil {
13260dbacebeSHans Verkuil 	msg->len = 3;
13270dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED;
13280dbacebeSHans Verkuil 	msg->msg[2] = ui_cmd->ui_cmd;
13290dbacebeSHans Verkuil 	if (!ui_cmd->has_opt_arg)
13300dbacebeSHans Verkuil 		return;
13310dbacebeSHans Verkuil 	switch (ui_cmd->ui_cmd) {
13320dbacebeSHans Verkuil 	case 0x56:
13330dbacebeSHans Verkuil 	case 0x57:
13340dbacebeSHans Verkuil 	case 0x60:
13350dbacebeSHans Verkuil 	case 0x68:
13360dbacebeSHans Verkuil 	case 0x69:
13370dbacebeSHans Verkuil 	case 0x6a:
13380dbacebeSHans Verkuil 		/* The optional operand is one byte for all these ui commands */
13390dbacebeSHans Verkuil 		msg->len++;
13400dbacebeSHans Verkuil 		msg->msg[3] = ui_cmd->play_mode;
13410dbacebeSHans Verkuil 		break;
13420dbacebeSHans Verkuil 	case 0x67:
13430dbacebeSHans Verkuil 		msg->len += 4;
13440dbacebeSHans Verkuil 		msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) |
13450dbacebeSHans Verkuil 			      (ui_cmd->channel_identifier.major >> 8);
13460dbacebeSHans Verkuil 		msg->msg[4] = ui_cmd->channel_identifier.major & 0xff;
13470dbacebeSHans Verkuil 		msg->msg[5] = ui_cmd->channel_identifier.minor >> 8;
13480dbacebeSHans Verkuil 		msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff;
13490dbacebeSHans Verkuil 		break;
13500dbacebeSHans Verkuil 	}
13510dbacebeSHans Verkuil }
13520dbacebeSHans Verkuil 
13530dbacebeSHans Verkuil static inline void cec_ops_user_control_pressed(const struct cec_msg *msg,
13540dbacebeSHans Verkuil 						struct cec_op_ui_command *ui_cmd)
13550dbacebeSHans Verkuil {
13560dbacebeSHans Verkuil 	ui_cmd->ui_cmd = msg->msg[2];
13573145c754SHans Verkuil 	ui_cmd->has_opt_arg = 0;
13580dbacebeSHans Verkuil 	if (msg->len == 3)
13590dbacebeSHans Verkuil 		return;
13600dbacebeSHans Verkuil 	switch (ui_cmd->ui_cmd) {
13610dbacebeSHans Verkuil 	case 0x56:
13620dbacebeSHans Verkuil 	case 0x57:
13630dbacebeSHans Verkuil 	case 0x60:
13640dbacebeSHans Verkuil 	case 0x68:
13650dbacebeSHans Verkuil 	case 0x69:
13660dbacebeSHans Verkuil 	case 0x6a:
13670dbacebeSHans Verkuil 		/* The optional operand is one byte for all these ui commands */
13680dbacebeSHans Verkuil 		ui_cmd->play_mode = msg->msg[3];
13693145c754SHans Verkuil 		ui_cmd->has_opt_arg = 1;
13700dbacebeSHans Verkuil 		break;
13710dbacebeSHans Verkuil 	case 0x67:
13720dbacebeSHans Verkuil 		if (msg->len < 7)
13730dbacebeSHans Verkuil 			break;
13743145c754SHans Verkuil 		ui_cmd->has_opt_arg = 1;
13750dbacebeSHans Verkuil 		ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2;
13760dbacebeSHans Verkuil 		ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4];
13770dbacebeSHans Verkuil 		ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6];
13780dbacebeSHans Verkuil 		break;
13790dbacebeSHans Verkuil 	}
13800dbacebeSHans Verkuil }
13810dbacebeSHans Verkuil 
13820dbacebeSHans Verkuil static inline void cec_msg_user_control_released(struct cec_msg *msg)
13830dbacebeSHans Verkuil {
13840dbacebeSHans Verkuil 	msg->len = 2;
13850dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED;
13860dbacebeSHans Verkuil }
13870dbacebeSHans Verkuil 
13880dbacebeSHans Verkuil /* Remote Control Passthrough Feature */
13890dbacebeSHans Verkuil 
13900dbacebeSHans Verkuil /* Power Status Feature */
13910dbacebeSHans Verkuil static inline void cec_msg_report_power_status(struct cec_msg *msg,
13920dbacebeSHans Verkuil 					       __u8 pwr_state)
13930dbacebeSHans Verkuil {
13940dbacebeSHans Verkuil 	msg->len = 3;
13950dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS;
13960dbacebeSHans Verkuil 	msg->msg[2] = pwr_state;
13970dbacebeSHans Verkuil }
13980dbacebeSHans Verkuil 
13990dbacebeSHans Verkuil static inline void cec_ops_report_power_status(const struct cec_msg *msg,
14000dbacebeSHans Verkuil 					       __u8 *pwr_state)
14010dbacebeSHans Verkuil {
14020dbacebeSHans Verkuil 	*pwr_state = msg->msg[2];
14030dbacebeSHans Verkuil }
14040dbacebeSHans Verkuil 
14050dbacebeSHans Verkuil static inline void cec_msg_give_device_power_status(struct cec_msg *msg,
14063145c754SHans Verkuil 						    int reply)
14070dbacebeSHans Verkuil {
14080dbacebeSHans Verkuil 	msg->len = 2;
14090dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS;
14100dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0;
14110dbacebeSHans Verkuil }
14120dbacebeSHans Verkuil 
14130dbacebeSHans Verkuil /* General Protocol Messages */
14140dbacebeSHans Verkuil static inline void cec_msg_feature_abort(struct cec_msg *msg,
14150dbacebeSHans Verkuil 					 __u8 abort_msg, __u8 reason)
14160dbacebeSHans Verkuil {
14170dbacebeSHans Verkuil 	msg->len = 4;
14180dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_FEATURE_ABORT;
14190dbacebeSHans Verkuil 	msg->msg[2] = abort_msg;
14200dbacebeSHans Verkuil 	msg->msg[3] = reason;
14210dbacebeSHans Verkuil }
14220dbacebeSHans Verkuil 
14230dbacebeSHans Verkuil static inline void cec_ops_feature_abort(const struct cec_msg *msg,
14240dbacebeSHans Verkuil 					 __u8 *abort_msg, __u8 *reason)
14250dbacebeSHans Verkuil {
14260dbacebeSHans Verkuil 	*abort_msg = msg->msg[2];
14270dbacebeSHans Verkuil 	*reason = msg->msg[3];
14280dbacebeSHans Verkuil }
14290dbacebeSHans Verkuil 
14300dbacebeSHans Verkuil /* This changes the current message into a feature abort message */
14310dbacebeSHans Verkuil static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason)
14320dbacebeSHans Verkuil {
14330dbacebeSHans Verkuil 	cec_msg_set_reply_to(msg, msg);
14340dbacebeSHans Verkuil 	msg->len = 4;
14350dbacebeSHans Verkuil 	msg->msg[2] = msg->msg[1];
14360dbacebeSHans Verkuil 	msg->msg[3] = reason;
14370dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_FEATURE_ABORT;
14380dbacebeSHans Verkuil }
14390dbacebeSHans Verkuil 
14400dbacebeSHans Verkuil static inline void cec_msg_abort(struct cec_msg *msg)
14410dbacebeSHans Verkuil {
14420dbacebeSHans Verkuil 	msg->len = 2;
14430dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_ABORT;
14440dbacebeSHans Verkuil }
14450dbacebeSHans Verkuil 
14460dbacebeSHans Verkuil 
14470dbacebeSHans Verkuil /* System Audio Control Feature */
14480dbacebeSHans Verkuil static inline void cec_msg_report_audio_status(struct cec_msg *msg,
14490dbacebeSHans Verkuil 					       __u8 aud_mute_status,
14500dbacebeSHans Verkuil 					       __u8 aud_vol_status)
14510dbacebeSHans Verkuil {
14520dbacebeSHans Verkuil 	msg->len = 3;
14530dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS;
14540dbacebeSHans Verkuil 	msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f);
14550dbacebeSHans Verkuil }
14560dbacebeSHans Verkuil 
14570dbacebeSHans Verkuil static inline void cec_ops_report_audio_status(const struct cec_msg *msg,
14580dbacebeSHans Verkuil 					       __u8 *aud_mute_status,
14590dbacebeSHans Verkuil 					       __u8 *aud_vol_status)
14600dbacebeSHans Verkuil {
14610dbacebeSHans Verkuil 	*aud_mute_status = msg->msg[2] >> 7;
14620dbacebeSHans Verkuil 	*aud_vol_status = msg->msg[2] & 0x7f;
14630dbacebeSHans Verkuil }
14640dbacebeSHans Verkuil 
14650dbacebeSHans Verkuil static inline void cec_msg_give_audio_status(struct cec_msg *msg,
14663145c754SHans Verkuil 					     int reply)
14670dbacebeSHans Verkuil {
14680dbacebeSHans Verkuil 	msg->len = 2;
14690dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS;
14700dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0;
14710dbacebeSHans Verkuil }
14720dbacebeSHans Verkuil 
14730dbacebeSHans Verkuil static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg,
14740dbacebeSHans Verkuil 						 __u8 sys_aud_status)
14750dbacebeSHans Verkuil {
14760dbacebeSHans Verkuil 	msg->len = 3;
14770dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE;
14780dbacebeSHans Verkuil 	msg->msg[2] = sys_aud_status;
14790dbacebeSHans Verkuil }
14800dbacebeSHans Verkuil 
14810dbacebeSHans Verkuil static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg,
14820dbacebeSHans Verkuil 						 __u8 *sys_aud_status)
14830dbacebeSHans Verkuil {
14840dbacebeSHans Verkuil 	*sys_aud_status = msg->msg[2];
14850dbacebeSHans Verkuil }
14860dbacebeSHans Verkuil 
14870dbacebeSHans Verkuil static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg,
14883145c754SHans Verkuil 						     int reply,
14890dbacebeSHans Verkuil 						     __u16 phys_addr)
14900dbacebeSHans Verkuil {
14910dbacebeSHans Verkuil 	msg->len = phys_addr == 0xffff ? 2 : 4;
14920dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST;
14930dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
14940dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
14950dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0;
14960dbacebeSHans Verkuil 
14970dbacebeSHans Verkuil }
14980dbacebeSHans Verkuil 
14990dbacebeSHans Verkuil static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg,
15000dbacebeSHans Verkuil 						     __u16 *phys_addr)
15010dbacebeSHans Verkuil {
15020dbacebeSHans Verkuil 	if (msg->len < 4)
15030dbacebeSHans Verkuil 		*phys_addr = 0xffff;
15040dbacebeSHans Verkuil 	else
15050dbacebeSHans Verkuil 		*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
15060dbacebeSHans Verkuil }
15070dbacebeSHans Verkuil 
15080dbacebeSHans Verkuil static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg,
15090dbacebeSHans Verkuil 						    __u8 sys_aud_status)
15100dbacebeSHans Verkuil {
15110dbacebeSHans Verkuil 	msg->len = 3;
15120dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS;
15130dbacebeSHans Verkuil 	msg->msg[2] = sys_aud_status;
15140dbacebeSHans Verkuil }
15150dbacebeSHans Verkuil 
15160dbacebeSHans Verkuil static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg,
15170dbacebeSHans Verkuil 						    __u8 *sys_aud_status)
15180dbacebeSHans Verkuil {
15190dbacebeSHans Verkuil 	*sys_aud_status = msg->msg[2];
15200dbacebeSHans Verkuil }
15210dbacebeSHans Verkuil 
15220dbacebeSHans Verkuil static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg,
15233145c754SHans Verkuil 							 int reply)
15240dbacebeSHans Verkuil {
15250dbacebeSHans Verkuil 	msg->len = 2;
15260dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS;
15270dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0;
15280dbacebeSHans Verkuil }
15290dbacebeSHans Verkuil 
15300dbacebeSHans Verkuil static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg,
15310dbacebeSHans Verkuil 					__u8 num_descriptors,
15320dbacebeSHans Verkuil 					const __u32 *descriptors)
15330dbacebeSHans Verkuil {
15340dbacebeSHans Verkuil 	unsigned int i;
15350dbacebeSHans Verkuil 
15360dbacebeSHans Verkuil 	if (num_descriptors > 4)
15370dbacebeSHans Verkuil 		num_descriptors = 4;
15380dbacebeSHans Verkuil 	msg->len = 2 + num_descriptors * 3;
15390dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR;
15400dbacebeSHans Verkuil 	for (i = 0; i < num_descriptors; i++) {
15410dbacebeSHans Verkuil 		msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff;
15420dbacebeSHans Verkuil 		msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff;
15430dbacebeSHans Verkuil 		msg->msg[4 + i * 3] = descriptors[i] & 0xff;
15440dbacebeSHans Verkuil 	}
15450dbacebeSHans Verkuil }
15460dbacebeSHans Verkuil 
15470dbacebeSHans Verkuil static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg,
15480dbacebeSHans Verkuil 							 __u8 *num_descriptors,
15490dbacebeSHans Verkuil 							 __u32 *descriptors)
15500dbacebeSHans Verkuil {
15510dbacebeSHans Verkuil 	unsigned int i;
15520dbacebeSHans Verkuil 
15530dbacebeSHans Verkuil 	*num_descriptors = (msg->len - 2) / 3;
15540dbacebeSHans Verkuil 	if (*num_descriptors > 4)
15550dbacebeSHans Verkuil 		*num_descriptors = 4;
15560dbacebeSHans Verkuil 	for (i = 0; i < *num_descriptors; i++)
15570dbacebeSHans Verkuil 		descriptors[i] = (msg->msg[2 + i * 3] << 16) |
15580dbacebeSHans Verkuil 			(msg->msg[3 + i * 3] << 8) |
15590dbacebeSHans Verkuil 			msg->msg[4 + i * 3];
15600dbacebeSHans Verkuil }
15610dbacebeSHans Verkuil 
15620dbacebeSHans Verkuil static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg,
15633145c754SHans Verkuil 					int reply,
15640dbacebeSHans Verkuil 					__u8 num_descriptors,
15650dbacebeSHans Verkuil 					const __u8 *audio_format_id,
15660dbacebeSHans Verkuil 					const __u8 *audio_format_code)
15670dbacebeSHans Verkuil {
15680dbacebeSHans Verkuil 	unsigned int i;
15690dbacebeSHans Verkuil 
15700dbacebeSHans Verkuil 	if (num_descriptors > 4)
15710dbacebeSHans Verkuil 		num_descriptors = 4;
15720dbacebeSHans Verkuil 	msg->len = 2 + num_descriptors;
15730dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR;
15740dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0;
15750dbacebeSHans Verkuil 	for (i = 0; i < num_descriptors; i++)
15760dbacebeSHans Verkuil 		msg->msg[2 + i] = (audio_format_id[i] << 6) |
15770dbacebeSHans Verkuil 				  (audio_format_code[i] & 0x3f);
15780dbacebeSHans Verkuil }
15790dbacebeSHans Verkuil 
15800dbacebeSHans Verkuil static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg,
15810dbacebeSHans Verkuil 					__u8 *num_descriptors,
15820dbacebeSHans Verkuil 					__u8 *audio_format_id,
15830dbacebeSHans Verkuil 					__u8 *audio_format_code)
15840dbacebeSHans Verkuil {
15850dbacebeSHans Verkuil 	unsigned int i;
15860dbacebeSHans Verkuil 
15870dbacebeSHans Verkuil 	*num_descriptors = msg->len - 2;
15880dbacebeSHans Verkuil 	if (*num_descriptors > 4)
15890dbacebeSHans Verkuil 		*num_descriptors = 4;
15900dbacebeSHans Verkuil 	for (i = 0; i < *num_descriptors; i++) {
15910dbacebeSHans Verkuil 		audio_format_id[i] = msg->msg[2 + i] >> 6;
15920dbacebeSHans Verkuil 		audio_format_code[i] = msg->msg[2 + i] & 0x3f;
15930dbacebeSHans Verkuil 	}
15940dbacebeSHans Verkuil }
15950dbacebeSHans Verkuil 
15960dbacebeSHans Verkuil 
15970dbacebeSHans Verkuil /* Audio Rate Control Feature */
15980dbacebeSHans Verkuil static inline void cec_msg_set_audio_rate(struct cec_msg *msg,
15990dbacebeSHans Verkuil 					  __u8 audio_rate)
16000dbacebeSHans Verkuil {
16010dbacebeSHans Verkuil 	msg->len = 3;
16020dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_SET_AUDIO_RATE;
16030dbacebeSHans Verkuil 	msg->msg[2] = audio_rate;
16040dbacebeSHans Verkuil }
16050dbacebeSHans Verkuil 
16060dbacebeSHans Verkuil static inline void cec_ops_set_audio_rate(const struct cec_msg *msg,
16070dbacebeSHans Verkuil 					  __u8 *audio_rate)
16080dbacebeSHans Verkuil {
16090dbacebeSHans Verkuil 	*audio_rate = msg->msg[2];
16100dbacebeSHans Verkuil }
16110dbacebeSHans Verkuil 
16120dbacebeSHans Verkuil 
16130dbacebeSHans Verkuil /* Audio Return Channel Control Feature */
16140dbacebeSHans Verkuil static inline void cec_msg_report_arc_initiated(struct cec_msg *msg)
16150dbacebeSHans Verkuil {
16160dbacebeSHans Verkuil 	msg->len = 2;
16170dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED;
16180dbacebeSHans Verkuil }
16190dbacebeSHans Verkuil 
16200dbacebeSHans Verkuil static inline void cec_msg_initiate_arc(struct cec_msg *msg,
16213145c754SHans Verkuil 					int reply)
16220dbacebeSHans Verkuil {
16230dbacebeSHans Verkuil 	msg->len = 2;
16240dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_INITIATE_ARC;
16250dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0;
16260dbacebeSHans Verkuil }
16270dbacebeSHans Verkuil 
16280dbacebeSHans Verkuil static inline void cec_msg_request_arc_initiation(struct cec_msg *msg,
16293145c754SHans Verkuil 						  int reply)
16300dbacebeSHans Verkuil {
16310dbacebeSHans Verkuil 	msg->len = 2;
16320dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION;
16330dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0;
16340dbacebeSHans Verkuil }
16350dbacebeSHans Verkuil 
16360dbacebeSHans Verkuil static inline void cec_msg_report_arc_terminated(struct cec_msg *msg)
16370dbacebeSHans Verkuil {
16380dbacebeSHans Verkuil 	msg->len = 2;
16390dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED;
16400dbacebeSHans Verkuil }
16410dbacebeSHans Verkuil 
16420dbacebeSHans Verkuil static inline void cec_msg_terminate_arc(struct cec_msg *msg,
16433145c754SHans Verkuil 					 int reply)
16440dbacebeSHans Verkuil {
16450dbacebeSHans Verkuil 	msg->len = 2;
16460dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_TERMINATE_ARC;
16470dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0;
16480dbacebeSHans Verkuil }
16490dbacebeSHans Verkuil 
16500dbacebeSHans Verkuil static inline void cec_msg_request_arc_termination(struct cec_msg *msg,
16513145c754SHans Verkuil 						   int reply)
16520dbacebeSHans Verkuil {
16530dbacebeSHans Verkuil 	msg->len = 2;
16540dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION;
16550dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0;
16560dbacebeSHans Verkuil }
16570dbacebeSHans Verkuil 
16580dbacebeSHans Verkuil 
16590dbacebeSHans Verkuil /* Dynamic Audio Lipsync Feature */
16600dbacebeSHans Verkuil /* Only for CEC 2.0 and up */
16610dbacebeSHans Verkuil static inline void cec_msg_report_current_latency(struct cec_msg *msg,
16620dbacebeSHans Verkuil 						  __u16 phys_addr,
16630dbacebeSHans Verkuil 						  __u8 video_latency,
16640dbacebeSHans Verkuil 						  __u8 low_latency_mode,
16650dbacebeSHans Verkuil 						  __u8 audio_out_compensated,
16660dbacebeSHans Verkuil 						  __u8 audio_out_delay)
16670dbacebeSHans Verkuil {
1668f3854973SHans Verkuil 	msg->len = 6;
16690dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
16700dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY;
16710dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
16720dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
16730dbacebeSHans Verkuil 	msg->msg[4] = video_latency;
16740dbacebeSHans Verkuil 	msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated;
1675f3854973SHans Verkuil 	if (audio_out_compensated == 3)
1676f3854973SHans Verkuil 		msg->msg[msg->len++] = audio_out_delay;
16770dbacebeSHans Verkuil }
16780dbacebeSHans Verkuil 
16790dbacebeSHans Verkuil static inline void cec_ops_report_current_latency(const struct cec_msg *msg,
16800dbacebeSHans Verkuil 						  __u16 *phys_addr,
16810dbacebeSHans Verkuil 						  __u8 *video_latency,
16820dbacebeSHans Verkuil 						  __u8 *low_latency_mode,
16830dbacebeSHans Verkuil 						  __u8 *audio_out_compensated,
16840dbacebeSHans Verkuil 						  __u8 *audio_out_delay)
16850dbacebeSHans Verkuil {
16860dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
16870dbacebeSHans Verkuil 	*video_latency = msg->msg[4];
16880dbacebeSHans Verkuil 	*low_latency_mode = (msg->msg[5] >> 2) & 1;
16890dbacebeSHans Verkuil 	*audio_out_compensated = msg->msg[5] & 3;
1690f3854973SHans Verkuil 	if (*audio_out_compensated == 3 && msg->len >= 7)
16910dbacebeSHans Verkuil 		*audio_out_delay = msg->msg[6];
1692f3854973SHans Verkuil 	else
1693f3854973SHans Verkuil 		*audio_out_delay = 0;
16940dbacebeSHans Verkuil }
16950dbacebeSHans Verkuil 
16960dbacebeSHans Verkuil static inline void cec_msg_request_current_latency(struct cec_msg *msg,
16973145c754SHans Verkuil 						   int reply,
16980dbacebeSHans Verkuil 						   __u16 phys_addr)
16990dbacebeSHans Verkuil {
17000dbacebeSHans Verkuil 	msg->len = 4;
17010dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17020dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY;
17030dbacebeSHans Verkuil 	msg->msg[2] = phys_addr >> 8;
17040dbacebeSHans Verkuil 	msg->msg[3] = phys_addr & 0xff;
17050dbacebeSHans Verkuil 	msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0;
17060dbacebeSHans Verkuil }
17070dbacebeSHans Verkuil 
17080dbacebeSHans Verkuil static inline void cec_ops_request_current_latency(const struct cec_msg *msg,
17090dbacebeSHans Verkuil 						   __u16 *phys_addr)
17100dbacebeSHans Verkuil {
17110dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
17120dbacebeSHans Verkuil }
17130dbacebeSHans Verkuil 
17140dbacebeSHans Verkuil 
17150dbacebeSHans Verkuil /* Capability Discovery and Control Feature */
17160dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg,
17170dbacebeSHans Verkuil 						 __u16 phys_addr1,
17180dbacebeSHans Verkuil 						 __u16 phys_addr2)
17190dbacebeSHans Verkuil {
17200dbacebeSHans Verkuil 	msg->len = 9;
17210dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17220dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
17230dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
17240dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;
17250dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
17260dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
17270dbacebeSHans Verkuil 	msg->msg[7] = phys_addr2 >> 8;
17280dbacebeSHans Verkuil 	msg->msg[8] = phys_addr2 & 0xff;
17290dbacebeSHans Verkuil }
17300dbacebeSHans Verkuil 
17310dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg,
17320dbacebeSHans Verkuil 						 __u16 *phys_addr,
17330dbacebeSHans Verkuil 						 __u16 *phys_addr1,
17340dbacebeSHans Verkuil 						 __u16 *phys_addr2)
17350dbacebeSHans Verkuil {
17360dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
17370dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
17380dbacebeSHans Verkuil 	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
17390dbacebeSHans Verkuil }
17400dbacebeSHans Verkuil 
17410dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg,
17420dbacebeSHans Verkuil 						__u16 target_phys_addr,
17430dbacebeSHans Verkuil 						__u8 hec_func_state,
17440dbacebeSHans Verkuil 						__u8 host_func_state,
17450dbacebeSHans Verkuil 						__u8 enc_func_state,
17460dbacebeSHans Verkuil 						__u8 cdc_errcode,
17470dbacebeSHans Verkuil 						__u8 has_field,
17480dbacebeSHans Verkuil 						__u16 hec_field)
17490dbacebeSHans Verkuil {
17500dbacebeSHans Verkuil 	msg->len = has_field ? 10 : 8;
17510dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17520dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
17530dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
17540dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE;
17550dbacebeSHans Verkuil 	msg->msg[5] = target_phys_addr >> 8;
17560dbacebeSHans Verkuil 	msg->msg[6] = target_phys_addr & 0xff;
17570dbacebeSHans Verkuil 	msg->msg[7] = (hec_func_state << 6) |
17580dbacebeSHans Verkuil 		      (host_func_state << 4) |
17590dbacebeSHans Verkuil 		      (enc_func_state << 2) |
17600dbacebeSHans Verkuil 		      cdc_errcode;
17610dbacebeSHans Verkuil 	if (has_field) {
17620dbacebeSHans Verkuil 		msg->msg[8] = hec_field >> 8;
17630dbacebeSHans Verkuil 		msg->msg[9] = hec_field & 0xff;
17640dbacebeSHans Verkuil 	}
17650dbacebeSHans Verkuil }
17660dbacebeSHans Verkuil 
17670dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg,
17680dbacebeSHans Verkuil 						__u16 *phys_addr,
17690dbacebeSHans Verkuil 						__u16 *target_phys_addr,
17700dbacebeSHans Verkuil 						__u8 *hec_func_state,
17710dbacebeSHans Verkuil 						__u8 *host_func_state,
17720dbacebeSHans Verkuil 						__u8 *enc_func_state,
17730dbacebeSHans Verkuil 						__u8 *cdc_errcode,
17740dbacebeSHans Verkuil 						__u8 *has_field,
17750dbacebeSHans Verkuil 						__u16 *hec_field)
17760dbacebeSHans Verkuil {
17770dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
17780dbacebeSHans Verkuil 	*target_phys_addr = (msg->msg[5] << 8) | msg->msg[6];
17790dbacebeSHans Verkuil 	*hec_func_state = msg->msg[7] >> 6;
17800dbacebeSHans Verkuil 	*host_func_state = (msg->msg[7] >> 4) & 3;
17810dbacebeSHans Verkuil 	*enc_func_state = (msg->msg[7] >> 4) & 3;
17820dbacebeSHans Verkuil 	*cdc_errcode = msg->msg[7] & 3;
17830dbacebeSHans Verkuil 	*has_field = msg->len >= 10;
17840dbacebeSHans Verkuil 	*hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0;
17850dbacebeSHans Verkuil }
17860dbacebeSHans Verkuil 
17870dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg,
17880dbacebeSHans Verkuil 					     __u16 phys_addr1,
17890dbacebeSHans Verkuil 					     __u16 phys_addr2,
17900dbacebeSHans Verkuil 					     __u8 hec_set_state,
17910dbacebeSHans Verkuil 					     __u16 phys_addr3,
17920dbacebeSHans Verkuil 					     __u16 phys_addr4,
17930dbacebeSHans Verkuil 					     __u16 phys_addr5)
17940dbacebeSHans Verkuil {
17950dbacebeSHans Verkuil 	msg->len = 10;
17960dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
17970dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
17980dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
17990dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;
18000dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
18010dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
18020dbacebeSHans Verkuil 	msg->msg[7] = phys_addr2 >> 8;
18030dbacebeSHans Verkuil 	msg->msg[8] = phys_addr2 & 0xff;
18040dbacebeSHans Verkuil 	msg->msg[9] = hec_set_state;
18050dbacebeSHans Verkuil 	if (phys_addr3 != CEC_PHYS_ADDR_INVALID) {
18060dbacebeSHans Verkuil 		msg->msg[msg->len++] = phys_addr3 >> 8;
18070dbacebeSHans Verkuil 		msg->msg[msg->len++] = phys_addr3 & 0xff;
18080dbacebeSHans Verkuil 		if (phys_addr4 != CEC_PHYS_ADDR_INVALID) {
18090dbacebeSHans Verkuil 			msg->msg[msg->len++] = phys_addr4 >> 8;
18100dbacebeSHans Verkuil 			msg->msg[msg->len++] = phys_addr4 & 0xff;
18110dbacebeSHans Verkuil 			if (phys_addr5 != CEC_PHYS_ADDR_INVALID) {
18120dbacebeSHans Verkuil 				msg->msg[msg->len++] = phys_addr5 >> 8;
18130dbacebeSHans Verkuil 				msg->msg[msg->len++] = phys_addr5 & 0xff;
18140dbacebeSHans Verkuil 			}
18150dbacebeSHans Verkuil 		}
18160dbacebeSHans Verkuil 	}
18170dbacebeSHans Verkuil }
18180dbacebeSHans Verkuil 
18190dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg,
18200dbacebeSHans Verkuil 					     __u16 *phys_addr,
18210dbacebeSHans Verkuil 					     __u16 *phys_addr1,
18220dbacebeSHans Verkuil 					     __u16 *phys_addr2,
18230dbacebeSHans Verkuil 					     __u8 *hec_set_state,
18240dbacebeSHans Verkuil 					     __u16 *phys_addr3,
18250dbacebeSHans Verkuil 					     __u16 *phys_addr4,
18260dbacebeSHans Verkuil 					     __u16 *phys_addr5)
18270dbacebeSHans Verkuil {
18280dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
18290dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
18300dbacebeSHans Verkuil 	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
18310dbacebeSHans Verkuil 	*hec_set_state = msg->msg[9];
18320dbacebeSHans Verkuil 	*phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID;
18330dbacebeSHans Verkuil 	if (msg->len >= 12)
18340dbacebeSHans Verkuil 		*phys_addr3 = (msg->msg[10] << 8) | msg->msg[11];
18350dbacebeSHans Verkuil 	if (msg->len >= 14)
18360dbacebeSHans Verkuil 		*phys_addr4 = (msg->msg[12] << 8) | msg->msg[13];
18370dbacebeSHans Verkuil 	if (msg->len >= 16)
18380dbacebeSHans Verkuil 		*phys_addr5 = (msg->msg[14] << 8) | msg->msg[15];
18390dbacebeSHans Verkuil }
18400dbacebeSHans Verkuil 
18410dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg,
18420dbacebeSHans Verkuil 						      __u16 phys_addr1,
18430dbacebeSHans Verkuil 						      __u8 hec_set_state)
18440dbacebeSHans Verkuil {
18450dbacebeSHans Verkuil 	msg->len = 8;
18460dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
18470dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
18480dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
18490dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT;
18500dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
18510dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
18520dbacebeSHans Verkuil 	msg->msg[7] = hec_set_state;
18530dbacebeSHans Verkuil }
18540dbacebeSHans Verkuil 
18550dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg,
18560dbacebeSHans Verkuil 						      __u16 *phys_addr,
18570dbacebeSHans Verkuil 						      __u16 *phys_addr1,
18580dbacebeSHans Verkuil 						      __u8 *hec_set_state)
18590dbacebeSHans Verkuil {
18600dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
18610dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
18620dbacebeSHans Verkuil 	*hec_set_state = msg->msg[7];
18630dbacebeSHans Verkuil }
18640dbacebeSHans Verkuil 
18650dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg,
18660dbacebeSHans Verkuil 							__u16 phys_addr1,
18670dbacebeSHans Verkuil 							__u16 phys_addr2,
18680dbacebeSHans Verkuil 							__u16 phys_addr3)
18690dbacebeSHans Verkuil {
18700dbacebeSHans Verkuil 	msg->len = 11;
18710dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
18720dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
18730dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
18740dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION;
18750dbacebeSHans Verkuil 	msg->msg[5] = phys_addr1 >> 8;
18760dbacebeSHans Verkuil 	msg->msg[6] = phys_addr1 & 0xff;
18770dbacebeSHans Verkuil 	msg->msg[7] = phys_addr2 >> 8;
18780dbacebeSHans Verkuil 	msg->msg[8] = phys_addr2 & 0xff;
18790dbacebeSHans Verkuil 	msg->msg[9] = phys_addr3 >> 8;
18800dbacebeSHans Verkuil 	msg->msg[10] = phys_addr3 & 0xff;
18810dbacebeSHans Verkuil }
18820dbacebeSHans Verkuil 
18830dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg,
18840dbacebeSHans Verkuil 							__u16 *phys_addr,
18850dbacebeSHans Verkuil 							__u16 *phys_addr1,
18860dbacebeSHans Verkuil 							__u16 *phys_addr2,
18870dbacebeSHans Verkuil 							__u16 *phys_addr3)
18880dbacebeSHans Verkuil {
18890dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
18900dbacebeSHans Verkuil 	*phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
18910dbacebeSHans Verkuil 	*phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
18920dbacebeSHans Verkuil 	*phys_addr3 = (msg->msg[9] << 8) | msg->msg[10];
18930dbacebeSHans Verkuil }
18940dbacebeSHans Verkuil 
18950dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg)
18960dbacebeSHans Verkuil {
18970dbacebeSHans Verkuil 	msg->len = 5;
18980dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
18990dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19000dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19010dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE;
19020dbacebeSHans Verkuil }
19030dbacebeSHans Verkuil 
19040dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg,
19050dbacebeSHans Verkuil 						__u16 *phys_addr)
19060dbacebeSHans Verkuil {
19070dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19080dbacebeSHans Verkuil }
19090dbacebeSHans Verkuil 
19100dbacebeSHans Verkuil static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg)
19110dbacebeSHans Verkuil {
19120dbacebeSHans Verkuil 	msg->len = 5;
19130dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19140dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19150dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19160dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER;
19170dbacebeSHans Verkuil }
19180dbacebeSHans Verkuil 
19190dbacebeSHans Verkuil static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg,
19200dbacebeSHans Verkuil 					    __u16 *phys_addr)
19210dbacebeSHans Verkuil {
19220dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19230dbacebeSHans Verkuil }
19240dbacebeSHans Verkuil 
19250dbacebeSHans Verkuil static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg,
19260dbacebeSHans Verkuil 					     __u8 input_port,
19270dbacebeSHans Verkuil 					     __u8 hpd_state)
19280dbacebeSHans Verkuil {
19290dbacebeSHans Verkuil 	msg->len = 6;
19300dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19310dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19320dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19330dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE;
19340dbacebeSHans Verkuil 	msg->msg[5] = (input_port << 4) | hpd_state;
19350dbacebeSHans Verkuil }
19360dbacebeSHans Verkuil 
19370dbacebeSHans Verkuil static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg,
19380dbacebeSHans Verkuil 					    __u16 *phys_addr,
19390dbacebeSHans Verkuil 					    __u8 *input_port,
19400dbacebeSHans Verkuil 					    __u8 *hpd_state)
19410dbacebeSHans Verkuil {
19420dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19430dbacebeSHans Verkuil 	*input_port = msg->msg[5] >> 4;
19440dbacebeSHans Verkuil 	*hpd_state = msg->msg[5] & 0xf;
19450dbacebeSHans Verkuil }
19460dbacebeSHans Verkuil 
19470dbacebeSHans Verkuil static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg,
19480dbacebeSHans Verkuil 						__u8 hpd_state,
19490dbacebeSHans Verkuil 						__u8 hpd_error)
19500dbacebeSHans Verkuil {
19510dbacebeSHans Verkuil 	msg->len = 6;
19520dbacebeSHans Verkuil 	msg->msg[0] |= 0xf; /* broadcast */
19530dbacebeSHans Verkuil 	msg->msg[1] = CEC_MSG_CDC_MESSAGE;
19540dbacebeSHans Verkuil 	/* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
19550dbacebeSHans Verkuil 	msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE;
19560dbacebeSHans Verkuil 	msg->msg[5] = (hpd_state << 4) | hpd_error;
19570dbacebeSHans Verkuil }
19580dbacebeSHans Verkuil 
19590dbacebeSHans Verkuil static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg,
19600dbacebeSHans Verkuil 						__u16 *phys_addr,
19610dbacebeSHans Verkuil 						__u8 *hpd_state,
19620dbacebeSHans Verkuil 						__u8 *hpd_error)
19630dbacebeSHans Verkuil {
19640dbacebeSHans Verkuil 	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];
19650dbacebeSHans Verkuil 	*hpd_state = msg->msg[5] >> 4;
19660dbacebeSHans Verkuil 	*hpd_error = msg->msg[5] & 0xf;
19670dbacebeSHans Verkuil }
19680dbacebeSHans Verkuil 
19690dbacebeSHans Verkuil #endif
1970