1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
/*
SiI8348 Linux Driver
Copyright (C) 2013 Silicon Image, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation version 2.
This program is distributed AS-IS WITHOUT ANY WARRANTY of any
kind, whether express or implied; INCLUDING without the implied warranty
of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE or NON-INFRINGEMENT. See
the GNU General Public License for more details at http://www.gnu.org/licenses/gpl-2.0.html.
*/
#if !defined(MHL_LINUX_TX_H)
#define MHL_LINUX_TX_H
#include "sii_hal.h"
/*
* Event codes
*
*/
/* No event worth reporting */
#define MHL_TX_EVENT_NONE 0x00
/* MHL connection has been lost */
#define MHL_TX_EVENT_DISCONNECTION 0x01
/* MHL connection has been established */
#define MHL_TX_EVENT_CONNECTION 0x02
/* Received an RCP key code */
#define MHL_TX_EVENT_RCP_RECEIVED 0x04
/* Received an RCPK message */
#define MHL_TX_EVENT_RCPK_RECEIVED 0x05
/* Received an RCPE message */
#define MHL_TX_EVENT_RCPE_RECEIVED 0x06
/* Received an UTF-8 key code */
#define MHL_TX_EVENT_UCP_RECEIVED 0x07
/* Received an UCPK message */
#define MHL_TX_EVENT_UCPK_RECEIVED 0x08
/* Received an UCPE message */
#define MHL_TX_EVENT_UCPE_RECEIVED 0x09
/* Scratch Pad Data received */
#define MHL_TX_EVENT_SPAD_RECEIVED 0x0A
/* Peer's power capability has changed */
#define MHL_TX_EVENT_POW_BIT_CHG 0x0B
/* Received a Request Action Protocol (RAP) message */
#define MHL_TX_EVENT_RAP_RECEIVED 0x0C
//we li
#define MHL_TX_EVENT_SMB_DATA 0x40
#define MHL_TX_EVENT_HPD_CLEAR 0x41
#define MHL_TX_EVENT_HPD_GOT 0x42
#define MHL_TX_EVENT_DEV_CAP_UPDATE 0x43
#define MHL_TX_EVENT_EDID_UPDATE 0x44
#define MHL_TX_EVENT_EDID_DONE 0x45
#define ADOPTER_ID_SIZE 2
#define MAX_SCRATCH_PAD_TRANSFER_SIZE 16
#define SCRATCH_PAD_SIZE 64
#define SCRATCHPAD_SIZE 16
typedef union {
MHL2_video_format_data_t videoFormatData;
uint8_t asBytes[SCRATCHPAD_SIZE];
} scratch_pad_u;
struct timer_obj {
struct list_head list_link;
struct work_struct work_item;
struct hrtimer hr_timer;
struct mhl_dev_context *dev_context;
uint8_t flags;
#define TIMER_OBJ_FLAG_WORK_IP 0x01
#define TIMER_OBJ_FLAG_DEL_REQ 0x02
void *callback_param;
void (*timer_callback_handler)(void *callback_param);
};
/* Convert a value specified in milliseconds to nanoseconds */
#define MSEC_TO_NSEC(x) (x * 1000000UL)
union misc_flags_u {
struct {
unsigned scratchpad_busy :1;
unsigned req_wrt_pending :1;
unsigned write_burst_pending :1;
unsigned rcp_ready :1;
unsigned have_complete_devcap :1;
unsigned sent_dcap_rdy :1;
unsigned sent_path_en :1;
unsigned rap_content_on :1;
unsigned mhl_hpd :1;
unsigned mhl_rsen :1;
unsigned edid_loop_active :1;
unsigned cbus_abort_delay_active :1;
unsigned reserved :20;
} flags;
uint32_t as_uint32;
};
/*
* structure used by interrupt handler to return
* information about an interrupt.
*/
struct interrupt_info {
uint16_t flags;
/* Flags returned by low level driver interrupt handler */
#define DRV_INTR_FLAG_MSC_DONE 0x0001 /* message send done */
#define DRV_INTR_FLAG_MSC_RECVD 0x0002 /* MSC message received */
#define DRV_INTR_FLAG_MSC_NAK 0x0004 /* message send unsuccessful */
#define DRV_INTR_FLAG_WRITE_STAT 0x0008 /* write stat msg received */
#define DRV_INTR_FLAG_SET_INT 0x0010 /* set int message received */
#define DRV_INTR_FLAG_WRITE_BURST 0x0020 /* write burst received */
#define DRV_INTR_FLAG_HPD_CHANGE 0x0040 /* Hot plug detect has changed */
#define DRV_INTR_FLAG_CONNECT 0x0080 /* MHL connection established */
#define DRV_INTR_FLAG_DISCONNECT 0x0100 /* MHL connection lost */
#define DRV_INTR_FLAG_CBUS_ABORT 0x0200 /* A CBUS message transfer was
aborted */
void *edid_parser_context;
uint8_t msc_done_data;
uint8_t hpd_status; /* status of hot plug detect */
uint8_t write_stat[2]; /* received write stat data */
uint8_t msc_msg[2]; /* received msc message data */
uint8_t int_msg[2]; /* received SET INT message data */
};
#define NUM_CBUS_EVENT_QUEUE_EVENTS 50
#define MHL_DEV_CONTEXT_SIGNATURE ( ('M' << 24) | ('H' << 16) | ('L' << 8) | ' ')
struct mhl_dev_context {
uint32_t signature; /* identifies an instance of
this struct */
struct mhl_drv_info const *drv_info;
struct i2c_client *client;
struct cdev mhl_cdev;
struct device *mhl_dev;
struct interrupt_info intr_info;
void *edid_parser_context;
bool edid_parse_done; // TODO: FD, TBU, just parse done, not parse successfully
u8 dev_flags;
#define DEV_FLAG_SHUTDOWN 0x01 /* Device is shutting down */
#define DEV_FLAG_COMM_MODE 0x02 /* user wants to peek/poke at registers */
u16 mhl_flags; /* various state flags */
#define MHL_STATE_FLAG_CONNECTED 0x0001 /* MHL connection
established */
#ifndef RCP_INPUTDEV_SUPPORT
#define MHL_STATE_FLAG_RCP_SENT 0x0002 /* last RCP event was a key
send */
#define MHL_STATE_FLAG_RCP_RECEIVED 0x0004 /* last RCP event was a key
code receive */
#define MHL_STATE_FLAG_RCP_ACK 0x0008 /* last RCP key code sent was
ACK'd */
#define MHL_STATE_FLAG_RCP_NAK 0x0010 /* last RCP key code sent was
NAK'd */
#endif
#define MHL_STATE_FLAG_UCP_SENT 0x0020 /* last UCP event was a key
send */
#define MHL_STATE_FLAG_UCP_RECEIVED 0x0040 /* last UCP event was a key
code receive */
#define MHL_STATE_FLAG_UCP_ACK 0x0080 /* last UCP key code sent was
ACK'd */
#define MHL_STATE_FLAG_UCP_NAK 0x0100 /* last UCP key code sent was
NAK'd */
#define MHL_STATE_FLAG_SPAD_SENT 0x0200 /* scratch pad send in
process */
#define MHL_STATE_APPLICATION_RAP_BUSY 0x0400 /* application has indicated
that it is processing an
outstanding request */
u8 dev_cap_offset;
u8 rap_sub_command;
u8 rcp_key_code;
u8 rcp_err_code;
u8 rcp_send_status;
u8 ucp_key_code;
u8 ucp_err_code;
u8 ucp_send_status;
u8 pending_event; /* event data wait for retrieval */
u8 pending_event_data; /* by user mode application */
u8 spad_offset;
u8 spad_xfer_length;
u8 spad_send_status;
u8 debug_i2c_address;
u8 debug_i2c_offset;
u8 debug_i2c_xfer_length;
#ifdef MEDIA_DATA_TUNNEL_SUPPORT
struct mdt_inputdevs mdt_devs;
#endif
#ifdef RCP_INPUTDEV_SUPPORT
u8 error_key;
struct input_dev *rcp_input_dev;
#endif
struct semaphore isr_lock; /* semaphore used to prevent driver access
from user mode from colliding with the
threaded interrupt handler */
u8 status_0; /* Received status from peer saved here */
u8 status_1;
bool msc_msg_arrived;
u8 msc_msg_sub_command;
u8 msc_msg_data;
u8 msc_msg_last_data;
u8 msc_save_rcp_key_code;
u8 msc_save_ucp_key_code;
u8 link_mode; /* local MHL LINK_MODE register value */
bool mhl_connection_event;
u8 mhl_connected;
struct workqueue_struct *timer_work_queue;
struct list_head timer_list;
struct list_head cbus_queue;
struct list_head cbus_free_list;
struct cbus_req cbus_req_entries[NUM_CBUS_EVENT_QUEUE_EVENTS];
struct cbus_req *current_cbus_req;
void *cbus_abort_timer;
void *cbus_dpi_timer;
MHLDevCap_u dev_cap_cache;
MHLDevCap_u dev_cap_cache_new;
u8 dev_cap_cache_index;
u8 preferred_clk_mode;
bool scratch_pad_read_done;
scratch_pad_u incoming_scratch_pad;
scratch_pad_u outgoing_scratch_pad;
union misc_flags_u misc_flags;
uint8_t numEdidExtensions;
void *drv_context; /* pointer aligned start of mhl transmitter driver context area */
};
#define PACKED_PIXEL_AVAILABLE(dev_context) \
((MHL_DEV_VID_LINK_SUPP_PPIXEL & \
dev_context->dev_cap_cache.devcap_cache[DEVCAP_OFFSET_VID_LINK_MODE]) && \
(MHL_DEV_VID_LINK_SUPP_PPIXEL & DEVCAP_VAL_VID_LINK_MODE))
enum scratch_pad_status {
SCRATCHPAD_FAIL= -4
,SCRATCHPAD_BAD_PARAM = -3
,SCRATCHPAD_NOT_SUPPORTED = -2
,SCRATCHPAD_BUSY = -1
,SCRATCHPAD_SUCCESS = 0
};
struct drv_hw_context;
struct mhl_drv_info {
int drv_context_size;
struct {
uint8_t major : 4;
uint8_t minor : 4;
} mhl_version_support;
/* APIs required to be supported by the low level MHL transmitter driver */
int (* mhl_device_initialize) (struct drv_hw_context *hw_context);
void (*mhl_device_isr) (struct drv_hw_context *hw_context, struct interrupt_info *intr_info);
int (* mhl_device_dbg_i2c_reg_xfer) (void *dev_context, u8 page, u8 offset, u8 count, bool rw_flag, u8 *buffer);
void (*mhl_start_video) (struct drv_hw_context *hw_context);
};
/* APIs provided by the Linux layer to the lower level driver */
int mhl_tx_init(struct mhl_drv_info const *drv_info, struct i2c_client *client);
int mhl_tx_remove(struct i2c_client *client);
void mhl_event_notify(struct mhl_dev_context *dev_context, u32 event, u32 event_param, void *data);
struct mhl_dev_context *get_mhl_device_context(void *context);
uint8_t calculate_generic_checksum(uint8_t *info_frame_data, uint8_t checksum, uint8_t length);
void *si_mhl_tx_get_drv_context(void *dev_context);
int mhl_tx_create_timer(void *context,
void (*callback_handler)(void *callback_param),
void *callback_param,
void **timer_handle);
int mhl_tx_delete_timer(void *context, void *timer_handle);
int mhl_tx_start_timer(void *context, void *timer_handle, uint32_t time_msec);
int mhl_tx_stop_timer(void *context, void *timer_handle);
void si_mhl_tx_request_first_edid_block(struct mhl_dev_context *dev_context);
void si_mhl_tx_handle_atomic_hw_edid_read_complete(edid_3d_data_p mhl_edid_3d_data,struct cbus_req *req);
/* APIs used within the Linux layer of the driver. */
uint8_t si_mhl_tx_get_peer_dev_cap_entry(struct mhl_dev_context *dev_context, uint8_t index, uint8_t *data);
enum scratch_pad_status si_get_scratch_pad_vector(
struct mhl_dev_context *dev_context,
uint8_t offset,uint8_t length,
uint8_t *data);
#endif /* if !defined(MHL_LINUX_TX_H) */
|