Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | #if defined(CONFIG_MTK_HDMI_SUPPORT) |
2 | #include <linux/kernel.h> | |
3 | ||
4 | #include <linux/xlog.h> | |
5 | ||
6 | #include <linux/module.h> | |
7 | #include <linux/init.h> | |
8 | #include <linux/fs.h> | |
9 | #include <linux/cdev.h> | |
10 | #include <linux/device.h> | |
11 | #include <linux/delay.h> | |
12 | #include <linux/kthread.h> | |
13 | #include "mhl_linuxdrv.h" | |
14 | #include "osal/include/osal.h" | |
15 | #include "si_mhl_tx_api.h" | |
16 | #include "si_cra.h" | |
17 | #include "si_drvisrconfig.h" | |
18 | #include "si_drv_mhl_tx.h" | |
19 | #include "si_drv_mdt_tx.h" | |
20 | #include "si_mhl_tx.h" | |
21 | ||
22 | #include <mtk_kpd.h> /* custom file */ | |
23 | ||
24 | #include "hdmi_drv.h" | |
25 | #include "hdmi_cust.h" | |
26 | ||
27 | ||
28 | #if 1 | |
29 | #include <mach/irqs.h> | |
30 | #include "mach/eint.h" | |
31 | #include "mach/irqs.h" | |
32 | #endif | |
33 | ||
34 | ||
35 | static size_t hdmi_log_on = true; | |
36 | #define HDMI_LOG(fmt, arg...) \ | |
37 | do { \ | |
38 | if (hdmi_log_on) printk("[hdmi_drv]%s,%d ", __func__, __LINE__); printk(fmt, ##arg); \ | |
39 | } while (0) | |
40 | ||
41 | #define HDMI_FUNC() \ | |
42 | do { \ | |
43 | if (hdmi_log_on) printk("[hdmi_drv] %s\n", __func__); \ | |
44 | } while (0) | |
45 | ||
46 | /* --------------------------------------------------------------------------- */ | |
47 | /* Local Constants */ | |
48 | /* --------------------------------------------------------------------------- */ | |
49 | ||
50 | #define FRAME_WIDTH (480) | |
51 | #define FRAME_HEIGHT (800) | |
52 | ||
53 | /* --------------------------------------------------------------------------- */ | |
54 | /* Local Variables */ | |
55 | /* --------------------------------------------------------------------------- */ | |
56 | ||
57 | /* static struct task_struct *hdmi_event_task = NULL; */ | |
58 | /* static struct task_struct *hdmi_hpd_detect_task = NULL; */ | |
59 | /* static int hdmi_event_status = HDMI_STATE_NO_DEVICE; */ | |
60 | ||
61 | wait_queue_head_t hdmi_event_wq; | |
62 | atomic_t hdmi_event = ATOMIC_INIT(0); | |
63 | ||
64 | static HDMI_UTIL_FUNCS hdmi_util = { 0 }; | |
65 | ||
66 | #define SET_RESET_PIN(v) (hdmi_util.set_reset_pin((v))) | |
67 | ||
68 | #define UDELAY(n) (hdmi_util.udelay(n)) | |
69 | #define MDELAY(n) (hdmi_util.mdelay(n)) | |
70 | ||
71 | /*************************************RCP function report added by garyyuan*********************************/ | |
72 | static struct input_dev *kpd_input_dev = NULL; | |
73 | HDMI_CABLE_TYPE MHL_Connect_type = MHL_CABLE; | |
74 | ||
75 | void mhl_init_rmt_input_dev(void) | |
76 | { | |
77 | int ret; | |
78 | printk(KERN_INFO "%s:%d:.................................................\n", __func__, | |
79 | __LINE__); | |
80 | kpd_input_dev = input_allocate_device(); | |
81 | if (!kpd_input_dev) { | |
82 | printk("\nError!!!failed to allocate input device, no memory!!!%s:%d:.....\n", | |
83 | __func__, __LINE__); | |
84 | return /*-ENOMEM*/; | |
85 | } | |
86 | #if 1 | |
87 | kpd_input_dev->name = "mhl-keyboard"; | |
88 | set_bit(EV_KEY, kpd_input_dev->evbit); | |
89 | set_bit(KEY_SELECT, kpd_input_dev->keybit); | |
90 | set_bit(KEY_UP, kpd_input_dev->keybit); | |
91 | set_bit(KEY_DOWN, kpd_input_dev->keybit); | |
92 | set_bit(KEY_LEFT, kpd_input_dev->keybit); | |
93 | set_bit(KEY_RIGHT, kpd_input_dev->keybit); | |
94 | /* set_bit(KEY_RIGHT_UP, kpd_input_dev->keybit); */ | |
95 | /* set_bit(KEY_RIGHT_DOWN , kpd_input_dev->keybit); */ | |
96 | /* set_bit(KEY_LEFT_UP,kpd_input_dev->keybit); */ | |
97 | /* set_bit(KEY_LEFT_DOWN, kpd_input_dev->keybit); */ | |
98 | ||
99 | set_bit(KEY_MENU, kpd_input_dev->keybit); | |
100 | /* set_bit(KEY_SETUP, kpd_input_dev->keybit); */ | |
101 | ||
102 | set_bit(KEY_EXIT, kpd_input_dev->keybit); | |
103 | ||
104 | /* set_bit(KEY_CONTEXT_MENU ,kpd_input_dev->keybit); */ | |
105 | /* set_bit(KEY_FAVORITES, kpd_input_dev->keybit); */ | |
106 | /* set_bit(KEY_EXIT, kpd_input_dev->keybit); */ | |
107 | ||
108 | ||
109 | set_bit(KEY_0, kpd_input_dev->keybit); | |
110 | set_bit(KEY_1, kpd_input_dev->keybit); | |
111 | set_bit(KEY_2, kpd_input_dev->keybit); | |
112 | set_bit(KEY_3, kpd_input_dev->keybit); | |
113 | set_bit(KEY_4, kpd_input_dev->keybit); | |
114 | set_bit(KEY_5, kpd_input_dev->keybit); | |
115 | set_bit(KEY_6, kpd_input_dev->keybit); | |
116 | set_bit(KEY_7, kpd_input_dev->keybit); | |
117 | set_bit(KEY_8, kpd_input_dev->keybit); | |
118 | set_bit(KEY_9, kpd_input_dev->keybit); | |
119 | ||
120 | set_bit(KEY_DOT, kpd_input_dev->keybit); | |
121 | set_bit(KEY_ENTER, kpd_input_dev->keybit); | |
122 | set_bit(KEY_CLEAR, kpd_input_dev->keybit); | |
123 | /* set_bit(KEY_CHANNELUP, kpd_input_dev->keybit); */ | |
124 | /* set_bit(KEY_CHANNELDOWN, kpd_input_dev->keybit); */ | |
125 | /* set_bit(KEY_CHANNEL_PREV, kpd_input_dev->keybit); */ | |
126 | ||
127 | set_bit(KEY_SOUND, kpd_input_dev->keybit); | |
128 | /* set_bit(KEY_INFO, kpd_input_dev->keybit); */ | |
129 | /* set_bit(KEY_HELP, kpd_input_dev->keybit); */ | |
130 | /* set_bit(KEY_PAGEUP,kpd_input_dev->keybit); */ | |
131 | /* set_bit(KEY_PAGEDOWN, kpd_input_dev->keybit); */ | |
132 | set_bit(KEY_VOLUMEUP, kpd_input_dev->keybit); | |
133 | set_bit(KEY_VOLUMEDOWN, kpd_input_dev->keybit); | |
134 | set_bit(KEY_MUTE, kpd_input_dev->keybit); | |
135 | ||
136 | set_bit(KEY_PLAY, kpd_input_dev->keybit); | |
137 | set_bit(KEY_STOP, kpd_input_dev->keybit); | |
138 | /* set_bit(KEY_PAUSE, kpd_input_dev->keybit); */ | |
139 | set_bit(KEY_PAUSECD, kpd_input_dev->keybit); | |
140 | ||
141 | /* set_bit(KEY_RECORD,kpd_input_dev->keybit); */ | |
142 | ||
143 | set_bit(KEY_REWIND, kpd_input_dev->keybit); | |
144 | set_bit(KEY_FASTFORWARD, kpd_input_dev->keybit); | |
145 | set_bit(KEY_EJECTCD, kpd_input_dev->keybit); | |
146 | /* set_bit(KEY_FORWARD, kpd_input_dev->keybit); */ | |
147 | set_bit(KEY_NEXTSONG, kpd_input_dev->keybit); | |
148 | set_bit(KEY_BACK, kpd_input_dev->keybit); | |
149 | set_bit(KEY_PREVIOUSSONG, kpd_input_dev->keybit); | |
150 | ||
151 | /* set_bit(KEY_ANGLE, kpd_input_dev->keybit); */ | |
152 | /* set_bit(KEY_RESTART, kpd_input_dev->keybit); */ | |
153 | set_bit(KEY_PLAYPAUSE, kpd_input_dev->keybit); | |
154 | ||
155 | ret = input_register_device(kpd_input_dev); | |
156 | if (ret) { | |
157 | TX_DEBUG_PRINT(("\nError!!!failed to register input device %s:%d\n", __func__, | |
158 | __LINE__)); | |
159 | input_free_device(kpd_input_dev); | |
160 | } | |
161 | #endif | |
162 | } | |
163 | ||
164 | /* input key conversion */ | |
165 | void input_report_rcp_key(uint8_t rcp_keycode, int up_down) | |
166 | { | |
167 | rcp_keycode &= 0x7F; | |
168 | ||
169 | TX_DEBUG_PRINT(("\nupdown = %d ", up_down)); | |
170 | switch (rcp_keycode) { | |
171 | case MHL_RCP_CMD_SELECT: /* error */ | |
172 | input_report_key(kpd_input_dev, KEY_SELECT, up_down); | |
173 | TX_DEBUG_PRINT(("\nSelect received\n\n")); | |
174 | break; | |
175 | case MHL_RCP_CMD_UP: | |
176 | input_report_key(kpd_input_dev, KEY_UP, up_down); | |
177 | TX_DEBUG_PRINT(("\nUp received\n\n")); | |
178 | break; | |
179 | case MHL_RCP_CMD_DOWN: | |
180 | input_report_key(kpd_input_dev, KEY_DOWN, up_down); | |
181 | TX_DEBUG_PRINT(("\nDown received\n\n")); | |
182 | break; | |
183 | case MHL_RCP_CMD_LEFT: | |
184 | input_report_key(kpd_input_dev, KEY_LEFT, up_down); | |
185 | TX_DEBUG_PRINT(("\nLeft received\n\n")); | |
186 | break; | |
187 | case MHL_RCP_CMD_RIGHT: | |
188 | input_report_key(kpd_input_dev, KEY_RIGHT, up_down); | |
189 | TX_DEBUG_PRINT(("\nRight received\n\n")); | |
190 | break; | |
191 | case MHL_RCP_CMD_ROOT_MENU: | |
192 | input_report_key(kpd_input_dev, KEY_MENU, up_down); | |
193 | TX_DEBUG_PRINT(("\nRoot Menu received\n\n")); | |
194 | break; | |
195 | case MHL_RCP_CMD_EXIT: | |
196 | input_report_key(kpd_input_dev, KEY_BACK, up_down); | |
197 | TX_DEBUG_PRINT(("\nExit received\n\n")); | |
198 | break; | |
199 | case MHL_RCP_CMD_NUM_0: | |
200 | input_report_key(kpd_input_dev, KEY_0, up_down); | |
201 | TX_DEBUG_PRINT(("\nNumber 0 received\n\n")); | |
202 | break; | |
203 | case MHL_RCP_CMD_NUM_1: | |
204 | input_report_key(kpd_input_dev, KEY_1, up_down); | |
205 | TX_DEBUG_PRINT(("\nNumber 1 received\n\n")); | |
206 | break; | |
207 | case MHL_RCP_CMD_NUM_2: | |
208 | input_report_key(kpd_input_dev, KEY_2, up_down); | |
209 | TX_DEBUG_PRINT(("\nNumber 2 received\n\n")); | |
210 | break; | |
211 | case MHL_RCP_CMD_NUM_3: | |
212 | input_report_key(kpd_input_dev, KEY_3, up_down); | |
213 | TX_DEBUG_PRINT(("\nNumber 3 received\n\n")); | |
214 | break; | |
215 | case MHL_RCP_CMD_NUM_4: | |
216 | input_report_key(kpd_input_dev, KEY_4, up_down); | |
217 | TX_DEBUG_PRINT(("\nNumber 4 received\n\n")); | |
218 | break; | |
219 | case MHL_RCP_CMD_NUM_5: | |
220 | input_report_key(kpd_input_dev, KEY_5, up_down); | |
221 | TX_DEBUG_PRINT(("\nNumber 5 received\n\n")); | |
222 | break; | |
223 | case MHL_RCP_CMD_NUM_6: | |
224 | input_report_key(kpd_input_dev, KEY_6, up_down); | |
225 | TX_DEBUG_PRINT(("\nNumber 6 received\n\n")); | |
226 | break; | |
227 | case MHL_RCP_CMD_NUM_7: | |
228 | input_report_key(kpd_input_dev, KEY_7, up_down); | |
229 | TX_DEBUG_PRINT(("\nNumber 7 received\n\n")); | |
230 | break; | |
231 | case MHL_RCP_CMD_NUM_8: | |
232 | input_report_key(kpd_input_dev, KEY_8, up_down); | |
233 | TX_DEBUG_PRINT(("\nNumber 8 received\n\n")); | |
234 | break; | |
235 | case MHL_RCP_CMD_NUM_9: | |
236 | input_report_key(kpd_input_dev, KEY_9, up_down); | |
237 | TX_DEBUG_PRINT(("\nNumber 9 received\n\n")); | |
238 | break; | |
239 | case MHL_RCP_CMD_DOT: | |
240 | input_report_key(kpd_input_dev, KEY_DOT, up_down); | |
241 | TX_DEBUG_PRINT(("\nDot received\n\n")); | |
242 | break; | |
243 | case MHL_RCP_CMD_ENTER: | |
244 | input_report_key(kpd_input_dev, KEY_ENTER, up_down); | |
245 | TX_DEBUG_PRINT(("\nEnter received\n\n")); | |
246 | break; | |
247 | case MHL_RCP_CMD_CLEAR: | |
248 | input_report_key(kpd_input_dev, KEY_CLEAR, up_down); | |
249 | TX_DEBUG_PRINT(("\nClear received\n\n")); | |
250 | break; | |
251 | case MHL_RCP_CMD_SOUND_SELECT: | |
252 | input_report_key(kpd_input_dev, KEY_SOUND, up_down); | |
253 | TX_DEBUG_PRINT(("\nSound Select received\n\n")); | |
254 | break; | |
255 | case MHL_RCP_CMD_PLAY: | |
256 | input_report_key(kpd_input_dev, KEY_PLAY, up_down); | |
257 | TX_DEBUG_PRINT(("\nPlay received\n\n")); | |
258 | break; | |
259 | case MHL_RCP_CMD_PAUSE: | |
260 | /* input_report_key(kpd_input_dev, KEY_PAUSE, up_down); */ | |
261 | input_report_key(kpd_input_dev, KEY_PAUSECD, up_down); | |
262 | ||
263 | TX_DEBUG_PRINT(("\nPause received\n\n")); | |
264 | break; | |
265 | case MHL_RCP_CMD_STOP: | |
266 | input_report_key(kpd_input_dev, KEY_STOP, up_down); | |
267 | TX_DEBUG_PRINT(("\nStop received\n\n")); | |
268 | break; | |
269 | case MHL_RCP_CMD_FAST_FWD: | |
270 | input_report_key(kpd_input_dev, KEY_FASTFORWARD, up_down); | |
271 | input_report_key(kpd_input_dev, KEY_FASTFORWARD, up_down); | |
272 | TX_DEBUG_PRINT(("\nFastfwd received\n\n")); | |
273 | break; | |
274 | case MHL_RCP_CMD_REWIND: | |
275 | input_report_key(kpd_input_dev, KEY_REWIND, up_down); | |
276 | TX_DEBUG_PRINT(("\nRewind received\n\n")); | |
277 | break; | |
278 | case MHL_RCP_CMD_EJECT: | |
279 | input_report_key(kpd_input_dev, KEY_EJECTCD, up_down); | |
280 | TX_DEBUG_PRINT(("\nEject received\n\n")); | |
281 | break; | |
282 | case MHL_RCP_CMD_FWD: | |
283 | /* input_report_key(kpd_input_dev, KEY_FORWARD, up_down);//next song */ | |
284 | input_report_key(kpd_input_dev, KEY_NEXTSONG, up_down); | |
285 | TX_DEBUG_PRINT(("\nNext song received\n\n")); | |
286 | break; | |
287 | case MHL_RCP_CMD_BKWD: | |
288 | /* input_report_key(kpd_input_dev, KEY_BACK, up_down);//previous song */ | |
289 | input_report_key(kpd_input_dev, KEY_PREVIOUSSONG, up_down); | |
290 | TX_DEBUG_PRINT(("\nPrevious song received\n\n")); | |
291 | break; | |
292 | case MHL_RCP_CMD_PLAY_FUNC: | |
293 | /* input_report_key(kpd_input_dev, KEY_PL, up_down); */ | |
294 | input_report_key(kpd_input_dev, KEY_PLAY, up_down); | |
295 | TX_DEBUG_PRINT(("\nPlay Function received\n\n")); | |
296 | break; | |
297 | case MHL_RCP_CMD_PAUSE_PLAY_FUNC: | |
298 | input_report_key(kpd_input_dev, KEY_PLAYPAUSE, up_down); | |
299 | TX_DEBUG_PRINT(("\nPause_Play Function received\n\n")); | |
300 | break; | |
301 | case MHL_RCP_CMD_STOP_FUNC: | |
302 | input_report_key(kpd_input_dev, KEY_STOP, up_down); | |
303 | TX_DEBUG_PRINT(("\nStop Function received\n\n")); | |
304 | break; | |
305 | case MHL_RCP_CMD_F1: | |
306 | input_report_key(kpd_input_dev, KEY_F1, up_down); | |
307 | TX_DEBUG_PRINT(("\nF1 received\n\n")); | |
308 | break; | |
309 | case MHL_RCP_CMD_F2: | |
310 | input_report_key(kpd_input_dev, KEY_F2, up_down); | |
311 | TX_DEBUG_PRINT(("\nF2 received\n\n")); | |
312 | break; | |
313 | case MHL_RCP_CMD_F3: | |
314 | input_report_key(kpd_input_dev, KEY_F3, up_down); | |
315 | TX_DEBUG_PRINT(("\nF3 received\n\n")); | |
316 | break; | |
317 | case MHL_RCP_CMD_F4: | |
318 | input_report_key(kpd_input_dev, KEY_F4, up_down); | |
319 | TX_DEBUG_PRINT(("\nF4 received\n\n")); | |
320 | break; | |
321 | case MHL_RCP_CMD_F5: | |
322 | input_report_key(kpd_input_dev, KEY_F5, up_down); | |
323 | TX_DEBUG_PRINT(("\nF5 received\n\n")); | |
324 | break; | |
325 | default: | |
326 | break; | |
327 | } | |
328 | ||
329 | /* added for improving mhl RCP start */ | |
330 | input_sync(kpd_input_dev); | |
331 | /* added for improving mhl RCP end */ | |
332 | } | |
333 | ||
334 | void input_report_mhl_rcp_key(uint8_t rcp_keycode) | |
335 | { | |
336 | /* added for improving mhl RCP start */ | |
337 | input_report_rcp_key(rcp_keycode & 0x7F, 1); | |
338 | ||
339 | if ((MHL_RCP_CMD_FAST_FWD == rcp_keycode) || (MHL_RCP_CMD_REWIND == rcp_keycode)) { | |
340 | msleep(100); | |
341 | } | |
342 | input_report_rcp_key(rcp_keycode & 0x7F, 0); | |
343 | /* added for improving mhl RCP end */ | |
344 | } | |
345 | ||
346 | /*************************************RCP function report added by garyyuan*********************************/ | |
347 | ||
348 | #define MAX_EVENT_STRING_LEN 40 | |
349 | void AppNotifyMhlDownStreamHPDStatusChange(bool_t connected) | |
350 | { | |
351 | char event_string[MAX_EVENT_STRING_LEN]; | |
352 | /* char *envp[] = {event_string, NULL}; */ | |
353 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
354 | "AppNotifyMhlDownStreamHPDStatusChange called, " | |
355 | "HPD status is: %s\n", connected ? "CONNECTED" : "NOT CONNECTED"); | |
356 | snprintf(event_string, MAX_EVENT_STRING_LEN, "MHLEVENT=%s", connected ? "HPD" : "NO_HPD"); | |
357 | printk("MHLEVENT=%s\n", connected ? "HPD" : "NO_HPD"); | |
358 | #if 0 | |
359 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
360 | #endif | |
361 | } | |
362 | ||
363 | MhlTxNotifyEventsStatus_e AppNotifyMhlEvent(uint8_t eventCode, uint8_t eventParam) | |
364 | { | |
365 | char event_string[MAX_EVENT_STRING_LEN]; | |
366 | /* char *envp[] = {event_string, NULL}; */ | |
367 | MhlTxNotifyEventsStatus_e retVal = MHL_TX_EVENT_STATUS_PASSTHROUGH; | |
368 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
369 | "AppNotifyEvent called, eventCode: 0x%02x eventParam: 0x%02x\n", | |
370 | eventCode, eventParam); | |
371 | ||
372 | /* return retVal; */ | |
373 | switch (eventCode) { | |
374 | case MHL_TX_EVENT_CONNECTION: | |
375 | gDriverContext.flags |= MHL_STATE_FLAG_CONNECTED; | |
376 | strncpy(event_string, "MHLEVENT=connected", MAX_EVENT_STRING_LEN); | |
377 | #if 0 | |
378 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
379 | #endif | |
380 | break; | |
381 | case MHL_TX_EVENT_RCP_READY: | |
382 | gDriverContext.flags |= MHL_STATE_FLAG_RCP_READY; | |
383 | strncpy(event_string, "MHLEVENT=rcp_ready", MAX_EVENT_STRING_LEN); | |
384 | #if 0 | |
385 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
386 | #endif | |
387 | break; | |
388 | case MHL_TX_EVENT_DISCONNECTION: | |
389 | gDriverContext.flags = 0; | |
390 | gDriverContext.keyCode = 0; | |
391 | gDriverContext.errCode = 0; | |
392 | strncpy(event_string, "MHLEVENT=disconnected", MAX_EVENT_STRING_LEN); | |
393 | #if 0 | |
394 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
395 | #endif | |
396 | break; | |
397 | case MHL_TX_EVENT_RCP_RECEIVED: | |
398 | gDriverContext.flags &= ~MHL_STATE_FLAG_RCP_SENT; | |
399 | gDriverContext.flags |= MHL_STATE_FLAG_RCP_RECEIVED; | |
400 | gDriverContext.keyCode = eventParam; | |
401 | /* for RCP report function by garyyuan */ | |
402 | if (eventParam > 0x7F) | |
403 | break; | |
404 | input_report_mhl_rcp_key(gDriverContext.keyCode); | |
405 | snprintf(event_string, MAX_EVENT_STRING_LEN, | |
406 | "MHLEVENT=received_RCP key code=0x%02x", eventParam); | |
407 | #if 0 | |
408 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
409 | #endif | |
410 | break; | |
411 | case MHL_TX_EVENT_RCPK_RECEIVED: | |
412 | if ((gDriverContext.flags & MHL_STATE_FLAG_RCP_SENT) | |
413 | && (gDriverContext.keyCode == eventParam)) { | |
414 | gDriverContext.flags |= MHL_STATE_FLAG_RCP_ACK; | |
415 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
416 | "Generating RCPK received event, keycode: 0x%02x\n", | |
417 | eventParam); | |
418 | snprintf(event_string, MAX_EVENT_STRING_LEN, | |
419 | "MHLEVENT=received_RCPK key code=0x%02x", eventParam); | |
420 | #if 0 | |
421 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
422 | #endif | |
423 | } else { | |
424 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
425 | "Ignoring unexpected RCPK received event, keycode: 0x%02x\n", | |
426 | eventParam); | |
427 | } | |
428 | break; | |
429 | case MHL_TX_EVENT_RCPE_RECEIVED: | |
430 | if (gDriverContext.flags & MHL_STATE_FLAG_RCP_SENT) { | |
431 | gDriverContext.errCode = eventParam; | |
432 | gDriverContext.flags |= MHL_STATE_FLAG_RCP_NAK; | |
433 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
434 | "Generating RCPE received event, error code: 0x%02x\n", | |
435 | eventParam); | |
436 | snprintf(event_string, MAX_EVENT_STRING_LEN, | |
437 | "MHLEVENT=received_RCPE error code=0x%02x", eventParam); | |
438 | #if 0 | |
439 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
440 | #endif | |
441 | } else { | |
442 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
443 | "Ignoring unexpected RCPE received event, error code: 0x%02x\n", | |
444 | eventParam); | |
445 | } | |
446 | break; | |
447 | case MHL_TX_EVENT_DCAP_CHG: | |
448 | snprintf(event_string, MAX_EVENT_STRING_LEN, "MHLEVENT=DEVCAP change"); | |
449 | #if 0 | |
450 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
451 | #endif | |
452 | break; | |
453 | case MHL_TX_EVENT_DSCR_CHG: | |
454 | snprintf(event_string, MAX_EVENT_STRING_LEN, "MHLEVENT=SCRATCHPAD change"); | |
455 | #if 0 | |
456 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
457 | #endif | |
458 | break; | |
459 | case MHL_TX_EVENT_POW_BIT_CHG: | |
460 | if (eventParam) { | |
461 | snprintf(event_string, MAX_EVENT_STRING_LEN, "MHLEVENT=MHL VBUS power OFF"); | |
462 | } else { | |
463 | snprintf(event_string, MAX_EVENT_STRING_LEN, "MHLEVENT=MHL VBUS power ON"); | |
464 | } | |
465 | #if 0 | |
466 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
467 | #endif | |
468 | break; | |
469 | case MHL_TX_EVENT_RGND_MHL: | |
470 | snprintf(event_string, MAX_EVENT_STRING_LEN, "MHLEVENT=MHL device detected"); | |
471 | #if 0 | |
472 | kobject_uevent_env(&gDriverContext.pDevice->kobj, KOBJ_CHANGE, envp); | |
473 | #endif | |
474 | break; | |
475 | default: | |
476 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
477 | "AppNotifyEvent called with unrecognized event code!\n"); | |
478 | } | |
479 | return retVal; | |
480 | } | |
481 | ||
482 | ||
483 | static void hdmi_drv_set_util_funcs(const HDMI_UTIL_FUNCS *util) | |
484 | { | |
485 | memcpy(&hdmi_util, util, sizeof(HDMI_UTIL_FUNCS)); | |
486 | } | |
487 | ||
488 | static void hdmi_drv_get_params(HDMI_PARAMS *params) | |
489 | { | |
490 | HDMI_FUNC(); | |
491 | memset(params, 0, sizeof(HDMI_PARAMS)); | |
492 | params->init_config.vformat = HDMI_VIDEO_1280x720p_60Hz; | |
493 | params->init_config.aformat = HDMI_AUDIO_44K_2CH; | |
494 | ||
495 | params->clk_pol = HDMI_POLARITY_FALLING; | |
496 | params->de_pol = HDMI_POLARITY_RISING; | |
497 | params->vsync_pol = HDMI_POLARITY_RISING; | |
498 | params->hsync_pol = HDMI_POLARITY_RISING; | |
499 | ||
500 | params->hsync_front_porch = 110; | |
501 | params->hsync_pulse_width = 40; | |
502 | params->hsync_back_porch = 220; | |
503 | ||
504 | params->vsync_front_porch = 5; | |
505 | params->vsync_pulse_width = 5; | |
506 | params->vsync_back_porch = 20; | |
507 | ||
508 | params->rgb_order = HDMI_COLOR_ORDER_RGB; | |
509 | ||
510 | params->io_driving_current = IO_DRIVING_CURRENT_2MA; | |
511 | params->intermediat_buffer_num = 4; | |
512 | params->scaling_factor = 4; | |
513 | params->cabletype = MHL_Connect_type; | |
514 | } | |
515 | ||
516 | void hdmi_drv_suspend(void) | |
517 | { | |
518 | } | |
519 | ||
520 | void hdmi_drv_resume(void) | |
521 | { | |
522 | } | |
523 | ||
524 | ||
525 | static int hdmi_drv_video_config(HDMI_VIDEO_RESOLUTION vformat, HDMI_VIDEO_INPUT_FORMAT vin, | |
526 | HDMI_VIDEO_OUTPUT_FORMAT vout) | |
527 | { | |
528 | ||
529 | if (vformat == HDMI_VIDEO_720x480p_60Hz) { | |
530 | HDMI_LOG("[hdmi_drv]480p\n"); | |
531 | siHdmiTx_VideoSel(HDMI_480P60_4X3); | |
532 | } else if (vformat == HDMI_VIDEO_1280x720p_60Hz) { | |
533 | HDMI_LOG("[hdmi_drv]720p\n"); | |
534 | siHdmiTx_VideoSel(HDMI_720P60); | |
535 | } else if (vformat == HDMI_VIDEO_1920x1080p_30Hz) { | |
536 | HDMI_LOG("[hdmi_drv]1080p\n"); | |
537 | siHdmiTx_VideoSel(HDMI_1080P30); | |
538 | } else { | |
539 | HDMI_LOG("%s, video format not support now\n", __func__); | |
540 | } | |
541 | return 0; | |
542 | } | |
543 | ||
544 | static int hdmi_drv_audio_config(HDMI_AUDIO_FORMAT aformat) | |
545 | { | |
546 | return 0; | |
547 | } | |
548 | ||
549 | static int hdmi_drv_video_enable(bool enable) | |
550 | { | |
551 | return 0; | |
552 | } | |
553 | ||
554 | static int hdmi_drv_audio_enable(bool enable) | |
555 | { | |
556 | return 0; | |
557 | } | |
558 | ||
559 | #define SiI8338DRIVER_INTERRUPT_MODE 1 | |
560 | ||
561 | static int hdmi_drv_init(void) | |
562 | { | |
563 | halReturn_t halStatus; | |
564 | SiiOsStatus_t osalStatus; | |
565 | printk("Starting %s\n", MHL_PART_NAME); | |
566 | ||
567 | cust_hdmi_power_on(true); | |
568 | ||
569 | if (!SiiCraInitialize()) { | |
570 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, "Initialization of CRA layer failed!\n"); | |
571 | return -EIO; | |
572 | } | |
573 | osalStatus = SiiOsInit(0); | |
574 | if (osalStatus != SII_OS_STATUS_SUCCESS) { | |
575 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
576 | "Initialization of OSAL failed, error code: %d\n", osalStatus); | |
577 | return -EIO; | |
578 | } | |
579 | halStatus = HalInit(); | |
580 | if (halStatus != HAL_RET_SUCCESS) { | |
581 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
582 | "Initialization of HAL failed, error code: %d\n", halStatus); | |
583 | SiiOsTerm(); | |
584 | return -EIO; | |
585 | } | |
586 | /* #if MTK_project */ | |
587 | /* I2c_Init(); */ | |
588 | /* #endif */ | |
589 | ||
590 | halStatus = HalOpenI2cDevice(MHL_PART_NAME, MHL_DRIVER_NAME); | |
591 | if (halStatus != HAL_RET_SUCCESS) { | |
592 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
593 | "Opening of I2c device %s failed, error code: %d\n", MHL_PART_NAME, | |
594 | halStatus); | |
595 | HalTerm(); | |
596 | SiiOsTerm(); | |
597 | return -EIO; | |
598 | } | |
599 | ||
600 | /* msleep(200); */ | |
601 | #ifdef SiI8338DRIVER_INTERRUPT_MODE | |
602 | halStatus = HalInstallIrqHandler(SiiMhlTxDeviceIsr); | |
603 | if (halStatus != HAL_RET_SUCCESS) { | |
604 | SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, | |
605 | "Initialization of HAL interrupt support failed, error code: %d\n", | |
606 | halStatus); | |
607 | HalCloseI2cDevice(); | |
608 | HalTerm(); | |
609 | SiiOsTerm(); | |
610 | return -EIO; | |
611 | } | |
612 | #else | |
613 | StartEventThread(); /* begin monitoring for events if using polling mode */ | |
614 | #endif | |
615 | ||
616 | #ifdef MDT_SUPPORT | |
617 | mhl_init_rmt_input_dev(); | |
618 | #endif | |
619 | ||
620 | return 0; | |
621 | } | |
622 | ||
623 | static int hdmi_drv_enter(void) | |
624 | { | |
625 | HDMI_FUNC(); | |
626 | return 0; | |
627 | } | |
628 | ||
629 | static int hdmi_drv_exit(void) | |
630 | { | |
631 | HDMI_FUNC(); | |
632 | return 0; | |
633 | } | |
634 | ||
635 | extern int SiiMhlTxInitialize(unsigned char pollIntervalMs); | |
636 | extern void SiiMhlTxHwReset(uint16_t hwResetPeriod, uint16_t hwResetDelay); | |
637 | extern unsigned int pmic_config_interface(unsigned int RegNum, unsigned int val, unsigned int MASK, | |
638 | unsigned int SHIFT); | |
639 | extern void SwitchToD3(void); | |
640 | extern void SiiMhlTxHwResetKeepLow(void); | |
641 | extern void ForceSwitchToD3(void); | |
642 | extern void SiiMhlTxHwGpioSuspend(void); | |
643 | extern void SiiMhlTxHwGpioResume(void); | |
644 | ||
645 | int hdmi_drv_power_on(void) | |
646 | { | |
647 | int ret = 0; | |
648 | HDMI_FUNC(); | |
649 | #ifdef CUST_EINT_MHL_NUM | |
650 | mt_eint_mask(CUST_EINT_MHL_NUM); | |
651 | #else | |
652 | printk("%s,%d Error: CUST_EINT_MHL_NUM is not defined\n", __func__, __LINE__); | |
653 | #endif | |
654 | ||
655 | cust_hdmi_dpi_gpio_on(true); | |
656 | cust_hdmi_i2s_gpio_on(true); | |
657 | ||
658 | SiiMhlTxHwReset(5, 5); | |
659 | ||
660 | HalInstallCheckDeviceCB(SiiCheckDevice); | |
661 | HalAcquireIsrLock(); | |
662 | siHdmiTx_VideoSel(HDMI_720P60); | |
663 | siHdmiTx_AudioSel(I2S_44); | |
664 | ret = SiiMhlTxInitialize(EVENT_POLL_INTERVAL_MS); | |
665 | HalReleaseIsrLock(); | |
666 | #ifdef CUST_EINT_MHL_NUM | |
667 | mt_eint_unmask(CUST_EINT_MHL_NUM); | |
668 | #endif | |
669 | return ret; | |
670 | } | |
671 | ||
672 | void hdmi_drv_power_off(void) | |
673 | { | |
674 | HDMI_FUNC(); | |
675 | ||
676 | cust_hdmi_dpi_gpio_on(false); | |
677 | cust_hdmi_i2s_gpio_on(false); | |
678 | ||
679 | ||
680 | SiiMhlTxHwReset(50, 200); | |
681 | ForceSwitchToD3(); | |
682 | /* SwitchToD3(); */ | |
683 | /* SiiMhlTxHwResetKeepLow(); */ | |
684 | /* pmic_config_interface(0x87,0x0,0x01,0x0); */ | |
685 | } | |
686 | ||
687 | extern unsigned char SiiTxReadConnectionStatus(void); | |
688 | HDMI_STATE hdmi_drv_get_state(void) | |
689 | { | |
690 | int ret = SiiTxReadConnectionStatus(); | |
691 | HDMI_FUNC(); | |
692 | HDMI_LOG("sii status:%d\n", ret); | |
693 | if (ret == 1) | |
694 | return HDMI_STATE_ACTIVE; | |
695 | else | |
696 | return HDMI_STATE_NO_DEVICE; | |
697 | } | |
698 | ||
699 | void hdmi_drv_log_enable(bool enable) | |
700 | { | |
701 | hdmi_log_on = enable; | |
702 | } | |
703 | ||
704 | const HDMI_DRIVER *HDMI_GetDriver(void) | |
705 | { | |
706 | static const HDMI_DRIVER HDMI_DRV = { | |
707 | .set_util_funcs = hdmi_drv_set_util_funcs, | |
708 | .get_params = hdmi_drv_get_params, | |
709 | .init = hdmi_drv_init, | |
710 | .enter = hdmi_drv_enter, | |
711 | .exit = hdmi_drv_exit, | |
712 | .suspend = hdmi_drv_suspend, | |
713 | .resume = hdmi_drv_resume, | |
714 | .video_config = hdmi_drv_video_config, | |
715 | .audio_config = hdmi_drv_audio_config, | |
716 | .video_enable = hdmi_drv_video_enable, | |
717 | .audio_enable = hdmi_drv_audio_enable, | |
718 | .power_on = hdmi_drv_power_on, | |
719 | .power_off = hdmi_drv_power_off, | |
720 | .get_state = hdmi_drv_get_state, | |
721 | .log_enable = hdmi_drv_log_enable | |
722 | }; | |
723 | ||
724 | HDMI_FUNC(); | |
725 | return &HDMI_DRV; | |
726 | } | |
727 | #endif |