861 lines
15 KiB
C
861 lines
15 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/delay.h>
|
|
|
|
|
|
#include "vtl_ts.h"
|
|
|
|
#define FLASH_I2C_ADDR 0X7F
|
|
#define CHIP_ID_ADDR 0xf000
|
|
#define RW_FLAG 0xff
|
|
|
|
#define CHIP_WRITE_FLASH_CMD 0x55
|
|
#define CHIP_FLASH_SOURCE_SIZE 8
|
|
|
|
#define TB1_USE_F402 0
|
|
|
|
struct chip_cmd {
|
|
unsigned short addr;
|
|
unsigned char data;
|
|
};
|
|
|
|
|
|
static struct ts_info * ts_object = NULL;
|
|
static struct chip_cmd (*chip) = NULL;
|
|
|
|
|
|
|
|
enum cmd_index {
|
|
|
|
FW_VERSION = 0X00,
|
|
FW_CHECKSUM_CMD,
|
|
FW_CHECKSUM_VAL,
|
|
CHIP_SLEEP,
|
|
CHIP_ID_CMD,
|
|
|
|
/***********flash***********/
|
|
FLASH_SECTOR_ERASE_CMD,
|
|
FLASH_SECTOR_NUM,
|
|
FLASH_SECTOR_SIZE,
|
|
FLASH_MASS_ERASE_CMD
|
|
};
|
|
|
|
static struct chip_cmd ct360_cmd[] = {
|
|
{0x0f2a,RW_FLAG}, //fw version
|
|
|
|
{0x0fff,0xe1}, //fw checksum cmd
|
|
{0x0a0d,RW_FLAG}, //fw checksum val
|
|
|
|
{0x0f2b,0x00}, //chip sleep cmd
|
|
|
|
{0xf000,RW_FLAG}, //chip id cmd
|
|
|
|
/************flash*************/
|
|
{0x33,RW_FLAG}, //FLASH_SECTOR_ERASE_CMD
|
|
{8,RW_FLAG}, //FLASH_SECTOR_NUM
|
|
{2048,RW_FLAG}, //FLASH_SECTOR_SIZE
|
|
{RW_FLAG,RW_FLAG}, //FLASH_MASS_ERASE_CMD
|
|
};
|
|
|
|
static struct chip_cmd ct36x_cmd[] = {
|
|
{0x3fff,RW_FLAG}, //fw version
|
|
|
|
{0x8fff,0xe1}, //fw checksum cmd
|
|
{0x8e0e,RW_FLAG}, //fw checksum val
|
|
|
|
{0x8fff,0xaf}, //chip sleep cmd
|
|
|
|
{0xf000,RW_FLAG}, //chip id cmd
|
|
|
|
/************flash*************/
|
|
{0x30,RW_FLAG}, //FLASH_SECTOR_ERASE_CMD
|
|
{256,RW_FLAG}, //FLASH_SECTOR_NUM
|
|
{128,RW_FLAG}, //FLASH_SECTOR_SIZE
|
|
{0x33,RW_FLAG}, //FLASH_MASS_ERASE_CMD
|
|
};
|
|
|
|
#if 0
|
|
unsigned int ct36x_cmd[4][2] = {
|
|
{0x3fff,0x00}, //fw version
|
|
|
|
{0x0fff,0xe1}, //fw checksum cmd
|
|
{0x0a0d,0x00}, //fw checksum val
|
|
|
|
{0x8fff,0xaf},//chip sleep cmd
|
|
};
|
|
|
|
unsigned int (*chip)[2] = ct36x_cmd;
|
|
#endif
|
|
|
|
|
|
static int chip_i2c_read(struct i2c_client *client, __u16 addr, __u8 *buf, __u16 len)
|
|
{
|
|
struct i2c_msg msgs;
|
|
int ret;
|
|
|
|
DEBUG();
|
|
msgs.addr = addr;
|
|
msgs.flags = 0x01; // 0x00: write 0x01:read
|
|
msgs.len = len;
|
|
msgs.buf = buf;
|
|
//#if(PLATFORM == ROCKCHIP)
|
|
//msgs.scl_rate = TS_I2C_SPEED;
|
|
//#endif
|
|
|
|
ret = i2c_transfer(client->adapter, &msgs, 1);
|
|
if(ret != 1){
|
|
printk("___%s:i2c read error___\n",__func__);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int chip_i2c_write(struct i2c_client *client, __u16 addr, __u8 *buf, __u16 len)
|
|
{
|
|
struct i2c_msg msgs;
|
|
int ret;
|
|
|
|
DEBUG();
|
|
msgs.addr = addr;
|
|
msgs.flags = 0x00; // 0x00: write 0x01:read
|
|
msgs.len = len;
|
|
msgs.buf = buf;
|
|
//#if(PLATFORM == ROCKCHIP)
|
|
//msgs.scl_rate = TS_I2C_SPEED;
|
|
//#endif
|
|
|
|
ret = i2c_transfer(client->adapter, &msgs, 1);
|
|
if(ret != 1){
|
|
printk("___%s:i2c write error___\n",__func__);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int chip_ram_write_1byte(unsigned short addr,unsigned char data)
|
|
{
|
|
struct i2c_client *client = ts_object->driver->client;
|
|
unsigned char buf[3];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
buf[0] = 0xff;
|
|
buf[1] = addr >> 8;
|
|
buf[2] = addr & 0x00ff;
|
|
//printk("addr = %x,buf[0] = %x,buf[1] = %x,buf[2] = %x,data = %x\n",addr,buf[0],buf[1],buf[2],data);
|
|
ret = chip_i2c_write(client, client->addr, buf,3);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
udelay(10);
|
|
buf[0] = 0x00;
|
|
buf[1] = data;
|
|
ret = chip_i2c_write(client, client->addr, buf,2);
|
|
udelay(10);
|
|
return ret;
|
|
}
|
|
|
|
static int chip_ram_read(unsigned short addr,unsigned char *rx_buf,unsigned short len)
|
|
{
|
|
struct i2c_client *client = ts_object->driver->client;
|
|
unsigned char buf[3];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
buf[0] = 0xff;
|
|
buf[1] = addr >> 8;
|
|
buf[2] = addr & 0x00ff;
|
|
//printk("addr = %x,buf[0] = %x,buf[1] = %x,buf[2] = %x\n",addr,buf[0],buf[1],buf[2]);
|
|
ret = chip_i2c_write(client, client->addr, buf,3);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
udelay(10);
|
|
buf[0] = 0x00;
|
|
ret = chip_i2c_write(client, client->addr, buf,1);
|
|
udelay(10);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
udelay(10);
|
|
ret = chip_i2c_read(client,client->addr,rx_buf,len);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int chip_get_fw_version(unsigned char *buf)
|
|
{
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
ret = chip_ram_read(chip[FW_VERSION].addr,buf,1);
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
int chip_get_chip_id(unsigned char *buf)
|
|
{
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
ret = chip_ram_read(chip[CHIP_ID_CMD].addr,buf,1);
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
int chip_enter_sleep_mode(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
if(chip == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
ret = chip_ram_write_1byte(chip[CHIP_SLEEP].addr,chip[CHIP_SLEEP].data);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int chip_function(enum cmd_index cmd_index,unsigned char *rx_buf,unsigned char len)
|
|
{
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
if(chip[cmd_index].data != RW_FLAG) //write
|
|
{
|
|
ret = chip_ram_write_1byte(chip[cmd_index].addr,chip[cmd_index].data);
|
|
}
|
|
else //read
|
|
{
|
|
ret = chip_ram_read(chip[cmd_index].addr,rx_buf,len);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/***************flash********************/
|
|
#if 0
|
|
static int chip_flash_init(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[2];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
buf[0] = 0x00;
|
|
buf[1] = 0x00;
|
|
ret = chip_i2c_write(client, FLASH_I2C_ADDR, buf,2);
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
static int chip_read_bus_status(struct i2c_client *client,unsigned char *rx_buf)
|
|
{
|
|
unsigned char buf[1];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
buf[0] = 0x00;
|
|
ret = chip_i2c_write(client, FLASH_I2C_ADDR, buf,1);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
mdelay(1);
|
|
ret = chip_i2c_read(client,FLASH_I2C_ADDR,rx_buf,1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int chip_enter_idle_mode(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[2];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
buf[0] = 0x00;
|
|
buf[1] = 0xa5;
|
|
ret = chip_i2c_write(client, FLASH_I2C_ADDR, buf,2);
|
|
mdelay(5);
|
|
//mdelay(10);
|
|
return ret;
|
|
}
|
|
|
|
int chip_solfware_reset(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[2];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
buf[0] = 0x00;
|
|
buf[1] = 0x5a;
|
|
ret = chip_i2c_write(client, FLASH_I2C_ADDR, buf,2);
|
|
msleep(200);//ct36x
|
|
//msleep(100);
|
|
return ret;
|
|
}
|
|
|
|
static int chip_erase_flash(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[4];
|
|
int sec,sec_addr;
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
if(chip[FLASH_MASS_ERASE_CMD].addr == 0x33)//ct36x mass erase
|
|
{
|
|
ret = chip_read_bus_status(client,buf);
|
|
if(buf[0] != 0xaa)
|
|
{
|
|
printk("___i2c bus busy,bus_status = %d___\n",buf[0]);
|
|
return -1;
|
|
}
|
|
buf[0] = 0x00;
|
|
buf[1] = chip[FLASH_MASS_ERASE_CMD].addr;
|
|
buf[2] = 0x00;
|
|
buf[3] = 0x00;
|
|
ret = chip_i2c_write(client, FLASH_I2C_ADDR, buf,4);
|
|
if(ret)
|
|
{
|
|
printk("vtl chip flash erase fail\n");
|
|
return ret;
|
|
}
|
|
//printk("mass erase\n");
|
|
//mdelay(10);
|
|
msleep(10);
|
|
}
|
|
else //ct360/ct36x sector erase
|
|
{
|
|
for(sec = 0;sec < chip[FLASH_SECTOR_NUM].addr;sec++)
|
|
{
|
|
ret = chip_read_bus_status(client,buf);
|
|
if(buf[0] != 0xaa)
|
|
{
|
|
printk("___i2c bus busy,bus_status = %x,sec = %d___\n",buf[0],sec);
|
|
return -1;
|
|
}
|
|
sec_addr = sec * chip[FLASH_SECTOR_SIZE].addr;
|
|
buf[0] = 0x00;
|
|
buf[1] = chip[FLASH_SECTOR_ERASE_CMD].addr;
|
|
buf[2] = sec_addr >> 8;
|
|
buf[3] = sec_addr & 0x00ff;
|
|
ret = chip_i2c_write(client, FLASH_I2C_ADDR, buf,4);
|
|
if(ret)
|
|
{
|
|
printk("vtl chip flash erase fail\n");
|
|
return ret;
|
|
}
|
|
//msleep(10);//ct36x
|
|
msleep(100);//ct360
|
|
}
|
|
//printk("sector erase\n");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
extern unsigned char *gtpfw;
|
|
static int chip_set_code(unsigned int flash_addr, unsigned char *buf)
|
|
{
|
|
unsigned char i;
|
|
static unsigned char *binary_data = NULL;
|
|
|
|
if (binary_data == NULL) {
|
|
binary_data = gtpfw;
|
|
}
|
|
|
|
buf[2] = (flash_addr >> 8);
|
|
buf[3] = (flash_addr & 0xFF);
|
|
buf[4] = 0x08;
|
|
|
|
DEBUG();
|
|
if ( (flash_addr == 160) || (flash_addr == 168) )
|
|
{
|
|
for(i=0;i<8;i++)
|
|
{
|
|
buf[i+6] = ~binary_data[flash_addr + i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(i=0;i<8;i++)
|
|
{
|
|
buf[i+6] = binary_data[flash_addr + i];
|
|
}
|
|
}
|
|
buf[5] = ~(buf[2]+buf[3]+buf[4]+buf[6]+buf[7]+buf[8]+buf[9]+buf[10]+buf[11]+buf[12]+buf[13]) + 1;
|
|
return buf[5];
|
|
}
|
|
|
|
static int chip_get_bin_checksum(void)
|
|
{
|
|
unsigned char buf[14];
|
|
int sec,cod;
|
|
int flash_addr;
|
|
unsigned short bin_checksum = 0;
|
|
|
|
DEBUG();
|
|
flash_addr = 0x00;
|
|
cod = chip[FLASH_SECTOR_NUM].addr * (chip[FLASH_SECTOR_SIZE].addr/CHIP_FLASH_SOURCE_SIZE);
|
|
for(sec=0;sec<cod;sec++)
|
|
{
|
|
bin_checksum += chip_set_code(flash_addr,buf);
|
|
flash_addr += CHIP_FLASH_SOURCE_SIZE;
|
|
//printk("sec = %d\n",sec);
|
|
}
|
|
return bin_checksum;
|
|
}
|
|
|
|
int chip_get_fwchksum(struct i2c_client *client,int *fwchksum)
|
|
{
|
|
unsigned char buf[2];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
if(chip == NULL){
|
|
return -1;
|
|
}
|
|
ret = chip_ram_write_1byte(chip[FW_CHECKSUM_CMD].addr,chip[FW_CHECKSUM_CMD].data);
|
|
if(ret)
|
|
{
|
|
return -1;
|
|
}
|
|
msleep(700);
|
|
ret = chip_ram_read(chip[FW_CHECKSUM_VAL].addr,buf,2);
|
|
*fwchksum = (buf[0]<<8)|buf[1];
|
|
//chip_solfware_reset(client);
|
|
vtl_ts_hw_reset();
|
|
return 0;
|
|
}
|
|
|
|
static int chip_write_flash(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[14];
|
|
#if 0
|
|
unsigned char bus_status[1];
|
|
#endif
|
|
int sec,cod,sec_8byte_num;
|
|
int flash_addr;
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
buf[0] = 0x00;
|
|
buf[1] = CHIP_WRITE_FLASH_CMD;
|
|
sec_8byte_num = chip[FLASH_SECTOR_SIZE].addr/CHIP_FLASH_SOURCE_SIZE;
|
|
cod = chip[FLASH_SECTOR_NUM].addr * sec_8byte_num;
|
|
flash_addr = 0x00;
|
|
for(sec=0;sec<cod;)
|
|
{
|
|
chip_set_code(flash_addr,buf);
|
|
flash_addr += CHIP_FLASH_SOURCE_SIZE;
|
|
#if 0
|
|
ret = chip_read_bus_status(client,bus_status);
|
|
if(bus_status[0] != 0xaa)
|
|
{
|
|
printk("i2c bus busy,sec = %d,bus_status = %x\n",sec,bus_status[0]);
|
|
return -1;
|
|
}
|
|
#endif
|
|
ret = chip_i2c_write(client,FLASH_I2C_ADDR, buf,14);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
sec++;
|
|
if(!(sec%sec_8byte_num))
|
|
{
|
|
msleep(10);
|
|
//mdelay(10);
|
|
}
|
|
mdelay(1);//ct360
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int chip_get_checksum(struct i2c_client *client,int *bin_checksum,int *fw_checksum)
|
|
{
|
|
DEBUG();
|
|
|
|
if(chip == NULL){
|
|
return -1;
|
|
}
|
|
*bin_checksum = chip_get_bin_checksum();
|
|
chip_get_fwchksum(client,fw_checksum);
|
|
//printk("bin_checksum = 0x%x,fw_checksum = 0x%x\n",*bin_checksum,*fw_checksum);
|
|
return 0;
|
|
}
|
|
|
|
int update(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[20];
|
|
int ret = 0;
|
|
DEBUG();
|
|
|
|
if(chip == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
printk("___chip update start___\n");
|
|
ret = chip_enter_idle_mode(client);
|
|
if(ret)
|
|
{
|
|
return -1;
|
|
}
|
|
ret = chip_read_bus_status(client,buf);
|
|
if(buf[0] != 0xaa)
|
|
{
|
|
printk("___i2c bus busy,bus_status = %x___\n",buf[0]);
|
|
return -1;
|
|
}
|
|
ret = chip_erase_flash(client);
|
|
if(ret)
|
|
{
|
|
printk("___erase flash fail___\n");
|
|
return -1;
|
|
}
|
|
ret = chip_write_flash(client);
|
|
if(ret)
|
|
{
|
|
printk("___write flash fail___\n");
|
|
return -1;
|
|
}
|
|
vtl_ts_hw_reset();
|
|
printk("___chip update end___\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int chip_update(struct i2c_client *client)
|
|
{
|
|
int bin_checksum = 0xff;
|
|
int fw_checksum = 0;
|
|
int cnt = 0;
|
|
|
|
DEBUG();
|
|
if(chip == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
chip_get_checksum(client,&bin_checksum,&fw_checksum);
|
|
printk("bin_checksum = 0x%x,fw_checksum = 0x%x\n",bin_checksum,fw_checksum);
|
|
cnt = 2;
|
|
while((bin_checksum != fw_checksum) && (cnt--))
|
|
{
|
|
if(update(client) < 0)
|
|
{
|
|
vtl_ts_hw_reset();
|
|
continue;
|
|
}
|
|
chip_get_fwchksum(client,&fw_checksum);
|
|
printk("bin_checksum = %x,fw_checksum = %x,cnt = %d\n",bin_checksum,fw_checksum,cnt);
|
|
}
|
|
|
|
if(bin_checksum != fw_checksum)
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
int chip_update(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[20];
|
|
int bin_checksum,fw_checksum,cnt;
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
if(chip == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
bin_checksum = chip_get_bin_checksum();
|
|
chip_get_fwchksum(client,&fw_checksum);
|
|
printk("bin_checksum = %x,fw_checksum = %x\n",bin_checksum,fw_checksum);
|
|
cnt = 2;
|
|
while((bin_checksum != fw_checksum) && (cnt--))
|
|
//while(cnt--)
|
|
{
|
|
printk("___chip update start___\n");
|
|
ret = chip_enter_idle_mode(client);
|
|
if(ret)
|
|
{
|
|
//return ret;
|
|
continue;
|
|
}
|
|
ret = chip_read_bus_status(client,buf);
|
|
if(buf[0] != 0xaa)
|
|
{
|
|
printk("___i2c bus busy,bus_status = %x___\n",buf[0]);
|
|
//return ret;
|
|
continue;
|
|
}
|
|
ret = chip_erase_flash(client);
|
|
if(ret)
|
|
{
|
|
printk("___erase flash fail___\n");
|
|
//return ret;
|
|
continue;
|
|
}
|
|
ret = chip_write_flash(client);
|
|
if(ret)
|
|
{
|
|
printk("___write flash fail___\n");
|
|
//return ret;
|
|
continue;
|
|
}
|
|
vtl_ts_hw_reset();
|
|
//chip_solfware_reset(client);
|
|
ret = chip_get_fwchksum(client,&fw_checksum);
|
|
if(ret)
|
|
{
|
|
printk("___get fwchksum fail___\n");
|
|
//return ret;
|
|
continue;
|
|
}
|
|
printk("___chip update end___\n");
|
|
printk("bin_checksum = %x,fw_checksum = %x\n",bin_checksum,fw_checksum);
|
|
}
|
|
//vtl_ts_hw_reset();
|
|
if(bin_checksum != fw_checksum)
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
int chip_get_chip_id(struct i2c_client *client,unsigned char *rx_buf)
|
|
{
|
|
unsigned char buf[3];
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
ret = chip_enter_idle_mode(client);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = chip_read_bus_status(client,buf);
|
|
if(buf[0]!= 0xaa)
|
|
{
|
|
printk("___i2c bus status = %x,ret = %d___\n",buf[0],ret);
|
|
return -1;
|
|
}
|
|
mdelay(1);
|
|
|
|
buf[0] = 0xff;
|
|
buf[1] = CHIP_ID_ADDR>>8;
|
|
buf[2] = CHIP_ID_ADDR & 0x00ff;
|
|
ret = chip_i2c_write(client,0x01, buf,3);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
mdelay(1);
|
|
buf[0] = 0x00;
|
|
ret = chip_i2c_write(client,0x01, buf,1);
|
|
if(ret)
|
|
{
|
|
return ret;
|
|
}
|
|
mdelay(1);
|
|
ret = chip_i2c_read(client,0x01,rx_buf,1);
|
|
//chip_solfware_reset(client);
|
|
vtl_ts_hw_reset();
|
|
|
|
//printk("___chip ID = %d___\n",*rx_buf);
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
static int chip_read_infoblk(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[20] = {0};
|
|
|
|
DEBUG();
|
|
|
|
buf[0] = 0x00;
|
|
buf[1] = 0x62;
|
|
buf[2] = 0x00;
|
|
buf[3] = 0x00;
|
|
buf[4] = 0x08;
|
|
|
|
chip_i2c_write(client,0x7F, buf,5);
|
|
mdelay(1);
|
|
chip_i2c_read(client,0x7f, buf,14);
|
|
|
|
if(buf[5] & 0x10)
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int chip_erase_infoblk(struct i2c_client *client)
|
|
{
|
|
unsigned char buf[20]={0};
|
|
int ret = -1;
|
|
|
|
DEBUG();
|
|
|
|
// info block erase command
|
|
buf[0] = 0x00;
|
|
buf[1] = 0x60;
|
|
buf[2] = 0x00;
|
|
chip_i2c_write(client, 0x7F, buf, 3);
|
|
mdelay(10);
|
|
|
|
ret = chip_read_bus_status(client,buf);
|
|
if(buf[0]!= 0xaa)
|
|
{
|
|
printk("___i2c bus status = %x,ret = %d___\n",buf[0],ret);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int chip_write_infoblk(struct i2c_client *client)
|
|
{
|
|
//int ret = -1;
|
|
unsigned char buf[20]={0};
|
|
int cod;
|
|
unsigned int flash_addr;
|
|
|
|
DEBUG();
|
|
|
|
flash_addr = 0x00;
|
|
|
|
// write info block 0
|
|
buf[0] = 0x00;
|
|
buf[1] = 0x61;
|
|
|
|
for ( cod = 0; cod < 16; cod++ ) {
|
|
// Flash address
|
|
// data length
|
|
buf[2] = (char)(flash_addr >> 8);
|
|
buf[3] = (char)(flash_addr & 0xFF);
|
|
buf[4] = 0x08;
|
|
if ( flash_addr == 0x0000 )
|
|
buf[6] = 0x17;
|
|
else
|
|
buf[6] = 0x00;
|
|
|
|
buf[7] = 0x00;
|
|
buf[8] = 0x00;
|
|
buf[9] = 0x00;
|
|
buf[10] = 0x00;
|
|
buf[11] = 0x00;
|
|
buf[12] = 0x00;
|
|
buf[13] = 0x00;
|
|
|
|
buf[5] = (~(buf[2]+buf[3]+buf[4]+buf[6]+buf[7]+buf[8]+buf[9]+buf[10]+buf[11]+buf[12]+buf[13]))+1;
|
|
|
|
chip_i2c_write(client, 0x7F, buf, 14);
|
|
mdelay(10);
|
|
|
|
flash_addr += 8;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int chip_trim_info_init(struct i2c_client *client)
|
|
{
|
|
int retry =5;
|
|
|
|
while(chip_read_infoblk(client) && (retry--))
|
|
{
|
|
chip_erase_infoblk(client);
|
|
chip_write_infoblk(client);
|
|
}
|
|
vtl_ts_hw_reset();
|
|
return 0;
|
|
}
|
|
|
|
int chip_init(void)
|
|
{
|
|
struct i2c_client *client;
|
|
unsigned char chip_id = 0xff;
|
|
unsigned char retry;
|
|
int ret = 0;
|
|
|
|
DEBUG();
|
|
|
|
ts_object = vtl_ts_get_object();
|
|
|
|
if(ts_object == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
client = ts_object->driver->client;
|
|
|
|
chip = NULL;
|
|
for(retry = 0;retry<3;retry++)
|
|
{
|
|
ret = chip_get_chip_id(client,&chip_id);
|
|
printk("___chip ID = %d___cnt = %d\n",chip_id,retry);
|
|
switch(chip_id)
|
|
{
|
|
case 1: { //chip: CT362, CT363, CT365, CT368, CT369
|
|
chip = ct36x_cmd;
|
|
chip_trim_info_init(client);
|
|
}break;
|
|
|
|
case 2: { //chip: CT360
|
|
chip = ct360_cmd;
|
|
}break;
|
|
|
|
case 6: { //chip: CT362M, CT363M, CT365M, CT368M, CT369M
|
|
chip = ct36x_cmd;
|
|
}break;
|
|
|
|
default : {
|
|
|
|
chip = NULL;
|
|
}
|
|
}
|
|
if(chip != NULL)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(chip == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
#if(CHIP_UPDATE_ENABLE)
|
|
if(chip_update(client)<0)
|
|
{
|
|
printk("___chip updata faile___\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|