Home | History | Annotate | Download | only in hardware
      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