hdmi_drv.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. #if defined(CONFIG_MTK_HDMI_SUPPORT)
  2. #include <linux/kernel.h>
  3. /*#include <linux/xlog.h>*/
  4. #include <linux/module.h>
  5. #include <linux/init.h>
  6. #include <linux/fs.h>
  7. #include <linux/cdev.h>
  8. #include <linux/device.h>
  9. #include <linux/delay.h>
  10. #include <linux/kthread.h>
  11. /*#include <mtk_kpd.h>*/
  12. #include "si_timing_defs.h"
  13. #include "hdmi_drv.h"
  14. #include "smartbook.h"
  15. /*#include "hdmi_cust.h"*/
  16. /**
  17. * MHL TX Chip Driver User Layer Interface
  18. */
  19. extern struct mhl_dev_context *si_dev_context;
  20. extern void ForceSwitchToD3( struct mhl_dev_context *dev_context);
  21. extern void ForceNotSwitchToD3(void);
  22. extern int si_mhl_tx_post_initialize(struct mhl_dev_context *dev_context, bool bootup);
  23. extern void siHdmiTx_VideoSel (int vmode);
  24. extern void siHdmiTx_AudioSel (int AduioMode);
  25. extern void set_platform_bitwidth(int bitWidth);
  26. extern bool si_mhl_tx_set_path_en_I(struct mhl_dev_context *dev_context);
  27. extern bool packed_pixel_available(struct mhl_dev_context *dev_context);
  28. extern void configure_and_send_audio_info(struct mhl_dev_context *dev_context, int audio_format);
  29. //Should align to mhl_linux_tx.h
  30. #define MHL_TX_EVENT_DISCONNECTION 0x01
  31. #define MHL_TX_EVENT_CONNECTION 0x02
  32. #define MHL_TX_EVENT_SMB_DATA 0x40
  33. #define MHL_TX_EVENT_HPD_CLEAR 0x41
  34. #define MHL_TX_EVENT_HPD_GOT 0x42
  35. #define MHL_TX_EVENT_DEV_CAP_UPDATE 0x43
  36. #define MHL_TX_EVENT_EDID_UPDATE 0x44
  37. #define MHL_TX_EVENT_EDID_DONE 0x45
  38. #define MHL_TX_EVENT_CALLBACK 0x46
  39. /**
  40. * Platform Related Layer Interface
  41. */
  42. extern int HalOpenI2cDevice(char const *DeviceName, char const *DriverName);
  43. extern int32_t sii_8348_tx_init(void); //Should move to MHL TX Chip user layer
  44. /**
  45. * LOG For MHL TX Chip HAL
  46. */
  47. static size_t hdmi_log_on = true;
  48. static int txInitFlag = 0;
  49. int chip_device_id = 0;
  50. bool need_reset_usb_switch = true;
  51. #define MHL_DBG(fmt, arg...) \
  52. do { \
  53. if (hdmi_log_on) pr_debug("[HDMI_Chip_HAL]%s,%d,", __func__, __LINE__); \
  54. }while (0)
  55. #define MHL_FUNC() \
  56. do { \
  57. if(hdmi_log_on) pr_debug("[HDMI_Chip_HAL] %s\n", __func__); \
  58. }while (0)
  59. void hdmi_drv_log_enable(bool enable)
  60. {
  61. hdmi_log_on = enable;
  62. }
  63. static int not_switch_to_d3 = 0;
  64. static int audio_enable = 0;
  65. #ifndef CONFIG_MTK_LEGACY
  66. extern void i2s_gpio_ctrl(int enable);
  67. extern void dpi_gpio_ctrl(int enable);
  68. #endif
  69. void hdmi_drv_force_on(int from_uart_drv )
  70. {
  71. MHL_DBG("hdmi_drv_force_on %d\n", from_uart_drv);
  72. if(from_uart_drv == 0)
  73. ForceNotSwitchToD3();
  74. not_switch_to_d3 = 1;
  75. #ifndef CONFIG_MTK_LEGACY
  76. //gpio:uart to be impl
  77. i2s_gpio_ctrl(0);
  78. #endif
  79. }
  80. /************************** Upper Layer To HAL*********************************/
  81. static struct HDMI_UTIL_FUNCS hdmi_util = {0};
  82. static void hdmi_drv_set_util_funcs(const struct HDMI_UTIL_FUNCS *util)
  83. {
  84. memcpy(&hdmi_util, util, sizeof(struct HDMI_UTIL_FUNCS));
  85. }
  86. static char* cable_type_print(unsigned short type)
  87. {
  88. switch(type)
  89. {
  90. case HDMI_CABLE:
  91. return "HDMI_CABLE";
  92. case MHL_CABLE:
  93. return "MHL_CABLE";
  94. case MHL_SMB_CABLE:
  95. return "MHL_SMB_CABLE";
  96. case MHL_2_CABLE:
  97. return "MHL_2_CABLE";
  98. default:
  99. MHL_DBG("Unknow MHL Cable Type\n");
  100. return "Unknow MHL Cable Type\n";
  101. }
  102. }
  103. static enum HDMI_CABLE_TYPE MHL_Connect_type = MHL_CABLE;
  104. static unsigned int HDCP_Supported_Info = 0;
  105. bool MHL_3D_Support = false;
  106. int MHL_3D_format=0x00;
  107. static void hdmi_drv_get_params(struct HDMI_PARAMS *params)
  108. {
  109. char* cable_str = "";
  110. enum HDMI_VIDEO_RESOLUTION input_resolution = params->init_config.vformat;
  111. memset(params, 0, sizeof(struct HDMI_PARAMS));
  112. switch (input_resolution)
  113. {
  114. case HDMI_VIDEO_720x480p_60Hz:
  115. params->clk_pol = HDMI_POLARITY_FALLING;
  116. params->de_pol = HDMI_POLARITY_RISING;
  117. params->hsync_pol = HDMI_POLARITY_RISING;
  118. params->vsync_pol = HDMI_POLARITY_RISING;;
  119. params->hsync_pulse_width = 62;
  120. params->hsync_back_porch = 60;
  121. params->hsync_front_porch = 16;
  122. params->vsync_pulse_width = 6;
  123. params->vsync_back_porch = 30;
  124. params->vsync_front_porch = 9;
  125. params->width = 720;
  126. params->height = 480;
  127. params->input_clock = 27027;
  128. params->init_config.vformat = HDMI_VIDEO_720x480p_60Hz;
  129. break;
  130. case HDMI_VIDEO_1280x720p_60Hz:
  131. params->clk_pol = HDMI_POLARITY_FALLING;
  132. params->de_pol = HDMI_POLARITY_RISING;
  133. params->hsync_pol = HDMI_POLARITY_FALLING;
  134. params->vsync_pol = HDMI_POLARITY_FALLING;;
  135. params->hsync_pulse_width = 40;
  136. params->hsync_back_porch = 220;
  137. params->hsync_front_porch = 110;
  138. params->vsync_pulse_width = 5;
  139. params->vsync_back_porch = 20;
  140. params->vsync_front_porch = 5;
  141. params->width = 1280;
  142. params->height = 720;
  143. #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
  144. if (MHL_Connect_type == MHL_SMB_CABLE)
  145. {
  146. params->width = 1366;
  147. params->height = 768;
  148. }
  149. #endif
  150. params->input_clock = 74250;
  151. params->init_config.vformat = HDMI_VIDEO_1280x720p_60Hz;
  152. break;
  153. case HDMI_VIDEO_1920x1080p_30Hz:
  154. params->clk_pol = HDMI_POLARITY_FALLING;
  155. params->de_pol = HDMI_POLARITY_RISING;
  156. params->hsync_pol = HDMI_POLARITY_FALLING;
  157. params->vsync_pol = HDMI_POLARITY_FALLING;;
  158. params->hsync_pulse_width = 44;
  159. params->hsync_back_porch = 148;
  160. params->hsync_front_porch = 88;
  161. params->vsync_pulse_width = 5;
  162. params->vsync_back_porch = 36;
  163. params->vsync_front_porch = 4;
  164. params->width = 1920;
  165. params->height = 1080;
  166. params->input_clock = 74250;
  167. params->init_config.vformat = HDMI_VIDEO_1920x1080p_30Hz;
  168. break;
  169. case HDMI_VIDEO_1920x1080p_60Hz:
  170. params->clk_pol = HDMI_POLARITY_FALLING;
  171. params->de_pol = HDMI_POLARITY_RISING;
  172. params->hsync_pol = HDMI_POLARITY_FALLING;
  173. params->vsync_pol = HDMI_POLARITY_FALLING;;
  174. params->hsync_pulse_width = 44;
  175. params->hsync_back_porch = 148;
  176. params->hsync_front_porch = 88;
  177. params->vsync_pulse_width = 5;
  178. params->vsync_back_porch = 36;
  179. params->vsync_front_porch = 4;
  180. params->width = 1920;
  181. params->height = 1080;
  182. params->input_clock = 148500;
  183. params->init_config.vformat = HDMI_VIDEO_1920x1080p_60Hz;
  184. break;
  185. default:
  186. MHL_DBG("Unknow support resolution\n");
  187. break;
  188. }
  189. params->init_config.aformat = HDMI_AUDIO_44K_2CH;
  190. params->rgb_order = HDMI_COLOR_ORDER_RGB;
  191. params->io_driving_current = IO_DRIVING_CURRENT_2MA;
  192. params->intermediat_buffer_num = 4;
  193. params->scaling_factor = 0;
  194. params->cabletype = MHL_Connect_type;
  195. params->HDCPSupported = HDCP_Supported_Info;
  196. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  197. if(MHL_Connect_type== MHL_3D_GLASSES)
  198. params->cabletype = MHL_CABLE;
  199. params->is_3d_support = MHL_3D_Support;
  200. #endif
  201. cable_str = cable_type_print(params->cabletype);
  202. MHL_DBG("type %s-%d hdcp %d-%d\n", cable_str, MHL_Connect_type, params->HDCPSupported, HDCP_Supported_Info);
  203. }
  204. void hdmi_drv_suspend(void) {return ;}
  205. void hdmi_drv_resume(void) {return ;}
  206. static int hdmi_drv_audio_config(enum HDMI_AUDIO_FORMAT aformat, int bitWidth)
  207. {
  208. set_platform_bitwidth(bitWidth);
  209. siHdmiTx_AudioSel(aformat);
  210. configure_and_send_audio_info(si_dev_context, aformat);
  211. return 0;
  212. }
  213. static int hdmi_drv_video_enable(bool enable)
  214. {
  215. return 0;
  216. }
  217. static int hdmi_drv_audio_enable(bool enable)
  218. {
  219. MHL_DBG("[EXTD]Set_I2S_Pin, enable = %d\n", enable);
  220. //gpio:uart
  221. #ifdef CONFIG_MTK_LEGACY
  222. /*
  223. if(not_switch_to_d3 == 1)
  224. cust_hdmi_i2s_gpio_on(2);
  225. else
  226. cust_hdmi_i2s_gpio_on(enable);
  227. */
  228. #else
  229. if (enable)
  230. i2s_gpio_ctrl(1);
  231. else
  232. i2s_gpio_ctrl(0);
  233. #endif
  234. audio_enable = enable;
  235. return 0;
  236. }
  237. static int hdmi_drv_enter(void) {return 0;}
  238. static int hdmi_drv_exit(void) {return 0;}
  239. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  240. extern void si_mhl_tx_drv_video_3d_update(struct mhl_dev_context *dev_context, int video_3d);
  241. extern void si_mhl_tx_drv_video_3d(struct mhl_dev_context *dev_context, int video_3d);
  242. static int hdmi_drv_video_config(enum HDMI_VIDEO_RESOLUTION vformat, enum HDMI_VIDEO_INPUT_FORMAT vin, int vout)
  243. #else
  244. static int hdmi_drv_video_config(enum HDMI_VIDEO_RESOLUTION vformat, enum HDMI_VIDEO_INPUT_FORMAT vin, enum HDMI_VIDEO_OUTPUT_FORMAT vout)
  245. #endif
  246. {
  247. if(vformat == HDMI_VIDEO_720x480p_60Hz)
  248. {
  249. MHL_DBG("[hdmi_drv]480p\n");
  250. siHdmiTx_VideoSel(HDMI_480P60_4X3);
  251. }
  252. else if(vformat == HDMI_VIDEO_1280x720p_60Hz)
  253. {
  254. MHL_DBG("[hdmi_drv]720p\n");
  255. siHdmiTx_VideoSel(HDMI_720P60);
  256. }
  257. else if(vformat == HDMI_VIDEO_1920x1080p_30Hz)
  258. {
  259. MHL_DBG("[hdmi_drv]1080p_30 %p\n", si_dev_context);
  260. siHdmiTx_VideoSel(HDMI_1080P30);
  261. }
  262. else if(vformat == HDMI_VIDEO_1920x1080p_60Hz)
  263. {
  264. MHL_DBG("[hdmi_drv]1080p_60 %p\n", si_dev_context);
  265. siHdmiTx_VideoSel(HDMI_1080P60);
  266. }
  267. else
  268. {
  269. MHL_DBG("%s, video format not support now\n", __func__);
  270. }
  271. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  272. if(vout & HDMI_VOUT_FORMAT_3D_SBS)
  273. MHL_3D_format=VIDEO_3D_SS;
  274. else if(vout & HDMI_VOUT_FORMAT_3D_TAB)
  275. MHL_3D_format=VIDEO_3D_TB;
  276. else
  277. MHL_3D_format = VIDEO_3D_NONE;
  278. if(si_dev_context)
  279. {
  280. MHL_DBG("video format -- %d, 0x%x, %d\n", MHL_3D_Support, vout, MHL_3D_format);
  281. if(vformat < HDMI_VIDEO_RESOLUTION_NUM)
  282. {
  283. ///if(MHL_3D_Support && (MHL_3D_format > 0))
  284. si_mhl_tx_drv_video_3d(si_dev_context, MHL_3D_format);
  285. si_mhl_tx_set_path_en_I(si_dev_context);
  286. }
  287. else
  288. si_mhl_tx_drv_video_3d_update(si_dev_context, MHL_3D_format);
  289. }
  290. #else
  291. if(si_dev_context)
  292. si_mhl_tx_set_path_en_I(si_dev_context);
  293. #endif
  294. return 0;
  295. }
  296. static unsigned int sii_mhl_connected = 0;
  297. static uint8_t ReadConnectionStatus(void)
  298. {
  299. return (sii_mhl_connected == MHL_TX_EVENT_CALLBACK)? 1 : 0;
  300. }
  301. enum HDMI_STATE hdmi_drv_get_state(void)
  302. {
  303. int ret = ReadConnectionStatus();
  304. MHL_DBG("ret: %d\n", ret);
  305. if(ret == 1)
  306. return HDMI_STATE_ACTIVE;
  307. else
  308. return HDMI_STATE_NO_DEVICE;
  309. }
  310. bool chip_inited = false;
  311. static int hdmi_drv_init(void)
  312. {
  313. MHL_DBG("hdmi_drv_init, not_switch_to_d3: %d, init-%d\n", not_switch_to_d3, chip_inited);
  314. if(chip_inited == true)
  315. return 0;
  316. /*cust_hdmi_power_on(true);*/
  317. if(not_switch_to_d3 == 0)
  318. {
  319. HalOpenI2cDevice("Sil_MHL", "sii8348drv");
  320. }
  321. txInitFlag = 0;
  322. chip_inited = true;
  323. //Should be enhanced
  324. chip_device_id = 0;
  325. need_reset_usb_switch = true;
  326. MHL_DBG("hdmi_drv_init -\n" );
  327. return 0;
  328. }
  329. int hdmi_drv_power_on(void)
  330. {
  331. int ret = 1;
  332. MHL_FUNC();
  333. /*
  334. if(not_switch_to_d3 > 0)
  335. {
  336. MHL_DBG("hdmi_drv_power_on direct to exit for forceon(%d_\n", not_switch_to_d3);
  337. return ;
  338. }
  339. */
  340. #ifdef CONFIG_MTK_LEGACY
  341. /*cust_hdmi_power_on(true);*/
  342. /*cust_hdmi_dpi_gpio_on(true);*/
  343. #else
  344. dpi_gpio_ctrl(1);
  345. i2s_gpio_ctrl(1);
  346. #endif
  347. //cust_hdmi_i2s_gpio_on(true);
  348. if(txInitFlag == 0)
  349. {
  350. ///sii_8348_tx_init();
  351. txInitFlag = 1;
  352. }
  353. goto power_on_exit;
  354. /*
  355. MHL_Power(true);
  356. Mask_MHL_Intr();
  357. if(chip_inited == false)
  358. {
  359. if(txInitFlag == 0)
  360. {
  361. sii_8348_tx_init();
  362. txInitFlag = 1;
  363. }
  364. else
  365. {
  366. si_mhl_tx_post_initialize(si_dev_context, false);
  367. }
  368. chip_inited = true;
  369. }
  370. */
  371. power_on_exit:
  372. if(chip_device_id >0)
  373. ret = 0;
  374. MHL_DBG("status %d, chipid: %x, ret: %d--%d\n", ReadConnectionStatus() , chip_device_id, ret, need_reset_usb_switch);
  375. return ret;
  376. }
  377. void hdmi_drv_power_off(void)
  378. {
  379. MHL_FUNC();
  380. if(not_switch_to_d3 > 0)
  381. {
  382. MHL_DBG("hdmi_drv_power_off direct to exit for forceon(%d_\n", not_switch_to_d3 );
  383. return ;
  384. }
  385. #ifdef CONFIG_MTK_LEGACY
  386. /*cust_hdmi_dpi_gpio_on(false);*/
  387. if(audio_enable == 0)
  388. cust_hdmi_i2s_gpio_on(false);
  389. #else
  390. dpi_gpio_ctrl(0);
  391. i2s_gpio_ctrl(0);
  392. if(audio_enable == 0)
  393. i2s_gpio_ctrl(1);
  394. #endif
  395. return ;
  396. if(ReadConnectionStatus()==1){
  397. need_reset_usb_switch = true;
  398. ForceSwitchToD3(si_dev_context);
  399. }
  400. else
  401. need_reset_usb_switch = false;
  402. /*cust_hdmi_power_on(false);*/
  403. chip_inited = false;
  404. return ;
  405. }
  406. /* for otg currency leakage */
  407. void switch_mhl_to_d3(void)
  408. {
  409. if(si_dev_context)
  410. ForceSwitchToD3(si_dev_context);
  411. }
  412. static unsigned int pal_resulution = 0;
  413. void update_av_info_edid(bool audio_video, unsigned int param1, unsigned int param2)
  414. {
  415. if(audio_video)///video infor
  416. {
  417. switch(param1)
  418. {
  419. case 0x22:
  420. case 0x14:
  421. pal_resulution |= SINK_1080P30;
  422. break;
  423. case 0x10:
  424. if(packed_pixel_available(si_dev_context))
  425. pal_resulution |= SINK_1080P60;
  426. break;
  427. case 0x4:
  428. pal_resulution |= SINK_720P60;
  429. break;
  430. case 0x3:
  431. case 0x2:
  432. pal_resulution |= SINK_480P;
  433. break;
  434. default:
  435. MHL_DBG("param1: %d\n", param1);
  436. }
  437. }
  438. return ;
  439. }
  440. unsigned int si_mhl_get_av_info(void)
  441. {
  442. unsigned int temp = SINK_1080P30;
  443. if(pal_resulution&SINK_1080P60)
  444. pal_resulution &= (~temp);
  445. return pal_resulution;
  446. }
  447. void reset_av_info(void)
  448. {
  449. pal_resulution = 0;
  450. }
  451. void hdmi_GetEdidInfo(void *pv_get_info)
  452. {
  453. struct HDMI_EDID_INFO_T *ptr = (struct HDMI_EDID_INFO_T *)pv_get_info;
  454. if(ptr)
  455. {
  456. ptr->ui4_ntsc_resolution = 0;
  457. ptr->ui4_pal_resolution = si_mhl_get_av_info();
  458. if(ptr->ui4_pal_resolution == 0)
  459. {
  460. MHL_DBG("MHL edid parse error \n");
  461. if(si_dev_context && packed_pixel_available(si_dev_context))
  462. ptr->ui4_pal_resolution = SINK_720P60 | SINK_1080P60 | SINK_480P;
  463. else
  464. ptr->ui4_pal_resolution = SINK_720P60 | SINK_1080P30 | SINK_480P;
  465. }
  466. }
  467. if(si_dev_context)
  468. {
  469. MHL_DBG("MHL hdmi_GetEdidInfo ntsc 0x%x,pal: 0x%x, packed: %d, parsed 0x%x\n", ptr->ui4_ntsc_resolution ,
  470. ptr->ui4_pal_resolution, packed_pixel_available(si_dev_context), si_mhl_get_av_info());
  471. }
  472. }
  473. extern uint8_t Cap_MAX_channel;
  474. extern uint16_t Cap_SampleRate;
  475. extern uint8_t Cap_Samplebit;
  476. int hdmi_drv_get_external_device_capablity(void)
  477. {
  478. int capablity = 0;
  479. MHL_DBG("Cap_MAX_channel: %d, Cap_Samplebit: %d, Cap_SampleRate: %d\n", Cap_MAX_channel, Cap_Samplebit, Cap_SampleRate);
  480. capablity = Cap_MAX_channel << 3 | Cap_SampleRate << 7 | Cap_Samplebit << 10;
  481. if(capablity == 0)
  482. {
  483. capablity = HDMI_CHANNEL_2 << 3 | HDMI_SAMPLERATE_44 << 7 | HDMI_BITWIDTH_16 << 10;
  484. }
  485. return capablity;
  486. }
  487. #define HDMI_MAX_INSERT_CALLBACK 10
  488. static CABLE_INSERT_CALLBACK hdmi_callback_table[HDMI_MAX_INSERT_CALLBACK];
  489. void hdmi_register_cable_insert_callback(CABLE_INSERT_CALLBACK cb)
  490. {
  491. int i = 0;
  492. for (i = 0; i < HDMI_MAX_INSERT_CALLBACK; i++) {
  493. if (hdmi_callback_table[i] == cb)
  494. break;
  495. }
  496. if (i < HDMI_MAX_INSERT_CALLBACK)
  497. return;
  498. for (i = 0; i < HDMI_MAX_INSERT_CALLBACK; i++) {
  499. if (hdmi_callback_table[i] == NULL)
  500. break;
  501. }
  502. if (i == HDMI_MAX_INSERT_CALLBACK) {
  503. MHL_DBG("not enough mhl callback entries for module\n");
  504. return;
  505. }
  506. hdmi_callback_table[i] = cb;
  507. MHL_DBG("callback: %p,i: %d\n", hdmi_callback_table[i], i);
  508. }
  509. void hdmi_unregister_cable_insert_callback(CABLE_INSERT_CALLBACK cb)
  510. {
  511. int i;
  512. for (i=0; i<HDMI_MAX_INSERT_CALLBACK; i++)
  513. {
  514. if (hdmi_callback_table[i] == cb)
  515. {
  516. MHL_DBG("unregister cable insert callback: %p, i: %d\n", hdmi_callback_table[i], i);
  517. hdmi_callback_table[i] = NULL;
  518. break;
  519. }
  520. }
  521. if (i == HDMI_MAX_INSERT_CALLBACK)
  522. {
  523. MHL_DBG("Try to unregister callback function 0x%lx which was not registered\n",(unsigned long int)cb);
  524. return;
  525. }
  526. }
  527. void hdmi_invoke_cable_callbacks(enum HDMI_STATE state)
  528. {
  529. int i = 0, j = 0;
  530. for (i=0; i<HDMI_MAX_INSERT_CALLBACK; i++) // 0 is for external display
  531. {
  532. if(hdmi_callback_table[i])
  533. {
  534. j = i;
  535. }
  536. }
  537. if (hdmi_callback_table[j])
  538. {
  539. MHL_DBG("callback: %p, state: %d, j: %d\n", hdmi_callback_table[j], state, j);
  540. hdmi_callback_table[j](state);
  541. }
  542. }
  543. /************************** ****************************************************/
  544. const struct HDMI_DRIVER* HDMI_GetDriver(void)
  545. {
  546. static const struct HDMI_DRIVER HDMI_DRV =
  547. {
  548. .set_util_funcs = hdmi_drv_set_util_funcs,
  549. .get_params = hdmi_drv_get_params,
  550. .init = hdmi_drv_init,
  551. .enter = hdmi_drv_enter,
  552. .exit = hdmi_drv_exit,
  553. .suspend = hdmi_drv_suspend,
  554. .resume = hdmi_drv_resume,
  555. .video_config = hdmi_drv_video_config,
  556. .audio_config = hdmi_drv_audio_config,
  557. .video_enable = hdmi_drv_video_enable,
  558. .audio_enable = hdmi_drv_audio_enable,
  559. .power_on = hdmi_drv_power_on,
  560. .power_off = hdmi_drv_power_off,
  561. .get_state = hdmi_drv_get_state,
  562. .log_enable = hdmi_drv_log_enable,
  563. .getedid = hdmi_GetEdidInfo,
  564. .get_external_device_capablity = hdmi_drv_get_external_device_capablity,
  565. .register_callback = hdmi_register_cable_insert_callback,
  566. .unregister_callback = hdmi_unregister_cable_insert_callback,
  567. .force_on = hdmi_drv_force_on,
  568. };
  569. MHL_FUNC();
  570. return &HDMI_DRV;
  571. }
  572. /************************** ****************************************************/
  573. /************************** HAL To SmartBook****************************************/
  574. static void SMB_Init(void)
  575. {
  576. #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
  577. //SMARTBOOK: HID init
  578. if(MHL_Connect_type == MHL_SMB_CABLE)
  579. {
  580. SiiHidSuspend(1);
  581. }
  582. #endif
  583. return ;
  584. }
  585. static void SMB_Denit(void)
  586. {
  587. #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
  588. if(MHL_Connect_type == MHL_SMB_CABLE)
  589. {
  590. SiiHidSuspend(0);
  591. }
  592. #endif
  593. return ;
  594. }
  595. static void SMB_Write_Data(uint8_t *data)
  596. {
  597. #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
  598. if(MHL_Connect_type == MHL_SMB_CABLE)
  599. {
  600. SiiHidWrite(data);
  601. }
  602. #endif
  603. return ;
  604. }
  605. static void SMB_HandShake_Init(void)
  606. {
  607. #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
  608. if(MHL_Connect_type == MHL_SMB_CABLE)
  609. {
  610. SiiHandshakeCommand(Init);
  611. }
  612. #endif
  613. return ;
  614. }
  615. /************************** *****************************************************/
  616. /************************** MHL TX Chip User Layer To HAL*******************************/
  617. static char* MHL_TX_Event_Print(unsigned int event)
  618. {
  619. switch(event)
  620. {
  621. case MHL_TX_EVENT_CONNECTION:
  622. return "MHL_TX_EVENT_CONNECTION";
  623. case MHL_TX_EVENT_DISCONNECTION:
  624. return "MHL_TX_EVENT_DISCONNECTION";
  625. case MHL_TX_EVENT_HPD_CLEAR:
  626. return "MHL_TX_EVENT_HPD_CLEAR";
  627. case MHL_TX_EVENT_HPD_GOT:
  628. return "MHL_TX_EVENT_HPD_GOT";
  629. case MHL_TX_EVENT_DEV_CAP_UPDATE:
  630. return "MHL_TX_EVENT_DEV_CAP_UPDATE";
  631. case MHL_TX_EVENT_EDID_UPDATE:
  632. return "MHL_TX_EVENT_EDID_UPDATE";
  633. case MHL_TX_EVENT_EDID_DONE:
  634. return "MHL_TX_EVENT_EDID_DONE";
  635. case MHL_TX_EVENT_SMB_DATA:
  636. return "MHL_TX_EVENT_SMB_DATA";
  637. default:
  638. MHL_DBG("Unknow MHL TX Event Type\n");
  639. return "Unknow MHL TX Event Type\n";
  640. }
  641. }
  642. void Notify_AP_MHL_TX_Event(unsigned int event, unsigned int event_param, void *param)
  643. {
  644. char* event_str = "";
  645. event_str = MHL_TX_Event_Print(event);
  646. if(event != MHL_TX_EVENT_SMB_DATA)
  647. MHL_DBG("%s, event_param: %d\n", event_str, event_param);
  648. switch(event)
  649. {
  650. case MHL_TX_EVENT_CONNECTION:
  651. break;
  652. case MHL_TX_EVENT_DISCONNECTION:
  653. {
  654. sii_mhl_connected = MHL_TX_EVENT_DISCONNECTION;
  655. hdmi_invoke_cable_callbacks(HDMI_STATE_NO_DEVICE);
  656. reset_av_info();
  657. SMB_Denit();
  658. MHL_Connect_type = MHL_CABLE;
  659. }
  660. break;
  661. case MHL_TX_EVENT_HPD_CLEAR:
  662. {
  663. sii_mhl_connected= MHL_TX_EVENT_DISCONNECTION;
  664. hdmi_invoke_cable_callbacks(HDMI_STATE_NO_DEVICE);
  665. }
  666. break;
  667. case MHL_TX_EVENT_HPD_GOT:
  668. break;
  669. case MHL_TX_EVENT_DEV_CAP_UPDATE:
  670. {
  671. #ifdef CONFIG_MTK_HDMI_3D_SUPPORT
  672. if(event_param == 0xBA)
  673. MHL_Connect_type = MHL_3D_GLASSES;
  674. else
  675. #endif
  676. MHL_Connect_type = MHL_SMB_CABLE;
  677. }
  678. break;
  679. case MHL_TX_EVENT_EDID_UPDATE:
  680. {
  681. update_av_info_edid(true, event_param, 0);
  682. }
  683. break;
  684. case MHL_TX_EVENT_EDID_DONE:
  685. {
  686. ///#ifdef HDCP_ENABLE
  687. if(chip_device_id == 0x8346)
  688. HDCP_Supported_Info = 140; ///HDCP 1.4
  689. ///#endif
  690. sii_mhl_connected = MHL_TX_EVENT_CALLBACK;
  691. hdmi_invoke_cable_callbacks(HDMI_STATE_ACTIVE);
  692. SMB_Init();
  693. SMB_HandShake_Init();
  694. }
  695. break;
  696. case MHL_TX_EVENT_SMB_DATA:
  697. {
  698. //SMARTBOOK: get write burst command
  699. SMB_Write_Data((uint8_t *)param);
  700. }
  701. break;
  702. default:
  703. return ;
  704. }
  705. return ;
  706. }
  707. /************************** ****************************************************/
  708. #endif