/**
 *  @brief		Switch HDCP Failure Check with Vertical Sync Rate
 *
 *  @param[in]		switch_on		true to switch on; false to switch off
 *
 *****************************************************************************/
static void switch_hdcp_failure_check_with_v_sync_rate(bool_t switch_on)
{
	if(switch_on)
	{
		rx_isr.hdcp_fail_cntr = 1;
		//rx_isr.check_hdcp_on_vsync = true; // don't clear HDCP Failure Int if this bit is set
		rx_isr.shadow_interrupt_mask[INT2] |= RX_M__INTR2__VSYNC;
		rx_isr.shadow_interrupt_mask[INT4] &= ~RX_M__INTR4__HDCP;
	}
	else
	{
		rx_isr.hdcp_fail_cntr = 0;
		//rx_isr.check_hdcp_on_vsync = false;
		rx_isr.shadow_interrupt_mask[INT2] &= ~RX_M__INTR2__VSYNC;
		rx_isr.shadow_interrupt_mask[INT4] |= RX_M__INTR4__HDCP;
	}
	SiiRegWrite(RX_A__INTR2_MASK, rx_isr.shadow_interrupt_mask[INT2]);
	SiiRegWrite(RX_A__INTR4_MASK, rx_isr.shadow_interrupt_mask[INT4]);

	// Clear BCH counter.
	// The counter accomulates BCH errors and  if it is not cleared it can cause an HDCP failure interrupt
	// Capture and clear BCH T4 errors.
	SiiRegWrite(RX_A__ECC_CTRL, RX_M__ECC_CTRL__CAPTURE_CNT);

}
static void MhlTxDrvProcessConnection ( void )
{
	TX_DEBUG_PRINT (("MHL Cable Connected. CBUS:0x0A = %02X\n", (int) SiiRegRead(REG_CBUS_BUS_STATUS)));
	if( POWER_STATE_D0_MHL == fwPowerState )
	{
		return;
	}
#ifdef __KERNEL__
    //HalGpioSetPin(GPIO_M2U_VBUS_CTRL,0);
#else
    pinM2uVbusCtrlM = 0;
#endif
#if (SYSTEM_BOARD == SB_EPV5_MARK_II)
    pinMhlConn = 0;
    pinUsbConn = 1;
#elif (SYSTEM_BOARD == SB_STARTER_KIT_X01)
#ifdef __KERNEL__
    //HalGpioSetPin(GPIO_MHL_USB,0);
#else
    pinMhlUsb = 0;
#endif
#endif
	SiiRegWrite(REG_MHLTX_CTL1, 0x10);
	fwPowerState = POWER_STATE_D0_MHL;
	
// change TMDS termination to 50 ohm termination(default)
//bits 1:0 set to 00
	SiiRegWrite(TX_PAGE_2|0x0001, 0x00);
	
	ENABLE_DISCOVERY;
	SiiMhlTxNotifyConnection(true);
}
/**
 *  @brief		Switch Receive Audio InfoFrame On Every Packet Interrupts Handler
 *
 *  @param[in]		switch_on		true to switch on; false to switch off
 *
 *****************************************************************************/
