/////////////////////////////////////////////////////////////////////////// // // 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); }
/** * @brief Interrupt Service Routine Initialization * *****************************************************************************/ void RxIsr_Init(void) { rx_isr.hdcp_fail_cntr = 0; //rx_isr.check_hdcp_on_vsync = false; memcpy(rx_isr.shadow_interrupt_mask, default_interrupt_masks, NMB_OF_RX_INTERRUPTS); SiiRegWriteBlock(RX_A__INTR1_MASK, &rx_isr.shadow_interrupt_mask[INT1], 4); SiiRegWriteBlock(RX_A__INTR5_MASK, &rx_isr.shadow_interrupt_mask[INT5], 2); SiiRegWriteBlock(RX_A__INTR7_MASK, &rx_isr.shadow_interrupt_mask[INT7], 2); }
/** * @brief Set the port type of the specific Rx port. * * @param[in] portIndex - SiiPORT_x - Rx port (0-1). * - SiiPORT_ALL - SiiPORT_ALL - All ports are acted on simultaneously. * @param[in] portType true - enable, false - disable * * @return void * * @note: The 'portIndex' parameter value 0xFF should not be used unless * all ports are HDMI1.3/a (not MHL or CDC) * *****************************************************************************/ void SiiDrvSwitchPortType(SiiPortType_t portType) { static uint8_t peq_val_HDMI[8] = {0xC6, 0XF5, 0XF4, 0XE4, 0XD4, 0XA4, 0X94, 0X25}; static uint8_t peq_val_MHL[8] = {0x26, 0X10, 0X24, 0X11, 0X12, 0X22, 0X1A, 0X25}; if (portType == SiiPortType_HDMI) { SiiRegWriteBlock(REG_PEQ_VAL0, peq_val_HDMI, 8); } else { SiiRegWriteBlock(REG_PEQ_VAL0, peq_val_MHL, 8); } g_portType = portType; }
void SiiHmdiTxLiteDrvSendHwAviInfoFrame( void ) { /* extern void *memcpy(void *dest, const void *src, uint8_t n); extern void *memset (void *s, char val, int n); uint8_t Real_aviPayLoad[17];*/ INFO_DEBUG_PRINT(("Output Mode: %s\n",(sink_type_HDMI == SiiMhlTxGetSinkType())?"HDMI":"DVI")); if (sink_type_HDMI == SiiMhlTxGetSinkType()) { SiiRegWrite(REG_TPI_INFO_FSEL , BIT_TPI_INFO_EN | BIT_TPI_INFO_RPT | BIT_TPI_INFO_READ_FLAG_NO_READ | BIT_TPI_INFO_SEL_AVI ); /* memset(&Real_aviPayLoad[0], 0x00, 17); memcpy(&Real_aviPayLoad[3],aviPayLoad.ifData,sizeof(aviPayLoad.ifData)); Real_aviPayLoad[0]=0x82; Real_aviPayLoad[1]=0x02; Real_aviPayLoad[2]=0x0D; SiiRegWriteBlock(REG_TPI_AVI_CHSUM, (uint8_t*)&Real_aviPayLoad, 17); DumpAviInfoFrame(&Real_aviPayLoad[0],"outgoing") // no semicolon needed */ SiiRegWriteBlock(REG_TPI_AVI_CHSUM, (uint8_t *)&aviPayLoad.ifData, sizeof(aviPayLoad.ifData)); DumpAviInfoFrame(&aviPayLoad,"outgoing") // no semicolon needed }
////////////////////////////////////////////////////////////////////////////// // // FUNCTION : SendAudioInfoFrame() // // PURPOSE : Load Audio InfoFrame data into registers and send to sink // // INPUT PARAMS : (1) Channel count (2) speaker configuration per CEA-861D // Tables 19, 20 (3) Coding type: 0x09 for DSD Audio. 0 (refer // to stream header) for all the rest (4) Sample Frequency. Non // zero for HBR only (5) Audio Sample Length. Non zero for HBR // only. // // OUTPUT PARAMS : None // // GLOBALS USED : None // // RETURNS : true // ////////////////////////////////////////////////////////////////////////////// void SendAudioInfoFrame (void) { if (sink_type_HDMI == SiiMhlTxGetSinkType()) { uint8_t ifData[SIZE_AUDIO_INFOFRAME]; uint8_t i; ifData[0] = 0x84; ifData[1] = 0x01; ifData[2] = 0x0A; for (i = 3; i < SIZE_AUDIO_INFOFRAME; ++i) { ifData[i] = 0; } ifData[3] = CalculateGenericCheckSum(ifData,0,SIZE_AUDIO_INFOFRAME); SiiRegWrite(REG_TPI_INFO_FSEL , BIT_TPI_INFO_EN | BIT_TPI_INFO_RPT | BIT_TPI_INFO_READ_FLAG_NO_READ | BIT_TPI_INFO_SEL_Audio ); SiiRegWriteBlock(REG_TPI_INFO_BYTE00,ifData,SIZE_AUDIO_INFOFRAME); INFO_DEBUG_PRINT(("REG_TPI_INFO_BYTE13: %02x\n",REG_TPI_INFO_BYTE13)); } }
static void SendAviInfoframe (void) { uint8_t ifData[SIZE_AVI_INFOFRAME]; extern uint8_t VIDEO_CAPABILITY_D_BLOCK_found; ifData[0] = 0x82; ifData[1] = 0x02; ifData[2] = 0x0D; ifData[3] = 0x00; ifData[4] = video_data.outputColorSpace << 5; ifData[5] = video_data.outputcolorimetryAspectRatio; if(VIDEO_CAPABILITY_D_BLOCK_found){ ifData[6] = 0x04; TX_DEBUG_PRINT(("VIDEO_CAPABILITY_D_BLOCK_found = true, limited range\n")); } else{ ifData[6] = 0x00; TX_DEBUG_PRINT(("VIDEO_CAPABILITY_D_BLOCK_found= false. defult range\n")); } //ifData[4] = video_data.outputColorSpace << 5; ifData[7] = video_data.inputVideoCode; TX_DEBUG_PRINT(("video_data.inputVideoCode:0x%02x, video_data.outputVideoCode=0x%x\n",(int)video_data.inputVideoCode,video_data.outputVideoCode)); //ifData[7] = video_data.outputVideoCode; ifData[8] = 0x00; ifData[9] = 0x00; ifData[10] = 0x00; ifData[11] = 0x00; ifData[12] = 0x00; ifData[13] = 0x00; ifData[14] = 0x00; ifData[15] = 0x00; ifData[16] = 0x00; ifData[3] = CalculateInfoFrameChecksum(ifData); SiiRegModify(TX_PAGE_L1 | 0x3E, BIT0|BIT1, CLEAR_BITS); SiiRegWriteBlock(TX_PAGE_L1 | 0x0040, ifData, SIZE_AVI_INFOFRAME); SiiRegModify(TX_PAGE_L1 | 0x3E, BIT0|BIT1, SET_BITS); }
static void MhlCbusIsr( void ) { uint8_t cbusInt; uint8_t gotData[4]; uint8_t i; cbusInt = SiiRegRead(REG_CBUS_MSC_INT2_STATUS); if(cbusInt == 0xFF) { return; } if( cbusInt ) { if ( BIT0 & cbusInt) { SiiMhlTxMscWriteBurstDone( cbusInt ); } if(cbusInt & BIT2) { uint8_t intr[4]={0}; TX_DEBUG_PRINT(("MHL INTR Received\n")); SiiRegReadBlock(REG_CBUS_SET_INT_0, intr, 4); SiiMhlTxGotMhlIntr( intr[0], intr[1] ); SiiRegWriteBlock(REG_CBUS_SET_INT_0, intr, 4); } if(cbusInt & BIT3) { uint8_t status[4]={0}; TX_DEBUG_PRINT(("MHL STATUS Received\n")); for (i = 0; i < 4;++i) { status[i] = SiiRegRead(REG_CBUS_WRITE_STAT_0 + i); SiiRegWrite((REG_CBUS_WRITE_STAT_0 + i), 0xFF ); } SiiMhlTxGotMhlStatus( status[0], status[1] ); } SiiRegWrite(REG_CBUS_MSC_INT2_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_2: %02X\n", (int) cbusInt)); } cbusInt = SiiRegRead(REG_CBUS_INTR_STATUS); if (cbusInt) { SiiRegWrite(REG_CBUS_INTR_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_1: %02X\n", (int) cbusInt)); } if((cbusInt & BIT3)) { uint8_t mscMsg[2]; TX_DEBUG_PRINT(("MSC_MSG Received\n")); mscMsg[0] = SiiRegRead(REG_CBUS_PRI_VS_CMD); mscMsg[1] = SiiRegRead(REG_CBUS_PRI_VS_DATA); TX_DEBUG_PRINT(("MSC MSG: %02X %02X\n", (int)mscMsg[0], (int)mscMsg[1] )); SiiMhlTxGotMhlMscMsg( mscMsg[0], mscMsg[1] ); } if (cbusInt & (BIT_MSC_ABORT | BIT_MSC_XFR_ABORT | BIT_DDC_ABORT)) { gotData[0] = CBusProcessErrors(cbusInt); mscCmdInProgress = false; } if(cbusInt & BIT4) { TX_DEBUG_PRINT(("MSC_REQ_DONE\n")); mscCmdInProgress = false; SiiMhlTxMscCommandDone( SiiRegRead(REG_CBUS_PRI_RD_DATA_1ST) ); } if (cbusInt & BIT7) { TX_DEBUG_PRINT(("Parity error count reaches 15\n")); SiiRegWrite(REG_CBUS_STAT2, 0x00); } }
bool_t SiiMhlTxDrvSendCbusCommand (cbus_req_t *pReq) { bool_t success = true; uint8_t startbit; // // If not connected, return with error // if( (POWER_STATE_D0_MHL != fwPowerState ) || (mscCmdInProgress)) { TX_DEBUG_PRINT(("Error: Drv:%d fwPowerState: %02X, or CBUS(0x0A):%02X mscCmdInProgress = %d\n",(int)__LINE__, (int) fwPowerState, (int) SiiRegRead(REG_CBUS_BUS_STATUS), (int) mscCmdInProgress)); return false; } // Now we are getting busy mscCmdInProgress = true; #if 0 TX_DEBUG_PRINT(("Drv: Sending MSC command %02X, %02X, %02X, %02X\n", (int)pReq->command, (int)(pReq->offsetData), (int)pReq->payload_u.msgData[0], (int)pReq->payload_u.msgData[1])); #endif /****************************************************************************************/ /* Setup for the command - write appropriate registers and determine the correct */ /* start bit. */ /****************************************************************************************/ // Set the offset and outgoing data byte right away SiiRegWrite(REG_CBUS_PRI_ADDR_CMD, pReq->offsetData); // set offset SiiRegWrite(REG_CBUS_PRI_WR_DATA_1ST, pReq->payload_u.msgData[0]); startbit = 0x00; switch ( pReq->command ) { case MHL_SET_INT: // Set one interrupt register = 0x60 startbit = MSC_START_BIT_WRITE_REG; break; case MHL_WRITE_STAT: // Write one status register = 0x60 | 0x80 startbit = MSC_START_BIT_WRITE_REG; break; case MHL_READ_DEVCAP: // Read one device capability register = 0x61 startbit = MSC_START_BIT_READ_REG; break; case MHL_GET_STATE: // 0x62 - case MHL_GET_VENDOR_ID: // 0x63 - for vendor id case MHL_SET_HPD: // 0x64 - Set Hot Plug Detect in follower case MHL_CLR_HPD: // 0x65 - Clear Hot Plug Detect in follower case MHL_GET_SC1_ERRORCODE: // 0x69 - Get channel 1 command error code case MHL_GET_DDC_ERRORCODE: // 0x6A - Get DDC channel command error code. case MHL_GET_MSC_ERRORCODE: // 0x6B - Get MSC command error code. case MHL_GET_SC3_ERRORCODE: // 0x6D - Get channel 3 command error code. SiiRegWrite(REG_CBUS_PRI_ADDR_CMD, pReq->command ); startbit = MSC_START_BIT_MSC_CMD; break; case MHL_MSC_MSG: SiiRegWrite(REG_CBUS_PRI_WR_DATA_2ND, pReq->payload_u.msgData[1]); SiiRegWrite(REG_CBUS_PRI_ADDR_CMD, pReq->command ); startbit = MSC_START_BIT_VS_CMD; break; case MHL_WRITE_BURST: SiiRegWrite(REG_MSC_WRITE_BURST_LEN, pReq->length -1 ); // Now copy all bytes from array to local scratchpad if (NULL == pReq->payload_u.pdatabytes) { TX_DEBUG_PRINT(("\nDrv:%d Put pointer to WRITE_BURST data in req.pdatabytes!!!\n\n",(int)__LINE__)); success = false; } else { uint8_t *pData = pReq->payload_u.pdatabytes; TX_DEBUG_PRINT(("\nDrv: Writing data into scratchpad\n\n")); SiiRegWriteBlock(REG_CBUS_SCRATCHPAD_0,pData,pReq->length); startbit = MSC_START_BIT_WRITE_BURST; } break; default: success = false; break; } /****************************************************************************************/ /* Trigger the CBUS command transfer using the determined start bit. */ /****************************************************************************************/ if ( success ) { SiiRegWrite(REG_CBUS_PRI_START, startbit ); } else { TX_DEBUG_PRINT(("\nDrv:%d SiiMhlTxDrvSendCbusCommand failed\n\n",(int)__LINE__)); } return( success ); }
/////////////////////////////////////////////////////////////////////////// // // MhlCbusIsr // // Only when MHL connection has been established. This is where we have the // first looks on the CBUS incoming commands or returned data bytes for the // previous outgoing command. // // It simply stores the event and allows application to pick up the event // and respond at leisure. // // Look for interrupts on CBUS:CBUS_INTR_STATUS [0xC8:0x08] // 7 = RSVD (reserved) // 6 = MSC_RESP_ABORT (interested) // 5 = MSC_REQ_ABORT (interested) // 4 = MSC_REQ_DONE (interested) // 3 = MSC_MSG_RCVD (interested) // 2 = DDC_ABORT (interested) // 1 = RSVD (reserved) // 0 = rsvd (reserved) /////////////////////////////////////////////////////////////////////////// static void MhlCbusIsr (void) { uint8_t cbusInt; uint8_t gotData[4]; // Max four status and int registers. // // Main CBUS interrupts on CBUS_INTR_STATUS // cbusInt = SiiRegRead(REG_CBUS_INTR_STATUS); // When I2C is inoperational (D3) and a previous interrupt brought us here, do nothing. if(cbusInt == 0xFF) { return; } if( cbusInt ) { // // Clear all interrupts that were raised even if we did not process // SiiRegWrite(REG_CBUS_INTR_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_1: %02X\n", (int) cbusInt)); } // MSC_MSG (RCP/RAP) if ((cbusInt & BIT_CBUS_MSC_MR_MSC_MSG)) { uint8_t mscMsg[2]; TX_DEBUG_PRINT(("Drv: MSC_MSG Received\n")); // // Two bytes arrive at registers 0x18 and 0x19 // mscMsg[0] = SiiRegRead(REG_CBUS_PRI_VS_CMD); mscMsg[1] = SiiRegRead(REG_CBUS_PRI_VS_DATA); TX_DEBUG_PRINT(("Drv: MSC MSG: %02X %02X\n", (int)mscMsg[0], (int)mscMsg[1] )); SiiMhlTxGotMhlMscMsg( mscMsg[0], mscMsg[1] ); } if (cbusInt & (BIT_MSC_ABORT | BIT_MSC_XFR_ABORT | BIT_DDC_ABORT)) { gotData[0] = CBusProcessErrors(cbusInt); mscCmdInProgress = false; } // MSC_REQ_DONE received. if (cbusInt & BIT_CBUS_MSC_MT_DONE) { TX_DEBUG_PRINT(("Drv: MSC_REQ_DONE\n")); mscCmdInProgress = false; // only do this after cBusInt interrupts are cleared above SiiMhlTxMscCommandDone( SiiRegRead(REG_CBUS_PRI_RD_DATA_1ST) ); } // // Clear all interrupts that were raised even if we did not process // // // Now look for interrupts on register 0x1E. CBUS_MSC_INT2 // 7:4 = Reserved // 3 = msc_mr_write_state = We got a WRITE_STAT // 2 = msc_mr_set_int. We got a SET_INT // 1 = reserved // 0 = msc_mr_write_burst. We received WRITE_BURST // cbusInt = SiiRegRead(REG_CBUS_MSC_INT2_STATUS); if(cbusInt) { // // Clear all interrupts that were raised even if we did not process // SiiRegWrite(REG_CBUS_MSC_INT2_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_2: %02X\n", (int) cbusInt)); } if ( BIT_CBUS_MSC_MR_WRITE_BURST & cbusInt) { // WRITE_BURST complete SiiMhlTxMscWriteBurstDone( cbusInt ); } if(cbusInt & BIT_CBUS_MSC_MR_SET_INT) { uint8_t intr[4]; TX_DEBUG_PRINT(("Drv: MHL INTR Received\n")); SiiRegReadBlock(REG_CBUS_SET_INT_0, intr, 4); SiiRegWriteBlock(REG_CBUS_SET_INT_0, intr, 4); // We are interested only in first two bytes. SiiMhlTxGotMhlIntr( intr[0], intr[1] ); } if (cbusInt & BIT_CBUS_MSC_MR_WRITE_STATE) { uint8_t status[4]; uint8_t clear[4]={0xff,0xff,0xff,0xff};// must write 0xFF to clear regardless! // don't put debug output here, it just creates confusion. SiiRegReadBlock(REG_CBUS_WRITE_STAT_0, status, 4); SiiRegWriteBlock(REG_CBUS_WRITE_STAT_0, clear, 4); SiiMhlTxGotMhlStatus( status[0], status[1] ); } }
void SiiRxInterruptHandler(void) { uint8_t interrupts[NMB_OF_RX_INTERRUPTS]; //DEBUG_PRINT(MSG_STAT, ("RX Interrupt detected!\n")); // get interrupt requests SiiRegReadBlock(RX_A__INTR1, &interrupts[INT1], 4); SiiRegReadBlock(RX_A__INTR5, &interrupts[INT5], 2); SiiRegReadBlock(RX_A__INTR7, &interrupts[INT7], 2); // do not touch interrupts which are masked out interrupts[INT1] &= rx_isr.shadow_interrupt_mask[INT1]; interrupts[INT2] &= rx_isr.shadow_interrupt_mask[INT2]; interrupts[INT3] &= rx_isr.shadow_interrupt_mask[INT3]; interrupts[INT4] &= rx_isr.shadow_interrupt_mask[INT4]; interrupts[INT5] &= rx_isr.shadow_interrupt_mask[INT5]; interrupts[INT6] &= rx_isr.shadow_interrupt_mask[INT6]; interrupts[INT7] &= rx_isr.shadow_interrupt_mask[INT7]; interrupts[INT8] &= rx_isr.shadow_interrupt_mask[INT8]; // Cable plug-in / plug-out interrupts are handled elsewhere //interrupts[INT6] &= ~RX_M__INTR6__CABLE_UNPLUG; //interrupts[INT8] &= ~RX_M__INTR8__CABLE_IN; // clear interrupt requests SiiRegWriteBlock(RX_A__INTR1, &interrupts[INT1], 4); SiiRegWriteBlock(RX_A__INTR5, &interrupts[INT5], 2); SiiRegWriteBlock(RX_A__INTR7, &interrupts[INT7], 2); if(interrupts[INT1] & RX_M__INTR1__AUTH_DONE) { DEBUG_PRINT(MSG_STAT, ("RX: Authentication done!\n")); switch_hdcp_failure_check_with_v_sync_rate(OFF); } if(interrupts[INT2] & RX_M__INTR2__VID_CLK_CHANGED) { rx_isr.bVidStableChgEvent = true; DEBUG_PRINT(MSG_STAT, ("RX: video clock change\n")); } if(interrupts[INT2] & RX_M__INTR2__SCDT) { switch_hdcp_failure_check_with_v_sync_rate(OFF); SiiDrvRxMuteVideo(ON); rx_isr.bVidStableChgEvent = true; if(SiiDrvRxIsSyncDetected()) { // SCDT detection for vdin utility. printk("sii9293 irq got SCDT!\n"); rx_isr.bScdtState = true; #if defined(__KERNEL__) SiiConnectionStateNotify(true); #endif } else { // SCDT detection for vdin utility. printk("sii9293 irq lost SCDT!\n"); sii_signal_notify(0); rx_isr.bScdtState = false; SiiDrvSoftwareReset(RX_M__SRST__SRST); VMD_ResetTimingData(); DEBUG_PRINT(MSG_STAT, ("RX: IDLE!\n")); } } if(interrupts[INT2] & RX_M__INTR2__HDMI_MODE) { DEBUG_PRINT(MSG_STAT, ("RX: HDMI mode change!\n")); RxIsr_HdmiDviTransition(); } if(interrupts[INT2] & RX_M__INTR2__VSYNC) { hdcp_error_handler(true); } if(interrupts[INT4] & RX_M__INTR4__HDCP) { hdcp_error_handler(false); } if((interrupts[INT5] & RX_M__INTR5__AUDIO_FS_CHANGED) || (interrupts[INT6] & RX_M__INTR6__CHST_READY)) { // Note: RX_M__INTR6__CHST_READY interrupt may be disabled //DEBUG_PRINT(MSG_STAT, ("RX: New Audio Fs\n")); RxAudio_OnChannelStatusChange(); } if(interrupts[INT4] & RX_M__INTR4__NO_AVI) { RxInfo_NoAviHandler(); rx_isr.bVidStableChgEvent = true; } if(interrupts[INT3] & RX_M__INTR3__NEW_AVI_PACKET) { RxInfo_InterruptHandler(INFO_AVI); rx_isr.bVidStableChgEvent = true; } if(interrupts[INT7] & RX_M__INTR7__NO_VSI_PACKET) { // Clear also vsif_received flag (indicating any VSIF packet detection). // If there is any other VSIF packet, the flag will be set again shortly. RxInfo_NoVsiHandler(); } if(interrupts[INT7] & RX_M__INTR7__NEW_VSI_PACKET) { RxInfo_InterruptHandler(INFO_VSI); } if(interrupts[INT3] & RX_M__INTR3__NEW_AUD_PACKET) { RxInfo_InterruptHandler(INFO_AUD); } if(interrupts[INT6] & RX_M__INTR6__NEW_ACP_PACKET) { RxInfo_InterruptHandler(INFO_AUD); } if (interrupts[INT6] & RX_M__INTR6__CABLE_UNPLUG) { if (SiiRegRead(RX_A__INTR6) & RX_M__INTR6__CABLE_UNPLUG) { rx_isr.bCableChgEvent = true; rx_isr.bCableState = false; rx_isr.shadow_interrupt_mask[INT6] &= ~RX_M__INTR6__CABLE_UNPLUG; // Disable 5v plug-out interrup rx_isr.shadow_interrupt_mask[INT8] |= RX_M__INTR8__CABLE_IN; // Enable 5v plug-in interrupt SiiRegWrite(RX_A__INTR6_MASK, rx_isr.shadow_interrupt_mask[INT6]); SiiRegWrite(RX_A__INTR8_MASK, rx_isr.shadow_interrupt_mask[INT8]); sii9293_cable_status_notify(0); } } if (interrupts[INT8] & RX_M__INTR8__CABLE_IN) { if (SiiRegRead(RX_A__INTR8) & RX_M__INTR8__CABLE_IN) { rx_isr.bCableChgEvent = true; rx_isr.bCableState = true; rx_isr.shadow_interrupt_mask[INT6] |= RX_M__INTR6__CABLE_UNPLUG; // Enable 5v plug-out interrup rx_isr.shadow_interrupt_mask[INT8] &= ~RX_M__INTR8__CABLE_IN; // Disable 5v plug-in interrupt SiiRegWrite(RX_A__INTR6_MASK, rx_isr.shadow_interrupt_mask[INT6]); SiiRegWrite(RX_A__INTR8_MASK, rx_isr.shadow_interrupt_mask[INT8]); sii9293_cable_status_notify(1); } } }