#include #include #include #include #include #include /* mux- */ #include /* -System V */ #include /* -XSI STREAMS */ #include #include #include #include #include /* ioctl - BSD and Linux */ #include "../inc/type.h" #include "../inc/i2c_drv.h" #include "../inc/sys_config.h" #include "../inc/delay.h" #include "../inc/ipara_cfg.h" #include "../inc/igpio.h" #include "../inc/isys_com.h" #include "../inc/tsoip.h" #define PRINT_TUNER_ERR 1 #if PRINT_TUNER_ERR #define PR_ERR(...) printf(__VA_ARGS__) #else #define PR_ERR(...) #endif #define FORCE_WR_SEGMENT (1) #define USE_I2C_HW 1 #define USE_I2C_HW_DIRECT_WR 0 //---------------------------------------- #define __un_used_stm32_i2c__ 1 #define __un_used_stm32_e2p__ 1 //---------------------------------------- extern volatile uint8 dpd_wr_cksum; extern volatile uint8 dpd_rd_cksum; extern uint8 dpd_data; extern volatile uint32 dbg_wr_checksum; //STM平台,底层处理逻辑和6911的不同,发送器件地址时,6911的API函数将地址左移了一位,而STM的没有,所以需要将6911平台定义的地址手动左移一位 //#define EXT_I2C_NUM 0 /*#define FPGA_I2C_NUM 1 #define E2_PROM_I2C_NUM 2 #define TUNER_I2C_NUM 3 #define DRYLOOP_I2C_NUM 4 #define E2_PROM_DEV1_ADDRESS (0X50<<1) //E2rom的器件地址 #define E2_PROM_DEV2_ADDRESS (0X53<<1) //片2E2器件地址 #define E2_PROM_DEV3_ADDRESS (0X57<<1) //片3E2器件地址 #define FPGA_DEV_ADDRESS (0X5A<<1) #define DRYLOOP_DEV_ADDRESS (0x42<<1) */ #define I2C_SDA_H(num) do{set_gpio_io_direct(t_i2c_gp[num].sda_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].sda_gp_num,1);}while(0) #define I2C_SDA_L(num) do{set_gpio_io_direct(t_i2c_gp[num].sda_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].sda_gp_num,0);}while(0) #define I2C_SCL_H(num) do{set_gpio_io_direct(t_i2c_gp[num].scl_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].scl_gp_num,1);}while(0) #define I2C_SCL_L(num) do{set_gpio_io_direct(t_i2c_gp[num].scl_gp_num,E_IO_OUT); set_gpio_value(t_i2c_gp[num].scl_gp_num,0);}while(0) //#define TS2IP_DEV_ADDRESS (0x70<<1) //#define FPGA2_DEV_ADDRESS (0x25<<1) static int fd_i2c_fpga = -1; static int fd_i2c_tsoip = -1; static int fd_i2c_tsoip2 = -1; int fd_i2c_tuner = -1; static volatile uint32 fpga1_segment_bak = (uint32)-1; pthread_mutex_t mux_i2c_fpga; pthread_mutex_t mux_i2c_tsoip; pthread_mutex_t mux_i2c_tuner; pthread_mutex_t mux_e_cfg; pthread_mutex_t mux_dpd_wr_ck; #if !USE_I2C_HW static void i2c_cfg_para_init(void); #endif void e_map_init(void) { pthread_mutex_init(&mux_e_cfg, NULL); } void e2_byte_write(uint16 addr,uint8 data,uint32 chip) { int ret; uint8 rdata; rdata = e2_byte_read(addr, chip&E2_TOTAL_NUM); if(rdata != data){ pthread_mutex_lock(&mux_e_cfg); ret = set_para_to_e_map(addr,data,chip&E2_TOTAL_NUM); pthread_mutex_unlock(&mux_e_cfg); } } uint8 e2_byte_read(uint16 addr,uint32 chip) { uint8 data = 0xff; pthread_mutex_lock(&mux_e_cfg); data = get_para_from_e_map(addr, chip&E2_TOTAL_NUM); pthread_mutex_unlock(&mux_e_cfg); return data; } uint8 e2_byte_read_v2(uint16 addr, uint8 default_value,uint32 chip) { uint8 data = 0xff; pthread_mutex_lock(&mux_e_cfg); data = get_para_from_e_map_v2(addr, default_value, chip&E2_TOTAL_NUM); pthread_mutex_unlock(&mux_e_cfg); return data; } static uint32 e2_read_buf(uint8* pbuf, uint16 offset, uint16 num,uint32 chip) { return I2C_READ_OK; } static uint32 e2_write_page(uint8* pbuf, uint16 offset, uint16 num,uint32 chip) { } static uint32 e2_write_buf(uint8* pbuf, uint16 offset, uint16 write_num,uint32 chip) { return I2C_WRITE_OK; } #if USE_I2C_HW #include #include #include #include #include #include #include #include #include #include "../inc/dpd_proc.h" #define I2C_WRITE_DATA 0 #define I2C_READ_DATA 1 struct i2cMsg { unsigned short addr; unsigned short flags; unsigned short len; unsigned char *buf; }; struct i2c_ioctl_data { struct i2cMsg *msgs; int nmsgs; }; static int i2c_hw_write(int fd,unsigned short devaddr,unsigned char *buf,unsigned short buflen) { struct i2cMsg msg[2]; struct i2c_ioctl_data date; int ret = 0; if(buf == NULL) return -1; msg[0].len = buflen;//buf len msg[0].flags = I2C_WRITE_DATA;//0write 1read msg[0].addr = devaddr; msg[0].buf = buf; date.nmsgs = 1; date.msgs = (struct i2cMsg *)&msg; ret = ioctl(fd, I2C_RDWR, (unsigned long)&date); if(ret < 0){ //usr_sec_printf(" [write-ioctrl-i2c] failed,ret = %d\r\n", ret); } return ret; } static int i2c_hw_read(int fd,unsigned short devaddr,unsigned char *buf,unsigned short buflen,unsigned char *retbuf,unsigned short retbuflen) { struct i2cMsg msg[2]; struct i2c_ioctl_data date; int ret = 0; if(buf == NULL) return -1; msg[0].len = buflen;//buf len msg[0].flags = I2C_WRITE_DATA;//0write 1read msg[0].addr = devaddr;//dev addr msg[0].buf = buf; msg[1].len = retbuflen;//buf len msg[1].flags = I2C_READ_DATA;//0write 1read msg[1].addr = devaddr;//dev addr msg[1].buf = retbuf; date.nmsgs = 2; date.msgs = (struct i2cMsg *)&msg; ret = ioctl(fd, I2C_RDWR, (unsigned long)&date); if(ret < 0){ usr_sec_printf(" [read-ioctrl-i2c] failed,ret = %d\r\n", ret); } //@tmp //printf("r fd=%d addr=0x%x buflen=%d\n",fd, buf[0], buflen); return ret; } static int i2c_hw_read2(int fd,unsigned short addr,unsigned char *retbuf,unsigned short retbuflen) { struct i2cMsg msg[1]; struct i2c_ioctl_data date; int ret = 0; if(retbuf == NULL) return -1; msg[0].len = retbuflen;//buf len msg[0].flags = I2C_READ_DATA;//0write 1read msg[0].addr = addr;//dev addr msg[0].buf = retbuf; date.nmsgs = 1; date.msgs = (struct i2cMsg *)&msg; ret = ioctl(fd, I2C_RDWR, (unsigned long)&date); if(ret < 0){ //usr_sec_printf(" [read2-ioctrl-i2c] failed,ret = %d\r\n", ret); } //@tmp //printf("r fd=%d addr=0x%x buflen=%d\n",fd, buf[0], buflen); return ret; } //FPGA_I2C_NUM static void i2c_hw_mode_init() { char buf[20]; //FPGA_I2C_NUM memset(buf,0,sizeof(buf)); sprintf(buf,"/dev/i2c-%d",FPGA_I2C_NUM); fd_i2c_fpga = open(buf, O_RDWR); if(fd_i2c_fpga < 0){ log_printf(LOG_ERR, I_NOUSED, "i2c-%d fd(fpga) open failed.\n",FPGA_I2C_NUM); fd_i2c_fpga = -1; return; } else{ ioctl(fd_i2c_fpga,I2C_TIMEOUT,1);/*超时时间*/ ioctl(fd_i2c_fpga,I2C_RETRIES,3);/*重复次数*/ //printf(">>i2c-%d fd(fpga) open ok\n",FPGA_I2C_NUM); } //EXT_I2C_NUM /*memset(buf,0,sizeof(buf)); sprintf(buf,"/dev/i2c-%d",EXT_I2C_NUM); fd_i2c_tsoip = open(buf, O_RDWR); if(fd_i2c_tsoip < 0){ log_printf(LOG_ERR, I_NOUSED, "i2c-%d fd(tsoip) open failed.\n", EXT_I2C_NUM); fd_i2c_tsoip = -1; } else{ ioctl(fd_i2c_tsoip,I2C_TIMEOUT,1);//超时时间 ioctl(fd_i2c_tsoip,I2C_RETRIES,2);//重复次数 //printf(">>i2c-%d fd(tsoip) open ok\n",EXT_I2C_NUM); }*/ //tuner memset(buf,0,sizeof(buf)); sprintf(buf,"/dev/i2c-%d",TUNER_I2C_NUM); fd_i2c_tuner = open(buf, O_RDWR); if(fd_i2c_tuner < 0){ log_printf(LOG_ERR, I_NOUSED, "i2c-%d fd(tuner) open failed.\n", TUNER_I2C_NUM); fd_i2c_tuner = -1; } else{ ioctl(fd_i2c_tuner,I2C_TIMEOUT,1);/*超时时间*/ ioctl(fd_i2c_tuner,I2C_RETRIES,2);/*重复次数*/ //printf(">>i2c-%d fd(tuner) open ok\n",TUNER_I2C_NUM); } } #if 0 static void i2c_tuner_hw_mode_init(void) { char buf[20]; memset(buf,0,sizeof(buf)); sprintf(buf,"/dev/i2c-%d", TUNER_I2C_NUM); fd_i2c_tuner = open(buf, O_RDWR); if(fd_i2c_tuner < 0){ log_printf(LOG_ERR, I_NOUSED, "Err. i2c-%d fd open failed.\r\n", TUNER_I2C_NUM); fd_i2c_tuner = -1; return; } else{ ioctl(fd_i2c_tuner,I2C_TIMEOUT,1);/*超时时间*/ ioctl(fd_i2c_tuner,I2C_RETRIES,3);/*重复次数*/ } } #endif #endif//USE_I2C_HW #if !USE_I2C_HW static void i2c_soft_mode_init() { i2c_cfg_para_init(); i2c_gpio_init(); } #endif #if !USE_I2C_HW //I2C_SOFT_GPIO #define I2C_Direction_Transmitter ((uint8_t)0x00) #define I2C_Direction_Receiver ((uint8_t)0x01) #define I2C_SOFT_DELAY_TIME 1 //100k 单周期12us,80k #define I2C_SOFT_EXTRA_DELAY 280 //ip2ts模块等待时间 #define DLY_TEST() ; typedef struct { uint16 sda_gp_num; uint16 scl_gp_num; }S_I2C_GPIO_N; static uint32 g_byte_cnt=0; S_I2C_GPIO_N t_i2c_gp[2]={0}; static void i2c_cfg_para_init(void) { t_i2c_gp[0].sda_gp_num = I2C1_SDA_GP_NUM; t_i2c_gp[0].scl_gp_num = I2C1_SCL_GP_NUM; t_i2c_gp[1].sda_gp_num = I2C2_SDA_GP_NUM; t_i2c_gp[1].scl_gp_num = I2C2_SCL_GP_NUM;// R350 } uint8 I2C_SDA_READ(uint8 num){ int ret; uint8 u8val; set_gpio_io_direct(t_i2c_gp[num].sda_gp_num,E_IO_IN); ret = get_gpio_value(t_i2c_gp[num].sda_gp_num, &u8val); //printf("sda read=%d\n",u8val); return u8val; } uint8 I2C_SCL_READ(uint8 num){ int ret; uint8 u8val; set_gpio_io_direct(t_i2c_gp[num].scl_gp_num,E_IO_IN); ret = get_gpio_value(t_i2c_gp[num].scl_gp_num, &u8val); return u8val; } //100K static void i2c_soft_delay(uint32 nus) { delay_us(I2C_SOFT_DELAY_TIME*nus); } static void i2c_soft_delay_ext(uint32 nus) { delay_us(I2C_SOFT_EXTRA_DELAY*nus); } static uint32 i2c_soft_start(uint32 i2c_num) { BOOL tmp; I2C_SDA_H(i2c_num); I2C_SCL_H(i2c_num); i2c_soft_delay(1); //tmp = I2C_SDA_READ(i2c_num); //printf("1.tmp=%d\n",tmp); /*if(!tmp) { //printf("2.tmp=%d\n",tmp); return 1; }*/ I2C_SDA_L(i2c_num); i2c_soft_delay(1); /*tmp = I2C_SDA_READ(i2c_num); if(tmp) { //printf("3.tmp=%d\n------------\n\n",tmp); return 2; }*/ I2C_SCL_L(i2c_num);//I2C_SDA_L i2c_soft_delay(1); //printf("i2c start ok.\n"); return 0; } static void i2c_soft_stop(uint32 i2c_num) { I2C_SCL_L(i2c_num); i2c_soft_delay(1); I2C_SDA_L(i2c_num); i2c_soft_delay(1); I2C_SCL_H(i2c_num); i2c_soft_delay(1); I2C_SDA_H(i2c_num); i2c_soft_delay(1); } static void i2c_soft_ack(uint32 i2c_num) { I2C_SCL_L(i2c_num); i2c_soft_delay(1); I2C_SDA_L(i2c_num); i2c_soft_delay(1); I2C_SCL_H(i2c_num); i2c_soft_delay(1); I2C_SCL_L(i2c_num); i2c_soft_delay(1); //add I2C_SDA_H(i2c_num); } //读取时,最后一字节不需要ACK static void i2c_no_ack(uint32 i2c_num) { I2C_SCL_L(i2c_num); i2c_soft_delay(1); I2C_SDA_H(i2c_num); i2c_soft_delay(1); I2C_SCL_H(i2c_num); i2c_soft_delay(1); I2C_SCL_L(i2c_num); i2c_soft_delay(1); } //true:等待到ACK false:无 ack static BOOL i2c_wait_ack(uint32 i2c_num) { BOOL tmp; I2C_SCL_L(i2c_num); i2c_soft_delay(1); I2C_SDA_H(i2c_num); i2c_soft_delay(1); I2C_SCL_H(i2c_num); i2c_soft_delay(1); tmp = I2C_SDA_READ(i2c_num); if(tmp) { I2C_SCL_L(i2c_num); return FALSE; } I2C_SCL_L(i2c_num); return TRUE; } //MSB static void i2c_soft_send_byte(uint32 i2c_num,uint8 data) { uint32 i=8; while(i--) { I2C_SCL_L(i2c_num); i2c_soft_delay(1); if(data&0x80) { I2C_SDA_H(i2c_num); } else { I2C_SDA_L(i2c_num); } data<<=1; i2c_soft_delay(1); I2C_SCL_H(i2c_num); i2c_soft_delay(2); } I2C_SCL_L(i2c_num); //printf("byte send.\n"); } static uint8 i2c_soft_read_byte(uint32 i2c_num) { BOOL tmp; uint32 i=8; uint8 data=0; I2C_SDA_H(i2c_num); while(i--) { data<<=1; I2C_SCL_L(i2c_num); i2c_soft_delay(2); I2C_SCL_H(i2c_num); i2c_soft_delay(1); tmp = I2C_SDA_READ(i2c_num); if(tmp) { data|=0x01; } i2c_soft_delay(1); } I2C_SCL_L(i2c_num); return data; } //读取偏移地址为单字节的I2C底层函数,不考虑页 static uint32 i2c1_read_offset8(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c) { uint16 read_cnt = num; uint32 time_in,time_out; if((num==0)||(pbuf==NULL)) return I2C_PARA_INVALID; if(i2c>=I2C_MAX_NUM) return I2C_PARA_INVALID; if(i2c_soft_start(i2c)) { log_printf(LOG_ERR,I_NOUSED,"i2c start for r failed.\n==============\n"); return 1; } // time_in = usr_get_cur_time_ms(); i2c_soft_send_byte(i2c, dev|I2C_Direction_Transmitter); // time_out = usr_get_cur_time_ms(); // printf(" time_byte1:%d\n",time_out-time_in); // time_in = usr_get_cur_time_ms(); if(!i2c_wait_ack(i2c)) { i2c_soft_stop(i2c); return 2; } DLY_TEST(); // time_out = usr_get_cur_time_ms(); // printf(" time_wait1:%d\n",time_out-time_in); i2c_soft_send_byte(i2c,offset); i2c_wait_ack(i2c); if(i2c_soft_start(i2c)) { return 3; } DLY_TEST(); // time_in = usr_get_cur_time_ms(); i2c_soft_send_byte(i2c, dev|I2C_Direction_Receiver); // time_out = usr_get_cur_time_ms(); // printf(" time_byte2:%d\n",time_out-time_in); // time_in = usr_get_cur_time_ms(); if(!i2c_wait_ack(i2c)) { i2c_soft_stop(i2c); return 3; } DLY_TEST(); // time_out = usr_get_cur_time_ms(); // printf(" time_wait2:%d\n",time_out-time_in); while(read_cnt--) { // time_in = usr_get_cur_time_ms(); *pbuf++ = i2c_soft_read_byte(i2c); DLY_TEST(); // time_out = usr_get_cur_time_ms(); // printf(" time_byte3:%d\n",time_out-time_in); if(read_cnt==0) { i2c_no_ack(i2c); i2c_soft_stop(i2c); } else { i2c_soft_ack(i2c); } } return I2C_READ_OK; } //参数偏移地址为1字节的i2c写函数 static uint32 i2c1_write_offset8(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c) { uint16 read_cnt = num; if((num==0)||(pbuf==NULL)) return I2C_PARA_INVALID; i2c_soft_start(i2c); i2c_soft_send_byte(i2c, dev|I2C_Direction_Transmitter); //写器件地址 if(!i2c_wait_ack(i2c)) { i2c_soft_stop(i2c); return 2; } DLY_TEST(); i2c_soft_send_byte(i2c,offset); i2c_wait_ack(i2c); DLY_TEST(); while(read_cnt--) { i2c_soft_send_byte(i2c,*pbuf++); i2c_wait_ack(i2c); DLY_TEST(); if(read_cnt==0) { i2c_soft_stop(i2c); } } return I2C_READ_OK; } //IP2TS读写专用函数,读写时,速度比较慢,需要加较长的延时,否则读写会出现异常 static uint32 i2c1_read_offset8_ip2ts(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c) { } //参数偏移地址为1字节的i2c写函数 static uint32 i2c1_write_offset8_ip2ts(uint8* pbuf,uint8 offset,uint32 num,uint8 dev,uint8 i2c) { } void test_i2c_io_time() { int i; uint32 time_in; uint32 time_out; time_in = usr_get_cur_time_ms(); for(i=0;i<50;i++){ I2C_SDA_H(FPGA_I2C_NUM); I2C_SDA_L(FPGA_I2C_NUM); //I2C_SCL_H(FPGA_I2C_NUM); //I2C_SCL_L(FPGA_I2C_NUM); } time_out = usr_get_cur_time_ms(); log_printf(LOG_DEBUG,I_NOUSED," time_read:%d [cnt=%d]\n",time_out-time_in,g_byte_cnt); } #endif #if 1 #include #include #include #include #include #include #include #define I2C_RETRIES 0x0701 #define I2C_TIMEOUT 0x0702 #define I2C_SLAVE 0x0703 //IIC从器件的地址设置 //#define I2C_BUS_MODE 0x0780 static int i2c_cdev_init(void); static int i2c_cdev_write(int fd, uint8 reg, uint8 *pval,uint8 wlen); static int i2c_cdev_read(int fd, uint8 reg, uint8 *pval,uint8 rlen); static int i2c_cdev_init(void) { char buf[20]; //FPGA_I2C_NUM memset(buf,0,sizeof(buf)); sprintf(buf,"/dev/i2c-%d",FPGA_I2C_NUM); fd_i2c_fpga = open(buf, O_RDWR); if(fd_i2c_fpga < 0){ log_printf(LOG_ERR,I_NOUSED," i2c-%d fd open failed.\r\n",FPGA_I2C_NUM); fd_i2c_fpga = -1; return -1; } else{ ioctl(fd_i2c_fpga,I2C_TIMEOUT,1);/*超时时间*/ ioctl(fd_i2c_fpga,I2C_RETRIES,0);/*重复次数*/ if(ioctl(fd_i2c_fpga, I2C_SLAVE, FPGA_DEV_ADDRESS>>1)<0) { //设置iic从器件地址 printf("fail to set fpga i2c device slave address!\n"); return -1; } } return 0; } static int i2c_cdev_write(int fd, uint8 reg, uint8 *pval,uint8 wlen) { uint8 dbuf[50];//temp use 50 if((wlen+1) > 50) return -1; memset(dbuf, 0, sizeof(dbuf)); dbuf[0] = reg; memcpy(&dbuf[1], pval, wlen+1); if(write(fd, dbuf, wlen+1) == (wlen+1)) return 0; return -1; } static int i2c_cdev_read(int fd, uint8 reg, uint8 *pval,uint8 rlen) { int ret; uint8 reg_addr; reg_addr = reg; ret = write(fd, ®_addr, 1); /*if(ret!=-1) printf("write addr ok.\n");*/ ret = read(fd, pval, rlen); if(ret==1){ return 0; //printf("read data ok.\n"); } return -1; } //extern S_CTTB_PARA cttb_para; //#include "../inc/dpd_proc.h" uint8 fpga_byte_reads(uint8 segment,uint32 addr,uint8 *pdata,uint8 rlen) { uint8 data=0xff; #if !DBG_DISABLE_I2C int ret; uint8 buf[5]; uint8 retbuf[5]; uint32 time_in; uint32 time_out; pthread_mutex_lock(&mux_i2c_fpga); if(fpga1_segment_bak != segment) { #if USE_I2C_HW memset(buf,0,sizeof(buf)); buf[0] = 0x00;//reg ==> 0x00 buf[1] = segment;//seg ==> 0x01 ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2); if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"Err.fpga set msg segment ret err.\n"); } #elif USE_I2C_HW_DIRECT_WR ret = i2c_cdev_write(fd_i2c_fpga, 0x00, &segment, 1); if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"fpga set cdev segment ret err.\n"); } #else ret = i2c1_write_offset8(&segment, 0, 1, FPGA_DEV_ADDRESS, FPGA_I2C_NUM); if(ret!=0){ log_printf(LOG_ERR,I_NOUSED,"fpga set soft segment ret err.\n"); } #endif fpga1_segment_bak = segment; } #if USE_I2C_HW memset(buf,0,sizeof(buf)); memset(retbuf,0,sizeof(retbuf)); buf[0] = addr;//reg addr ==> 0x12 ret = i2c_hw_read(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 1, pdata, rlen); data= retbuf[0]; if(ret<0){ log_printf(LOG_ERR, I_NOUSED, "Err.fpga read msg byte errnum=%d.\n",ret); data =0xff; } #elif USE_I2C_HW_DIRECT_WR memset(buf,0,sizeof(buf)); memset(retbuf,0,sizeof(retbuf)); buf[0] = addr;//reg addr ==> 0x12 ret = i2c_cdev_read(fd_i2c_fpga, addr, pdata, rlen); //printf("%d\n",*pdata[0]); data= retbuf[0]; #else ret = i2c1_read_offset8(&data,addr,1,FPGA_DEV_ADDRESS, FPGA_I2C_NUM); if(ret!=0){ log_printf(LOG_ERR,I_NOUSED,"Err.fpga read soft byte errnum=%d.\n",ret); data =0xff; } #endif pthread_mutex_unlock(&mux_i2c_fpga); #endif return data; } int fpga_byte_writes(uint8 segment,uint32 addr,uint8 *pdata,uint8 wlen) { int ret=0; uint8 buf[5]; #if !DBG_DISABLE_I2C //printf("fpga write[addr=0x%x,data=0x%x]\n",addr,data); pthread_mutex_lock(&mux_i2c_fpga); if(fpga1_segment_bak != segment) { #if USE_I2C_HW memset(buf,0,sizeof(buf)); buf[0] = 0x00;//reg ==> 0x00 buf[1] = segment;//seg ==> 0x01 ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2); if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"Err.fpga set segment ret err.\n"); } #elif USE_I2C_HW_DIRECT_WR ret = i2c_cdev_write(fd_i2c_fpga, 0x00, &segment, 1); if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"fpga set cdev segment ret err.\n"); } #else ret = i2c1_write_offset8(&segment, 0, 1, FPGA_DEV_ADDRESS, FPGA_I2C_NUM); if(ret!=0){ log_printf(LOG_DEBUG,I_NOUSED,"fpga set segment ret err.\n"); } #endif fpga1_segment_bak = segment; } #if USE_I2C_HW uint8 dbuf[50]; memset(dbuf, 0,sizeof(dbuf)); dbuf[0] = addr; if(wlen<50) memcpy(&dbuf[1],pdata,wlen); else{ ret = -1; log_printf(LOG_ERR,I_NOUSED,"fpga write byte errnum=%d.\n",ret); pthread_mutex_unlock(&mux_i2c_fpga); return ret; } ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, &dbuf[0], wlen); if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"fpga write byte errnum=%d.\n",ret); } #elif USE_I2C_HW_DIRECT_WR ret = i2c_cdev_write(fd_i2c_fpga, addr, pdata, wlen); if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"fpga set cdev data ret err.\n"); } #else i2c1_write_offset8(pdata, addr, 1, FPGA_DEV_ADDRESS,FPGA_I2C_NUM); if(ret!=0){ log_printf(LOG_ERR,I_NOUSED,"pga write byte errnum=%d.\n",ret); } #endif pthread_mutex_unlock(&mux_i2c_fpga); #endif } uint8 fpga_byte_read(uint8 segment,uint32 addr) { uint8 data=0xff; int ret; #if !DBG_DISABLE_I2C uint8 buf[5]; uint8 retbuf[5]; uint32 time_in; uint32 time_out; pthread_mutex_lock(&mux_i2c_fpga); if(fpga1_segment_bak != segment || FORCE_WR_SEGMENT) { memset(buf,0,sizeof(buf)); buf[0] = 0x00; //reg ==> 0x00 buf[1] = segment; //seg ==> 0x01 ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2); if(ret < 0){ log_printf(LOG_ERR,I_NOUSED,"fpga set msg segment ret err.\n"); } fpga1_segment_bak = segment; } memset(buf,0,sizeof(buf)); memset(retbuf,0,sizeof(retbuf)); buf[0] = addr;//reg addr ==> 0x12 ret = i2c_hw_read(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 1, retbuf, 1); data= retbuf[0]; if(ret<0){ log_printf(LOG_ERR,I_NOUSED,"fpga read msg byte errnum=%d.\n",ret); data =0xff; } pthread_mutex_unlock(&mux_i2c_fpga); #endif//DBG_DISABLE_I2C #if DBG_I2C_ERR_DELAY if(ret<0)sleep(1); #endif return data; } extern volatile uint32 usr_sys_ready; void fpga_byte_write(uint8 segment,uint32 addr,uint8 data) { #if !DBG_DISABLE_I2C int ret=0; uint8 buf[5]; pthread_mutex_lock(&mux_i2c_fpga); if(fpga1_segment_bak != segment || FORCE_WR_SEGMENT) { memset(buf,0,sizeof(buf)); buf[0] = 0x00;//reg ==> 0x00 buf[1] = segment;//seg ==> 0x01 ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2); if(ret<0){ log_printf(LOG_ERR, I_NOUSED, "fpga set segment ret err.\n"); } fpga1_segment_bak = segment; } memset(buf,0,sizeof(buf)); buf[0] = (uint8)addr; //reg ==> 0x12 buf[1] = data; //data ==> 0x25 ret = i2c_hw_write(fd_i2c_fpga, FPGA_DEV_ADDRESS>>1, buf, 2); if(ret < 0){ log_printf(LOG_ERR, I_NOUSED, "fpga write byte errnum=%d.\n", ret); } pthread_mutex_unlock(&mux_i2c_fpga); #if DBG_I2C_ERR_DELAY if(ret<0)sleep(1); #endif #endif//DBG_DISABLE_I2C } void tsoip_byte_write(int tsoip_index, uint32 addr, uint8 data) { #if !DBG_DISABLE_I2C int ret = 0; uint8 buf[5] = {0}; tsoip_index = tsoip_index & 0x1; pthread_mutex_lock(&mux_i2c_fpga); memset(buf, 0, sizeof(buf)); buf[0] = (uint8)addr; buf[1] = data; ret = i2c_hw_write(fd_i2c_fpga, (tsoip_index==TSOIP_1)?(TS2IP_DEV_ADDRESS>>1):(TS2IP2_DEV_ADDRESS>>1), buf, 2); if(ret < 0) { log_printf(LOG_ERR,I_NOUSED,"fpga write [tsoip] byte errnum=%d\n", ret); } pthread_mutex_unlock(&mux_i2c_fpga); #if DBG_I2C_ERR_DELAY if(ret<0)sleep(1); #endif #endif } uint8 tsoip_byte_read(int tsoip_index,uint32 addr) { uint8 data = 0xff; #if !DBG_DISABLE_I2C int ret; uint8 buf[5]; uint8 retbuf[5]; uint32 time_in; uint32 time_out; tsoip_index = tsoip_index & 0x01; pthread_mutex_lock(&mux_i2c_fpga); memset(buf, 0, sizeof(buf)); memset(retbuf,0,sizeof(retbuf)); buf[0] = addr; ret = i2c_hw_read(fd_i2c_fpga, (tsoip_index==TSOIP_1)?(TS2IP_DEV_ADDRESS>>1) :(TS2IP2_DEV_ADDRESS>>1) , buf, 1, retbuf, 1); data= retbuf[0]; if(ret < 0) { log_printf(LOG_ERR,I_NOUSED,"Err.fpga read [tsoip] msg byte errnum=%d.\n",ret); data = 0xff; } pthread_mutex_unlock(&mux_i2c_fpga); #if DBG_I2C_ERR_DELAY if(ret<0)sleep(1); #endif #endif return data; } void fpga_i2c_sim_spi_write(uint16 addr, uint32 data) { // addr fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_L_OFFSET_ADDR, addr & 0xFF); fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_H_OFFSET_ADDR, (addr>>8) & 0x0F); // data fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_1_OFFSET_ADDR, (data>> 0) & 0xFF); fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_2_OFFSET_ADDR, (data>> 8) & 0xFF); fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_3_OFFSET_ADDR, (data>>16) & 0xFF); fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_4_OFFSET_ADDR, (data>>24) & 0xFF); // Wr fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, JESD204b_WR); // restore fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, 0x00); } void fpga_i2c_sim_spi_read(uint16 addr, uint32 *p_data) { uint8 d[4] = {0}; // addr fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_L_OFFSET_ADDR, addr & 0xFF); fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_ADDRESS_H_OFFSET_ADDR, (addr>>8) & 0x0F); // rd fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, JESD204b_RD); // data d[0] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_1_OFFSET_ADDR); d[1] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_2_OFFSET_ADDR); d[2] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_3_OFFSET_ADDR); d[3] = fpga_byte_read(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_4_OFFSET_ADDR); *p_data = d[0]+ (d[1]<<8)+(d[2]<<16)+(d[3]<<24); // restore fpga_byte_write(JESD_SEG_ADDR, JESD204B_AXI_WR_RD_CTRL_OFFSET_ADDR, 0x00); } void fpga_reset_save_segment(void) { fpga1_segment_bak = (uint32)-1; } void ii2c_hw_init(void) { pthread_mutex_init(&mux_i2c_fpga, NULL); #if USE_I2C_HW i2c_hw_mode_init(); //i2c_tuner_hw_mode_init(); #elif USE_I2C_HW_DIRECT_WR i2c_cdev_init(); #else i2c_soft_mode_init(); #endif } #if 1 // @tmpNot uint32 dryloop_write(uint32 addr,uint8 data) { return 0; } uint8 dryloop_read(uint32 addr) { } void ip2ts_i2c_rw(uint8 *pucData, uint8 addr,uint16 cnt, uint32 rw) { } void ip2ts2_i2c_rw(uint8 *pucData, uint8 addr,uint16 cnt, uint32 rw)//h20190220 { } uint32 atmel_write_e2rom_buf(uint8 *pbuf,uint16 offset,uint16 num,uint8 chip) { uint32 ret = 0; return ret; } uint32 atmel_read_e2rom_buf(uint8 *pbuf,uint16 offset,uint16 num,uint8 chip) { uint32 ret = 0; return ret; } #if 1//@TMP_UNUSED_TUNER TMP_NOT_USED //mux_i2c_tuner uint32 tuner_byte_write(uint32 addr,uint8 data) { #if USE_TUNER /* @f attation: not used, slave addr not used */ int ret = 0; uint8 buf[5] = {0}; pthread_mutex_lock(&mux_i2c_tuner); memset(buf, 0, sizeof(buf)); buf[0] = (uint8)addr; buf[1] = data; ret = i2c_hw_write(fd_i2c_tuner, TUNER18273_ADDRESS, buf, 2); if(ret < 0) { log_printf(LOG_ERR,I_NOUSED,"tuner write byte errnum=%d.\n", ret); sleep(1); } pthread_mutex_unlock(&mux_i2c_tuner); return ret; #else return 0; #endif } /* { uint32 ret = 0; take_mutex(i2c_mutex[TUNER_I2C_NUM]); ret = i2c1_write_offset8(&data, addr, sizeof(data), TUNER18273_ADDRESS,TUNER_I2C_NUM); give_mutex(i2c_mutex[TUNER_I2C_NUM]); delay_ms(4); return ret; } */ uint8 tuner_byte_read(uint32 addr) { #if USE_TUNER /* @f attation: not used, slave addr not used */ uint8 data = 0xff; int ret; uint8 buf[5]; uint8 retbuf[5]; uint32 time_in; uint32 time_out; pthread_mutex_lock(&mux_i2c_tuner); memset(buf, 0, sizeof(buf)); memset(retbuf,0,sizeof(retbuf)); buf[0] = addr; ret = i2c_hw_read(fd_i2c_tuner, TUNER18273_ADDRESS , buf, 1, retbuf, 1); data= retbuf[0]; if(ret < 0) { log_printf(LOG_ERR,I_NOUSED,"tuner read msg byte errnum=%d.[%s,%d]\n",ret); sleep(1); data = 0xff; } pthread_mutex_unlock(&mux_i2c_tuner); return data; #else return 0; #endif } /* { uint8 data = 0xff; uint32 ret = 0; take_mutex(i2c_mutex[TUNER_I2C_NUM]); ret = i2c1_read_offset8(&data,addr,sizeof(data),TUNER18273_ADDRESS,TUNER_I2C_NUM); give_mutex(i2c_mutex[TUNER_I2C_NUM]); if(ret!=I2C_READ_OK) { data =0xff; } delay_ms(2); return data; }*/ //调用时,第一个字节为地址 uint32 tuner_i2c_write(uint8 addr,uint8 *pdata,uint8 length) { #if USE_TUNER static uint8 stc_shot=0; int ret = length; uint8 buf[5] = {0}; static uint8 stc_addr=0; if(stc_addr!=addr){ stc_addr = addr; //log_printf(LOG_ERR,I_NOUSED,"w_tuner_addr=0x%x\n",stc_addr); } pthread_mutex_lock(&mux_i2c_tuner); ret = i2c_hw_write(fd_i2c_tuner, addr, pdata, length); if(ret < 0) { if(stc_shot==0){ stc_shot=1; printf("Err.W.tuner addr/len={0x%x %d},[%s,%d]\n",addr,length,__FUNCTION__,__LINE__); } //log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner W.addr/len={0x%x %d},[%s,%d]\n",addr,length,__FUNCTION__,__LINE__); //usleep(2*1000); ret=0; } else{ ret = length; } pthread_mutex_unlock(&mux_i2c_tuner); return ret; #else return 0; #endif } uint32 tuner_i2c_read(uint8 addr,uint8 *pdata,uint8 length) { #if USE_TUNER //---------------------------------- int ret; int retdata=1; uint8 buf[5]; uint32 time_in; uint32 time_out; static uint8 stc_addr=0; if(stc_addr!=addr){ stc_addr = addr; //log_printf(LOG_ERR,I_NOUSED,"r_tuner_addr=0x%x\n",stc_addr); } pthread_mutex_lock(&mux_i2c_tuner); #if 1 ret = i2c_hw_read2(fd_i2c_tuner, addr , pdata, length); #else //... #endif if(ret < 0) { //usr_sec_printf("Err.R.tuner i2c addr/len={0x%x %d},[%s,%d]\n",addr,length,__FUNCTION__,__LINE__); //log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner R.addr/len={0x%x %d} [%s,%d]\n",addr,length,__FUNCTION__,__LINE__); retdata = 0; //usleep(2*1000); } else{ //log_printf(LOG_DEBUG,I_NOUSED,"Ok.tuner R.addr/len={0x%x %d} [%s,%d]\n",addr,length,__FUNCTION__,__LINE__); } pthread_mutex_unlock(&mux_i2c_tuner); return retdata; //------------------------------------ #else return 0; #endif } uint32 tuner_i2c_read_offset8(uint8 slave_addr,uint8 offset,uint8 *pdata,uint8 length) { #if USE_TUNER int ret; int retdata=1; uint8 buf[5]; uint32 time_in; uint32 time_out; pthread_mutex_lock(&mux_i2c_tuner); memset(buf, 0, sizeof(buf)); buf[0] = offset; ret = i2c_hw_read(fd_i2c_tuner, slave_addr , buf, 1, pdata, length); if(ret < 0) { usr_sec_printf("Err.R.tuner offset8 addr/len={0x%x %d},[%s,%d]\n",slave_addr,length,__FUNCTION__,__LINE__); //log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner read msg offset8 byte errnum=%d.addr/len={0x%x %d}\n",ret,slave_addr,length); retdata = 0; //sleep(1); } pthread_mutex_unlock(&mux_i2c_tuner); return retdata; #else return 0; #endif } uint32 tuner_i2c_read_offset16(uint8 slave_addr,uint8 offset[8],uint8 *pdata,uint8 length) { #if USE_TUNER int ret; int retdata=length; uint8 buf[5]; uint32 time_in; uint32 time_out; pthread_mutex_lock(&mux_i2c_tuner); memset(buf, 0, sizeof(buf)); buf[0] = offset[0]; buf[1] = offset[1]; ret = i2c_hw_read(fd_i2c_tuner, slave_addr , buf, 2, pdata, length); if(ret < 0) { usr_sec_printf("Err.R.tuner offset16 addr/len={0x%x %d},[%s,%d]\n",slave_addr,length,__FUNCTION__,__LINE__); //log_printf(LOG_DEBUG,I_NOUSED,"Err.tuner read msg offset16 byte errnum=%d.addr/len={0x%x %d} \n",ret,slave_addr,length); retdata = 0; //sleep(1); } pthread_mutex_unlock(&mux_i2c_tuner); return retdata; #else return 0; #endif } /* { uint32 ret = 0; take_mutex(i2c_mutex[TUNER_I2C_NUM]); ret = i2c1_read_offset_tuner(pdata,offset,length,slave_addr,TUNER_I2C_NUM); give_mutex(i2c_mutex[TUNER_I2C_NUM]); delay_ms(2); if(ret!=I2C_READ_OK) return 0; else return length; } */ #endif //TMP_NOT_USED #endif // @tmpNot void fpga_write_axi0(uint32 addr, uint32 data, uint32 count) { /*uint32 tmp_cnt = count; uint32 tmp_addr = addr; //printf(">>W [fpga_wr_axi] addr=0x%x data=0x%x\n", addr, data); while (count--) { // 向地址 0x040 写入 0x000000A5 fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位 fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位 fpga_byte_write(JESD_SEG_ADDR, 0xB8, data&0xff); // 写数据低 8 位(高 24 位固定为 0) fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_WR = 0,便于形成新的上升沿 fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x04); // 触发 AXI 写(AXI_WR: 0 -> 1) printf(" -W- [fpga_wr_i2c] addr=0x%x data=0x%x\n", addr, data); // 写操作无需等待完成标志,FPGA 内部自动处理 addr += 1; } */ fpga_byte_write(JESD_SEG_ADDR, addr, data); } int fpga_read_axi0(uint32 addr, uint32 *pdata, uint32 count) { uint8 tmp_data; //printf(">>R [fpga_rd_axi] addr=0x%x count=0x%x\n", addr, count); /*while (count--) { // 读取地址 0x040 的寄存器 fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位 fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位 fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_RD = 0,便于形成新的上升沿 fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x02); // 触发 AXI 读(AXI_RD: 0 -> 1) // 等待读完成 uint8_t status; uint32_t time_out=5000; do { status = fpga_byte_read(JESD_SEG_ADDR, 0xB4); time_out--; if(time_out<=0){ time_out = 1; break; } } while (!(status & 0x04)); // 等待 AXI_RD_DONE = 1 // 读取 32 位数据 uint8_t d0, d1, d2, d3; d0 = fpga_byte_read(JESD_SEG_ADDR, 0xB5); d1 = fpga_byte_read(JESD_SEG_ADDR, 0xB6); d2 = fpga_byte_read(JESD_SEG_ADDR, 0xB7); d3 = fpga_byte_read(JESD_SEG_ADDR, 0xB8); uint32_t result = ((uint32_t)d3 << 24) | ((uint32_t)d2 << 16) | ((uint32_t)d1 << 8) | d0; *pdata = result; printf(" -R- fpga_rd_i2c addr=0x%x data=0x%x timeout=%d\n", addr, result, time_out); pdata += 1; addr += 1; }*/ while (count--) { tmp_data = fpga_byte_read(JESD_SEG_ADDR, addr); *pdata = tmp_data; } return 0; } void fpga_write_axi0_test(uint32 addr, uint32 data, uint32 count) { uint32 tmp_cnt = count; uint32 tmp_addr = addr; //printf(">>W [fpga_wr_axi] addr=0x%x data=0x%x\n", addr, data); while (count--) { // 向地址 0x040 写入 0x000000A5 fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位 fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位 fpga_byte_write(JESD_SEG_ADDR, 0xB8, data&0xff); // 写数据低 8 位(高 24 位固定为 0) fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_WR = 0,便于形成新的上升沿 fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x04); // 触发 AXI 写(AXI_WR: 0 -> 1) printf(" -W- [fpga_wr_i2c] addr=0x%x data=0x%x\n", addr, data); // 写操作无需等待完成标志,FPGA 内部自动处理 addr += 1; } } int fpga_read_axi0_test(uint32 addr, uint32 *pdata, uint32 count) { uint8 tmp_data; //printf(">>R [fpga_rd_axi] addr=0x%x count=0x%x\n", addr, count); while (count--) { // 读取地址 0x040 的寄存器 fpga_byte_write(JESD_SEG_ADDR, 0xB6, (addr)&0xff); // 地址低 8 位 fpga_byte_write(JESD_SEG_ADDR, 0xB7, (addr>>8)&0xff); // 地址高 4 位 fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x00); // 确保 AXI_RD = 0,便于形成新的上升沿 fpga_byte_write(JESD_SEG_ADDR, 0xB5, 0x02); // 触发 AXI 读(AXI_RD: 0 -> 1) // 等待读完成 uint8_t status; uint32_t time_out=5000; do { status = fpga_byte_read(JESD_SEG_ADDR, 0xB4); time_out--; if(time_out<=0){ time_out = 1; break; } } while (!(status & 0x04)); // 等待 AXI_RD_DONE = 1 // 读取 32 位数据 uint8_t d0, d1, d2, d3; d0 = fpga_byte_read(JESD_SEG_ADDR, 0xB5); d1 = fpga_byte_read(JESD_SEG_ADDR, 0xB6); d2 = fpga_byte_read(JESD_SEG_ADDR, 0xB7); d3 = fpga_byte_read(JESD_SEG_ADDR, 0xB8); uint32_t result = ((uint32_t)d3 << 24) | ((uint32_t)d2 << 16) | ((uint32_t)d1 << 8) | d0; *pdata = result; printf(" -R- [fpga_rd_i2c] addr=0x%x data=0x%x timeout=%d\n", addr, result, time_out); pdata += 1; addr += 1; } return 0; } #endif /* ================= Sony CXD2878 i2c glue (ported from EMV9.3) ================= */ #include "../sonytuner/sony_i2c.h" #ifndef BURST_WRITE_MAX #define BURST_WRITE_MAX 128 #endif sony_result_t i2c_read(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t* pData, uint32_t numberOfBytes, uint8_t mode) { int ret; sony_result_t result=SONY_RESULT_OK; uint8_t reg_addr = (uint8_t)pData[0]; printf("[%s,%d] deviceAddress=0x%x reg_addr=0x%x numberOfBytes=0x%x\n", __FUNCTION__,__LINE__,deviceAddress,reg_addr,numberOfBytes); /*ret = HI_UNF_I2C_Read(SONY_CXD_I2C_NUM, deviceAddress, reg_addr, 1, pData+1, numberOfBytes-1); if(ret != HI_SUCCESS) { printf("[%s] ret error code:0x%x.",__FUNCTION__,ret); }*/ pthread_mutex_lock(&mux_i2c_tuner); ret = i2c_hw_read(fd_i2c_tuner, deviceAddress>>1, ®_addr, 1, (pData+1), numberOfBytes-1);//pData������ַ if(ret < 0) { printf("Err.tuner read byte errnum=%d.[%s,%d]\n", ret,__FUNCTION__,__LINE__); result = SONY_RESULT_ERROR_I2C; } else{ result = SONY_RESULT_OK; } pthread_mutex_unlock(&mux_i2c_tuner); return result; } // CXD2878 family can be accessed through the I2C bus with burst-write and burst-read operations /* S | SLAVE ADDRESS | R/W | A| DATA | A | DATA | P <0 W> */ sony_result_t i2c_write(sony_i2c_t* pI2c, uint8_t deviceAddress,uint8_t* pData, uint32_t numberOfBytes, uint8_t mode) { int ret; sony_result_t result=SONY_RESULT_OK; uint32_t reg_addr = (uint32_t)pData[0]; printf("[%s,%d] deviceAddress=0x%x reg_addr=0x%x numberOfBytes=0x%x\n", __FUNCTION__,__LINE__,deviceAddress,reg_addr,numberOfBytes); //sony_result_t (*Write)(struct sony_i2c_t* pI2c, uint8_t deviceAddress, const uint8_t *pData, uint32_t size, uint8_t mode); /*ret = HI_UNF_I2C_Write(SONY_CXD_I2C_NUM, deviceAddress, reg_addr, 1, pData+1, numberOfBytes-1); if(ret != HI_SUCCESS) { printf("[%s] ret error code:0x%x.",__FUNCTION__,ret); }*/ ret = i2c_hw_write(fd_i2c_tuner, deviceAddress>>1, pData, numberOfBytes);//pData������ַ if(ret < 0) { printf("Err.tuner write byte errnum=%d.[%s,%d]\n", ret,__FUNCTION__,__LINE__); result = SONY_RESULT_ERROR_I2C; } else{ result = SONY_RESULT_OK; } return result; } sony_result_t sony_i2c_CommonReadRegister(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, uint8_t* pData, uint32_t size) { sony_result_t result = SONY_RESULT_OK; int ret; SONY_TRACE_I2C_ENTER("sony_i2c_CommonReadRegister"); if(!pI2c || (!pData)){ SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG); } #if 0 result = pI2c->Write(pI2c, deviceAddress, &subAddress, 1, SONY_I2C_START_EN); if(result == SONY_RESULT_OK){ result = pI2c->Read(pI2c, deviceAddress, pData, size, SONY_I2C_START_EN | SONY_I2C_STOP_EN); } SONY_TRACE_I2C_RETURN(result); #else uint8 sub_addr; sub_addr = subAddress; pthread_mutex_lock(&mux_i2c_tuner); ret = i2c_hw_read(fd_i2c_tuner, deviceAddress>>1, &sub_addr, 1, pData, size); if(ret < 0) { printf("Err.tuner read byte errnum=%d.[%s,%d]\n", result,__FUNCTION__,__LINE__); result = SONY_RESULT_ERROR_I2C; } else{ result = SONY_RESULT_OK; } pthread_mutex_unlock(&mux_i2c_tuner); //printf("I2CR addr=0x%0X data=0x%02X slv=0x%X\n", subAddress, *pData, deviceAddress); return result; #endif } sony_result_t sony_i2c_CommonWriteRegister(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, const uint8_t* pData, uint32_t size) { sony_result_t result = SONY_RESULT_OK; int ret; uint8_t buffer[BURST_WRITE_MAX + 1]; #if 0 SONY_TRACE_I2C_ENTER("sony_i2c_CommonWriteRegister"); if(!pI2c || (!pData)){ SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG); } if(size > BURST_WRITE_MAX){ /* Buffer is too small... */ SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG); } buffer[0] = subAddress; memcpy(&(buffer[1]), pData, size); /* send the new buffer */ result = pI2c->Write(pI2c, deviceAddress, buffer, size+1, SONY_I2C_START_EN | SONY_I2C_STOP_EN); SONY_TRACE_I2C_RETURN(result); #else ret = tuner_nbytes_write(deviceAddress>>1, subAddress, (uint8_t*)pData, size); // deviceAddress=0xdc if(ret < 0) { printf("Err.tuner write byte errnum=%d.[%s,%d]\n", result,__FUNCTION__,__LINE__); result = SONY_RESULT_ERROR_I2C; } else { result = SONY_RESULT_OK; } //printf("I2CW addr=0x%0X data=0x%02X slv=0x%X\n", subAddress, *pData, deviceAddress); return result; #endif } sony_result_t sony_i2c_CommonWriteOneRegister(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, uint8_t data) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_I2C_ENTER("sony_i2c_CommonWriteOneRegister"); //printf("sony_i2c_CommonWriteOneRegister\r\n"); if(!pI2c){ SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG); } result = pI2c->WriteRegister(pI2c, deviceAddress, subAddress, &data, 1); SONY_TRACE_I2C_RETURN(result); } /* For Read-Modify-Write */ sony_result_t sony_i2c_SetRegisterBits(sony_i2c_t* pI2c, uint8_t deviceAddress, uint8_t subAddress, uint8_t data, uint8_t mask) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_I2C_ENTER("sony_i2c_SetRegisterBits"); if(!pI2c){ SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG); } if(mask == 0x00){ /* Nothing to do */ SONY_TRACE_I2C_RETURN(SONY_RESULT_OK); } if(mask != 0xFF){ uint8_t rdata = 0x00; result = pI2c->ReadRegister(pI2c, deviceAddress, subAddress, &rdata, 1); if(result != SONY_RESULT_OK){ SONY_TRACE_I2C_RETURN(result); } data = (uint8_t)((data & mask) | (rdata & (mask ^ 0xFF))); } result = pI2c->WriteOneRegister(pI2c, deviceAddress, subAddress, data); SONY_TRACE_I2C_RETURN(result); } /* I2c object creation , Repeater*/ sony_result_t i2c_drv_imx_init(sony_i2c_t* pI2c)//i2c_drv_his3796mv100_init { SONY_TRACE_I2C_ENTER("drvi2c_feusb_CreateI2c"); if( !pI2c ) { SONY_TRACE_I2C_RETURN(SONY_RESULT_ERROR_ARG); } pI2c->Read = i2c_read; pI2c->Write = i2c_write; pI2c->ReadRegister = sony_i2c_CommonReadRegister; pI2c->WriteRegister = sony_i2c_CommonWriteRegister; pI2c->WriteOneRegister = sony_i2c_CommonWriteOneRegister; pI2c->gwAddress = 0; pI2c->gwSub = 0; //pI2c->user = pDrvI2c; /* Store driver object to user pointer */ SONY_TRACE_I2C_RETURN(SONY_RESULT_OK); } /* PR04 SMOD: multi-byte tuner i2c write (ported from EMV9.3, used by sony_i2c glue) */ int tuner_nbytes_write(uint32 dev_addr, uint32 offset, uint8 *pdata, uint32 wlen) { int ret = 0; uint8 dbuf[50] = {0}; pthread_mutex_lock(&mux_i2c_tuner); dbuf[0] = (uint8)offset; if(wlen<50){ memcpy(&dbuf[1], pdata, wlen); } else{ printf("Err.tuner nbytes wlen over_range wlen=%u\n", (unsigned)wlen); } ret = i2c_hw_write(fd_i2c_tuner, dev_addr, dbuf, wlen+1); if(ret < 0){ printf("Err.tuner nbytes write errnum=%d\n", ret); } pthread_mutex_unlock(&mux_i2c_tuner); return ret; }