diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 11 | ||||
-rw-r--r-- | drivers/input/touchscreen/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/gt9xx/Kconfig | 51 | ||||
-rw-r--r-- | drivers/input/touchscreen/gt9xx/Makefile | 8 | ||||
-rw-r--r-- | drivers/input/touchscreen/gt9xx/goodix_tool.c | 107 | ||||
-rw-r--r-- | drivers/input/touchscreen/gt9xx/gt9xx.c | 231 | ||||
-rw-r--r-- | drivers/input/touchscreen/gt9xx/gt9xx.h | 43 |
7 files changed, 253 insertions, 199 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index b9956170b909..49df5e0afbfb 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1217,4 +1217,15 @@ config TOUCHSCREEN_IT7260_I2C To compile this driver as a module, choose M here: the module will be called it7258_ts_i2c. +config TOUCHSCREEN_GT9XX + bool "Goodix touchpanel GT9xx series" + depends on I2C + help + Say Y here if you have a Goodix GT9xx touchscreen. + Gt9xx controllers are multi touch controllers which can + report 5 touches at a time. + + If unsure, say N. + +source "drivers/input/touchscreen/gt9xx/Kconfig" endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index f448df5b234c..06953a69123f 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -99,3 +99,4 @@ obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o obj-$(CONFIG_TOUCHSCREEN_MSTAR21XX) += msg21xx_ts.o +obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/ diff --git a/drivers/input/touchscreen/gt9xx/Kconfig b/drivers/input/touchscreen/gt9xx/Kconfig new file mode 100644 index 000000000000..2e1b5ba567a0 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/Kconfig @@ -0,0 +1,51 @@ +# +# Goodix GT9xx Touchscreen driver +# + +config GT9XX_TOUCHPANEL_DRIVER + tristate "Goodix GT9xx touchpanel driver" + depends on TOUCHSCREEN_GT9XX + default n + help + This is the main file for touchpanel driver for Goodix GT9xx + touchscreens. + + Say Y here if you have a Goodix GT9xx touchscreen connected + to your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called gt9xx. + +config GT9XX_TOUCHPANEL_UPDATE + tristate "Goodix GT9xx touchpanel auto update support" + depends on GT9XX_TOUCHPANEL_DRIVER + default n + help + This enables support for firmware update for Goodix GT9xx + touchscreens. + + Say Y here if you have a Goodix GT9xx touchscreen connected + to your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called gt9xx_update. + +config GT9XX_TOUCHPANEL_DEBUG + tristate "Goodix GT9xx Tools for debuging" + depends on GT9XX_TOUCHPANEL_DRIVER + default n + help + This is application debug interface support for Goodix GT9xx + touchscreens. + + Say Y here if you want to have a Android app debug interface + to your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called gt9xx_tool. diff --git a/drivers/input/touchscreen/gt9xx/Makefile b/drivers/input/touchscreen/gt9xx/Makefile new file mode 100644 index 000000000000..482d869a2d37 --- /dev/null +++ b/drivers/input/touchscreen/gt9xx/Makefile @@ -0,0 +1,8 @@ +#gt915 touchpanel driver + + +obj-$(CONFIG_GT9XX_TOUCHPANEL_DRIVER) += gt9xx.o +#gt915 update file +obj-$(CONFIG_GT9XX_TOUCHPANEL_UPDATE) += gt9xx_update.o +#debug tool +obj-$(CONFIG_GT9XX_TOUCHPANEL_DEBUG) += goodix_tool.o diff --git a/drivers/input/touchscreen/gt9xx/goodix_tool.c b/drivers/input/touchscreen/gt9xx/goodix_tool.c index bef080671ab0..59de914cceef 100644 --- a/drivers/input/touchscreen/gt9xx/goodix_tool.c +++ b/drivers/input/touchscreen/gt9xx/goodix_tool.c @@ -22,6 +22,7 @@ */ #include "gt9xx.h" +#include <linux/mutex.h> #define DATA_LENGTH_UINT 512 #define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8 *)) @@ -53,6 +54,8 @@ static struct i2c_client *gt_client; 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, @@ -181,7 +184,7 @@ static void unregister_i2c_func(void) s32 init_wr_node(struct i2c_client *client) { - s32 i; + u8 i; gt_client = client; memset(&cmd_head, 0, sizeof(cmd_head)); @@ -195,8 +198,8 @@ s32 init_wr_node(struct i2c_client *client) i--; } if (i) { - DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH; - GTP_INFO("Applied memory size:%d.", DATA_LENGTH); + DATA_LENGTH = i * DATA_LENGTH_UINT; + dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH); } else { GTP_ERROR("Apply for memory failed."); return FAIL; @@ -207,8 +210,9 @@ s32 init_wr_node(struct i2c_client *client) register_i2c_func(); + mutex_init(&lock); tool_set_proc_name(procname); - goodix_proc_entry = create_proc_entry(procname, 0666, NULL); + goodix_proc_entry = create_proc_entry(procname, 0660, NULL); if (goodix_proc_entry == NULL) { GTP_ERROR("Couldn't create proc entry!"); return FAIL; @@ -330,9 +334,13 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, GTP_DEBUG_FUNC(); GTP_DEBUG_ARRAY((u8 *)buff, len); + mutex_lock(&lock); ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH); - if (ret) + if (ret) { GTP_ERROR("copy_from_user failed."); + ret = -EACCES; + goto exit; + } GTP_DEBUG("wr :0x%02x.", cmd_head.wr); GTP_DEBUG("flag:0x%02x.", cmd_head.flag); @@ -350,6 +358,19 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, GTP_DEBUG("len:%d.", (s32)len); GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]); + if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) { + pr_err("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_err(" addr len %d > data buff %d, rejected!\n", + cmd_head.addr_len, 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); @@ -370,7 +391,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, if (cmd_head.flag == 1) { if (comfirm() == FAIL) { GTP_ERROR("[WRITE]Comfirm fail!"); - return FAIL; + ret = -EINVAL; + goto exit; } } else if (cmd_head.flag == 2) { /* Need interrupt! */ @@ -379,7 +401,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, &cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len], cmd_head.data_len + cmd_head.addr_len) <= 0) { GTP_ERROR("[WRITE]Write data failed!"); - return FAIL; + ret = -EIO; + goto exit; } GTP_DEBUG_ARRAY( @@ -388,7 +411,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, if (cmd_head.delay) msleep(cmd_head.delay); - return cmd_head.data_len + CMD_HEAD_LENGTH; + 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], @@ -396,30 +420,40 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, if (ret) GTP_ERROR("copy_from_user failed."); + if (cmd_head.data_len > sizeof(IC_TYPE)) { + pr_err("<<-GTP->> 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); register_i2c_func(); - return cmd_head.data_len + CMD_HEAD_LENGTH; - } else if (cmd_head.wr == 3) { + 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); */ - return cmd_head.data_len + CMD_HEAD_LENGTH; + ret = cmd_head.data_len + CMD_HEAD_LENGTH; + goto exit; } else if (cmd_head.wr == 7) { /* disable irq! */ gtp_irq_disable(i2c_get_clientdata(gt_client)); #if GTP_ESD_PROTECT gtp_esd_switch(gt_client, SWITCH_OFF); #endif - return CMD_HEAD_LENGTH; + ret = CMD_HEAD_LENGTH; + goto exit; } else if (cmd_head.wr == 9) { /* enable irq! */ gtp_irq_enable(i2c_get_clientdata(gt_client)); #if GTP_ESD_PROTECT gtp_esd_switch(gt_client, SWITCH_ON); #endif - return CMD_HEAD_LENGTH; + ret = CMD_HEAD_LENGTH; + goto exit; } else if (cmd_head.wr == 17) { struct goodix_ts_data *ts = i2c_get_clientdata(gt_client); @@ -434,27 +468,40 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, ts->gtp_rawdiff_mode = false; GTP_DEBUG("gtp leave rawdiff."); } - return CMD_HEAD_LENGTH; + 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) - return 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! */ show_len = 0; total_len = 0; + if (cmd_head.data_len + 1 > DATA_LENGTH) { + pr_err("<<-GTP->> 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], cmd_head.data_len); - if (gup_update_proc((void *)cmd_head.data) == FAIL) - return FAIL; + if (gup_update_proc((void *)cmd_head.data) == FAIL) { + ret = -EBUSY; + goto exit; + } } #endif + ret = CMD_HEAD_LENGTH; - return CMD_HEAD_LENGTH; +exit: + mutex_unlock(&lock); + return ret; } /******************************************************* @@ -469,10 +516,14 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff, static s32 goodix_tool_read(char *page, char **start, off_t off, int count, int *eof, void *data) { + s32 ret; GTP_DEBUG_FUNC(); + mutex_lock(&lock); if (cmd_head.wr % 2) { - return FAIL; + pr_err("<< [READ]command head wrong\n"); + ret = -EINVAL; + goto exit; } else if (!cmd_head.wr) { u16 len = 0; s16 data_len = 0; @@ -481,7 +532,8 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, if (cmd_head.flag == 1) { if (comfirm() == FAIL) { GTP_ERROR("[READ]Comfirm fail!"); - return FAIL; + ret = -EINVAL; + goto exit; } } else if (cmd_head.flag == 2) { /* Need interrupt! */ @@ -504,11 +556,12 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, else len = data_len; - data_len -= DATA_LENGTH; + data_len -= len; if (tool_i2c_read(cmd_head.data, len) <= 0) { GTP_ERROR("[READ]Read data failed!"); - return FAIL; + ret = -EINVAL; + goto exit; } memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH], len); @@ -525,15 +578,14 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, GTP_DEBUG("Return ic type:%s len:%d.", page, (s32)cmd_head.data_len); - return cmd_head.data_len; + ret = cmd_head.data_len; + 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; - - return cmd_head.data_len; } else if (cmd_head.wr == 6) { /* Read error code! */ } else if (cmd_head.wr == 8) { /*Read driver version */ @@ -546,6 +598,9 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count, memcpy(page, GTP_DRIVER_VERSION, tmp_len); page[tmp_len] = 0; } + ret = cmd_head.data_len; - return cmd_head.data_len; +exit: + mutex_unlock(&lock); + return ret; } diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c index ebb9ce7ba6a4..b8bdbd7fd7fd 100644 --- a/drivers/input/touchscreen/gt9xx/gt9xx.c +++ b/drivers/input/touchscreen/gt9xx/gt9xx.c @@ -45,11 +45,9 @@ #include <linux/of_gpio.h> -#if GTP_ICS_SLOT_REPORT #include <linux/input/mt.h> -#endif -#define GOODIX_DEV_NAME "Goodix Capacitive TouchScreen" +#define GOODIX_DEV_NAME "Goodix-CTP" #define CFG_MAX_TOUCH_POINTS 5 #define GOODIX_COORDS_ARR_SIZE 4 #define MAX_BUTTONS 4 @@ -140,8 +138,6 @@ int gtp_i2c_read(struct i2c_client *client, u8 *buf, int len) int ret = -EIO; int retries = 0; - GTP_DEBUG_FUNC(); - msgs[0].flags = !I2C_M_RD; msgs[0].addr = client->addr; msgs[0].len = GTP_ADDR_LENGTH; @@ -164,7 +160,6 @@ int gtp_i2c_read(struct i2c_client *client, u8 *buf, int len) if (doze_status == DOZE_ENABLED) return ret; #endif - GTP_DEBUG("I2C communication timeout, resetting chip..."); if (init_done) gtp_reset_guitar(ts, 10); else @@ -194,8 +189,6 @@ int gtp_i2c_write(struct i2c_client *client, u8 *buf, int len) int ret = -EIO; int retries = 0; - GTP_DEBUG_FUNC(); - msg.flags = !I2C_M_RD; msg.addr = client->addr; msg.len = len; @@ -212,7 +205,6 @@ int gtp_i2c_write(struct i2c_client *client, u8 *buf, int len) if (doze_status == DOZE_ENABLED) return ret; #endif - GTP_DEBUG("I2C communication timeout, resetting chip..."); if (init_done) gtp_reset_guitar(ts, 10); else @@ -309,8 +301,6 @@ void gtp_irq_disable(struct goodix_ts_data *ts) { unsigned long irqflags; - GTP_DEBUG_FUNC(); - spin_lock_irqsave(&ts->irq_lock, irqflags); if (!ts->irq_is_disabled) { ts->irq_is_disabled = true; @@ -331,8 +321,6 @@ void gtp_irq_enable(struct goodix_ts_data *ts) { unsigned long irqflags = 0; - GTP_DEBUG_FUNC(); - spin_lock_irqsave(&ts->irq_lock, irqflags); if (ts->irq_is_disabled) { enable_irq(ts->client->irq); @@ -357,26 +345,15 @@ static void gtp_touch_down(struct goodix_ts_data *ts, int id, int x, int y, int w) { #if GTP_CHANGE_X2Y - GTP_SWAP(x, y); + swap(x, y); #endif -#if GTP_ICS_SLOT_REPORT input_mt_slot(ts->input_dev, id); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); -#else - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); - input_mt_sync(ts->input_dev); -#endif - - GTP_DEBUG("ID:%d, X:%d, Y:%d, W:%d", id, x, y, w); } /******************************************************* @@ -389,15 +366,8 @@ Output: *********************************************************/ static void gtp_touch_up(struct goodix_ts_data *ts, int id) { -#if GTP_ICS_SLOT_REPORT input_mt_slot(ts->input_dev, id); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); - GTP_DEBUG("Touch id[%2d] release!", id); -#else - 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(ts->input_dev); -#endif + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); } @@ -438,8 +408,6 @@ static void goodix_ts_work_func(struct work_struct *work) u8 doze_buf[3] = {0x81, 0x4B}; #endif - GTP_DEBUG_FUNC(); - ts = container_of(work, struct goodix_ts_data, work); #ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE if (ts->enter_update) @@ -449,7 +417,6 @@ static void goodix_ts_work_func(struct work_struct *work) #if GTP_SLIDE_WAKEUP if (doze_status == DOZE_ENABLED) { ret = gtp_i2c_read(ts->client, doze_buf, 3); - GTP_DEBUG("0x814B = 0x%02X", doze_buf[2]); if (ret > 0) { if (doze_buf[2] == 0xAA) { dev_dbg(&ts->client->dev, @@ -547,12 +514,9 @@ static void goodix_ts_work_func(struct work_struct *work) #endif pre_key = key_value; - GTP_DEBUG("pre_touch:%02x, finger:%02x.", pre_touch, finger); - -#if GTP_ICS_SLOT_REPORT #if GTP_WITH_PEN if (pre_pen && (touch_num == 0)) { - GTP_DEBUG("Pen touch UP(Slot)!"); + dev_dbg(&ts->client->dev, "Pen touch UP(Slot)!"); input_report_key(ts->input_dev, BTN_TOOL_PEN, 0); input_mt_slot(ts->input_dev, 5); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); @@ -569,7 +533,8 @@ static void goodix_ts_work_func(struct work_struct *work) #if GTP_WITH_PEN id = coor_data[pos]; if (id == 128) { - GTP_DEBUG("Pen touch DOWN(Slot)!"); + dev_dbg(&ts->client->dev, + "Pen touch DOWN(Slot)!"); input_x = coor_data[pos + 1] | (coor_data[pos + 2] << 8); input_y = coor_data[pos + 3] @@ -588,7 +553,8 @@ static void goodix_ts_work_func(struct work_struct *work) ABS_MT_POSITION_Y, input_y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); - GTP_DEBUG("Pen/Stylus: (%d, %d)[%d]", + dev_dbg(&ts->client->dev, + "Pen/Stylus: (%d, %d)[%d]", input_x, input_y, input_w); pre_pen = 1; pre_touch = 0; @@ -598,8 +564,6 @@ static void goodix_ts_work_func(struct work_struct *work) touch_index |= (0x01<<id); } - GTP_DEBUG("id = %d,touch_index = 0x%x, pre_touch = 0x%x\n", - id, touch_index, pre_touch); for (i = 0; i < GTP_MAX_TOUCH; i++) { #if GTP_WITH_PEN if (pre_pen == 1) @@ -626,42 +590,6 @@ static void goodix_ts_work_func(struct work_struct *work) } } } -#else - input_report_key(ts->input_dev, BTN_TOUCH, (touch_num || key_value)); - if (touch_num) { - for (i = 0; i < touch_num; i++) { - coor_data = &point_data[i * 8 + 3]; - - id = coor_data[0]; - input_x = coor_data[1] | coor_data[2] << 8; - input_y = coor_data[3] | coor_data[4] << 8; - input_w = coor_data[5] | coor_data[6] << 8; -#if GTP_WITH_PEN - if (id == 128) { - GTP_DEBUG("Pen touch DOWN!"); - input_report_key(ts->input_dev, - BTN_TOOL_PEN, 1); - pre_pen = 1; - id = 0; - } -#endif - gtp_touch_down(ts, id, input_x, input_y, input_w); - } - } else if (pre_touch) { -#if GTP_WITH_PEN - if (pre_pen == 1) { - GTP_DEBUG("Pen touch UP!"); - input_report_key(ts->input_dev, BTN_TOOL_PEN, 0); - pre_pen = 0; - } -#endif - GTP_DEBUG("Touch Released!"); - gtp_touch_up(ts, 0); - } - - pre_touch = touch_num; -#endif - input_sync(ts->input_dev); exit_work_func: @@ -691,8 +619,6 @@ static enum hrtimer_restart goodix_ts_timer_handler(struct hrtimer *timer) struct goodix_ts_data *ts = container_of(timer, struct goodix_ts_data, timer); - GTP_DEBUG_FUNC(); - queue_work(ts->goodix_wq, &ts->work); hrtimer_start(&ts->timer, ktime_set(0, (GTP_POLL_TIME + 6) * 1000000), HRTIMER_MODE_REL); @@ -713,8 +639,6 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) { struct goodix_ts_data *ts = dev_id; - GTP_DEBUG_FUNC(); - gtp_irq_disable(ts); queue_work(ts->goodix_wq, &ts->work); @@ -746,8 +670,6 @@ Output: *******************************************************/ static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms) { - GTP_DEBUG_FUNC(); - /* This reset sequence will selcet I2C slave address */ gpio_direction_output(ts->pdata->reset_gpio, 0); msleep(ms); @@ -788,20 +710,17 @@ static s8 gtp_enter_doze(struct goodix_ts_data *ts) (u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 8}; - GTP_DEBUG_FUNC(); - #if GTP_DBL_CLK_WAKEUP i2c_control_buf[2] = 0x09; #endif gtp_irq_disable(ts); - GTP_DEBUG("entering doze mode..."); while (retry++ < 5) { i2c_control_buf[0] = 0x80; i2c_control_buf[1] = 0x46; ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); if (ret < 0) { - GTP_DEBUG( + dev_err(&ts->client->dev, "failed to set doze flag into 0x8046, %d", retry); continue; @@ -840,8 +759,6 @@ static s8 gtp_enter_sleep(struct goodix_ts_data *ts) (u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; - GTP_DEBUG_FUNC(); - ret = gpio_direction_output(ts->pdata->irq_gpio, 0); usleep(5000); while (retry++ < 5) { @@ -872,8 +789,6 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) u8 retry = 0; s8 ret = -1; - GTP_DEBUG_FUNC(); - #if GTP_POWER_CTRL_SLEEP gtp_reset_guitar(ts, 20); @@ -961,10 +876,6 @@ static int gtp_init_panel(struct goodix_ts_data *ts) ARRAY_SIZE(cfg_info_group5), ARRAY_SIZE(cfg_info_group6)}; - GTP_DEBUG("Config Groups\' Lengths: %d, %d, %d, %d, %d, %d", - cfg_info_len[0], cfg_info_len[1], cfg_info_len[2], - cfg_info_len[3], cfg_info_len[4], cfg_info_len[5]); - ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1); if (ret == SUCCESS) { if (opr_buf[0] != 0xBE) { @@ -993,8 +904,6 @@ static int gtp_init_panel(struct goodix_ts_data *ts) return -EINVAL; } } - GTP_DEBUG("Sensor_ID: %d", sensor_id); - ts->gtp_cfg_len = cfg_info_len[sensor_id]; if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH) { @@ -1082,7 +991,6 @@ static int gtp_init_panel(struct goodix_ts_data *ts) } #endif /* !DRIVER NOT SEND CONFIG */ - GTP_DEBUG_FUNC(); if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) { ts->abs_x_max = (config_data[RESOLUTION_LOC + 1] << 8) + config_data[RESOLUTION_LOC]; @@ -1094,49 +1002,79 @@ static int gtp_init_panel(struct goodix_ts_data *ts) if (ret < 0) dev_err(&client->dev, "%s: Send config error.\n", __func__); - GTP_DEBUG("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x", - ts->abs_x_max, ts->abs_y_max, - ts->int_trigger_type); - msleep(20); return ret; } /******************************************************* Function: - Read chip version. + Read firmware version Input: client: i2c device version: buffer to keep ic firmware version Output: read operation return. - 2: succeed, otherwise: failed + 0: succeed, otherwise: failed *******************************************************/ -int gtp_read_version(struct i2c_client *client, u16 *version) +static int gtp_read_fw_version(struct i2c_client *client, u16 *version) { - int ret = -EIO; - u8 buf[8] = { GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff }; - - GTP_DEBUG_FUNC(); + int ret = 0; + u8 buf[GTP_FW_VERSION_BUFFER_MAXSIZE] = { + GTP_REG_FW_VERSION >> 8, GTP_REG_FW_VERSION & 0xff }; ret = gtp_i2c_read(client, buf, sizeof(buf)); if (ret < 0) { dev_err(&client->dev, "GTP read version failed.\n"); - return ret; + return -EIO; } if (version) - *version = (buf[7] << 8) | buf[6]; + *version = (buf[3] << 8) | buf[2]; + + return ret; +} +/* + * Function: + * Read and check chip id. + * Input: + * client: i2c device + * Output: + * read operation return. + * 0: succeed, otherwise: failed + */ +static int gtp_check_product_id(struct i2c_client *client) +{ + int ret = 0; + char product_id[GTP_PRODUCT_ID_MAXSIZE]; + struct goodix_ts_data *ts = i2c_get_clientdata(client); + /* 04 bytes are used for the Product-id in the register space.*/ + u8 buf[GTP_PRODUCT_ID_BUFFER_MAXSIZE] = { + GTP_REG_PRODUCT_ID >> 8, GTP_REG_PRODUCT_ID & 0xff }; + + ret = gtp_i2c_read(client, buf, sizeof(buf)); + if (ret < 0) { + dev_err(&client->dev, "GTP read version failed.\n"); + return -EIO; + } if (buf[5] == 0x00) { - dev_dbg(&client->dev, "IC Version: %c%c%c_%02x%02x\n", buf[2], - buf[3], buf[4], buf[7], buf[6]); + /* copy (GTP_PRODUCT_ID_MAXSIZE - 1) from buffer. Ex: 915 */ + strlcpy(product_id, &buf[2], GTP_PRODUCT_ID_MAXSIZE - 1); } else { if (buf[5] == 'S' || buf[5] == 's') chip_gt9xxs = 1; - dev_dbg(&client->dev, "IC Version: %c%c%c%c_%02x%02x\n", buf[2], - buf[3], buf[4], buf[5], buf[7], buf[6]); + /* copy GTP_PRODUCT_ID_MAXSIZE from buffer. Ex: 915s */ + strlcpy(product_id, &buf[2], GTP_PRODUCT_ID_MAXSIZE); } + + dev_info(&client->dev, "Goodix Product ID = %s\n", product_id); + + if (!IS_ERR(ts->pdata->product_id)) + ret = strcmp(product_id, ts->pdata->product_id); + + if (ret != 0) + return -EINVAL; + return ret; } @@ -1155,8 +1093,6 @@ static int gtp_i2c_test(struct i2c_client *client) int retry = 5; int ret = -EIO; - GTP_DEBUG_FUNC(); - while (retry--) { ret = gtp_i2c_read(client, buf, 3); if (ret > 0) @@ -1246,9 +1182,6 @@ static int gtp_request_irq(struct goodix_ts_data *ts) int ret; const u8 irq_table[] = GTP_IRQ_TAB; - GTP_DEBUG("INT trigger type:%x, irq=%d", ts->int_trigger_type, - ts->client->irq); - ret = request_irq(ts->client->irq, goodix_ts_irq_handler, irq_table[ts->int_trigger_type], ts->client->name, ts); @@ -1287,8 +1220,6 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts) int index = 0; #endif - GTP_DEBUG_FUNC(); - ts->input_dev = input_allocate_device(); if (ts->input_dev == NULL) { dev_err(&ts->client->dev, @@ -1298,12 +1229,10 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts) ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); -#if GTP_ICS_SLOT_REPORT + set_bit(BTN_TOOL_FINGER, ts->input_dev->keybit); __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - input_mt_init_slots(ts->input_dev, 10);/* in case of "out of memory" */ -#else - ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); -#endif + /* in case of "out of memory" */ + input_mt_init_slots(ts->input_dev, 10, 0); #if GTP_HAVE_TOUCH_KEY for (index = 0; index < ARRAY_SIZE(touch_key_array); index++) { @@ -1324,7 +1253,7 @@ static int gtp_request_input_dev(struct goodix_ts_data *ts) #endif #if GTP_CHANGE_X2Y - GTP_SWAP(ts->abs_x_max, ts->abs_y_max); + swap(ts->abs_x_max, ts->abs_y_max); #endif input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, @@ -1631,10 +1560,9 @@ static int goodix_parse_dt(struct device *dev, if (pdata->irq_gpio < 0) return pdata->irq_gpio; - rc = of_property_read_u32(np, "goodix,family-id", &temp_val); - if (!rc) - pdata->family_id = temp_val; - else + rc = of_property_read_string(np, "goodix,product-id", + &pdata->product_id); + if (rc < 0 || strlen(pdata->product_id) > GTP_PRODUCT_ID_MAXSIZE) return rc; prop = of_find_property(np, "goodix,button-map", NULL); @@ -1807,9 +1735,13 @@ static int goodix_ts_probe(struct i2c_client *client, else dev_info(&client->dev, "GTP works in interrupt mode.\n"); - ret = gtp_read_version(client, &version_info); - if (ret != 2) { - dev_err(&client->dev, "Read version failed.\n"); + ret = gtp_read_fw_version(client, &version_info); + if (ret != 0) + 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"); goto exit_free_irq; } if (ts->use_irq) @@ -1874,7 +1806,6 @@ static int goodix_ts_remove(struct i2c_client *client) { struct goodix_ts_data *ts = i2c_get_clientdata(client); - GTP_DEBUG_FUNC(); #if defined(CONFIG_FB) if (fb_unregister_client(&ts->fb_notif)) dev_err(&client->dev, @@ -1935,9 +1866,7 @@ Output: *******************************************************/ static void goodix_ts_suspend(struct goodix_ts_data *ts) { - int ret = -1; - - GTP_DEBUG_FUNC(); + int ret = -1, i; #if GTP_ESD_PROTECT ts->gtp_is_suspend = 1; @@ -1951,6 +1880,12 @@ static void goodix_ts_suspend(struct goodix_ts_data *ts) gtp_irq_disable(ts); else hrtimer_cancel(&ts->timer); + + for (i = 0; i < GTP_MAX_TOUCH; i++) + gtp_touch_up(ts, i); + + input_sync(ts->input_dev); + ret = gtp_enter_sleep(ts); #endif if (ret < 0) @@ -1973,8 +1908,6 @@ static void goodix_ts_resume(struct goodix_ts_data *ts) { int ret = -1; - GTP_DEBUG_FUNC(); - ret = gtp_wakeup_sleep(ts); #if GTP_SLIDE_WAKEUP @@ -2101,9 +2034,6 @@ static int gtp_init_ext_watchdog(struct i2c_client *client) int ret; int retries = 0; - GTP_DEBUG("Init external watchdog..."); - GTP_DEBUG_FUNC(); - msg.flags = !I2C_M_RD; msg.addr = client->addr; msg.len = 4; @@ -2136,8 +2066,6 @@ static void gtp_esd_check_func(struct work_struct *work) struct goodix_ts_data *ts = NULL; u8 test[4] = {0x80, 0x40}; - GTP_DEBUG_FUNC(); - ts = i2c_get_clientdata(i2c_connect_client); if (ts->gtp_is_suspend) { @@ -2153,7 +2081,6 @@ static void gtp_esd_check_func(struct work_struct *work) for (i = 0; i < 3; i++) { ret = gtp_i2c_read(ts->client, test, 4); - GTP_DEBUG("0x8040 = 0x%02X, 0x8041 = 0x%02X", test[2], test[3]); if ((ret < 0)) { /* IC works abnormally..*/ continue; @@ -2224,7 +2151,6 @@ static int __init goodix_ts_init(void) { int ret; - GTP_DEBUG_FUNC(); #if GTP_ESD_PROTECT INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); @@ -2243,7 +2169,6 @@ Output: ********************************************************/ static void __exit goodix_ts_exit(void) { - GTP_DEBUG_FUNC(); i2c_del_driver(&goodix_ts_driver); } diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h index 185927c6d2b5..1cae9fa3b0ab 100644 --- a/drivers/input/touchscreen/gt9xx/gt9xx.h +++ b/drivers/input/touchscreen/gt9xx/gt9xx.h @@ -47,7 +47,7 @@ struct goodix_ts_platform_data { u32 irq_gpio_flags; int reset_gpio; u32 reset_gpio_flags; - u32 family_id; + const char *product_id; u32 x_max; u32 y_max; u32 x_min; @@ -104,7 +104,6 @@ extern u16 total_len; #define GTP_DRIVER_SEND_CFG 1 #define GTP_HAVE_TOUCH_KEY 1 #define GTP_POWER_CTRL_SLEEP 0 -#define GTP_ICS_SLOT_REPORT 1 /* auto updated by .bin file as default */ #define GTP_AUTO_UPDATE 0 @@ -121,7 +120,7 @@ extern u16 total_len; /* double-click wakeup, function together with GTP_SLIDE_WAKEUP */ #define GTP_DBL_CLK_WAKEUP 0 -#define GTP_DEBUG_ON 1 +#define GTP_DEBUG_ON 0 #define GTP_DEBUG_ARRAY_ON 0 #define GTP_DEBUG_FUNC_ON 0 @@ -206,30 +205,34 @@ extern u16 total_len; #define GTP_INT_TRIGGER GTP_IRQ_TAB_FALLING #endif -#define GTP_MAX_TOUCH 5 -#define GTP_ESD_CHECK_CIRCLE 2000 /* jiffy: ms */ +#define GTP_PRODUCT_ID_MAXSIZE 5 +#define GTP_PRODUCT_ID_BUFFER_MAXSIZE 6 +#define GTP_FW_VERSION_BUFFER_MAXSIZE 4 +#define GTP_MAX_TOUCH 5 +#define GTP_ESD_CHECK_CIRCLE 2000 /* jiffy: ms */ /***************************PART3:OTHER define*********************************/ -#define GTP_DRIVER_VERSION "V1.8<2013/06/08>" -#define GTP_I2C_NAME "Goodix-TS" -#define GTP_POLL_TIME 10 /* jiffy: ms*/ -#define GTP_ADDR_LENGTH 2 +#define GTP_DRIVER_VERSION "V1.8.1<2013/09/01>" +#define GTP_I2C_NAME "Goodix-TS" +#define GTP_POLL_TIME 10 /* jiffy: ms*/ +#define GTP_ADDR_LENGTH 2 #define GTP_CONFIG_MIN_LENGTH 186 #define GTP_CONFIG_MAX_LENGTH 240 -#define FAIL 0 -#define SUCCESS 1 -#define SWITCH_OFF 0 -#define SWITCH_ON 1 +#define FAIL 0 +#define SUCCESS 1 +#define SWITCH_OFF 0 +#define SWITCH_ON 1 /* Registers define */ -#define GTP_READ_COOR_ADDR 0x814E -#define GTP_REG_SLEEP 0x8040 -#define GTP_REG_SENSOR_ID 0x814A -#define GTP_REG_CONFIG_DATA 0x8047 -#define GTP_REG_VERSION 0x8140 +#define GTP_READ_COOR_ADDR 0x814E +#define GTP_REG_SLEEP 0x8040 +#define GTP_REG_SENSOR_ID 0x814A +#define GTP_REG_CONFIG_DATA 0x8047 +#define GTP_REG_FW_VERSION 0x8144 +#define GTP_REG_PRODUCT_ID 0x8140 -#define RESOLUTION_LOC 3 -#define TRIGGER_LOC 8 +#define RESOLUTION_LOC 3 +#define TRIGGER_LOC 8 /* Log define */ #define GTP_DEBUG(fmt, arg...) do {\ |