2 * cec - HDMI Consumer Electronics Control message functions
4 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 * This program is free software; you may redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * Alternatively you can redistribute this file under the terms of the
11 * BSD license as stated below:
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in
20 * the documentation and/or other materials provided with the
22 * 3. The names of its contributors may not be used to endorse or promote
23 * products derived from this software without specific prior written
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 * Note: this framework is still in staging and it is likely the API
38 * will change before it goes out of staging.
40 * Once it is moved out of staging this header will move to uapi.
42 #ifndef _CEC_UAPI_FUNCS_H
43 #define _CEC_UAPI_FUNCS_H
45 #include <linux/cec.h>
47 /* One Touch Play Feature */
48 static inline void cec_msg_active_source(struct cec_msg
*msg
, __u16 phys_addr
)
51 msg
->msg
[0] |= 0xf; /* broadcast */
52 msg
->msg
[1] = CEC_MSG_ACTIVE_SOURCE
;
53 msg
->msg
[2] = phys_addr
>> 8;
54 msg
->msg
[3] = phys_addr
& 0xff;
57 static inline void cec_ops_active_source(const struct cec_msg
*msg
,
60 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
63 static inline void cec_msg_image_view_on(struct cec_msg
*msg
)
66 msg
->msg
[1] = CEC_MSG_IMAGE_VIEW_ON
;
69 static inline void cec_msg_text_view_on(struct cec_msg
*msg
)
72 msg
->msg
[1] = CEC_MSG_TEXT_VIEW_ON
;
76 /* Routing Control Feature */
77 static inline void cec_msg_inactive_source(struct cec_msg
*msg
,
81 msg
->msg
[1] = CEC_MSG_INACTIVE_SOURCE
;
82 msg
->msg
[2] = phys_addr
>> 8;
83 msg
->msg
[3] = phys_addr
& 0xff;
86 static inline void cec_ops_inactive_source(const struct cec_msg
*msg
,
89 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
92 static inline void cec_msg_request_active_source(struct cec_msg
*msg
,
96 msg
->msg
[0] |= 0xf; /* broadcast */
97 msg
->msg
[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE
;
98 msg
->reply
= reply
? CEC_MSG_ACTIVE_SOURCE
: 0;
101 static inline void cec_msg_routing_information(struct cec_msg
*msg
,
105 msg
->msg
[0] |= 0xf; /* broadcast */
106 msg
->msg
[1] = CEC_MSG_ROUTING_INFORMATION
;
107 msg
->msg
[2] = phys_addr
>> 8;
108 msg
->msg
[3] = phys_addr
& 0xff;
111 static inline void cec_ops_routing_information(const struct cec_msg
*msg
,
114 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
117 static inline void cec_msg_routing_change(struct cec_msg
*msg
,
119 __u16 orig_phys_addr
,
123 msg
->msg
[0] |= 0xf; /* broadcast */
124 msg
->msg
[1] = CEC_MSG_ROUTING_CHANGE
;
125 msg
->msg
[2] = orig_phys_addr
>> 8;
126 msg
->msg
[3] = orig_phys_addr
& 0xff;
127 msg
->msg
[4] = new_phys_addr
>> 8;
128 msg
->msg
[5] = new_phys_addr
& 0xff;
129 msg
->reply
= reply
? CEC_MSG_ROUTING_INFORMATION
: 0;
132 static inline void cec_ops_routing_change(const struct cec_msg
*msg
,
133 __u16
*orig_phys_addr
,
134 __u16
*new_phys_addr
)
136 *orig_phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
137 *new_phys_addr
= (msg
->msg
[4] << 8) | msg
->msg
[5];
140 static inline void cec_msg_set_stream_path(struct cec_msg
*msg
, __u16 phys_addr
)
143 msg
->msg
[0] |= 0xf; /* broadcast */
144 msg
->msg
[1] = CEC_MSG_SET_STREAM_PATH
;
145 msg
->msg
[2] = phys_addr
>> 8;
146 msg
->msg
[3] = phys_addr
& 0xff;
149 static inline void cec_ops_set_stream_path(const struct cec_msg
*msg
,
152 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
156 /* Standby Feature */
157 static inline void cec_msg_standby(struct cec_msg
*msg
)
160 msg
->msg
[1] = CEC_MSG_STANDBY
;
164 /* One Touch Record Feature */
165 static inline void cec_msg_record_off(struct cec_msg
*msg
)
168 msg
->msg
[1] = CEC_MSG_RECORD_OFF
;
171 struct cec_op_arib_data
{
174 __u16 orig_network_id
;
177 struct cec_op_atsc_data
{
179 __u16 program_number
;
182 struct cec_op_dvb_data
{
185 __u16 orig_network_id
;
188 struct cec_op_channel_data
{
189 __u8 channel_number_fmt
;
194 struct cec_op_digital_service_id
{
195 __u8 service_id_method
;
196 __u8 dig_bcast_system
;
198 struct cec_op_arib_data arib
;
199 struct cec_op_atsc_data atsc
;
200 struct cec_op_dvb_data dvb
;
201 struct cec_op_channel_data channel
;
205 struct cec_op_record_src
{
208 struct cec_op_digital_service_id digital
;
223 static inline void cec_set_digital_service_id(__u8
*msg
,
224 const struct cec_op_digital_service_id
*digital
)
226 *msg
++ = (digital
->service_id_method
<< 7) | digital
->dig_bcast_system
;
227 if (digital
->service_id_method
== CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL
) {
228 *msg
++ = (digital
->channel
.channel_number_fmt
<< 2) |
229 (digital
->channel
.major
>> 8);
230 *msg
++ = digital
->channel
.major
&& 0xff;
231 *msg
++ = digital
->channel
.minor
>> 8;
232 *msg
++ = digital
->channel
.minor
& 0xff;
237 switch (digital
->dig_bcast_system
) {
238 case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN
:
239 case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE
:
240 case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT
:
241 case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T
:
242 *msg
++ = digital
->atsc
.transport_id
>> 8;
243 *msg
++ = digital
->atsc
.transport_id
& 0xff;
244 *msg
++ = digital
->atsc
.program_number
>> 8;
245 *msg
++ = digital
->atsc
.program_number
& 0xff;
250 *msg
++ = digital
->dvb
.transport_id
>> 8;
251 *msg
++ = digital
->dvb
.transport_id
& 0xff;
252 *msg
++ = digital
->dvb
.service_id
>> 8;
253 *msg
++ = digital
->dvb
.service_id
& 0xff;
254 *msg
++ = digital
->dvb
.orig_network_id
>> 8;
255 *msg
++ = digital
->dvb
.orig_network_id
& 0xff;
260 static inline void cec_get_digital_service_id(const __u8
*msg
,
261 struct cec_op_digital_service_id
*digital
)
263 digital
->service_id_method
= msg
[0] >> 7;
264 digital
->dig_bcast_system
= msg
[0] & 0x7f;
265 if (digital
->service_id_method
== CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL
) {
266 digital
->channel
.channel_number_fmt
= msg
[1] >> 2;
267 digital
->channel
.major
= ((msg
[1] & 3) << 6) | msg
[2];
268 digital
->channel
.minor
= (msg
[3] << 8) | msg
[4];
271 digital
->dvb
.transport_id
= (msg
[1] << 8) | msg
[2];
272 digital
->dvb
.service_id
= (msg
[3] << 8) | msg
[4];
273 digital
->dvb
.orig_network_id
= (msg
[5] << 8) | msg
[6];
276 static inline void cec_msg_record_on_own(struct cec_msg
*msg
)
279 msg
->msg
[1] = CEC_MSG_RECORD_ON
;
280 msg
->msg
[2] = CEC_OP_RECORD_SRC_OWN
;
283 static inline void cec_msg_record_on_digital(struct cec_msg
*msg
,
284 const struct cec_op_digital_service_id
*digital
)
287 msg
->msg
[1] = CEC_MSG_RECORD_ON
;
288 msg
->msg
[2] = CEC_OP_RECORD_SRC_DIGITAL
;
289 cec_set_digital_service_id(msg
->msg
+ 3, digital
);
292 static inline void cec_msg_record_on_analog(struct cec_msg
*msg
,
298 msg
->msg
[1] = CEC_MSG_RECORD_ON
;
299 msg
->msg
[2] = CEC_OP_RECORD_SRC_ANALOG
;
300 msg
->msg
[3] = ana_bcast_type
;
301 msg
->msg
[4] = ana_freq
>> 8;
302 msg
->msg
[5] = ana_freq
& 0xff;
303 msg
->msg
[6] = bcast_system
;
306 static inline void cec_msg_record_on_plug(struct cec_msg
*msg
,
310 msg
->msg
[1] = CEC_MSG_RECORD_ON
;
311 msg
->msg
[2] = CEC_OP_RECORD_SRC_EXT_PLUG
;
315 static inline void cec_msg_record_on_phys_addr(struct cec_msg
*msg
,
319 msg
->msg
[1] = CEC_MSG_RECORD_ON
;
320 msg
->msg
[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR
;
321 msg
->msg
[3] = phys_addr
>> 8;
322 msg
->msg
[4] = phys_addr
& 0xff;
325 static inline void cec_msg_record_on(struct cec_msg
*msg
,
326 const struct cec_op_record_src
*rec_src
)
328 switch (rec_src
->type
) {
329 case CEC_OP_RECORD_SRC_OWN
:
330 cec_msg_record_on_own(msg
);
332 case CEC_OP_RECORD_SRC_DIGITAL
:
333 cec_msg_record_on_digital(msg
, &rec_src
->digital
);
335 case CEC_OP_RECORD_SRC_ANALOG
:
336 cec_msg_record_on_analog(msg
,
337 rec_src
->analog
.ana_bcast_type
,
338 rec_src
->analog
.ana_freq
,
339 rec_src
->analog
.bcast_system
);
341 case CEC_OP_RECORD_SRC_EXT_PLUG
:
342 cec_msg_record_on_plug(msg
, rec_src
->ext_plug
.plug
);
344 case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR
:
345 cec_msg_record_on_phys_addr(msg
,
346 rec_src
->ext_phys_addr
.phys_addr
);
351 static inline void cec_ops_record_on(const struct cec_msg
*msg
,
352 struct cec_op_record_src
*rec_src
)
354 rec_src
->type
= msg
->msg
[2];
355 switch (rec_src
->type
) {
356 case CEC_OP_RECORD_SRC_OWN
:
358 case CEC_OP_RECORD_SRC_DIGITAL
:
359 cec_get_digital_service_id(msg
->msg
+ 3, &rec_src
->digital
);
361 case CEC_OP_RECORD_SRC_ANALOG
:
362 rec_src
->analog
.ana_bcast_type
= msg
->msg
[3];
363 rec_src
->analog
.ana_freq
=
364 (msg
->msg
[4] << 8) | msg
->msg
[5];
365 rec_src
->analog
.bcast_system
= msg
->msg
[6];
367 case CEC_OP_RECORD_SRC_EXT_PLUG
:
368 rec_src
->ext_plug
.plug
= msg
->msg
[3];
370 case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR
:
371 rec_src
->ext_phys_addr
.phys_addr
=
372 (msg
->msg
[3] << 8) | msg
->msg
[4];
377 static inline void cec_msg_record_status(struct cec_msg
*msg
, __u8 rec_status
)
380 msg
->msg
[1] = CEC_MSG_RECORD_STATUS
;
381 msg
->msg
[2] = rec_status
;
384 static inline void cec_ops_record_status(const struct cec_msg
*msg
,
387 *rec_status
= msg
->msg
[2];
390 static inline void cec_msg_record_tv_screen(struct cec_msg
*msg
,
394 msg
->msg
[1] = CEC_MSG_RECORD_TV_SCREEN
;
395 msg
->reply
= reply
? CEC_MSG_RECORD_ON
: 0;
399 /* Timer Programming Feature */
400 static inline void cec_msg_timer_status(struct cec_msg
*msg
,
401 __u8 timer_overlap_warning
,
409 msg
->msg
[1] = CEC_MSG_TIMER_STATUS
;
410 msg
->msg
[2] = (timer_overlap_warning
<< 7) |
412 (prog_info
? 0x10 : 0) |
413 (prog_info
? prog_info
: prog_error
);
414 if (prog_info
== CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE
||
415 prog_info
== CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE
||
416 prog_error
== CEC_OP_PROG_ERROR_DUPLICATE
) {
418 msg
->msg
[3] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
419 msg
->msg
[4] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
423 static inline void cec_ops_timer_status(const struct cec_msg
*msg
,
424 __u8
*timer_overlap_warning
,
431 *timer_overlap_warning
= msg
->msg
[2] >> 7;
432 *media_info
= (msg
->msg
[2] >> 5) & 3;
433 if (msg
->msg
[2] & 0x10) {
434 *prog_info
= msg
->msg
[2] & 0xf;
438 *prog_error
= msg
->msg
[2] & 0xf;
440 if (*prog_info
== CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE
||
441 *prog_info
== CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE
||
442 *prog_error
== CEC_OP_PROG_ERROR_DUPLICATE
) {
443 *duration_hr
= (msg
->msg
[3] >> 4) * 10 + (msg
->msg
[3] & 0xf);
444 *duration_min
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
446 *duration_hr
= *duration_min
= 0;
450 static inline void cec_msg_timer_cleared_status(struct cec_msg
*msg
,
451 __u8 timer_cleared_status
)
454 msg
->msg
[1] = CEC_MSG_TIMER_CLEARED_STATUS
;
455 msg
->msg
[2] = timer_cleared_status
;
458 static inline void cec_ops_timer_cleared_status(const struct cec_msg
*msg
,
459 __u8
*timer_cleared_status
)
461 *timer_cleared_status
= msg
->msg
[2];
464 static inline void cec_msg_clear_analogue_timer(struct cec_msg
*msg
,
478 msg
->msg
[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER
;
481 /* Hours and minutes are in BCD format */
482 msg
->msg
[4] = ((start_hr
/ 10) << 4) | (start_hr
% 10);
483 msg
->msg
[5] = ((start_min
/ 10) << 4) | (start_min
% 10);
484 msg
->msg
[6] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
485 msg
->msg
[7] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
486 msg
->msg
[8] = recording_seq
;
487 msg
->msg
[9] = ana_bcast_type
;
488 msg
->msg
[10] = ana_freq
>> 8;
489 msg
->msg
[11] = ana_freq
& 0xff;
490 msg
->msg
[12] = bcast_system
;
491 msg
->reply
= reply
? CEC_MSG_TIMER_CLEARED_STATUS
: 0;
494 static inline void cec_ops_clear_analogue_timer(const struct cec_msg
*msg
,
502 __u8
*ana_bcast_type
,
507 *month
= msg
->msg
[3];
508 /* Hours and minutes are in BCD format */
509 *start_hr
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
510 *start_min
= (msg
->msg
[5] >> 4) * 10 + (msg
->msg
[5] & 0xf);
511 *duration_hr
= (msg
->msg
[6] >> 4) * 10 + (msg
->msg
[6] & 0xf);
512 *duration_min
= (msg
->msg
[7] >> 4) * 10 + (msg
->msg
[7] & 0xf);
513 *recording_seq
= msg
->msg
[8];
514 *ana_bcast_type
= msg
->msg
[9];
515 *ana_freq
= (msg
->msg
[10] << 8) | msg
->msg
[11];
516 *bcast_system
= msg
->msg
[12];
519 static inline void cec_msg_clear_digital_timer(struct cec_msg
*msg
,
528 const struct cec_op_digital_service_id
*digital
)
531 msg
->reply
= reply
? CEC_MSG_TIMER_CLEARED_STATUS
: 0;
532 msg
->msg
[1] = CEC_MSG_CLEAR_DIGITAL_TIMER
;
535 /* Hours and minutes are in BCD format */
536 msg
->msg
[4] = ((start_hr
/ 10) << 4) | (start_hr
% 10);
537 msg
->msg
[5] = ((start_min
/ 10) << 4) | (start_min
% 10);
538 msg
->msg
[6] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
539 msg
->msg
[7] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
540 msg
->msg
[8] = recording_seq
;
541 cec_set_digital_service_id(msg
->msg
+ 9, digital
);
544 static inline void cec_ops_clear_digital_timer(const struct cec_msg
*msg
,
552 struct cec_op_digital_service_id
*digital
)
555 *month
= msg
->msg
[3];
556 /* Hours and minutes are in BCD format */
557 *start_hr
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
558 *start_min
= (msg
->msg
[5] >> 4) * 10 + (msg
->msg
[5] & 0xf);
559 *duration_hr
= (msg
->msg
[6] >> 4) * 10 + (msg
->msg
[6] & 0xf);
560 *duration_min
= (msg
->msg
[7] >> 4) * 10 + (msg
->msg
[7] & 0xf);
561 *recording_seq
= msg
->msg
[8];
562 cec_get_digital_service_id(msg
->msg
+ 9, digital
);
565 static inline void cec_msg_clear_ext_timer(struct cec_msg
*msg
,
579 msg
->msg
[1] = CEC_MSG_CLEAR_EXT_TIMER
;
582 /* Hours and minutes are in BCD format */
583 msg
->msg
[4] = ((start_hr
/ 10) << 4) | (start_hr
% 10);
584 msg
->msg
[5] = ((start_min
/ 10) << 4) | (start_min
% 10);
585 msg
->msg
[6] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
586 msg
->msg
[7] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
587 msg
->msg
[8] = recording_seq
;
588 msg
->msg
[9] = ext_src_spec
;
590 msg
->msg
[11] = phys_addr
>> 8;
591 msg
->msg
[12] = phys_addr
& 0xff;
592 msg
->reply
= reply
? CEC_MSG_TIMER_CLEARED_STATUS
: 0;
595 static inline void cec_ops_clear_ext_timer(const struct cec_msg
*msg
,
608 *month
= msg
->msg
[3];
609 /* Hours and minutes are in BCD format */
610 *start_hr
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
611 *start_min
= (msg
->msg
[5] >> 4) * 10 + (msg
->msg
[5] & 0xf);
612 *duration_hr
= (msg
->msg
[6] >> 4) * 10 + (msg
->msg
[6] & 0xf);
613 *duration_min
= (msg
->msg
[7] >> 4) * 10 + (msg
->msg
[7] & 0xf);
614 *recording_seq
= msg
->msg
[8];
615 *ext_src_spec
= msg
->msg
[9];
616 *plug
= msg
->msg
[10];
617 *phys_addr
= (msg
->msg
[11] << 8) | msg
->msg
[12];
620 static inline void cec_msg_set_analogue_timer(struct cec_msg
*msg
,
634 msg
->msg
[1] = CEC_MSG_SET_ANALOGUE_TIMER
;
637 /* Hours and minutes are in BCD format */
638 msg
->msg
[4] = ((start_hr
/ 10) << 4) | (start_hr
% 10);
639 msg
->msg
[5] = ((start_min
/ 10) << 4) | (start_min
% 10);
640 msg
->msg
[6] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
641 msg
->msg
[7] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
642 msg
->msg
[8] = recording_seq
;
643 msg
->msg
[9] = ana_bcast_type
;
644 msg
->msg
[10] = ana_freq
>> 8;
645 msg
->msg
[11] = ana_freq
& 0xff;
646 msg
->msg
[12] = bcast_system
;
647 msg
->reply
= reply
? CEC_MSG_TIMER_STATUS
: 0;
650 static inline void cec_ops_set_analogue_timer(const struct cec_msg
*msg
,
658 __u8
*ana_bcast_type
,
663 *month
= msg
->msg
[3];
664 /* Hours and minutes are in BCD format */
665 *start_hr
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
666 *start_min
= (msg
->msg
[5] >> 4) * 10 + (msg
->msg
[5] & 0xf);
667 *duration_hr
= (msg
->msg
[6] >> 4) * 10 + (msg
->msg
[6] & 0xf);
668 *duration_min
= (msg
->msg
[7] >> 4) * 10 + (msg
->msg
[7] & 0xf);
669 *recording_seq
= msg
->msg
[8];
670 *ana_bcast_type
= msg
->msg
[9];
671 *ana_freq
= (msg
->msg
[10] << 8) | msg
->msg
[11];
672 *bcast_system
= msg
->msg
[12];
675 static inline void cec_msg_set_digital_timer(struct cec_msg
*msg
,
684 const struct cec_op_digital_service_id
*digital
)
687 msg
->reply
= reply
? CEC_MSG_TIMER_STATUS
: 0;
688 msg
->msg
[1] = CEC_MSG_SET_DIGITAL_TIMER
;
691 /* Hours and minutes are in BCD format */
692 msg
->msg
[4] = ((start_hr
/ 10) << 4) | (start_hr
% 10);
693 msg
->msg
[5] = ((start_min
/ 10) << 4) | (start_min
% 10);
694 msg
->msg
[6] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
695 msg
->msg
[7] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
696 msg
->msg
[8] = recording_seq
;
697 cec_set_digital_service_id(msg
->msg
+ 9, digital
);
700 static inline void cec_ops_set_digital_timer(const struct cec_msg
*msg
,
708 struct cec_op_digital_service_id
*digital
)
711 *month
= msg
->msg
[3];
712 /* Hours and minutes are in BCD format */
713 *start_hr
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
714 *start_min
= (msg
->msg
[5] >> 4) * 10 + (msg
->msg
[5] & 0xf);
715 *duration_hr
= (msg
->msg
[6] >> 4) * 10 + (msg
->msg
[6] & 0xf);
716 *duration_min
= (msg
->msg
[7] >> 4) * 10 + (msg
->msg
[7] & 0xf);
717 *recording_seq
= msg
->msg
[8];
718 cec_get_digital_service_id(msg
->msg
+ 9, digital
);
721 static inline void cec_msg_set_ext_timer(struct cec_msg
*msg
,
735 msg
->msg
[1] = CEC_MSG_SET_EXT_TIMER
;
738 /* Hours and minutes are in BCD format */
739 msg
->msg
[4] = ((start_hr
/ 10) << 4) | (start_hr
% 10);
740 msg
->msg
[5] = ((start_min
/ 10) << 4) | (start_min
% 10);
741 msg
->msg
[6] = ((duration_hr
/ 10) << 4) | (duration_hr
% 10);
742 msg
->msg
[7] = ((duration_min
/ 10) << 4) | (duration_min
% 10);
743 msg
->msg
[8] = recording_seq
;
744 msg
->msg
[9] = ext_src_spec
;
746 msg
->msg
[11] = phys_addr
>> 8;
747 msg
->msg
[12] = phys_addr
& 0xff;
748 msg
->reply
= reply
? CEC_MSG_TIMER_STATUS
: 0;
751 static inline void cec_ops_set_ext_timer(const struct cec_msg
*msg
,
764 *month
= msg
->msg
[3];
765 /* Hours and minutes are in BCD format */
766 *start_hr
= (msg
->msg
[4] >> 4) * 10 + (msg
->msg
[4] & 0xf);
767 *start_min
= (msg
->msg
[5] >> 4) * 10 + (msg
->msg
[5] & 0xf);
768 *duration_hr
= (msg
->msg
[6] >> 4) * 10 + (msg
->msg
[6] & 0xf);
769 *duration_min
= (msg
->msg
[7] >> 4) * 10 + (msg
->msg
[7] & 0xf);
770 *recording_seq
= msg
->msg
[8];
771 *ext_src_spec
= msg
->msg
[9];
772 *plug
= msg
->msg
[10];
773 *phys_addr
= (msg
->msg
[11] << 8) | msg
->msg
[12];
776 static inline void cec_msg_set_timer_program_title(struct cec_msg
*msg
,
777 const char *prog_title
)
779 unsigned int len
= strlen(prog_title
);
784 msg
->msg
[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE
;
785 memcpy(msg
->msg
+ 2, prog_title
, len
);
788 static inline void cec_ops_set_timer_program_title(const struct cec_msg
*msg
,
791 unsigned int len
= msg
->len
> 2 ? msg
->len
- 2 : 0;
795 memcpy(prog_title
, msg
->msg
+ 2, len
);
796 prog_title
[len
] = '\0';
799 /* System Information Feature */
800 static inline void cec_msg_cec_version(struct cec_msg
*msg
, __u8 cec_version
)
803 msg
->msg
[1] = CEC_MSG_CEC_VERSION
;
804 msg
->msg
[2] = cec_version
;
807 static inline void cec_ops_cec_version(const struct cec_msg
*msg
,
810 *cec_version
= msg
->msg
[2];
813 static inline void cec_msg_get_cec_version(struct cec_msg
*msg
,
817 msg
->msg
[1] = CEC_MSG_GET_CEC_VERSION
;
818 msg
->reply
= reply
? CEC_MSG_CEC_VERSION
: 0;
821 static inline void cec_msg_report_physical_addr(struct cec_msg
*msg
,
822 __u16 phys_addr
, __u8 prim_devtype
)
825 msg
->msg
[0] |= 0xf; /* broadcast */
826 msg
->msg
[1] = CEC_MSG_REPORT_PHYSICAL_ADDR
;
827 msg
->msg
[2] = phys_addr
>> 8;
828 msg
->msg
[3] = phys_addr
& 0xff;
829 msg
->msg
[4] = prim_devtype
;
832 static inline void cec_ops_report_physical_addr(const struct cec_msg
*msg
,
833 __u16
*phys_addr
, __u8
*prim_devtype
)
835 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
836 *prim_devtype
= msg
->msg
[4];
839 static inline void cec_msg_give_physical_addr(struct cec_msg
*msg
,
843 msg
->msg
[1] = CEC_MSG_GIVE_PHYSICAL_ADDR
;
844 msg
->reply
= reply
? CEC_MSG_REPORT_PHYSICAL_ADDR
: 0;
847 static inline void cec_msg_set_menu_language(struct cec_msg
*msg
,
848 const char *language
)
851 msg
->msg
[0] |= 0xf; /* broadcast */
852 msg
->msg
[1] = CEC_MSG_SET_MENU_LANGUAGE
;
853 memcpy(msg
->msg
+ 2, language
, 3);
856 static inline void cec_ops_set_menu_language(const struct cec_msg
*msg
,
859 memcpy(language
, msg
->msg
+ 2, 3);
863 static inline void cec_msg_get_menu_language(struct cec_msg
*msg
,
867 msg
->msg
[1] = CEC_MSG_GET_MENU_LANGUAGE
;
868 msg
->reply
= reply
? CEC_MSG_SET_MENU_LANGUAGE
: 0;
872 * Assumes a single RC Profile byte and a single Device Features byte,
873 * i.e. no extended features are supported by this helper function.
875 * As of CEC 2.0 no extended features are defined, should those be added
876 * in the future, then this function needs to be adapted or a new function
879 static inline void cec_msg_report_features(struct cec_msg
*msg
,
880 __u8 cec_version
, __u8 all_device_types
,
881 __u8 rc_profile
, __u8 dev_features
)
884 msg
->msg
[0] |= 0xf; /* broadcast */
885 msg
->msg
[1] = CEC_MSG_REPORT_FEATURES
;
886 msg
->msg
[2] = cec_version
;
887 msg
->msg
[3] = all_device_types
;
888 msg
->msg
[4] = rc_profile
;
889 msg
->msg
[5] = dev_features
;
892 static inline void cec_ops_report_features(const struct cec_msg
*msg
,
893 __u8
*cec_version
, __u8
*all_device_types
,
894 const __u8
**rc_profile
, const __u8
**dev_features
)
896 const __u8
*p
= &msg
->msg
[4];
898 *cec_version
= msg
->msg
[2];
899 *all_device_types
= msg
->msg
[3];
901 while (p
< &msg
->msg
[14] && (*p
& CEC_OP_FEAT_EXT
))
903 if (!(*p
& CEC_OP_FEAT_EXT
)) {
904 *dev_features
= p
+ 1;
905 while (p
< &msg
->msg
[15] && (*p
& CEC_OP_FEAT_EXT
))
908 if (*p
& CEC_OP_FEAT_EXT
)
909 *rc_profile
= *dev_features
= NULL
;
912 static inline void cec_msg_give_features(struct cec_msg
*msg
,
916 msg
->msg
[1] = CEC_MSG_GIVE_FEATURES
;
917 msg
->reply
= reply
? CEC_MSG_REPORT_FEATURES
: 0;
920 /* Deck Control Feature */
921 static inline void cec_msg_deck_control(struct cec_msg
*msg
,
922 __u8 deck_control_mode
)
925 msg
->msg
[1] = CEC_MSG_DECK_CONTROL
;
926 msg
->msg
[2] = deck_control_mode
;
929 static inline void cec_ops_deck_control(const struct cec_msg
*msg
,
930 __u8
*deck_control_mode
)
932 *deck_control_mode
= msg
->msg
[2];
935 static inline void cec_msg_deck_status(struct cec_msg
*msg
,
939 msg
->msg
[1] = CEC_MSG_DECK_STATUS
;
940 msg
->msg
[2] = deck_info
;
943 static inline void cec_ops_deck_status(const struct cec_msg
*msg
,
946 *deck_info
= msg
->msg
[2];
949 static inline void cec_msg_give_deck_status(struct cec_msg
*msg
,
954 msg
->msg
[1] = CEC_MSG_GIVE_DECK_STATUS
;
955 msg
->msg
[2] = status_req
;
956 msg
->reply
= reply
? CEC_MSG_DECK_STATUS
: 0;
959 static inline void cec_ops_give_deck_status(const struct cec_msg
*msg
,
962 *status_req
= msg
->msg
[2];
965 static inline void cec_msg_play(struct cec_msg
*msg
,
969 msg
->msg
[1] = CEC_MSG_PLAY
;
970 msg
->msg
[2] = play_mode
;
973 static inline void cec_ops_play(const struct cec_msg
*msg
,
976 *play_mode
= msg
->msg
[2];
980 /* Tuner Control Feature */
981 struct cec_op_tuner_device_info
{
983 __u8 tuner_display_info
;
986 struct cec_op_digital_service_id digital
;
995 static inline void cec_msg_tuner_device_status_analog(struct cec_msg
*msg
,
997 __u8 tuner_display_info
,
1003 msg
->msg
[1] = CEC_MSG_TUNER_DEVICE_STATUS
;
1004 msg
->msg
[2] = (rec_flag
<< 7) | tuner_display_info
;
1005 msg
->msg
[3] = ana_bcast_type
;
1006 msg
->msg
[4] = ana_freq
>> 8;
1007 msg
->msg
[5] = ana_freq
& 0xff;
1008 msg
->msg
[6] = bcast_system
;
1011 static inline void cec_msg_tuner_device_status_digital(struct cec_msg
*msg
,
1012 __u8 rec_flag
, __u8 tuner_display_info
,
1013 const struct cec_op_digital_service_id
*digital
)
1016 msg
->msg
[1] = CEC_MSG_TUNER_DEVICE_STATUS
;
1017 msg
->msg
[2] = (rec_flag
<< 7) | tuner_display_info
;
1018 cec_set_digital_service_id(msg
->msg
+ 3, digital
);
1021 static inline void cec_msg_tuner_device_status(struct cec_msg
*msg
,
1022 const struct cec_op_tuner_device_info
*tuner_dev_info
)
1024 if (tuner_dev_info
->is_analog
)
1025 cec_msg_tuner_device_status_analog(msg
,
1026 tuner_dev_info
->rec_flag
,
1027 tuner_dev_info
->tuner_display_info
,
1028 tuner_dev_info
->analog
.ana_bcast_type
,
1029 tuner_dev_info
->analog
.ana_freq
,
1030 tuner_dev_info
->analog
.bcast_system
);
1032 cec_msg_tuner_device_status_digital(msg
,
1033 tuner_dev_info
->rec_flag
,
1034 tuner_dev_info
->tuner_display_info
,
1035 &tuner_dev_info
->digital
);
1038 static inline void cec_ops_tuner_device_status(const struct cec_msg
*msg
,
1039 struct cec_op_tuner_device_info
*tuner_dev_info
)
1041 tuner_dev_info
->is_analog
= msg
->len
< 10;
1042 tuner_dev_info
->rec_flag
= msg
->msg
[2] >> 7;
1043 tuner_dev_info
->tuner_display_info
= msg
->msg
[2] & 0x7f;
1044 if (tuner_dev_info
->is_analog
) {
1045 tuner_dev_info
->analog
.ana_bcast_type
= msg
->msg
[3];
1046 tuner_dev_info
->analog
.ana_freq
= (msg
->msg
[4] << 8) | msg
->msg
[5];
1047 tuner_dev_info
->analog
.bcast_system
= msg
->msg
[6];
1050 cec_get_digital_service_id(msg
->msg
+ 3, &tuner_dev_info
->digital
);
1053 static inline void cec_msg_give_tuner_device_status(struct cec_msg
*msg
,
1058 msg
->msg
[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS
;
1059 msg
->msg
[2] = status_req
;
1060 msg
->reply
= reply
? CEC_MSG_TUNER_DEVICE_STATUS
: 0;
1063 static inline void cec_ops_give_tuner_device_status(const struct cec_msg
*msg
,
1066 *status_req
= msg
->msg
[2];
1069 static inline void cec_msg_select_analogue_service(struct cec_msg
*msg
,
1070 __u8 ana_bcast_type
,
1075 msg
->msg
[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE
;
1076 msg
->msg
[2] = ana_bcast_type
;
1077 msg
->msg
[3] = ana_freq
>> 8;
1078 msg
->msg
[4] = ana_freq
& 0xff;
1079 msg
->msg
[5] = bcast_system
;
1082 static inline void cec_ops_select_analogue_service(const struct cec_msg
*msg
,
1083 __u8
*ana_bcast_type
,
1087 *ana_bcast_type
= msg
->msg
[2];
1088 *ana_freq
= (msg
->msg
[3] << 8) | msg
->msg
[4];
1089 *bcast_system
= msg
->msg
[5];
1092 static inline void cec_msg_select_digital_service(struct cec_msg
*msg
,
1093 const struct cec_op_digital_service_id
*digital
)
1096 msg
->msg
[1] = CEC_MSG_SELECT_DIGITAL_SERVICE
;
1097 cec_set_digital_service_id(msg
->msg
+ 2, digital
);
1100 static inline void cec_ops_select_digital_service(const struct cec_msg
*msg
,
1101 struct cec_op_digital_service_id
*digital
)
1103 cec_get_digital_service_id(msg
->msg
+ 2, digital
);
1106 static inline void cec_msg_tuner_step_decrement(struct cec_msg
*msg
)
1109 msg
->msg
[1] = CEC_MSG_TUNER_STEP_DECREMENT
;
1112 static inline void cec_msg_tuner_step_increment(struct cec_msg
*msg
)
1115 msg
->msg
[1] = CEC_MSG_TUNER_STEP_INCREMENT
;
1119 /* Vendor Specific Commands Feature */
1120 static inline void cec_msg_device_vendor_id(struct cec_msg
*msg
, __u32 vendor_id
)
1123 msg
->msg
[0] |= 0xf; /* broadcast */
1124 msg
->msg
[1] = CEC_MSG_DEVICE_VENDOR_ID
;
1125 msg
->msg
[2] = vendor_id
>> 16;
1126 msg
->msg
[3] = (vendor_id
>> 8) & 0xff;
1127 msg
->msg
[4] = vendor_id
& 0xff;
1130 static inline void cec_ops_device_vendor_id(const struct cec_msg
*msg
,
1133 *vendor_id
= (msg
->msg
[2] << 16) | (msg
->msg
[3] << 8) | msg
->msg
[4];
1136 static inline void cec_msg_give_device_vendor_id(struct cec_msg
*msg
,
1140 msg
->msg
[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID
;
1141 msg
->reply
= reply
? CEC_MSG_DEVICE_VENDOR_ID
: 0;
1144 static inline void cec_msg_vendor_remote_button_up(struct cec_msg
*msg
)
1147 msg
->msg
[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP
;
1151 /* OSD Display Feature */
1152 static inline void cec_msg_set_osd_string(struct cec_msg
*msg
,
1156 unsigned int len
= strlen(osd
);
1161 msg
->msg
[1] = CEC_MSG_SET_OSD_STRING
;
1162 msg
->msg
[2] = disp_ctl
;
1163 memcpy(msg
->msg
+ 3, osd
, len
);
1166 static inline void cec_ops_set_osd_string(const struct cec_msg
*msg
,
1170 unsigned int len
= msg
->len
> 3 ? msg
->len
- 3 : 0;
1172 *disp_ctl
= msg
->msg
[2];
1175 memcpy(osd
, msg
->msg
+ 3, len
);
1180 /* Device OSD Transfer Feature */
1181 static inline void cec_msg_set_osd_name(struct cec_msg
*msg
, const char *name
)
1183 unsigned int len
= strlen(name
);
1188 msg
->msg
[1] = CEC_MSG_SET_OSD_NAME
;
1189 memcpy(msg
->msg
+ 2, name
, len
);
1192 static inline void cec_ops_set_osd_name(const struct cec_msg
*msg
,
1195 unsigned int len
= msg
->len
> 2 ? msg
->len
- 2 : 0;
1199 memcpy(name
, msg
->msg
+ 2, len
);
1203 static inline void cec_msg_give_osd_name(struct cec_msg
*msg
,
1207 msg
->msg
[1] = CEC_MSG_GIVE_OSD_NAME
;
1208 msg
->reply
= reply
? CEC_MSG_SET_OSD_NAME
: 0;
1212 /* Device Menu Control Feature */
1213 static inline void cec_msg_menu_status(struct cec_msg
*msg
,
1217 msg
->msg
[1] = CEC_MSG_MENU_STATUS
;
1218 msg
->msg
[2] = menu_state
;
1221 static inline void cec_ops_menu_status(const struct cec_msg
*msg
,
1224 *menu_state
= msg
->msg
[2];
1227 static inline void cec_msg_menu_request(struct cec_msg
*msg
,
1232 msg
->msg
[1] = CEC_MSG_MENU_REQUEST
;
1233 msg
->msg
[2] = menu_req
;
1234 msg
->reply
= reply
? CEC_MSG_MENU_STATUS
: 0;
1237 static inline void cec_ops_menu_request(const struct cec_msg
*msg
,
1240 *menu_req
= msg
->msg
[2];
1243 struct cec_op_ui_command
{
1247 struct cec_op_channel_data channel_identifier
;
1248 __u8 ui_broadcast_type
;
1249 __u8 ui_sound_presentation_control
;
1251 __u8 ui_function_media
;
1252 __u8 ui_function_select_av_input
;
1253 __u8 ui_function_select_audio_input
;
1257 static inline void cec_msg_user_control_pressed(struct cec_msg
*msg
,
1258 const struct cec_op_ui_command
*ui_cmd
)
1261 msg
->msg
[1] = CEC_MSG_USER_CONTROL_PRESSED
;
1262 msg
->msg
[2] = ui_cmd
->ui_cmd
;
1263 if (!ui_cmd
->has_opt_arg
)
1265 switch (ui_cmd
->ui_cmd
) {
1272 /* The optional operand is one byte for all these ui commands */
1274 msg
->msg
[3] = ui_cmd
->play_mode
;
1278 msg
->msg
[3] = (ui_cmd
->channel_identifier
.channel_number_fmt
<< 2) |
1279 (ui_cmd
->channel_identifier
.major
>> 8);
1280 msg
->msg
[4] = ui_cmd
->channel_identifier
.major
&& 0xff;
1281 msg
->msg
[5] = ui_cmd
->channel_identifier
.minor
>> 8;
1282 msg
->msg
[6] = ui_cmd
->channel_identifier
.minor
& 0xff;
1287 static inline void cec_ops_user_control_pressed(const struct cec_msg
*msg
,
1288 struct cec_op_ui_command
*ui_cmd
)
1290 ui_cmd
->ui_cmd
= msg
->msg
[2];
1291 ui_cmd
->has_opt_arg
= false;
1294 switch (ui_cmd
->ui_cmd
) {
1301 /* The optional operand is one byte for all these ui commands */
1302 ui_cmd
->play_mode
= msg
->msg
[3];
1303 ui_cmd
->has_opt_arg
= true;
1308 ui_cmd
->has_opt_arg
= true;
1309 ui_cmd
->channel_identifier
.channel_number_fmt
= msg
->msg
[3] >> 2;
1310 ui_cmd
->channel_identifier
.major
= ((msg
->msg
[3] & 3) << 6) | msg
->msg
[4];
1311 ui_cmd
->channel_identifier
.minor
= (msg
->msg
[5] << 8) | msg
->msg
[6];
1316 static inline void cec_msg_user_control_released(struct cec_msg
*msg
)
1319 msg
->msg
[1] = CEC_MSG_USER_CONTROL_RELEASED
;
1322 /* Remote Control Passthrough Feature */
1324 /* Power Status Feature */
1325 static inline void cec_msg_report_power_status(struct cec_msg
*msg
,
1329 msg
->msg
[1] = CEC_MSG_REPORT_POWER_STATUS
;
1330 msg
->msg
[2] = pwr_state
;
1333 static inline void cec_ops_report_power_status(const struct cec_msg
*msg
,
1336 *pwr_state
= msg
->msg
[2];
1339 static inline void cec_msg_give_device_power_status(struct cec_msg
*msg
,
1343 msg
->msg
[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS
;
1344 msg
->reply
= reply
? CEC_MSG_REPORT_POWER_STATUS
: 0;
1347 /* General Protocol Messages */
1348 static inline void cec_msg_feature_abort(struct cec_msg
*msg
,
1349 __u8 abort_msg
, __u8 reason
)
1352 msg
->msg
[1] = CEC_MSG_FEATURE_ABORT
;
1353 msg
->msg
[2] = abort_msg
;
1354 msg
->msg
[3] = reason
;
1357 static inline void cec_ops_feature_abort(const struct cec_msg
*msg
,
1358 __u8
*abort_msg
, __u8
*reason
)
1360 *abort_msg
= msg
->msg
[2];
1361 *reason
= msg
->msg
[3];
1364 /* This changes the current message into a feature abort message */
1365 static inline void cec_msg_reply_feature_abort(struct cec_msg
*msg
, __u8 reason
)
1367 cec_msg_set_reply_to(msg
, msg
);
1369 msg
->msg
[2] = msg
->msg
[1];
1370 msg
->msg
[3] = reason
;
1371 msg
->msg
[1] = CEC_MSG_FEATURE_ABORT
;
1374 static inline void cec_msg_abort(struct cec_msg
*msg
)
1377 msg
->msg
[1] = CEC_MSG_ABORT
;
1381 /* System Audio Control Feature */
1382 static inline void cec_msg_report_audio_status(struct cec_msg
*msg
,
1383 __u8 aud_mute_status
,
1384 __u8 aud_vol_status
)
1387 msg
->msg
[1] = CEC_MSG_REPORT_AUDIO_STATUS
;
1388 msg
->msg
[2] = (aud_mute_status
<< 7) | (aud_vol_status
& 0x7f);
1391 static inline void cec_ops_report_audio_status(const struct cec_msg
*msg
,
1392 __u8
*aud_mute_status
,
1393 __u8
*aud_vol_status
)
1395 *aud_mute_status
= msg
->msg
[2] >> 7;
1396 *aud_vol_status
= msg
->msg
[2] & 0x7f;
1399 static inline void cec_msg_give_audio_status(struct cec_msg
*msg
,
1403 msg
->msg
[1] = CEC_MSG_GIVE_AUDIO_STATUS
;
1404 msg
->reply
= reply
? CEC_MSG_REPORT_AUDIO_STATUS
: 0;
1407 static inline void cec_msg_set_system_audio_mode(struct cec_msg
*msg
,
1408 __u8 sys_aud_status
)
1411 msg
->msg
[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE
;
1412 msg
->msg
[2] = sys_aud_status
;
1415 static inline void cec_ops_set_system_audio_mode(const struct cec_msg
*msg
,
1416 __u8
*sys_aud_status
)
1418 *sys_aud_status
= msg
->msg
[2];
1421 static inline void cec_msg_system_audio_mode_request(struct cec_msg
*msg
,
1425 msg
->len
= phys_addr
== 0xffff ? 2 : 4;
1426 msg
->msg
[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST
;
1427 msg
->msg
[2] = phys_addr
>> 8;
1428 msg
->msg
[3] = phys_addr
& 0xff;
1429 msg
->reply
= reply
? CEC_MSG_SET_SYSTEM_AUDIO_MODE
: 0;
1433 static inline void cec_ops_system_audio_mode_request(const struct cec_msg
*msg
,
1437 *phys_addr
= 0xffff;
1439 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1442 static inline void cec_msg_system_audio_mode_status(struct cec_msg
*msg
,
1443 __u8 sys_aud_status
)
1446 msg
->msg
[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
;
1447 msg
->msg
[2] = sys_aud_status
;
1450 static inline void cec_ops_system_audio_mode_status(const struct cec_msg
*msg
,
1451 __u8
*sys_aud_status
)
1453 *sys_aud_status
= msg
->msg
[2];
1456 static inline void cec_msg_give_system_audio_mode_status(struct cec_msg
*msg
,
1460 msg
->msg
[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS
;
1461 msg
->reply
= reply
? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
: 0;
1464 static inline void cec_msg_report_short_audio_descriptor(struct cec_msg
*msg
,
1465 __u8 num_descriptors
,
1466 const __u32
*descriptors
)
1470 if (num_descriptors
> 4)
1471 num_descriptors
= 4;
1472 msg
->len
= 2 + num_descriptors
* 3;
1473 msg
->msg
[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR
;
1474 for (i
= 0; i
< num_descriptors
; i
++) {
1475 msg
->msg
[2 + i
* 3] = (descriptors
[i
] >> 16) & 0xff;
1476 msg
->msg
[3 + i
* 3] = (descriptors
[i
] >> 8) & 0xff;
1477 msg
->msg
[4 + i
* 3] = descriptors
[i
] & 0xff;
1481 static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg
*msg
,
1482 __u8
*num_descriptors
,
1487 *num_descriptors
= (msg
->len
- 2) / 3;
1488 if (*num_descriptors
> 4)
1489 *num_descriptors
= 4;
1490 for (i
= 0; i
< *num_descriptors
; i
++)
1491 descriptors
[i
] = (msg
->msg
[2 + i
* 3] << 16) |
1492 (msg
->msg
[3 + i
* 3] << 8) |
1493 msg
->msg
[4 + i
* 3];
1496 static inline void cec_msg_request_short_audio_descriptor(struct cec_msg
*msg
,
1498 __u8 num_descriptors
,
1499 const __u8
*audio_format_id
,
1500 const __u8
*audio_format_code
)
1504 if (num_descriptors
> 4)
1505 num_descriptors
= 4;
1506 msg
->len
= 2 + num_descriptors
;
1507 msg
->msg
[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR
;
1508 msg
->reply
= reply
? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR
: 0;
1509 for (i
= 0; i
< num_descriptors
; i
++)
1510 msg
->msg
[2 + i
] = (audio_format_id
[i
] << 6) |
1511 (audio_format_code
[i
] & 0x3f);
1514 static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg
*msg
,
1515 __u8
*num_descriptors
,
1516 __u8
*audio_format_id
,
1517 __u8
*audio_format_code
)
1521 *num_descriptors
= msg
->len
- 2;
1522 if (*num_descriptors
> 4)
1523 *num_descriptors
= 4;
1524 for (i
= 0; i
< *num_descriptors
; i
++) {
1525 audio_format_id
[i
] = msg
->msg
[2 + i
] >> 6;
1526 audio_format_code
[i
] = msg
->msg
[2 + i
] & 0x3f;
1531 /* Audio Rate Control Feature */
1532 static inline void cec_msg_set_audio_rate(struct cec_msg
*msg
,
1536 msg
->msg
[1] = CEC_MSG_SET_AUDIO_RATE
;
1537 msg
->msg
[2] = audio_rate
;
1540 static inline void cec_ops_set_audio_rate(const struct cec_msg
*msg
,
1543 *audio_rate
= msg
->msg
[2];
1547 /* Audio Return Channel Control Feature */
1548 static inline void cec_msg_report_arc_initiated(struct cec_msg
*msg
)
1551 msg
->msg
[1] = CEC_MSG_REPORT_ARC_INITIATED
;
1554 static inline void cec_msg_initiate_arc(struct cec_msg
*msg
,
1558 msg
->msg
[1] = CEC_MSG_INITIATE_ARC
;
1559 msg
->reply
= reply
? CEC_MSG_REPORT_ARC_INITIATED
: 0;
1562 static inline void cec_msg_request_arc_initiation(struct cec_msg
*msg
,
1566 msg
->msg
[1] = CEC_MSG_REQUEST_ARC_INITIATION
;
1567 msg
->reply
= reply
? CEC_MSG_INITIATE_ARC
: 0;
1570 static inline void cec_msg_report_arc_terminated(struct cec_msg
*msg
)
1573 msg
->msg
[1] = CEC_MSG_REPORT_ARC_TERMINATED
;
1576 static inline void cec_msg_terminate_arc(struct cec_msg
*msg
,
1580 msg
->msg
[1] = CEC_MSG_TERMINATE_ARC
;
1581 msg
->reply
= reply
? CEC_MSG_REPORT_ARC_TERMINATED
: 0;
1584 static inline void cec_msg_request_arc_termination(struct cec_msg
*msg
,
1588 msg
->msg
[1] = CEC_MSG_REQUEST_ARC_TERMINATION
;
1589 msg
->reply
= reply
? CEC_MSG_TERMINATE_ARC
: 0;
1593 /* Dynamic Audio Lipsync Feature */
1594 /* Only for CEC 2.0 and up */
1595 static inline void cec_msg_report_current_latency(struct cec_msg
*msg
,
1598 __u8 low_latency_mode
,
1599 __u8 audio_out_compensated
,
1600 __u8 audio_out_delay
)
1603 msg
->msg
[0] |= 0xf; /* broadcast */
1604 msg
->msg
[1] = CEC_MSG_REPORT_CURRENT_LATENCY
;
1605 msg
->msg
[2] = phys_addr
>> 8;
1606 msg
->msg
[3] = phys_addr
& 0xff;
1607 msg
->msg
[4] = video_latency
;
1608 msg
->msg
[5] = (low_latency_mode
<< 2) | audio_out_compensated
;
1609 msg
->msg
[6] = audio_out_delay
;
1612 static inline void cec_ops_report_current_latency(const struct cec_msg
*msg
,
1614 __u8
*video_latency
,
1615 __u8
*low_latency_mode
,
1616 __u8
*audio_out_compensated
,
1617 __u8
*audio_out_delay
)
1619 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1620 *video_latency
= msg
->msg
[4];
1621 *low_latency_mode
= (msg
->msg
[5] >> 2) & 1;
1622 *audio_out_compensated
= msg
->msg
[5] & 3;
1623 *audio_out_delay
= msg
->msg
[6];
1626 static inline void cec_msg_request_current_latency(struct cec_msg
*msg
,
1631 msg
->msg
[0] |= 0xf; /* broadcast */
1632 msg
->msg
[1] = CEC_MSG_REQUEST_CURRENT_LATENCY
;
1633 msg
->msg
[2] = phys_addr
>> 8;
1634 msg
->msg
[3] = phys_addr
& 0xff;
1635 msg
->reply
= reply
? CEC_MSG_REPORT_CURRENT_LATENCY
: 0;
1638 static inline void cec_ops_request_current_latency(const struct cec_msg
*msg
,
1641 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1645 /* Capability Discovery and Control Feature */
1646 static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg
*msg
,
1651 msg
->msg
[0] |= 0xf; /* broadcast */
1652 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1653 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1654 msg
->msg
[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE
;
1655 msg
->msg
[5] = phys_addr1
>> 8;
1656 msg
->msg
[6] = phys_addr1
& 0xff;
1657 msg
->msg
[7] = phys_addr2
>> 8;
1658 msg
->msg
[8] = phys_addr2
& 0xff;
1661 static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg
*msg
,
1666 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1667 *phys_addr1
= (msg
->msg
[5] << 8) | msg
->msg
[6];
1668 *phys_addr2
= (msg
->msg
[7] << 8) | msg
->msg
[8];
1671 static inline void cec_msg_cdc_hec_report_state(struct cec_msg
*msg
,
1672 __u16 target_phys_addr
,
1673 __u8 hec_func_state
,
1674 __u8 host_func_state
,
1675 __u8 enc_func_state
,
1680 msg
->len
= has_field
? 10 : 8;
1681 msg
->msg
[0] |= 0xf; /* broadcast */
1682 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1683 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1684 msg
->msg
[4] = CEC_MSG_CDC_HEC_REPORT_STATE
;
1685 msg
->msg
[5] = target_phys_addr
>> 8;
1686 msg
->msg
[6] = target_phys_addr
& 0xff;
1687 msg
->msg
[7] = (hec_func_state
<< 6) |
1688 (host_func_state
<< 4) |
1689 (enc_func_state
<< 2) |
1692 msg
->msg
[8] = hec_field
>> 8;
1693 msg
->msg
[9] = hec_field
& 0xff;
1697 static inline void cec_ops_cdc_hec_report_state(const struct cec_msg
*msg
,
1699 __u16
*target_phys_addr
,
1700 __u8
*hec_func_state
,
1701 __u8
*host_func_state
,
1702 __u8
*enc_func_state
,
1707 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1708 *target_phys_addr
= (msg
->msg
[5] << 8) | msg
->msg
[6];
1709 *hec_func_state
= msg
->msg
[7] >> 6;
1710 *host_func_state
= (msg
->msg
[7] >> 4) & 3;
1711 *enc_func_state
= (msg
->msg
[7] >> 4) & 3;
1712 *cdc_errcode
= msg
->msg
[7] & 3;
1713 *has_field
= msg
->len
>= 10;
1714 *hec_field
= *has_field
? ((msg
->msg
[8] << 8) | msg
->msg
[9]) : 0;
1717 static inline void cec_msg_cdc_hec_set_state(struct cec_msg
*msg
,
1726 msg
->msg
[0] |= 0xf; /* broadcast */
1727 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1728 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1729 msg
->msg
[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE
;
1730 msg
->msg
[5] = phys_addr1
>> 8;
1731 msg
->msg
[6] = phys_addr1
& 0xff;
1732 msg
->msg
[7] = phys_addr2
>> 8;
1733 msg
->msg
[8] = phys_addr2
& 0xff;
1734 msg
->msg
[9] = hec_set_state
;
1735 if (phys_addr3
!= CEC_PHYS_ADDR_INVALID
) {
1736 msg
->msg
[msg
->len
++] = phys_addr3
>> 8;
1737 msg
->msg
[msg
->len
++] = phys_addr3
& 0xff;
1738 if (phys_addr4
!= CEC_PHYS_ADDR_INVALID
) {
1739 msg
->msg
[msg
->len
++] = phys_addr4
>> 8;
1740 msg
->msg
[msg
->len
++] = phys_addr4
& 0xff;
1741 if (phys_addr5
!= CEC_PHYS_ADDR_INVALID
) {
1742 msg
->msg
[msg
->len
++] = phys_addr5
>> 8;
1743 msg
->msg
[msg
->len
++] = phys_addr5
& 0xff;
1749 static inline void cec_ops_cdc_hec_set_state(const struct cec_msg
*msg
,
1753 __u8
*hec_set_state
,
1758 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1759 *phys_addr1
= (msg
->msg
[5] << 8) | msg
->msg
[6];
1760 *phys_addr2
= (msg
->msg
[7] << 8) | msg
->msg
[8];
1761 *hec_set_state
= msg
->msg
[9];
1762 *phys_addr3
= *phys_addr4
= *phys_addr5
= CEC_PHYS_ADDR_INVALID
;
1764 *phys_addr3
= (msg
->msg
[10] << 8) | msg
->msg
[11];
1766 *phys_addr4
= (msg
->msg
[12] << 8) | msg
->msg
[13];
1768 *phys_addr5
= (msg
->msg
[14] << 8) | msg
->msg
[15];
1771 static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg
*msg
,
1776 msg
->msg
[0] |= 0xf; /* broadcast */
1777 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1778 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1779 msg
->msg
[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT
;
1780 msg
->msg
[5] = phys_addr1
>> 8;
1781 msg
->msg
[6] = phys_addr1
& 0xff;
1782 msg
->msg
[7] = hec_set_state
;
1785 static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg
*msg
,
1788 __u8
*hec_set_state
)
1790 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1791 *phys_addr1
= (msg
->msg
[5] << 8) | msg
->msg
[6];
1792 *hec_set_state
= msg
->msg
[7];
1795 static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg
*msg
,
1801 msg
->msg
[0] |= 0xf; /* broadcast */
1802 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1803 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1804 msg
->msg
[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION
;
1805 msg
->msg
[5] = phys_addr1
>> 8;
1806 msg
->msg
[6] = phys_addr1
& 0xff;
1807 msg
->msg
[7] = phys_addr2
>> 8;
1808 msg
->msg
[8] = phys_addr2
& 0xff;
1809 msg
->msg
[9] = phys_addr3
>> 8;
1810 msg
->msg
[10] = phys_addr3
& 0xff;
1813 static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg
*msg
,
1819 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1820 *phys_addr1
= (msg
->msg
[5] << 8) | msg
->msg
[6];
1821 *phys_addr2
= (msg
->msg
[7] << 8) | msg
->msg
[8];
1822 *phys_addr3
= (msg
->msg
[9] << 8) | msg
->msg
[10];
1825 static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg
*msg
)
1828 msg
->msg
[0] |= 0xf; /* broadcast */
1829 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1830 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1831 msg
->msg
[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE
;
1834 static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg
*msg
,
1837 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1840 static inline void cec_msg_cdc_hec_discover(struct cec_msg
*msg
)
1843 msg
->msg
[0] |= 0xf; /* broadcast */
1844 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1845 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1846 msg
->msg
[4] = CEC_MSG_CDC_HEC_DISCOVER
;
1849 static inline void cec_ops_cdc_hec_discover(const struct cec_msg
*msg
,
1852 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1855 static inline void cec_msg_cdc_hpd_set_state(struct cec_msg
*msg
,
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_HPD_SET_STATE
;
1864 msg
->msg
[5] = (input_port
<< 4) | hpd_state
;
1867 static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg
*msg
,
1872 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1873 *input_port
= msg
->msg
[5] >> 4;
1874 *hpd_state
= msg
->msg
[5] & 0xf;
1877 static inline void cec_msg_cdc_hpd_report_state(struct cec_msg
*msg
,
1882 msg
->msg
[0] |= 0xf; /* broadcast */
1883 msg
->msg
[1] = CEC_MSG_CDC_MESSAGE
;
1884 /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
1885 msg
->msg
[4] = CEC_MSG_CDC_HPD_REPORT_STATE
;
1886 msg
->msg
[5] = (hpd_state
<< 4) | hpd_error
;
1889 static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg
*msg
,
1894 *phys_addr
= (msg
->msg
[2] << 8) | msg
->msg
[3];
1895 *hpd_state
= msg
->msg
[5] >> 4;
1896 *hpd_error
= msg
->msg
[5] & 0xf;