void RxIsr_SwitchReceiveInfoFrameOnEveryPacket(uint8_t info_type, bool_t switch_on)
{
    switch(info_type)
    {
        case INFO_AVI:
            SiiRegBitsSet(RX_A__INT_IF_CTRL, RX_M__INT_IF_CTRL__NEW_AVI, switch_on);
            SiiRegWrite(RX_A__INTR3, RX_M__INTR3__NEW_AVI_PACKET); // reset the interrupt
            break;
        case INFO_AUD:
            SiiRegBitsSet(RX_A__INT_IF_CTRL, RX_M__INT_IF_CTRL__NEW_AUD, switch_on);
            SiiRegWrite(RX_A__INTR3, RX_M__INTR3__NEW_AUD_PACKET); // reset the interrupt
            break;
        case INFO_ACP:
            SiiRegBitsSet(RX_A__INT_IF_CTRL, RX_M__INT_IF_CTRL__NEW_ACP, switch_on);
            SiiRegWrite(RX_A__INTR6, RX_M__INTR6__NEW_ACP_PACKET); // reset the interrupt
            break;
        case INFO_VSI:
            SiiRegBitsSet(RX_A__INT_IF_CTRL, RX_M__INT_IF_CTRL__NEW_VSI, switch_on);
            SiiRegWrite(RX_A__INTR7, RX_M__INTR7__NEW_VSI_PACKET); // reset the interrupt
            break;
        default:
            break;

    }

}
/**
 *  @brief        Initialize the CBUS hardware for the current instance.
 *
 *  @return    Status
 *  @retval    true        Success
 *  @retval    false        Failure
 *
 *  @note: Requires that SiiDrvCbusInstanceSet() is called prior to this call
 * 
 *****************************************************************************/
 bool_t SiiDrvCbusInitialize ( void )
{
    uint_t  index;

    SiiRegModify(RX_A__SWRST2, RX_M__SWRST2__CBUS_SRST, SET_BITS);
    SiiRegModify(RX_A__SWRST2, RX_M__SWRST2__CBUS_SRST, CLEAR_BITS);

    memset( pDrvCbus, 0, sizeof( CbusDrvInstanceData_t ));

    // Setup local DEVCAP registers for read by the peer
    for ( index = 0; index < (sizeof( cbusInitCbusRegsList) / 2); index += 2 )
    {
        SiiRegWrite( cbusInitCbusRegsList[ index], cbusInitCbusRegsList[ index + 1] );
    }

    // Audio link mode update by switch status
    if ( SiiSpdifEnableGet() || !SiiTdmEnableGet() )
    {
        SiiRegWrite(REG_CBUS_DEVICE_CAP_6, MHL_AUD_LINK_MODE_2CH);
    }
    
    // Enable the VS commands, all interrupts, and clear legacy
    SiiRegWrite( REG_CBUS_INTR_0_MASK, 0xFF );      // Enable desired interrupts
    SiiRegWrite( REG_CBUS_INTR_1_MASK, 0xCC );      // Enable desired interrupts
    SiiRegWrite( RX_CBUS_CH_RST_CTRL, 0x00 );       // MHL: Tri-state CBUS

#ifdef MHAWB_SUPPORT
    SiiDrvHawbEnable(false);
#endif
    return( true );
}
///////////////////////////////////////////////////////////////////////////
//
// MhlTxDrvProcessConnection
//
///////////////////////////////////////////////////////////////////////////
static void MhlTxDrvProcessConnection (void)
{
	TX_DEBUG_PRINT (("Drv: MHL Cable Connected. CBUS:0x0A = %02X\n", (int) SiiRegRead(TX_PAGE_CBUS | 0x000A)));

	if( POWER_STATE_D0_MHL == fwPowerState )
	{
		return;
	}
	// VBUS control gpio
	//pinM2uVbusCtrlM = 0;
	//pinMhlConn = 0;
	//pinUsbConn = 1;

	//
	// Discovery over-ride: reg_disc_ovride	
	//
	SiiRegWrite(REG_MHLTX_CTL1, 0x10);

	fwPowerState = POWER_STATE_D0_MHL;

	//
	// Increase DDC translation layer timer (uint8_t mode)
	// Setting DDC Byte Mode
	//
	SiiRegWrite(REG_CBUS_COMMON_CONFIG, 0xF2);

	// Enable segment pointer safety
	//SET_BIT(0x0C44, 1);

	// Un-force HPD (it was kept low, now propagate to source
	//CLR_BIT(REG_INT_CTRL, 4);

	// Enable TMDS
	//SiiMhlTxDrvTmdsControl( true );

	
	// Change TMDS termination to 50 ohm termination (default)
	// Bits 1:0 set to 00
	SiiRegWrite(TX_PAGE_2 | 0x0001, 0x00);

	// Keep the discovery enabled. Need RGND interrupt
	ENABLE_DISCOVERY

	// Wait T_SRC_RXSENSE_CHK ms to allow connection/disconnection to be stable (MHL 1.0 specs)
//	TX_DEBUG_PRINT (("[%d] Drv: Wait T_SRC_RXSENSE_CHK (%d ms) before checking RSEN\n",
//							(int) (HalTimerElapsed( ELAPSED_TIMER ) * MONITORING_PERIOD),
//							(int) T_SRC_RXSENSE_CHK) );

	//
	// Ignore RSEN interrupt for T_SRC_RXSENSE_CHK duration.
	// Get the timer started
	//
//	HalTimerSet(TIMER_TO_DO_RSEN_CHK, T_SRC_RXSENSE_CHK);

	// Notify upper layer of cable connection
	SiiMhlTxNotifyConnection(mhlConnected = true);
}
static void MhlTxDrvProcessDisconnection ( void )
{
	TX_DEBUG_PRINT(("MhlTxDrvProcessDisconnection\n"));
	SiiRegWrite(REG_INTR4, SiiRegRead(REG_INTR4));
	dsHpdStatus &= ~BIT6;  
	SiiRegWrite(REG_MSC_REQ_ABORT_REASON, dsHpdStatus);
	SiiMhlTxNotifyDsHpdChange(0);
	if( POWER_STATE_D0_MHL == fwPowerState )
	{
		SiiMhlTxNotifyConnection(false);
	}
	SwitchToD3();
}
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;
}
////////////////////////////////////////////////////////////////////
// Int5Isr
//
//
//	Look for interrupts on INTR5
//		7 = 
//		6 = 
//		5 = 
//		4 = 
//		3 = 
//		2 = 
//		1 = 
//		0 = 
////////////////////////////////////////////////////////////////////
static void Int5Isr (void)
{
	uint8_t int5Status;

	int5Status = SiiRegRead(REG_INTR5);	// read status
#if 0
	if((int5Status & BIT4) || (int5Status & BIT3)) // FIFO U/O
	{
		TX_DEBUG_PRINT(("** int5Status = %02X; Applying MHL FIFO Reset\n", (int)int5Status));
		SiiRegWrite(REG_SRST, 0x94);
		SiiRegWrite(REG_SRST, 0x84);
	}
#endif
	SiiRegWrite(REG_INTR5, int5Status);	// clear all interrupts
}
//////////////////////////////////////////////////////////////////////////////
//
// 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));
        }
}
Exemple #10
0
bool_t SiiCraInitialize ( void )
{
    uint8_t i, index;
    craInstance.lastResultCode = RESULT_CRA_SUCCESS;

    for (i = 0; i < SII_CRA_DEVICE_PAGE_COUNT; i++)
    {
        l_pageInstance[i] = 0;
    }

    // Perform any register page base address reassignments
    i = 0;
    while ( g_siiRegPageBaseReassign[ i] != 0xFFFF )
    {
        index = g_siiRegPageBaseReassign[ i] >> 8;
        if (( index < SII_CRA_DEVICE_PAGE_COUNT ) && ( g_siiRegPageBaseRegs[ index] != 0xFF))
        {
            // The page base registers allow reassignment of the
            // I2C device ID for almost all device register pages.
            SiiRegWrite( g_siiRegPageBaseRegs[ index], g_siiRegPageBaseReassign[ index] & 0x00FF );
        }
        else
        {
            craInstance.lastResultCode = SII_ERR_INVALID_PARAMETER;
            break;
        }
        i++;
    }

    return( craInstance.lastResultCode == RESULT_CRA_SUCCESS );
}
static void Int5Isr (void)
{
	uint8_t int5Status;
	int5Status = SiiRegRead(REG_INTR5);	
	if (int5Status)
	{
#if (SYSTEM_BOARD == SB_STARTER_KIT_X01)
    	if((int5Status & BIT3) || (int5Status & BIT2))
    	{
    		TX_DEBUG_PRINT (("** Apply MHL FIFO Reset\n"));
    		SiiRegModify(REG_SRST, BIT4, SET_BITS);
    		SiiRegModify(REG_SRST, BIT4, CLEAR_BITS);
    	}
#endif
        if (int5Status & BIT4)
        {
    		TX_DEBUG_PRINT (("** PXL Format changed\n"));
#ifndef __KERNEL__
            SiiOsBumpMhlTxEvent();
#else
            //SiiTriggerExtInt();
#endif
        }
    	SiiRegWrite(REG_INTR5, int5Status);	
	}
}
static void Int1Isr(void)
{
    uint8_t regIntr1;
    regIntr1 = SiiRegRead(REG_INTR1);
    if (regIntr1)
    {
        SiiRegWrite(REG_INTR1,regIntr1);
        if (BIT6 & regIntr1)
        {
            uint8_t cbusStatus;
        	cbusStatus = SiiRegRead(REG_MSC_REQ_ABORT_REASON);
        	TX_DEBUG_PRINT(("Drv: dsHpdStatus =%02X\n", (int) dsHpdStatus));
        	if(BIT6 & (dsHpdStatus ^ cbusStatus))
        	{
                uint8_t status = cbusStatus & BIT6;
        		TX_DEBUG_PRINT(("Drv: Downstream HPD changed to: %02X\n", (int) cbusStatus));
        		SiiMhlTxNotifyDsHpdChange( status );
                if(status)
                {
                   AudioVideoIsr(true);
                }
        		dsHpdStatus = cbusStatus;
        	}
        }
        if(BIT7 & regIntr1)
        {
        	TX_DEBUG_PRINT(("MHL soft interrupt triggered \n"));
        }
    }
}
///////////////////////////////////////////////////////////////////////////
//
// ForceUsbIdSwitchOpen
//
///////////////////////////////////////////////////////////////////////////
static void ForceUsbIdSwitchOpen (void)
{
	DISABLE_DISCOVERY
	SiiRegModify(REG_DISC_CTRL6, BIT6, BIT6);				// Force USB ID switch to open
	SiiRegWrite(REG_DISC_CTRL3, 0x86);
	SiiRegModify(REG_INT_CTRL, BIT5 | BIT4, BIT4);		// Force HPD to 0 when not in Mobile HD mode.
}
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
        }
