⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 anx9021.c

📁 HDMI anx9021的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    // set video output format
    Vid_Output_Format = VIDEO_OUTPUT_FORMAT;
    ANX9021_WriteI2C_RX0(VID_AOF_REG, Vid_Output_Format);	

    //# set auto audio mute
    ANX9021_WriteI2C_RX0(AEC_CTRL_REG, 0x05);

    // MCLK select 
    if(MCLK_SEL)
    {
        debug_puts("Select external MCLK.");
        ANX9021_ReadI2C_RX1(ACR_CTRL1_REG, &c);
        ANX9021_WriteI2C_RX1(ACR_CTRL1_REG, c | MCLK_SEL);
    }

    // MCLK frequence select
    if(MCLK_FREQ_SEL)
    {
        debug_puts("Select MCLK frequence.");
        ANX9021_ReadI2C_RX1(FREQ_SVAL_REG, &c);
        ANX9021_WriteI2C_RX1(FREQ_SVAL_REG, c | MCLK_FREQ_SEL);
    }
    

    // Enable I2S output 
    if(AUD_I2S_EN)
    {
        debug_puts("Enable I2S audio output.");
        ANX9021_ReadI2C_RX1(I2S_CTRL2_REG, &c);
        ANX9021_WriteI2C_RX1(I2S_CTRL2_REG, c | 0xf9);
    }
    else  // Disable I2S 
    {
        debug_puts("Disable I2S audio output.");
        ANX9021_ReadI2C_RX1(I2S_CTRL2_REG, &c);
        ANX9021_WriteI2C_RX1(I2S_CTRL2_REG, c & 0x0f);
    }
        
    // Enable hardware soft mute
    ANX9021_WriteI2C_RX1(AUD_CTRL_REG, 0x5);
    
    if(AUD_SPDIF_EN)    // Enable SPDIF
    {
        debug_puts("Enable SPDIF audio output.");
        ANX9021_ReadI2C_RX1(AUD_CTRL_REG, &c);
        ANX9021_WriteI2C_RX1(AUD_CTRL_REG, c | 0x01);
    }
    else        //Disable SPDIF
    {
        debug_puts("Disable SPDIF audio output.");
        ANX9021_ReadI2C_RX1(AUD_CTRL_REG, &c);
        ANX9021_WriteI2C_RX1(AUD_CTRL_REG, c & 0xfe);
    }
      
    //  reset HDCP
    ANX9021_ReadI2C_RX0(SRST_REG, &c);
    ANX9021_WriteI2C_RX0(SRST_REG, c | 0x09);
    ANX9021_ReadI2C_RX0(SRST_REG, &c);
    ANX9021_WriteI2C_RX0(SRST_REG, c & 0xf6);
    
    ANX9021_ReadI2C_RX0(SYS_CTRL1_REG, &c);
    ANX9021_WriteI2C_RX0(SYS_CTRL1_REG, c | 0x01); // power up all

    // Set EQ Value
    ANX9021_WriteI2C_RX0(0xa4, 0x0c);
    ANX9021_WriteI2C_RX0(0xa5, 0x0c);
    ANX9021_WriteI2C_RX0(0xa6, 0x04);       // to receive 165M + HDCP

    // Set video DAC output
    if(!(ANALOG_VID_EN))
    {
        ANX9021_ReadI2C_RX1(PD_SYS_REG, &c);
        ANX9021_WriteI2C_RX1(PD_SYS_REG, c & 0xef);
    }
          
#if 0
// modify the registers by ATI graph card input settings, not used yet

    ANX9021_WriteI2C_RX0(0xa6, 0x04);
    ANX9021_WriteI2C_RX0(0xa9, 0x20); 
    ANX9021_WriteI2C_RX0(0xae, 0x7f);
#endif

    ANX9021_WriteI2C_RX1(I2S_CTRL1_REG, 0x00);  
    debug_puts("Chip is initialized..."); 

    return 1;
}


void ANX9021_HDMI_Port_Switch(INPUT_PORT B_InputConnector)
{
    BYTE B_CurrentANX9021InputPort ;

    ANX9021_ReadI2C_RX0(PORT_SEL_REG, &B_CurrentANX9021InputPort);

    if( (B_InputConnector == INPUT_HDMI) && (B_CurrentANX9021InputPort != 0x22) )  
    {
        debug_puts("**** switch to port1"); 
        ANX9021_Initialize();

        ANX9021_WriteI2C_RX1(PD_SYS2_REG, 0xef); //Power down Port 0 termination circuit
        ANX9021_WriteI2C_RX0(PORT_SEL_REG, 0x02); // Enable TMDS

        ANX9021_HPD_Port1(300);

        ANX9021_WriteI2C_RX0(PORT_SEL_REG, 0x22); // Enable DDC after HPD
    }
    else if((B_InputConnector == INPUT_HDMI2) && (B_CurrentANX9021InputPort != 0x11) ) 
    {
        debug_puts("**** switch to port0"); 
        ANX9021_Initialize();
        ANX9021_WriteI2C_RX1(PD_SYS2_REG, 0xdf); // power on port 1 temination
        ANX9021_WriteI2C_RX0(PORT_SEL_REG, 0x01);

        ANX9021_HPD_Port0(300);
        ANX9021_WriteI2C_RX0(PORT_SEL_REG, 0x11); 

    }
}


