ADV7611是一款高质量、单输入HDMI® 接收器,支持HDMI 1.4a 规范规定的所有强制性3D电视格式和最高UXGA 60 Hz、8位的分辨率,可从HDMI流提取的音频数据。HDMI接收器具有高级静音控制器,可消除音频输出中的外来声频噪声。此外,可以将ADV7611设置为输出TDM I2S,以便支持发送四个多路复用的I2S通道。 HDMI端口具有专用的5 V检测和热插拔(Hot Plug™)置位引脚。64引脚、10 mm × 10 mm LQFP_EP表贴封装,额定温度范围为−40°C至+85°C。

文档

软件

PCLK

PCLK = (X Resolution + 1) × (Y Resolution + 1) × Vertical Refresh Rate

e.g. PCLK = (1080px +1) x (1920px +1) x 60Hz = 124MHz

注意事项

adv7611_i2c_map_addresses

 

修改 I2C 地址,可以实现 Dual ADV7611 方案

修改 I2C 地址方法1: VS/FIELD/ALSB 脚接 10K 上拉电阻至3.3V,使 IO Map 地址变为 0x9A(>>1=0x4D)

修改 I2C 地址方法2:通过 I2C 向 IO Map 中的 SAMPLE_ALSB (0x1B) 地址 写入1,使 IO Map 地址变为 0x9A(>>1=0x4D)

论坛资源

应用笔记

RGB 输出调试

将主机画面分别设置为纯R, 纯G, 纯B,后通过示波器,分别检查24个脚,如画面为纯B时,B 的8个pin 输出都应为 HIGH,其他 G 和 B 均为 LOW。

ADV7611 可以通过 I2C 控制,使用 I2CTool,follow 這一篇:http://boundarydevices.com/i2c-tools-under-android/舊版頁面 去download 3.0.2 解開到 framework 下, 再follow 那一篇,把 Android.mk create 出來。 為了避免 link 不見, copy 了一份在gist。 OK, build 出來後,在 android 下就可以 run 了。 先用 i2cdetect -l 看一下:

i2c-0 i2c imx-i2c I2C adapter i2c-1 i2c imx-i2c I2C adapter i2c-2 i2c imx-i2c I2C adapter

会扫描出 I2C Bus 总线,查看 ADV7611 数据手册,有说明 RESET 后,I2C 地址是 0x98,但是 I2C Address  是 7 个 bit + 1 个 bit R/W。 在用 linux driver 控制時,要把这种标示 i2c address shift 1 bit:

0x98 >> 1

就是 0x4c 用 i2cget command 读一下 register 0xEA, 0xEB : Revision identification:

bash-3.2# i2cget -f -y 0 0x4c 0xea

返回 0x20

bash-3.2# i2cget -f -y 0 0x4c 0xeb

返回 0x51

所以是 0x2051 为 ADV7611 没错。接着测试 write function。 ADV7611 有说,他的 address 是考 VS/FIELD/ALSB 決定的。 所以 chip power on reset 後,address 都是 0x98。 之後 write 0x01 到 register 0x1B (SAMPLE_ALSB),之后, chip 就会根据 VS/FIELD/ALSB 的电压决定 Address:

  • low : 0x98 (shift 后就是 0x4c)
  • high: 0x9A (shift 后就是 0x4d)

所以先读一下 0x1B:

bash-3.2# i2cget -f -y 0 0x4c 0x1b

返回 0x00

然后写入:

bash-3.2# i2cset 0 0x4c 0x1b 1

WARNING! This program can confuse your I2C bus, cause data loss and worse! I will write to device file /dev/i2c-0, chip address 0x4c, data address 0x1b, data 0x01, mode byte. Continue? [Y/n] Y

用新 address 0x4d 读读看 :

bash-3.2# i2cget -f -y 0 0x4d 0x1b

返回 0x01

好像成功了。

音频