void SiiDrvHdmiTxLiteDisableEncryption (void)
{
    HDCP_DEBUG_PRINT(("HDCP -> Stopped. 2A = 0\n"));
    printk("HDCP -> Stopped. 2A = 0\n");	
	
    SiiRegWrite(TPI_HDCP_CONTROL_DATA_REG, 0);
}
Exemple #16
0
void SiiRegBitsSet ( SiiReg_t virtualAddr, uint8_t bitMask, bool_t setBits )
{
    uint8_t aByte;

    aByte = SiiRegRead( virtualAddr );
    aByte = (setBits) ? (aByte | bitMask) : (aByte & ~bitMask);
    SiiRegWrite( virtualAddr, aByte );
}
/**
 *  @brief		Handler for HDCP Error
 *
 *****************************************************************************/
static void hdcp_error_handler(bool_t v_sync_mode)
{
	if(v_sync_mode)
	{
		if(0 == SiiRegReadWord(RX_A__HDCP_ERR))
		{
			// Recovered- return to normal checking mode
			DEBUG_PRINT(MSG_STAT, ( "RX: BCH recovered ***\n"));
			switch_hdcp_failure_check_with_v_sync_rate(OFF);
		}
		else
		{
			// Another failure
			rx_isr.hdcp_fail_cntr++;
			if(HDCP_FAIL_THRESHOLD_1ST == rx_isr.hdcp_fail_cntr)
			{
				DEBUG_PRINT(MSG_STAT, ( "RX: Cont. BCH Error ***\n"));

				// Reset Ri to notify an upstream device about the failure.
				// In most cases Ri is already mismatched if we see BCH errors,
				// but there is one rare case when the reseting can help.
				// It is when Ri and Ri' are matched all the time but Ri and Ri'
				// switching happens not synchronously causing a snow
				// screen flashing every 2 seconds. It may happen with
				// some old incomplaint sources or sinks (especially DVI).
				SiiRegWrite(RX_A__HDCP_DEBUG, RX_M__HDCP_DEBUG__CLEAR_RI);

				// Clear BCH counter.
				// The counter accumulates BCH errors and
				// if it is not cleared it can cause an HDCP failure interrupt.
				// Capture and clear BCH T4 errors.
				SiiRegWrite(RX_A__ECC_CTRL, RX_M__ECC_CTRL__CAPTURE_CNT);


				// repeat HPD cycle if HDCP is not recovered
				// in some time
				rx_isr.hdcp_fail_cntr = HDCP_FAIL_THRESHOLD_1ST - HDCP_FAIL_THRESHOLD_CONTINUED;
			}
		}
	}
	else
	{
		switch_hdcp_failure_check_with_v_sync_rate(ON);
		DEBUG_PRINT(MSG_STAT, ( "RX: 1st BCH Error ***\n"));
	}
}
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
	}
}
Exemple #19
0
void SiiRegModify ( SiiReg_t virtualAddr, uint8_t mask, uint8_t value)
{
    uint8_t aByte;

    aByte = SiiRegRead( virtualAddr );
    aByte &= (~mask);                       // first clear all bits in mask
    aByte |= (mask & value);                // then set bits from value
    SiiRegWrite( virtualAddr, aByte );
}
static void SetACRNValue (void)
{
    uint8_t audioFs;
    if ((SiiRegRead(TX_PAGE_L1 | 0x14) & BIT1) && !(SiiRegRead(TX_PAGE_L1 | 0x15) & BIT1))
        audioFs = SiiRegRead(TX_PAGE_L1 | 0x18) & 0x0F;
    else
        audioFs = SiiRegRead(TX_PAGE_L1 | 0x21) & 0x0F;
    switch (audioFs)
    {
        case 0x03:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_32k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_32k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_32k));
            break;
        case 0x00:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_44k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_44k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_44k));
            break;
        case 0x02:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_48k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_48k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_48k));
            break;
        case 0x08:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_88k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_88k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_88k));
            break;
        case 0x0A:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_96k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_96k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_96k));
            break;
        case 0x0C:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_176k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_176k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_176k));
            break;
        case 0x0E:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_192k >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_192k >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_192k));
            break;
        default:
            SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t)(ACR_N_value_default >> 16));
            SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t)(ACR_N_value_default >> 8));
            SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t)(ACR_N_value_default));
            break;
    }
    SiiRegModify(REG_AUDP_TXCTRL, BIT2, CLEAR_BITS); 
}
/**
 *  @brief		Switch No VSI InfoFrame Interrupts Handler
 *
 *  @param[in]		switch_on		true to switch on; false to switch off
 *
 *****************************************************************************/