void ANX9021_Clk_Detected_Int(void)
{
    BYTE c;

    debug_printf("*ANX9021 Interrupt: Pixel Clock Change.\n");
    ANX9021_ReadI2C_RX0(STATE_REG, &c);
    if (c & 0x02)
    {
        debug_printf("   Pixel clock existed. \n");
        return;
    } 
    else
    {
        debug_printf("   Pixel clock lost. \n");
        ANX9021_Set_Sys_State(MONITOR_CKDT);
        g_Sync_Expire_Cntr = 0;
        //power down chip
        //ANX9021_ReadI2C_RX0(SYS_CTRL1_REG, &c);
        //ANX9021_WriteI2C_RX0(SYS_CTRL1_REG, c & 0xfe); 
    }	
}

// sync changed and pixel clock divider enabled, so software reset
void ANX9021_Align_ODCK_Repeated_Mode(void)
{
    BYTE c;
    
    if(g_Sync_Change)
    {
        ANX9021_ReadI2C_RX0(SYS_CTRL1_REG, &c);
        if(c & 0xc0)
        {
            debug_puts("Align clock and data in repeated mode.");
            g_Sync_Change = 0;
            ANX9021_ReadI2C_RX0(SRST_REG, &c);
            ANX9021_WriteI2C_RX0(SRST_REG, c | 0x01);
            ANX9021_WriteI2C_RX0(SRST_REG, c);
        }
    }

}

void ANX9021_RGBin_Range_Scaling(void)
{
    BYTE c;
    BYTE c0,c1,c2,c3,c4;
    BYTE a1,a2,a3,a4,a5,a6,a7,a8,a9;
    
    ANX9021_ReadI2C_RX0(AEC_CTRL_REG, &c0);
    ANX9021_ReadI2C_RX1(0x40, &c);   
    ANX9021_ReadI2C_RX1(0x44, &c4);   

    if((c != 0x82) && g_HDMI_DVI_Status)
    {
        debug_puts("No AVI infoframe.");
        ANX9021_ReadI2C_RX0(AEC_CTRL_REG, &c);
        ANX9021_WriteI2C_RX0(AEC_CTRL_REG, c | 0x04);            
    }
    else    // AVI infoframe existed
    {
        if(((c4 & 0x60) == 0x00) && ((c0 & 0x04) == 0x04))
        {
            debug_puts("Input RGB range scaling enable.");
            
            ANX9021_ReadI2C_RX0(SYS_CTRL1_REG,&a1);      //0x08
            ANX9021_ReadI2C_RX0(VID_BLANK1_REG,&a2);      //0x4B
            ANX9021_ReadI2C_RX0(VID_BLANK2_REG,&a3);      //0x4C
            ANX9021_ReadI2C_RX0(VID_BLANK3_REG,&a4);      //0x4D
            ANX9021_ReadI2C_RX0(VID_CHLCH_REG,&a5);      //0x58
            ANX9021_ReadI2C_RX0(VID_CHLCL_REG,&a6);      //0x57
            ANX9021_ReadI2C_RX0(VID_PREPC_REG,&a7);      //0x5A
            ANX9021_ReadI2C_RX0(VID_SERPC_REG,&a8);      //0x5D
            ANX9021_ReadI2C_RX0(VID_POSTPC_REG,&a9);      //0x5E
            
            ANX9021_ReadI2C_RX0(VID_MODE_REG, &c1);     //0x4A
            ANX9021_ReadI2C_RX0(VID_MODE2_REG, &c2);   //0x49
            ANX9021_ReadI2C_RX0(VID_CTRL_REG, &c3);      //0x48
            ANX9021_ReadI2C_RX0(AEC_CTRL_REG, &c);
            ANX9021_WriteI2C_RX0(AEC_CTRL_REG, c & 0xfb);
             
            ANX9021_WriteI2C_RX0(VID_MODE2_REG, c2);
            ANX9021_WriteI2C_RX0(VID_CTRL_REG, c3);
            ANX9021_WriteI2C_RX0(VID_MODE_REG, (c1 | 0x10));
            
            ANX9021_WriteI2C_RX0(SYS_CTRL1_REG, a1);
            ANX9021_WriteI2C_RX0(VID_BLANK1_REG, a2);
            ANX9021_WriteI2C_RX0(VID_BLANK2_REG, a3);
            ANX9021_WriteI2C_RX0(VID_BLANK3_REG, a4);
            ANX9021_WriteI2C_RX0(VID_CHLCH_REG, a5);
            ANX9021_WriteI2C_RX0(VID_CHLCL_REG, a6);
            ANX9021_WriteI2C_RX0(VID_PREPC_REG, a7);
            ANX9021_WriteI2C_RX0(VID_SERPC_REG, a8);
            ANX9021_WriteI2C_RX0(VID_POSTPC_REG, a9);
            
 
        }
        else if (((c4 & 0x60) != 0x00) && ((c0 & 0x04) == 0x00)) 
        {
            ANX9021_ReadI2C_RX0(AEC_CTRL_REG, &c);
            ANX9021_WriteI2C_RX0(AEC_CTRL_REG, c | 0x04);           
        }
    }
}

