cbus_mid.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. //***************************************************************************
  2. //!file mid_cbus.c
  3. //!brief
  4. //
  5. //***************************************************************************/
  6. #include <linux/kernel.h> /* printk */
  7. #include <linux/string.h>
  8. #include "cbus_mid.h"
  9. #include "cbus_drv.h"
  10. #include "cbus_debug.h"
  11. #include "../hdmi_cfg.h"
  12. #include "drv_hdmi_external.h"
  13. #include "../hdmi_hw.h"
  14. #include <drv2kmf.h>
  15. #include <drv_event.h>
  16. #include "../hdmi_notice.h"
  17. #include "../hdmi_time.h"
  18. #include "../sysreg.h"
  19. #include "../../../module_include/drv_hdmi_internal.h"
  20. //------------------------------------------------------------------------------
  21. // CBUS Component Instance Data
  22. //------------------------------------------------------------------------------
  23. #define CH_ACTIVE_INDEX (pMidCbus->chState.activeIndex)
  24. #define CH_NEXT_INDEX ((pMidCbus->chState.activeIndex + 1) % CBUS_MAX_COMMAND_QUEUE)
  25. //------------------------------------------------------------------------------
  26. // CBUS Instance Data
  27. //------------------------------------------------------------------------------
  28. CbusMidInstanceData_t cbusInstance[NUM_CBUS];
  29. CbusMidInstanceData_t *pMidCbus = &cbusInstance[0];
  30. //------------------------------------------------------------------------------
  31. // CBUS Global Data
  32. //------------------------------------------------------------------------------
  33. #define DEV_CAP_OFFSET_ARRAY_SIZE 9
  34. static const UINT8 bGetDevCapOffsetArray[DEV_CAP_OFFSET_ARRAY_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e};
  35. //------------------------------------------------------------------------------
  36. // Function: CbusMidRequestStatus
  37. // Description: Return the status of the message currently in process, if any.
  38. // Parameters:
  39. // Returns: CBUS_REQ_IDLE, CBUS_REQ_PENDING, CBUS_REQ_SENT, or CBUS_REQ_RECEIVED
  40. //------------------------------------------------------------------------------
  41. CBUS_REQ_e CbusMidRequestStatus(void)
  42. {
  43. return(pMidCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus);
  44. }
  45. //------------------------------------------------------------------------------
  46. // Function: CbusMidRequestSetStatus
  47. // Description: Set the active request to the specified state
  48. // Parameters:
  49. //------------------------------------------------------------------------------
  50. void CbusMidRequestSetStatus(CBUS_REQ_e newState)
  51. {
  52. pMidCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = newState;
  53. }
  54. //------------------------------------------------------------------------------
  55. // Function: CbusMidRequestDataGet
  56. // Description: Return a copy of the currently active request structure
  57. // Parameters: pbCmdType: return received MSC Command Type
  58. // pbData: return received MSC Command data
  59. // Returns: none
  60. //------------------------------------------------------------------------------
  61. UINT8 CbusMidRequestDataGet(UINT8 *pbCmdType, UINT8 *pbData)
  62. {
  63. if(CbusDrvMSCSubDataGet(pbCmdType, pbData) == FALSE) //if no received sub command
  64. {
  65. return ERROR_INVALID;
  66. }
  67. //mhldbg("[%s] received MSC SubCmd 0x%x 0x%x\n", __FUNCTION__, *pbCmdType, *pbData);
  68. return CBUS_SUCCESS;
  69. }
  70. //------------------------------------------------------------------------------
  71. // Function: CbusMidChannelConnected
  72. // Description: Return the CBUS channel connected status for this channel.
  73. // Returns: TRUE if connected.
  74. // FALSE if disconnected.
  75. //------------------------------------------------------------------------------
  76. BOOL CbusMidChannelConnected(void)
  77. {
  78. return(pMidCbus->chState.connected);
  79. }
  80. //------------------------------------------------------------------------------
  81. // Function: CbusMidSendNextInQueue
  82. // Description: Starting at the current active index, send the next pending
  83. // entry, if any
  84. //------------------------------------------------------------------------------
  85. static INT32 CbusMidSendNextInQueue(void)
  86. {
  87. INT32 result = CBUS_SUCCESS;
  88. INT32 nextIndex = 0, endIndex = (CH_ACTIVE_INDEX+CBUS_MAX_COMMAND_QUEUE-1)%CBUS_MAX_COMMAND_QUEUE;
  89. nextIndex =CH_ACTIVE_INDEX;
  90. while(1)
  91. {
  92. if(pMidCbus->chState.request[ nextIndex].reqStatus == CBUS_REQ_PENDING)
  93. break;
  94. if(nextIndex == endIndex) // Searched whole queue, no pending messages
  95. {
  96. return(CBUS_SUCCESS); // No pending messages, return success
  97. }
  98. nextIndex =(nextIndex ==(CBUS_MAX_COMMAND_QUEUE - 1))? 0 :(nextIndex + 1);
  99. }
  100. //CbusMidPrintChannelInfo(__FUNCTION__, __LINE__);
  101. mhldbg("[%s] index:%d cmd:0x%x offset: 0x%x\n", __FUNCTION__, nextIndex, pMidCbus->chState.request[ nextIndex].command, pMidCbus->chState.request[ nextIndex].offsetData);
  102. // Found a pending message, send it out
  103. if(CbusDrvWriteCommand(&pMidCbus->chState.request[ nextIndex]))
  104. {
  105. pMidCbus->chState.request[nextIndex].reqStatus = CBUS_REQ_SENT;
  106. pMidCbus->chState.state = CBUS_SENT_WAIT_RESPONSE;
  107. pMidCbus->chState.lastSendTime = HDMI_GetSysTime();
  108. pMidCbus->chState.sendNextWaitTime = 0; //reset wait time
  109. if(pMidCbus->chState.request[CH_ACTIVE_INDEX].command == MHL_CLR_HPD)
  110. {
  111. pMidCbus->chState.sendNextWaitTime = CBUS_HPD_WAIT_TIME;
  112. }
  113. }
  114. else
  115. {
  116. result = ERROR_WRITE_FAILED;
  117. }
  118. //CbusMidPrintChannelInfo(__FUNCTION__, __LINE__);
  119. return(result);
  120. }
  121. //------------------------------------------------------------------------------
  122. // Function: CbusMidResetToIdle
  123. // Description: Set the specified channel state to IDLE. Clears any messages that
  124. // are in progress or queued. Usually used if a channel connection
  125. // changed or the channel heartbeat has been lost.
  126. //------------------------------------------------------------------------------
  127. static void CbusMidResetToIdle(void)
  128. {
  129. UINT8 queueIndex;
  130. mhldbg("[%s]\n", __FUNCTION__);
  131. pMidCbus->chState.state = CBUS_IDLE;
  132. for(queueIndex = 0; queueIndex < CBUS_MAX_COMMAND_QUEUE; queueIndex++)
  133. {
  134. pMidCbus->chState.request[ queueIndex].reqStatus = CBUS_REQ_IDLE;
  135. }
  136. }
  137. //------------------------------------------------------------------------------
  138. // Function: CbusMidInsertCmdToQueue
  139. // Description: Place a command in the CBUS message queue. If queue was empty,
  140. // send the new command immediately.
  141. //
  142. // Parameters:
  143. // pReq - Pointer to a cbus_req_t structure containing the
  144. // command to write
  145. // Returns: TRUE - successful queue/write
  146. // FALSE - write and/or queue failed
  147. //------------------------------------------------------------------------------
  148. BOOL CbusMidInsertCmdToQueue(cbus_req_t *pReq)
  149. {
  150. INT32 queueIndex;
  151. BOOL success = FALSE;
  152. #ifdef CBUS_DETAIL_DEBUG_MSG
  153. UINT8 i = 0;
  154. UINT8 bStr[100] = "";
  155. char bTemp[10] = "";
  156. mhldbg("[%s] Channel State: cmd:0x%02x offset:0x%02x len:%d\n", __FUNCTION__, pReq->command, pReq->offsetData, pReq->length);
  157. memset(bStr, 0, 100);
  158. for(i = 0; i< MHL_MAX_BUFFER_SIZE;i++)
  159. {
  160. sprintf(bTemp, "0x%x ",pReq->msgData[i]);
  161. strcat(bStr, bTemp);
  162. }
  163. mhldbg("\tmsg: %s\n",bStr);
  164. #endif
  165. //print request for debug
  166. //CbusMidPrintChannelInfo(__FUNCTION__, __LINE__);
  167. if(pMidCbus->chState.connected)
  168. {
  169. queueIndex = CH_NEXT_INDEX;
  170. do{
  171. if(pMidCbus->chState.request[ queueIndex].reqStatus == CBUS_REQ_IDLE)
  172. {
  173. // Found an idle queue entry, copy the request and set to pending.
  174. memcpy(&pMidCbus->chState.request[ queueIndex], pReq, sizeof(cbus_req_t));
  175. pMidCbus->chState.request[ queueIndex].reqStatus = CBUS_REQ_PENDING;
  176. success = TRUE;
  177. mhldbg("[%s] index:%d cmd:0x%x offset: 0x%x\n", __FUNCTION__, queueIndex, pReq->command, pReq->offsetData);
  178. break;
  179. }
  180. queueIndex=((queueIndex+1)%CBUS_MAX_COMMAND_QUEUE);
  181. }while(queueIndex != CH_NEXT_INDEX);
  182. /* If successful at putting the request into the queue */
  183. if(success == FALSE)
  184. {
  185. printk("[MHL]CBUS:: Queue full - skip cmd:0x%x offset:0x%x\n", pReq->command, pReq->offsetData);
  186. }
  187. }
  188. //print queue data for debug
  189. //CbusMidPrintChannelInfo(__FUNCTION__, __LINE__);
  190. return(success);
  191. }
  192. //------------------------------------------------------------------------------
  193. // Function: CbusMidMscMsgSubCmdSend
  194. // Description: Send MSC_MSG(RCP)message to the specified CBUS channel(port)
  195. //
  196. // Parameters: channel - CBUS channel
  197. // vsCommand - MSC_MSG cmd(RCP, RCPK or RCPE)
  198. // cmdData - MSC_MSG data
  199. // Returns: TRUE - successful queue/write
  200. // FALSE - write and/or queue failed
  201. //------------------------------------------------------------------------------
  202. BOOL CbusMidMscMsgSubCmdSend(UINT8 vsCommand, UINT8 cmdData)
  203. {
  204. cbus_req_t req;
  205. // Send MSC_MSG command(Vendor Specific command)
  206. req.command = MHL_MSC_MSG;
  207. req.msgData[0] = vsCommand;
  208. req.msgData[1] = cmdData;
  209. if(!(CbusMidInsertCmdToQueue(&req)))
  210. {
  211. printk("[MHL]Couldn't send MHL_MSC_MSG to peer\n");
  212. return FALSE;
  213. }
  214. return TRUE;
  215. }
  216. //------------------------------------------------------------------------------
  217. // Function: CbusMidRapMessageAck
  218. // Description: Send RAPK(acknowledge)message to the specified CBUS channel
  219. // and set the request status to idle.
  220. //
  221. // Returns: TRUE - successful queue/write
  222. // FALSE - write and/or queue failed
  223. //------------------------------------------------------------------------------
  224. BOOL CbusMidRapMessageAck(MHL_RAPE_STATUS_e cmdStatus)
  225. {
  226. return(CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RAPK, (UINT8)cmdStatus));
  227. }
  228. //------------------------------------------------------------------------------
  229. // Function: CbusMidProcessFailureInterrupts
  230. // Description: Check for and process any failure interrupts.
  231. // Returns: SUCCESS or ERROR_CBUS_ABORT
  232. //------------------------------------------------------------------------------
  233. static UINT8 CbusMidProcessFailureInterrupts(UINT32 CbusTransIntStatus)
  234. {
  235. UINT8 result = CBUS_SUCCESS;
  236. UINT8 mscAbortReason, ddcAbortReason;
  237. UINT8 mscFailReason;
  238. CbusDrvDdcAbortReasonGet(&ddcAbortReason);
  239. CbusDrvMscAbortReasonGet(&mscAbortReason);
  240. CbusDrvMscFailReasonGet(&mscFailReason);
  241. if(CbusTransIntStatus)
  242. {
  243. // Check for failure interrupts.
  244. if(mscFailReason != 0)
  245. {
  246. mhldbg("CBUS:: ----mscFailReason:%x----\n",mscFailReason);
  247. mhldbg("CBUS:: ----mscAbortReason:%x----\n",mscAbortReason);
  248. if(CbusDrvNackFromPeerGet())
  249. {
  250. mhldbg("NACK received from peer!!! \n");
  251. pMidCbus->chState.sendNextWaitTime = CBUS_NACK_WAIT_TIME;
  252. //responder nack, retry this command
  253. pMidCbus->chState.state = CBUS_IDLE;
  254. pMidCbus->chState.request[CH_ACTIVE_INDEX].reqStatus = CBUS_REQ_PENDING;
  255. result = ERROR_NACK_FROM_PEER;
  256. }
  257. else if(mscFailReason != 0)
  258. {
  259. //send fail, skip this command
  260. pMidCbus->chState.state = CBUS_IDLE;
  261. pMidCbus->chState.request[CH_ACTIVE_INDEX].reqStatus = CBUS_REQ_IDLE;
  262. if(CbusDrvAbortFromPeerGet())
  263. {
  264. //responder abort
  265. pMidCbus->chState.sendNextWaitTime = CBUS_ABORT_WAIT_TIME;
  266. mhldbg("ABORT received from peer!!! \n");
  267. result = ERROR_ABORT_FROM_PEER;
  268. }
  269. else if(CbusDrvIneffectCodeFromPeerGet())
  270. {
  271. //responder ineffect code
  272. mhldbg("INEFFECT CODE received from peer!!! \n");
  273. result = ERROR_INEFFECT_CODE_FROM_PEER;
  274. }
  275. else
  276. {
  277. mhldbg("MSC other fail 0x%x received from peer!!! \n", mscFailReason);
  278. result = ERROR_WRITE_FAILED;
  279. }
  280. }
  281. if(CbusTransIntStatus & wrt_stat_intr)
  282. {
  283. mhldbg("CBUS:: ----wrt_stat Fail----\n");
  284. }
  285. if(CbusTransIntStatus & red_devc_intr)
  286. {
  287. mhldbg("CBUS:: ----red_devc Fail----\n");
  288. }
  289. if(CbusTransIntStatus & get_state_intr)
  290. {
  291. mhldbg("CBUS:: ----get_state Fail----\n");
  292. }
  293. if(CbusTransIntStatus & get_ven_id_intr)
  294. {
  295. mhldbg("CBUS:: ----get_ven_id Fail----\n");
  296. }
  297. if(CbusTransIntStatus & get_src1_err_intr)
  298. {
  299. mhldbg("CBUS:: ----get_src1_err Fail----\n");
  300. }
  301. if(CbusTransIntStatus & get_ddc_err_intr)
  302. {
  303. mhldbg("CBUS:: ----get_ddc_err Fail----\n");
  304. }
  305. if(CbusTransIntStatus & get_msc_err_intr)
  306. {
  307. mhldbg("CBUS:: ----get_msc_err Fail----\n");
  308. }
  309. if(CbusTransIntStatus & get_src3_err_intr)
  310. {
  311. mhldbg("CBUS:: ----get_src3_err Fail----\n");
  312. }
  313. if(CbusTransIntStatus & wrt_burst_intr)
  314. {
  315. mhldbg("CBUS:: ----wrt_burst Fail----\n");
  316. }
  317. if(CbusTransIntStatus & set_hpd_intr)
  318. {
  319. mhldbg("CBUS:: ----set_hpd Fail----\n");
  320. }
  321. if(CbusTransIntStatus & clr_hpd_intr)
  322. {
  323. mhldbg("CBUS:: ----clr_hpd Fail----\n");
  324. }
  325. if(CbusTransIntStatus & rap_act_ack_intr)
  326. {
  327. mhldbg("CBUS:: ----rap_act_ack Fail----\n");
  328. }
  329. //NACK packet of MSC_MSG back from respender, wait T_NACK_RETRY_NEXT = 1000ms
  330. if(CbusTransIntStatus & rcp_cmd_intr)
  331. {
  332. mhldbg("CBUS:: ----rcp_cmd Fail----\n");
  333. }
  334. if(CbusTransIntStatus & ucp_cmd_intr)
  335. {
  336. mhldbg("CBUS:: ----ucp_cmd Fail----\n");
  337. }
  338. if(CbusTransIntStatus & rap_cmd_intr)
  339. {
  340. mhldbg("CBUS:: ----rap_cmd Fail----\n");
  341. }
  342. }
  343. else
  344. {
  345. pMidCbus->chState.state = CBUS_IDLE;
  346. pMidCbus->chState.request[CH_ACTIVE_INDEX].reqStatus = CBUS_REQ_IDLE;
  347. }
  348. if(pMidCbus->chState.request[CH_ACTIVE_INDEX].reqStatus == CBUS_REQ_IDLE)
  349. CH_ACTIVE_INDEX = CH_NEXT_INDEX; //next index
  350. if(ddcAbortReason != 0)
  351. {
  352. mhldbg("CBUS:: ----ddcAbortReason:%x----\n",ddcAbortReason);
  353. }
  354. }
  355. return(result);
  356. }
  357. //------------------------------------------------------------------------------
  358. // Function: CbusMidCheckInterruptStatus
  359. // Description: If any interrupts on the specified channel are set, process them.
  360. // Parameters:
  361. // Returns: SUCCESS or CBUS_SW_ERR_e error code.
  362. //------------------------------------------------------------------------------
  363. BOOL HAVE_MHL_ADOPTER_ID=FALSE;
  364. static CBUS_SW_ERR_e CbusMidCheckInterruptStatus(void)
  365. {
  366. UINT32 CbusTransIntStatus, CbusLinkIntStatus, result;
  367. UINT8 bData1, bData2;
  368. UINT16 wAdopterId;
  369. /* Read CBUS interrupt status. */
  370. CbusDrvInterruptStatusGet(&CbusTransIntStatus, &CbusLinkIntStatus);
  371. /* Check for interrupts. */
  372. result = CBUS_SUCCESS;
  373. if(CbusTransIntStatus != 0)
  374. {
  375. //CbusDrvWriteCommand's intr
  376. if((CbusTransIntStatus & wrt_stat_intr)||(CbusTransIntStatus & red_devc_intr)||(CbusTransIntStatus & get_state_intr)||(CbusTransIntStatus & get_ven_id_intr)||
  377. (CbusTransIntStatus & get_src1_err_intr)||(CbusTransIntStatus & get_ddc_err_intr)||(CbusTransIntStatus & get_msc_err_intr)||(CbusTransIntStatus & get_src3_err_intr)||(CbusTransIntStatus & wrt_burst_intr)||
  378. (CbusTransIntStatus & rcp_cmd_intr)||(CbusTransIntStatus & rap_cmd_intr)||(CbusTransIntStatus & ucp_cmd_intr)||(CbusTransIntStatus & rap_act_ack_intr)||
  379. (CbusTransIntStatus & set_hpd_intr)||(CbusTransIntStatus & clr_hpd_intr))
  380. {
  381. /* A previous MSC sub-command has been acknowledged by the responder. */
  382. /* Does not include MSC MSG commands.*/
  383. mhldbg("CBUS:: Transfer Done \n");
  384. /* Check for failure interrupts. */
  385. result = CbusMidProcessFailureInterrupts(CbusTransIntStatus);
  386. //mhldbg("CBUS:: Transfer Done - Data returned: %02X %02X\n", *pData, *pData1);
  387. }
  388. if(CbusDrvWrtStateAckInfoGet(&bData1, &bData2) == TRUE)
  389. {
  390. if((bData1 == 0x31) && ((bData2 & 0x08) != 0))
  391. {
  392. pMidCbus->chState.sinkPathEn = TRUE;
  393. }
  394. else if((bData1 == 0x20) && ((bData2 & 0x02) != 0))
  395. {
  396. pMidCbus->chState.sinkDscrChgAck = TRUE;
  397. }
  398. }
  399. if(CbusTransIntStatus & rcp_cmd_intr)
  400. {
  401. #ifdef MHL_ONLY_ONE_RCP_IN_QUEUE
  402. if(pMidCbus->chState.SrcNotSprtRcpRelease == TRUE) //if source does not support RCP release command, there is one RCP command in queue
  403. {
  404. if(pMidCbus->chState.request[CH_ACTIVE_INDEX].reqStatus == CBUS_REQ_IDLE) //RCP command done, needn't retry
  405. {
  406. pMidCbus->chState.existRcpInQueue = FALSE;
  407. }
  408. }
  409. else //if source supports RCP release command, there is two RCP command in queue
  410. {
  411. if((pMidCbus->chState.request[CH_ACTIVE_INDEX].reqStatus == CBUS_REQ_IDLE) && (pMidCbus->chState.request[CH_ACTIVE_INDEX].msgData[1] & 0x80) == 0x80) //RCP command done, needn't retry
  412. {
  413. pMidCbus->chState.existRcpInQueue = FALSE;
  414. }
  415. }
  416. #endif
  417. //source does not support RCP release command
  418. if((result == ERROR_INEFFECT_CODE_FROM_PEER) &&
  419. (pMidCbus->chState.request[CH_ACTIVE_INDEX].command == MHL_MSC_MSG) &&
  420. (pMidCbus->chState.request[CH_ACTIVE_INDEX].msgData[0] == MHL_MSC_MSG_RCP) &&
  421. ((pMidCbus->chState.request[CH_ACTIVE_INDEX].msgData[1] & 0x80) == 0x80))
  422. {
  423. mhldbg("Source does not support RCP release command!!! \n");
  424. pMidCbus->chState.SrcNotSprtRcpRelease = TRUE;
  425. }
  426. }
  427. if(CbusTransIntStatus & req_3d_intr)
  428. {
  429. pMidCbus->chState.srcReq3D = TRUE;
  430. CbusMidSend3DVideoSupportList(TRUE);
  431. }
  432. if(CbusTransIntStatus & req_wrt_intr)
  433. {
  434. // request received from peer to write into scratchpad
  435. if(CbusDrvReqWrtGet())
  436. {
  437. mhldbg("\n\ngranting peer's request to write scratchpad!!\n");
  438. CbusMidGrtWrt();
  439. }
  440. }
  441. if(CbusTransIntStatus & grt_wrt_intr)
  442. {
  443. // request to write into peer's scratchpad is granted
  444. if(CbusDrvGrtWrtGet())
  445. {
  446. mhldbg("peer sent grtWrt!!\n");
  447. pMidCbus->chState.srcGrtWrt = TRUE;
  448. }
  449. }
  450. if(CbusTransIntStatus & clr_hpd_intr)
  451. {
  452. CbusMidSendCommand(MHL_SET_HPD);
  453. }
  454. if(CbusTransIntStatus & set_hpd_intr)
  455. {
  456. pMidCbus->chState.setHPD = TRUE;
  457. }
  458. if(CbusTransIntStatus & red_devc_intr)
  459. {
  460. CbusDrvDevCapGet(&bData1, &bData2);
  461. pMidCbus->chState.stSrcDevCap.bDevCap[bData1] = bData2;
  462. if(bData1 == bGetDevCapOffsetArray[DEV_CAP_OFFSET_ARRAY_SIZE-1]) //fetch read_device_capability done
  463. {
  464. pMidCbus->chState.stSrcDevCap.fDevCapReady = TRUE;
  465. wAdopterId = pMidCbus->chState.stSrcDevCap.wAdopterId;
  466. noticekmf(KMF2UMF_EVID_HDMI, KMF2UMF_EVTYPE_HDMI_MHL_ADOPTER_ID, (UINT8 *)&wAdopterId, 2);
  467. //print device capability
  468. mhldbg("[%s] source dev_cap: MHL_VER: 0x%x Dev_type:0x%x Adopter_ID:0x%x\n \tsupport RCP:%d, RAP:%d SP:%d UCP_Send:%d UCP_RECV:%d\n \tDevice_ID:0x%x SP_Size:%d INT_size:%d STAT_Size:%d\n",
  469. __FUNCTION__, pMidCbus->chState.stSrcDevCap.bMhlVersion, pMidCbus->chState.stSrcDevCap.bDevType, pMidCbus->chState.stSrcDevCap.wAdopterId,
  470. pMidCbus->chState.stSrcDevCap.bRcpSupport, pMidCbus->chState.stSrcDevCap.bRapSupport, pMidCbus->chState.stSrcDevCap.bSpSupport, pMidCbus->chState.stSrcDevCap.bUcpSendSupport, pMidCbus->chState.stSrcDevCap.bUcpRecvSupport,
  471. pMidCbus->chState.stSrcDevCap.wDeviceId, pMidCbus->chState.stSrcDevCap.bScratchpadSize, pMidCbus->chState.stSrcDevCap.bIntSize, pMidCbus->chState.stSrcDevCap.bStatSize);
  472. /* SAMSUNG S2, Note3, Xiaomi do not support RCP release */
  473. if((pMidCbus->chState.stSrcDevCap.wAdopterId == ADOPTER_ID_SAMSUNG) || (pMidCbus->chState.stSrcDevCap.wAdopterId == ADOPTER_ID_SIMPLAY))
  474. {
  475. pMidCbus->chState.SrcNotSprtRcpRelease = TRUE;
  476. }
  477. if((pMidCbus->chState.stSrcDevCap.wAdopterId == ADOPTER_ID_SIMPLAY) && (pMidCbus->chState.stSrcDevCap.wDeviceId == DEVICE_ID_SIMPLAY))
  478. {
  479. mhldbg("Set MHL_CTS = TRUE !!\n");
  480. HDMI_MHL_CTS(TRUE);
  481. }
  482. else
  483. {
  484. mhldbg("Set MHL_CTS = FALSE !!\n");
  485. HDMI_MHL_CTS(FALSE);
  486. }
  487. if(pMidCbus->chState.stSrcDevCap.wAdopterId == 0x00 )
  488. {
  489. mhldbg("MHL ADOPTER_ID == 0x00 !!\n");
  490. HAVE_MHL_ADOPTER_ID = FALSE;
  491. }
  492. else
  493. {
  494. HAVE_MHL_ADOPTER_ID = TRUE;
  495. }
  496. }
  497. }
  498. //Peer's Device Capability ready
  499. if(CbusTransIntStatus & connected_rdy_intr)
  500. {
  501. CbusMidSendCommand(MHL_SET_HPD);
  502. }
  503. }
  504. if(CbusLinkIntStatus != 0)
  505. {
  506. if((CbusLinkIntStatus & connt_intr)||(CbusLinkIntStatus & attach_intr)||(CbusLinkIntStatus & discv_intr)||(CbusLinkIntStatus & detach_intr))//[2]HDMIRX_CBUS_connt_int__p Nedd check ??
  507. {
  508. BOOL Connected;
  509. /* The connection change interrupt has been received. */
  510. mhldbg("CBUS:: ----Connection Change----\n");
  511. // Update component bus status for this channel.
  512. CbusDrvConnectedGet(&Connected);
  513. pMidCbus->chState.connected = Connected;
  514. //printk("[MD_INT] pMidCbus->chState.connected = %d\n", pMidCbus->chState.connected);
  515. if((CbusLinkIntStatus & discv_intr))
  516. {
  517. pMidCbus->chState.sinkPathEn = FALSE;
  518. pMidCbus->chState.setHPD =FALSE;
  519. pMidCbus->chState.SrcNotSprtRcpRelease = FALSE;
  520. HDMI_RegisterWrite(HDMIRX_CBUS_r_reset_reg, 1);
  521. HDMI_RegisterWrite(HDMIRX_CBUS_r_reset_reg, 0);
  522. CbusMidResetToIdle();
  523. #ifdef CONFIG_HDMI_MHL_PORT
  524. if(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)
  525. {
  526. DRV_HDMI_SW_HDCP_RSTN();//After plug in HTC EVO then plug in XIAOMI display NG
  527. CbusMidSendCommand(MHL_CLR_HPD);//For Samsung 9100 display NG
  528. //CbusMidSendCommand(MHL_SET_HPD);
  529. }
  530. else
  531. {
  532. CbusMidSendCommand(MHL_CLR_HPD);
  533. }
  534. #else
  535. // Send MHL_SET_HPD command(same as heartbeat)
  536. CbusMidSendCommand(MHL_CLR_HPD);//For Samsung 9100 display NG
  537. CbusMidSendCommand(MHL_SET_HPD);
  538. #endif
  539. }
  540. // If a disconnect, reset the channel write request state machine
  541. if(pMidCbus->chState.connected == FALSE)
  542. {
  543. //set the cbus to idle
  544. CbusMidResetToIdle();
  545. }
  546. }
  547. }
  548. CbusDrvInterruptStatusSet(0, 0);//Clear
  549. return(result);
  550. }
  551. //------------------------------------------------------------------------------
  552. // Function: CbusMidGetDevCapReadyBit
  553. // Description: see if dev cap ready msg has been sent or not
  554. // Parameters: channel to check
  555. // Returns: TRUE - success
  556. // FALSE - failure
  557. //------------------------------------------------------------------------------
  558. BOOL CbusMidGetDevCapReadyBit(void)
  559. {
  560. return(pMidCbus->chState.dev_cap_regs_ready_bit);
  561. }
  562. //------------------------------------------------------------------------------
  563. // Function: CbusMidSetDevCapReadyBit
  564. // Description: set the devCapReady bit
  565. // Parameters: channel to check, value to set
  566. // Returns: void
  567. //------------------------------------------------------------------------------
  568. void CbusMidSetDevCapReadyBit(BOOL value)
  569. {
  570. pMidCbus->chState.dev_cap_regs_ready_bit = value;
  571. }
  572. //------------------------------------------------------------------------------
  573. // Function: CbusMidSendDcapRdyMsg
  574. // Description: Send a msg to peer informing the devive capability registers are
  575. // ready to be read.
  576. // Parameters: channel to check
  577. // Returns: TRUE - success
  578. // FALSE - failure
  579. //------------------------------------------------------------------------------
  580. BOOL CbusMidSendDcapRdyMsg(void)
  581. {
  582. BOOL result = TRUE;
  583. if(CbusMidChannelConnected()&&(pMidCbus->chState.setHPD==TRUE))
  584. {
  585. mhldbg("CbusMidSendDcapRdyMsg() Called!!\n");
  586. //send a msg to peer that the device capability registers are ready to be read.
  587. //set DCAP_RDY bit
  588. CbusMidSendDcapRdy();
  589. //set DCAP_CHG bit
  590. CbusMidSendDcapChange();
  591. CbusMidSetDevCapReadyBit(TRUE);
  592. // set path_en bit too
  593. result = CbusMidPathEnable();
  594. }
  595. return result;
  596. }
  597. //------------------------------------------------------------------------------
  598. // Function: CbusMidSendWriteBurst
  599. // Description: sends MHL write burst cmd
  600. // Parameters:
  601. //------------------------------------------------------------------------------
  602. BOOL CbusMidSendWriteBurst(UINT8 startOffset, UINT8 length, UINT8* pMsgData)
  603. {
  604. cbus_req_t req;
  605. INT32 i;
  606. req.command = MHL_WRITE_BURST;
  607. req.offsetData = startOffset;
  608. req.length = length;
  609. // write different values in different registers
  610. for(i = 0; i < length; i++)
  611. {
  612. req.msgData[i] = pMsgData[i];
  613. }
  614. if(!(CbusMidInsertCmdToQueue(&req)))
  615. {
  616. printk("[MHL]Couldn't send Write Burst to peer\n");
  617. return FALSE;
  618. }
  619. return TRUE;
  620. }
  621. //------------------------------------------------------------------------------
  622. // Function: CbusMidSendCommand
  623. // Description: sends general MHL commands
  624. // Parameters:
  625. //------------------------------------------------------------------------------
  626. BOOL CbusMidSendCommand(UINT8 cmd)
  627. {
  628. cbus_req_t req;
  629. req.command = cmd;
  630. if(!(CbusMidInsertCmdToQueue(&req)))
  631. {
  632. printk("[MHL]Couldn't send cmd: %02X to peer\n", cmd);
  633. return FALSE;
  634. }
  635. return TRUE;
  636. }
  637. //------------------------------------------------------------------------------
  638. // Function: CbusMidSetInt
  639. // Description: write peer's status registers
  640. // regOffset - peer's register offset
  641. // regBit - bit to be set
  642. //------------------------------------------------------------------------------
  643. BOOL CbusMidSetInt(UINT8 regOffset, UINT8 regBit)
  644. {
  645. cbus_req_t req;
  646. req.command = MHL_SET_INT;
  647. req.offsetData = regOffset;
  648. req.msgData[0] = regBit;
  649. if(!(CbusMidInsertCmdToQueue(&req)))
  650. {
  651. printk("[MHL]Couldn't send MHL_SET_INT to peer\n");
  652. return FALSE;
  653. }
  654. return TRUE;
  655. }
  656. //------------------------------------------------------------------------------
  657. // Function: EdidChange
  658. // Description: set edid_chg interrupt
  659. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  660. //------------------------------------------------------------------------------
  661. BOOL CbusMidEdidChange(void)
  662. {
  663. return(CbusMidSetInt(0x01, BIT1));
  664. }
  665. //------------------------------------------------------------------------------
  666. // Function: DcapChange
  667. // Description:
  668. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  669. //------------------------------------------------------------------------------
  670. BOOL CbusMidSendDcapChange(void)
  671. {
  672. return(CbusMidSetInt(0x00, BIT0));
  673. }
  674. //------------------------------------------------------------------------------
  675. // Function: CbusDscrChange
  676. // Description:
  677. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  678. //------------------------------------------------------------------------------
  679. BOOL CbusMidSendDscrChange(void)
  680. {
  681. return(CbusMidSetInt(0x00, BIT1));
  682. }
  683. //------------------------------------------------------------------------------
  684. // Function: CbusMidReqWrt
  685. // Description:
  686. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  687. //------------------------------------------------------------------------------
  688. BOOL CbusMidReqWrt(void)
  689. {
  690. return(CbusMidSetInt(0x00, BIT2));
  691. }
  692. //------------------------------------------------------------------------------
  693. // Function: CbusMidGrtWrt
  694. // Description:
  695. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  696. //------------------------------------------------------------------------------
  697. BOOL CbusMidGrtWrt(void)
  698. {
  699. return(CbusMidSetInt(0x00, BIT3));
  700. }
  701. //------------------------------------------------------------------------------
  702. // Function: CbusMidWriteStatus
  703. // Description: write peer's status registers
  704. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  705. // regOffset - peer's register offset
  706. // value - value to be written
  707. //------------------------------------------------------------------------------
  708. BOOL CbusMidWriteStatus(UINT8 regOffset, UINT8 value)
  709. {
  710. cbus_req_t req;
  711. req.command = MHL_WRITE_STAT;
  712. req.offsetData = regOffset;
  713. req.msgData[0] = value;
  714. if(!(CbusMidInsertCmdToQueue(&req)))
  715. {
  716. printk("[MHL]Couldn't send MHL_WRITE_STAT to peer\n");
  717. return FALSE;
  718. }
  719. return TRUE;
  720. }
  721. //------------------------------------------------------------------------------
  722. // Function: CbusMidPathEnable
  723. // Description: Check if the channel is an active channel
  724. // Parameters: port - current active port
  725. //------------------------------------------------------------------------------
  726. BOOL CbusMidPathEnable(void)
  727. {
  728. mhldbg("[%s]\n", __FUNCTION__);
  729. #ifdef CONFIG_HDMI_MHL_PORT
  730. if(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)
  731. {
  732. CbusMidWriteStatus(0x01, 0);//Disable PATH_EN bit on peer's appropriate status register(offset 0x31)
  733. // enable PATH_EN bit on peer's appropriate status register(offset 0x31)
  734. mhldbg("PathEnable:: Setting bit 3 to peer's status register.\n");
  735. pMidCbus->isPrevPortMHL = TRUE;
  736. #if 0 //Need marked for MHL CTS 4.3.23.2
  737. if(CONFIG_HDMI_MHL_PORT==0)
  738. {
  739. HDMI_RegisterWrite(HDMIRX_HDMIP0_Rx_Sense_external, 1);
  740. HDMI_RegisterWrite(HDMIRX_HDMIP0_Rx_Sense_mux, 1);
  741. }
  742. else if(CONFIG_HDMI_MHL_PORT==1)
  743. {
  744. HDMI_RegisterWrite(HDMIRX_HDMIP1_Rx_Sense_external, 1);
  745. HDMI_RegisterWrite(HDMIRX_HDMIP1_Rx_Sense_mux, 1);
  746. }
  747. #endif
  748. return(CbusMidWriteStatus(0x01, BIT3));
  749. }
  750. else
  751. {
  752. if(pMidCbus->isPrevPortMHL)
  753. {
  754. // disable PATH_EN bit on peer's appropriate status register(offset 0x31)
  755. mhldbg("PathEnable:: Clearing bit 3 to peer's status register.\n");
  756. pMidCbus->isPrevPortMHL = FALSE;
  757. return(CbusMidWriteStatus(0x01, 0));
  758. }
  759. }
  760. #endif
  761. return(TRUE);
  762. }
  763. //------------------------------------------------------------------------------
  764. // Function: CbusMidReadDevCap
  765. // Description: read peer's status registers
  766. // Parameters: regOffset - peer's register offset
  767. //------------------------------------------------------------------------------
  768. BOOL CbusMidReadDevCap(UINT8 regOffset)
  769. {
  770. cbus_req_t req;
  771. req.command = MHL_READ_DEVCAP;
  772. req.offsetData = regOffset;
  773. if(!(CbusMidInsertCmdToQueue(&req)))
  774. {
  775. printk("[MHL]Couldn't send MHL_READ_DEVCAP to peer\n");
  776. return FALSE;
  777. }
  778. return TRUE;
  779. }
  780. //------------------------------------------------------------------------------
  781. // Function: CbusMidSendDcapRdy
  782. // Description:
  783. // Parameters: channel - CBUS channel to check, must be in range, NOT 0xFF
  784. //------------------------------------------------------------------------------
  785. BOOL CbusMidSendDcapRdy(void)
  786. {
  787. return(CbusMidWriteStatus(0x00, BIT0));
  788. }
  789. //------------------------------------------------------------------------------
  790. // Function: CbusMidSendPathEn_RcvdAck
  791. // Description: check if PATH_EN msg has been sent and received ACK or not
  792. // Parameters: channel to check
  793. // Returns: TRUE - success
  794. // FALSE - failure
  795. //------------------------------------------------------------------------------
  796. BOOL CbusMidSendPathEn_RcvdAck(void)
  797. {
  798. return(pMidCbus->chState.sinkPathEn);
  799. }
  800. //------------------------------------------------------------------------------
  801. // Function: CbusMidGet_HPD_Status
  802. // Description: check if Set HPD msg has been sent or not
  803. // Returns: TRUE - success
  804. // FALSE - failure
  805. //------------------------------------------------------------------------------
  806. BOOL CbusMidGet_HPD_Status(void)
  807. {
  808. return(pMidCbus->chState.setHPD );
  809. }
  810. //------------------------------------------------------------------------------
  811. // Function: CbusMidSend3DVideoSupportList
  812. // Description: sends 3D Support list by Write Burst
  813. // Parameters:
  814. //------------------------------------------------------------------------------
  815. BOOL CbusMidSend3DVideoSupportList(BOOL fReset)
  816. {
  817. static CBUS_3D_FSM_STATE_e eSend3dListState = CBUS_3D_FSM_FINISHED;
  818. #ifdef CONFIG_SUPPORT_3D_EN
  819. #define CBUS_3DLIST_NUM 4
  820. static UINT8 pb3DList[CBUS_3DLIST_NUM][MHL_MAX_BUFFER_SIZE] = {{0x00, 0x11, 0xEB, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //DTD_3D
  821. {0x00, 0x10, 0xD3, 0x0f, 0x01, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}, //VIC_3D
  822. {0x00, 0x10, 0xD6, 0x0f, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, //VIC_3D
  823. {0x00, 0x10, 0xD4, 0x0f, 0x03, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //VIC_3D
  824. #else
  825. #define CBUS_3DLIST_NUM 2
  826. static UINT8 pb3DList[CBUS_3DLIST_NUM][MHL_MAX_BUFFER_SIZE] = {{0x00, 0x11, 0xEE, 0x0, 0x1, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //DTD_3D null
  827. {0x00, 0x10, 0xEF, 0x0, 0x1, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; //VIC_3D null
  828. #endif
  829. static UINT8 b3DListIndex = 0, bTimeout_cnt = 0, bTimeout_target =20;
  830. if(eSend3dListState != CBUS_3D_FSM_FINISHED)
  831. {
  832. mhldbg("%s state:%d\n", __FUNCTION__, eSend3dListState);
  833. }
  834. if(pMidCbus->chState.srcReq3D == FALSE)
  835. return TRUE;
  836. if(fReset == TRUE) //new 3d_intr happened, reset FSM
  837. {
  838. eSend3dListState = CBUS_3D_FSM_IDLE;
  839. b3DListIndex = 0;
  840. }
  841. switch(eSend3dListState)
  842. {
  843. case CBUS_3D_FSM_IDLE:
  844. if(pMidCbus->chState.srcReq3D == TRUE)
  845. eSend3dListState = CBUS_3D_FSM_SEND_REQ_WRT;
  846. break;
  847. case CBUS_3D_FSM_SEND_REQ_WRT:
  848. if(!CbusMidReqWrt()) //send REQ_WRT to request BURST_WRITE
  849. {
  850. mhldbg("Couldn't send REQ_WRT list to peer\n");
  851. return FALSE;
  852. }
  853. eSend3dListState = CBUS_3D_FSM_WAIT_GRT_WRT;
  854. break;
  855. //case CBUS_3D_FSM_WAIT_REQ_WRT_ACK:
  856. case CBUS_3D_FSM_WAIT_GRT_WRT:
  857. if(pMidCbus->chState.srcGrtWrt == TRUE)
  858. {
  859. pMidCbus->chState.srcGrtWrt = FALSE;
  860. eSend3dListState = CBUS_3D_FSM_SEND_BURST_WRT;
  861. }
  862. break;
  863. case CBUS_3D_FSM_SEND_BURST_WRT:
  864. if(!CbusMidSendWriteBurst(0, MHL_MAX_BUFFER_SIZE, pb3DList[b3DListIndex]))
  865. {
  866. mhldbg("Couldn't send 3D[%d] list to peer\n", b3DListIndex);
  867. return FALSE;
  868. }
  869. eSend3dListState = CBUS_3D_FSM_WAIT_BURST_WRT_ACK;
  870. bTimeout_cnt =0;
  871. break;
  872. case CBUS_3D_FSM_WAIT_BURST_WRT_ACK:
  873. if(CbusDrvWrtBurstAckGet() == TRUE)
  874. eSend3dListState = CBUS_3D_FSM_SEND_DSCR_CHG;
  875. else
  876. {
  877. bTimeout_cnt++;
  878. if(bTimeout_cnt == bTimeout_target)
  879. eSend3dListState = CBUS_3D_FSM_SEND_BURST_WRT;
  880. }
  881. break;
  882. case CBUS_3D_FSM_SEND_DSCR_CHG:
  883. if(!CbusMidSendDscrChange())
  884. {
  885. mhldbg("Couldn't send DSCR_CHG list to peer\n");
  886. return FALSE;
  887. }
  888. eSend3dListState = CBUS_3D_FSM_WAIT_DSCR_CHG_ACK;
  889. break;
  890. case CBUS_3D_FSM_WAIT_DSCR_CHG_ACK:
  891. if(pMidCbus->chState.sinkDscrChgAck == TRUE)
  892. {
  893. b3DListIndex++;
  894. if(b3DListIndex < CBUS_3DLIST_NUM)
  895. {
  896. eSend3dListState = CBUS_3D_FSM_SEND_REQ_WRT;
  897. }
  898. else
  899. {
  900. pMidCbus->chState.srcReq3D = FALSE;
  901. eSend3dListState = CBUS_3D_FSM_FINISHED;
  902. }
  903. pMidCbus->chState.sinkDscrChgAck = FALSE;
  904. }
  905. break;
  906. case CBUS_3D_FSM_FINISHED:
  907. default:
  908. break;
  909. }
  910. return TRUE;
  911. }
  912. //------------------------------------------------------------------------------
  913. // Function: CbusMidGetSrcDevCap
  914. // Description: get interest device capabilityies of source
  915. // Parameters: fReset - reset the flow of fetching Device Capability
  916. // Returns: TRUE - success
  917. // FALSE - failure
  918. //------------------------------------------------------------------------------
  919. BOOL CbusMidGetSrcDevCap(BOOL fReset)
  920. {
  921. static UINT8 bGetIndex = 0xff;
  922. if(fReset == TRUE)
  923. {
  924. bGetIndex = 0;
  925. pMidCbus->chState.stSrcDevCap.fDevCapReady = FALSE;
  926. }
  927. if((bGetIndex >= DEV_CAP_OFFSET_ARRAY_SIZE) || (pMidCbus->chState.dev_cap_regs_ready_bit == FALSE))
  928. return TRUE;
  929. else
  930. {
  931. if(CbusMidReadDevCap(bGetDevCapOffsetArray[bGetIndex]) == TRUE)
  932. {
  933. //mhldbg("[%s] Offset 0x%x\n", __FUNCTION__, bGetDevCapOffsetArray[bGetIndex]);
  934. bGetIndex++;
  935. }
  936. else
  937. {
  938. mhldbg("[%s] Offset 0x%x fail\n", __FUNCTION__, bGetDevCapOffsetArray[bGetIndex]);
  939. return FALSE;
  940. }
  941. }
  942. return TRUE;
  943. }
  944. // This is to check all the Timers
  945. BOOL CbusMidIsTimeout(void)
  946. {
  947. UINT32 tNow = HDMI_GetSysTime();
  948. if((tNow - pMidCbus->chState.lastSendTime) >= pMidCbus->chState.sendNextWaitTime)
  949. {
  950. //mhldbg("[%s] timeout!\n", __FUNCTION__);
  951. return TRUE;
  952. }
  953. else
  954. {
  955. mhldbg("[%s] wait timeout!now:%d lastSend:%d wait:%d\n", __FUNCTION__, tNow, pMidCbus->chState.lastSendTime, pMidCbus->chState.sendNextWaitTime);
  956. return FALSE;
  957. }
  958. }
  959. //------------------------------------------------------------------------------
  960. // Function: CbusMidHandler
  961. // Description: Check the state of any current CBUS message on specified channel.
  962. // Handle responses or failures and send any pending message if
  963. // channel is IDLE.
  964. // Returns: SUCCESS or one of CBUS_SW_ERR_e
  965. //------------------------------------------------------------------------------
  966. CBUS_SW_ERR_e CbusMidHandler(void)
  967. {
  968. CBUS_SW_ERR_e result;
  969. /* Check the channel interrupt status to see if anybody is */
  970. /* talking to us. If they are, talk back. */
  971. result = CbusMidCheckInterruptStatus();
  972. if(result != CBUS_SUCCESS)
  973. {
  974. return (result);
  975. }
  976. CbusMidSend3DVideoSupportList(FALSE);
  977. // check timer for send next command
  978. if(CbusMidIsTimeout() == FALSE)
  979. return (result);
  980. /* check channel to send next command */
  981. if(pMidCbus->chState.state == CBUS_IDLE)
  982. CbusMidSendNextInQueue();
  983. else
  984. result = CBUS_SUCCESS;
  985. return (result);
  986. }
  987. //------------------------------------------------------------------------------
  988. // Function: CbusMidInitialize
  989. // Description: Initialize the CBUS.
  990. //------------------------------------------------------------------------------
  991. void CbusMidInitialize(void)
  992. {
  993. mhldbg("[%s]\n", __FUNCTION__);
  994. memset(pMidCbus, 0, sizeof(CbusMidInstanceData_t));
  995. }
  996. //------------------------------------------------------------------------------
  997. // Function: DRV_MHL_SendRcpCmd
  998. // Description: Receive RCP Command from APP.
  999. // Returns: None
  1000. //------------------------------------------------------------------------------
  1001. void DRV_MHL_SendRcpCmd(MHL_RCP_CMD_e eRcpCmd)
  1002. {
  1003. mhldbg("[%s] 0x%x\n", __FUNCTION__, eRcpCmd);
  1004. //if(pMidCbus->chState.stSrcDevCap.bRcpSupport == FALSE)
  1005. //{
  1006. // mhldbg("this device does not support RCP\n");
  1007. // return;
  1008. //}
  1009. #ifdef MHL_ONLY_ONE_RCP_IN_QUEUE
  1010. if(pMidCbus->chState.existRcpInQueue == TRUE)
  1011. {
  1012. mhldbg("there is already one RCP in queue, skip this RCP 0x%x\n", eRcpCmd);
  1013. }
  1014. if(CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, eRcpCmd) == TRUE) //key press
  1015. pMidCbus->chState.existRcpInQueue = TRUE;
  1016. if(pMidCbus->chState.SrcNotSprtRcpRelease == FALSE)
  1017. {
  1018. CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, 0x80 | eRcpCmd); //key release
  1019. }
  1020. #else
  1021. CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, eRcpCmd); //key press
  1022. if(pMidCbus->chState.SrcNotSprtRcpRelease == FALSE)
  1023. {
  1024. CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, 0x80 | eRcpCmd); //key release
  1025. }
  1026. #endif
  1027. }
  1028. //------------------------------------------------------------------------------
  1029. // Function: DRV_MHL_SendRcpPressAndHoldCmd
  1030. // Description: Receive Press And Hold RCP Command from APP.
  1031. // Returns: None
  1032. //------------------------------------------------------------------------------
  1033. void DRV_MHL_SendRcpPressAndHoldCmd(MHL_RCP_CMD_e eRcpCmd ,BOOL fPress)
  1034. {
  1035. mhldbg("[%s] 0x%x Press:%x\n", __FUNCTION__, eRcpCmd,fPress);
  1036. //if(pMidCbus->chState.stSrcDevCap.bRcpSupport == FALSE)
  1037. //{
  1038. // mhldbg("this device does not support RCP\n");
  1039. // return;
  1040. //}
  1041. #ifdef MHL_ONLY_ONE_RCP_IN_QUEUE
  1042. if(pMidCbus->chState.existRcpInQueue == TRUE)
  1043. {
  1044. mhldbg("there is already one RCP in queue, skip this RCP 0x%x\n", eRcpCmd);
  1045. }
  1046. if(fPress == TRUE)
  1047. {
  1048. if(CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, eRcpCmd) == TRUE) //key press
  1049. pMidCbus->chState.existRcpInQueue = TRUE;
  1050. }
  1051. else
  1052. {
  1053. CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, 0x80 | eRcpCmd); //key release
  1054. }
  1055. #else
  1056. if(fPress == TRUE)
  1057. {
  1058. CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, eRcpCmd); //key press
  1059. }
  1060. else
  1061. {
  1062. if(pMidCbus->chState.SrcNotSprtRcpRelease == FALSE)
  1063. {
  1064. CbusMidMscMsgSubCmdSend(MHL_MSC_MSG_RCP, 0x80 | eRcpCmd); //key release
  1065. }
  1066. }
  1067. #endif
  1068. }
  1069. //------------------------------------------------------------------------------
  1070. // Function: MHL_VbusCtrl
  1071. // Description: Turn on or off VBUS.
  1072. // Parameters: vbusEn - 1-Enable; 0 - Disable
  1073. // Returns: TRUE
  1074. //------------------------------------------------------------------------------
  1075. BOOL MHL_VbusCtrl(BOOL vbusEn)
  1076. {
  1077. BOOL success = TRUE;
  1078. sysset_VbusEnable(vbusEn);
  1079. return(success);
  1080. }
  1081. //------------------------------------------------------------------------------
  1082. // Function: MHL_ADOPTER_ID_Check
  1083. // Description: check if device have MHL_ADOPTER_ID
  1084. // Parameters:
  1085. // Returns: TRUE -
  1086. // FALSE -
  1087. //------------------------------------------------------------------------------
  1088. BOOL MHL_ADOPTER_ID_Check(void)
  1089. {
  1090. return(HAVE_MHL_ADOPTER_ID);
  1091. }
  1092. //for debug
  1093. void CbusMidPrintChannelInfo(const UINT8 *bFunc, const UINT32 dLine)
  1094. {
  1095. UINT8 bStr[100] = "";
  1096. char bTemp[10] = "";
  1097. UINT8 i=0,j=0;
  1098. mhldbg("[%s] caller:%s %d\n", __FUNCTION__,bFunc, dLine);
  1099. mhldbg("statusFlags:%d isPrevPortMHL:%d", pMidCbus->statusFlags, pMidCbus->isPrevPortMHL);
  1100. mhldbg("\tconnected:%d state:%d activeIndex:%d dev_cap_regs_ready_bit:%d\n", pMidCbus->chState.connected, pMidCbus->chState.state, pMidCbus->chState.activeIndex, pMidCbus->chState.dev_cap_regs_ready_bit);
  1101. mhldbg("\ttxReq3D:%d txGrtWrt:%d\n", pMidCbus->chState.srcReq3D, pMidCbus->chState.srcGrtWrt);
  1102. for(i = 0; i< CBUS_MAX_COMMAND_QUEUE;i++)
  1103. {
  1104. mhldbg("req[%d] reqStatus:%d command:0x%x offsetData0x%x length:%d\n", i, pMidCbus->chState.request[i].reqStatus, pMidCbus->chState.request[i].command, pMidCbus->chState.request[i].offsetData, pMidCbus->chState.request[i].length);
  1105. memset(bStr, 0, 100);
  1106. for(j = 0; j< MHL_MAX_BUFFER_SIZE;j++)
  1107. {
  1108. sprintf(bTemp, "0x%x ", pMidCbus->chState.request[i].msgData[j]);
  1109. strcat(bStr, bTemp);
  1110. }
  1111. mhldbg("msg: %s\n",bStr);
  1112. }
  1113. }