/******************************************************************************/ //!file drv_cbus.c //!brief CBUS Driver. // /******************************************************************************/ #include #include "cbus_debug.h" #include "cbus_drv.h" #include "cbus_drv_internal.h" #include "cbus_enums.h" #include "../hdmi_time.h" #include "../hdmi_hw.h" #include "../hdmi.h" //------------------------------------------------------------------------------ // CBUS Driver Instance Data //------------------------------------------------------------------------------ CbusDrvInstanceData_t cbusDrvInstance; CbusDrvInstanceData_t *pDrvCbus = &cbusDrvInstance; void CbusDrvInitCbusRegsList(void) { HDMI_RegisterWrite(HDMIRX_CBUS_r_dev_state, MHL_DEV_STATE); HDMI_RegisterWrite(HDMIRX_CBUS_r_mhl_version, MHL_VERSION); HDMI_RegisterWrite(HDMIRX_CBUS_r_dev_cat, MHL_DEV_CAT_POW_PLIM); HDMI_RegisterWrite(HDMIRX_CBUS_r_adopter_id_h, MHL_DEV_CAT_ADOPTER_ID_H); HDMI_RegisterWrite(HDMIRX_CBUS_r_adopter_id_l, MHL_DEV_CAT_ADOPTER_ID_L); HDMI_RegisterWrite(HDMIRX_CBUS_r_vid_link_mode, MHL_VID_LINK_MODE); HDMI_RegisterWrite(HDMIRX_CBUS_r_log_dev_map, MHL_LOG_DEV_MAP); HDMI_RegisterWrite(HDMIRX_CBUS_r_bandwidth, MHL_LINK_CLK_FREQUENCY); HDMI_RegisterWrite(HDMIRX_CBUS_r_feature_flag, MHL_FEATURE_SUPPORT); HDMI_RegisterWrite(HDMIRX_CBUS_r_int_stat_size, MHL_INT_STAT_SIZE); } //------------------------------------------------------------------------------ // Function: CbusDrvStatus // Description: Returns a status flag word containing CBUS driver-specific // information about the state of the device. // Parameters: none // Returns: status flags word for the CBUS Driver //------------------------------------------------------------------------------ CBUS_DRV_STATUS_e CbusDrvStatus(void) { CBUS_DRV_STATUS_e statusFlags; statusFlags = pDrvCbus->statusFlags; pDrvCbus->statusFlags &= ~(CBUS_INT | CBUS_TRANS_INT | CBUS_LINK_INT | CBUS_WAKE_INT |CBUS_DISCV_INT |CBUS_CONNT_INT |CBUS_ATTACH_INT | CBUS_DEATCH_INT); // INT flag only valid first time it is read. return(statusFlags); } //------------------------------------------------------------------------------ // Function: CbusDrvInterruptStatusGet // Description: Returns the last Interrupt Status data retrieved by the CBUS ISR. // Parameters: pData - pointer to return data buffer(1 byte). // Returns: pData - Destination for interrupt status data. //------------------------------------------------------------------------------ void CbusDrvInterruptStatusGet(UINT32 *pData, UINT32 *pData2) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pData = pDrvCbus->CBUS_TRANS_INT_STATUS; *pData2 = pDrvCbus->CBUS_LINK_INT_STATUS; } //------------------------------------------------------------------------------ // Function: CbusDrvInterruptStatusSet // Description: Clears the interrupt variable // Parameters: channel //------------------------------------------------------------------------------ void CbusDrvInterruptStatusSet(UINT32 intBits, UINT32 intBits2) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; pDrvCbus->CBUS_TRANS_INT_STATUS = intBits; pDrvCbus->CBUS_LINK_INT_STATUS = intBits; } //------------------------------------------------------------------------------ // Function: CbusDrvConnectedGet // Description: Returns the Connected Status retrieved by the CBUS ISR. // Parameters: pData - pointer to return data buffer(1 byte). // Returns: pData - Destination for bus status data. //------------------------------------------------------------------------------ void CbusDrvConnectedGet(UINT8 *pData) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pData = pDrvCbus->Connected; } //------------------------------------------------------------------------------ // Function: CbusDrvSrcPathEnStatusGet // Description: Returns the SrcPathEn Status of DrvCbus // Parameters: None // Returns: SrcPathEn Status //------------------------------------------------------------------------------ BOOL CbusDrvSrcPathEnStatusGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; return pDrvCbus->SrcPathEn; } //------------------------------------------------------------------------------ // Function: CbusDrvMSCSubDataGet // Description: Returns the MSC sub-cmd and data bytes retrieved by the CBUS ISR. // Parameters: pbCmdType, pbData - pointer to return data // Returns: pbCmdType - the oldest received MSC sub-command type value // pbData - the oldest received MSC sub-command data value // return TRUE if data is available, otherwise return FALSE //------------------------------------------------------------------------------ BOOL CbusDrvMSCSubDataGet(UINT8 *pbCmdType, UINT8 *pbData) { CbusDrvInstanceData_t *pDrvCbus; BOOL success = TRUE; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->stMscSubCmd_R.bLock == TRUE) { mhldbg("[%s] data lockedn", __FUNCTION__); success = FALSE; } else { if(pDrvCbus->stMscSubCmd_R.bSize > 0) { mhldbg("[%s] CmdType:0x%x Data:0x%x size:%d SIndex:%d EIndex:%d\n", __FUNCTION__, pDrvCbus->stMscSubCmd_R.bCmdType[pDrvCbus->stMscSubCmd_R.bStartIndex], pDrvCbus->stMscSubCmd_R.bData[pDrvCbus->stMscSubCmd_R.bStartIndex], pDrvCbus->stMscSubCmd_R.bSize, pDrvCbus->stMscSubCmd_R.bStartIndex, pDrvCbus->stMscSubCmd_R.bEndIndex); *pbCmdType = pDrvCbus->stMscSubCmd_R.bCmdType[pDrvCbus->stMscSubCmd_R.bStartIndex]; *pbData= pDrvCbus->stMscSubCmd_R.bData[pDrvCbus->stMscSubCmd_R.bStartIndex]; pDrvCbus->stMscSubCmd_R.bSize--; if(pDrvCbus->stMscSubCmd_R.bSize != 0) pDrvCbus->stMscSubCmd_R.bStartIndex = (pDrvCbus->stMscSubCmd_R.bStartIndex + 1) %MHL_MSC_SUB_CMD_MAX_SIZE; success = TRUE; } else success = FALSE; } return success; } //------------------------------------------------------------------------------ // Function: CbusDrvMSCSubDataInsert // Description: Insert the MSC sub-cmd and data bytes // Parameters: bCmdType - MSC sub-command type value // bData - MSC sub-command data value // return TRUE if data is inserted successful, otherwise return FALSE //------------------------------------------------------------------------------ BOOL CbusDrvMSCSubDataInsert(UINT8 bCmdType, UINT8 bData) { CbusDrvInstanceData_t *pDrvCbus; BOOL success = TRUE; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->stMscSubCmd_R.bLock == TRUE) { mhldbg("[%s] data lockedn", __FUNCTION__); success = FALSE; } else { pDrvCbus->stMscSubCmd_R.bLock = TRUE; if(pDrvCbus->stMscSubCmd_R.bSize == MHL_MSC_SUB_CMD_MAX_SIZE) success = FALSE; else { if(pDrvCbus->stMscSubCmd_R.bSize != 0) pDrvCbus->stMscSubCmd_R.bEndIndex = (pDrvCbus->stMscSubCmd_R.bEndIndex + 1) %MHL_MSC_SUB_CMD_MAX_SIZE; pDrvCbus->stMscSubCmd_R.bCmdType[pDrvCbus->stMscSubCmd_R.bEndIndex] = bCmdType; pDrvCbus->stMscSubCmd_R.bData[pDrvCbus->stMscSubCmd_R.bEndIndex] = bData; pDrvCbus->stMscSubCmd_R.bSize++; mhldbg("[%s] CmdType:0x%x Data:0x%x size:%d SIndex:%d EIndex:%d\n", __FUNCTION__, pDrvCbus->stMscSubCmd_R.bCmdType[pDrvCbus->stMscSubCmd_R.bEndIndex], pDrvCbus->stMscSubCmd_R.bData[pDrvCbus->stMscSubCmd_R.bEndIndex], pDrvCbus->stMscSubCmd_R.bSize, pDrvCbus->stMscSubCmd_R.bStartIndex, pDrvCbus->stMscSubCmd_R.bEndIndex); } pDrvCbus->stMscSubCmd_R.bLock = FALSE; } return success; } //------------------------------------------------------------------------------ // Function: CbusDrvMsgDataGet // Description: Returns the last MSG data retrieved by the CBUS ISR. // Parameters: pData - pointer to return data buffer(?? bytes). // Returns: pData - Destination for msg data. //------------------------------------------------------------------------------ void CbusDrvMsgDataGet(UINT8 *pData0, UINT8 *pData1) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pData0 = pDrvCbus->msgData0; *pData1 = pDrvCbus->msgData1; } //------------------------------------------------------------------------------ // Function: CbusDrvDevCapGet // Description: Returns the Device Capability data retrieved by the CBUS ISR. // Parameters: pOffset - return offset // pData - return fetched data //------------------------------------------------------------------------------ void CbusDrvDevCapGet(UINT8 *pOffset, UINT8 *pData) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pOffset = pDrvCbus->bReadDevCap_Offset; *pData = pDrvCbus->bReadDevCap_Data; } //------------------------------------------------------------------------------ // Function: CbusDrvDdcAbortReasonGet // Description: Returns the last DDC Abort reason received by the CBUS ISR. // Parameters: pData - pointer to return data buffer(1 byte). // Returns: pData - Destination for DDC Abort reason data. //------------------------------------------------------------------------------ void CbusDrvDdcAbortReasonGet(UINT8 *pData) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pData = pDrvCbus->ddcAbortReason; } //------------------------------------------------------------------------------ // Function: CbusDrvMscAbortReasonGet // Description: Returns the last MSC Abort reason received by the CBUS ISR. // Parameters: pData - pointer to return data buffer(1 byte). // Returns: pData - Destination for MSC Abort reason data. //------------------------------------------------------------------------------ void CbusDrvMscAbortReasonGet(UINT8 *pData) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pData = pDrvCbus->MscAbortReason; } //------------------------------------------------------------------------------ // Function: CbusDrvMscFailReasonGet // Description: Returns the last MSC Fail reason received by the CBUS ISR. // Parameters: pData - pointer to return data buffer(1 byte). // Returns: pData - Destination for MSC Fail reason data. //------------------------------------------------------------------------------ void CbusDrvMscFailReasonGet(UINT8 *pData) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; *pData = pDrvCbus->MscFailReason; } //------------------------------------------------------------------------------ // Function: CbusDrvDevCapReadyGet // Description: Returns if the peer's device capability values are ready // Parameters: channel // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvDevCapReadyGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_DCAP_RDY_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_DCAP_RDY_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvDevCapChangedGet // Description: Returns if the peer's device capability values are changed // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvDevCapChangedGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_DCAP_CHG_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_DCAP_CHG_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvReqWrtGet // Description: Returns if the peer is requesting for scratchpad write permission // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvReqWrtGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_REQ_WRT_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_REQ_WRT_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvGrtWrtGet // Description: Returns if the peer is requesting for scratchpad write permission // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvGrtWrtGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_GRT_WRT_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_GRT_WRT_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvNackFromPeerGet // Description: Returns the last MSC NACK received by the CBUS ISR. // Parameters: NONE // Returns: TRUE if a new MSC NACK data was received, FALSE if not. //------------------------------------------------------------------------------ BOOL CbusDrvNackFromPeerGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_NACK_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_NACK_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvAbortFromPeerGet // Description: Returns the last MSC Abort received by the CBUS ISR. // Parameters: NONE // Returns: TRUE if a new MSC ABORT data was received, FALSE if not. //------------------------------------------------------------------------------ BOOL CbusDrvAbortFromPeerGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_ABORT_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_ABORT_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvIneffectCodeFromPeerGet // Description: Returns the last MSC Ineffect Code received by the CBUS ISR. // Parameters: NONE // Returns: TRUE if a new MSC INEFFECT_CODE data was received, FALSE if not. //------------------------------------------------------------------------------ BOOL CbusDrvIneffectCodeFromPeerGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_INEFFECT_CODE_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_INEFFECT_CODE_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvWrtBurstAckGet // Description: Returns if the peer is return ACK for WRITE_BURST // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvWrtBurstAckGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_WRT_BURST_ACK_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_WRT_BURST_ACK_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvWrtStateAckGet // Description: Returns if the peer is return ACK for WRITE_STATE // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvWrtStateAckGet(void) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_WRT_STATE_ACK_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_WRT_STATE_ACK_RECEIVED_FM_PEER; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: CbusDrvWrtStateAckInfoGet // Description: Returns if the peer is return ACK for WRITE_STATE // Returns: TRUE/FALSE //------------------------------------------------------------------------------ BOOL CbusDrvWrtStateAckInfoGet(UINT8 *pOffset, UINT8 *pData) { CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->statusFlags & CBUS_WRT_STATE_ACK_RECEIVED_FM_PEER) { pDrvCbus->statusFlags &= ~CBUS_WRT_STATE_ACK_RECEIVED_FM_PEER; *pOffset = pDrvCbus->AckWrtStatOffset; *pData = pDrvCbus->AckWrtStatData; return(TRUE); } return(FALSE); } //------------------------------------------------------------------------------ // Function: DrvMHLPortSelectBitsGet // Description: Reads the MHL selected port(s)bit-field. // Parameters: None // Returns: MHL selected port(s)bit-field. // //------------------------------------------------------------------------------ UINT8 DrvMHLPortSelectBitsGet(void) { return(HDMI_RegisterRead(HDMIRX_R_mhl_port_sel)); } //------------------------------------------------------------------------------ // Function: CbusDrvWriteCommand // Description: Write the specified Sideband Channel command to the CBUS. // Command can be a MSC_MSG command(RCP/RAP/UCP..), or another command // such as READ_DEVCAP, GET_VENDOR_ID, SET_HPD, CLR_HPD, etc. // // Parameters: channel - CBUS channel to write // pReq - Pointer to a cbus_req_t structure containing the // command to write // Returns: TRUE - successful write // FALSE - write failed //------------------------------------------------------------------------------ BOOL CbusDrvWriteCommand(cbus_req_t *pReq) { BOOL success = TRUE; #ifdef CBUS_DETAIL_DEBUG_MSG UINT8 i = 0; UINT8 bStr[100] = ""; #endif CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; if(pDrvCbus->Connected) { //print request for debug /* printk("[MHL] %s cmd:0x%x len:%d data:", __FUNCTION__, pReq->command, pReq->length); for(i = 0; i < pReq->length; i++) printk("0x%x ", pReq->msgData[i]); printk("\n"); */ switch(pReq->command) { case MHL_SET_INT: // Set one interrupt register = 0x60 mhldbg("[%s] MHL_SET_INT data:0x%02x\n", __FUNCTION__, pReq->msgData[0]); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_offset_i, pReq->offsetData + 0x20); // set offset HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_din, pReq->msgData[0]); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_req,1); break; case MHL_WRITE_STAT: // Write one status register = 0x60 | 0x80 mhldbg("[%s] MHL_WRITE_STAT data:0x%02x\n", __FUNCTION__, pReq->msgData[0]); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_offset_i, pReq->offsetData + 0x30); // set offset HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_din,pReq->msgData[0]); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_req,1); break; case MHL_READ_DEVCAP: mhldbg("[%s] MHL_READ_DEVCAP offset:0x%x\n", __FUNCTION__, pReq->offsetData); HDMI_RegisterWrite(HDMIRX_CBUS_r_red_devc_offset,pReq->offsetData); HDMI_RegisterWrite(HDMIRX_CBUS_r_red_devc_req, 1); break; case MHL_GET_STATE: mhldbg("[%s] MHL_GET_STATE data:0x%02x\n", __FUNCTION__, pReq->msgData[0]); // Set the offset and outgoing data byte right away HDMI_RegisterWrite(HDMIRX_CBUS_r_get_state_data,pReq->msgData[0]); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_state_req, 1); break; case MHL_GET_VENDOR_ID: mhldbg("[%s] MHL_GET_VENDOR_ID\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_ven_id_req, 1); break; case MHL_SET_HPD: mhldbg("[%s] MHL_SET_HPD\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_set_hpd_req,1); break; case MHL_CLR_HPD: mhldbg("[%s] MHL_CLR_HPD\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_clr_hpd_req,1); break; case MHL_GET_SC1_ERRORCODE: // 0x69 - Get channel 1 command error code mhldbg("[%s] MHL_GET_SC1_ERRORCODE\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_src1_err_req,1); break; case MHL_GET_DDC_ERRORCODE: // 0x6A - Get DDC channel command error code. mhldbg("[%s] MHL_GET_DDC_ERRORCODE\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_ddc_err_req,1); break; case MHL_GET_MSC_ERRORCODE: // 0x6B - Get MSC command error code. mhldbg("[%s] MHL_GET_MSC_ERRORCODE\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_msc_err_req,1); break; case MHL_GET_SC3_ERRORCODE: // 0x6D - Get channel 3 command error code. mhldbg("[%s] MHL_GET_SC3_ERRORCODE\n", __FUNCTION__); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_src3_err_req,1); break; case MHL_MSC_MSG: mhldbg("[%s] MHL_MSC_MSG data:0x%02x 0x%02x\n", __FUNCTION__, pReq->msgData[0], pReq->msgData[1]); switch(pReq->msgData[0]) { case MHL_MSC_MSG_RCP: // MSC Sub-Command 0x10 HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_cmd_code,pReq->msgData[1]); HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_cmd_req,1); break; case MHL_MSC_MSG_RAP: // MSC Sub-Command 0x20 HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_cmd_code,pReq->msgData[1]); HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_cmd_req,1); break; case MHL_MSC_MSG_UCP: // MSC Sub-Command 0x30 HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_cmd_code,pReq->msgData[1]); HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_cmd_req,1); break; case MHL_MSC_MSG_RAPK: // MSC Sub-Command 0x21 HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_act_ack_code,pReq->msgData[1]); HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_act_ack_req,1); break; default: break; } break; case MHL_WRITE_BURST: #ifdef CBUS_DETAIL_DEBUG_MSG memset(bStr, 0, 100); for(i = 0; i< MHL_MAX_BUFFER_SIZE;i++) { char bTemp[10] = ""; sprintf(bTemp, "0x%x ",pReq->msgData[i]); strcat(bStr,bTemp); } mhldbg("[%s] MHL_WRITE_BURST len:%d data:%s\n", __FUNCTION__, pReq->length, bStr); #else mhldbg("[%s] MHL_WRITE_BURST len:%d\n", __FUNCTION__, pReq->length); #endif HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_offset_i, pReq->offsetData + 0x40); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_num, pReq->length); // Now copy all bytes from array to local scratchpad HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_dina, *((UINT32*)&pReq->msgData[0])); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_dinb, *((UINT32*)&pReq->msgData[4])); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_dinc, *((UINT32*)&pReq->msgData[8])); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_dind, *((UINT32*)&pReq->msgData[12])); HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_req,1);// Trigger the CBUS command transfer break; default: success = FALSE; break; } } else { success = FALSE; } return(success); } //------------------------------------------------------------------------------ // Function: CbusDrvInitialize // Description: Attempts to initialize the CBUS. If register reads return 0xFF, // it declares error in initialization. // Initializes discovery enabling registers and anything needed in // config register, interrupt masks. // Returns: TRUE if no problem //------------------------------------------------------------------------------ BOOL CbusDrvInitialize(void) { BOOL success = TRUE; /* Initialize CBUS System Reg. */ sysset_Cbus_Init(); /* Initialize CBUS channels. */ // Setup local DEVCAP registers for read by the peer CbusDrvInitCbusRegsList(); //set supported RCP key CbusDrvSetSupportRcpKey(); //clear all driver status memset(pDrvCbus, 0, sizeof(CbusDrvInstanceData_t)); //Set reset=0(0AA8[0])to enable engine // Enable CBUS_TRANS_INT HDMI_RegisterWrite(HDMIRX_CBUS_r_intr_en1, rcp_act_intr| ucp_cmd_intr| ucp_act_intr| //EDID_rd_intr| //msge_act_intr| //OTHR_cmd_intr| //device_status2_intr| //device_status3_intr| //get_ddc_err_intr| get_msc_err_intr| get_src1_err_intr| get_src3_err_intr| rap_cmd_intr| rap_act_ack_intr| rap_act_intr| rcp_cmd_intr| connected_rdy_intr| link_mode_intr| wrt_burst_intr| set_hpd_intr| clr_hpd_intr| //get_state_intr| //get_ven_id_intr| red_devc_intr| dcap_chg_intr| dscr_chg_intr| req_wrt_intr| grt_wrt_intr| req_3d_intr| //edid_chg_intr| wrt_stat_intr); // Enable CBUS_LINK_INT HDMI_RegisterWrite(HDMIRX_CBUS_cfg_wake_int_en,1);// HDMI_RegisterWrite(HDMIRX_CBUS_cfg_discv_int_en,1);// HDMI_RegisterWrite(HDMIRX_CBUS_cfg_connt_int_en,1);// HDMI_RegisterWrite(HDMIRX_CBUS_cfg_attach_int_en,1);// HDMI_RegisterWrite(HDMIRX_CBUS_cfg_detach_int_en,1);// HDMI_RegisterWrite(HDMIRX_R_align_cnt_24,4); HDMI_RegisterWrite(HDMIRX_R_align_cnt_pp,4); //reset cbus HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_r_reset_reg, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_buf_reset, 1); HDMI_DelayMs(100); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_r_reset_reg, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_buf_reset, 0); //Set Min and Max wake up pulse width unit HDMI_RegisterWrite(HDMIRX_CBUS_cfg_wake_pulse_w1_max, 0xba001);//IC default 1720 HDMI_RegisterWrite(HDMIRX_CBUS_cfg_wake_pulse_w2_max, 0x1aa004);//IC default 1720 HDMI_RegisterWrite(HDMIRX_CBUS_cfg_wake_pulse_w1_min, 0x4dfa8);//For MEIZU MX HDMI_RegisterWrite(HDMIRX_CBUS_cfg_wake_pulse_w2_min, 0x12C000);//For MEIZU MX HDMI_RegisterWrite(HDMIRX_CBUS_cfg_bittime_max, 30);//MHL CTS 4.3.18.1 HDMI_RegisterWrite(HDMIRX_CBUS_cfg_ack0_start, 8);//MHL CTS 4.3.8.1 HDMI_RegisterWrite(HDMIRX_CBUS_cfg_ack0_end, 21);//MHL CTS 4.3.8.1 HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_arb, 6);//MHL CTS 4.3.8.1 HDMI_RegisterWrite(HDMIRX_CBUS_r_abort_next_reg, 40000);//@IST 20160712 MHL CTS 6.3.6.5 HDMI_RegisterWrite(HDMIRX_CBUS_r_msc_r_cmd_receiver_timeout_reg, 4000);//MHL CTS 6.3.10.6 HDMI_RegisterWrite(HDMIRX_CBUS_cfg_txclk_div, 24);//MHL CTS 4.3.10.2 331 A1 ECO modify HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_float_min, 0x168000);//MHL CTS 4.3.5.1 HDMI_RegisterWrite(HDMIRX_CBUS_r_msc_s_pkt_sender_timeout_reg, 1756);//MHL CTS 6.3.10.6 HDMI_RegisterWrite(HDMIRX_CBUS_r_msc_s_pkt_receiver_timeout_reg, 1756);//MHL CTS 6.3.10.6 HDMI_RegisterWrite(HDMIRX_CBUS_r_msc_r_pkt_receiver_timeout_reg, 1756);//MHL CTS 6.3.10.6 //disable auto-retry HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_auto_nack_retry, 0); HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_auto_nack_retry, 0); HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_auto_nack_retry, 0); //Set Min and Max discover pulse width unit //HDMI_RegisterWrite(HDMIRX_CBUS_cfg_discv_width_min, 1720);//IC default 1720 //HDMI_RegisterWrite(HDMIRX_CBUS_cfg_discv_width_min, 3250);//IC default 3250 return(success); } //------------------------------------------------------------------------------ // Function: CbusDrvProcessInterrupts // Description: Check CBUS registers for a CBUS event //------------------------------------------------------------------------------ void CbusDrvProcessInterrupts(void) { UINT32 CbusTransIntStatus, CbusLinkIntStatus; //UINT8 writeBurstLen; UINT8 bTmpData = 0; CbusDrvInstanceData_t *pDrvCbus; pDrvCbus = &cbusDrvInstance; // Read CBUS interrupt status. Return if nothing happening on the interrupt front CbusTransIntStatus = HDMI_RegisterRead(HDMIRX_CBUS_r_intr_status1); CbusLinkIntStatus = HDMI_RegisterRead(CBUS_LINK_8034_DW_8034); CbusLinkIntStatus = CbusLinkIntStatus & 0xFF; // An interrupt occurred, save the status. pDrvCbus->CBUS_TRANS_INT_STATUS = CbusTransIntStatus; pDrvCbus->CBUS_LINK_INT_STATUS = CbusLinkIntStatus; pDrvCbus->statusFlags |= CBUS_INT ; if(CbusTransIntStatus) { /*********************************************** * Interrupts of reciving command from Src ************************************************/ // Get any VS or MSC data received if(CbusTransIntStatus & rcp_act_intr) { mhldbg("[INT] rcp_act_intr\n"); //pDrvCbus->MSCSubCmd = MHL_MSC_MSG_RCP; //pDrvCbus->RCP_ACT_NUM = 0; while(HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_act_num) > 0) { //pDrvCbus->RCP_ACT_CODE = HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_act_code); //if(pDrvCbus->RCP_ACT_NUM == MHL_MSC_SUB_CMD_MAX_SIZE) bTmpData = HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_act_code); mhldbg("recv RCP 0x%x size:%d\n", bTmpData, HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_act_num)); if(CbusDrvMSCSubDataInsert(MHL_MSC_MSG_RCP, bTmpData) == FALSE) { #if 0 //drop received mssages when MSCSubData stack full mhldbg("druop received RCP 0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_act_code)); HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_act_ack, 1); #else mhldbg("ERR! recv RCP Full or Locked\n"); break; //MSCSubData size is full, process remain message later #endif } else { HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_act_ack, 1); //send RCPK } } if(HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_act_num) == 0) HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_act_intr, 1); //Clear HW interrupt flag } if(CbusTransIntStatus & rap_act_intr) { mhldbg("[INT] rap_act_intr\n"); bTmpData = HDMI_RegisterRead(HDMIRX_CBUS_r_rap_act_code); mhldbg("recv RAP 0x%x\n", bTmpData); if(CbusDrvMSCSubDataInsert(MHL_MSC_MSG_RAP, bTmpData) == FALSE) { mhldbg("ERR! recv RAP Full or Locked\n"); } else { HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_act_intr, 1); //Clear HW interrupt flag } } if(CbusTransIntStatus & ucp_act_intr) { mhldbg("[INT] ucp_act_intr\n"); while(HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_act_num) > 0) { if(pDrvCbus->stMscSubCmd_R.bSize == MHL_MSC_SUB_CMD_MAX_SIZE) { #if 0 //drop received mssages when MSCSubData stack full mhldbg("druop received UCP 0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_act_code)); HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_act_ack, 1); #else break; //MSCSubData size is full, handle remain message later #endif } else { pDrvCbus->stMscSubCmd_R.bEndIndex = (pDrvCbus->stMscSubCmd_R.bEndIndex + 1) %MHL_MSC_SUB_CMD_MAX_SIZE; pDrvCbus->stMscSubCmd_R.bCmdType[pDrvCbus->stMscSubCmd_R.bEndIndex] = MHL_MSC_MSG_UCP; pDrvCbus->stMscSubCmd_R.bData[pDrvCbus->stMscSubCmd_R.bEndIndex] = HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_act_code); HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_act_ack, 1); pDrvCbus->stMscSubCmd_R.bSize++; } } if(HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_act_num) == 0) HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_act_intr, 1); //Clear HW interrupt flag } //Peer's Device Capability ready if(CbusTransIntStatus & connected_rdy_intr) { mhldbg("[INT] connected_rdy_intr\n"); pDrvCbus->statusFlags |= CBUS_DCAP_RDY_RECEIVED_FM_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_connected_rdy_intr, 1);//Clear HW interrupt flag } //Peer's change link mode if(CbusTransIntStatus & link_mode_intr) { mhldbg("[INT] link_mode_intr status:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_link_mode_status)); if((HDMI_RegisterRead(HDMIRX_CBUS_r_link_mode_status) & 0x08) != 0) pDrvCbus->SrcPathEn = TRUE; else pDrvCbus->SrcPathEn = FALSE; HDMI_RegisterWrite(HDMIRX_CBUS_r_link_mode_intr, 1);//Clear HW interrupt flag #ifdef CONFIG_HDMI_MHL_PORT if( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT) { HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 0);//For CTS Nosiglal issue HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 1); } #endif } //Peer changed our device scratchpad if(CbusTransIntStatus & dscr_chg_intr) { mhldbg("[INT] dscr_chg_intr\n"); pDrvCbus->statusFlags |= CBUS_SCRATCHPAD_WRITTEN_BY_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_dscr_chg_intr, 1);//Clear HW interrupt flag } //Peer's Device Capability changed if(CbusTransIntStatus & dcap_chg_intr) { mhldbg("[INT] dcap_chg_intr\n"); pDrvCbus->statusFlags |= CBUS_DCAP_CHG_RECEIVED_FM_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_dcap_chg_intr, 1);//Clear HW interrupt flag } //Peer sends Request-to-Write if(CbusTransIntStatus & req_wrt_intr) { mhldbg("[INT] req_wrt_intr\n"); pDrvCbus->statusFlags |= CBUS_REQ_WRT_RECEIVED_FM_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_req_wrt_intr, 1);//Clear HW interrupt flag } //Peer sends Grant-to-Write if(CbusTransIntStatus & grt_wrt_intr) { mhldbg("[INT] grt_wrt_intr\n"); pDrvCbus->statusFlags |= CBUS_GRT_WRT_RECEIVED_FM_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_grt_wrt_intr, 1);//Clear HW interrupt flag } //Peer request for 3D information if(CbusTransIntStatus & req_3d_intr) { mhldbg("[INT] req_3d_intr\n"); pDrvCbus->statusFlags |= CBUS_3D_REQ_RECEIVED_FM_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_req_3d_intr, 1);//Clear HW interrupt flag } /*********************************************** * Interrupts of sending command to Src ************************************************/ //TX if(CbusTransIntStatus & rcp_cmd_intr) { mhldbg("[INT] rcp_cmd_intr code:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_cmd_code)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_cmd_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]rcp_cmd_fail { mhldbg("[INT] rcp_cmd_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)//[1] rcp_cmd_ineffect_code { mhldbg("[INT] rcp_cmd_intr INEFFECT CODE\n"); pDrvCbus->statusFlags |= CBUS_INEFFECT_CODE_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)//[2] msc_s_nack_event { mhldbg("[INT] rcp_cmd_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x08)//[3] msc_s_nack_event { mhldbg("[INT] rcp_cmd_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason!=0) { pDrvCbus->RCPE_STATUS_CODE = HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_cmd_rcpe_statuscode_from_src); mhldbg("[INT] rcp_cmd_intr RCPE status:0x%x\n", pDrvCbus->RCPE_STATUS_CODE); } pDrvCbus->RCPK_CMD_CODE = HDMI_RegisterRead(HDMIRX_CBUS_r_rcp_cmd_rcpk_code_from_src); mhldbg("[INT] rcp_cmd_intr RCPK:0x%x\n", pDrvCbus->RCPK_CMD_CODE); HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_cmd_intr, 1); } if(CbusTransIntStatus & ucp_cmd_intr) { mhldbg("[INT] ucp_cmd_intr code:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_cmd_code)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_cmd_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]ucp_cmd_fail { mhldbg("[INT] ucp_cmd_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]ucp_cmd_ineffect_code { mhldbg("[INT] ucp_cmd_intr INEFFECT CODE\n"); pDrvCbus->statusFlags |= CBUS_INEFFECT_CODE_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_abort_event { mhldbg("[INT] ucp_cmd_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x08)// [3]msc_s_nack_event { mhldbg("[INT] ucp_cmd_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason!=0) { pDrvCbus->UCPE_STATUS_CODE = HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_cmd_ucpe_statuscode_from_src); } pDrvCbus->UCPK_CMD_CODE = HDMI_RegisterRead(HDMIRX_CBUS_r_ucp_cmd_ucpk_code_from_src); mhldbg("[INT] ucp_cmd_intr UCPK:0x%x\n", pDrvCbus->UCPK_CMD_CODE); HDMI_RegisterWrite(HDMIRX_CBUS_r_ucp_cmd_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & rap_cmd_intr) { mhldbg("[INT] rap_cmd_intr code:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_rap_cmd_code)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_rap_cmd_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]rap_cmd_fail: no rapk, command fail { mhldbg("[INT] rap_cmd_intr no rapk, command fail\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] rap_cmd_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] rap_cmd_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } pDrvCbus->RAPK_CMD_CODE = HDMI_RegisterRead(HDMIRX_CBUS_r_rap_cmd_rapk); HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_cmd_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & rap_act_ack_intr) { mhldbg("[INT] rap_act_ack_intr code:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_rap_act_code)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_rap_act_ack_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]rap_act_ack_fail { mhldbg("[INT] rap_act_ack_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] rap_act_ack_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] rap_act_ack_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_rap_act_ack_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & wrt_burst_intr) { mhldbg("[INT] wrt_burst_intr\n"); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_wrt_burst_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]wrt_burst_fail { mhldbg("[INT] wrt_burst_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]wrt_burst_offset_invalid { mhldbg("[INT] wrt_burst_intr OFFSET INVALID\n"); } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_abort_event { mhldbg("[INT] wrt_burst_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x08)// [3]msc_s_nack_event { mhldbg("[INT] wrt_burst_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason == 0) pDrvCbus->statusFlags |= CBUS_WRT_BURST_ACK_RECEIVED_FM_PEER; HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_burst_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & set_hpd_intr) { mhldbg("[INT] set_hpd_intr\n"); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_set_hpd_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]set_hpd_fail { mhldbg("[INT] set_hpd_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] set_hpd_intr ABORT\n"); } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] set_hpd_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_set_hpd_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & clr_hpd_intr) { mhldbg("[INT] clr_hpd_intr\n"); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_clr_hpd_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]clr_hpd_fail { mhldbg("[INT] clr_hpd_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] clr_hpd_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] clr_hpd_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_clr_hpd_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & wrt_stat_intr) { pDrvCbus->AckWrtStatOffset = HDMI_RegisterRead(HDMIRX_CBUS_r_wrt_stat_offset_i); pDrvCbus->AckWrtStatData = HDMI_RegisterRead(HDMIRX_CBUS_r_wrt_stat_din); mhldbg("[INT] wrt_stat_intr offset:0x%x data:0x%x\n", pDrvCbus->AckWrtStatOffset, pDrvCbus->AckWrtStatData); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_wrt_stat_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]wrt_stat_fail { mhldbg("[INT] wrt_stat_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]wrt_stat_offset_invalid { mhldbg("[INT] wrt_stat_intr OFFSET INVALID\n"); } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_abort_event { mhldbg("[INT] wrt_stat_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x08)// [3]msc_s_nack_event { mhldbg("[INT] wrt_stat_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason == 0x0) { pDrvCbus->statusFlags |= CBUS_WRT_STATE_ACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_wrt_stat_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & get_state_intr) { mhldbg("[INT] get_state_intr data:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_get_state_data)); pDrvCbus->MscFailReason= HDMI_RegisterRead(HDMIRX_CBUS_r_get_state_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]get_state_fail { mhldbg("[INT] get_state_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] get_state_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] get_state_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_get_state_intr, 1); } if(CbusTransIntStatus & get_ven_id_intr) { mhldbg("[INT] get_ven_id_intr data:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_get_ven_id_data)); pDrvCbus->MscFailReason= HDMI_RegisterRead(HDMIRX_CBUS_r_get_ven_id_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]get_ven_id_fail { mhldbg("[INT] get_state_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] get_state_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] get_state_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_get_ven_id_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & get_src1_err_intr) { mhldbg("[INT] get_src1_err_intr data:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_get_src1_err_data)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_get_src1_err_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]get_src1_err_fail { mhldbg("[INT] get_src1_err_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] get_src1_err_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] get_src1_err_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_get_src1_err_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & get_src3_err_intr) { mhldbg("[INT] get_src3_err_intr data:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_get_src3_err_data)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_get_src3_err_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]get_src3_err_fail { mhldbg("[INT] get_src3_err_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] get_src3_err_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] get_src3_err_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_get_src3_err_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & red_devc_intr) { pDrvCbus->bReadDevCap_Data = HDMI_RegisterRead(HDMIRX_CBUS_r_red_devc_data_reg); pDrvCbus->bReadDevCap_Offset = HDMI_RegisterRead(HDMIRX_CBUS_r_red_devc_offset); mhldbg("[INT] red_devc_intr offset:0x%x data:0x%x\n", pDrvCbus->bReadDevCap_Offset, pDrvCbus->bReadDevCap_Data); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_red_devc_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]red_devc_fail { mhldbg("[INT] red_devc_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]red_devc_offset_invalid { mhldbg("[INT] red_devc_intr OFFSET INVALID\n"); } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_abort_event { mhldbg("[INT] red_devc_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x08)// [3]msc_s_nack_event { mhldbg("[INT] red_devc_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } HDMI_RegisterWrite(HDMIRX_CBUS_r_red_devc_intr, 1); //Clear HW interrupt flag } // Check for failure interrupts. if(CbusTransIntStatus & get_ddc_err_intr) { mhldbg("[INT] get_ddc_err_intr data:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_get_ddc_err_data)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_get_ddc_err_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]get_ddc_err_fail { mhldbg("[INT] get_ddc_err_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] get_ddc_err_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] get_ddc_err_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } pDrvCbus->ddcAbortReason = HDMI_RegisterRead(HDMIRX_CBUS_r_get_ddc_err_data); mhldbg("[INT] get_ddc_err_intr data:0x%x\n", pDrvCbus->ddcAbortReason); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_ddc_err_intr, 1);//Clear HW interrupt flag } if(CbusTransIntStatus & get_msc_err_intr) { mhldbg("[INT] get_msc_err_intr data:0x%x\n", HDMI_RegisterRead(HDMIRX_CBUS_r_get_msc_err_data)); pDrvCbus->MscFailReason = HDMI_RegisterRead(HDMIRX_CBUS_r_get_msc_err_fail_reg); if(pDrvCbus->MscFailReason & 0x01)// [0]get_msc_err_fail { mhldbg("[INT] get_msc_err_intr FAIL\n"); } if(pDrvCbus->MscFailReason & 0x02)// [1]msc_s_abort_event { mhldbg("[INT] get_msc_err_intr ABORT\n"); pDrvCbus->statusFlags |= CBUS_ABORT_RECEIVED_FM_PEER; } if(pDrvCbus->MscFailReason & 0x04)// [2]msc_s_nack_event { mhldbg("[INT] get_msc_err_intr NACK\n"); pDrvCbus->statusFlags |= CBUS_NACK_RECEIVED_FM_PEER; } pDrvCbus->MscAbortReason = HDMI_RegisterRead(HDMIRX_CBUS_r_get_msc_err_data); HDMI_RegisterWrite(HDMIRX_CBUS_r_get_msc_err_intr, 1);//Clear HW interrupt flag } } if(CbusLinkIntStatus) { pDrvCbus->statusFlags |= CBUS_LINK_INT; if(CbusLinkIntStatus & wake_int)//[0]HDMIRX_CBUS_wake_int_p { mhldbg("[INT] wake_int\n"); pDrvCbus->statusFlags |= CBUS_WAKE_INT; HDMI_RegisterWrite(HDMIRX_CBUS_wake_int_p, 1);//Clear HW interrupt flag } if(CbusLinkIntStatus & discv_intr)//[1]HDMIRX_CBUS_discv_int__p { mhldbg("[INT] discv_intr\n"); pDrvCbus->Connected = TRUE; pDrvCbus->statusFlags |= CBUS_DISCV_INT; HDMI_RegisterWrite(HDMIRX_CBUS_discv_int__p, 1);//Clear HW interrupt flag } // Bus status changed? if(CbusLinkIntStatus & connt_intr)//[2]HDMIRX_CBUS_connt_int__p { mhldbg("[INT] connt_intr\n"); pDrvCbus->Connected = TRUE; pDrvCbus->statusFlags |= CBUS_CONNT_INT; HDMI_RegisterWrite(HDMIRX_CBUS_connt_int__p, 1);//Clear HW interrupt flag } // CBUS_attach status changed? if(CbusLinkIntStatus & attach_intr)//[3]HDMIRX_CBUS_attach_int__p { mhldbg("[INT] attach_intr\n"); pDrvCbus->Connected = FALSE; pDrvCbus->statusFlags |= CBUS_ATTACH_INT; HDMI_RegisterWrite(HDMIRX_CBUS_attach_int__p, 1);//Clear HW interrupt flag } if(CbusLinkIntStatus & detach_intr)//[4]HDMIRX_CBUS_detach_int__p { mhldbg("[INT] detach_intr\n"); pDrvCbus->Connected = FALSE; pDrvCbus->statusFlags |= CBUS_DEATCH_INT; HDMI_RegisterWrite(HDMIRX_CBUS_detach_int__p, 1);//Clear HW interrupt flag } } } //------------------------------------------------------------------------------ // Function: CbusDrvSetSupportRcpKey // Description: Set supported RCP key //------------------------------------------------------------------------------ void CbusDrvSetSupportRcpKey(void) { HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_vd_key_mapa, 0x2207);//MHL_RCP_CMD_SELECT(0x00),MHL_RCP_CMD_UP(0x01),MHL_RCP_CMD_DOWN(0x02),MHL_RCP_CMD_ROOT_MENU(0x9),MHL_RCP_CMD_EXIT(0x0D) HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_vd_key_mapb, 0x0); HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_vd_key_mapc, 0x0); HDMI_RegisterWrite(HDMIRX_CBUS_r_rcp_vd_key_mapd, 0x0); }