static int Int4Isr( void ) { uint8_t int4Status; int4Status = SiiRegRead(REG_INTR4); if(!int4Status) { } else if(0xFF == int4Status) { return I2C_INACCESSIBLE; }else { TX_DEBUG_PRINT(("INT4 Status = %02X\n", (int) int4Status)); if(int4Status & BIT0) { ProcessScdtStatusChange(); } if(int4Status & BIT2) { MhlTxDrvProcessConnection(); } else if(int4Status & BIT3) { TX_DEBUG_PRINT(("uUSB-A type device detected.\n")); SiiRegWrite(REG_DISC_STAT2, 0x80); SwitchToD3(); return I2C_INACCESSIBLE; } if (int4Status & BIT5) { MhlTxDrvProcessDisconnection(); return I2C_INACCESSIBLE; } if((POWER_STATE_D0_MHL != fwPowerState) && (int4Status & BIT6)) { SwitchToD0(); ProcessRgnd(); } if(fwPowerState != POWER_STATE_D3) { if (int4Status & BIT4) { TX_DEBUG_PRINT(("CBus Lockout\n")); ForceUsbIdSwitchOpen(); ReleaseUsbIdSwitchOpen(); } } } SiiRegWrite(REG_INTR4, int4Status); return I2C_ACCESSIBLE; }
//////////////////////////////////////////////////////////////////// // Int4Isr // // // Look for interrupts on INTR4 (Register 0x74) // 7 = RSVD (reserved) // 6 = RGND Rdy (interested) // 5 = VBUS Low (ignore) // 4 = CBUS LKOUT (interested) // 3 = USB EST (interested) // 2 = MHL EST (interested) // 1 = RPWR5V Change (ignore) // 0 = SCDT Change (interested during D0) //////////////////////////////////////////////////////////////////// static int Int4Isr (void) { uint8_t int4Status; int4Status = SiiRegRead(REG_INT_CTRL); // read status if( int4Status ) { TX_DEBUG_PRINT(("Drv: int4Status test: 0x%02X\n", (int) int4Status)); } int4Status = SiiRegRead(REG_INTR4); // read status if( int4Status ) { TX_DEBUG_PRINT(("Drv: int4Status: 0x%02X\n", (int) int4Status)); } // When I2C is inoperational (D3) and a previous interrupt brought us here, do nothing. if(0xFF == int4Status || 0x87 == int4Status|| 0x38 == int4Status) { return I2C_INACCESSIBLE; } if((int4Status & BIT0)&&( POWER_STATE_D0_MHL == fwPowerState )) // SCDT Status Change { //if (g_chipRevId < 1) ProcessScdtStatusChange(); } // process MHL_EST interrupt if(int4Status & BIT2) // MHL_EST_INT { MhlTxDrvProcessConnection(); } // process USB_EST interrupt else if(int4Status & BIT3) { TX_DEBUG_PRINT(("Drv: uUSB-A type device detected.\n")); SiiRegWrite(REG_DISC_STAT2, 0x80); // Exit D3 via CBUS falling edge SwitchToD3(); return I2C_INACCESSIBLE; } if (int4Status & BIT5) { MhlTxDrvProcessDisconnection(); return I2C_INACCESSIBLE; } if((POWER_STATE_D0_MHL != fwPowerState) && (int4Status & BIT6)) { // Switch to full power mode. SwitchToD0(); // // If a sink is connected but not powered on, this interrupt can keep coming // Determine when to go back to sleep. Say after 1 second of this state. // // Check RGND register and send wake up pulse to the peer // ProcessRgnd(); } // Can't succeed at these in D3 if(fwPowerState != POWER_STATE_D3) { // CBUS Lockout interrupt? if (int4Status & BIT4) { TX_DEBUG_PRINT(("Drv: CBus Lockout\n")); SwitchToD0(); ForceUsbIdSwitchOpen(); ReleaseUsbIdSwitchOpen(); SwitchToD3(); } } SiiRegWrite(REG_INTR4, int4Status); // clear all interrupts return I2C_ACCESSIBLE; }
/////////////////////////////////////////////////////////////////////////// // // CBusProcessErrors // // /////////////////////////////////////////////////////////////////////////// static uint8_t CBusProcessErrors (uint8_t intStatus) { uint8_t result = 0; uint8_t mscAbortReason = 0; uint8_t ddcAbortReason = 0; /* At this point, we only need to look at the abort interrupts. */ intStatus &= (BIT_CBUS_MSC_MR_ABRT| BIT_MSC_XFR_ABORT| BIT_DDC_ABORT); if ( intStatus ) { // result = ERROR_CBUS_ABORT; // No Retry will help /* If transfer abort or MSC abort, clear the abort reason register. */ if( intStatus & BIT_DDC_ABORT) { result = ddcAbortReason = SiiRegRead(REG_DDC_ABORT_REASON); TX_DEBUG_PRINT(("CBUS DDC ABORT happened, reason:: %02X\n", (int)(ddcAbortReason))); } if ( intStatus & BIT_MSC_XFR_ABORT) { result = mscAbortReason = SiiRegRead(REG_PRI_XFR_ABORT_REASON); TX_DEBUG_PRINT(("CBUS:: MSC Transfer ABORTED. Clearing 0x0D\n")); SiiRegWrite(REG_PRI_XFR_ABORT_REASON, 0xFF); MhlTxDrvProcessDisconnection(); } if ( intStatus & BIT_CBUS_MSC_MR_ABRT) { TX_DEBUG_PRINT(("CBUS:: MSC Peer sent an ABORT. Clearing 0x0E\n")); SiiRegWrite(REG_CBUS_PRI_FWR_ABORT_REASON, 0xFF); } // Now display the abort reason. if ( mscAbortReason != 0 ) { TX_DEBUG_PRINT(("CBUS:: Reason for ABORT is ....0x%02X = ", (int)mscAbortReason)); if ( mscAbortReason & CBUSABORT_BIT_REQ_MAXFAIL) { TX_DEBUG_PRINT(("Requestor MAXFAIL - retry threshold exceeded\n")); } if ( mscAbortReason & CBUSABORT_BIT_PROTOCOL_ERROR) { TX_DEBUG_PRINT(("Protocol Error\n")); } if ( mscAbortReason & CBUSABORT_BIT_REQ_TIMEOUT) { TX_DEBUG_PRINT(("Requestor translation layer timeout\n")); } if ( mscAbortReason & CBUSABORT_BIT_PEER_ABORTED) { TX_DEBUG_PRINT( ("Peer sent an abort\n")); } if ( mscAbortReason & CBUSABORT_BIT_UNDEFINED_OPCODE) { TX_DEBUG_PRINT( ("Undefined opcode\n")); } } } return( result ); }