static void switch_NoVSI_interrupt(bool_t switch_on)
{
	uint8_t pipe = SiiDrvRxInstanceGet();
	uint8_t mask7 = rx_isr[pipe].shadow_interrupt_mask[INT7];
	if(switch_on)
	{
		SiiRegWrite(RX_A__INTR7, RX_M__INTR7__NO_VSI_PACKET); // clear No AVI interrupt if it was raised
		rx_isr[pipe].shadow_interrupt_mask[INT7] |= RX_M__INTR7_MASK__NO_VSI_PACKET;
	}
	else
	{
		rx_isr[pipe].shadow_interrupt_mask[INT7] &= ~RX_M__INTR7_MASK__NO_VSI_PACKET;
	}
	if(mask7!= rx_isr[pipe].shadow_interrupt_mask[INT7])
		SiiRegWrite(RX_A__INTR7_MASK, rx_isr[pipe].shadow_interrupt_mask[INT7]);

	// If NO AVI interrupt is ON, look for NEW AVI only.
	// If NO AVI interrupt is OFF, look for ANY AVI.
	RxIsr_SwitchReceiveInfoFrameOnEveryPacket(INFO_VSI, !switch_on);
}
/**
 *  @brief		Switch HDCP Interrupts Handler
 *
 *  @param[in]		switch_on		true to switch on; false to switch off
 *
 *****************************************************************************/