ADV7611不可能直接送声音到耳机, 所以在ADV7611输出后,系统一定经过声音处理芯片. 如有一个声道有声音的. 所以要不是音频处理芯片没有配置好, 或者是ADV7611和音频处理芯片的配置不匹配. 您可以查看一下音频处理芯片需要不需要MCLK, MCLK的频率需要是多少(DPLL Map 0xB5[2:0]), 音频处理芯片需不需要配置音频的采样频率(从HDMI Map, 0x39[3:0]可以读到), I2S输出的模式是需要什么配置(HDMI Map 0x03[6:5]).

笔记

  • 如果通过修改SAMPLE_ALSB 导致 I2C 地址变为 0x4D,需要短路 ADV7611 RESET 到 GND 进行复位

 

  • ADV7611_I2CADDR_HDMI,0x6c,配置成0xa7==>手动模式
  • ADV7611_I2 ADDR_EDID,0x20,0x70 按文档所说这样配置就是拉低HPA然后delay 了1000毫秒。再拉高HPA。

 

故障排查

首先要分析EDID的timing format是否是AD7611可以支持的,如果是不可以支持的话,则需要修改EDID,否则源很有可能送出ADV7611不能支持的timing format。

如果是可以支持的timing,ADV7611还是不能工作,您需要回读以下寄存器来查找原因:

  1.  IO Map R0x6F[0]是否为1 (是否检测到cable接入)
  2. IO Map R0x6A[4]是否为1 (是否检测到HDMI Clock)
  3. HDMI Map R0x04[1]是否为1 (是否HDMI PLL lock)
  4. HDMI Map R0x05[6]是否为1 (HDMI 内容是否加密)
  5.  HDMI Map R0x07[5]是否为1 (De generation是否锁定)
  6. IO Map R0x6F[0]是否为1 (是否检测到cable接入) 看是否HDMI接头有连接问题. 或者是7611供电不正常, 结果不能正确检测.
  7. IO Map R0x6A[4]是否为1 (是否检测到HDMI Clock) 看是否是连接问题. 或者是HDMI源没有输出. 可以量测CLK的TMDS电平, 如果是3.3V说明ADV7611的上拉已经配置了, 如果是0V, 需要配置ADV7611的Termination. 如果源还是没有输出, 要看EDID有没有配置. 配置EDID后, 最好toggle一下HPA这个管脚, 让源知道重新获取EDID.
  8.  HDMI Map R0x04[1]是否为1 (是否HDMI PLL lock) 源送出的信号不稳定; HDMI Cable过程, 信号衰减大; 焊接有问题, 信号不能正常送入芯片; ADV7611的供电电源噪声比较大.
  9. HDMI Map R0x05[6]是否为1 (HDMI 内容是否加密) 加密不机密, ADV7611都能送出正确的同步信号, 只是图像可能是雪花或者是黑屏. ADV7611可以自动解HDCP, 只要HDMI block使能了.
  10. HDMI Map R0x07[5]是否为1 (De generation是否锁定)

 寄存器注释

/*@group Basic Config */
{0x98,0xF4,0x80}, //CEC
{0x98,0xF5,0x7C}, //INFORFRAME
{0x98,0xF8,0x4C}, //DPLL
{0x98,0xF9,0x64}, //KSV
{0x98,0xFA,0x6C},  //EDID
{0x98,0xFB,0x68},  //HDMI
{0x98,0xFD,0x44}  //CP
/* @end */


