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