void RxIsr_SwitchRxHdcpInterrupts(bool_t switch_on)
{
	if(switch_on)
	{
		rx_isr.shadow_interrupt_mask[INT1] |= (RX_M__INTR1__AUTH_START | RX_M__INTR1__AUTH_DONE);

		SiiRegWrite(RX_A__INTR1, RX_M__INTR1__AUTH_START | RX_M__INTR1__AUTH_DONE); // interrupt reset
	}
	else
	{
		rx_isr.shadow_interrupt_mask[INT1] &= ~RX_M__INTR1__AUTH_START;
		rx_isr.shadow_interrupt_mask[INT1] |= RX_M__INTR1__AUTH_DONE;
	}
	SiiRegWrite(RX_A__INTR1_MASK, rx_isr.shadow_interrupt_mask[INT1]); // set mask

	if(!switch_on) // just in case: reset interrupt if they were set
	{
		SiiRegWrite(RX_A__INTR1, RX_M__INTR1__AUTH_START | RX_M__INTR1__AUTH_DONE);
	}
}
Exemple #23
0
void SiiRegBitsSetNew ( SiiReg_t virtualAddr, uint8_t bitMask, bool_t setBits )
{
    uint8_t newByte, oldByte;

    oldByte = SiiRegRead( virtualAddr );
    newByte = (setBits) ? (oldByte | bitMask) : (oldByte & ~bitMask);
    if ( oldByte != newByte )
    {
        SiiRegWrite( virtualAddr, newByte );
    }
}
/**
 *  @brief		Interrupt Handler for HDMI / DVI Transition
 *
 *****************************************************************************/
