import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / hdmi / Sii8348 / hdmi_drv.c
CommitLineData
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
14#include <mtk_kpd.h> /* custom file */
15#include "si_timing_defs.h"
16
17#include "hdmi_drv.h"
18#include "smartbook.h"
19
20#include "hdmi_cust.h"
21/**
22* MHL TX Chip Driver User Layer Interface
23*/
24extern struct mhl_dev_context *si_dev_context;
25extern void ForceSwitchToD3( struct mhl_dev_context *dev_context);
26extern void ForceNotSwitchToD3();
27extern int si_mhl_tx_post_initialize(struct mhl_dev_context *dev_context, bool bootup);
28extern void siHdmiTx_VideoSel (int vmode);
29extern void siHdmiTx_AudioSel (int AduioMode);
30extern void set_platform_bitwidth(int bitWidth);
31extern bool si_mhl_tx_set_path_en_I(struct mhl_dev_context *dev_context);
32extern bool packed_pixel_available(struct mhl_dev_context *dev_context);
33extern void configure_and_send_audio_info(struct mhl_dev_context *dev_context, int audio_format);
34
35//Should align to mhl_linux_tx.h
36#define MHL_TX_EVENT_DISCONNECTION 0x01
37#define MHL_TX_EVENT_CONNECTION 0x02
38#define MHL_TX_EVENT_SMB_DATA 0x40
39#define MHL_TX_EVENT_HPD_CLEAR 0x41
40#define MHL_TX_EVENT_HPD_GOT 0x42
41#define MHL_TX_EVENT_DEV_CAP_UPDATE 0x43
42#define MHL_TX_EVENT_EDID_UPDATE 0x44
43#define MHL_TX_EVENT_EDID_DONE 0x45
44#define MHL_TX_EVENT_CALLBACK 0x46
45
46/**
47* Platform Related Layer Interface
48*/
49extern int HalOpenI2cDevice(char const *DeviceName, char const *DriverName);
50extern Mask_MHL_Intr(void);
51extern Unmask_MHL_Intr(void);
52extern int32_t sii_8348_tx_init(void); //Should move to MHL TX Chip user layer
53/**
54* LOG For MHL TX Chip HAL
55*/
56static size_t hdmi_log_on = true;
57static int txInitFlag = 0;
58
59#define HDMI_LOG(fmt, arg...) \
60 do { \
61 if (hdmi_log_on) printk("[HDMI_Chip_HAL]%s,%d,", __func__, __LINE__); printk(fmt, ##arg); \
62 }while (0)
63
64#define HDMI_FUNC() \
65 do { \
66 if(hdmi_log_on) printk("[HDMI_Chip_HAL] %s\n", __func__); \
67 }while (0)
68
69void hdmi_drv_log_enable(bool enable)
70{
71 hdmi_log_on = enable;
72}
73
74static int not_switch_to_d3 = 0;
75static int audio_enable = 0;
76
77void hdmi_drv_force_on(int from_uart_drv )
78{
79 HDMI_LOG("hdmi_drv_force_on %d\n", from_uart_drv);
80 if(from_uart_drv == 0)
81 ForceNotSwitchToD3();
82 not_switch_to_d3 = 1;
83//gpio:uart
84 cust_hdmi_i2s_gpio_on(2);
85}
86
87/************************** Upper Layer To HAL*********************************/
88static HDMI_UTIL_FUNCS hdmi_util = {0};
89static void hdmi_drv_set_util_funcs(const HDMI_UTIL_FUNCS *util)
90{
91 memcpy(&hdmi_util, util, sizeof(HDMI_UTIL_FUNCS));
92}
93
94static char* cable_type_print(unsigned short type)
95{
96 switch(type)
97 {
98 case HDMI_CABLE:
99 return "HDMI_CABLE";
100 case MHL_CABLE:
101 return "MHL_CABLE";
102 case MHL_SMB_CABLE:
103 return "MHL_SMB_CABLE";
104 case MHL_2_CABLE:
105 return "MHL_2_CABLE";
106 default:
107 HDMI_LOG("Unknow MHL Cable Type\n");
108 return "Unknow MHL Cable Type\n";
109 }
110}
111
112static HDMI_CABLE_TYPE MHL_Connect_type = MHL_CABLE;
113static bool HDCP_Supported_Info = false;
114static void hdmi_drv_get_params(HDMI_PARAMS *params)
115{
116 memset(params, 0, sizeof(HDMI_PARAMS));
117 params->init_config.vformat = HDMI_VIDEO_1280x720p_60Hz;
118 params->init_config.aformat = HDMI_AUDIO_44K_2CH;
119
120 params->clk_pol = HDMI_POLARITY_FALLING;
121 params->de_pol = HDMI_POLARITY_RISING;
122 params->vsync_pol = HDMI_POLARITY_RISING;
123 params->hsync_pol = HDMI_POLARITY_RISING;
124
125 params->hsync_front_porch = 110;
126 params->hsync_pulse_width = 40;
127 params->hsync_back_porch = 220;
128
129 params->vsync_front_porch = 5;
130 params->vsync_pulse_width = 5;
131 params->vsync_back_porch = 20;
132
133 params->rgb_order = HDMI_COLOR_ORDER_RGB;
134
135 params->io_driving_current = IO_DRIVING_CURRENT_2MA;
136 params->intermediat_buffer_num = 4;
137 params->scaling_factor = 0;
138 params->cabletype = MHL_Connect_type;
139 params->HDCPSupported = HDCP_Supported_Info;
140
141 HDMI_LOG("type %s\n", cable_type_print(params->cabletype));
142 return ;
143}
144
145void hdmi_drv_suspend(void) {return ;}
146void hdmi_drv_resume(void) {return ;}
147static int hdmi_drv_audio_config(HDMI_AUDIO_FORMAT aformat, int bitWidth)
148{
149 set_platform_bitwidth(bitWidth);
150 siHdmiTx_AudioSel(aformat);
151 configure_and_send_audio_info(si_dev_context, aformat);
152
153 return 0;
154}
155static int hdmi_drv_video_enable(bool enable)
156{
157 return 0;
158}
159
160static int hdmi_drv_audio_enable(bool enable)
161{
162 printk("[EXTD]Set_I2S_Pin, enable = %d\n", enable);
163 //gpio:uart
164 if(not_switch_to_d3 == 1)
165 cust_hdmi_i2s_gpio_on(2);
166 else
167 cust_hdmi_i2s_gpio_on(enable);
168
169 audio_enable = enable;
170 return 0;
171}
172
173static int hdmi_drv_enter(void) {return 0;}
174static int hdmi_drv_exit(void) {return 0;}
175
176static int hdmi_drv_video_config(HDMI_VIDEO_RESOLUTION vformat, HDMI_VIDEO_INPUT_FORMAT vin, HDMI_VIDEO_OUTPUT_FORMAT vout)
177{
178 if(vformat == HDMI_VIDEO_720x480p_60Hz)
179 {
180 HDMI_LOG("[hdmi_drv]480p\n");
181 siHdmiTx_VideoSel(HDMI_480P60_4X3);
182 }
183 else if(vformat == HDMI_VIDEO_1280x720p_60Hz)
184 {
185 HDMI_LOG("[hdmi_drv]720p\n");
186 siHdmiTx_VideoSel(HDMI_720P60);
187 }
188 else if(vformat == HDMI_VIDEO_1920x1080p_30Hz)
189 {
190 HDMI_LOG("[hdmi_drv]1080p_30 %p\n", si_dev_context);
191 siHdmiTx_VideoSel(HDMI_1080P30);
192 }
193 else if(vformat == HDMI_VIDEO_1920x1080p_60Hz)
194 {
195 HDMI_LOG("[hdmi_drv]1080p_60 %p\n", si_dev_context);
196 siHdmiTx_VideoSel(HDMI_1080P60);
197 }
198 else
199 {
200 HDMI_LOG("%s, video format not support now\n", __func__);
201 }
202
203 if(si_dev_context)
204 si_mhl_tx_set_path_en_I(si_dev_context);
205 return 0;
206}
207
208static unsigned int sii_mhl_connected = 0;
209static uint8_t ReadConnectionStatus(void)
210{
211 return (sii_mhl_connected == MHL_TX_EVENT_CALLBACK)? 1 : 0;
212}
213HDMI_STATE hdmi_drv_get_state(void)
214{
215 int ret = ReadConnectionStatus();
216 HDMI_LOG("ret: %d\n", ret);
217
218 if(ret == 1)
219 return HDMI_STATE_ACTIVE;
220 else
221 return HDMI_STATE_NO_DEVICE;
222}
223
224bool chip_inited = false;
225static int hdmi_drv_init(void)
226{
227 HDMI_LOG("hdmi_drv_init +\n" );
228
229 Mask_MHL_Intr();
230 cust_hdmi_power_on(true);
231 if(not_switch_to_d3 == 0)
232 {
233 HalOpenI2cDevice("Sil_MHL", "sii8348drv");
234 }
235
236 txInitFlag = 0;
237 chip_inited = false;
238 HDMI_LOG("hdmi_drv_init -\n" );
239 return 0;
240}
241
242//Should be enhanced
243int chip_device_id = 0;
244bool need_reset_usb_switch = true;
245int hdmi_drv_power_on(void)
246{
247 int ret = 1;
248 HDMI_FUNC();
249
250 if(not_switch_to_d3 > 0)
251 {
252 HDMI_LOG("hdmi_drv_power_on direct to exit for forceon(%d_\n", not_switch_to_d3 );
253 return ;
254 }
255
256 cust_hdmi_power_on(true);
257 cust_hdmi_dpi_gpio_on(true);
258 //cust_hdmi_i2s_gpio_on(true);
259
260 if(txInitFlag == 0)
261 {
262 ///sii_8348_tx_init();
263 txInitFlag = 1;
264 }
265
266 goto power_on_exit;
267
268/*
269 MHL_Power(true);
270 Mask_MHL_Intr();
271
272 if(chip_inited == false)
273 {
274 if(txInitFlag == 0)
275 {
276 sii_8348_tx_init();
277 txInitFlag = 1;
278 }
279 else
280 {
281 si_mhl_tx_post_initialize(si_dev_context, false);
282 }
283
284 chip_inited = true;
285 }
286*/
287power_on_exit:
288
289 if(chip_device_id >0)
290 ret = 0;
291
292 ///Unmask_MHL_Intr();
293 HDMI_LOG("status %d, chipid: %x, ret: %d--%d\n", ReadConnectionStatus() , chip_device_id, ret, need_reset_usb_switch);
294
295 return ret;
296}
297
298void hdmi_drv_power_off(void)
299{
300
301 HDMI_FUNC();
302
303 if(not_switch_to_d3 > 0)
304 {
305 HDMI_LOG("hdmi_drv_power_off direct to exit for forceon(%d_\n", not_switch_to_d3 );
306 return ;
307 }
308
309 cust_hdmi_dpi_gpio_on(false);
310 if(audio_enable == 0)
311 cust_hdmi_i2s_gpio_on(false);
312
313 return ;
314
315 Mask_MHL_Intr();
316
317 if(ReadConnectionStatus()==1){
318 need_reset_usb_switch = true;
319 ForceSwitchToD3(si_dev_context);
320 }
321 else
322 need_reset_usb_switch = false;
323
324 cust_hdmi_power_on(false);
325 chip_inited = false;
326 return ;
327
328}
329
330
331static unsigned int pal_resulution = 0;
332void update_av_info_edid(bool audio_video, unsigned int param1, unsigned int param2)
333{
334 if(audio_video)///video infor
335 {
336 switch(param1)
337 {
338 case 0x22:
339 case 0x14:
340 pal_resulution |= SINK_1080P30;
341 break;
342 case 0x10:
343 if(packed_pixel_available(si_dev_context))
344 pal_resulution |= SINK_1080P60;
345 break;
346 case 0x4:
347 pal_resulution |= SINK_720P60;
348 break;
349 case 0x3:
350 case 0x2:
351 pal_resulution |= SINK_480P;
352 break;
353 default:
354 HDMI_LOG("param1: %d\n", param1);
355 }
356 }
357
358 return ;
359}
360unsigned int si_mhl_get_av_info()
361{
362 unsigned int temp = SINK_1080P30;
363
364 if(pal_resulution&SINK_1080P60)
365 pal_resulution &= (~temp);
366
367 return pal_resulution;
368}
369void reset_av_info()
370{
371 pal_resulution = 0;
372}
373void hdmi_GetEdidInfo(void *pv_get_info)
374{
375 HDMI_EDID_INFO_T *ptr = (HDMI_EDID_INFO_T *)pv_get_info;
376 if(ptr)
377 {
378 ptr->ui4_ntsc_resolution = 0;
379 ptr->ui4_pal_resolution = si_mhl_get_av_info();
380 if(ptr->ui4_pal_resolution == 0)
381 {
382 HDMI_LOG("MHL edid parse error \n");
383
384 if(si_dev_context && packed_pixel_available(si_dev_context))
385 ptr->ui4_pal_resolution = SINK_720P60 | SINK_1080P60 | SINK_480P;
386 else
387 ptr->ui4_pal_resolution = SINK_720P60 | SINK_1080P30 | SINK_480P;
388 }
389 }
390
391 if(si_dev_context)
392 {
393 HDMI_LOG("MHL hdmi_GetEdidInfo ntsc 0x%x,pal: 0x%x, packed: %d, parsed 0x%x\n", ptr->ui4_ntsc_resolution ,
394 ptr->ui4_pal_resolution, packed_pixel_available(si_dev_context), si_mhl_get_av_info());
395 }
396}
397
398
399extern uint8_t Cap_MAX_channel;
400extern uint16_t Cap_SampleRate;
401extern uint8_t Cap_Samplebit;
402
403int hdmi_drv_get_external_device_capablity(void)
404{
405 HDMI_LOG("Cap_MAX_channel: %d, Cap_Samplebit: %d, Cap_SampleRate: %d\n", Cap_MAX_channel, Cap_Samplebit, Cap_SampleRate);
406 int capablity = Cap_MAX_channel << 3 | Cap_SampleRate << 7 | Cap_Samplebit << 10;
407
408 if(capablity == 0)
409 {
410 capablity = HDMI_CHANNEL_2 << 3 | HDMI_SAMPLERATE_44 << 7 | HDMI_BITWIDTH_16 << 10;
411 }
412
413 return capablity;
414}
415
416const HDMI_DRIVER* HDMI_GetDriver(void)
417{
418 static const HDMI_DRIVER HDMI_DRV =
419 {
420 .set_util_funcs = hdmi_drv_set_util_funcs,
421 .get_params = hdmi_drv_get_params,
422 .init = hdmi_drv_init,
423 .enter = hdmi_drv_enter,
424 .exit = hdmi_drv_exit,
425 .suspend = hdmi_drv_suspend,
426 .resume = hdmi_drv_resume,
427 .video_config = hdmi_drv_video_config,
428 .audio_config = hdmi_drv_audio_config,
429 .video_enable = hdmi_drv_video_enable,
430 .audio_enable = hdmi_drv_audio_enable,
431 .power_on = hdmi_drv_power_on,
432 .power_off = hdmi_drv_power_off,
433 .get_state = hdmi_drv_get_state,
434 .log_enable = hdmi_drv_log_enable,
435 .getedid = hdmi_GetEdidInfo,
436 .get_external_device_capablity = hdmi_drv_get_external_device_capablity,
437 .force_on = hdmi_drv_force_on,
438 };
439
440 HDMI_FUNC();
441 return &HDMI_DRV;
442}
443/************************** ****************************************************/
444
445/************************** HAL To SmartBook****************************************/
446static void SMB_Init(void)
447{
448#ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
449 //SMARTBOOK: HID init
450 if(MHL_Connect_type == MHL_SMB_CABLE)
451 {
452 SiiHidSuspend(1);
453 }
454#endif
455 return ;
456}
457static void SMB_Denit(void)
458{
459#ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
460 if(MHL_Connect_type == MHL_SMB_CABLE)
461 {
462 SiiHidSuspend(0);
463 }
464#endif
465 return ;
466}
467static void SMB_Write_Data(uint8_t *data)
468{
469#ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
470 if(MHL_Connect_type == MHL_SMB_CABLE)
471 {
472 SiiHidWrite(data);
473 }
474#endif
475 return ;
476}
477static void SMB_HandShake_Init(void)
478{
479#ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
480 if(MHL_Connect_type == MHL_SMB_CABLE)
481 {
482 SiiHandshakeCommand(Init);
483 }
484#endif
485 return ;
486}
487/************************** *****************************************************/
488
489/************************** MHL TX Chip User Layer To HAL*******************************/
490static char* MHL_TX_Event_Print(unsigned int event)
491{
492 switch(event)
493 {
494 case MHL_TX_EVENT_CONNECTION:
495 return "MHL_TX_EVENT_CONNECTION";
496 case MHL_TX_EVENT_DISCONNECTION:
497 return "MHL_TX_EVENT_DISCONNECTION";
498 case MHL_TX_EVENT_HPD_CLEAR:
499 return "MHL_TX_EVENT_HPD_CLEAR";
500 case MHL_TX_EVENT_HPD_GOT:
501 return "MHL_TX_EVENT_HPD_GOT";
502 case MHL_TX_EVENT_DEV_CAP_UPDATE:
503 return "MHL_TX_EVENT_DEV_CAP_UPDATE";
504 case MHL_TX_EVENT_EDID_UPDATE:
505 return "MHL_TX_EVENT_EDID_UPDATE";
506 case MHL_TX_EVENT_EDID_DONE:
507 return "MHL_TX_EVENT_EDID_DONE";
508 case MHL_TX_EVENT_SMB_DATA:
509 return "MHL_TX_EVENT_SMB_DATA";
510 default:
511 HDMI_LOG("Unknow MHL TX Event Type\n");
512 return "Unknow MHL TX Event Type\n";
513 }
514}
515
516extern void hdmi_state_callback(HDMI_STATE state);
517void Notify_AP_MHL_TX_Event(unsigned int event, unsigned int event_param, void *param)
518{
519 if(event != MHL_TX_EVENT_SMB_DATA)
520 HDMI_LOG("%s, event_param: %d\n", MHL_TX_Event_Print(event), event_param);
521 switch(event)
522 {
523 case MHL_TX_EVENT_CONNECTION:
524 break;
525 case MHL_TX_EVENT_DISCONNECTION:
526 {
527 sii_mhl_connected = MHL_TX_EVENT_DISCONNECTION;
528 hdmi_state_callback(HDMI_STATE_NO_DEVICE);
529 reset_av_info();
530 SMB_Denit();
531 MHL_Connect_type = MHL_CABLE;
532 }
533 break;
534 case MHL_TX_EVENT_HPD_CLEAR:
535 {
536 sii_mhl_connected= MHL_TX_EVENT_DISCONNECTION;
537 hdmi_state_callback(HDMI_STATE_NO_DEVICE);
538 }
539 break;
540 case MHL_TX_EVENT_HPD_GOT:
541 break;
542 case MHL_TX_EVENT_DEV_CAP_UPDATE:
543 {
544 MHL_Connect_type = MHL_SMB_CABLE;
545 }
546 break;
547 case MHL_TX_EVENT_EDID_UPDATE:
548 {
549 update_av_info_edid(true, event_param, 0);
550 }
551 break;
552 case MHL_TX_EVENT_EDID_DONE:
553 {
554#ifdef HDCP_ENABLE
555 HDCP_Supported_Info = true;
556#endif
557 sii_mhl_connected = MHL_TX_EVENT_CALLBACK;
558 hdmi_state_callback(HDMI_STATE_ACTIVE);
559 SMB_Init();
560 SMB_HandShake_Init();
561 }
562 break;
563 case MHL_TX_EVENT_SMB_DATA:
564 {
565 //SMARTBOOK: get write burst command
566 SMB_Write_Data((uint8_t *)param);
567 }
568 break;
569 default:
570 return ;
571 }
572
573 return ;
574}
575/************************** ****************************************************/
576#endif