void ANX9021_PLL_Reset(void)
{
    BYTE c, c1;

    ANX9021_WriteI2C_RX0(TMDS_PLL_RNG_CTRL_REG, 0x00);
    ANX9021_WriteI2C_RX0(SRST2_REG, 0x08);  // misc reset 
    delay_ms(5); 
    ANX9021_ReadI2C_RX0(TMDS_PLL_RNG_STATUS_REG, &c);
    c1 = c & 0x61;
    if(c&0x02)  c1 = c1 | 0x04; 
    if(c&0x04)  c1 = c1 | 0x10;  
    if(c&0x08)  c1 = c1 | 0x02;
    if(c&0x10)  c1 = c1 | 0x08;   
    c1 = c1 | 0x80;
    ANX9021_WriteI2C_RX0(TMDS_PLL_RNG_CTRL_REG, c1);
    ANX9021_WriteI2C_RX0(SRST2_REG, 0x08);  // misc reset
    debug_puts("++++++++++Debug information:  PLL reset completed."); 

    ANX9021_Set_Sys_State(WAIT_SCDT);
}

void ANX9021_Show_Video_Info(void)
{
    BYTE c;
    BYTE cl,ch;
    WORD n;
    WORD h_res,v_res;
    
    ANX9021_ReadI2C_RX0(DE_PIXL_REG, &cl);
    ANX9021_ReadI2C_RX0(DE_PIXH_REG, &ch);
    n = ch;
    n = (n << 8) + cl;
    h_res = n;
    
    ANX9021_ReadI2C_RX0(DE_LINL_REG, &cl);
    ANX9021_ReadI2C_RX0(DE_LINH_REG, &ch);
    n = ch;
    n = (n << 8) + cl;
    v_res = n;
    
    debug_puts("");
    debug_puts("***********************************ANX9021 Info************************************");
    debug_printf("ANX9021 Is Normally Play Back.\n");
    ANX9021_ReadI2C_RX0(SHD_BSTAT2_REG, &c); 
    if(c&0x10)
        debug_printf("ANX9021 Mode = HDMI Mode.\n");
    else
        debug_printf("ANX9021 Mode = DVI Mode.\n");

    ANX9021_ReadI2C_RX0(VID_STAT_REG, &c); 
    if(c & 0x04)
    {
        v_res += v_res;
    }       
    debug_printf("ANX9021 Video Resolution = %d * %d ",h_res,v_res);
    ANX9021_ReadI2C_RX0(VID_STAT_REG, &c); 
    if(c & 0x04)
        debug_puts("    Interlace Video.");
    else
        debug_puts("    Progressive Video.");


    debug_printf("The Video Interface = Digital Video");
    if(ANALOG_VID_EN)
        debug_printf("  +  Analog Video.\n");
    else
        debug_printf(" .\n");
    
    ANX9021_ReadI2C_RX0(SYS_CTRL1_REG, &c);  
    if((c & 0x30) == 0x00)
        debug_printf("Input Pixel Clock = Not Repeated.\n");
    else if((c & 0x30) == 0x10)
        debug_printf("Input Pixel Clock = 2x Video Clock. Repeated.\n");
    else if((c & 0x30) == 0x30)
        debug_printf("Input Pixel Clock = 4x Vvideo Clock. Repeated.\n");

    if((c & 0xc0) == 0x00)
        debug_printf("Output Video Clock = Not Divided.\n");
    else if((c & 0xc0) == 0x40)
        debug_printf("Output Video Clock = Divided By 2.\n");
    else if((c & 0xc0) == 0xc0)
        debug_printf("Output Video Clock = Divided By 4.\n");

    if(c & 0x02)
        debug_printf("Output Video Using Rising Edge To Latch Data.\n");
    else
        debug_printf("Output Video Using Falling Edge To Latch Data.\n");

    debug_printf("Input Video Color Space = ");
    ANX9021_ReadI2C_RX1(0x44, &c);  
    c &= 0x60;
    if(c == 0x20)        
        debug_printf("YCbCr4:2:2 .\n");
    else if(c == 0x40)   
        debug_printf("YCbCr4:4:4 .\n");
    else if(c == 0x00)   
        debug_printf("RGB.\n");
    else                 
        debug_printf("Unknow 0x44 = 0x%.2x\n",(int)c);
    
    ANX9021_ReadI2C_RX0(VID_AOF_REG, &c);  
    if(c&0x80)
    {
        if(c&0x40)
            debug_printf("Output Video Format = YCbCr4:2:2.\n");
        else
            debug_printf("Output Video Format = YCbCr4:4:4.\n");
    }
    else if((c&0x80) == 0x00)
        debug_printf("Output Video Format = RGB.\n");

    if(MCLK_SEL)
    {
        debug_puts("Input MCLK is selected.");
    }
    else
    {
        debug_printf("Output MCLK Frequence = ");
        
        switch(MCLK_FREQ_SEL)
        {
            case 0x00: 
                debug_puts("128 * Fs.");
                break;
            case 0x10: 
                debug_puts("256 * Fs.");
                break;
            case 0x20:
                debug_puts("384 * Fs.");
                break;
            case 0x30: 
                debug_puts("512 * Fs.");
                break;
            default :         
                debug_puts("Wrong MCLK output.");
                break;
        }
    }

    debug_printf("Audio Fs = ");
    ANX9021_ReadI2C_RX1(CHST4_REG, &c); 
    c &= 0x0f;
    switch(c)
    {
        case 0x00: 
            debug_puts("44.1 KHz.");
            break;
        case 0x02: 
            debug_puts("48 KHz.");
            break;
        case 0x03: 
            debug_puts("32 KHz.");
            break;
        case 0x08: 
            debug_puts("88.2 KHz.");
            break;        
        case 0x0a: 
            debug_puts("96 KHz.");
            break;
        case 0x0e: 
            debug_puts("192 KHz.");
            break;
        default :         
            debug_puts("Wrong MCLK output.");
            break;
    }

    ANX9021_ReadI2C_RX0(HDCP_STAT_REG, &c); 
    if(c & 0x10)
        debug_puts("Authentication is attempted.");
    else
        debug_puts("Authentication is not attempted.");

    for(cl=0;cl<20;cl++)
    {
        ANX9021_ReadI2C_RX0(HDCP_STAT_REG, &c); 
        if(c & 0x20)
            break;
        else
            delay_ms(20);
    }
    if(cl < 20)
        debug_puts("Decryption is active.");
    else
        debug_puts("Decryption is not active.");
             
    debug_puts("***********************************************************************************");
    debug_puts("");
}