/*@group Required Registers */
    writeAT(0x98, 0x01, 0x06);
    writeAT(0x98, 0x02, 0xF7);
    writeAT(0x98, 0x03, 0x40);
    writeAT(0x98, 0x04, 0x42);
    writeAT(0x98, 0x05, 0x28);
    writeAT(0x98, 0x06, 0xA6);
    writeAT(0x98, 0x0B, 0x44);
    writeAT(0x98, 0x0C, 0x42);
    writeAT(0x98, 0x15, 0x80);
    writeAT(0x98, 0x19, 0x8A);
    writeAT(0x98, 0x14, 0x7F);	//LLC的时钟范围
    writeAT(0x98, 0x33, 0x40); 
    writeAT(0x44, 0xBA, 0x01);//0关闭FREE RUN	00测试与这个配置无关
    writeAT(0x64, 0x40, 0x81);//最高位为0:DVI	01测试与这个配置无关



    writeAT(0x68, 0x9B, 0x03);
    writeAT(0x68, 0xC1, 0x01);
    writeAT(0x68, 0xC2, 0x01);
    writeAT(0x68, 0xC3, 0x01);
    writeAT(0x68, 0xC4, 0x01);
    writeAT(0x68, 0xC5, 0x01);
    writeAT(0x68, 0xC6, 0x01);
    writeAT(0x68, 0xC7, 0x01);
    writeAT(0x68, 0xC8, 0x01);
    writeAT(0x68, 0xC9, 0x01);
    writeAT(0x68, 0xCA, 0x01);
    writeAT(0x68, 0xCB, 0x01);
{0x68, 0xCC, 0x01);

{0x68, 0x00, 0x00);
{0x68, 0x83, 0xFE);
{0x68, 0x6F, 0x08);
{0x68, 0x85, 0x1F);
{0x68, 0x87, 0x70);
{0x68, 0x8D, 0x04);
{0x68, 0x8E, 0x1E}
{0x68, 0x1A, 0x8A}
{0x68, 0x57, 0xDA}
{0x68, 0x58, 0x01}
{0x68, 0x75, 0x10}
// {0x64, 0x74, 0x03} // disable internal EDID

/* @end */

(0X64,0X76);	//	读取EDID STATUS 01为ENABLE
(0x68,0x04);	//读取TMDS LOCKED=0X23
(0x98,0x6A);	//读取TMDS PLL LOCKED=0X53


/*@ Process to write EDID */
char code EDID[128]=
{
0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X10,0XAC,0X72,0XA0,0X53,0X44,0X32,0X31,
0X03,0X16,0X01,0X03,0X80,0X30,0X1B,0X78,0XEA,0X01,0XF5,0XA2,0X57,0X52,0X9F,0X27,
0X0A,0X50,0X54,0XA5,0X4B,0X00,0X71,0X4F,0X81,0X80,0XD1,0XC0,0X01,0X01,0X01,0X01,
0X01,0X01,0X01,0X01,0X01,0X01,0X02,0X3A,0X80,0X18,0X71,0X38,0X2D,0X40,0X58,0X2C,
0X45,0X00,0XDD,0X0C,0X11,0X00,0X00,0X1E,0X00,0X00,0X00,0XFF,0X00,0X57,0X38,0X57,
0X33,0X36,0X32,0X31,0X49,0X31,0X32,0X44,0X53,0X0A,0X00,0X00,0X00,0XFC,0X00,0X44,
0X45,0X4C,0X4C,0X20,0X45,0X32,0X32,0X31,0X31,0X48,0X0A,0X20,0X00,0X00,0X00,0XFD,
0X00,0X38,0X4C,0X1E,0X53,0X11,0X00,0X0A,0X20,0X20,0X20,0X20,0X20,0X20,0X00,0XA3
} ;
void Write_EDID()
{
    uchar i=0;
//	writeAT(0x68, 0x6C, 0xA3); // enable manual HPA
//	writeAT(0x98, 0x20, 0x70); // HPD low
//	writeAT(0x64, 0x74, 0x00); // disable internal EDID

    for (i=0; i<128; i++)
        writeAT(0x6C, i, EDID[i]);

//	delay1(50);
//	writeAT(0x64, 0x74, 0x01); // enable internal EDID
//	writeAT(0x98, 0x20, 0x70); // HPD high
//	writeAT(0x68, 0x6C, 0xA3); // disable manual HPA
}
/* @end */

/*@group Dectect Hot Plug */
{0x98,0x21} //检测HPD 0x08
{0x98,0x6F} //检测插入
/* @end */