Merge "input: touchscreen: Change dev_pm_ops for Goodix driver"

This commit is contained in:
Linux Build Service Account 2016-09-29 11:20:33 -07:00 committed by Gerrit - the friendly Code Review server
commit 612fafbe3e
5 changed files with 719 additions and 895 deletions

View file

@ -23,16 +23,15 @@
#include "gt9xx.h" #include "gt9xx.h"
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/debugfs.h>
#define DATA_LENGTH_UINT 512 #define DATA_LENGTH_UINT 512
#define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8 *)) #define CMD_HEAD_LENGTH (sizeof(struct st_cmd_head) - sizeof(u8 *))
static char procname[20] = {0}; static char procname[20] = {0};
#define UPDATE_FUNCTIONS struct st_cmd_head {
u8 wr; /* write read flag 0:R 1:W 2:PID 3: */
#pragma pack(1)
struct {
u8 wr; /* write read flag£¬0:R 1:W 2:PID 3: */
u8 flag; /* 0:no need flag/int 1: need flag 2:need int */ u8 flag; /* 0:no need flag/int 1: need flag 2:need int */
u8 flag_addr[2];/* flag address */ u8 flag_addr[2];/* flag address */
u8 flag_val; /* flag val */ u8 flag_val; /* flag val */
@ -46,9 +45,9 @@ struct {
u8 addr[2]; /* address */ u8 addr[2]; /* address */
u8 res[3]; /* reserved */ u8 res[3]; /* reserved */
u8 *data; /* data pointer */ u8 *data; /* data pointer */
} st_cmd_head; } __packed;
#pragma pack()
st_cmd_head cmd_head; static struct st_cmd_head cmd_head;
static struct i2c_client *gt_client; static struct i2c_client *gt_client;
@ -56,15 +55,11 @@ static struct proc_dir_entry *goodix_proc_entry;
static struct mutex lock; static struct mutex lock;
static s32 goodix_tool_write(struct file *filp, const char __user *buff,
unsigned long len, void *data);
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
int *eof, void *data);
static s32 (*tool_i2c_read)(u8 *, u16); static s32 (*tool_i2c_read)(u8 *, u16);
static s32 (*tool_i2c_write)(u8 *, u16); static s32 (*tool_i2c_write)(u8 *, u16);
s32 DATA_LENGTH; s32 data_length;
s8 IC_TYPE[16] = {0}; s8 ic_type[16] = {0};
static void tool_set_proc_name(char *procname) static void tool_set_proc_name(char *procname)
{ {
@ -113,7 +108,7 @@ static s32 tool_i2c_read_no_extra(u8 *buf, u16 len)
} }
if (i == cmd_head.retry) { if (i == cmd_head.retry) {
dev_err(&client->dev, "I2C read retry limit over.\n"); dev_err(&gt_client->dev, "I2C read retry limit over\n");
ret = -EIO; ret = -EIO;
} }
@ -138,7 +133,7 @@ static s32 tool_i2c_write_no_extra(u8 *buf, u16 len)
} }
if (i == cmd_head.retry) { if (i == cmd_head.retry) {
dev_err(&client->dev, "I2C write retry limit over.\n"); dev_err(&gt_client->dev, "I2C write retry limit over\n");
ret = -EIO; ret = -EIO;
} }
@ -173,17 +168,17 @@ static s32 tool_i2c_write_with_extra(u8 *buf, u16 len)
static void register_i2c_func(void) static void register_i2c_func(void)
{ {
if (strcmp(IC_TYPE, "GT8110") && strcmp(IC_TYPE, "GT8105") if (strcmp(ic_type, "GT8110") && strcmp(ic_type, "GT8105")
&& strcmp(IC_TYPE, "GT801") && strcmp(IC_TYPE, "GT800") && strcmp(ic_type, "GT801") && strcmp(ic_type, "GT800")
&& strcmp(IC_TYPE, "GT801PLUS") && strcmp(IC_TYPE, "GT811") && strcmp(ic_type, "GT801PLUS") && strcmp(ic_type, "GT811")
&& strcmp(IC_TYPE, "GTxxx")) { && strcmp(ic_type, "GTxxx")) {
tool_i2c_read = tool_i2c_read_with_extra; tool_i2c_read = tool_i2c_read_with_extra;
tool_i2c_write = tool_i2c_write_with_extra; tool_i2c_write = tool_i2c_write_with_extra;
pr_debug("I2C function: with pre and end cmd!\n"); pr_debug("I2C function: with pre and end cmd\n");
} else { } else {
tool_i2c_read = tool_i2c_read_no_extra; tool_i2c_read = tool_i2c_read_no_extra;
tool_i2c_write = tool_i2c_write_no_extra; tool_i2c_write = tool_i2c_write_no_extra;
pr_info("I2C function: without pre and end cmd!\n"); pr_info("I2C function: without pre and end cmd\n");
} }
} }
@ -191,57 +186,14 @@ static void unregister_i2c_func(void)
{ {
tool_i2c_read = NULL; tool_i2c_read = NULL;
tool_i2c_write = NULL; tool_i2c_write = NULL;
pr_info("I2C function: unregister i2c transfer function!\n"); pr_info("I2C function: unregister i2c transfer function\n");
}
s32 init_wr_node(struct i2c_client *client)
{
u8 i;
gt_client = client;
memset(&cmd_head, 0, sizeof(cmd_head));
cmd_head.data = NULL;
i = 5;
while ((!cmd_head.data) && i) {
cmd_head.data = devm_kzalloc(&client->dev,
i * DATA_LENGTH_UINT, GFP_KERNEL);
if (cmd_head.data)
break;
i--;
}
if (i) {
DATA_LENGTH = i * DATA_LENGTH_UINT;
dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH);
} else {
pr_err("Apply for memory failed.\n");
return FAIL;
}
cmd_head.addr_len = 2;
cmd_head.retry = 5;
register_i2c_func();
mutex_init(&lock);
tool_set_proc_name(procname);
goodix_proc_entry = create_proc_entry(procname, 0660, NULL);
if (goodix_proc_entry == NULL) {
pr_err("Couldn't create proc entry!\n");
return FAIL;
}
GTP_INFO("Create proc entry success!");
goodix_proc_entry->write_proc = goodix_tool_write;
dix_proc_entry->read_proc = goodix_tool_read;
return SUCCESS;
} }
void uninit_wr_node(void) void uninit_wr_node(void)
{ {
cmd_head.data = NULL; cmd_head.data = NULL;
unregister_i2c_func(); unregister_i2c_func();
remove_proc_entry(procname, NULL); proc_remove(goodix_proc_entry);
} }
static u8 relation(u8 src, u8 dst, u8 rlt) static u8 relation(u8 src, u8 dst, u8 rlt)
@ -256,7 +208,7 @@ static u8 relation(u8 src, u8 dst, u8 rlt)
case 1: case 1:
ret = (src == dst) ? true : false; ret = (src == dst) ? true : false;
pr_debug("equal:src:0x%02x dst:0x%02x ret:%d.\n", pr_debug("equal:src:0x%02x dst:0x%02x ret:%d\n",
src, dst, (s32)ret); src, dst, (s32)ret);
break; break;
@ -298,23 +250,18 @@ static u8 comfirm(void)
s32 i = 0; s32 i = 0;
u8 buf[32]; u8 buf[32];
/* memcpy(&buf[GTP_ADDR_LENGTH - cmd_head.addr_len],
* &cmd_head.flag_addr, cmd_head.addr_len);
* memcpy(buf, &cmd_head.flag_addr, cmd_head.addr_len);
* //Modified by Scott, 2012-02-17
*/
memcpy(buf, cmd_head.flag_addr, cmd_head.addr_len); memcpy(buf, cmd_head.flag_addr, cmd_head.addr_len);
for (i = 0; i < cmd_head.times; i++) { for (i = 0; i < cmd_head.times; i++) {
if (tool_i2c_read(buf, 1) <= 0) { if (tool_i2c_read(buf, 1) <= 0) {
pr_err("Read flag data failed!\n"); dev_err(&gt_client->dev, "Read flag data failed");
return FAIL; return FAIL;
} }
if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val, if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val,
cmd_head.flag_relation)) { cmd_head.flag_relation)) {
pr_debug("value at flag addr:0x%02x.\n", pr_debug("value at flag addr:0x%02x\n",
buf[GTP_ADDR_LENGTH]); buf[GTP_ADDR_LENGTH]);
pr_debug("flag value:0x%02x.\n", cmd_head.flag_val); pr_debug("flag value:0x%02x\n", cmd_head.flag_val);
break; break;
} }
@ -322,89 +269,99 @@ static u8 comfirm(void)
} }
if (i >= cmd_head.times) { if (i >= cmd_head.times) {
pr_debug("Didn't get the flag to continue!\n"); dev_err(&gt_client->dev, "Didn't get the flag to continue");
return FAIL; return FAIL;
} }
return SUCCESS; return SUCCESS;
} }
/******************************************************** #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
static s32 fill_update_info(char __user *user_buf,
size_t count, loff_t *ppos)
{
u8 buf[4];
buf[0] = show_len >> 8;
buf[1] = show_len & 0xff;
buf[2] = total_len >> 8;
buf[3] = total_len & 0xff;
return simple_read_from_buffer(user_buf, count, ppos,
buf, sizeof(buf));
}
#else
static s32 fill_update_info(char __user *user_buf,
size_t count, loff_t *ppos)
{
return -ENODEV;
}
#endif
/*
* Function: * Function:
* Goodix tool write function. * Goodix tool write function.
* Input: * Input:
* standard proc write function param. * standard proc write function param.
* Output: * Output:
* Return write length. * Return write length.
*******************************************************
*/ */
static s32 goodix_tool_write(struct file *filp, const char __user *buff, static s32 goodix_tool_write(struct file *filp, const char __user *userbuf,
unsigned long len, void *data) size_t count, loff_t *ppos)
{ {
s32 ret = 0; s32 ret = 0;
mutex_lock(&lock); mutex_lock(&lock);
ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH); ret = copy_from_user(&cmd_head, userbuf, CMD_HEAD_LENGTH);
if (ret) { if (ret) {
pr_err("copy_from_user failed.\n"); dev_err(&gt_client->dev, "copy_from_user failed");
ret = -EACCES; ret = -EFAULT;
goto exit; goto exit;
} }
pr_debug("wr :0x%02x.\n", cmd_head.wr); dev_dbg(&gt_client->dev, "wr:0x%02x, flag:0x%02x, flag addr:0x%02x%02x,
pr_debug("flag:0x%02x.\n", cmd_head.flag); flag val:0x%02x, flag rel:0x%02x,", cmd_headd.wr,
pr_debug("flag addr:0x%02x%02x.\n", cmd_head.flag_addr[0], cmd_head.flag, cmd_head.flag_addr[0],
cmd_head.flag_addr[1]); cmd_head.flag_addr[1], cmd_head.flag_val,
pr_debug("flag val:0x%02x.\n", cmd_head.flag_val); cmd_head.flag_relation);
pr_debug("flag rel:0x%02x.\n", cmd_head.flag_relation); dev_dbg(&gt_client->dev, "circle:%d, times:%d, retry:%d, delay:%d,
pr_debug("circle :%d.\n", (s32)cmd_head.circle); data len:%d, addr len:%d, addr:0x%02x%02x, write len: %d",
pr_debug("times :%d.\n", (s32)cmd_head.times); (s32)cmd_head.circle, (s32)cmd_head.times, (s32)cmd_head.retry,
pr_debug("retry :%d.\n", (s32)cmd_head.retry); (s32)cmd_head.delay, (s32)cmd_head.data_len,
pr_debug("delay :%d.\n", (s32)cmd_head.delay); (s32)cmd_head.addr_len, cmd_head.addr[0], cmd_head.addr[1],
pr_debug("data len:%d.\n", (s32)cmd_head.data_len); (s32)count);
pr_debug("addr len:%d.\n", (s32)cmd_head.addr_len);
pr_debug("addr:0x%02x%02x.\n", cmd_head.addr[0], cmd_head.addr[1]);
pr_debug("len:%d.\n", (s32)len);
pr_debug("buf[20]:0x%02x.\n", buff[CMD_HEAD_LENGTH]);
if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) { if (cmd_head.data_len > (data_length - GTP_ADDR_LENGTH)) {
pr_debug("data len %d > data buff %d, rejected!\n", dev_err(&gt_client->dev, "data len %d > data buff %d, rejected\n",
cmd_head.data_len, (DATA_LENGTH - GTP_ADDR_LENGTH)); cmd_head.data_len, (data_length - GTP_ADDR_LENGTH));
ret = -EINVAL;
goto exit;
}
if (cmd_head.addr_len > GTP_ADDR_LENGTH) {
pr_debug(" addr len %d > data buff %d, rejected!\n",
cmd_head.addr_len, GTP_ADDR_LENGTH);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
if (cmd_head.wr == 1) { if (cmd_head.wr == GTP_RW_WRITE) {
/* copy_from_user(&cmd_head.data[cmd_head.addr_len],
* &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
*/
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
&buff[CMD_HEAD_LENGTH], cmd_head.data_len); &userbuf[CMD_HEAD_LENGTH], cmd_head.data_len);
if (ret) if (ret) {
pr_err("copy_from_user failed.\n"); dev_err(&gt_client->dev, "copy_from_user failed");
ret = -EFAULT;
goto exit;
}
memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], memcpy(&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
cmd_head.addr, cmd_head.addr_len); cmd_head.addr, cmd_head.addr_len);
if (cmd_head.flag == 1) { if (cmd_head.flag == GTP_NEED_FLAG) {
if (comfirm() == FAIL) { if (comfirm() == FAIL) {
pr_err("[WRITE]Comfirm fail!\n"); dev_err(&gt_client->dev, "Confirm fail");
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
} else if (cmd_head.flag == 2) { } else if (cmd_head.flag == GTP_NEED_INTERRUPT) {
/* Need interrupt! */ /* Need interrupt! */
} }
if (tool_i2c_write( if (tool_i2c_write(
&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
cmd_head.data_len + cmd_head.addr_len) <= 0) { cmd_head.data_len + cmd_head.addr_len) <= 0) {
pr_err("[WRITE]Write data failed!\n"); dev_err(&gt_client->dev, "Write data failed");
ret = -EIO; ret = -EIO;
goto exit; goto exit;
} }
@ -414,32 +371,33 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
ret = cmd_head.data_len + CMD_HEAD_LENGTH; ret = cmd_head.data_len + CMD_HEAD_LENGTH;
goto exit; goto exit;
} else if (cmd_head.wr == 3) { /* Write ic type */ } else if (cmd_head.wr == GTP_RW_WRITE_IC_TYPE) { /* Write ic type */
ret = copy_from_user(&cmd_head.data[0],
ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH], &userbuf[CMD_HEAD_LENGTH],
cmd_head.data_len); cmd_head.data_len);
if (ret) if (ret) {
pr_err("copy_from_user failed.\n"); dev_err(&gt_client->dev, "copy_from_user failed");
ret = -EFAULT;
goto exit;
}
if (cmd_head.data_len > sizeof(IC_TYPE)) { if (cmd_head.data_len > sizeof(ic_type)) {
pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n", dev_err(&gt_client->dev,
cmd_head.data_len, sizeof(IC_TYPE)); "data len %d > data buff %d, rejected\n",
cmd_head.data_len, sizeof(ic_type));
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); memcpy(ic_type, cmd_head.data, cmd_head.data_len);
register_i2c_func(); register_i2c_func();
ret = cmd_head.data_len + CMD_HEAD_LENGTH; ret = cmd_head.data_len + CMD_HEAD_LENGTH;
goto exit; goto exit;
} else if (cmd_head.wr == 5) { } else if (cmd_head.wr == GTP_RW_NO_WRITE) {
/* memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); */
ret = cmd_head.data_len + CMD_HEAD_LENGTH; ret = cmd_head.data_len + CMD_HEAD_LENGTH;
goto exit; goto exit;
} else if (cmd_head.wr == 7) { /* disable irq! */ } else if (cmd_head.wr == GTP_RW_DISABLE_IRQ) { /* disable irq! */
gtp_irq_disable(i2c_get_clientdata(gt_client)); gtp_irq_disable(i2c_get_clientdata(gt_client));
#if GTP_ESD_PROTECT #if GTP_ESD_PROTECT
@ -447,7 +405,7 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
#endif #endif
ret = CMD_HEAD_LENGTH; ret = CMD_HEAD_LENGTH;
goto exit; goto exit;
} else if (cmd_head.wr == 9) { /* enable irq! */ } else if (cmd_head.wr == GTP_RW_ENABLE_IRQ) { /* enable irq! */
gtp_irq_enable(i2c_get_clientdata(gt_client)); gtp_irq_enable(i2c_get_clientdata(gt_client));
#if GTP_ESD_PROTECT #if GTP_ESD_PROTECT
@ -455,41 +413,45 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
#endif #endif
ret = CMD_HEAD_LENGTH; ret = CMD_HEAD_LENGTH;
goto exit; goto exit;
} else if (cmd_head.wr == 17) { } else if (cmd_head.wr == GTP_RW_CHECK_RAWDIFF_MODE) {
struct goodix_ts_data *ts = i2c_get_clientdata(gt_client); struct goodix_ts_data *ts = i2c_get_clientdata(gt_client);
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH], ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
&buff[CMD_HEAD_LENGTH], cmd_head.data_len); &userbuf[CMD_HEAD_LENGTH], cmd_head.data_len);
if (ret) if (ret) {
pr_debug("copy_from_user failed.\n"); dev_err(&gt_client->dev, "copy_from_user failed");
goto exit;
}
if (cmd_head.data[GTP_ADDR_LENGTH]) { if (cmd_head.data[GTP_ADDR_LENGTH]) {
pr_debug("gtp enter rawdiff.\n"); pr_debug("gtp enter rawdiff\n");
ts->gtp_rawdiff_mode = true; ts->gtp_rawdiff_mode = true;
} else { } else {
ts->gtp_rawdiff_mode = false; ts->gtp_rawdiff_mode = false;
pr_debug("gtp leave rawdiff.\n"); pr_debug("gtp leave rawdiff\n");
} }
ret = CMD_HEAD_LENGTH; ret = CMD_HEAD_LENGTH;
goto exit; goto exit;
} } else if (cmd_head.wr == GTP_RW_ENTER_UPDATE_MODE) {
#ifdef UPDATE_FUNCTIONS /* Enter update mode! */
else if (cmd_head.wr == 11) { /* Enter update mode! */ if (gup_enter_update_mode(gt_client) == FAIL) {
if (gup_enter_update_mode(gt_client) == FAIL)
ret = -EBUSY; ret = -EBUSY;
goto exit; goto exit;
} else if (cmd_head.wr == 13) { /* Leave update mode! */ }
gup_leave_update_mode(); } else if (cmd_head.wr == GTP_RW_LEAVE_UPDATE_MODE) {
} else if (cmd_head.wr == 15) { /* Update firmware! */ /* Leave update mode! */
gup_leave_update_mode(gt_client);
} else if (cmd_head.wr == GTP_RW_UPDATE_FW) {
/* Update firmware! */
show_len = 0; show_len = 0;
total_len = 0; total_len = 0;
if (cmd_head.data_len + 1 > DATA_LENGTH) { if (cmd_head.data_len + 1 > data_length) {
pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n", dev_err(&gt_client->dev, "data len %d > data buff %d, rejected\n",
cmd_head.data_len + 1, DATA_LENGTH); cmd_head.data_len + 1, data_length);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
memset(cmd_head.data, 0, cmd_head.data_len + 1); memset(cmd_head.data, 0, cmd_head.data_len + 1);
memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH], memcpy(cmd_head.data, &userbuf[CMD_HEAD_LENGTH],
cmd_head.data_len); cmd_head.data_len);
if (gup_update_proc((void *)cmd_head.data) == FAIL) { if (gup_update_proc((void *)cmd_head.data) == FAIL) {
@ -497,7 +459,6 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
goto exit; goto exit;
} }
} }
#endif
ret = CMD_HEAD_LENGTH; ret = CMD_HEAD_LENGTH;
exit: exit:
@ -505,37 +466,37 @@ exit:
return ret; return ret;
} }
/******************************************************* /*
* Function: * Function:
* Goodix tool read function. * Goodix tool read function.
* Input: * Input:
* standard proc read function param. * standard proc read function param.
* Output: * Output:
* Return read length. * Return read length.
******************************************************* */
*/ static s32 goodix_tool_read(struct file *file, char __user *user_buf,
static s32 goodix_tool_read(char *page, char **start, off_t off, int count, size_t count, loff_t *ppos)
int *eof, void *data)
{ {
u16 data_len = 0;
s32 ret; s32 ret;
u8 buf[32];
mutex_lock(&lock); mutex_lock(&lock);
if (cmd_head.wr % 2) { if (cmd_head.wr & 0x1) {
pr_err("<< [READ]command head wrong\n"); dev_err(&gt_client->dev, "command head wrong\n");
ret = -EINVAL;
goto exit;
} else if (!cmd_head.wr) {
u16 len = 0;
s16 data_len = 0;
u16 loc = 0;
if (cmd_head.flag == 1) {
if (comfirm() == FAIL) {
pr_err("[READ]Comfirm fail!\n");
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
} else if (cmd_head.flag == 2) {
switch (cmd_head.wr) {
case GTP_RW_READ:
if (cmd_head.flag == GTP_NEED_FLAG) {
if (comfirm() == FAIL) {
dev_err(&gt_client->dev, "Confirm fail");
ret = -EINVAL;
goto exit;
}
} else if (cmd_head.flag == GTP_NEED_INTERRUPT) {
/* Need interrupt! */ /* Need interrupt! */
} }
@ -550,54 +511,86 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
msleep(cmd_head.delay); msleep(cmd_head.delay);
data_len = cmd_head.data_len; data_len = cmd_head.data_len;
while (data_len > 0) { if (data_len <= 0 || (data_len > data_length)) {
if (data_len > DATA_LENGTH) dev_err(&gt_client->dev, "Invalid data length %d\n",
len = DATA_LENGTH; data_len);
else
len = data_len;
data_len -= len;
if (tool_i2c_read(cmd_head.data, len) <= 0) {
pr_err("[READ]Read data failed!\n");
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], if (data_len > count)
len); data_len = count;
loc += len;
}
} else if (cmd_head.wr == 2) {
/* memcpy(page, "gt8", cmd_head.data_len);
* memcpy(page, "GT818", 5);
* page[5] = 0;
*/
pr_debug("Return ic type:%s len:%d.\n", page, if (tool_i2c_read(cmd_head.data, data_len) <= 0) {
(s32)cmd_head.data_len); dev_err(&gt_client->dev, "Read data failed\n");
ret = cmd_head.data_len; ret = -EIO;
goto exit; goto exit;
/* return sizeof(IC_TYPE_NAME); */
} else if (cmd_head.wr == 4) {
page[0] = show_len >> 8;
page[1] = show_len & 0xff;
page[2] = total_len >> 8;
page[3] = total_len & 0xff;
} else if (cmd_head.wr == 6) {
/* Read error code! */
} else if (cmd_head.wr == 8) { /*Read driver version */
/* memcpy(page, GTP_DRIVER_VERSION,
* strlen(GTP_DRIVER_VERSION));
*/
s32 tmp_len;
tmp_len = strlen(GTP_DRIVER_VERSION);
memcpy(page, GTP_DRIVER_VERSION, tmp_len);
page[tmp_len] = 0;
} }
ret = cmd_head.data_len; ret = simple_read_from_buffer(user_buf, count, ppos,
&cmd_head.data[GTP_ADDR_LENGTH], data_len);
break;
case GTP_RW_FILL_INFO:
ret = fill_update_info(user_buf, count, ppos);
break;
case GTP_RW_READ_VERSION:
/* Read driver version */
data_len = scnprintf(buf, sizeof(buf), "%s\n",
GTP_DRIVER_VERSION);
ret = simple_read_from_buffer(user_buf, count, ppos,
buf, data_len);
break;
default:
ret = -EINVAL;
break;
}
exit: exit:
mutex_unlock(&lock); mutex_unlock(&lock);
return ret; return ret;
} }
static const struct file_operations goodix_proc_fops = {
.write = goodix_tool_write,
.read = goodix_tool_read,
.open = simple_open,
.owner = THIS_MODULE,
};
s32 init_wr_node(struct i2c_client *client)
{
u8 i;
gt_client = client;
memset(&cmd_head, 0, sizeof(cmd_head));
cmd_head.data = NULL;
i = GTP_I2C_RETRY_5;
while ((!cmd_head.data) && i) {
cmd_head.data = devm_kzalloc(&client->dev,
i * DATA_LENGTH_UINT, GFP_KERNEL);
if (cmd_head.data)
break;
i--;
}
if (i) {
data_length = i * DATA_LENGTH_UINT;
dev_dbg(&client->dev, "Applied memory size:%d", data_length);
}
cmd_head.addr_len = 2;
cmd_head.retry = GTP_I2C_RETRY_5;
register_i2c_func();
mutex_init(&lock);
tool_set_proc_name(procname);
goodix_proc_entry = proc_create(procname,
S_IWUSR | S_IWGRP | S_IRUSR | S_IRGRP,
goodix_proc_entry,
&goodix_proc_fops);
if (goodix_proc_entry == NULL) {
dev_err(&client->dev, "Couldn't create proc entry");
return FAIL;
}
return SUCCESS;
}

View file

@ -44,18 +44,16 @@
#include "gt9xx.h" #include "gt9xx.h"
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/debugfs.h>
#define GOODIX_DEV_NAME "Goodix-CTP" #define GOODIX_DEV_NAME "Goodix-CTP"
#define CFG_MAX_TOUCH_POINTS 5 #define CFG_MAX_TOUCH_POINTS 5
#define GOODIX_COORDS_ARR_SIZE 4 #define GOODIX_COORDS_ARR_SIZE 4
#define MAX_BUTTONS 4 #define MAX_BUTTONS 4
/* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
#define GTP_I2C_ADDRESS_HIGH 0x14
#define GTP_I2C_ADDRESS_LOW 0x5D
#define GOODIX_VTG_MIN_UV 2600000 #define GOODIX_VTG_MIN_UV 2600000
#define GOODIX_VTG_MAX_UV 3300000 #define GOODIX_VTG_MAX_UV 3300000
#define GOODIX_I2C_VTG_MIN_UV 1800000 #define GOODIX_I2C_VTG_MIN_UV 1800000
@ -79,7 +77,6 @@ static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK};
#endif #endif
static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms);
static void gtp_int_sync(struct goodix_ts_data *ts, int ms); static void gtp_int_sync(struct goodix_ts_data *ts, int ms);
static int gtp_i2c_test(struct i2c_client *client); static int gtp_i2c_test(struct i2c_client *client);
static int goodix_power_off(struct goodix_ts_data *ts); static int goodix_power_off(struct goodix_ts_data *ts);
@ -88,6 +85,8 @@ static int goodix_power_on(struct goodix_ts_data *ts);
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
static int fb_notifier_callback(struct notifier_block *self, static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data); unsigned long event, void *data);
static int goodix_ts_suspend(struct device *dev);
static int goodix_ts_resume(struct device *dev);
#elif defined(CONFIG_HAS_EARLYSUSPEND) #elif defined(CONFIG_HAS_EARLYSUSPEND)
static void goodix_ts_early_suspend(struct early_suspend *h); static void goodix_ts_early_suspend(struct early_suspend *h);
static void goodix_ts_late_resume(struct early_suspend *h); static void goodix_ts_late_resume(struct early_suspend *h);
@ -98,7 +97,6 @@ static struct delayed_work gtp_esd_check_work;
static struct workqueue_struct *gtp_esd_check_workqueue; static struct workqueue_struct *gtp_esd_check_workqueue;
static void gtp_esd_check_func(struct work_struct *work); static void gtp_esd_check_func(struct work_struct *work);
static int gtp_init_ext_watchdog(struct i2c_client *client); static int gtp_init_ext_watchdog(struct i2c_client *client);
struct i2c_client *i2c_connect_client;
#endif #endif
#if GTP_SLIDE_WAKEUP #if GTP_SLIDE_WAKEUP
@ -113,6 +111,10 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts);
bool init_done; bool init_done;
static u8 chip_gt9xxs; /* true if ic is gt9xxs, like gt915s */ static u8 chip_gt9xxs; /* true if ic is gt9xxs, like gt915s */
u8 grp_cfg_version; u8 grp_cfg_version;
struct i2c_client *i2c_connect_client;
#define GTP_DEBUGFS_DIR "ts_debug"
#define GTP_DEBUGFS_FILE_SUSPEND "suspend"
/******************************************************* /*******************************************************
Function: Function:
@ -264,7 +266,7 @@ Output:
result of i2c write operation. result of i2c write operation.
> 0: succeed, otherwise: failed > 0: succeed, otherwise: failed
*********************************************************/ *********************************************************/
static int gtp_send_cfg(struct goodix_ts_data *ts) int gtp_send_cfg(struct goodix_ts_data *ts)
{ {
int ret; int ret;
#if GTP_DRIVER_SEND_CFG #if GTP_DRIVER_SEND_CFG
@ -593,26 +595,6 @@ exit_work_func:
return; return;
} }
/*******************************************************
Function:
Timer interrupt service routine for polling mode.
Input:
timer: timer struct pointer
Output:
Timer work mode.
HRTIMER_NORESTART: no restart mode
*********************************************************/
static enum hrtimer_restart goodix_ts_timer_handler(struct hrtimer *timer)
{
struct goodix_ts_data
*ts = container_of(timer, struct goodix_ts_data, timer);
queue_work(ts->goodix_wq, &ts->work);
hrtimer_start(&ts->timer, ktime_set(0, (GTP_POLL_TIME + 6) * 1000000),
HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
/******************************************************* /*******************************************************
Function: Function:
External interrupt service routine for interrupt mode. External interrupt service routine for interrupt mode.
@ -656,7 +638,7 @@ Input:
Output: Output:
None. None.
*******************************************************/ *******************************************************/
static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms) void gtp_reset_guitar(struct goodix_ts_data *ts, int ms)
{ {
/* This reset sequence will selcet I2C slave address */ /* This reset sequence will selcet I2C slave address */
gpio_direction_output(ts->pdata->reset_gpio, 0); gpio_direction_output(ts->pdata->reset_gpio, 0);
@ -730,16 +712,13 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts)
return ret; return ret;
} }
#else #else
/******************************************************* /**
Function: * gtp_enter_sleep - Enter sleep mode
Enter sleep mode. * @ts: driver private data
Input: *
ts: private data. * Returns zero on success, else an error.
Output: */
Executive outcomes. static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
>0: succeed, otherwise failed.
*******************************************************/
static s8 gtp_enter_sleep(struct goodix_ts_data *ts)
{ {
int ret = -1; int ret = -1;
s8 retry = 0; s8 retry = 0;
@ -761,16 +740,16 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts)
ret = goodix_power_off(ts); ret = goodix_power_off(ts);
if (ret) { if (ret) {
dev_err(&ts->client->dev, "GTP power off failed.\n"); dev_err(&ts->client->dev, "GTP power off failed.\n");
return 0; return ret;
} }
return 1; return 0;
} }
usleep(5000); usleep(5000);
while (retry++ < GTP_I2C_RETRY_5) { while (retry++ < GTP_I2C_RETRY_5) {
ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); ret = gtp_i2c_write(ts->client, i2c_control_buf, 3);
if (ret == 1) { if (ret == 1) {
dev_dbg(&ts->client->dev, "GTP enter sleep!"); dev_dbg(&ts->client->dev, "GTP enter sleep!");
return ret; return 0;
} }
msleep(20); msleep(20);
} }
@ -1196,19 +1175,14 @@ static int gtp_request_irq(struct goodix_ts_data *ts)
int ret; int ret;
const u8 irq_table[] = GTP_IRQ_TAB; const u8 irq_table[] = GTP_IRQ_TAB;
ret = request_irq(ts->client->irq, goodix_ts_irq_handler, GTP_DEBUG("INT trigger type:%x, irq=%d", ts->int_trigger_type,
ts->client->irq);
ret = request_threaded_irq(ts->client->irq, NULL,
goodix_ts_irq_handler,
irq_table[ts->int_trigger_type], irq_table[ts->int_trigger_type],
ts->client->name, ts); ts->client->name, ts);
if (ret) { if (ret) {
dev_err(&ts->client->dev, "Request IRQ failed!ERRNO:%d.\n",
ret);
gpio_direction_input(ts->pdata->irq_gpio);
hrtimer_init(&ts->timer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL);
ts->timer.function = goodix_ts_timer_handler;
hrtimer_start(&ts->timer, ktime_set(1, 0),
HRTIMER_MODE_REL);
ts->use_irq = false; ts->use_irq = false;
return ret; return ret;
} }
@ -1560,6 +1534,56 @@ static const struct attribute_group gtp_attr_grp = {
.attrs = gtp_attrs, .attrs = gtp_attrs,
}; };
static int gtp_debug_suspend_set(void *_data, u64 val)
{
struct goodix_ts_data *ts = _data;
mutex_lock(&ts->input_dev->mutex);
if (val)
goodix_ts_suspend(&ts->client->dev);
else
goodix_ts_resume(&ts->client->dev);
mutex_unlock(&ts->input_dev->mutex);
return 0;
}
static int gtp_debug_suspend_get(void *_data, u64 *val)
{
struct goodix_ts_data *ts = _data;
mutex_lock(&ts->input_dev->mutex);
*val = ts->gtp_is_suspend;
mutex_unlock(&ts->input_dev->mutex);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, gtp_debug_suspend_get,
gtp_debug_suspend_set, "%lld\n");
static int gtp_debugfs_init(struct goodix_ts_data *data)
{
data->debug_base = debugfs_create_dir(GTP_DEBUGFS_DIR, NULL);
if (IS_ERR_OR_NULL(data->debug_base)) {
pr_err("Failed to create debugfs dir\n");
return -EINVAL;
}
if ((IS_ERR_OR_NULL(debugfs_create_file(GTP_DEBUGFS_FILE_SUSPEND,
S_IWUSR | S_IWGRP | S_IRUSR | S_IRGRP,
data->debug_base,
data,
&debug_suspend_fops)))) {
pr_err("Failed to create suspend file\n");
debugfs_remove_recursive(data->debug_base);
return -EINVAL;
}
return 0;
}
static int goodix_ts_get_dt_coords(struct device *dev, char *name, static int goodix_ts_get_dt_coords(struct device *dev, char *name,
struct goodix_ts_platform_data *pdata) struct goodix_ts_platform_data *pdata)
{ {
@ -1694,7 +1718,7 @@ static int goodix_parse_dt(struct device *dev,
prop->value, pdata->config_data_len[i]); prop->value, pdata->config_data_len[i]);
read_cfg_num++; read_cfg_num++;
} }
dev_dbg(dev, "%d config data read from device tree.\n", read_cfg_num); dev_dbg(dev, "%d config data read from device tree\n", read_cfg_num);
return 0; return 0;
} }
@ -1783,7 +1807,7 @@ static int goodix_ts_probe(struct i2c_client *client,
ret = gtp_i2c_test(client); ret = gtp_i2c_test(client);
if (ret != 2) { if (ret != 2) {
dev_err(&client->dev, "I2C communication ERROR!\n"); dev_err(&client->dev, "I2C communication ERROR\n");
goto exit_power_off; goto exit_power_off;
} }
@ -1791,7 +1815,7 @@ static int goodix_ts_probe(struct i2c_client *client,
strlcpy(ts->fw_name, pdata->fw_name, strlcpy(ts->fw_name, pdata->fw_name,
strlen(pdata->fw_name) + 1); strlen(pdata->fw_name) + 1);
#if GTP_AUTO_UPDATE #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
ret = gup_init_update_proc(ts); ret = gup_init_update_proc(ts);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, dev_err(&client->dev,
@ -1834,24 +1858,24 @@ static int goodix_ts_probe(struct i2c_client *client,
INIT_WORK(&ts->work, goodix_ts_work_func); INIT_WORK(&ts->work, goodix_ts_work_func);
ret = gtp_request_irq(ts); ret = gtp_request_irq(ts);
if (ret < 0) if (ret)
dev_info(&client->dev, "GTP works in polling mode.\n"); dev_info(&client->dev, "GTP request irq failed %d\n", ret);
else else
dev_info(&client->dev, "GTP works in interrupt mode.\n"); dev_info(&client->dev, "GTP works in interrupt mode\n");
ret = gtp_read_fw_version(client, &version_info); ret = gtp_read_fw_version(client, &version_info);
if (ret != 2) if (ret != 2)
dev_err(&client->dev, "GTP firmware version read failed.\n"); dev_err(&client->dev, "GTP firmware version read failed\n");
ret = gtp_check_product_id(client); ret = gtp_check_product_id(client);
if (ret != 0) { if (ret != 0) {
dev_err(&client->dev, "GTP Product id doesn't match.\n"); dev_err(&client->dev, "GTP Product id doesn't match\n");
goto exit_free_irq; goto exit_free_irq;
} }
if (ts->use_irq) if (ts->use_irq)
gtp_irq_enable(ts); gtp_irq_enable(ts);
#if GTP_CREATE_WR_NODE #ifdef CONFIG_GT9XX_TOUCHPANEL_DEBUG
init_wr_node(client); init_wr_node(client);
#endif #endif
@ -1860,10 +1884,14 @@ static int goodix_ts_probe(struct i2c_client *client,
#endif #endif
ret = sysfs_create_group(&client->dev.kobj, &gtp_attr_grp); ret = sysfs_create_group(&client->dev.kobj, &gtp_attr_grp);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "sys file creation failed.\n"); dev_err(&client->dev, "sys file creation failed\n");
goto exit_free_irq; goto exit_free_irq;
} }
ret = gtp_debugfs_init(ts);
if (ret != 0)
goto exit_remove_sysfs;
init_done = true; init_done = true;
return 0; return 0;
exit_free_irq: exit_free_irq:
@ -1871,7 +1899,7 @@ exit_free_irq:
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
if (fb_unregister_client(&ts->fb_notif)) if (fb_unregister_client(&ts->fb_notif))
dev_err(&client->dev, dev_err(&client->dev,
"Error occurred while unregistering fb_notifier.\n"); "Error occurred while unregistering fb_notifier\n");
#elif defined(CONFIG_HAS_EARLYSUSPEND) #elif defined(CONFIG_HAS_EARLYSUSPEND)
unregister_early_suspend(&ts->early_suspend); unregister_early_suspend(&ts->early_suspend);
#endif #endif
@ -1888,6 +1916,8 @@ exit_free_irq:
input_free_device(ts->input_dev); input_free_device(ts->input_dev);
ts->input_dev = NULL; ts->input_dev = NULL;
} }
exit_remove_sysfs:
sysfs_remove_group(&ts->input_dev->dev.kobj, &gtp_attr_grp);
exit_free_inputdev: exit_free_inputdev:
kfree(ts->config_data); kfree(ts->config_data);
exit_power_off: exit_power_off:
@ -1921,13 +1951,13 @@ static int goodix_ts_remove(struct i2c_client *client)
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
if (fb_unregister_client(&ts->fb_notif)) if (fb_unregister_client(&ts->fb_notif))
dev_err(&client->dev, dev_err(&client->dev,
"Error occurred while unregistering fb_notifier.\n"); "Error occurred while unregistering fb_notifier\n");
#elif defined(CONFIG_HAS_EARLYSUSPEND) #elif defined(CONFIG_HAS_EARLYSUSPEND)
unregister_early_suspend(&ts->early_suspend); unregister_early_suspend(&ts->early_suspend);
#endif #endif
mutex_destroy(&ts->lock); mutex_destroy(&ts->lock);
#if GTP_CREATE_WR_NODE #ifdef CONFIG_GT9XX_TOUCHPANEL_DEBUG
uninit_wr_node(); uninit_wr_node();
#endif #endif
@ -1962,6 +1992,7 @@ static int goodix_ts_remove(struct i2c_client *client)
goodix_power_deinit(ts); goodix_power_deinit(ts);
i2c_set_clientdata(client, NULL); i2c_set_clientdata(client, NULL);
} }
debugfs_remove_recursive(ts->debug_base);
return 0; return 0;
} }
@ -1980,9 +2011,13 @@ static int goodix_ts_suspend(struct device *dev)
struct goodix_ts_data *ts = dev_get_drvdata(dev); struct goodix_ts_data *ts = dev_get_drvdata(dev);
int ret = 0, i; int ret = 0, i;
if (ts->gtp_is_suspend) {
dev_dbg(&ts->client->dev, "Already in suspend state\n");
return 0;
}
mutex_lock(&ts->lock); mutex_lock(&ts->lock);
#if GTP_ESD_PROTECT #if GTP_ESD_PROTECT
ts->gtp_is_suspend = 1;
gtp_esd_switch(ts->client, SWITCH_OFF); gtp_esd_switch(ts->client, SWITCH_OFF);
#endif #endif
@ -2001,13 +2036,14 @@ static int goodix_ts_suspend(struct device *dev)
ret = gtp_enter_sleep(ts); ret = gtp_enter_sleep(ts);
#endif #endif
if (ret <= 0) if (ret < 0)
dev_err(&ts->client->dev, "GTP early suspend failed.\n"); dev_err(&ts->client->dev, "GTP early suspend failed\n");
/* to avoid waking up while not sleeping, /* to avoid waking up while not sleeping,
* delay 48 + 10ms to ensure reliability * delay 48 + 10ms to ensure reliability
*/ */
msleep(58); msleep(58);
mutex_unlock(&ts->lock); mutex_unlock(&ts->lock);
ts->gtp_is_suspend = 1;
return ret; return ret;
} }
@ -2025,6 +2061,11 @@ static int goodix_ts_resume(struct device *dev)
struct goodix_ts_data *ts = dev_get_drvdata(dev); struct goodix_ts_data *ts = dev_get_drvdata(dev);
int ret = 0; int ret = 0;
if (!ts->gtp_is_suspend) {
dev_dbg(&ts->client->dev, "Already in awake state\n");
return 0;
}
mutex_lock(&ts->lock); mutex_lock(&ts->lock);
ret = gtp_wakeup_sleep(ts); ret = gtp_wakeup_sleep(ts);
@ -2033,7 +2074,7 @@ static int goodix_ts_resume(struct device *dev)
#endif #endif
if (ret <= 0) if (ret <= 0)
dev_err(&ts->client->dev, "GTP resume failed.\n"); dev_err(&ts->client->dev, "GTP resume failed\n");
if (ts->use_irq) if (ts->use_irq)
gtp_irq_enable(ts); gtp_irq_enable(ts);
@ -2042,10 +2083,10 @@ static int goodix_ts_resume(struct device *dev)
ktime_set(1, 0), HRTIMER_MODE_REL); ktime_set(1, 0), HRTIMER_MODE_REL);
#if GTP_ESD_PROTECT #if GTP_ESD_PROTECT
ts->gtp_is_suspend = 0;
gtp_esd_switch(ts->client, SWITCH_ON); gtp_esd_switch(ts->client, SWITCH_ON);
#endif #endif
mutex_unlock(&ts->lock); mutex_unlock(&ts->lock);
ts->gtp_is_suspend = 0;
return ret; return ret;
} }
@ -2236,8 +2277,15 @@ static void gtp_esd_check_func(struct work_struct *work)
} }
#endif #endif
static SIMPLE_DEV_PM_OPS(goodix_ts_dev_pm_ops, goodix_ts_suspend, #if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
goodix_ts_resume); static const struct dev_pm_ops goodix_ts_dev_pm_ops = {
.suspend = goodix_ts_suspend,
.resume = goodix_ts_resume,
};
#else
static const struct dev_pm_ops goodix_ts_dev_pm_ops = {
};
#endif
static const struct i2c_device_id goodix_ts_id[] = { static const struct i2c_device_id goodix_ts_id[] = {
{ GTP_I2C_NAME, 0 }, { GTP_I2C_NAME, 0 },

View file

@ -22,18 +22,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/uaccess.h>
#include <linux/firmware.h>
#include <linux/debugfs.h>
#include <linux/mutex.h>
#if defined(CONFIG_FB) #if defined(CONFIG_FB)
#include <linux/notifier.h> #include <linux/notifier.h>
@ -105,6 +96,7 @@ struct goodix_ts_data {
#elif defined(CONFIG_HAS_EARLYSUSPEND) #elif defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend; struct early_suspend early_suspend;
#endif #endif
struct dentry *debug_base;
}; };
extern u16 show_len; extern u16 show_len;
@ -116,14 +108,6 @@ extern u16 total_len;
#define GTP_DRIVER_SEND_CFG 1 #define GTP_DRIVER_SEND_CFG 1
#define GTP_HAVE_TOUCH_KEY 1 #define GTP_HAVE_TOUCH_KEY 1
/* auto updated by .bin file as default */
#define GTP_AUTO_UPDATE 0
/* auto updated by head_fw_array in gt9xx_firmware.h,
* function together with GTP_AUTO_UPDATE
*/
#define GTP_HEADER_FW_UPDATE 0
#define GTP_CREATE_WR_NODE 0
#define GTP_ESD_PROTECT 0 #define GTP_ESD_PROTECT 0
#define GTP_WITH_PEN 0 #define GTP_WITH_PEN 0
@ -132,18 +116,6 @@ extern u16 total_len;
/* double-click wakeup, function together with GTP_SLIDE_WAKEUP */ /* double-click wakeup, function together with GTP_SLIDE_WAKEUP */
#define GTP_DBL_CLK_WAKEUP 0 #define GTP_DBL_CLK_WAKEUP 0
/*************************** PART2:TODO define *******************************/
/* STEP_1(REQUIRED): Define Configuration Information Group(s) */
/* Sensor_ID Map: */
/* sensor_opt1 sensor_opt2 Sensor_ID
* GND GND 0
* VDDIO GND 1
* NC GND 2
* GND NC/300K 3
* VDDIO NC/300K 4
* NC NC/300K 5
*/
#define GTP_IRQ_TAB {\ #define GTP_IRQ_TAB {\
IRQ_TYPE_EDGE_RISING,\ IRQ_TYPE_EDGE_RISING,\
IRQ_TYPE_EDGE_FALLING,\ IRQ_TYPE_EDGE_FALLING,\
@ -151,7 +123,7 @@ extern u16 total_len;
IRQ_TYPE_LEVEL_HIGH\ IRQ_TYPE_LEVEL_HIGH\
} }
/* STEP_3(optional): Specify your special config info if needed */
#define GTP_IRQ_TAB_RISING 0 #define GTP_IRQ_TAB_RISING 0
#define GTP_IRQ_TAB_FALLING 1 #define GTP_IRQ_TAB_FALLING 1
#if GTP_CUSTOM_CFG #if GTP_CUSTOM_CFG
@ -197,16 +169,52 @@ extern u16 total_len;
#define RESOLUTION_LOC 3 #define RESOLUTION_LOC 3
#define TRIGGER_LOC 8 #define TRIGGER_LOC 8
/* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
#define GTP_I2C_ADDRESS_HIGH 0x14
#define GTP_I2C_ADDRESS_LOW 0x5D
/* GTP CM_HEAD RW flags */
#define GTP_RW_READ 0
#define GTP_RW_WRITE 1
#define GTP_RW_READ_IC_TYPE 2
#define GTP_RW_WRITE_IC_TYPE 3
#define GTP_RW_FILL_INFO 4
#define GTP_RW_NO_WRITE 5
#define GTP_RW_READ_ERROR 6
#define GTP_RW_DISABLE_IRQ 7
#define GTP_RW_READ_VERSION 8
#define GTP_RW_ENABLE_IRQ 9
#define GTP_RW_ENTER_UPDATE_MODE 11
#define GTP_RW_LEAVE_UPDATE_MODE 13
#define GTP_RW_UPDATE_FW 15
#define GTP_RW_CHECK_RAWDIFF_MODE 17
/* GTP need flag or interrupt */
#define GTP_NO_NEED 0
#define GTP_NEED_FLAG 1
#define GTP_NEED_INTERRUPT 2
/*****************************End of Part III********************************/ /*****************************End of Part III********************************/
void gtp_esd_switch(struct i2c_client *client, int on); void gtp_esd_switch(struct i2c_client *client, int on);
#if GTP_CREATE_WR_NODE int gtp_i2c_read_dbl_check(struct i2c_client *client, u16 addr,
extern s32 init_wr_node(struct i2c_client *client); u8 *rxbuf, int len);
extern void uninit_wr_node(void); int gtp_send_cfg(struct goodix_ts_data *ts);
void gtp_reset_guitar(struct goodix_ts_data *ts, int ms);
void gtp_irq_disable(struct goodix_ts_data *ts);
void gtp_irq_enable(struct goodix_ts_data *ts);
#ifdef CONFIG_GT9XX_TOUCHPANEL_DEBUG
s32 init_wr_node(struct i2c_client *client);
void uninit_wr_node(void);
#endif #endif
#if GTP_AUTO_UPDATE #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
extern u8 gup_init_update_proc(struct goodix_ts_data *ts); extern u8 gup_init_update_proc(struct goodix_ts_data *ts);
s32 gup_enter_update_mode(struct i2c_client *client);
void gup_leave_update_mode(struct i2c_client *client);
s32 gup_update_proc(void *dir);
extern struct i2c_client *i2c_connect_client;
#endif #endif
#endif /* _GOODIX_GT9XX_H_ */ #endif /* _GOODIX_GT9XX_H_ */

View file

@ -1,6 +0,0 @@
/*
* make sense only when GTP_HEADER_FW_UPDATE & GTP_AUTO_UPDATE are enabled
* define your own firmware array here
*/
const unsigned char header_fw_array[] = {
};

File diff suppressed because it is too large Load diff