Merge "input: touchscreen: Change dev_pm_ops for Goodix driver"
This commit is contained in:
commit
612fafbe3e
5 changed files with 719 additions and 895 deletions
|
@ -23,16 +23,15 @@
|
|||
|
||||
#include "gt9xx.h"
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#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};
|
||||
|
||||
#define UPDATE_FUNCTIONS
|
||||
|
||||
#pragma pack(1)
|
||||
struct {
|
||||
u8 wr; /* write read flag£¬0:R 1:W 2:PID 3: */
|
||||
struct st_cmd_head {
|
||||
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_addr[2];/* flag address */
|
||||
u8 flag_val; /* flag val */
|
||||
|
@ -46,9 +45,9 @@ struct {
|
|||
u8 addr[2]; /* address */
|
||||
u8 res[3]; /* reserved */
|
||||
u8 *data; /* data pointer */
|
||||
} st_cmd_head;
|
||||
#pragma pack()
|
||||
st_cmd_head cmd_head;
|
||||
} __packed;
|
||||
|
||||
static struct st_cmd_head cmd_head;
|
||||
|
||||
static struct i2c_client *gt_client;
|
||||
|
||||
|
@ -56,15 +55,11 @@ static struct proc_dir_entry *goodix_proc_entry;
|
|||
|
||||
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_write)(u8 *, u16);
|
||||
|
||||
s32 DATA_LENGTH;
|
||||
s8 IC_TYPE[16] = {0};
|
||||
s32 data_length;
|
||||
s8 ic_type[16] = {0};
|
||||
|
||||
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) {
|
||||
dev_err(&client->dev, "I2C read retry limit over.\n");
|
||||
dev_err(>_client->dev, "I2C read retry limit over\n");
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
|
@ -138,7 +133,7 @@ static s32 tool_i2c_write_no_extra(u8 *buf, u16 len)
|
|||
}
|
||||
|
||||
if (i == cmd_head.retry) {
|
||||
dev_err(&client->dev, "I2C write retry limit over.\n");
|
||||
dev_err(>_client->dev, "I2C write retry limit over\n");
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
|
@ -173,17 +168,17 @@ static s32 tool_i2c_write_with_extra(u8 *buf, u16 len)
|
|||
|
||||
static void register_i2c_func(void)
|
||||
{
|
||||
if (strcmp(IC_TYPE, "GT8110") && strcmp(IC_TYPE, "GT8105")
|
||||
&& strcmp(IC_TYPE, "GT801") && strcmp(IC_TYPE, "GT800")
|
||||
&& strcmp(IC_TYPE, "GT801PLUS") && strcmp(IC_TYPE, "GT811")
|
||||
&& strcmp(IC_TYPE, "GTxxx")) {
|
||||
if (strcmp(ic_type, "GT8110") && strcmp(ic_type, "GT8105")
|
||||
&& strcmp(ic_type, "GT801") && strcmp(ic_type, "GT800")
|
||||
&& strcmp(ic_type, "GT801PLUS") && strcmp(ic_type, "GT811")
|
||||
&& strcmp(ic_type, "GTxxx")) {
|
||||
tool_i2c_read = tool_i2c_read_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 {
|
||||
tool_i2c_read = tool_i2c_read_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_write = NULL;
|
||||
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;
|
||||
pr_info("I2C function: unregister i2c transfer function\n");
|
||||
}
|
||||
|
||||
void uninit_wr_node(void)
|
||||
{
|
||||
cmd_head.data = NULL;
|
||||
unregister_i2c_func();
|
||||
remove_proc_entry(procname, NULL);
|
||||
proc_remove(goodix_proc_entry);
|
||||
}
|
||||
|
||||
static u8 relation(u8 src, u8 dst, u8 rlt)
|
||||
|
@ -256,7 +208,7 @@ static u8 relation(u8 src, u8 dst, u8 rlt)
|
|||
|
||||
case 1:
|
||||
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);
|
||||
break;
|
||||
|
||||
|
@ -298,23 +250,18 @@ static u8 comfirm(void)
|
|||
s32 i = 0;
|
||||
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);
|
||||
|
||||
for (i = 0; i < cmd_head.times; i++) {
|
||||
if (tool_i2c_read(buf, 1) <= 0) {
|
||||
pr_err("Read flag data failed!\n");
|
||||
dev_err(>_client->dev, "Read flag data failed");
|
||||
return FAIL;
|
||||
}
|
||||
if (true == relation(buf[GTP_ADDR_LENGTH], cmd_head.flag_val,
|
||||
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]);
|
||||
pr_debug("flag value:0x%02x.\n", cmd_head.flag_val);
|
||||
pr_debug("flag value:0x%02x\n", cmd_head.flag_val);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -322,89 +269,99 @@ static u8 comfirm(void)
|
|||
}
|
||||
|
||||
if (i >= cmd_head.times) {
|
||||
pr_debug("Didn't get the flag to continue!\n");
|
||||
dev_err(>_client->dev, "Didn't get the flag to continue");
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
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:
|
||||
* Goodix tool write function.
|
||||
* Input:
|
||||
* standard proc write function param.
|
||||
* Output:
|
||||
* Return write length.
|
||||
*******************************************************
|
||||
*/
|
||||
static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
unsigned long len, void *data)
|
||||
static s32 goodix_tool_write(struct file *filp, const char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
s32 ret = 0;
|
||||
|
||||
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) {
|
||||
pr_err("copy_from_user failed.\n");
|
||||
ret = -EACCES;
|
||||
dev_err(>_client->dev, "copy_from_user failed");
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pr_debug("wr :0x%02x.\n", cmd_head.wr);
|
||||
pr_debug("flag:0x%02x.\n", cmd_head.flag);
|
||||
pr_debug("flag addr:0x%02x%02x.\n", cmd_head.flag_addr[0],
|
||||
cmd_head.flag_addr[1]);
|
||||
pr_debug("flag val:0x%02x.\n", cmd_head.flag_val);
|
||||
pr_debug("flag rel:0x%02x.\n", cmd_head.flag_relation);
|
||||
pr_debug("circle :%d.\n", (s32)cmd_head.circle);
|
||||
pr_debug("times :%d.\n", (s32)cmd_head.times);
|
||||
pr_debug("retry :%d.\n", (s32)cmd_head.retry);
|
||||
pr_debug("delay :%d.\n", (s32)cmd_head.delay);
|
||||
pr_debug("data len:%d.\n", (s32)cmd_head.data_len);
|
||||
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]);
|
||||
dev_dbg(>_client->dev, "wr:0x%02x, flag:0x%02x, flag addr:0x%02x%02x,
|
||||
flag val:0x%02x, flag rel:0x%02x,", cmd_headd.wr,
|
||||
cmd_head.flag, cmd_head.flag_addr[0],
|
||||
cmd_head.flag_addr[1], cmd_head.flag_val,
|
||||
cmd_head.flag_relation);
|
||||
dev_dbg(>_client->dev, "circle:%d, times:%d, retry:%d, delay:%d,
|
||||
data len:%d, addr len:%d, addr:0x%02x%02x, write len: %d",
|
||||
(s32)cmd_head.circle, (s32)cmd_head.times, (s32)cmd_head.retry,
|
||||
(s32)cmd_head.delay, (s32)cmd_head.data_len,
|
||||
(s32)cmd_head.addr_len, cmd_head.addr[0], cmd_head.addr[1],
|
||||
(s32)count);
|
||||
|
||||
if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) {
|
||||
pr_debug("data len %d > data buff %d, rejected!\n",
|
||||
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);
|
||||
if (cmd_head.data_len > (data_length - GTP_ADDR_LENGTH)) {
|
||||
dev_err(>_client->dev, "data len %d > data buff %d, rejected\n",
|
||||
cmd_head.data_len, (data_length - GTP_ADDR_LENGTH));
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (cmd_head.wr == 1) {
|
||||
/* copy_from_user(&cmd_head.data[cmd_head.addr_len],
|
||||
* &buff[CMD_HEAD_LENGTH], cmd_head.data_len);
|
||||
*/
|
||||
if (cmd_head.wr == GTP_RW_WRITE) {
|
||||
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
|
||||
&buff[CMD_HEAD_LENGTH], cmd_head.data_len);
|
||||
if (ret)
|
||||
pr_err("copy_from_user failed.\n");
|
||||
&userbuf[CMD_HEAD_LENGTH], cmd_head.data_len);
|
||||
if (ret) {
|
||||
dev_err(>_client->dev, "copy_from_user failed");
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(&cmd_head.data[GTP_ADDR_LENGTH - 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) {
|
||||
pr_err("[WRITE]Comfirm fail!\n");
|
||||
dev_err(>_client->dev, "Confirm fail");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
} else if (cmd_head.flag == 2) {
|
||||
} else if (cmd_head.flag == GTP_NEED_INTERRUPT) {
|
||||
/* Need interrupt! */
|
||||
}
|
||||
if (tool_i2c_write(
|
||||
&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
|
||||
cmd_head.data_len + cmd_head.addr_len) <= 0) {
|
||||
pr_err("[WRITE]Write data failed!\n");
|
||||
dev_err(>_client->dev, "Write data failed");
|
||||
ret = -EIO;
|
||||
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;
|
||||
goto exit;
|
||||
} else if (cmd_head.wr == 3) { /* Write ic type */
|
||||
|
||||
ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH],
|
||||
} else if (cmd_head.wr == GTP_RW_WRITE_IC_TYPE) { /* Write ic type */
|
||||
ret = copy_from_user(&cmd_head.data[0],
|
||||
&userbuf[CMD_HEAD_LENGTH],
|
||||
cmd_head.data_len);
|
||||
if (ret)
|
||||
pr_err("copy_from_user failed.\n");
|
||||
if (ret) {
|
||||
dev_err(>_client->dev, "copy_from_user failed");
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (cmd_head.data_len > sizeof(IC_TYPE)) {
|
||||
pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n",
|
||||
cmd_head.data_len, sizeof(IC_TYPE));
|
||||
if (cmd_head.data_len > sizeof(ic_type)) {
|
||||
dev_err(>_client->dev,
|
||||
"data len %d > data buff %d, rejected\n",
|
||||
cmd_head.data_len, sizeof(ic_type));
|
||||
ret = -EINVAL;
|
||||
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();
|
||||
|
||||
ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
goto exit;
|
||||
} else if (cmd_head.wr == 5) {
|
||||
|
||||
/* memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); */
|
||||
|
||||
} else if (cmd_head.wr == GTP_RW_NO_WRITE) {
|
||||
ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
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));
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
|
@ -447,7 +405,7 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
|||
#endif
|
||||
ret = CMD_HEAD_LENGTH;
|
||||
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));
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
|
@ -455,41 +413,45 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
|||
#endif
|
||||
ret = CMD_HEAD_LENGTH;
|
||||
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);
|
||||
|
||||
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
|
||||
&buff[CMD_HEAD_LENGTH], cmd_head.data_len);
|
||||
if (ret)
|
||||
pr_debug("copy_from_user failed.\n");
|
||||
&userbuf[CMD_HEAD_LENGTH], cmd_head.data_len);
|
||||
if (ret) {
|
||||
dev_err(>_client->dev, "copy_from_user failed");
|
||||
goto exit;
|
||||
}
|
||||
if (cmd_head.data[GTP_ADDR_LENGTH]) {
|
||||
pr_debug("gtp enter rawdiff.\n");
|
||||
pr_debug("gtp enter rawdiff\n");
|
||||
ts->gtp_rawdiff_mode = true;
|
||||
} else {
|
||||
ts->gtp_rawdiff_mode = false;
|
||||
pr_debug("gtp leave rawdiff.\n");
|
||||
pr_debug("gtp leave rawdiff\n");
|
||||
}
|
||||
ret = CMD_HEAD_LENGTH;
|
||||
goto exit;
|
||||
}
|
||||
#ifdef UPDATE_FUNCTIONS
|
||||
else if (cmd_head.wr == 11) { /* Enter update mode! */
|
||||
if (gup_enter_update_mode(gt_client) == FAIL)
|
||||
} else if (cmd_head.wr == GTP_RW_ENTER_UPDATE_MODE) {
|
||||
/* Enter update mode! */
|
||||
if (gup_enter_update_mode(gt_client) == FAIL) {
|
||||
ret = -EBUSY;
|
||||
goto exit;
|
||||
} else if (cmd_head.wr == 13) { /* Leave update mode! */
|
||||
gup_leave_update_mode();
|
||||
} else if (cmd_head.wr == 15) { /* Update firmware! */
|
||||
}
|
||||
} else if (cmd_head.wr == GTP_RW_LEAVE_UPDATE_MODE) {
|
||||
/* Leave update mode! */
|
||||
gup_leave_update_mode(gt_client);
|
||||
} else if (cmd_head.wr == GTP_RW_UPDATE_FW) {
|
||||
/* Update firmware! */
|
||||
show_len = 0;
|
||||
total_len = 0;
|
||||
if (cmd_head.data_len + 1 > DATA_LENGTH) {
|
||||
pr_debug("<<-GTP->> data len %d > data buff %d, rejected!\n",
|
||||
cmd_head.data_len + 1, DATA_LENGTH);
|
||||
if (cmd_head.data_len + 1 > data_length) {
|
||||
dev_err(>_client->dev, "data len %d > data buff %d, rejected\n",
|
||||
cmd_head.data_len + 1, data_length);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = CMD_HEAD_LENGTH;
|
||||
|
||||
exit:
|
||||
|
@ -505,37 +466,37 @@ exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
/*
|
||||
* Function:
|
||||
* Goodix tool read function.
|
||||
* Input:
|
||||
* standard proc read function param.
|
||||
* Output:
|
||||
* Return read length.
|
||||
*******************************************************
|
||||
*/
|
||||
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
int *eof, void *data)
|
||||
*/
|
||||
static s32 goodix_tool_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
u16 data_len = 0;
|
||||
s32 ret;
|
||||
u8 buf[32];
|
||||
|
||||
mutex_lock(&lock);
|
||||
if (cmd_head.wr % 2) {
|
||||
pr_err("<< [READ]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");
|
||||
if (cmd_head.wr & 0x1) {
|
||||
dev_err(>_client->dev, "command head wrong\n");
|
||||
ret = -EINVAL;
|
||||
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(>_client->dev, "Confirm fail");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
} else if (cmd_head.flag == GTP_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);
|
||||
|
||||
data_len = cmd_head.data_len;
|
||||
while (data_len > 0) {
|
||||
if (data_len > DATA_LENGTH)
|
||||
len = DATA_LENGTH;
|
||||
else
|
||||
len = data_len;
|
||||
|
||||
data_len -= len;
|
||||
|
||||
if (tool_i2c_read(cmd_head.data, len) <= 0) {
|
||||
pr_err("[READ]Read data failed!\n");
|
||||
if (data_len <= 0 || (data_len > data_length)) {
|
||||
dev_err(>_client->dev, "Invalid data length %d\n",
|
||||
data_len);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH],
|
||||
len);
|
||||
loc += len;
|
||||
}
|
||||
} else if (cmd_head.wr == 2) {
|
||||
/* memcpy(page, "gt8", cmd_head.data_len);
|
||||
* memcpy(page, "GT818", 5);
|
||||
* page[5] = 0;
|
||||
*/
|
||||
if (data_len > count)
|
||||
data_len = count;
|
||||
|
||||
pr_debug("Return ic type:%s len:%d.\n", page,
|
||||
(s32)cmd_head.data_len);
|
||||
ret = cmd_head.data_len;
|
||||
if (tool_i2c_read(cmd_head.data, data_len) <= 0) {
|
||||
dev_err(>_client->dev, "Read data failed\n");
|
||||
ret = -EIO;
|
||||
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:
|
||||
mutex_unlock(&lock);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -44,18 +44,16 @@
|
|||
#include "gt9xx.h"
|
||||
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#define GOODIX_DEV_NAME "Goodix-CTP"
|
||||
#define CFG_MAX_TOUCH_POINTS 5
|
||||
#define GOODIX_COORDS_ARR_SIZE 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_MAX_UV 3300000
|
||||
#define GOODIX_I2C_VTG_MIN_UV 1800000
|
||||
|
@ -79,7 +77,6 @@ static const u16 touch_key_array[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK};
|
|||
|
||||
#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 int gtp_i2c_test(struct i2c_client *client);
|
||||
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)
|
||||
static int fb_notifier_callback(struct notifier_block *self,
|
||||
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)
|
||||
static void goodix_ts_early_suspend(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 void gtp_esd_check_func(struct work_struct *work);
|
||||
static int gtp_init_ext_watchdog(struct i2c_client *client);
|
||||
struct i2c_client *i2c_connect_client;
|
||||
#endif
|
||||
|
||||
#if GTP_SLIDE_WAKEUP
|
||||
|
@ -113,6 +111,10 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts);
|
|||
bool init_done;
|
||||
static u8 chip_gt9xxs; /* true if ic is gt9xxs, like gt915s */
|
||||
u8 grp_cfg_version;
|
||||
struct i2c_client *i2c_connect_client;
|
||||
|
||||
#define GTP_DEBUGFS_DIR "ts_debug"
|
||||
#define GTP_DEBUGFS_FILE_SUSPEND "suspend"
|
||||
|
||||
/*******************************************************
|
||||
Function:
|
||||
|
@ -264,7 +266,7 @@ Output:
|
|||
result of i2c write operation.
|
||||
> 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;
|
||||
#if GTP_DRIVER_SEND_CFG
|
||||
|
@ -593,26 +595,6 @@ exit_work_func:
|
|||
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:
|
||||
External interrupt service routine for interrupt mode.
|
||||
|
@ -656,7 +638,7 @@ Input:
|
|||
Output:
|
||||
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 */
|
||||
gpio_direction_output(ts->pdata->reset_gpio, 0);
|
||||
|
@ -730,16 +712,13 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts)
|
|||
return ret;
|
||||
}
|
||||
#else
|
||||
/*******************************************************
|
||||
Function:
|
||||
Enter sleep mode.
|
||||
Input:
|
||||
ts: private data.
|
||||
Output:
|
||||
Executive outcomes.
|
||||
>0: succeed, otherwise failed.
|
||||
*******************************************************/
|
||||
static s8 gtp_enter_sleep(struct goodix_ts_data *ts)
|
||||
/**
|
||||
* gtp_enter_sleep - Enter sleep mode
|
||||
* @ts: driver private data
|
||||
*
|
||||
* Returns zero on success, else an error.
|
||||
*/
|
||||
static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
|
||||
{
|
||||
int ret = -1;
|
||||
s8 retry = 0;
|
||||
|
@ -761,16 +740,16 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts)
|
|||
ret = goodix_power_off(ts);
|
||||
if (ret) {
|
||||
dev_err(&ts->client->dev, "GTP power off failed.\n");
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
usleep(5000);
|
||||
while (retry++ < GTP_I2C_RETRY_5) {
|
||||
ret = gtp_i2c_write(ts->client, i2c_control_buf, 3);
|
||||
if (ret == 1) {
|
||||
dev_dbg(&ts->client->dev, "GTP enter sleep!");
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
msleep(20);
|
||||
}
|
||||
|
@ -1196,19 +1175,14 @@ static int gtp_request_irq(struct goodix_ts_data *ts)
|
|||
int ret;
|
||||
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],
|
||||
ts->client->name, ts);
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
|
@ -1560,6 +1534,56 @@ static const struct attribute_group gtp_attr_grp = {
|
|||
.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,
|
||||
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]);
|
||||
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;
|
||||
}
|
||||
|
@ -1783,7 +1807,7 @@ static int goodix_ts_probe(struct i2c_client *client,
|
|||
|
||||
ret = gtp_i2c_test(client);
|
||||
if (ret != 2) {
|
||||
dev_err(&client->dev, "I2C communication ERROR!\n");
|
||||
dev_err(&client->dev, "I2C communication ERROR\n");
|
||||
goto exit_power_off;
|
||||
}
|
||||
|
||||
|
@ -1791,7 +1815,7 @@ static int goodix_ts_probe(struct i2c_client *client,
|
|||
strlcpy(ts->fw_name, pdata->fw_name,
|
||||
strlen(pdata->fw_name) + 1);
|
||||
|
||||
#if GTP_AUTO_UPDATE
|
||||
#ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
|
||||
ret = gup_init_update_proc(ts);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
ret = gtp_request_irq(ts);
|
||||
if (ret < 0)
|
||||
dev_info(&client->dev, "GTP works in polling mode.\n");
|
||||
if (ret)
|
||||
dev_info(&client->dev, "GTP request irq failed %d\n", ret);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
if (ts->use_irq)
|
||||
gtp_irq_enable(ts);
|
||||
|
||||
#if GTP_CREATE_WR_NODE
|
||||
#ifdef CONFIG_GT9XX_TOUCHPANEL_DEBUG
|
||||
init_wr_node(client);
|
||||
#endif
|
||||
|
||||
|
@ -1860,10 +1884,14 @@ static int goodix_ts_probe(struct i2c_client *client,
|
|||
#endif
|
||||
ret = sysfs_create_group(&client->dev.kobj, >p_attr_grp);
|
||||
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;
|
||||
}
|
||||
|
||||
ret = gtp_debugfs_init(ts);
|
||||
if (ret != 0)
|
||||
goto exit_remove_sysfs;
|
||||
|
||||
init_done = true;
|
||||
return 0;
|
||||
exit_free_irq:
|
||||
|
@ -1871,7 +1899,7 @@ exit_free_irq:
|
|||
#if defined(CONFIG_FB)
|
||||
if (fb_unregister_client(&ts->fb_notif))
|
||||
dev_err(&client->dev,
|
||||
"Error occurred while unregistering fb_notifier.\n");
|
||||
"Error occurred while unregistering fb_notifier\n");
|
||||
#elif defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
|
@ -1888,6 +1916,8 @@ exit_free_irq:
|
|||
input_free_device(ts->input_dev);
|
||||
ts->input_dev = NULL;
|
||||
}
|
||||
exit_remove_sysfs:
|
||||
sysfs_remove_group(&ts->input_dev->dev.kobj, >p_attr_grp);
|
||||
exit_free_inputdev:
|
||||
kfree(ts->config_data);
|
||||
exit_power_off:
|
||||
|
@ -1921,13 +1951,13 @@ static int goodix_ts_remove(struct i2c_client *client)
|
|||
#if defined(CONFIG_FB)
|
||||
if (fb_unregister_client(&ts->fb_notif))
|
||||
dev_err(&client->dev,
|
||||
"Error occurred while unregistering fb_notifier.\n");
|
||||
"Error occurred while unregistering fb_notifier\n");
|
||||
#elif defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
unregister_early_suspend(&ts->early_suspend);
|
||||
#endif
|
||||
mutex_destroy(&ts->lock);
|
||||
|
||||
#if GTP_CREATE_WR_NODE
|
||||
#ifdef CONFIG_GT9XX_TOUCHPANEL_DEBUG
|
||||
uninit_wr_node();
|
||||
#endif
|
||||
|
||||
|
@ -1962,6 +1992,7 @@ static int goodix_ts_remove(struct i2c_client *client)
|
|||
goodix_power_deinit(ts);
|
||||
i2c_set_clientdata(client, NULL);
|
||||
}
|
||||
debugfs_remove_recursive(ts->debug_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1980,9 +2011,13 @@ static int goodix_ts_suspend(struct device *dev)
|
|||
struct goodix_ts_data *ts = dev_get_drvdata(dev);
|
||||
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);
|
||||
#if GTP_ESD_PROTECT
|
||||
ts->gtp_is_suspend = 1;
|
||||
gtp_esd_switch(ts->client, SWITCH_OFF);
|
||||
#endif
|
||||
|
||||
|
@ -2001,13 +2036,14 @@ static int goodix_ts_suspend(struct device *dev)
|
|||
|
||||
ret = gtp_enter_sleep(ts);
|
||||
#endif
|
||||
if (ret <= 0)
|
||||
dev_err(&ts->client->dev, "GTP early suspend failed.\n");
|
||||
if (ret < 0)
|
||||
dev_err(&ts->client->dev, "GTP early suspend failed\n");
|
||||
/* to avoid waking up while not sleeping,
|
||||
* delay 48 + 10ms to ensure reliability
|
||||
*/
|
||||
msleep(58);
|
||||
mutex_unlock(&ts->lock);
|
||||
ts->gtp_is_suspend = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2025,6 +2061,11 @@ static int goodix_ts_resume(struct device *dev)
|
|||
struct goodix_ts_data *ts = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (!ts->gtp_is_suspend) {
|
||||
dev_dbg(&ts->client->dev, "Already in awake state\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&ts->lock);
|
||||
ret = gtp_wakeup_sleep(ts);
|
||||
|
||||
|
@ -2033,7 +2074,7 @@ static int goodix_ts_resume(struct device *dev)
|
|||
#endif
|
||||
|
||||
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)
|
||||
gtp_irq_enable(ts);
|
||||
|
@ -2042,10 +2083,10 @@ static int goodix_ts_resume(struct device *dev)
|
|||
ktime_set(1, 0), HRTIMER_MODE_REL);
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
ts->gtp_is_suspend = 0;
|
||||
gtp_esd_switch(ts->client, SWITCH_ON);
|
||||
#endif
|
||||
mutex_unlock(&ts->lock);
|
||||
ts->gtp_is_suspend = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2236,8 +2277,15 @@ static void gtp_esd_check_func(struct work_struct *work)
|
|||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(goodix_ts_dev_pm_ops, goodix_ts_suspend,
|
||||
goodix_ts_resume);
|
||||
#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
|
||||
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[] = {
|
||||
{ GTP_I2C_NAME, 0 },
|
||||
|
|
|
@ -22,18 +22,9 @@
|
|||
|
||||
#include <linux/kernel.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/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#if defined(CONFIG_FB)
|
||||
#include <linux/notifier.h>
|
||||
|
@ -105,6 +96,7 @@ struct goodix_ts_data {
|
|||
#elif defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
struct early_suspend early_suspend;
|
||||
#endif
|
||||
struct dentry *debug_base;
|
||||
};
|
||||
|
||||
extern u16 show_len;
|
||||
|
@ -116,14 +108,6 @@ extern u16 total_len;
|
|||
#define GTP_DRIVER_SEND_CFG 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_WITH_PEN 0
|
||||
|
||||
|
@ -132,18 +116,6 @@ extern u16 total_len;
|
|||
/* double-click wakeup, function together with GTP_SLIDE_WAKEUP */
|
||||
#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 {\
|
||||
IRQ_TYPE_EDGE_RISING,\
|
||||
IRQ_TYPE_EDGE_FALLING,\
|
||||
|
@ -151,7 +123,7 @@ extern u16 total_len;
|
|||
IRQ_TYPE_LEVEL_HIGH\
|
||||
}
|
||||
|
||||
/* STEP_3(optional): Specify your special config info if needed */
|
||||
|
||||
#define GTP_IRQ_TAB_RISING 0
|
||||
#define GTP_IRQ_TAB_FALLING 1
|
||||
#if GTP_CUSTOM_CFG
|
||||
|
@ -197,16 +169,52 @@ extern u16 total_len;
|
|||
#define RESOLUTION_LOC 3
|
||||
#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********************************/
|
||||
|
||||
void gtp_esd_switch(struct i2c_client *client, int on);
|
||||
|
||||
#if GTP_CREATE_WR_NODE
|
||||
extern s32 init_wr_node(struct i2c_client *client);
|
||||
extern void uninit_wr_node(void);
|
||||
int gtp_i2c_read_dbl_check(struct i2c_client *client, u16 addr,
|
||||
u8 *rxbuf, int len);
|
||||
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
|
||||
|
||||
#if GTP_AUTO_UPDATE
|
||||
#ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE
|
||||
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 /* _GOODIX_GT9XX_H_ */
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue