使用sil9233a芯片控制海思hi3531d的hdmi输入

前言

准备用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
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值