1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H 18 #define ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H 19 20 #include <stdint.h> 21 #include <sys/cdefs.h> 22 23 #include <hardware/hardware.h> 24 25 __BEGIN_DECLS 26 27 #define HDMI_CEC_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) 28 #define HDMI_CEC_MODULE_API_VERSION_CURRENT HDMI_MODULE_API_VERSION_1_0 29 30 #define HDMI_CEC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) 31 #define HDMI_CEC_DEVICE_API_VERSION_CURRENT HDMI_DEVICE_API_VERSION_1_0 32 33 #define HDMI_CEC_HARDWARE_MODULE_ID "hdmi_cec" 34 #define HDMI_CEC_HARDWARE_INTERFACE "hdmi_cec_hw_if" 35 36 typedef enum cec_device_type { 37 CEC_DEVICE_INACTIVE = -1, 38 CEC_DEVICE_TV = 0, 39 CEC_DEVICE_RECORDER = 1, 40 CEC_DEVICE_RESERVED = 2, 41 CEC_DEVICE_TUNER = 3, 42 CEC_DEVICE_PLAYBACK = 4, 43 CEC_DEVICE_AUDIO_SYSTEM = 5, 44 CEC_DEVICE_MAX = CEC_DEVICE_AUDIO_SYSTEM 45 } cec_device_type_t; 46 47 typedef enum cec_logical_address { 48 CEC_ADDR_TV = 0, 49 CEC_ADDR_RECORDER_1 = 1, 50 CEC_ADDR_RECORDER_2 = 2, 51 CEC_ADDR_TUNER_1 = 3, 52 CEC_ADDR_PLAYBACK_1 = 4, 53 CEC_ADDR_AUDIO_SYSTEM = 5, 54 CEC_ADDR_TUNER_2 = 6, 55 CEC_ADDR_TUNER_3 = 7, 56 CEC_ADDR_PLAYBACK_2 = 8, 57 CEC_ADDR_RECORDER_3 = 9, 58 CEC_ADDR_TUNER_4 = 10, 59 CEC_ADDR_PLAYBACK_3 = 11, 60 CEC_ADDR_RESERVED_1 = 12, 61 CEC_ADDR_RESERVED_2 = 13, 62 CEC_ADDR_FREE_USE = 14, 63 CEC_ADDR_UNREGISTERED = 15, 64 CEC_ADDR_BROADCAST = 15 65 } cec_logical_address_t; 66 67 /* 68 * HDMI CEC messages 69 */ 70 enum cec_message_type { 71 CEC_MESSAGE_FEATURE_ABORT = 0x00, 72 CEC_MESSAGE_IMAGE_VIEW_ON = 0x04, 73 CEC_MESSAGE_TUNER_STEP_INCREMENT = 0x05, 74 CEC_MESSAGE_TUNER_STEP_DECREMENT = 0x06, 75 CEC_MESSAGE_TUNER_DEVICE_STATUS = 0x07, 76 CEC_MESSAGE_GIVE_TUNER_DEVICE_STATUS = 0x08, 77 CEC_MESSAGE_RECORD_ON = 0x09, 78 CEC_MESSAGE_RECORD_STATUS = 0x0A, 79 CEC_MESSAGE_RECORD_OFF = 0x0B, 80 CEC_MESSAGE_TEXT_VIEW_ON = 0x0D, 81 CEC_MESSAGE_RECORD_TV_SCREEN = 0x0F, 82 CEC_MESSAGE_GIVE_DECK_STATUS = 0x1A, 83 CEC_MESSAGE_DECK_STATUS = 0x1B, 84 CEC_MESSAGE_SET_MENU_LANGUAGE = 0x32, 85 CEC_MESSAGE_CLEAR_ANALOG_TIMER = 0x33, 86 CEC_MESSAGE_SET_ANALOG_TIMER = 0x34, 87 CEC_MESSAGE_TIMER_STATUS = 0x35, 88 CEC_MESSAGE_STANDBY = 0x36, 89 CEC_MESSAGE_PLAY = 0x41, 90 CEC_MESSAGE_DECK_CONTROL = 0x42, 91 CEC_MESSAGE_TIMER_CLEARED_STATUS = 0x043, 92 CEC_MESSAGE_USER_CONTROL_PRESSED = 0x44, 93 CEC_MESSAGE_USER_CONTROL_RELEASED = 0x45, 94 CEC_MESSAGE_GIVE_OSD_NAME = 0x46, 95 CEC_MESSAGE_SET_OSD_NAME = 0x47, 96 CEC_MESSAGE_SET_OSD_STRING = 0x64, 97 CEC_MESSAGE_SET_TIMER_PROGRAM_TITLE = 0x67, 98 CEC_MESSAGE_SYSTEM_AUDIO_MODE_REQUEST = 0x70, 99 CEC_MESSAGE_GIVE_AUDIO_STATUS = 0x71, 100 CEC_MESSAGE_SET_SYSTEM_AUDIO_MODE = 0x72, 101 CEC_MESSAGE_REPORT_AUDIO_STATUS = 0x7A, 102 CEC_MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D, 103 CEC_MESSAGE_SYSTEM_AUDIO_MODE_STATUS = 0x7E, 104 CEC_MESSAGE_ROUTING_CHANGE = 0x80, 105 CEC_MESSAGE_ROUTING_INFORMATION = 0x81, 106 CEC_MESSAGE_ACTIVE_SOURCE = 0x82, 107 CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS = 0x83, 108 CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS = 0x84, 109 CEC_MESSAGE_REQUEST_ACTIVE_SOURCE = 0x85, 110 CEC_MESSAGE_SET_STREAM_PATH = 0x86, 111 CEC_MESSAGE_DEVICE_VENDOR_ID = 0x87, 112 CEC_MESSAGE_VENDOR_COMMAND = 0x89, 113 CEC_MESSAGE_VENDOR_REMOTE_BUTTON_DOWN = 0x8A, 114 CEC_MESSAGE_VENDOR_REMOTE_BUTTON_UP = 0x8B, 115 CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID = 0x8C, 116 CEC_MESSAGE_MENU_REQUEST = 0x8D, 117 CEC_MESSAGE_MENU_STATUS = 0x8E, 118 CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS = 0x8F, 119 CEC_MESSAGE_REPORT_POWER_STATUS = 0x90, 120 CEC_MESSAGE_GET_MENU_LANGUAGE = 0x91, 121 CEC_MESSAGE_SELECT_ANALOG_SERVICE = 0x92, 122 CEC_MESSAGE_SELECT_DIGITAL_SERVICE = 0x93, 123 CEC_MESSAGE_SET_DIGITAL_TIMER = 0x97, 124 CEC_MESSAGE_CLEAR_DIGITAL_TIMER = 0x99, 125 CEC_MESSAGE_SET_AUDIO_RATE = 0x9A, 126 CEC_MESSAGE_INACTIVE_SOURCE = 0x9D, 127 CEC_MESSAGE_CEC_VERSION = 0x9E, 128 CEC_MESSAGE_GET_CEC_VERSION = 0x9F, 129 CEC_MESSAGE_VENDOR_COMMAND_WITH_ID = 0xA0, 130 CEC_MESSAGE_CLEAR_EXTERNAL_TIMER = 0xA1, 131 CEC_MESSAGE_SET_EXTERNAL_TIMER = 0xA2, 132 CEC_MESSAGE_INITIATE_ARC = 0xC0, 133 CEC_MESSAGE_REPORT_ARC_INITIATED = 0xC1, 134 CEC_MESSAGE_REPORT_ARC_TERMINATED = 0xC2, 135 CEC_MESSAGE_REQUEST_ARC_INITIATION = 0xC3, 136 CEC_MESSAGE_REQUEST_ARC_TERMINATION = 0xC4, 137 CEC_MESSAGE_TERMINATE_ARC = 0xC5, 138 CEC_MESSAGE_ABORT = 0xFF 139 }; 140 141 /* 142 * Operand description [Abort Reason] 143 */ 144 enum abort_reason { 145 ABORT_UNRECOGNIZED_MODE = 0, 146 ABORT_NOT_IN_CORRECT_MODE = 1, 147 ABORT_CANNOT_PROVIDE_SOURCE = 2, 148 ABORT_INVALID_OPERAND = 3, 149 ABORT_REFUSED = 4, 150 ABORT_UNABLE_TO_DETERMINE = 5 151 }; 152 153 /* 154 * HDMI event type. used for hdmi_event_t. 155 */ 156 enum { 157 HDMI_EVENT_CEC_MESSAGE = 1, 158 HDMI_EVENT_HOT_PLUG = 2, 159 }; 160 161 /* 162 * HDMI hotplug event type. Used when the event 163 * type is HDMI_EVENT_HOT_PLUG. 164 */ 165 enum { 166 HDMI_NOT_CONNECTED = 0, 167 HDMI_CONNECTED = 1 168 }; 169 170 /* 171 * error code used for send_message. 172 */ 173 enum { 174 HDMI_RESULT_SUCCESS = 0, 175 HDMI_RESULT_NACK = 1, /* not acknowledged */ 176 HDMI_RESULT_BUSY = 2, /* bus is busy */ 177 HDMI_RESULT_FAIL = 3, 178 }; 179 180 /* 181 * HDMI port type. 182 */ 183 typedef enum hdmi_port_type { 184 HDMI_INPUT = 0, 185 HDMI_OUTPUT = 1 186 } hdmi_port_type_t; 187 188 /* 189 * Flags used for set_option() 190 */ 191 enum { 192 /* When set to false, HAL does not wake up the system upon receiving 193 * <Image View On> or <Text View On>. Used when user changes the TV 194 * settings to disable the auto TV on functionality. 195 * True by default. 196 */ 197 HDMI_OPTION_WAKEUP = 1, 198 199 /* When set to false, all the CEC commands are discarded. Used when 200 * user changes the TV settings to disable CEC functionality. 201 * True by default. 202 */ 203 HDMI_OPTION_ENABLE_CEC = 2, 204 205 /* Setting this flag to false means Android system will stop handling 206 * CEC service and yield the control over to the microprocessor that is 207 * powered on through the standby mode. When set to true, the system 208 * will gain the control over, hence telling the microprocessor to stop 209 * handling the cec commands. This is called when system goes 210 * in and out of standby mode to notify the microprocessor that it should 211 * start/stop handling CEC commands on behalf of the system. 212 * False by default. 213 */ 214 HDMI_OPTION_SYSTEM_CEC_CONTROL = 3, 215 216 /* Option 4 not used */ 217 218 /* Passes the updated language information of Android system. 219 * Contains 3-byte ASCII code as defined in ISO/FDIS 639-2. Can be 220 * used for HAL to respond to <Get Menu Language> while in standby mode. 221 * English(eng), for example, is converted to 0x656e67. 222 */ 223 HDMI_OPTION_SET_LANG = 5, 224 }; 225 226 /* 227 * Maximum length in bytes of cec message body (exclude header block), 228 * should not exceed 16 (spec CEC 6 Frame Description) 229 */ 230 #define CEC_MESSAGE_BODY_MAX_LENGTH 16 231 232 typedef struct cec_message { 233 /* logical address of sender */ 234 cec_logical_address_t initiator; 235 236 /* logical address of receiver */ 237 cec_logical_address_t destination; 238 239 /* Length in bytes of body, range [0, CEC_MESSAGE_BODY_MAX_LENGTH] */ 240 size_t length; 241 unsigned char body[CEC_MESSAGE_BODY_MAX_LENGTH]; 242 } cec_message_t; 243 244 typedef struct hotplug_event { 245 /* 246 * true if the cable is connected; otherwise false. 247 */ 248 int connected; 249 int port_id; 250 } hotplug_event_t; 251 252 typedef struct tx_status_event { 253 int status; 254 int opcode; /* CEC opcode */ 255 } tx_status_event_t; 256 257 /* 258 * HDMI event generated from HAL. 259 */ 260 typedef struct hdmi_event { 261 int type; 262 struct hdmi_cec_device* dev; 263 union { 264 cec_message_t cec; 265 hotplug_event_t hotplug; 266 }; 267 } hdmi_event_t; 268 269 /* 270 * HDMI port descriptor 271 */ 272 typedef struct hdmi_port_info { 273 hdmi_port_type_t type; 274 // Port ID should start from 1 which corresponds to HDMI "port 1". 275 int port_id; 276 int cec_supported; 277 int arc_supported; 278 uint16_t physical_address; 279 } hdmi_port_info_t; 280 281 /* 282 * Callback function type that will be called by HAL implementation. 283 * Services can not close/open the device in the callback. 284 */ 285 typedef void (*event_callback_t)(const hdmi_event_t* event, void* arg); 286 287 typedef struct hdmi_cec_module { 288 /** 289 * Common methods of the HDMI CEC module. This *must* be the first member of 290 * hdmi_cec_module as users of this structure will cast a hw_module_t to hdmi_cec_module 291 * pointer in contexts where it's known the hw_module_t references a hdmi_cec_module. 292 */ 293 struct hw_module_t common; 294 } hdmi_module_t; 295 296 /* 297 * HDMI-CEC HAL interface definition. 298 */ 299 typedef struct hdmi_cec_device { 300 /** 301 * Common methods of the HDMI CEC device. This *must* be the first member of 302 * hdmi_cec_device as users of this structure will cast a hw_device_t to hdmi_cec_device 303 * pointer in contexts where it's known the hw_device_t references a hdmi_cec_device. 304 */ 305 struct hw_device_t common; 306 307 /* 308 * (*add_logical_address)() passes the logical address that will be used 309 * in this system. 310 * 311 * HAL may use it to configure the hardware so that the CEC commands addressed 312 * the given logical address can be filtered in. This method can be called 313 * as many times as necessary in order to support multiple logical devices. 314 * addr should be in the range of valid logical addresses for the call 315 * to succeed. 316 * 317 * Returns 0 on success or -errno on error. 318 */ 319 int (*add_logical_address)(const struct hdmi_cec_device* dev, cec_logical_address_t addr); 320 321 /* 322 * (*clear_logical_address)() tells HAL to reset all the logical addresses. 323 * 324 * It is used when the system doesn't need to process CEC command any more, 325 * hence to tell HAL to stop receiving commands from the CEC bus, and change 326 * the state back to the beginning. 327 */ 328 void (*clear_logical_address)(const struct hdmi_cec_device* dev); 329 330 /* 331 * (*get_physical_address)() returns the CEC physical address. The 332 * address is written to addr. 333 * 334 * The physical address depends on the topology of the network formed 335 * by connected HDMI devices. It is therefore likely to change if the cable 336 * is plugged off and on again. It is advised to call get_physical_address 337 * to get the updated address when hot plug event takes place. 338 * 339 * Returns 0 on success or -errno on error. 340 */ 341 int (*get_physical_address)(const struct hdmi_cec_device* dev, uint16_t* addr); 342 343 /* 344 * (*send_message)() transmits HDMI-CEC message to other HDMI device. 345 * 346 * The method should be designed to return in a certain amount of time not 347 * hanging forever, which can happen if CEC signal line is pulled low for 348 * some reason. HAL implementation should take the situation into account 349 * so as not to wait forever for the message to get sent out. 350 * 351 * It should try retransmission at least once as specified in the standard. 352 * 353 * Returns error code. See HDMI_RESULT_SUCCESS, HDMI_RESULT_NACK, and 354 * HDMI_RESULT_BUSY. 355 */ 356 int (*send_message)(const struct hdmi_cec_device* dev, const cec_message_t*); 357 358 /* 359 * (*register_event_callback)() registers a callback that HDMI-CEC HAL 360 * can later use for incoming CEC messages or internal HDMI events. 361 * When calling from C++, use the argument arg to pass the calling object. 362 * It will be passed back when the callback is invoked so that the context 363 * can be retrieved. 364 */ 365 void (*register_event_callback)(const struct hdmi_cec_device* dev, 366 event_callback_t callback, void* arg); 367 368 /* 369 * (*get_version)() returns the CEC version supported by underlying hardware. 370 */ 371 void (*get_version)(const struct hdmi_cec_device* dev, int* version); 372 373 /* 374 * (*get_vendor_id)() returns the identifier of the vendor. It is 375 * the 24-bit unique company ID obtained from the IEEE Registration 376 * Authority Committee (RAC). 377 */ 378 void (*get_vendor_id)(const struct hdmi_cec_device* dev, uint32_t* vendor_id); 379 380 /* 381 * (*get_port_info)() returns the hdmi port information of underlying hardware. 382 * info is the list of HDMI port information, and 'total' is the number of 383 * HDMI ports in the system. 384 */ 385 void (*get_port_info)(const struct hdmi_cec_device* dev, 386 struct hdmi_port_info* list[], int* total); 387 388 /* 389 * (*set_option)() passes flags controlling the way HDMI-CEC service works down 390 * to HAL implementation. Those flags will be used in case the feature needs 391 * update in HAL itself, firmware or microcontroller. 392 */ 393 void (*set_option)(const struct hdmi_cec_device* dev, int flag, int value); 394 395 /* 396 * (*set_audio_return_channel)() configures ARC circuit in the hardware logic 397 * to start or stop the feature. Flag can be either 1 to start the feature 398 * or 0 to stop it. 399 * 400 * Returns 0 on success or -errno on error. 401 */ 402 void (*set_audio_return_channel)(const struct hdmi_cec_device* dev, int port_id, int flag); 403 404 /* 405 * (*is_connected)() returns the connection status of the specified port. 406 * Returns HDMI_CONNECTED if a device is connected, otherwise HDMI_NOT_CONNECTED. 407 * The HAL should watch for +5V power signal to determine the status. 408 */ 409 int (*is_connected)(const struct hdmi_cec_device* dev, int port_id); 410 411 /* Reserved for future use to maximum 16 functions. Must be NULL. */ 412 void* reserved[16 - 11]; 413 } hdmi_cec_device_t; 414 415 /** convenience API for opening and closing a device */ 416 417 static inline int hdmi_cec_open(const struct hw_module_t* module, 418 struct hdmi_cec_device** device) { 419 return module->methods->open(module, 420 HDMI_CEC_HARDWARE_INTERFACE, (struct hw_device_t**)device); 421 } 422 423 static inline int hdmi_cec_close(struct hdmi_cec_device* device) { 424 return device->common.close(&device->common); 425 } 426 427 __END_DECLS 428 429 #endif /* ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H */ 430