cbus_mid.c 43 KB

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