#include <linux/completion.h>
#include <asm/uaccess.h>
#include <mach/board.h>
+#include <linux/reboot.h>
#define GOODIX_I2C_NAME "Goodix-TS"
//define default resolution of the touchscreen
#define GOODIX_MULTI_TOUCH
-#define GT819_IIC_SPEED 350*1000 //400*1000
+#define GT819_IIC_SPEED 400*1000 //400*1000
#define TOUCH_MAX_WIDTH 800
#define TOUCH_MAX_HEIGHT 480
#define TOUCH_MAJOR_MAX 200
unsigned int oldcrc32 = 0xFFFFFFFF;
unsigned int ulPolynomial = 0x04c11db7;
struct i2c_client * i2c_connect_client = NULL;
+static struct early_suspend gt819_power;
static u8 gt819_fw[]=
{
-#include "gt819_fw.bin"
+#include "gt819_fw.i"
};
#if 0
uint8_t config_info[] = {
if(ret>0)
return ret;
ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
+ if(ret>0)
+ return ret;
+ ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
+ if(ret>0)
+ return ret;
+ ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
+ if(ret>0)
+ return ret;
+ ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
return ret;
}
if(ret>0)
return ret;
ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
+ if(ret>0)
+ return ret;
+ ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
+ if(ret>0)
+ return ret;
+ ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
+ if(ret>0)
+ return ret;
+ ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
return ret;
}
return 0;
}
-int gt189_wait_for_slave(struct i2c_client *client)
+int gt189_wait_for_slave(struct i2c_client *client, u8 status)
{
unsigned char i2c_state_buf[2];
int ret,i = 0;
while(i < MAX_I2C_RETRIES)
{
ret = gt819_read_regs(client,ADDR_STA, i2c_state_buf, 1);
+ printk("i2c read state byte:0x%x\n",i2c_state_buf[0]);
if(ret < 0)
return ERROR_I2C_TRANSFER;
- if((i2c_state_buf[0] & SLAVE_READY) || (i2c_state_buf[0] & UPDATE_START))
+ if(i2c_state_buf[0]==0xff)continue;
+ if(i2c_state_buf[0] & status)
return i2c_state_buf[0];
msleep(10);
i++;
}
- return ERROR_TIMEOUT;
+ return -ERROR_TIMEOUT;
}
int gt819_update_write_config(struct i2c_client *client)
-{
- int i,ret,len = sizeof(config_info);
- ret = gt819_set_regs(client, 101, config_info, len);
- if(ret < 0)
- return ret;
- for (i=0; i<len; i++) {
- //printk("buf[%d] = 0x%x \n", i, config_info[i]);
+ {
+ int ret,len = sizeof(config_info)-1; //byte[0] is the reg addr in the gt819.cfg
+ u8 cfg_rd_buf[len];
+ u8 cfg_cmd_buf = 0x03;
+ u8 retries = 0;
+
+ reconfig:
+ ret = gt819_set_regs(client, 101, &config_info[1], len);
+ if(ret < 0)
+ return ret;
+ gt819_printf(config_info, len);
+ ret = gt819_read_regs(client, 101, cfg_rd_buf, len);
+ if(ret < 0)
+ return ret;
+ if(memcmp(cfg_rd_buf, &config_info[1], len))
+ {
+ dev_info(&client->dev, "config info check error!\n");
+ if(retries < 5)
+ {
+ retries++;
+ ret = gt819_set_regs(client, ADDR_CMD, &cfg_cmd_buf, 1);
+ if(ret < 0)
+ return ret;
+ goto reconfig;
+ }
+ return -1;
+ }
+ cfg_cmd_buf = 0x04;
+ ret = gt819_set_regs(client, ADDR_CMD, &cfg_cmd_buf, 1);
+ if(ret < 0)
+ return ret;
+ return 0;
}
- return 0;
-}
-static int gt819_read_version(struct i2c_client *client)
+
+static int gt819_read_version(struct i2c_client *client,char *version)
{
int ret, count = 0;
- char version[17],*p;
+ char *p;
ret = gt819_read_regs(client,240, version, 16);
if (ret < 0)
{
int ret,data_len,i,check_len,frame_checksum,frame_number = 0;
unsigned char *p,i2c_data_buf[PACK_SIZE+8];
+ u8 i2c_rd_buf[PACK_SIZE+8];
+
+ u8 retries = 0;
+ u8 check_state = 0;
+
if(!client || !fw_buf)
return -1;
while(len){
frame_checksum = 0;
+ retries = 0;
check_len = (len >= PACK_SIZE) ? PACK_SIZE : len;
data_len = check_len+8;
- dev_info(&client->dev, "PACK[%d]:prepare data,len = %d\n",frame_number,check_len);
- p = fw_buf;
+ dev_info(&client->dev, "PACK[%d]:prepare data,remained len = %d\n",frame_number,len);
+ p = &fw_buf[frame_number*PACK_SIZE];
for(i=0; i<check_len; i++)
frame_checksum += *p++;
frame_checksum = 0 - frame_checksum;
*p++ = (frame_number>>16)&0xff;
*p++ = (frame_number>>8)&0xff;
*p++ = frame_number&0xff;
- memcpy(p,fw_buf,check_len);
+ memcpy(p, &fw_buf[frame_number*PACK_SIZE],check_len);
p += check_len;
*p++ = frame_checksum&0xff;
*p++ = (frame_checksum>>8)&0xff;
*p++ = (frame_checksum>>16)&0xff;
*p++ = (frame_checksum>>24)&0xff;
- gt819_printf(i2c_data_buf, data_len);
+ //gt819_printf(i2c_data_buf, data_len);
dev_info(&client->dev, "PACK[%d]:write to slave\n",frame_number);
+resend:
ret = gt819_set_regs(client,ADDR_DAT, i2c_data_buf, data_len);
if(ret < 0)
return ret;
- gt819_printf(i2c_data_buf, data_len);
+ //gt819_printf(i2c_data_buf, data_len);
+ msleep(10);
dev_info(&client->dev, "PACK[%d]:read data\n",frame_number);
- memset(i2c_data_buf, 0, sizeof(i2c_data_buf));
- ret = gt819_read_regs(client,ADDR_DAT, i2c_data_buf, data_len);
+ memset(i2c_rd_buf, 0, sizeof(i2c_rd_buf));
+ ret = gt819_read_regs(client,ADDR_DAT, i2c_rd_buf, data_len);
if(ret < 0)
return ret;
- gt819_printf(i2c_data_buf, data_len);
+ //gt819_printf(i2c_data_buf, data_len);
+ msleep(10);
dev_info(&client->dev, "PACK[%d]:check data\n",frame_number);
- if(memcmp(&i2c_data_buf[4],&fw_buf[frame_number*PACK_SIZE],data_len))
- return -1;
- //if(frame_number != (*((int*)i2c_data_buf)))
- // return -1;
- dev_info(&client->dev, "PACK[%d]:tell slave check data pass\n",frame_number);
- i2c_data_buf[0] = 0x04;
- ret = gt819_set_regs(client,ADDR_CMD, i2c_data_buf, 1);
- if(ret < 0)
- return ret;
- dev_info(&client->dev, "PACK[%d]:wait for slave to start next frame\n",frame_number);
- ret = gt189_wait_for_slave(client);
- if((ret & CHECKSUM_ERROR) || (ret & FRAME_ERROR) || (ret & ERROR_I2C_TRANSFER) || (ret & ERROR_TIMEOUT))
+ if(memcmp(&i2c_rd_buf[4],&fw_buf[frame_number*PACK_SIZE],check_len))
+ {
+ dev_info(&client->dev, "PACK[%d]:File Data Frame readback check Error!\n",frame_number);
+ i2c_rd_buf[0] = 0x03;
+ ret = gt819_set_regs(client, ADDR_CMD, i2c_rd_buf, 1);
+ if(ret < 0)
+ return ret;
+ check_state = 0x01;
+ }
+ else
+ {
+ dev_info(&client->dev, "PACK[%d]:tell slave check data pass\n",frame_number);
+ i2c_rd_buf[0] = 0x04;
+ ret = gt819_set_regs(client,ADDR_CMD, i2c_rd_buf, 1);
+ if(ret < 0)
+ return ret;
+ dev_info(&client->dev, "PACK[%d]:wait for slave to start next frame\n",frame_number);
+ }
+
+ ret = gt189_wait_for_slave(client, SLAVE_READY);
+ if((ret & CHECKSUM_ERROR) || (ret & FRAME_ERROR) || (ret == ERROR_I2C_TRANSFER) || (ret < 0) || (check_state == 0x01))
+ {
+
+ if(((ret & CHECKSUM_ERROR) || (ret & FRAME_ERROR) || (check_state == 0x01))&&(retries < 5))
+ {
+ if(check_state != 0x01)
+ {
+ printk("checksum error or miss frame error!\n");
+ }
+ check_state = 0x00;
+ retries++;
+ msleep(20);
+ goto resend;
+ }
+ printk("wait slave return state:%d\n", ret);
return ret;
+ }
dev_info(&client->dev, "PACK[%d]:frame transfer finished\n",frame_number);
if(len < PACK_SIZE)
return 0;
{
int ret,file_len,update_need_config;
unsigned char i2c_control_buf[10];
+ char version[17];
+ const char version_base[17]={"GT81XNI"};
dev_info(&client->dev, "gt819 firmware update start...\n");
dev_info(&client->dev, "step 1:read version...\n");
- ret = gt819_read_version(client);
+ ret = gt819_read_version(client,version);
if (ret < 0)
return ret;
dev_info(&client->dev, "done!\n");
msleep(1000);
dev_info(&client->dev, "done!\n");
dev_info(&client->dev, "step 4:wait for slave start...\n");
- ret = gt189_wait_for_slave(client);
+ ret = gt189_wait_for_slave(client, UPDATE_START);
if(ret < 0)
return ret;
if(!(ret & UPDATE_START))
dev_info(&client->dev, "done!\n");
dev_info(&client->dev, "step 5:write the fw length...\n");
file_len = sizeof(gt819_fw) + 4;
+ dev_info(&client->dev, "file length is:%d\n", file_len);
i2c_control_buf[0] = (file_len>>24) & 0xff;
i2c_control_buf[1] = (file_len>>16) & 0xff;
i2c_control_buf[2] = (file_len>>8) & 0xff;
return ret;
dev_info(&client->dev, "done!\n");
dev_info(&client->dev, "step 6:wait for slave ready\n");
- ret = gt189_wait_for_slave(client);
+ ret = gt189_wait_for_slave(client, SLAVE_READY);
if(ret < 0)
return ret;
dev_info(&client->dev, "done!\n");
return ret;
dev_info(&client->dev, "done!\n");
dev_info(&client->dev, "step 9:wait for slave ready\n");
- ret = gt189_wait_for_slave(client);
+ ret = gt189_wait_for_slave(client,SLAVE_READY);
if(ret < 0)
return ret;
if(ret & SLAVE_READY)
dev_info(&client->dev, "step 10:enable irq...\n");
enable_irq(client->irq);
dev_info(&client->dev, "done!\n");
+ msleep(1000); //wait slave reset
dev_info(&client->dev, "step 11:read version...\n");
- ret = gt819_read_version(client);
+ ret = gt819_read_version(client,version);
if (ret < 0)
return ret;
dev_info(&client->dev, "done!\n");
+ version[7] = '\0';
+ if(strcmp(version ,version_base)==0)
+ {
+ sys_sync();
+ msleep(200);
+ kernel_restart(NULL);
+ }
return 0;
}
struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data, work);
uint8_t point_data[53]={ 0 };
int ret,i,offset,points;
+ int points_chect;
int x,y,w;
+ unsigned int count = 0;
+ uint8_t check_sum = 0;
- ret = gt819_read_regs(ts->client,1, point_data, 1);
+ ret = gt819_read_regs(ts->client,1, point_data, 2);
if (ret < 0) {
dev_err(&ts->client->dev, "i2c_read_bytes fail:%d!\n",ret);
+ enable_irq(ts->irq);
return;
}
+ check_sum =point_data[0]+point_data[1];
points = point_data[0] & 0x1f;
//dev_info(&ts->client->dev, "points = %d\n",points);
enable_irq(ts->irq);
dev_info(&ts->client->dev, "touch release\n");
return;
+ }
+ for(i=0;0!=points;)
+ {
+ if(points&0x01)
+ i++;
+ points>>=1;
}
- for(i=0;0!=points;i++)
- points>>=1;
+
points = i;
- ret = gt819_read_regs(ts->client,3, point_data, points*5);
+ points_chect = points;
+ ret = gt819_read_regs(ts->client,3, point_data, points*5+1);
if (ret < 0) {
dev_err(&ts->client->dev, "i2c_read_bytes fail:%d!\n",ret);
+ enable_irq(ts->irq);
return;
}
+ //add by Nitiion
+ for(points_chect *= 5; points_chect > 0; points_chect--)
+ {
+ check_sum += point_data[count++];
+ }
+ check_sum += point_data[count];
+ if(check_sum != 0) //checksum verify error
+ {
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
+ input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
+ //input_mt_sync(data->input_dev);
+ input_sync(ts->input_dev);
+ enable_irq(ts->irq);
+ dev_info(&ts->client->dev, "coor checksum error!touch release\n");
+ return;
+ }
+
for(i=0;i<points;i++){
offset = i*5;
x = (((s16)(point_data[offset+0]))<<8) | ((s16)point_data[offset+1]);
return 0;
}
+static void gt819_early_suspend(struct early_suspend *h)
+{
+ dev_info(&i2c_connect_client->dev, "gt819_early_suspend!\n");
+ gt819_suspend(i2c_connect_client,PMSG_SUSPEND);
+}
+
+static void gt819_early_resume(struct early_suspend *h)
+{
+ dev_info(&i2c_connect_client->dev, "gt819_resume_early!\n");
+ gt819_resume(i2c_connect_client);
+}
/*******************************************************
Description:
remove_proc_entry("goodix-update", NULL);
#endif
//goodix_debug_sysfs_deinit();
- gpio_direction_input(ts->irq_gpio);
- gpio_free(ts->irq_gpio);
- free_irq(client->irq, ts);
+ gpio_direction_input(ts->irq_gpio);
+ gpio_free(ts->irq_gpio);
+ free_irq(client->irq, ts);
if(ts->goodix_wq)
destroy_workqueue(ts->goodix_wq);
dev_notice(&client->dev,"The driver is removing...\n");
i2c_set_clientdata(client, NULL);
input_unregister_device(ts->input_dev);
+ unregister_early_suspend(>819_power);
+ i2c_connect_client = 0;
kfree(ts);
return 0;
}
static int gt819_init_panel(struct goodix_ts_data *ts)
{
int ret,I2cDelay;
+ int len = sizeof(config_info)-1;
uint8_t rd_cfg_buf[10];
+ struct goodix_platform_data *pdata = ts->client->dev.platform_data;
+
+ ret = gt819_set_regs(ts->client, 101, &config_info[1], len);
+ if(ret < 0)
+ {
+ pdata->platform_sleep();
+ msleep(10);
+ pdata->platform_wakeup();
+ msleep(100);
+ printk("First IIC request failed,retry!\n");
+ ret = gt819_set_regs(ts->client, 101, &config_info[1], len);
+ if(ret<0)
+ return ret;
+ }
ret = gt819_read_regs(ts->client, 101, rd_cfg_buf, 10);
if (ret < 0)
static int gt819_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int ret = 0;
+ char version[17];
+ char version_base[17]={"GT81XNI_1R05_18Q"};
struct goodix_ts_data *ts;
struct goodix_platform_data *pdata = client->dev.platform_data;
const char irq_table[4] = {IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_LEVEL_LOW,
IRQ_TYPE_LEVEL_HIGH};
- dev_info(&client->dev,"Install touch driver\n");
+ dev_info(&client->dev,"Install goodix touch driver\n");
if (!pdata) {
dev_err(&client->dev, "platform data is required!\n");
dev_err(&client->dev,"init panel fail,ret = %d\n",ret);
goto err_init_panel_fail;
}
- //gt819_update_fw(client);
+
+ ret = gt819_read_version(client,version);
+ if((ret>=0) && (strcmp(version ,version_base)!=0)){
+ gt819_update_fw(client);
+ }
+
if (!client->irq){
dev_err(&client->dev,"no irq fail\n");
ret = -ENODEV;
ts->goodix_wq = create_workqueue("goodix_wq");
if (!ts->goodix_wq) {
- printk(KERN_ALERT "creat workqueue faiked\n");
+ printk(KERN_ALERT "creat workqueue failed\n");
ret = -ENOMEM;
goto err_create_work_queue_fail;
}
- //INIT_WORK(&ts->work, goodix_ts_work_func);
+
INIT_WORK(&ts->work, gt819_queue_work);
ts->input_dev = input_allocate_device();
}
i2c_set_clientdata(client, ts);
+ gt819_power.suspend = gt819_early_suspend;
+ gt819_power.resume = gt819_early_resume;
+ gt819_power.level = 0x2;
+ register_early_suspend(>819_power);
return 0;
i2c_set_clientdata(client, NULL);
input_unregister_device(ts->input_dev);
static struct i2c_driver gt819_driver = {
.probe = gt819_probe,
.remove = gt819_remove,
- .suspend = gt819_suspend,
- .resume = gt819_resume,
.id_table = gt819_id,
.driver = {
.name = GOODIX_I2C_NAME,