前言
准备用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;
pdev->regdata[0] = 0x0f;
pdev->regdata[1] = fifoValue;
pdev->regdata[2] = 0x00;
reg_num = 3;
status = hi_i2c_write(*pdev, pdev->edid_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_init_edid_reg error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->edid_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
uint8_t buf[0x100] = {
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,
};
for (i = 0; i < 0x100; i++)
{
pdev->regaddr[i] = 0x03;
pdev->regdata[i] = buf[i];
}
status = hi_i2c_write(*pdev, pdev->edid_addr, pdev->regaddr, pdev->regdata, 0x100);
if(status < 0)
{
sii9233_printf("sii9233_init_edid_reg error\n");
return -1;
}
return 0;
}
int sii9233_get_chip_id(SII9233_Dev_t *pdev)
{
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x0 value:0x1
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x1 value:0x0
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x2 value:0x33
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x3 value:0x92
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x4 value:0x33
// get chip id : chipId=0x9233, chipRevision=0x33, firmwareVersion=0x1
int status = 0;
int reg_num = 0;
pdev->regaddr[0] = 0x00;
pdev->regaddr[1] = 0x01;
pdev->regaddr[2] = 0x02;
pdev->regaddr[3] = 0x03;
pdev->regaddr[4] = 0x04;
pdev->regdata[0] = 0;
pdev->regdata[1] = 0;
pdev->regdata[2] = 0;
pdev->regdata[3] = 0;
pdev->regdata[4] = 0;
reg_num = 5;
status = hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_get_chip_id error\n");
return -1;
}
pdev->chip_info.chipId = pdev->regdata[3] << 8 | pdev->regdata[2];
pdev->chip_info.chipRevision = (pdev->regdata[4]);
pdev->chip_info.firmwareVersion = (pdev->regdata[1] << 8 | pdev->regdata[0]);
// sii9233_printf("sii9233_get_chip_id : chipId=0x%x, chipRevision=0x%x, firmwareVersion=0x%x\n", \
// pdev->chip_info.chipId, pdev->chip_info.chipRevision, pdev->chip_info.firmwareVersion);
return 0;
}
int sii9233_get_video_status(SII9233_Dev_t *pdev)
{
// i2c_write 0x1 0x62 0x6a 0x0 1 1
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x3a value:0x98
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x3b value:0x8
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x3c value:0x65
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x3d value:0x4
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x4e value:0x80
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x4f value:0x7
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x50 value:0x38
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x51 value:0x4
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x6e value:0xe8
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x6f value:0x2
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x55 value:0x3
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x6 value:0x3b
// hRes=0x898, vRes=0x465, dePix=0x780, deLin=0x438, xclkInPclk=0x2e8, vidStat=0x3, sysStat=0x3b
// i2c_write 0x1 0x62 0x6a 0x1 1 1
// VCAP: DEVICE-0 (0x31): Detected video ([email protected], 0) !!!
int status = 0;
int reg_num = 0;
uint32_t hRes = 0; //horizontal resolution
uint32_t vRes = 0; //vertical resolution
uint32_t dePix = 0; //horizontal active data resolution
uint32_t deLin = 0; //vertical active data resolution
uint32_t xclkInPclk = 0; //number of xclks per 2048 video clocks
uint32_t vidStat = 0; //video status
uint32_t sysStat = 0; //system status
pdev->regaddr[0] = 0x6a;
pdev->regdata[0] = 0x00;
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_get_video_status 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] = 0x3a;
pdev->regaddr[1] = 0x3b;
pdev->regaddr[2] = 0x3c;
pdev->regaddr[3] = 0x3d;
pdev->regaddr[4] = 0x4e;
pdev->regaddr[5] = 0x4f;
pdev->regaddr[6] = 0x50;
pdev->regaddr[7] = 0x51;
pdev->regaddr[8] = 0x6e;
pdev->regaddr[9] = 0x6f;
pdev->regaddr[10] = 0x55;
pdev->regaddr[11] = 0x06;
pdev->regdata[0] = 0x0;
pdev->regdata[1] = 0x0;
pdev->regdata[2] = 0x0;
pdev->regdata[3] = 0x0;
pdev->regdata[4] = 0x0;
pdev->regdata[5] = 0x0;
pdev->regdata[6] = 0x0;
pdev->regdata[7] = 0x0;
pdev->regdata[8] = 0x0;
pdev->regdata[9] = 0x0;
pdev->regdata[10] =0x0;
pdev->regdata[11] =0x0;
reg_num = 12;
status = hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_get_video_status error\n");
return -1;
}
hRes = ((uint32_t)pdev->regdata[1] << 8) | pdev->regdata[0];
vRes = ( ( uint32_t ) pdev->regdata[3] << 8 ) | pdev->regdata[2];
dePix = ( ( uint32_t ) pdev->regdata[5] << 8 ) | pdev->regdata[4];
deLin = ( ( uint32_t ) pdev->regdata[7] << 8 ) | pdev->regdata[6];
xclkInPclk = ( ( uint32_t ) pdev->regdata[9] << 8 ) | pdev->regdata[8];
vidStat = pdev->regdata[10];
sysStat = pdev->regdata[11];
// sii9233_printf("hRes=0x%x, vRes=0x%x, dePix=0x%x, deLin=0x%x, xclkInPclk=0x%x, vidStat=0x%x, sysStat=0x%x\n", hRes, vRes, dePix, deLin, xclkInPclk, vidStat, sysStat);
if ( sysStat & DEVICE_SII9233A_VID_DETECT )
{
uint32_t t_line;
pdev->video_status.isVideoDetect = true;
if ( vidStat & DEVICE_SII9233A_VID_INTERLACE )
{
pdev->video_status.isInterlaced = true;
}
pdev->video_status.frameWidth = dePix;
pdev->video_status.frameHeight = deLin;
//time interval in usecs for each line
t_line = ( uint32_t ) ( ( ( uint32_t ) hRes * xclkInPclk * 1000 ) / ( DEVICE_SII9233A_FXTAL_KHZ * 2048 ) ); /* in usecs */
//time interval in usecs for each frame/field
pdev->video_status.frameInterval = t_line * vRes;
}
pdev->regaddr[0] = 0x6A;
pdev->regdata[0] = 0x01;
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_get_video_status 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_output_enable(SII9233_Dev_t *pdev, bool enable)
{
int status = 0;
int reg_num = 0;
pdev->regaddr[0] = 0x3E;
pdev->regdata[0] = 0xC3;
if ( enable )
pdev->regdata[0] |= ( 1 << 2 );
pdev->regaddr[1] = 0x3F;
pdev->regdata[1] = 0xAD;
if ( enable )
pdev->regdata[1] |= ( 1 << 6 );
reg_num = 2;
status = hi_i2c_write(*pdev, pdev->second_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_output_enable error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->second_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
return 0;
}
int sii9233_start(SII9233_Dev_t *pdev)
{
int status = 0;
status = sii9233_output_enable(pdev, true);
if(status < 0)
{
sii9233_printf("sii9233_stop error\n");
return -1;
}
return 0;
}
int sii9233_stop(SII9233_Dev_t *pdev)
{
// Device_sii9233aStop
// Device_sii9233aOutputEnable(pObj,false);
// i2c_write 0x1 0x6a 0x3e 0xc3 1 1
// i2c_write 0x1 0x6a 0x3f 0xad 1 1
int status = 0;
status = sii9233_output_enable(pdev, false);
if(status < 0)
{
sii9233_printf("sii9233_stop error\n");
return -1;
}
return 0;
}
int sii9233_powerdown(SII9233_Dev_t *pdev, bool powerdown)
{
int status = 0;
int reg_num = 0;
pdev->regaddr[0] = 0x08;
pdev->regdata[0] = 0;
reg_num = 1;
status = hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_powerdown error\n");
return -1;
}
if ( powerdown )
pdev->regdata[0] &= 0xfd; // power down
else
pdev->regdata[0] |= 0x01; // normal operation
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_powerdown 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_select_tmds_core(SII9233_Dev_t *pdev, uint32_t coreId)
{
// i2c_write 0x1 0x62 0x9 0x10 1 1
// i2c_write 0x1 0x62 0xa 0x8 1 1
// i2c_write 0x1 0x62 0x10 0x1 1 1
int status = 0;
int reg_num = 0;
// sii9233_printf("select_port = %d \n",coreId+1);
pdev->regaddr[0] = 0x09;
pdev->regaddr[1] = 0x0A;
pdev->regaddr[2] = 0x10;
pdev->regdata[0] =(0x01 << coreId) << 4; // DDC0_EN = 1
pdev->regdata[1] = 0x08 | coreId; // DDCDLY_EN = 1, HDMI_PORT0
pdev->regdata[2] = 0x01 << (2 * coreId); // HPD0 = 1
reg_num = 3;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_powerdown 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_port_switch(SII9233_Dev_t *pdev)
{
int status = 0;
int reg_num = 0;
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] == 1)
status = sii9233_select_tmds_core(pdev,0);
else if( (pdev->regdata[0] == 2) || (pdev->regdata[0] == 3))
status = sii9233_select_tmds_core(pdev,1);
else if( (pdev->regdata[0] == 4) || (pdev->regdata[0] == 5))
status = sii9233_select_tmds_core(pdev,2);
else if( (pdev->regdata[0] == 8)|| (pdev->regdata[0] == 9))
status = sii9233_select_tmds_core(pdev,3);
else
status = sii9233_select_tmds_core(pdev,1);
return 0;
}
int sii9233_reset(SII9233_Dev_t *pdev)
{
//Device_sii9233aStop
//Device_sii9233aPowerDown
int status = 0;
int reg_num = 0;
status = sii9233_stop(pdev); //disable outputs
if(status < 0)
{
sii9233_printf("sii9233_reset error\n");
return -1;
}
// i2c_read form i2c-1 devaddr:0x62 regaddr:0x8 value:0x5
// i2c_write 0x1 0x62 0x8 0x5 1 1
status = sii9233_powerdown(pdev, false); //Normal operation
if(status < 0)
{
sii9233_printf("sii9233_reset error\n");
return -1;
}
// i2c_write 0x1 0x62 0x5 0x2f 1 1
// i2c_write 0x1 0x62 0x7 0x9 1 1
pdev->regaddr[0] = 0x05;
pdev->regaddr[1] = 0x07;
pdev->regdata[0] = 0x2F; // reset AAC, HDCP, ACR, audio FIFO, SW
pdev->regdata[1] = 0x09; // reset HDCP
reg_num = 2;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_reset error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
usleep( 50000 ); //wait for reset to be effective
// i2c_write 0x1 0x62 0x5 0x10 1 1
//remove reset and setup in auto-reset mode
pdev->regaddr[0] = 0x05;
pdev->regdata[0] = 0x10; //auto-reset SW
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_reset error\n");
return -1;
}
#if SII9233_DEBUG
hi_i2c_read(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
#endif
//select TDMS core
sii9233_port_switch(pdev);
// i2c_write 0x1 0x62 0x2e 0xe0 1 1
pdev->regaddr[0] = 0x2E;
pdev->regdata[0] = 0xE0; //set HDCP
reg_num = 1;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_reset 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_detect_video(SII9233_Dev_t *pdev)
{
int status = 0;
usleep(100000);
status = sii9233_get_video_status(pdev);
if ( status < 0)
return status;
if( pdev->video_status.isVideoDetect != true )
{
printf("NO Video Detected, get video info failed !!!\n");
return -1;
}
status = sii9233_read_av_info(pdev);
if(status < 0)
{
sii9233_printf("sii9233_set_video_mode error\n");
return -1;
}
return 0;
}
int sii9233_read_av_info(SII9233_Dev_t *pdev)
{
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x40 value:0x82
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x41 value:0x2
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x42 value:0xd
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x43 value:0x23
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x44 value:0x2
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x45 value:0x28
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x46 value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x47 value:0x22
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x48 value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x49 value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x4a value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x4b value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x4c value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x4d value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x4e value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x4f value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x50 value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x51 value:0x0
// i2c_read form i2c-1 devaddr:0x6a regaddr:0x52 value:0x0
int status = 0;
int reg_num = 0;
uint8_t *aviData;
uint8_t aviAddr;
pdev->av_info.detected = false;
for ( aviAddr = DEVICE_SII9233A_REG_AVI_TYPE;
aviAddr <= DEVICE_SII9233A_REG_AVI_DBYTE15; aviAddr++ )
{
pdev->regaddr[reg_num] = aviAddr;
pdev->regdata[reg_num] = 0;
reg_num++;
}
status = hi_i2c_read(*pdev, pdev->second_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_port_switch error\n");
return -1;
}
if ( pdev->regdata[0] == DEVICE_SII9233A_AVI_INFO_PACKET_CODE
&& pdev->regdata[1] == DEVICE_SII9233A_AVI_INFO_VERSION_CODE
&& pdev->regdata[2] == DEVICE_SII9233A_AVI_INFO_PACKET_LENGTH )
{
pdev->av_info.detected = true; //Valid AVI packet recevied
aviData = &pdev->regdata[3]; // point to start of AVI data checksum
pdev->av_info.colorSpace = ( ( aviData[1] >> 5 ) & 0x3 ); //parse information
pdev->av_info.colorImetric = ( ( aviData[2] >> 6 ) & 0x3 );
pdev->av_info.pixelRepeat = ( ( aviData[5] >> 0 ) & 0xF );
// sii9233_printf("av_info : colorSpace=0x%x, colorImetric=0x%x, pixelRepeat=0x%x\n",pdev->av_info.colorSpace, pdev->av_info.colorImetric, pdev->av_info.pixelRepeat);
}
return 0;
}
/*
For SII9233A below parameters in Device_VideoDecoderVideoModeParams are ignored
and any value set by user for these parameters is not effective.
videoIfMode
standard
videoCaptureMode
videoSystem
Depending on video data format SII9233A is configured as below
videoDataFormat =
SYSTEM_DF_YUV422P : 16-bit YUV422 single CH embedded sync auto-detect mode
SYSTEM_DF_YUV444P : 24-bit YUV444 single CH discrete sync auto-detect mode
SYSTEM_DF_RGB24_888 : 24-bit RGB24 single CH discrete sync auto-detect mode
*/
int sii9233_setup_video(SII9233_Dev_t *pdev)
{
int status = 0;
int reg_num = 0;
uint32_t outColorSpace, inPixRep, isBT709, cscR2Y, cscY2R, upSmp, downSmp, chMap, insSavEav;
if(pdev->videoDataFormat == SYSTEM_DF_RGB24_888)
outColorSpace = DEVICE_SII9233A_COLOR_FORMAT_RGB;
else
outColorSpace = DEVICE_SII9233A_COLOR_FORMAT_YUV;
// Hard code AVI frame info
if (pdev->av_info.detected == false)
{
pdev->av_info.colorSpace = DEVICE_SII9233A_AVI_INFO_COLOR_RGB444;
pdev->av_info.colorImetric = DEVICE_SII9233A_AVI_INFO_CMETRIC_ITU709;
pdev->av_info.pixelRepeat = DEVICE_SII9233A_AVI_INFO_PIXREP_NONE;
if ( pdev->standard==SYSTEM_STD_480I
|| pdev->standard==SYSTEM_STD_576I
|| pdev->standard==SYSTEM_STD_D1
|| pdev->standard==SYSTEM_STD_NTSC
|| pdev->standard==SYSTEM_STD_PAL )
{
pdev->av_info.colorImetric = DEVICE_SII9233A_AVI_INFO_CMETRIC_ITU601;
pdev->av_info.pixelRepeat = DEVICE_SII9233A_AVI_INFO_PIXREP_2X;
}
}
inPixRep = pdev->av_info.pixelRepeat;
if ( inPixRep > DEVICE_SII9233A_AVI_INFO_PIXREP_4X )
{
inPixRep = 0;
status = -1;
}
isBT709 = 1;
if ( pdev->av_info.colorImetric == DEVICE_SII9233A_AVI_INFO_CMETRIC_ITU601 )
isBT709 = 0;
cscR2Y = 0;
upSmp = 0;
downSmp = 0;
cscY2R = 0;
insSavEav = 0;
switch ( pdev->av_info.colorSpace )
{
case DEVICE_SII9233A_AVI_INFO_COLOR_RGB444:
switch ( pdev->videoDataFormat )
{
case SYSTEM_DF_YUV422P:
cscR2Y = 1;
downSmp = 1;
insSavEav = 1;
break;
case SYSTEM_DF_YUV444P:
cscR2Y = 1;
break;
case SYSTEM_DF_RGB24_888:
break;
default:
status = -1;
break;
}
break;
case DEVICE_SII9233A_AVI_INFO_COLOR_YUV444:
switch ( pdev->videoDataFormat )
{
case SYSTEM_DF_YUV422P:
downSmp = 1;
insSavEav = 1;
break;
case SYSTEM_DF_YUV444P:
break;
case SYSTEM_DF_RGB24_888:
cscY2R = 1;
break;
default:
status = -1;
break;
}
break;
case DEVICE_SII9233A_AVI_INFO_COLOR_YUV422:
switch ( pdev->videoDataFormat )
{
case SYSTEM_DF_YUV422P:
insSavEav = 1;
break;
case SYSTEM_DF_YUV444P:
upSmp = 1;
break;
case SYSTEM_DF_RGB24_888:
upSmp = 1;
cscY2R = 1;
break;
default:
status = -1;
break;
}
break;
default:
status = -1;
break;
}
pdev->regaddr[0] = DEVICE_SII9233A_REG_VID_MODE_1;
pdev->regdata[0] = ( insSavEav << 7 ) /* 1: SAV2EAV enable , 0: disable */
| ( 0 << 6 ) /* 1: Mux Y/C , 0: No MUX */
| ( 1 << 5 ) /* 1: Dither enable , 0: disable */
| ( 1 << 4 ) /* 1: R2Y compress , 0: bypass */
| ( cscR2Y << 3 ) /* 1: Enable R2Y CSC , 0: bypass */
| ( upSmp << 2 ) /* 1: YUV422 to YUV444 , 0: bypass */
| ( downSmp << 1 ) /* 1: YUV444 to YUV422 , 0: bypass */
;
pdev->regaddr[1] = DEVICE_SII9233A_REG_VID_MODE_2;
pdev->regdata[1] = ( 0 << 6 ) /* 0: Dither to 8bits, 1: 10bits, 2: 12bits */
| ( 0 << 5 ) /* 0: EVNODD LOW if field 0 is even, 1: HIGH */
| ( 0 << 3 ) /* 1: Y2R compress , 0: bypass , modify by ltz 20161027, adjust color difference, last value is 1 */
| ( cscY2R << 2 ) /* 1: Y2R CSC , 0: bypass */
| ( outColorSpace << 1 ) /* 0: Output format RGB, 1: YUV */
| ( 0 << 0 ) /* 1: Range clip enable, 0: disable */
;
pdev->regaddr[2] = DEVICE_SII9233A_REG_VID_CTRL;
pdev->regdata[2] = ( 0 << 7 ) /* 0: Do not invert VSYNC, 1: invert */
| ( 0 << 6 ) /* 0: Do not invert HSYNC, 1: invert */
| ( isBT709 << 2 ) /* 0: Y2R BT601 , 1: BT709 */
| ( 0 << 1 ) /* 0: 8bits RGB or YUV , 1: YUV422 > 8 bits */
| ( isBT709 << 0 ) /* 0: R2Y BT601 , 1: BT709 */
;
pdev->regaddr[3] = DEVICE_SII9233A_REG_SYS_CTRL_1;
pdev->regdata[3] = ( inPixRep << 6 ) /* 0: Output pixel clock divided 1x, 1: 1/2x, 3: 1/4x */
| ( inPixRep << 4 ) /* 0: Input pixel replicate 1x, 1:2x, 3:4x */
| ( 1 << 2 ) /* 0: 12-bit mode , 1: 24-bit mode */
| ( 0 << 1 ) /* 0: Normal output clock , 1: Invert clock */
| ( 1 << 0 ) /* 0: Power down , 1: Normal operation */
;
/* this is device connected to VIP1 and is connected in
16-bit mode */
chMap = 0x00;
/* Q[23:16] Q[15:8] Q[7:0]
0: R G B
1: R B G
2: G R B
3: G B R
4: B R G
5: B G R
*/
pdev->regaddr[4] = DEVICE_SII9233A_REG_VID_CH_MAP;
pdev->regdata[4] = chMap;
reg_num = 5;
status = hi_i2c_write(*pdev, pdev->first_dev_addr, pdev->regaddr, pdev->regdata, reg_num);
if(status < 0)
{
sii9233_printf("sii9233_setup_video 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_video_mode(SII9233_Dev_t *pdev)
{
// Device_sii9233aReset
// Device_sii9233aDetectVideo
int status = 0;
status = sii9233_reset(pdev); //reset device
if(status < 0)
{
sii9233_printf("sii9233_set_video_mode error\n");
return -1;
}
status = sii9233_detect_video(pdev); //detect video source properties
if(status < 0)
{
sii9233_printf("sii9233_set_video_mode error\n");
return -1;
}
status = sii9233_setup_video(pdev); //setup video processing path based on detected source
if(status < 0)
{
sii9233_printf("sii9233_set_video_mode error\n");
return -1;
}
return 0;
}
int sii9233_api_init(SII9233_Dev_t *pdev)
{
int status = 0;
status = sii9233_para_init(pdev);
if(status < 0)
{
sii9233_printf("sii9233_para_init error\n");
return -1;
}
status = sii9233_open(pdev);
if(status < 0)
{
sii9233_printf("sii9233_open error\n");
return -1;
}
status = sii9233_set_slave_addr_reg(pdev);
if(status < 0)
{
sii9233_printf("sii9233_set_slave_addr_reg error\n");
return -1;
}
status = sii9233_set_factory_reg(pdev);
if(status < 0)
{
sii9233_printf("sii9233_set_factory_reg error\n");
return -1;
}
status = sii9233_init_edid_reg(pdev);
if(status < 0)
{
sii9233_printf("sii9233_init_edid_reg error\n");
return -1;
}
status = sii9233_get_chip_id(pdev);
if(0 == status)
{
sii9233_get_video_status(pdev);
if (pdev->video_status.isVideoDetect)
{
printf("Detected video (%dx%d@%dHz, Interlaced ? :%d) !!!\n",
pdev->video_status.frameWidth,
pdev->video_status.frameHeight,
pdev->video_status.frameInterval/1000,
pdev->video_status.isInterlaced);
/* Assumption here is height width of video remains same across channels */
if (pdev->video_status.frameHeight == 288)
pdev->isPalMode = true;
}
else
{
printf("sii9233_get_video_status error, NO Video Detected !!!\n");
return -1;
}
}
else {
printf("sii9233_get_chip_id error, sii9233 Device not found !!!\n");
return -1;
}
status = sii9233_set_video_mode(pdev);
if(status < 0)
{
sii9233_printf("sii9233_set_video_mode error\n");
return -1;
}
return 0;
}
int sii9233_api_deinit(SII9233_Dev_t *pdev)
{
return (sii9233_close(pdev));
}
int sii9233_api_start(SII9233_Dev_t *pdev)
{
return (sii9233_start(pdev));
}
int sii9233_api_stop(SII9233_Dev_t *pdev)
{
return(sii9233_stop(pdev));
}
#if SELF_TEST
int main()
{
int status = 0;
SII9233_Dev_t sii9233_dev;
status = sii9233_api_init(&sii9233_dev);
if(status < 0)
{
sii9233_printf("sii9233_api_init error\n");
return -1;
}
printf("init done!\n");
status = sii9233_api_start(&sii9233_dev);
if(status < 0)
{
sii9233_printf("sii9233_api_start error\n");
return -1;
}
printf("start done!\n");
// while(1);
sleep(20);
status = sii9233_api_stop(&sii9233_dev);
if(status < 0)
{
sii9233_printf("sii9233_api_stop error\n");
return -1;
}
printf("stop done!\n");
sleep(5);
status = sii9233_api_deinit(&sii9233_dev);
if(status < 0)
{
sii9233_printf("sii9233_api_deinit error\n");
return -1;
}
printf("deinit done!\n");
return 0;
}
#endif
sii9233a.h
#ifndef __SII_9233A_H__
#define __SII_9233A_H__
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
inline int sii9233_printf(const char *__format, ...){};
#define SII9233_DEBUG 1
#if SII9233_DEBUG
#define sii9233_printf printf
#else
#define sii9233_printf
#endif
#define I2C_SLAVE 0x0703 /* Use this slave address */
#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it is already in use by a driver! */
#define I2C_16BIT_REG 0x0709 /* 16BIT REG WIDTH */
#define I2C_16BIT_DATA 0x070a /* 16BIT DATA WIDTH */
/* PCLK stable, Clock detect, Sync Detect */
#define DEVICE_SII9233A_VID_DETECT ((1<<0) | (1<<1) | (1<<4))
/* Video interlace status */
#define DEVICE_SII9233A_VID_INTERLACE (1<<2)
/* color format */
#define DEVICE_SII9233A_COLOR_FORMAT_RGB (0)
#define DEVICE_SII9233A_COLOR_FORMAT_YUV (1)
/* F_xtal frequency in Khz */
#define DEVICE_SII9233A_FXTAL_KHZ (27000)
#define DEVICE_SII9233A_REG_AVI_TYPE (0x40)
#define DEVICE_SII9233A_REG_AVI_DBYTE15 (0x52)
/* AVI packet info values */
#define DEVICE_SII9233A_AVI_INFO_PACKET_CODE (0x82)
#define DEVICE_SII9233A_AVI_INFO_VERSION_CODE (0x02)
#define DEVICE_SII9233A_AVI_INFO_PACKET_LENGTH (0x0D)
/* color space */
#define DEVICE_SII9233A_AVI_INFO_COLOR_RGB444 (0)
#define DEVICE_SII9233A_AVI_INFO_COLOR_YUV422 (1)
#define DEVICE_SII9233A_AVI_INFO_COLOR_YUV444 (2)
/* color imetric */
#define DEVICE_SII9233A_AVI_INFO_CMETRIC_NO_DATA (0)
#define DEVICE_SII9233A_AVI_INFO_CMETRIC_ITU601 (1)
#define DEVICE_SII9233A_AVI_INFO_CMETRIC_ITU709 (2)
/* pixel repition */
#define DEVICE_SII9233A_AVI_INFO_PIXREP_NONE (0)
#define DEVICE_SII9233A_AVI_INFO_PIXREP_2X (1)
#define DEVICE_SII9233A_AVI_INFO_PIXREP_4X (3)
/* AVI packet info values */
#define DEVICE_SII9233A_AVI_INFO_PACKET_CODE (0x82)
#define DEVICE_SII9233A_AVI_INFO_VERSION_CODE (0x02)
#define DEVICE_SII9233A_AVI_INFO_PACKET_LENGTH (0x0D)
/* SII9233A Registers - I2C Port 0 */
#define DEVICE_SII9233A_REG_VND_IDL (0x00)
#define DEVICE_SII9233A_REG_VND_IDH (0x01)
#define DEVICE_SII9233A_REG_DEV_IDL (0x02)
#define DEVICE_SII9233A_REG_DEV_IDH (0x03)
#define DEVICE_SII9233A_REG_DEV_REV (0x04)
#define DEVICE_SII9233A_REG_SW_RST_0 (0x05)
#define DEVICE_SII9233A_REG_STATE (0x06)
#define DEVICE_SII9233A_REG_SW_RST_1 (0x07)
#define DEVICE_SII9233A_REG_SYS_CTRL_1 (0x08)
#define DEVICE_SII9233A_REG_SYS_SWTCHC (0x09)
#define DEVICE_SII9233A_REG_HP_CTRL (0x10)
#define DEVICE_SII9233A_REG_SLAVE_ADDRESS_4 (0x15)
#define DEVICE_SII9233A_REG_SLAVE_ADDRESS_2 (0x18)
#define DEVICE_SII9233A_REG_SLAVE_ADDRESS_3 (0x19)
#define DEVICE_SII9233A_REG_SYS_SWTCHC2 (0x0A)
#define DEVICE_SII9233A_REG_CHIP_SEL (0x0C)
#define DEVICE_SII9233A_REG_HDCP_BCAPS_SET (0x2E)
#define DEVICE_SII9233A_REG_H_RESL (0x3A)
#define DEVICE_SII9233A_REG_H_RESH (0x3B)
#define DEVICE_SII9233A_REG_V_RESL (0x3C)
#define DEVICE_SII9233A_REG_V_RESH (0x3D)
#define DEVICE_SII9233A_REG_VID_CTRL (0x48)
#define DEVICE_SII9233A_REG_VID_MODE_2 (0x49)
#define DEVICE_SII9233A_REG_VID_MODE_1 (0x4A)
#define DEVICE_SII9233A_REG_VID_BLANK1 (0x4B)
#define DEVICE_SII9233A_REG_VID_BLANK2 (0x4C)
#define DEVICE_SII9233A_REG_VID_BLANK3 (0x4D)
#define DEVICE_SII9233A_REG_DE_PIXL (0x4E)
#define DEVICE_SII9233A_REG_DE_PIXH (0x4F)
#define DEVICE_SII9233A_REG_DE_LINL (0x50)
#define DEVICE_SII9233A_REG_DE_LINH (0x51)
#define DEVICE_SII9233A_REG_VID_STAT (0x55)
#define DEVICE_SII9233A_REG_VID_CH_MAP (0x56)
#define DEVICE_SII9233A_REG_VID_AOF (0x5F)
#define DEVICE_SII9233A_REG_VID_XPM_EN (0x6A)
#define DEVICE_SII9233A_REG_VID_XPCNTL (0x6E)
#define DEVICE_SII9233A_REG_VID_XPCNTH (0x6F)
#define DEVICE_SII9233A_REG_AEC0_CTRL (0xB5)
#define DEVICE_SII9233A_REG_DS_BSTAT2 (0xD6)
typedef enum
{
SYSTEM_DF_YUV422I_UYVY = 0x0000,
/**< YUV 422 Interleaved format - UYVY. */
SYSTEM_DF_YUV422I_YUYV,
/**< YUV 422 Interleaved format - YUYV. */
SYSTEM_DF_YUV422I_YVYU,
/**< YUV 422 Interleaved format - YVYU. */
SYSTEM_DF_YUV422I_VYUY,
/**< YUV 422 Interleaved format - VYUY. */
SYSTEM_DF_YUV422SP_UV,
/**< YUV 422 Semi-Planar - Y separate, UV interleaved. */
SYSTEM_DF_YUV422SP_VU,
/**< YUV 422 Semi-Planar - Y separate, VU interleaved. */
SYSTEM_DF_YUV422P,
/**< YUV 422 Planar - Y, U and V separate. */
SYSTEM_DF_YUV420SP_UV,
/**< YUV 420 Semi-Planar - Y separate, UV interleaved. */
SYSTEM_DF_YUV420SP_VU,
/**< YUV 420 Semi-Planar - Y separate, VU interleaved. */
SYSTEM_DF_YUV420P,
/**< YUV 420 Planar - Y, U and V separate. */
SYSTEM_DF_YUV444P,
/**< YUV 444 Planar - Y, U and V separate. */
SYSTEM_DF_YUV444I,
/**< YUV 444 interleaved - YUVYUV... */
SYSTEM_DF_RGB16_565 = 0x1000,
/**< RGB565 16-bit - 5-bits R, 6-bits G, 5-bits B. */
SYSTEM_DF_ARGB16_1555,
/**< ARGB1555 16-bit - 5-bits R, 5-bits G, 5-bits B, 1-bit Alpha (MSB). */
SYSTEM_DF_RGBA16_5551,
/**< RGBA5551 16-bit - 5-bits R, 5-bits G, 5-bits B, 1-bit Alpha (LSB). */
SYSTEM_DF_ARGB16_4444,
/**< ARGB4444 16-bit - 4-bits R, 4-bits G, 4-bits B, 4-bit Alpha (MSB). */
SYSTEM_DF_RGBA16_4444,
/**< RGBA4444 16-bit - 4-bits R, 4-bits G, 4-bits B, 4-bit Alpha (LSB). */
SYSTEM_DF_ARGB24_6666,
/**< ARGB6666 24-bit - 6-bits R, 6-bits G, 6-bits B, 6-bit Alpha (MSB). */
SYSTEM_DF_RGBA24_6666,
/**< RGBA6666 24-bit - 6-bits R, 6-bits G, 6-bits B, 6-bit Alpha (LSB). */
SYSTEM_DF_RGB24_888,
/**< RGB24 24-bit - 8-bits R, 8-bits G, 8-bits B. */
SYSTEM_DF_ARGB32_8888,
/**< ARGB32 32-bit - 8-bits R, 8-bits G, 8-bits B, 8-bit Alpha (MSB). */
SYSTEM_DF_RGBA32_8888,
/**< RGBA32 32-bit - 8-bits R, 8-bits G, 8-bits B, 8-bit Alpha (LSB). */
SYSTEM_DF_BGR16_565,
/**< BGR565 16-bit - 5-bits B, 6-bits G, 5-bits R. */
SYSTEM_DF_ABGR16_1555,
/**< ABGR1555 16-bit - 5-bits B, 5-bits G, 5-bits R, 1-bit Alpha (MSB). */
SYSTEM_DF_ABGR16_4444,
/**< ABGR4444 16-bit - 4-bits B, 4-bits G, 4-bits R, 4-bit Alpha (MSB). */
SYSTEM_DF_BGRA16_5551,
/**< BGRA5551 16-bit - 5-bits B, 5-bits G, 5-bits R, 1-bit Alpha (LSB). */
SYSTEM_DF_BGRA16_4444,
/**< BGRA4444 16-bit - 4-bits B, 4-bits G, 4-bits R, 4-bit Alpha (LSB). */
SYSTEM_DF_ABGR24_6666,
/**< ABGR6666 24-bit - 6-bits B, 6-bits G, 6-bits R, 6-bit Alpha (MSB). */
SYSTEM_DF_BGR24_888,
/**< BGR888 24-bit - 8-bits B, 8-bits G, 8-bits R. */
SYSTEM_DF_ABGR32_8888,
/**< ABGR8888 32-bit - 8-bits B, 8-bits G, 8-bits R, 8-bit Alpha (MSB). */
SYSTEM_DF_BGRA24_6666,
/**< BGRA6666 24-bit - 6-bits B, 6-bits G, 6-bits R, 6-bit Alpha (LSB). */
SYSTEM_DF_BGRA32_8888,
/**< BGRA8888 32-bit - 8-bits B, 8-bits G, 8-bits R, 8-bit Alpha (LSB). */
SYSTEM_DF_BITMAP8 = 0x2000,
/**< BITMAP 8bpp. */
SYSTEM_DF_BITMAP4_LOWER,
/**< BITMAP 4bpp lower address in CLUT. */
SYSTEM_DF_BITMAP4_UPPER,
/**< BITMAP 4bpp upper address in CLUT. */
SYSTEM_DF_BITMAP2_OFFSET0,
/**< BITMAP 2bpp offset 0 in CLUT. */
SYSTEM_DF_BITMAP2_OFFSET1,
/**< BITMAP 2bpp offset 1 in CLUT. */
SYSTEM_DF_BITMAP2_OFFSET2,
/**< BITMAP 2bpp offset 2 in CLUT. */
SYSTEM_DF_BITMAP2_OFFSET3,
/**< BITMAP 2bpp offset 3 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET0,
/**< BITMAP 1bpp offset 0 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET1,
/**< BITMAP 1bpp offset 1 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET2,
/**< BITMAP 1bpp offset 2 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET3,
/**< BITMAP 1bpp offset 3 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET4,
/**< BITMAP 1bpp offset 4 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET5,
/**< BITMAP 1bpp offset 5 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET6,
/**< BITMAP 1bpp offset 6 in CLUT. */
SYSTEM_DF_BITMAP1_OFFSET7,
/**< BITMAP 1bpp offset 7 in CLUT. */
SYSTEM_DF_BITMAP8_BGRA32,
/**< BITMAP 8bpp BGRA32. */
SYSTEM_DF_BITMAP4_BGRA32_LOWER,
/**< BITMAP 4bpp BGRA32 lower address in CLUT. */
SYSTEM_DF_BITMAP4_BGRA32_UPPER,
/**< BITMAP 4bpp BGRA32 upper address in CLUT. */
SYSTEM_DF_BITMAP2_BGRA32_OFFSET0,
/**< BITMAP 2bpp BGRA32 offset 0 in CLUT. */
SYSTEM_DF_BITMAP2_BGRA32_OFFSET1,
/**< BITMAP 2bpp BGRA32 offset 1 in CLUT. */
SYSTEM_DF_BITMAP2_BGRA32_OFFSET2,
/**< BITMAP 2bpp BGRA32 offset 2 in CLUT. */
SYSTEM_DF_BITMAP2_BGRA32_OFFSET3,
/**< BITMAP 2bpp BGRA32 offset 3 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET0,
/**< BITMAP 1bpp BGRA32 offset 0 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET1,
/**< BITMAP 1bpp BGRA32 offset 1 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET2,
/**< BITMAP 1bpp BGRA32 offset 2 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET3,
/**< BITMAP 1bpp BGRA32 offset 3 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET4,
/**< BITMAP 1bpp BGRA32 offset 4 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET5,
/**< BITMAP 1bpp BGRA32 offset 5 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET6,
/**< BITMAP 1bpp BGRA32 offset 6 in CLUT. */
SYSTEM_DF_BITMAP1_BGRA32_OFFSET7,
/**< BITMAP 1bpp BGRA32 offset 7 in CLUT. */
SYSTEM_DF_BAYER_RAW = 0x3000,
/**< Bayer pattern. */
SYSTEM_DF_RAW_VBI,
/**< Raw VBI data. */
SYSTEM_DF_RAW,
/**< Raw data - Format not interpreted. */
SYSTEM_DF_MISC,
/**< For future purpose. */
SYSTEM_DF_INVALID
/**< Invalid data format. Could be used to initialize variables. */
}System_VideoDataFormat;
typedef enum
{
SYSTEM_STD_NTSC = 0u,
/**< 720x480 30FPS interlaced NTSC standard. */
SYSTEM_STD_PAL,
/**< 720x576 30FPS interlaced PAL standard. */
SYSTEM_STD_480I,
/**< 720x480 30FPS interlaced SD standard. */
SYSTEM_STD_576I,
/**< 720x576 30FPS interlaced SD standard. */
SYSTEM_STD_CIF,
/**< Interlaced, 360x120 per field NTSC, 360x144 per field PAL. */
SYSTEM_STD_HALF_D1,
/**< Interlaced, 360x240 per field NTSC, 360x288 per field PAL. */
SYSTEM_STD_D1,
/**< Interlaced, 720x240 per field NTSC, 720x288 per field PAL. */
SYSTEM_STD_480P,
/**< 720x480 60FPS progressive ED standard. */
SYSTEM_STD_480P_30,
/**< 720x480 30FPS progressive ED standard. */
SYSTEM_STD_576P,
/**< 720x576 50FPS progressive ED standard. */
SYSTEM_STD_576P_25,
/**< 720x576 25FPS progressive ED standard. */
SYSTEM_STD_720P_60,
/**< 1280x720 60FPS progressive HD standard. */
SYSTEM_STD_720P_50,
/**< 1280x720 50FPS progressive HD standard. */
SYSTEM_STD_720P_30,
/**< 1280x720 30FPS progressive HD standard. */
SYSTEM_STD_720P_25,
/**< 1280x720 25FPS progressive HD standard. */
SYSTEM_STD_720P_24,
/**< 1280x720 24FPS progressive HD standard. */
SYSTEM_STD_1080I_60,
/**< 1920x1080 30FPS interlaced HD standard. */
SYSTEM_STD_1080I_50,
/**< 1920x1080 25FPS interlaced HD standard. */
SYSTEM_STD_1080P_60,
/**< 1920x1080 60FPS progressive HD standard. */
SYSTEM_STD_1080P_50,
/**< 1920x1080 50FPS progressive HD standard. */
SYSTEM_STD_1080P_30,
/**< 1920x1080 30FPS progressive HD standard. */
SYSTEM_STD_1080P_25,
/**< 1920x1080 25FPS progressive HD standard. */
SYSTEM_STD_1080P_24,
/**< 1920x1080 24FPS progressive HD standard. */
/* Vesa standards from here Please add all SMTPE and CEA standard enums
above this only. this is to ensure proxy Oses compatibility
*/
SYSTEM_STD_VGA_60 = 0x100,
/**< 640x480 60FPS VESA standard. */
SYSTEM_STD_VGA_72,
/**< 640x480 72FPS VESA standard. */
SYSTEM_STD_VGA_75,
/**< 640x480 75FPS VESA standard. */
SYSTEM_STD_VGA_85,
/**< 640x480 85FPS VESA standard. */
SYSTEM_STD_WVGA_60,
/**< 800x480 60PFS WVGA */
SYSTEM_STD_SVGA_60,
/**< 800x600 60FPS VESA standard. */
SYSTEM_STD_SVGA_72,
/**< 800x600 72FPS VESA standard. */
SYSTEM_STD_SVGA_75,
/**< 800x600 75FPS VESA standard. */
SYSTEM_STD_SVGA_85,
/**< 800x600 85FPS VESA standard. */
SYSTEM_STD_WSVGA_70,
/**< 1024x600 70FPS standard. */
SYSTEM_STD_XGA_60,
/**< 1024x768 60FPS VESA standard. */
SYSTEM_STD_XGA_70,
/**< 1024x768 72FPS VESA standard. */
SYSTEM_STD_XGA_75,
/**< 1024x768 75FPS VESA standard. */
SYSTEM_STD_XGA_85,
/**< 1024x768 85FPS VESA standard. */
SYSTEM_STD_1368_768_60,
/**< 1368x768 60 PFS VESA>*/
SYSTEM_STD_1366_768_60,
/**< 1366x768 60 PFS VESA>*/
SYSTEM_STD_1360_768_60,
/**< 1360x768 60 PFS VESA>*/
SYSTEM_STD_WXGA_60,
/**< 1280x768 60FPS VESA standard. */
SYSTEM_STD_WXGA_75,
/**< 1280x768 75FPS VESA standard. */
SYSTEM_STD_WXGA_85,
/**< 1280x768 85FPS VESA standard. */
SYSTEM_STD_1440_900_60,
/**< 1440x900 60 PFS VESA>*/
SYSTEM_STD_SXGA_60,
/**< 1280x1024 60FPS VESA standard. */
SYSTEM_STD_SXGA_75,
/**< 1280x1024 75FPS VESA standard. */
SYSTEM_STD_SXGA_85,
/**< 1280x1024 85FPS VESA standard. */
SYSTEM_STD_WSXGAP_60,
/**< 1680x1050 60 PFS VESA>*/
SYSTEM_STD_SXGAP_60,
/**< 1400x1050 60FPS VESA standard. */
SYSTEM_STD_SXGAP_75,
/**< 1400x1050 75FPS VESA standard. */
SYSTEM_STD_UXGA_60,
/**< 1600x1200 60FPS VESA standard. */
SYSTEM_STD_WUXGA_60,
/**< 1920x1200 60FPS VESA standard. */
/* Multi channel standards from here Please add all VESA standards enums
above this only. this is to ensure proxy Oses compatibility */
SYSTEM_STD_MUX_2CH_D1 = 0x200,
/**< Interlaced, 2Ch D1, NTSC or PAL. */
SYSTEM_STD_MUX_2CH_HALF_D1,
/**< Interlaced, 2ch half D1, NTSC or PAL. */
SYSTEM_STD_MUX_2CH_CIF,
/**< Interlaced, 2ch CIF, NTSC or PAL. */
SYSTEM_STD_MUX_4CH_D1,
/**< Interlaced, 4Ch D1, NTSC or PAL. */
SYSTEM_STD_MUX_4CH_CIF,
/**< Interlaced, 4Ch CIF, NTSC or PAL. */
SYSTEM_STD_MUX_4CH_HALF_D1,
/**< Interlaced, 4Ch Half-D1, NTSC or PAL. */
SYSTEM_STD_MUX_8CH_CIF,
/**< Interlaced, 8Ch CIF, NTSC or PAL. */
SYSTEM_STD_MUX_8CH_HALF_D1,
/**< Interlaced, 8Ch Half-D1, NTSC or PAL. */
SYSTEM_STD_MUX_4CH_960H,
/**< Interlaced ,4Ch 960H , NTSC or PAL */
/* Auto detect and Custom standards Please add all multi channel standard
enums above this only. this is to ensure proxy Oses compatibility */
SYSTEM_STD_AUTO_DETECT = 0x300,
/**< Auto-detect standard. Used in capture mode. */
SYSTEM_STD_CUSTOM,
/**< Custom standard used when connecting to external LCD etc...
The video timing is provided by the application.
Used in display mode. */
SYSTEM_STD_INVALID = 0xFFFF
/**< Invalid standard used for initializations and error checks*/
} SYSTEM_Standard;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef struct SII9233_video_status{
uint32_t isVideoDetect;
uint32_t frameWidth;
uint32_t frameHeight;
uint32_t frameInterval;
uint32_t isInterlaced;
}SII9233_video_status_t;
typedef struct SII9233_chip_info{
uint32_t chipId;
uint32_t chipRevision;
uint32_t firmwareVersion;
}SII9233_chip_info_t;
typedef struct SII9233_av_info{
uint32_t colorSpace; /* RGB444 ot YUV422 or YUV422 */
uint32_t colorImetric; /* BT709 or BT601 */
uint32_t pixelRepeat; /* 1x, 2x, 4x */
uint32_t detected; /* detected or hard code*/
} SII9233_av_info_t;
typedef struct SII9233_Dev {
int i2c_dev_fd;
char i2c_dev_name[32];
uint8_t first_dev_addr; //0x62
uint8_t second_dev_addr; //0x6a
uint8_t xv_color_addr; //0x64
uint8_t edid_addr; //0xe0
uint8_t cec_addr; //0xc0
uint8_t regaddr[0x100];
uint8_t regdata[0x100];
SII9233_chip_info_t chip_info;
SII9233_video_status_t video_status;
SII9233_av_info_t av_info;
bool isPalMode;
System_VideoDataFormat videoDataFormat;
SYSTEM_Standard standard;
}SII9233_Dev_t;
int sii9233_api_init(SII9233_Dev_t *pdev);
int sii9233_api_deinit(SII9233_Dev_t *pdev);
int sii9233_api_start(SII9233_Dev_t *pdev);
int sii9233_api_stop(SII9233_Dev_t *pdev);
#endif