前言
准备用hi3531d做hdmi输入,但是只有IT6801FN的驱动ko,担心调不好,于是决定先使用原来一直用的sii9233a,这款芯片的资料比较难找,而且都是英文的,所以我先放个链接好了
链接:https://pan.baidu.com/s/1Ikt8G5sJTTrnsrHmg7SLUQ 提取码:gkh7
通过海思的应用层i2c接口,完成sii9233a的配置,代码较长,可以参考,从main函数看起
sii9233a.c
#include "sii9233a.h"
#define SELF_TEST 1
int hi_i2c_read_single(SII9233_Dev_t dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t *value)
{
int status = 0;
char recvbuf[2] = {
0};
ioctl(dev.i2c_dev_fd, I2C_SLAVE_FORCE, dev_addr);
ioctl(dev.i2c_dev_fd, I2C_16BIT_REG, 0); //8bit
ioctl(dev.i2c_dev_fd, I2C_16BIT_DATA, 0); //8bit
recvbuf[0] = reg_addr;
recvbuf[1] = 0;
status = read(dev.i2c_dev_fd, recvbuf, 1);
*value = recvbuf[0];
if(status <= 0)
{
sii9233_printf("i2c device[%s] read error, dev_addr=0x%x, reg_addr=0x%x\n", dev.i2c_dev_name, dev_addr, reg_addr);
return -1;
}
sii9233_printf("i2c device[%s] read, dev_addr=0x%x, reg_addr=0x%x, value=0x%x\n", dev.i2c_dev_name, dev_addr, reg_addr, recvbuf[0]);
return status;
}
int hi_i2c_write_single(SII9233_Dev_t dev, uint8_t dev_addr, uint8_t reg_addr, uint8_t value)
{
int status = 0;
char sendbuf[2];
ioctl(dev.i2c_dev_fd, I2C_SLAVE_FORCE, dev_addr);
ioctl(dev.i2c_dev_fd, I2C_16BIT_REG, 0); //8bit
ioctl(dev.i2c_dev_fd, I2C_16BIT_DATA, 0); //8bit
sendbuf[0] = reg_addr;
sendbuf[1] = value;
status = write(dev.i2c_dev_fd, sendbuf, 2);
if(status <= 0)
{
sii9233_printf("i2c device[%s] write error, dev_addr=0x%x, reg_addr=0x%x, value=0x%x\n", dev.i2c_dev_name, dev_addr, reg_addr, value);
return -1;
}
sii9233_printf("i2c device[%s] write, dev_addr=0x%x, reg_addr=0x%x, value=0x%x\n", dev.i2c_dev_name, dev_addr, reg_addr, value);
return status;
}
int hi_i2c_read(SII9233_Dev_t dev, uint8_t dev_addr, uint8_t *reg_addr, uint8_t *value, uint8_t len)
{
int status = 0;
int i = 0;
for (i=0; i < len; i++)
{
status = hi_i2c_read_single(dev, dev_addr, reg_addr[i], &value[i]);
if (status <= 0)
return -1;
}
return 0;
}
int hi_i2c_write(SII9233_Dev_t dev, uint8_t dev_addr, uint8_t *reg_addr, uint8_t *value, uint16_t len)
{
int status = 0;
int i = 0;
for (i=0; i < len; i++)
{
status = hi_i2c_write_single(dev, dev_addr, reg_addr[i], value[i]);
if (status <= 0)
return -1;
}
return 0;
}
int sii9233_para_init(SII9233_Dev_t *pdev)
{
memset(pdev, 0, sizeof(SII9233_Dev_t));
strcpy(pdev->i2c_dev_name, "/dev/i2c-1");
pdev->first_dev_addr = 0x62;
pdev->second_dev_addr = 0x6a;
pdev->xv_color_addr = 0x64;
pdev->edid_addr = 0xe0;
pdev->cec_addr = 0xc0;
pdev->videoDataFormat = SYSTEM_DF_YUV422P;
pdev->standard = SYSTEM_STD_1080P_30;
return 0;
}
int sii9233_open(SII9233_Dev_t *pdev)
{
pdev->i2c_dev_fd = open(pdev->i2c_dev_name, O_RDWR);
if(pdev->i2c_dev_fd < 0)
{
sii9233_printf("open i2c device[%s] error, fd = %d\n", pdev->i2c_dev_name, pdev->i2c_dev_fd);
return pdev->i2c_dev_fd;
}
return 0;
}
int sii9233_close(SII9233_Dev_t *pdev)
{
close(pdev->i2c_dev_fd);
return 0;
}
int sii9233_set_slave_addr_reg(SII9233_Dev_t *pdev)
{
// Device_sii9233aSetSlaveAddress
// i2c_write 0x1 0x62 0x15 0x64 1 1
// i2c_write 0x1 0x62 0x18 0xc0 1 1
// i2c_write 0x1 0x62 0x19 0xe0 1 1
int status = 0;
int reg_num = 0;
pdev->regaddr[0] = 0x15;
pdev->regaddr[1] = 0x18;
pdev->regaddr[2] = 0x19;
pdev->regdata[0] = pdev->xv_color_addr;
pdev->regdata[1] = pdev->cec_addr;
pdev->regdata[2] = pdev->edid_addr;
reg_num = 3;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_set_slave_addr error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
return 0;
}
int sii9233_set_factory_reg(SII9233_Dev_t *pdev)
{
// i2c_write 0x1 0x62 0x0e 0x40 1 1
// i2c_write 0x1 0xe0 0xe5 0x02 1 1
// i2c_write 0x1 0x64 0x81 0x18 1 1
// i2c_write 0x1 0x64 0x87 0x43 1 1
// i2c_write 0x1 0x64 0x89 0x00 1 1
// i2c_write 0x1 0x64 0x92 0x8a 1 1
// i2c_write 0x1 0x64 0x93 0xaa 1 1
// i2c_write 0x1 0x64 0x94 0x1a 1 1
// i2c_write 0x1 0x64 0x95 0x2a 1 1
// i2c_write 0x1 0x64 0xb5 0x40 1 1
// i2c_write 0x1 0x64 0xbb 0x04 1 1
int status = 0;
int reg_num = 0;
pdev->regaddr[0] = 0x0e;
pdev->regdata[0] = 0x40;
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_set_factory_reg error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
pdev->regaddr[0] = 0xe5;
pdev->regdata[0] = 0x2;
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->edid_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_set_factory_reg error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->edid_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
pdev->regaddr[0] = 0x81;
pdev->regaddr[1] = 0x87;
pdev->regaddr[2] = 0x89;
pdev->regaddr[3] = 0x92;
pdev->regaddr[4] = 0x93;
pdev->regaddr[5] = 0x94;
pdev->regaddr[6] = 0x95;
pdev->regaddr[7] = 0xb5;
pdev->regaddr[8] = 0xbb;
pdev->regdata[0] = 0x18;
pdev->regdata[1] = 0x43; //这个寄存器的值,读出来看是0x03,设了0x43也改变不了,但是好像没什么影响
pdev->regdata[2] = 0x00;
pdev->regdata[3] = 0x8a;
pdev->regdata[4] = 0xaa;
pdev->regdata[5] = 0x1a;
pdev->regdata[6] = 0x2a;
pdev->regdata[7] = 0x40;
pdev->regdata[8] = 0x04;
reg_num = 9;
status = hi_i2c_write(*pdev, pdev->xv_color_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_set_factory_reg error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->xv_color_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
return 0;
}
int sii9233_init_edid_reg(SII9233_Dev_t *pdev)
{
// i2c_write 0x1 0xe0 0x1 0xf 1 1
// i2c_write 0x1 0xe0 0x4 0x1 1 1
// i2c_write 0x1 0xe0 0x2 0x0 1 1
// 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x4D, 0x29, 0x23, 0x92, 0x01, 0x00, 0x00, 0x00,
// 0x00, 0x12, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78, 0x0A, 0x0D, 0xC9, 0xA0, 0x57, 0x47, 0x98, 0x27,
// 0x12, 0x48, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
// 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
// 0x45, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20,
// 0x6E, 0x28, 0x55, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x43,
// 0x50, 0x39, 0x32, 0x32, 0x33, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFD,
// 0x00, 0x17, 0x78, 0x0F, 0x7E, 0x17, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x66,
// 0x02, 0x03, 0x3D, 0x72, 0x55, 0x90, 0x04, 0x03, 0x02, 0x0E, 0x0F, 0x07, 0x23, 0x24, 0x05, 0x94,
// 0x13, 0x12, 0x11, 0x1D, 0x1E, 0xA0, 0xA1, 0xA2, 0x01, 0x1F, 0x35, 0x09, 0x7F, 0x07, 0x09, 0x7F,
// 0x07, 0x17, 0x07, 0x50, 0x3F, 0x06, 0xC0, 0x57, 0x06, 0x00, 0x5F, 0x7F, 0x01, 0x67, 0x1F, 0x00,
// 0x83, 0x4F, 0x00, 0x00, 0x68, 0x03, 0x0C, 0x00, 0x10, 0x00, 0xB8, 0x2D, 0x00, 0x8C, 0x0A, 0xD0,
// 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x18, 0x8C,
// 0x0A, 0xD0, 0x90, 0x20, 0x40, 0x31, 0x20, 0x0C, 0x40, 0x55, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00,
// 0x18, 0x01, 0x1D, 0x80, 0x18, 0x71, 0x1C, 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0xC4, 0x8E, 0x21,
// 0x00, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E
int status = 0 ,i;
int reg_num = 0;
uint8_t fifoValue;
pdev->regaddr[0] = 0xd1;
pdev->regdata[0] = 0;
reg_num = 1;
// i2c_read form i2c-1 devaddr:0xe0 regaddr:0xd1 value:0x1
status = hi_i2c_read(*pdev, pdev->edid_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_port_switch error\n");
return -1;
}
if(pdev->regdata[0] == 0x01)
fifoValue =0x01;
else if((pdev->regdata[0] == 0x02) || (pdev->regdata[0] == 0x03))
fifoValue =0x02;
else if((pdev->regdata[0] == 0x04) || (pdev->regdata[0] == 0x05))
fifoValue =0x04;
else if((pdev->regdata[0] == 0x08) || (pdev->regdata[0] == 0x09))
fifoValue =0x08;
else
fifoValue =0x02;
pdev->regaddr[0] = 0x01;
pdev->regaddr[1] = 0x04;
pdev->regaddr[2] = 0x02