void SwitchToD3( void ) { if(POWER_STATE_D3 != fwPowerState) { TX_DEBUG_PRINT(("Switch To D3\n")); #ifdef __KERNEL__ //HalGpioSetPin(GPIO_M2U_VBUS_CTRL,1); #else pinM2uVbusCtrlM = 1; #endif #if (SYSTEM_BOARD == SB_EPV5_MARK_II) pinMhlConn = 1; pinUsbConn = 0; #elif (SYSTEM_BOARD == SB_STARTER_KIT_X01) #ifdef __KERNEL__ //HalGpioSetPin(GPIO_MHL_USB,1); #else pinMhlUsb = 1; #endif #endif // change TMDS termination to high impedance //bits 1:0 set to 03 SiiRegWrite(TX_PAGE_2|0x0001, 0x03); SiiRegWrite(REG_MHLTX_CTL1, 0xD0); // clear all interrupt here before go into D3 mode by oscar SiiRegWrite(REG_INTR1,0xFF); SiiRegWrite(REG_INTR2,0xFF); SiiRegWrite(REG_INTR4,0xFF); SiiRegWrite(REG_INTR5,0xFF); SiiRegWrite(REG_CBUS_INTR_STATUS,0xFF); SiiRegWrite(REG_CBUS_MSC_INT2_STATUS,0xFF); #ifndef __KERNEL__ //if(HalGpioGetPin(pinAllowD3)) { #endif ForceUsbIdSwitchOpen(); HalTimerWait(50); ReleaseUsbIdSwitchOpen(); //HalTimerWait(50); CLR_BIT(REG_POWER_EN, 0); CBusQueueReset(); fwPowerState = POWER_STATE_D3; #ifndef __KERNEL__ }/*else { //fwPowerState = POWER_STATE_D0_NO_MHL; } */ #endif } }
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; }
void SwitchToD3 (void) { if(POWER_STATE_D3 != fwPowerState) { TX_DEBUG_PRINT(("Drv: Switch To D3\n")); //SiiRegModify(REG_DISC_CTRL6, BIT4, BIT4); //Block RGND INT in Discovery SM. added by garyyuan 20100804 // TX_DEBUG_PRINT(("[%d] Drv: Switch To D3: pinAllowD3 = %d\n", // (int) (HalTimerElapsed( ELAPSED_TIMER ) * MONITORING_PERIOD), (int) pinAllowD3 ) ); //pinM2uVbusCtrlM = 1; //pinMhlConn = 1; //pinUsbConn = 0; ForceUsbIdSwitchOpen(); HalTimerWait(50); // // To allow RGND engine to operate correctly. // So when moving the chip from D0 MHL connected to D3 the values should be // 94[1:0] = 00 reg_cbusmhl_pup_sel[1:0] should be set for open // 93[7:6] = 00 reg_cbusdisc_pup_sel[1:0] should be set for open // 93[5:4] = 00 reg_cbusidle_pup_sel[1:0] = open (default) // // Disable CBUS pull-up during RGND measurement // I2C_WriteByte(PAGE_0_0X72, 0x93, 0x04); // ReadModifyWritePage0(0x93, BIT_7 | BIT_6 | BIT_5 | BIT_4, 0); // ReadModifyWritePage0(0x94, BIT_1 | BIT_0, 0); // 1.8V CBUS VTH & GND threshold // I2C_WriteByte(PAGE_0_0X72, 0x94, 0x64); ReleaseUsbIdSwitchOpen(); // Force HPD to 0 when not in MHL mode. SiiMhlTxDrvAcquireUpstreamHPDControlDriveLow(); // Change TMDS termination to high impedance on disconnection; reduce leakage to QCOM HDMI out, due to QCOM HDMI out can't be truly tri-stated. Each TMDS pin has about 0.1125mA leakage from AVCC33. // Bits 1:0 set to 11 SiiRegWrite(REG_MHLTX_CTL1, 0xD0); // clear all interrupt here before go into D3 mode by oscar SiiRegWrite(TX_PAGE_TPI | 0x0071, 0xFF); SiiRegWrite(TX_PAGE_TPI | 0x0072, 0xFF); SiiRegWrite(TX_PAGE_TPI | 0x0074, 0xBF); // keep BIT6 for fast plug case SiiRegWrite(TX_PAGE_CBUS | 0x0008, 0xFF); SiiRegWrite(TX_PAGE_CBUS | 0x001E, 0xFF); // // GPIO controlled from SiIMon can be utilized to disallow // low power mode, thereby allowing SiIMon to debug register contents. // Otherwise SiIMon reads all registers as 0xFF // // if(pinAllowD3) // { // wait Tsrc:cbus_float HalTimerWait(50); // // Change state to D3 by clearing bit 0 of 3D (SW_TPI, Page 1) register // ReadModifyWriteIndexedRegister(INDEXED_PAGE_1, 0x3D, BIT_0, 0x00); // CLR_BIT(TX_PAGE_L1 | 0x003D, 0); CBusQueueReset(); fwPowerState = POWER_STATE_D3; // } #if (VBUS_POWER_CHK == ENABLE) // Turn VBUS power off when switch to D3(cable out) if( vbusPowerState == false ) { AppVbusControl( vbusPowerState = true ); } #endif } else { fwPowerState = POWER_STATE_D0_NO_MHL; } }