blob: de6c70c990bdf2c2d1688e0481e68ba778354076 [file] [log] [blame]
Jinsuk Kim62195dc2014-02-19 10:21:35 +09001/*
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
36typedef enum cec_device_type {
Jinsuk Kimefbdb252014-03-24 13:26:40 +090037 CEC_DEVICE_INACTIVE = -1,
Jinsuk Kim62195dc2014-02-19 10:21:35 +090038 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
47typedef 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 */
70enum 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_GET_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,
Jinsuk Kimefbdb252014-03-24 13:26:40 +0900131 CEC_MESSAGE_SET_EXTERNAL_TIMER = 0xA2,
132 CEC_MESSAGE_ABORT = 0xFF
133};
134
135/*
136 * Operand description [Abort Reason]
137 */
138enum abort_reason {
139 ABORT_UNRECOGNIZED_MODE = 0,
140 ABORT_NOT_IN_CORRECT_MODE = 1,
141 ABORT_CANNOT_PROVIDE_SOURCE = 2,
142 ABORT_INVALID_OPERAND = 3,
143 ABORT_REFUSED = 4,
144 ABORT_UNABLE_TO_DETERMINE = 5
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900145};
146
147/*
148 * HDMI event type. used for hdmi_event_t.
149 */
150enum {
151 HDMI_EVENT_CEC_MESSAGE = 1,
152 HDMI_EVENT_HOT_PLUG = 2
153};
154
155/*
156 * HDMI hotplug event type. Used when the event
157 * type is HDMI_EVENT_HOT_PLUG.
158 */
159enum {
160 HDMI_NOT_CONNECTED = 0,
161 HDMI_CONNECTED = 1
162};
163
164/*
165 * Maximum length in bytes of cec message body (exclude header block),
166 * should not exceed 16 (spec CEC 6 Frame Description)
167 */
168#define CEC_MESSAGE_BODY_MAX_LENGTH 16
169
170typedef struct cec_message {
171 /*
172 * logical address of sender
173 */
174 cec_logical_address_t initiator;
175
176 /*
177 * logical address of receiver
178 */
179 cec_logical_address_t destination;
180
181 /*
182 * length in bytes of body, range [0, CEC_MESSAGE_BODY_MAX_LENGTH]
183 */
184 size_t length;
185 unsigned char body[CEC_MESSAGE_BODY_MAX_LENGTH];
186} cec_message_t;
187
188typedef struct hotplug_event {
189 /*
190 * true if the cable is connected; otherwise false.
191 */
192 int connected;
193} hotplug_event_t;
194
195/*
196 * HDMI event generated from HAL.
197 */
198typedef struct hdmi_event {
199 int type;
200 struct hdmi_cec_device* dev;
201 union {
202 cec_message_t cec;
203 hotplug_event_t hotplug;
204 };
205} hdmi_event_t;
206
207/*
208 * Callback function type that will be called by HAL implementation.
209 * Services can not close/open the device in the callback.
210 */
Jinsuk Kim70ae7772014-03-06 19:25:19 +0900211typedef void (*event_callback_t)(const hdmi_event_t* event, void* arg);
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900212
213typedef struct hdmi_cec_module {
214 struct hw_module_t common;
215} hdmi_module_t;
216
217/*
218 * HDMI-CEC HAL interface definition.
219 */
220typedef struct hdmi_cec_device {
221 struct hw_device_t common;
222
223 /*
224 * (*allocate_logical_address)() allocates a new logical address
225 * for a given device type. The address is written to addr. The HAL
226 * implementation is also expected to configure itself to start receiving
Jinsuk Kimefbdb252014-03-24 13:26:40 +0900227 * the messages addressed to the allocated one. If the address has been already
228 * allocated, it should simply return the allocated address without attempting
229 * the allocation again. If allocation is not successful the addr will be
230 * set to CEC_ADDR_UNREGISTERED.
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900231 *
232 * Returns 0 on success or -errno on error.
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900233 */
234 int (*allocate_logical_address)(const struct hdmi_cec_device* dev,
Jinsuk Kimefbdb252014-03-24 13:26:40 +0900235 cec_device_type_t device_type, cec_logical_address_t* addr);
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900236
237 /*
Jinsuk Kim98add892014-03-05 18:08:02 +0900238 * (*get_logical_address)() returns the logical address already allocated
239 * for the device of the given type. It is necessary to call this function
240 * when HAL implementation, without being triggered by service, updated
241 * the address by itself. Such situation happens when an event like
242 * hotplug occurs, since it is possible the HDMI network topology or
243 * the port which the device was connected to might have changed while it
244 * was unplugged. In response to such events, the service is required to
245 * call this function to get the updated address. The address is written
246 * to addr.
247 *
248 * Returns 0 on success or -errno on error.
249 */
250 int (*get_logical_address)(const struct hdmi_cec_device* dev,
Jinsuk Kimefbdb252014-03-24 13:26:40 +0900251 cec_device_type_t device_type, cec_logical_address_t* addr);
Jinsuk Kim98add892014-03-05 18:08:02 +0900252 /*
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900253 * (*get_physical_address)() returns the CEC physical address. The
254 * address is written to addr.
255 *
256 * The physical address depends on the topology of the network formed
257 * by connected HDMI devices. It is therefore likely to change if the cable
258 * is plugged off and on again. It is advised to call get_physical_address
259 * to get the updated address when hot plug event takes place.
260 *
261 * Returns 0 on success or -errno on error.
262 */
263 int (*get_physical_address)(const struct hdmi_cec_device* dev, uint16_t* addr);
264
265 /*
266 * (*send_message)() transmits HDMI-CEC message to other HDMI device.
267 *
268 * Returns 0 on success or -errno on error.
269 */
Jinsuk Kimefbdb252014-03-24 13:26:40 +0900270 int (*send_message)(const struct hdmi_cec_device* dev, const cec_message_t*);
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900271
272 /*
273 * (*register_event_callback)() registers a callback that HDMI-CEC HAL
274 * can later use for incoming CEC messages or internal HDMI events.
Jinsuk Kim70ae7772014-03-06 19:25:19 +0900275 * When calling from C++, use the argument arg to pass the calling object.
276 * It will be passed back when the callback is invoked so that the context
277 * can be retrieved.
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900278 */
279 void (*register_event_callback)(const struct hdmi_cec_device* dev,
Jinsuk Kim70ae7772014-03-06 19:25:19 +0900280 event_callback_t callback, void* arg);
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900281
282 /*
283 * (*get_version)() returns the CEC version supported by underlying
284 * hardware. The version this HAL interface is based on is 0x04,
285 * which corresponds to 1.3a.
286 */
287 void (*get_version)(const struct hdmi_cec_device* dev, int* version);
288
289 /*
290 * (*get_vendor_id)() returns the identifier of the vendor. It is
291 * the 24-bit unique company ID obtained from the IEEE Registration
292 * Authority Committee (RAC).
293 */
294 void (*get_vendor_id)(const struct hdmi_cec_device* dev, uint32_t* vendor_id);
295
296 /* Reserved for future use to maximum 16 functions. Must be NULL. */
Jinsuk Kim98add892014-03-05 18:08:02 +0900297 void* reserved[16 - 7];
Jinsuk Kim62195dc2014-02-19 10:21:35 +0900298} hdmi_cec_device_t;
299
300/** convenience API for opening and closing a device */
301
302static inline int hdmi_cec_open(const struct hw_module_t* module,
303 struct hdmi_cec_device** device) {
304 return module->methods->open(module,
305 HDMI_CEC_HARDWARE_INTERFACE, (struct hw_device_t**)device);
306}
307
308static inline int hdmi_cec_close(struct hdmi_cec_device* device) {
309 return device->common.close(&device->common);
310}
311
312__END_DECLS
313
314#endif /* ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H */