void ANX9021_HPD_Port0(int delaytime)
{
    debug_puts("ANX9201 port 0 HPD issued... ");
    P3_4 = 0;
    delay_ms(delaytime);
    P3_4 = 1;
    
}
void ANX9021_HPD_Port1(int delaytime)
{
    debug_puts("ANX9201 port 1 HPD issued... ");
    P3_5 = 0;
    delay_ms(delaytime);
    P3_5 = 1;
}

BYTE ANX9021_ReadI2C_RX0(BYTE sub_addr, BYTE *rxdata)
{
    BYTE rc;
    rc = i2c_read_p0_reg(sub_addr,rxdata);
    if(rc) { debug_puts("**** ANX9021 RX0 Read Error"); }
    return	rc;
}

BYTE ANX9021_WriteI2C_RX0(BYTE sub_addr, BYTE txdata)
{
    BYTE rc;
    rc = i2c_write_p0_reg(sub_addr,txdata);
    if(rc) { debug_puts("**** ANX9021 RX0 Write Error"); }
    return	rc;	
}

BYTE ANX9021_ReadI2C_RX1(BYTE sub_addr,  BYTE *rxdata)
{
    BYTE rc;
    rc = i2c_read_p1_reg(sub_addr,rxdata);
    if(rc) { debug_puts("**** ANX9021 RX1 Read Error"); }
    return	rc;
}

BYTE ANX9021_WriteI2C_RX1(BYTE sub_addr,  BYTE txdata)
{
    BYTE	rc;
    rc = i2c_write_p1_reg(sub_addr,txdata);
    if(rc) { debug_puts("**** ANX9021 RX1 Write Error"); }
    return	rc;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -