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