/** * @brief Reset the 5293 chip by toggle the reset pin at 5293 * * @param[in] hwResetPeriod The delay time during the low level. * @param[in] hwResetDelay The delay time after reset hw. * *****************************************************************************/ void SiiHwReset(uint16_t hwResetPeriod,uint16_t hwResetDelay) { // Toggle RX reset pin SiiGpioControl(GPIO_RST, false); HalTimerWait(hwResetPeriod); SiiGpioControl(GPIO_RST, true); // then wait per spec HalTimerWait(hwResetDelay); }
void CbusReset (void) { uint8_t idx; TX_DEBUG_PRINT( ("CBUS reset!!!\n")); SET_BIT(REG_SRST, 3); HalTimerWait(2); CLR_BIT(REG_SRST, 3); mscCmdInProgress = false; UNMASK_INTR_4_INTERRUPTS; #if (SYSTEM_BOARD == SB_STARTER_KIT_X01) UNMASK_INTR_1_INTERRUPTS; UNMASK_INTR_2_INTERRUPTS; UNMASK_INTR_5_INTERRUPTS; #else MASK_INTR_1_INTERRUPTS; MASK_INTR_5_INTERRUPTS; #endif UNMASK_CBUS1_INTERRUPTS; UNMASK_CBUS2_INTERRUPTS; for(idx=0; idx < 4; idx++) { WriteByteCBUS((0xE0 + idx), 0xFF); WriteByteCBUS((0xF0 + idx), 0xFF); } }
/////////////////////////////////////////////////////////////////////////// // // CbusReset // /////////////////////////////////////////////////////////////////////////// void CbusReset (void) { uint8_t enable[4]={0xff,0xff,0xff,0xff};// must write 0xFF to clear regardless! SET_BIT(REG_SRST, 3); HalTimerWait(2); CLR_BIT(REG_SRST, 3); mscCmdInProgress = false; // Adjust interrupt mask everytime reset is performed. UNMASK_INTR_1_INTERRUPTS; UNMASK_INTR_4_INTERRUPTS; if (g_chipRevId < 1) { if(fwPowerState != POWER_STATE_FIRST_INIT) UNMASK_INTR_5_INTERRUPTS; } else { //RG disabled due to auto FIFO reset MASK_INTR_5_INTERRUPTS; } UNMASK_CBUS1_INTERRUPTS; UNMASK_CBUS2_INTERRUPTS; // Enable WRITE_STAT interrupt for writes to all 4 MSC Status registers. SiiRegWriteBlock(REG_CBUS_WRITE_STAT_ENABLE_0,enable,4); // Enable SET_INT interrupt for writes to all 4 MSC Interrupt registers. SiiRegWriteBlock(REG_CBUS_SET_INT_ENABLE_0,enable,4); }
void main ( void ) { uint8_t monitorState; static uint8_t oldMute = 0x00; BOOL externalAccess; uint8_t u8Data, rotarySwitch; externalAccess = false; oldMute = true; HalInitialize(); HalTimerInit(); HalUartInit(); HalTimerWait(100); GPIOC->DDR |= 0x30; GPIOC->CR1 |= 0x30; GPIOC->ODR |= 0x30; /* Perform a hard reset on the device to ensure that it is in a known */ /* state (also downloads a fresh copy of EDID from NVRAM). */ DEBUG_PRINT(MSG_ALWAYS,("\nPower up Initialize...")); u8Data = SI_DevicePowerUpBoot(0); if ( u8Data <= 0x02 ) { DEBUG_PRINT( MSG_ALWAYS, ( "0 FAILED - " )); } DEBUG_PRINT(MSG_ALWAYS,("\n0 Base Address: %02X BSM Status: %02X\n", (int)u8Data, (int)SiIRegioRead(0, REG_BSM_STAT ))); /*u8Data = SI_DevicePowerUpBoot(1); if ( u8Data <= 0x02 ) { DEBUG_PRINT( MSG_ALWAYS, ( "1 FAILED - " )); } DEBUG_PRINT(MSG_ALWAYS,("\n1 Base Address: %02X BSM Status: %02X\n", (int)u8Data, (int)SiIRegioRead(1, REG_BSM_STAT ))); */ CpDisplayChipInfo(0); //CpDisplayChipInfo(1); //HalTimerSet( TIMER_POLLING, DEM_POLLING_DELAY ); while ( 1 ) { HalTimerWait(100); process(0); // process(1); } }
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 } }
uint8_t siMhlTx_VideoAudioSet (void) { TX_DEBUG_PRINT(("[MHL]: >>siMhlTx_VideoAudioSet()\n")); SiiRegModify(TX_PAGE_L1 | 0xDF, BIT0, SET_BITS); SiiMhlTxDrvTmdsControl( false ); HalTimerWait(T_RES_CHANGE_DELAY); // allow control InfoFrames to pass through to the sink device. //siMhlTx_AudioSet(); AudioVideoIsr(true); //siMhlTx_Init(); SiiRegModify(TX_PAGE_L1 | 0xDF, BIT0, CLEAR_BITS); SiiMhlTxTmdsEnable(); return 0; }
/** * @brief Thread function that periodically polls for MHLTx events. * * @param[in] data Pointer to driver context structure * * @return Always returns zero when the thread exits. * *****************************************************************************/ static int EventThread(void *data) { printk("%s EventThread starting up\n", MHL_DRIVER_NAME); while (true) { if (kthread_should_stop()) { printk("%s EventThread exiting\n", MHL_DRIVER_NAME); break; } HalTimerWait(EVENT_POLL_INTERVAL_30_MS); SiiMhlTxDeviceIsr(); } return 0; }
static void ResumeWorkFunc(struct work_struct *work) { printk(KERN_INFO "%s Resume MHL start.\n", __func__); Sii8334_plat_data->reset(); msleep(1000); //deleted by zhangyue on 2011-12-15 for solving the hpd problems start //enable_irq(sii8334_PAGE_TPI->irq); //deleted by zhangyue on 2011-12-15 for solving the hpd problems end SiiMhlTxInitialize(); //added by zhangyue on 2011-12-19 for debugging the mhl irq problem start printk(KERN_INFO "%s Init Register End.\n", __func__); HalTimerWait(30);//wait 30ms before enable registers mhl_set_irq_locked(true, false); //added by zhangyue on 2011-12-19 for debugging the mhl irq problem end }
/////////////////////////////////////////////////////////////////////////////// // // SiiMhlTxDrvNotifyEdidChange // // MhlTx may need to inform upstream device of an EDID change. This can be // achieved by toggling the HDMI HPD signal or by simply calling EDID read // function. // void SiiMhlTxDrvNotifyEdidChange (void) { TX_DEBUG_PRINT(("Drv: SiiMhlTxDrvNotifyEdidChange\n")); // // Prepare to toggle HPD to upstream // SiiMhlTxDrvAcquireUpstreamHPDControl(); // reg_hpd_out_ovr_val = LOW to force the HPD low CLR_BIT(REG_INT_CTRL, 5); // wait a bit HalTimerWait(110); // release HPD back to high by reg_hpd_out_ovr_val = HIGH SET_BIT(REG_INT_CTRL, 5); // release control to allow transcoder to modulate for CLR_HPD and SET_HPD SiiMhlTxDrvReleaseUpstreamHPDControl(); }
/** * @brief Thread function that periodically polls for MHLTx events. * * @param[in] data Pointer to driver context structure * * @return Always returns zero when the thread exits. * *****************************************************************************/ static int EventThread(void *data) { uint8_t event; uint8_t eventParam; printk("%s EventThread starting up\n", MHL_DRIVER_NAME); while (true) { if (kthread_should_stop()) { printk("%s EventThread exiting\n", MHL_DRIVER_NAME); break; } HalTimerWait(30); SiiMhlTxDeviceIsr(); } return 0; }
bool_t SiiMhlTxChipInitialize (void) { tmdsPoweredUp = false; mhlConnected = false; mscCmdInProgress = false; // false when it is okay to send a new command dsHpdStatus = 0; fwPowerState = POWER_STATE_FIRST_INIT; //SI_OS_DISABLE_DEBUG_CHANNEL(SII_OSAL_DEBUG_SCHEDULER); g_chipRevId = SiiRegRead(REG_DEV_REV); // then wait 100ms per MHL spec HalTimerWait(TX_HW_RESET_DELAY); TX_DEBUG_PRINT(("Drv: SiiMhlTxChipInitialize: %02X%02X%02x\n", g_chipRevId, SiiRegRead(TX_PAGE_L0 | 0x03), SiiRegRead(TX_PAGE_L0 | 0x02))); // setup device registers. Ensure RGND interrupt would happen. WriteInitialRegisterValues(); //SiiOsMhlTxInterruptEnable(); // CBUS interrupts are unmasked after performing the reset. // UNMASK_CBUS1_INTERRUPTS; // UNMASK_CBUS2_INTERRUPTS; // // Allow regular operation - i.e. pinAllowD3 is high so we do enter // D3 first time. Later on, SiIMon shall control this GPIO. // //pinAllowD3 = 1; SwitchToD3(); return true; }
/** * @brief Thread function that periodically polls for MHLTx events. * * @param[in] data Pointer to driver context structure * * @return Always returns zero when the thread exits. * *****************************************************************************/ static int EventThread(void *data) { uint8_t event; uint8_t eventParam; printk("%s EventThread starting up\n", MHL_DRIVER_NAME); while (true){ if (kthread_should_stop()){ printk("%s EventThread exiting\n", MHL_DRIVER_NAME); break; } HalTimerWait(EVENT_POLL_INTERVAL_30_MS); SiiMhlTxGetEvents(&event, &eventParam); if( MHL_TX_EVENT_NONE != event ) { AppRcpDemo( event, eventParam); } } return 0; }
/* * i2c client ftn. */ static int __devinit mhl_Sii8334_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) { int ret = 0; if(match_id(&mhl_Sii8334_idtable[0], client)){ sii8334_PAGE_TPI = client; dev_info(&client->adapter->dev, "attached %s " "into i2c adapter successfully\n", dev_id->name); } /* else if(match_id(&mhl_Sii8334_idtable[1], client)){ sii8334_PAGE_TX_L0 = client; dev_info(&client->adapter->dev, "attached %s " "into i2c adapter successfully \n", dev_id->name); } */ else if(match_id(&mhl_Sii8334_idtable[2], client)){ sii8334_PAGE_TX_L1 = client; dev_info(&client->adapter->dev, "attached %s " "into i2c adapter successfully \n", dev_id->name); }else if(match_id(&mhl_Sii8334_idtable[3], client)){ sii8334_PAGE_TX_2 = client; dev_info(&client->adapter->dev, "attached %s " "into i2c adapter successfully\n", dev_id->name); }else if(match_id(&mhl_Sii8334_idtable[4], client)){ sii8334_PAGE_TX_3 = client; dev_info(&client->adapter->dev, "attached %s " "into i2c adapter successfully\n", dev_id->name); }else if(match_id(&mhl_Sii8334_idtable[5], client)) { sii8334_PAGE_CBUS = client; dev_info(&client->adapter->dev, "attached %s " "into i2c adapter successfully\n", dev_id->name); }else{ dev_info(&client->adapter->dev, "invalid i2c adapter: can not found dev_id matched\n"); return -EIO; } if(sii8334_PAGE_TPI != NULL //&&sii8334_PAGE_TX_L0 != NULL &&sii8334_PAGE_TX_L1 != NULL && sii8334_PAGE_TX_2 != NULL && sii8334_PAGE_TX_3 != NULL && sii8334_PAGE_CBUS != NULL){ Sii8334_plat_data = sii8334_PAGE_TPI->dev.platform_data; #ifdef mhl_power_dbg ret = Sii8334_plat_data->mhl_power_on(); if(ret){ printk("%s:call mhl_power_on failed.\n", __func__); } //added by zhangyue on 2011-11-21 for config irq Sii8334_plat_data->mhl_irq_config(); //added by zhangyue on 2011-11-21 end #endif if(false == Sii8334_mhl_reset()){ printk("/nCan't find the reset function in your platform file============================================\n"); return -EIO; } // Announce on RS232c port. // printk("\n============================================\n"); printk("SiI-8334 Driver Version based on 8051 driver Version 1.14 \n"); printk("============================================\n"); // // Initialize the registers as required. Setup firmware vars. // SiiMhlTxInitialize(); #ifdef SiI8334DRIVER_INTERRUPT_MODE #ifdef zy_dbg_err_handle sii8334work = kmalloc(sizeof(*sii8334work), GFP_KERNEL); if(NULL == sii8334work){ printk(KERN_ERR "NO memory for allocating sii8334work.\n"); ret = -ENOMEM; goto ERR_ALLOC_INT_WORK; } #else sii8334work = kmalloc(sizeof(*sii8334work), GFP_ATOMIC); #endif INIT_WORK(sii8334work, work_queue); #ifdef mhl_power_dbg #ifdef zy_dbg_err_handle ResumeWork = kmalloc(sizeof(*ResumeWork ), GFP_ATOMIC); if(NULL == ResumeWork){ printk(KERN_ERR "NO memory for allocating ResumeWork.\n"); ret = -ENOMEM; goto ERR_ALLOC_RESUM_WORK; } #else ResumeWork = kmalloc(sizeof(*ResumeWork ), GFP_ATOMIC); #endif INIT_DELAYED_WORK(ResumeWork, ResumeWorkFunc); #endif #ifdef ZY_IMPLEMENT_RCP mhl_state.rmt_input = input_allocate_device(); if(NULL == mhl_state.rmt_input){ printk(KERN_INFO "Bad input_allocate_device()\n"); ret = -ENOMEM; goto ERR_ALLOC_INPUT; } mhl_init_rmt_input_dev(); //Register with the Input subsystem ret = input_register_device(mhl_state.rmt_input); if(ret){ printk(KERN_INFO "Register input device failed.\n "); goto ERR_REG_INPUT; } #endif #ifdef zy_dbg_irq //modified by zhangyue on 2011-12-07 //for debugging, because some time, the irq handler not run when the irq came. ret = request_threaded_irq(sii8334_PAGE_TPI->irq, NULL, Sii8334_mhl_interrupt, IRQ_TYPE_LEVEL_LOW |IRQF_ONESHOT, sii8334_PAGE_TPI->name, sii8334_PAGE_TPI); #else ret = request_irq(sii8334_PAGE_TPI->irq, Sii8334_mhl_interrupt, IRQ_TYPE_LEVEL_LOW, sii8334_PAGE_TPI->name, sii8334_PAGE_TPI); #endif if (ret){ printk(KERN_INFO "%s:%d:Sii8334 interrupt failed\n", __func__,__LINE__); #ifdef zy_dbg_err_handle goto ERR_REQ_IRQ; #endif //free_irq(irq, iface); }else{ #ifdef zy_usrspace_enalbe_mhl_irq //modified by zhangyue on 2011-12-26 for debugging the mhl charging start disable_irq(sii8334_PAGE_TPI->irq); HalTimerWait(40);//sleep 40ms enable_irq(sii8334_PAGE_TPI->irq); //disable_irq(sii8334_PAGE_TPI->irq); //modified by zhangyue on 2011-12-26 for debugging the mhl charging end #else enable_irq_wake(sii8334_PAGE_TPI->irq); #endif //printk(KERN_INFO "%s:%d:Sii8334 interrupt successed\n", __func__,__LINE__); } #ifdef zy_usrspace_enalbe_mhl_irq mhl_state.irq_Inited = false; #endif #ifdef mhl_power_dbg mhl_state.state = true; #endif #else StartEventThread(); /* begin monitoring for events if using polling mode*/ #endif #ifdef zy_dbg_err_handle goto ERR_ALLOC_INT_WORK; #endif ERR_REQ_IRQ: input_unregister_device(mhl_state.rmt_input); ERR_REG_INPUT: input_free_device(mhl_state.rmt_input); ERR_ALLOC_INPUT: kfree(ResumeWork); ERR_ALLOC_RESUM_WORK: kfree(sii8334work); } ERR_ALLOC_INT_WORK: return ret; }
uint8_t SiiMhlRxIntrHandler () { uint8_t result = SUCCESS; bool_t retrycheck = false; /* Check the channel interrupt status to see if anybody is */ /* talking to us. If they are, talk back. */ result = CBusCheckInterruptStatus(); /* Don't bother with the rest if the heart is gone. */ if ( result != SUCCESS ) { if (result & ERROR_CBUS_ABORT) { //Set abort timer #if defined(__KERNEL__) SiiCbusAbortTimerStart(); #else pCbus->chState.abortTimer = SiiTimerTotalElapsed(); #endif SiiCbusAbortStateSet(true); pCbus->chState.state = CBUS_IDLE; SiiMhlRxSetQueueEmpty(); } else if (result & ERROR_CBUS_ABORT_OTHER) { //send MSC error cannot retry if (pCbus->chState.state == CBUS_SENT) { pCbus->chState.state = CBUS_IDLE; pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_IDLE; } } else if (result & (ERROR_CBUS_TIMEOUT | ERROR_NACK_FROM_PEER)) { //send MSC error, retry if possible if (pCbus->chState.state == CBUS_SENT) { retrycheck = true; } } } // If there's some in the burst queue, send it out CBusBurstNextInQueue(); // Check if there's any cbus message arrived if (pCbus->chState.receive.arrived) { SiiMhlRxRcpRapRcvdNtfy(pCbus->chState.receive.command, pCbus->chState.receive.offsetData); pCbus->chState.receive.arrived = false; } /* Update the channel state machine as necessary. */ if ( pCbus->chState.state == CBUS_XFR_DONE ) { pCbus->chState.state = CBUS_IDLE; /* We may be waiting for a response message, but the */ /* request queue is idle. */ if ( pCbus->chState.request[ CH_ACTIVE_INDEX ].command == MHL_READ_DEVCAP ) { DEBUG_PRINT( MSG_DBG, "Response data Received, %02X\n", pCbus->chState.request[ CH_ACTIVE_INDEX ].retData[0] ); if (pCbus->chState.request[ CH_ACTIVE_INDEX ].offsetData < 15) SiiMhlRxReadDevCapReg(pCbus->chState.request[ CH_ACTIVE_INDEX ].offsetData+1); else pCbus->chState.dcap_ongoing = false; pCbus->chState.remote_dcap[pCbus->chState.request[ CH_ACTIVE_INDEX ].offsetData] = pCbus->chState.request[ CH_ACTIVE_INDEX ].retData[0]; } if ( (pCbus->chState.request[ CH_ACTIVE_INDEX ].command == MHL_MSC_MSG ) && ((pCbus->chState.request[ CH_ACTIVE_INDEX ].msgData[0] == MHL_MSC_MSG_RCPE) || (pCbus->chState.request[ CH_ACTIVE_INDEX ].msgData[0] == MHL_MSC_MSG_UCPE))) { //Add a little delay after sending RCPE/UCPE HalTimerWait(20); } pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_IDLE; CH_ACTIVE_INDEX = (CH_ACTIVE_INDEX + 1)% CBUS_MAX_COMMAND_QUEUE; } #if 0 if (pCbus->chState.state == CBUS_SENT) { //From spec need Wait for TCMD_RECEIVER_TIMEOUT, at least 320ms if (pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus == CBUS_REQ_SENT) { if (SiiTimerTotalElapsed() - pCbus->chState.request[ CH_ACTIVE_INDEX ].reqTimer > CBUS_CMD_TIMEOUT) { //should never be here, when this timeout occured, there should be abort interrupt firstly. retrycheck = true; } } else { //should never be here pCbus->chState.state = CBUS_IDLE; result = ERROR_INVALID; return result; } } #endif if (retrycheck) { pCbus->chState.state = CBUS_IDLE; if (pCbus->chState.request[ CH_ACTIVE_INDEX ].retry) { pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_PENDING; pCbus->chState.request[ CH_ACTIVE_INDEX ].retry--; } else { // retry failed, skip the current index, and move on. pCbus->chState.request[ CH_ACTIVE_INDEX ].reqStatus = CBUS_REQ_IDLE; CH_ACTIVE_INDEX = (CH_ACTIVE_INDEX + 1)% CBUS_MAX_COMMAND_QUEUE; } } if (pCbus->chState.state == CBUS_IDLE) { result = CBusSendNextInQueue(); // No command in progress, write new command immediately. } return( result ); }
static void ReleaseUsbIdSwitchOpen ( void ) { HalTimerWait(50); SiiRegModify(REG_DISC_CTRL6, BIT6, 0x00); ENABLE_DISCOVERY; }
void SiiMhlTriggerSoftInt(void) { SiiRegBitsSet(REG_INT_CTRL,BIT3,true); HalTimerWait(5); SiiRegBitsSet(REG_INT_CTRL,BIT3,false); }
long SiiMhlIoctl(struct file *pFile, unsigned int ioctlCode, unsigned long ioctlParam) { long retStatus = 0; Register_t RegisterInfo; uint8_t reg; UserControl_t user_control; if (HalAcquireIsrLock() != HAL_RET_SUCCESS) { return -ERESTARTSYS; } switch (ioctlCode) { case SII_IOCTRL_REGISTER_READ: retStatus = copy_from_user(&RegisterInfo, (Register_t *) ioctlParam, sizeof(Register_t)); if (!retStatus) { RegisterInfo.value = I2C_ReadByte(RegisterInfo.dev_address, RegisterInfo.subaddr); retStatus = copy_to_user((Register_t *) ioctlParam, &RegisterInfo, sizeof(Register_t)); } else { pr_info("register read error!\n"); } break; case SII_IOCTRL_REGISTER_WRITE: retStatus = copy_from_user(&RegisterInfo, (Register_t *) ioctlParam, sizeof(Register_t)); reg = I2C_ReadByte(RegisterInfo.dev_address, RegisterInfo.subaddr); reg = (reg & (~RegisterInfo.mask)) | (RegisterInfo.mask & RegisterInfo.value); I2C_WriteByte(RegisterInfo.dev_address, RegisterInfo.subaddr, reg); break; case SII_IOCTRL_USER: retStatus = copy_from_user(&user_control, (UserControl_t *) ioctlParam, sizeof(UserControl_t)); switch (user_control.ControlID) { case USER_GPIO_GET: /* HalGpioGetPin(user_control.SubCommand.GpioCtrl.GpioIndex, &user_control.SubCommand.GpioCtrl.Value); */ break; case USER_GPIO_SET: /* HalGpioSetPin(user_control.SubCommand.GpioCtrl.GpioIndex, user_control.SubCommand.GpioCtrl.Value); */ break; case USER_TRIGGER_EXT_INT: /* SiiTriggerExtInt(); */ break; case USER_TRIGGER_MHL_INT: { if (TestDelay != NULL) { SiiOsTimerDelete(TestDelay); TestDelay = NULL; } SiiOsTimerCreate("Abort Time Out", SiiMhlTimerTestCB, NULL, true, 2000, false, &TestDelay); } break; case USER_ON_OFF_MHL_INT: HalEnableIrq(user_control.SubCommand.iSubCommand ? 1 : 0); break; case USER_RESET_MHL_CHIP: SiiMhlTxInitialize(EVENT_POLL_INTERVAL_MS); break; case USER_READ_SINK_EDID: { #define _MASK_(aByte, bitMask, setBits) ((setBits) ? (aByte | bitMask) : (aByte & ~bitMask)) int RepeatNums = 5, i; int iRepeatCnt = 0; uint8_t reg; uint8_t reg_save; reg_save = reg = I2C_ReadByte(0x72, 0xC7); reg = _MASK_(reg, BIT0, 1); I2C_WriteByte(0x72, 0xc7, reg); do { if (++iRepeatCnt > RepeatNums) break; reg = I2C_ReadByte(0x72, 0xC7); HalTimerWait(10); } while (!(reg & BIT1)); if (iRepeatCnt > RepeatNums) { printk("try time out\n"); } else { reg = I2C_ReadByte(0x72, 0xC7); reg = _MASK_(reg, BIT2, 1); I2C_WriteByte(0x72, 0xc7, reg); for (i = 0; i < 256; i++) { } I2C_ReadBlock(0xa0, 0, user_control.SubCommand.EDID, 128); I2C_ReadBlock(0xa0, 128, &user_control.SubCommand.EDID[128], 128); I2C_WriteByte(0x72, 0xc7, reg_save); } } break; } retStatus = copy_to_user((UserControl_t *) ioctlParam, &user_control, sizeof(UserControl_t)); break; default: SII_DEBUG_PRINT(SII_OSAL_DEBUG_TRACE, "SiiMhlIoctl, unrecognized ioctlCode 0x%0x received!\n", ioctlCode); retStatus = -EINVAL; break; } HalReleaseIsrLock(); return retStatus; }
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; } }