cbus_app.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. //***************************************************************************
  2. //!file app_cbus.c
  3. //!brief Wraps board and device functions for the CBUS component
  4. // and the application
  5. //
  6. //***************************************************************************/
  7. #include <linux/kernel.h> /* printk */
  8. #include <linux/string.h>
  9. #include "drv_types.h"
  10. #include "cbus_app.h"
  11. #include "cbus_mid.h"
  12. #include "cbus_drv.h"
  13. #include <drv2kmf.h>
  14. #include <drv_event.h>
  15. #include "../hdmi_hw.h"
  16. #include "../hdmi_cfg.h"
  17. #include "../../../module_include/drv_hdmi_internal.h"
  18. //#include "../hdmi_hpd.h"
  19. #include "../hdmi_notice.h"
  20. #include "../sysreg.h"
  21. #include "../hdmi_time.h"
  22. #include "../hdmi_processing.h"
  23. //#include <linux/string.h>
  24. //#include "pin_config.h"
  25. #include "../../../module_include/drv_gpio.h"
  26. //#include "drivers/drv_hdmi.h"
  27. //#include "pin_allocator.h"
  28. //------------------------------------------------------------------------------
  29. // Module variables
  30. //------------------------------------------------------------------------------
  31. static CBUS_APP_FSM_STATE_e eCbusAppState = CBUS_APP_FSM_UNATTACHED, eCbusAppNextState = CBUS_APP_FSM_UNATTACHED;
  32. static UINT32 HPDWaitConnectedCnt = 0;
  33. static UINT32 WaitDiscvCnt = 0;
  34. static MHLAppInstanceData_t MHLAppInstanceData=
  35. {
  36. 0, // statusFlags
  37. // CBUS App-specific
  38. FALSE, // discvDetect;
  39. FALSE, //cbusCableSense
  40. FALSE, //Cbus connected
  41. };
  42. MHLAppInstanceData_t *pMHLApp = &MHLAppInstanceData;
  43. void CbusAppInitialize(void)
  44. {
  45. eCbusAppNextState = CBUS_APP_FSM_UNATTACHED;
  46. }
  47. //------------------------------------------------------------------------------
  48. // Function: CbusAppProcessRecvRcpMsg
  49. // Description: Process the passed RCP message.
  50. // Returns: The RCPK status code.
  51. //------------------------------------------------------------------------------
  52. static UINT8 CbusAppProcessRecvRcpMsg(MHL_RCP_CMD_e rcpData)
  53. {
  54. MHL_RCPE_STATUS_e rcpkStatus = MHL_MSC_MSG_RCP_NO_ERROR;
  55. mhldbg("[%s] RCP Key Code: 0x%02X\n", __FUNCTION__, (INT32)rcpData);
  56. switch ( rcpData )
  57. {
  58. case MHL_RCP_CMD_SELECT:
  59. printk("[MHL]SELECT received\n" );
  60. break;
  61. case MHL_RCP_CMD_UP:
  62. printk("[MHL]UP received\n" );
  63. break;
  64. case MHL_RCP_CMD_DOWN:
  65. printk("[MHL]DOWN received\n" );
  66. break;
  67. case MHL_RCP_CMD_ROOT_MENU:
  68. printk("[MHL]ROOT_MENU received\n" );
  69. break;
  70. case MHL_RCP_CMD_EXIT:
  71. printk("[MHL]EXIT received\n" );
  72. break;
  73. case MHL_RCP_CMD_VOL_UP:
  74. printk("[MHL]VOL_UP received\n" );
  75. break;
  76. case MHL_RCP_CMD_VOL_DOWN:
  77. printk("[MHL]VOL_DOWN received\n" );
  78. break;
  79. default:
  80. printk("[MHL] un-support RCP key received 0x%x\n", rcpData);
  81. rcpkStatus = MHL_MSC_MSG_INEFFECTIVE_KEY_CODE;
  82. break;
  83. }
  84. if ( rcpkStatus == MHL_MSC_MSG_RCP_NO_ERROR )
  85. {
  86. noticekmf(KMF2UMF_EVID_HDMI, KMF2UMF_EVTYPE_HDMI_MHL_RCP_CMD, (UINT8 *)&rcpData, sizeof(MHL_RCP_CMD_e));
  87. }
  88. return( rcpkStatus );
  89. }
  90. //------------------------------------------------------------------------------
  91. // Function: CbusAppProcessRecvRapMsg
  92. // Description: Process the passed RAP message.
  93. // Returns: The RAPK status code.
  94. //------------------------------------------------------------------------------
  95. static MHL_RAPE_STATUS_e CbusAppProcessRecvRapMsg(MHL_RAP_SUBCMD_e rapData)
  96. {
  97. MHL_RAPE_STATUS_e rapkStatus = MHL_MSC_MSG_RAP_NO_ERROR;
  98. mhldbg("[%s] RAP Key Code: 0x%02X\n", __FUNCTION__, (INT32)rapData);
  99. switch ( rapData )
  100. {
  101. case MHL_RAP_CMD_POLL:
  102. mhldbg("POLL received\n" );
  103. break;
  104. case MHL_RAP_CONTENT_ON:
  105. mhldbg("Change TO CONTENT_ON STATE received\n" );
  106. HDMI_NoticeHandler(HDMINOTICE_MHL_CONTENT_ON, "MHL_RAP_CONTENT_ON");
  107. break;
  108. case MHL_RAP_CONTENT_OFF:
  109. mhldbg("Change TO CONTENT_OFF STATE received\n" );
  110. HDMI_NoticeHandler(HDMINOTICE_MHL_CONTENT_OFF, "MHL_RAP_CONTENT_OFF");
  111. break;
  112. default:
  113. rapkStatus = MHL_MSC_MSG_RAP_UNRECOGNIZED_ACT_CODE;
  114. mhldbg("Action Code not recognized !! \n" );
  115. break;
  116. }
  117. return( rapkStatus );
  118. }
  119. //------------------------------------------------------------------------------
  120. // Function: CbusAppProcessPrivateMessage
  121. // Description: Get the result of the last message sent and use it appropriately
  122. // or process a request from the connected device.
  123. // Parameters: channel - CBUS channel that has message data for us.
  124. //------------------------------------------------------------------------------
  125. static void CbusAppProcessPrivateMessage(void)
  126. {
  127. UINT8 status;
  128. //cbus_req_t cmdRequest;
  129. UINT8 bCmdType, bData;
  130. //CbusMidRequestDataGet( &cmdRequest);
  131. if(CbusMidRequestDataGet( &bCmdType, &bData) == ERROR_INVALID)
  132. return;
  133. //mhldbg("[%s] received 0x%x 0x%x\n", __FUNCTION__, bCmdType, bData);
  134. switch ( bCmdType )
  135. {
  136. case MHL_MSC_MSG_RCP:
  137. /* Acknowledge receipt of command and process it. Note that */
  138. /* we could send the ack before processing anything, because it */
  139. /* is an indicator that the command was properly received, not */
  140. /* that it was executed, however, we use one function to parse */
  141. /* the command for errors AND for processing. The only thing we */
  142. /* must do is make sure that the processing does not exceed the */
  143. /* ACK response time limit. */
  144. status = CbusAppProcessRecvRcpMsg( bData );
  145. //RCP ACK by HW
  146. //CbusRcpMessageAck(status, cmdRequest.offsetData );
  147. break;
  148. case MHL_MSC_MSG_RCPK:
  149. break;
  150. case MHL_MSC_MSG_RCPE:
  151. break;
  152. case MHL_MSC_MSG_RAP:
  153. status = CbusAppProcessRecvRapMsg( bData );
  154. CbusMidRapMessageAck(status );
  155. break;
  156. case MHL_MSC_MSG_RAPK:
  157. break;
  158. default:
  159. break;
  160. }
  161. }
  162. //------------------------------------------------------------------------------
  163. // Function: CbusAppDeviceInit
  164. // Description: Perform any board-level initialization required at the same
  165. // time as CBUS component initialization
  166. // Parameters: none
  167. // Returns: none
  168. //------------------------------------------------------------------------------
  169. void CbusAppDeviceInit(void)
  170. {
  171. mhldbg("[%s]\n", __FUNCTION__);
  172. CbusAppInitialize();
  173. CbusMidInitialize();
  174. CbusDrvInitialize();
  175. }
  176. void DRV_MHL_GetMHLAppInstanceData(MHLAppInstanceData_t * pMHLdata)
  177. {
  178. if(NULL == pMHLdata)
  179. return;
  180. memset(pMHLdata,0x0,sizeof(MHLAppInstanceData_t));
  181. memcpy(pMHLdata,pMHLApp,sizeof(MHLAppInstanceData_t));
  182. mhldbg("[%s] MHLConnected: %d \n", __FUNCTION__,pMHLApp->cbusConnected);
  183. }
  184. //------------------------------------------------------------------------------
  185. // Function: CbusAppTask
  186. // Description: Wrapper for the CBUS Component at the application level
  187. // Parameters: none
  188. // Returns: none
  189. //------------------------------------------------------------------------------
  190. void CbusAppTask(void)
  191. {
  192. // UINT8 status;
  193. BOOL fCbusConnected=FALSE;
  194. // Check for any interrupt.
  195. CbusDrvProcessInterrupts();
  196. MHLTaskInterruptMonitor();
  197. /* Monitor all CBUS channels. */
  198. CbusMidHandler(); // Monitor CBUS interrupts.
  199. /* do something at changing state once */
  200. if(eCbusAppState != eCbusAppNextState)
  201. {
  202. mhldbg("[%s] state:%d -> %d\n", __FUNCTION__, eCbusAppState, eCbusAppNextState);
  203. switch(eCbusAppNextState)
  204. {
  205. case CBUS_APP_FSM_UNATTACHED:
  206. CbusMidInitialize();
  207. if(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==0)
  208. {
  209. MHLTaskCableDetect(FALSE);
  210. fCbusConnected=FALSE;
  211. HPDWaitConnectedCnt=0;
  212. WaitDiscvCnt =0;
  213. }
  214. pMHLApp->cbusConnected =fCbusConnected ;
  215. noticekmf(KMF2UMF_EVID_HDMI, KMF2UMF_EVTYPE_HDMI_MHL_CONNECTED, &fCbusConnected, sizeof(BOOL));
  216. break;
  217. case CBUS_APP_FSM_ATTATCHED:
  218. MHLTaskCableDetect(TRUE);
  219. break;
  220. case CBUS_APP_FSM_CONNECTED:
  221. CbusMidSetDevCapReadyBit(FALSE);
  222. fCbusConnected=TRUE;
  223. HPDWaitConnectedCnt=0;
  224. pMHLApp->cbusConnected =fCbusConnected ;
  225. noticekmf(KMF2UMF_EVID_HDMI, KMF2UMF_EVTYPE_HDMI_MHL_CONNECTED, &fCbusConnected, sizeof(BOOL));
  226. mhldbg("[%s] KMF2UMF_EVTYPE_HDMI_MHL_CONNECTED :%d\n", __FUNCTION__ ,fCbusConnected);
  227. /* Remove no signal timer */
  228. hdmi_signal_check_stop();
  229. break;
  230. case CBUS_APP_FSM_PATH_ENABLED:
  231. break;
  232. default:
  233. break;
  234. }
  235. eCbusAppState = eCbusAppNextState;
  236. }
  237. if (CbusMidGet_HPD_Status()==FALSE)
  238. {
  239. if((eCbusAppState >= CBUS_APP_FSM_CONNECTED) && (pMHLApp->cbusCableSense == TRUE))
  240. {
  241. HPDWaitConnectedCnt++;
  242. }
  243. if(HPDWaitConnectedCnt>100)// *10ms
  244. {
  245. mhldbg("[%s] CbusMidSendCommand(MHL_SET_HPD)\n", __FUNCTION__);
  246. CbusMidSendCommand(MHL_SET_HPD);
  247. HPDWaitConnectedCnt=0;
  248. }
  249. }
  250. else
  251. {
  252. HPDWaitConnectedCnt=0;
  253. }
  254. /* 1. check status to change state machine
  255. 2. check received RCP & RAP after PATH_EN*/
  256. switch(eCbusAppState)
  257. {
  258. case CBUS_APP_FSM_UNATTACHED:
  259. if(pMHLApp->cbusCableSense == TRUE)
  260. eCbusAppNextState = CBUS_APP_FSM_ATTATCHED;
  261. break;
  262. case CBUS_APP_FSM_ATTATCHED: //have CD_SENSE
  263. if(WaitDiscvCnt<=50)// *10ms
  264. {
  265. mhldbg("WaitDiscvCnt=%d.\n",WaitDiscvCnt);
  266. if(WaitDiscvCnt==50)
  267. {
  268. mhldbg("WaitDiscvCnt=%d=>TOGGLE MHL_VbusCtrl.\n",WaitDiscvCnt);
  269. MHL_VbusCtrl(VBUS_DISABLE);
  270. HDMI_DelayMs(500);
  271. MHL_VbusCtrl(VBUS_ENABLE);
  272. }
  273. WaitDiscvCnt++;
  274. }
  275. break;
  276. case CBUS_APP_FSM_CONNECTED: //got discovery pulse
  277. if(CbusMidSendPathEn_RcvdAck())
  278. {
  279. eCbusAppNextState = CBUS_APP_FSM_PATH_ENABLED;
  280. CbusMidGetSrcDevCap(TRUE);//Get source's device capability
  281. }
  282. else
  283. {
  284. if((CbusMidGetDevCapReadyBit() == FALSE) && (DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT))
  285. CbusMidSendDcapRdyMsg(); //send DCAP_CHG DCAP_RDY PATH_EN
  286. }
  287. break;
  288. case CBUS_APP_FSM_PATH_ENABLED: //source sent PATH_EN
  289. //source's device capability changed, fetch it
  290. if(CbusDrvDevCapChangedGet() == TRUE)
  291. {
  292. CbusMidGetSrcDevCap(TRUE);
  293. }
  294. else
  295. {
  296. CbusMidGetSrcDevCap(FALSE);
  297. }
  298. //process received RCP or RAP command
  299. CbusAppProcessPrivateMessage();
  300. break;
  301. default:
  302. break;
  303. }
  304. if((pMHLApp->discvDetect == TRUE) && (eCbusAppState != CBUS_APP_FSM_UNATTACHED))
  305. {
  306. eCbusAppNextState = CBUS_APP_FSM_CONNECTED;
  307. pMHLApp->discvDetect = FALSE;
  308. }
  309. /* if CableDetect is False, change to UNATTACHED state */
  310. if((eCbusAppState != CBUS_APP_FSM_UNATTACHED) && (pMHLApp->cbusCableSense == FALSE))
  311. eCbusAppNextState = CBUS_APP_FSM_UNATTACHED;
  312. }
  313. //------------------------------------------------------------------------------
  314. // Function: MHLTaskCableDetect
  315. // Description: MHLCableDetect at the application level
  316. // Parameters: none
  317. // Returns: none
  318. //------------------------------------------------------------------------------
  319. extern BOOL HAVE_MHL_ADOPTER_ID;
  320. void MHLTaskCableDetect(BOOL fCdSense)
  321. {
  322. if (fCdSense)//(MID_GPIO_GetGPIOInputLevel(GPIO_MHL_CD_SENSE))//Bryan@2013.0403 Need Config GPIO for MHL in IFH118
  323. {
  324. mhldbg("MHL cable connect is TRUE.\n");
  325. mhldbg("Cbus Reset Discovery Logic" );
  326. //CbusMidSetDevCapReadyBit(FALSE );
  327. HDMI_MHL_CABLE_IN(TRUE);
  328. #if 0
  329. /* Turn VBUS ON */
  330. if( MHL_ADOPTER_ID_Check()== FALSE)
  331. {
  332. mhldbg("=>TOGGLE MHL_VbusCtrl.\n");
  333. MHL_VbusCtrl(VBUS_DISABLE);
  334. HDMI_DelayMs(500);
  335. }
  336. #endif
  337. MHL_VbusCtrl(VBUS_ENABLE);
  338. #ifdef CONFIG_HDMI_MHL_PORT
  339. if( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)
  340. {
  341. //CbusMhlHpdSetState(CbusHPD_TOGGLE);//Bryan@20140506 Marked for MHL CTS 4.3.17.2
  342. HDMI_MHL_RxSense_Term_Debug(FALSE); //auto HDMI or MHL mode)
  343. if(CONFIG_HDMI_MHL_PORT==0)
  344. {
  345. //hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_HIGH);
  346. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_A, FALSE);
  347. }
  348. else if(CONFIG_HDMI_MHL_PORT==1)
  349. {
  350. //hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_HIGH);
  351. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_B, FALSE);
  352. }
  353. }
  354. else
  355. {
  356. HDMI_MHL_RxSense_Term_Debug(TRUE);
  357. }
  358. #endif
  359. }
  360. else
  361. {
  362. mhldbg("MHL cable connect is FALSE.\n");
  363. if(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==0)
  364. {
  365. mhldbg("=>MHL_VbusCtrl(VBUS_DISABLE).\n");
  366. MHL_VbusCtrl(VBUS_DISABLE);
  367. }
  368. HDMI_MHL_CABLE_IN(FALSE);
  369. #ifdef CONFIG_HDMI_MHL_PORT
  370. if( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)
  371. {
  372. HDMI_Set_PLL_Mode(HDMI_PLL_MODE_HDMI_ENABLE);
  373. HDMI_MHL_RxSense_Term_Debug(TRUE); //force HDMI mode for debug(not MHL mode)
  374. #ifdef HDMI_HPD_USE_1K_OHM
  375. if(CONFIG_HDMI_MHL_PORT==0)
  376. {
  377. //hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW);
  378. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_A, TRUE);
  379. }
  380. else if(CONFIG_HDMI_MHL_PORT==1)
  381. {
  382. //hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW);
  383. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_B, TRUE);
  384. }
  385. #endif
  386. }
  387. #endif
  388. }
  389. noticekmf(KMF2UMF_EVID_HDMI, KMF2UMF_EVTYPE_HDMI_MHL_PLUG_STATE, &fCdSense, sizeof(BOOL));
  390. }
  391. //-------------------------------------------------------------------------------------------------
  392. //! @brief Monitors interrupts and notifies components that have received
  393. //! an interrupt.
  394. //-------------------------------------------------------------------------------------------------
  395. void MHLTaskInterruptMonitor(void)
  396. {
  397. CBUS_DRV_STATUS_e statusFlags;
  398. statusFlags =CbusDrvStatus();
  399. if ( statusFlags & CBUS_INT )// CBUS_INT
  400. {
  401. if ( statusFlags & CBUS_DISCV_INT )// CBUS_DISCV_INT
  402. {
  403. printk("[MHL]** CBUS_DISCV_INT **\n");
  404. pMHLApp->discvDetect=TRUE;
  405. eCbusAppState= 0;
  406. }
  407. if ( statusFlags & CBUS_ATTACH_INT )// CBUS_ATTACH_INT
  408. {
  409. printk("[MHL]** CBUS_ATTACH_INT **\n");
  410. pMHLApp->cbusCableSense = TRUE;
  411. }
  412. else if ( statusFlags & CBUS_DEATCH_INT )// CBUS_DEATCH_INT
  413. {
  414. printk("[MHL]** CBUS_DEATCH_INT **\n");
  415. HAVE_MHL_ADOPTER_ID =FALSE;
  416. pMHLApp->cbusCableSense = FALSE;
  417. }
  418. }
  419. if((pMHLApp->cbusCableSense = TRUE)&&(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==0))
  420. {
  421. HAVE_MHL_ADOPTER_ID =FALSE;
  422. pMHLApp->cbusCableSense = FALSE;
  423. }
  424. }