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