static void RxIsr_HdmiDviTransition(void)
{
	if(SiiDrvRxHdmiModeGet())
	{
		// Clear BCH counter and the interrupt associated with it.
		// It'll help avoiding a false HDCP Error interrupt caused by pre-HDMI
		// counter content.
		// Capture and clear BCH T4 errors.
		SiiRegWrite(RX_A__ECC_CTRL, RX_M__ECC_CTRL__CAPTURE_CNT);
		SiiRegWrite(RX_A__INTR4, RX_M__INTR4__HDCP); // reset the HDCP BCH error interrupt

		DEBUG_PRINT(MSG_STAT, ("RX: HDMI\n"));
		RxAudio_ReStart();
	}
	else
	{
		DEBUG_PRINT(MSG_STAT, ("RX: DVI\n"));
		// forget all HDMI settings
		RxInfo_ResetData();
		RxAudio_Stop();
	}
}
///////////////////////////////////////////////////////////////////////////////
//
// Function Name: MHLSinkOrDonglePowerStatusCheck()
//
// Function Description: Check MHL device is dongle or sink to set inputting current limitation.
//
void MHLSinkOrDonglePowerStatusCheck (void)
{
	uint8_t RegValue;

	if( POWER_STATE_D0_MHL == fwPowerState )
	{
		SiiRegWrite( REG_CBUS_PRI_ADDR_CMD, MHL_DEV_CATEGORY_OFFSET ); 	// DevCap 0x02
		SiiRegWrite( REG_CBUS_PRI_START, MSC_START_BIT_READ_REG ); // execute DevCap reg read command

		RegValue = SiiRegRead( REG_CBUS_PRI_RD_DATA_1ST );
		TX_DEBUG_PRINT(("[MHL]: Device Category register=0x%02X...\n", (int)RegValue));
	
		if( MHL_DEV_CAT_DONGLE == (RegValue & 0x0F) )
			{
				TX_DEBUG_PRINT(("[MHL]: DevTypeValue=0x%02X, the peer is a dongle, please limit the VBUS current input from dongle to be 100mA...\n", (int)RegValue));
			}
		else if( MHL_DEV_CAT_SINK == (RegValue & 0x0F) )
			{
				TX_DEBUG_PRINT(("[MHL]: DevTypeValue=0x%02X, the peer is a sink, limit the VBUS current input from sink to be 500mA...\n", (int)RegValue));
			}
	}
}
static void ProcessScdtStatusChange(void)
{
	uint8_t scdtStatus;
	uint8_t mhlFifoStatus;

	scdtStatus = SiiRegRead(REG_TMDS_CSTAT);

	TX_DEBUG_PRINT(("Drv: ProcessScdtStatusChange scdtStatus: 0x%02x\n", scdtStatus));

	if (scdtStatus & 0x02)
	{
		 mhlFifoStatus = SiiRegRead(REG_INTR5);
		 TX_DEBUG_PRINT(("MHL FIFO status: 0x%02x\n", mhlFifoStatus));
		 if (mhlFifoStatus & 0x0C)
		 {
			SiiRegWrite(REG_INTR5, 0x0C);

			TX_DEBUG_PRINT(("** Apply MHL FIFO Reset\n"));
			SiiRegWrite(REG_SRST, 0x94);
			SiiRegWrite(REG_SRST, 0x84);
		 }
	}
}
///////////////////////////////////////////////////////////////////////////
//
// MhlTxDrvProcessDisconnection
//
///////////////////////////////////////////////////////////////////////////
static void MhlTxDrvProcessDisconnection (void)
{

	TX_DEBUG_PRINT(("Drv: MhlTxDrvProcessDisconnection\n"));

	// clear all interrupts
	SiiRegWrite(REG_INTR4, SiiRegRead(REG_INTR4));

	SiiRegWrite(REG_MHLTX_CTL1, 0xD0);

    
	dsHpdStatus &= ~BIT6;  //cable disconnect implies downstream HPD low
	SiiRegWrite(REG_PRI_XFR_ABORT_REASON, dsHpdStatus);
	SiiMhlTxNotifyDsHpdChange(0);

	if( POWER_STATE_D0_MHL == fwPowerState )
	{
		// Notify upper layer of cable removal
		SiiMhlTxNotifyConnection(false);
	}

	// Now put chip in sleep mode
	SwitchToD3();
}
static void SetAudioMode(inAudioTypes_t audiomode)
{
    if (audiomode >= AUD_TYP_NUM)
        audiomode = I2S_48;
    SiiRegWrite(REG_AUDP_TXCTRL, audioData[audiomode].regAUD_path);
    SiiRegWrite(TX_PAGE_L1 | 0x14, audioData[audiomode].regAUD_mode);
    SiiRegWrite(TX_PAGE_L1 | 0x1D, audioData[audiomode].regAUD_ctrl);
    SiiRegWrite(TX_PAGE_L1 | 0x21, audioData[audiomode].regAUD_freq);
    SiiRegWrite(TX_PAGE_L1 | 0x23, audioData[audiomode].regAUD_src);
    SiiRegWrite(TX_PAGE_L1 | 0x28, audioData[audiomode].regAUD_tdm_ctrl);
//  SiiRegWrite(TX_PAGE_L1 | 0x22, 0x0B); 
//0x02 for word length=16bits
		    SiiRegWrite(TX_PAGE_L1 | 0x22, 0x02); 
		SiiRegWrite(TX_PAGE_L1 | 0x24,0x02); 

    SiiRegWrite(TX_PAGE_L1 | 0x15, 0x00); 
	//0x7A:0x24 = 0x0B for word lenth is defult 24bit
	
	TX_DEBUG_PRINT(("SiiRegRead(TX_PAGE_L1 | 0x21)=0x%x\n",SiiRegRead(TX_PAGE_L1 | 0x21)));
	TX_DEBUG_PRINT(("SiiRegRead(TX_PAGE_L1 | 0x1D)=0x%x\n",SiiRegRead(TX_PAGE_L1 | 0x1D)));
}
static void SendAudioInfoFrame (void)
{
    SiiRegModify(TX_PAGE_L1 | 0x3E, BIT4|BIT5, CLEAR_BITS); 
    SiiRegWrite(TX_PAGE_L1 | 0x80, 0x84); 
    SiiRegWrite(TX_PAGE_L1 | 0x81, 0x01); 
    SiiRegWrite(TX_PAGE_L1 | 0x82, 0x0A); 
    SiiRegWrite(TX_PAGE_L1 | 0x83, 0x70); 
    SiiRegWrite(TX_PAGE_L1 | 0x84, 0x01); 
    SiiRegWrite(TX_PAGE_L1 | 0x8D, 0x00); 
    SiiRegModify(TX_PAGE_L1 | 0x3E, BIT4|BIT5, SET_BITS); 
}
static	int	Int2Isr( void )
{
    if(SiiRegRead(REG_INTR2) & INTR_2_DESIRED_MASK)
    {
        SiiRegWrite(REG_INTR2, INTR_2_DESIRED_MASK);
        if(SiiRegRead(REG_SYS_STAT) & BIT1)
        {
            TX_DEBUG_PRINT(("PCLK is STABLE\n"));
            if (tmdsPowRdy)
            {
                SendAudioInfoFrame();
                SendAviInfoframe();
            }
        }
    }
    return 0;
}