static byte CBusCheckInterruptStatus ( byte channel ) { byte intStatus, result; byte vs_cmd, vs_data; byte writeBurstLen = 0; /* Read CBUS interrupt status. */ intStatus = SiIRegioCbusRead( REG_CBUS_INTR_STATUS, channel ); if( intStatus & BIT_MSC_MSG_RCV ) { printk("( intStatus & BIT_MSC_MSG_RCV )\n"); vs_cmd = SiIRegioCbusRead( REG_CBUS_PRI_VS_CMD, channel ); vs_data = SiIRegioCbusRead( REG_CBUS_PRI_VS_DATA, channel ); } SiIRegioCbusWrite( REG_CBUS_INTR_STATUS, channel, intStatus ); /* Check for interrupts. */ result = STATUS_SUCCESS; intStatus &= (~BIT_HEARTBEAT_TIMEOUT); //don't check heartbeat if( intStatus != 0 ) { if( intStatus & BIT_CONNECT_CHG ) { printk("( intStatus & BIT_CONNECT_CHG )\n"); /* The connection change interrupt has been received. */ result = CBusProcessConnectionChange( channel ); SiIRegioCbusWrite( REG_CBUS_BUS_STATUS, channel, BIT_CONNECT_CHG ); } if( intStatus & BIT_MSC_XFR_DONE ) { printk("( intStatus & BIT_MSC_XFR_DONE )\n"); /* A previous MSC sub-command has been acknowledged by the responder. */ /* Does not include MSC MSG commands. */ l_cbus[ channel].state = CBUS_XFR_DONE; /* Save any response data in the channel request structure to be returned */ /* to the upper level. */ msc_return_cmd = l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].msgData[0] = SiIRegioCbusRead( REG_CBUS_PRI_RD_DATA_1ST, channel ); msc_return_value = l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].msgData[1] = SiIRegioCbusRead( REG_CBUS_PRI_RD_DATA_2ND, channel ); printk ( "\nCBUS:: Transfer Done \n" ); printk ("Response data Received:: %02X\n\n", (int)l_cbus[ channel].request[l_cbus[channel].activeIndex].msgData[0]); result = STATUS_SUCCESS; // Check if we received NACK from Peer writeBurstLen = SiIRegioCbusRead( REG_MSC_WRITE_BURST_LEN, channel ); if( writeBurstLen & MSC_REQUESTOR_DONE_NACK ) { result = ERROR_NACK_FROM_PEER; printk( "NACK received!!! :: %02X\n", (int)writeBurstLen) ; } result = CBusProcessFailureInterrupts( channel, intStatus, result ); } if( intStatus & BIT_MSC_MSG_RCV ) { printk("( intStatus & BIT_MSC_MSG_RCV )\n"); /* Receiving a sub-command, either an actual command or */ /* the response to a command we sent. */ result = CBusProcessSubCommand( channel, vs_cmd, vs_data ); } } return( result ); }
//------------------------------------------------------------------------------ // Function: CBusCheckInterruptStatus // Description: If any interrupts on the specified channel are set, process them. // Returns: SUCCESS or CBUS_SOFTWARE_ERRORS_t error code. //------------------------------------------------------------------------------ static uint8_t CBusCheckInterruptStatus ( void ) { uint8_t result; uint8_t busStatus; uint8_t temp; uint8_t cbusData[2]; result = SUCCESS; if ( SiiDrvCbusIntrFlagGet() ) { //CBUS connction change if ( SiiDrvCbusBusStatusGet( &busStatus ) ) { /* The connection change interrupt has been received. */ pCbus->chState.connected = busStatus ? true : false; DEBUG_PRINT( MSG_DBG, "CBUS:: ----Connection Change---- %s \n", pCbus->chState.connected ? "Connected" : "Disconnected" ); if( pCbus->chState.connected ) { SiiDrvCbusTermCtrl( true ); if ( SiiCbusSendDcapRdy()) { //set DCAP_CHG bit if(SiiMhlRxSendDcapChange()) { // send set_hpd and set path_en bit too SiMhlRxHpdSet(true); } } #if defined(__KERNEL__) SiiOsTimerStart(pCbus->chState.dcapTimer, CBUS_DCAP_READY_TIMER); #else pCbus->chState.dcapTimer = SiiTimerTotalElapsed(); #endif } else { SiiDrvCbusTermCtrl( false ); //set the cbus to idle CBusResetToIdle(); } SiiMhlRxConnNtfy(pCbus->chState.connected); } // Receive CBUS messages if ( SiiDrvCbusVsDataGet( &cbusData[0] ) ) { CBusProcessSubCommand( &cbusData[0] ); } //Cbus message transfer done if ( SiiDrvCbusCmdRetDataGet( &pCbus->chState.request[ CH_ACTIVE_INDEX ].retData[0] ) ) { if (pCbus->chState.state == CBUS_SENT) pCbus->chState.state = CBUS_XFR_DONE; } //Cbus Devcap ready if (SiiDrvCbusDevCapReadyGet ()) { if (!pCbus->chState.dcap_ready) { DEBUG_PRINT( MSG_DBG, "CBUS:: DCap Ready received!\n"); #if defined(__KERNEL__) SiiOsTimerStop(pCbus->chState.dcapTimer); #endif pCbus->chState.dcap_ready = true; // Read Dcap SiiMhlRxReadDevCapReg(0x00); pCbus->chState.dcap_ongoing = true; } } if (SiiDrvCbusDevCapChangedGet ()) { DEBUG_PRINT( MSG_DBG, "CBUS:: DCap Change received!\n"); if (pCbus->chState.dcap_ready) { // Read Dcap if (!pCbus->chState.dcap_ongoing) { SiiMhlRxReadDevCapReg(0x00); pCbus->chState.dcap_ongoing = true; } } } // request received from peer to write into scratchpad if ( SiiDrvCbusReqWrtGet() ) { DEBUG_PRINT( MSG_DBG, "Grant peer's request to write scratchpad\n"); SiiCbusGrtWrt(); } // scratchpad write notification received from peer if ( SiiDrvCbusScratchpadWrtnGet() ) { // send it to app layer SiiMhlRxScratchpadWrittenNtfy(); } // request to write into peer's scratchpad is granted if ( SiiDrvCbusGrtWrtGet() && pCbus->chState.burstWaitState ) { DEBUG_PRINT( MSG_DBG, "Peer sent grant write\n"); SiiCbusWriteBurst(); //Recieve grt, stop burst timer. pCbus->chState.burst [CH_ACTIVE_BURST].burstStatus = CBUS_BURST_IDLE; pCbus->chState.burstWaitState = false; #if defined(__KERNEL__) SiiOsTimerStop(pCbus->chState.burstTimer); #else pCbus->chState.burstTimer = 0; #endif } if ( SiiDrvCbus3DReqGet() ) { DEBUG_PRINT( MSG_DBG, "Peer request 3D infomation\n"); SiiDrvCbusBuild3DData(); SiiDrv3DWriteBurst(); } if( SiiDrvCbusNackFromPeerGet() ) { DEBUG_PRINT( MSG_ERR,( "NACK received from peer\n" )); result |= ERROR_NACK_FROM_PEER; } if( SiiDrvCbusDdcAbortReasonGet( &temp ) ) { DEBUG_PRINT( MSG_DBG, "CBUS DDC ABORT happened, reason: %02X\n", (int)temp ); if (temp & BIT_MSC_ABORT_BY_PEER) //Abort by peer { result |= ERROR_CBUS_ABORT; } else if(temp) { result |= ERROR_CBUS_OTHER; } } if ( SiiDrvCbusMscAbortReasonGet( &temp ) ) { DEBUG_PRINT( MSG_DBG, "MSC CMD aborted, reason: %02X\n", (int)temp ); if (temp & BIT_MSC_ABORT_BY_PEER) //Abort by peer { result |= ERROR_CBUS_ABORT; } if (temp & (BIT_MSC_MAX_RETRY|BIT_MSC_TIMEOUT)) { result |= ERROR_CBUS_TIMEOUT; } if ((temp & ~(ERROR_CBUS_ABORT|BIT_MSC_MAX_RETRY|BIT_MSC_TIMEOUT)) != 0) { result |= ERROR_CBUS_ABORT_OTHER; } } if ( SiiDrvCbusMscAbortResReasonGet( &temp ) ) { DEBUG_PRINT( MSG_DBG, "MSC CMD aborted as Responder , reason: %02X\n", (int)temp ); if (temp & BIT_MSC_ABORT_BY_PEER) //Abort by peer { result |= ERROR_CBUS_ABORT;; } else if(temp) { result |= ERROR_CBUS_OTHER; } } } SiiDrvCbusIntrFlagSet(); return( result ); }