From 6a9ad61a324330f2c3db7a89fda429161b7d887e Mon Sep 17 00:00:00 2001 From: ronnie <ronnie@industiosoft.com> Date: Sun, 23 Oct 2022 10:04:50 +0000 Subject: [PATCH] add gt911 drivers --- longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xx/gt9xx.c | 1842 +++++++++--------- longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xxnew/gt9xx.c | 4084 ++++++++++------------------------------ 2 files changed, 1,994 insertions(+), 3,932 deletions(-) diff --git a/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xx/gt9xx.c b/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xx/gt9xx.c index 9406e47..f555183 100755 --- a/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xx/gt9xx.c +++ b/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xx/gt9xx.c @@ -28,18 +28,18 @@ #include <linux/pm.h> #if GTP_ICS_SLOT_REPORT - #include <linux/input/mt.h> +#include <linux/input/mt.h> #endif static const char *goodix_ts_name = "gt9xx"; static struct workqueue_struct *goodix_wq; struct i2c_client * i2c_connect_client = NULL; static u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH] - = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; += {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; #if GTP_HAVE_TOUCH_KEY - static const u16 touch_key_array[] = GTP_KEY_TAB; - #define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0])) +static const u16 touch_key_array[] = GTP_KEY_TAB; +#define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0])) #endif static s8 gtp_i2c_test(struct i2c_client *client); @@ -50,7 +50,7 @@ static void goodix_ts_early_suspend(struct early_suspend *h); static void goodix_ts_late_resume(struct early_suspend *h); #endif - + #if GTP_CREATE_WR_NODE extern s32 init_wr_node(struct i2c_client*); @@ -79,11 +79,11 @@ #define PRESS_MAX (255) -static int screen_max_x = 0; -static int screen_max_y = 0; -static int revert_x_flag = 0; +static int screen_max_x = 1280; +static int screen_max_y = 800; +static int revert_x_flag = 1; static int revert_y_flag = 0; -static int exchange_x_y_flag = 0; +static int exchange_x_y_flag = 1; static __u32 twi_id = 0; static char irq_pin_name[8]; @@ -100,7 +100,7 @@ }; #define dprintk(level_mask,fmt,arg...) if(unlikely(debug_mask & level_mask)) \ - printk("***CTP***"fmt, ## arg) + printk("***CTP***"fmt, ## arg) module_param_named(debug_mask,debug_mask,int,S_IRUGO | S_IWUSR | S_IWGRP); static const unsigned short normal_i2c[3] = {0x14, 0x5d, I2C_CLIENT_END}; @@ -129,27 +129,27 @@ static int ctp_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; - int ret = -1; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)){ - printk("======return=====\n"); - return -ENODEV; - } - - if(twi_id == adapter->nr){ - dprintk(DEBUG_INIT,"%s: addr = %x\n", __func__, client->addr); - ret = gtp_i2c_test(client); - printk("detect ret %d\n",ret); - if(!ret){ - printk("%s:I2C connection might be something wrong \n", __func__); - return -ENODEV; - }else{ - strlcpy(info->type, CTP_NAME, I2C_NAME_SIZE); - printk("======detect ok !=====\n"); - return 0; - } + int ret = -1; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)){ + printk("======return=====\n"); + return -ENODEV; + } + + if(twi_id == adapter->nr){ + dprintk(DEBUG_INIT,"%s: addr = %x\n", __func__, client->addr); + ret = gtp_i2c_test(client); + printk("detect ret %d\n",ret); + if(!ret){ + printk("%s:I2C connection might be something wrong \n", __func__); + return -ENODEV; + }else{ + strlcpy(info->type, CTP_NAME, I2C_NAME_SIZE); + printk("======detect ok !=====\n"); + return 0; + } }else{ - return -ENODEV; + return -ENODEV; } } @@ -208,450 +208,454 @@ void gtp_set_int_value(int status) { - long unsigned int config; - - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); - pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); + long unsigned int config; - if (1 != SUNXI_PINCFG_UNPACK_VALUE(config)){ - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,1); - pin_config_set(SUNXI_PINCTRL,irq_pin_name,config);; - } + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); + pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); - __gpio_set_value(CTP_IRQ_NUMBER, status); + if (1 != SUNXI_PINCFG_UNPACK_VALUE(config)){ + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,1); + pin_config_set(SUNXI_PINCTRL,irq_pin_name,config);; + } + + __gpio_set_value(CTP_IRQ_NUMBER, status); } void gtp_set_io_int(void) { - long unsigned int config; - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); - pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); + long unsigned int config; + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); + pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); - if (6 != SUNXI_PINCFG_UNPACK_VALUE(config)) { - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, 6); - pin_config_set(SUNXI_PINCTRL, irq_pin_name, config); - } - + if (6 != SUNXI_PINCFG_UNPACK_VALUE(config)) { + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, 6); + pin_config_set(SUNXI_PINCTRL, irq_pin_name, config); + } + } void gtp_io_init(int ms) { - ctp_wakeup(0, 0); - msleep(ms); - - gtp_set_int_value(0); - msleep(2); - - ctp_wakeup(1, 0); - msleep(6); + ctp_wakeup(0, 0); + msleep(ms); - + gtp_set_int_value(0); + msleep(2); + + ctp_wakeup(1, 0); + msleep(6); + + #if GTP_ESD_PROTECT - // gtp_init_ext_watchdog(client); + // gtp_init_ext_watchdog(client); #endif - + } /******************************************************* Function: - Read data from the i2c slave device. +Read data from the i2c slave device. Input: - client: i2c device. - buf[0]:operate address. - buf[1]~buf[len]:read data buffer. - len:operate length. - +client: i2c device. +buf[0]:operate address. +buf[1]~buf[len]:read data buffer. +len:operate length. + Output: - numbers of i2c_msgs to transfer -*********************************************************/ +numbers of i2c_msgs to transfer + *********************************************************/ s32 gtp_i2c_read(struct i2c_client *client, u8 *buf, s32 len) { - struct i2c_msg msgs[2]; - s32 ret = -1; - s32 retries = 0; - - msgs[0].flags = !I2C_M_RD; - msgs[0].addr = client->addr; - msgs[0].len = GTP_ADDR_LENGTH; - msgs[0].buf = &buf[0]; - - msgs[1].flags = I2C_M_RD; - msgs[1].addr = client->addr; - msgs[1].len = len - GTP_ADDR_LENGTH; - msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + struct i2c_msg msgs[2]; + s32 ret = -1; + s32 retries = 0; - while(retries < 2) { - ret = i2c_transfer(client->adapter, msgs, 2); - if(ret == 2) - break; - retries++; - } + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; - if(retries >= 2) { - printk("%s:I2C retry timeout, reset chip.", __func__); - } - return ret; + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; + + while(retries < 2) { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2) + break; + retries++; + } + + if(retries >= 2) { + printk("%s:I2C retry timeout, reset chip.", __func__); + } + return ret; } /******************************************************* Function: - write data to the i2c slave device. +write data to the i2c slave device. Input: - client: i2c device. - buf[0]:operate address. - buf[1]~buf[len]:write data buffer. - len:operate length. - +client: i2c device. +buf[0]:operate address. +buf[1]~buf[len]:write data buffer. +len:operate length. + Output: - numbers of i2c_msgs to transfer. -*********************************************************/ +numbers of i2c_msgs to transfer. + *********************************************************/ s32 gtp_i2c_write(struct i2c_client *client,u8 *buf,s32 len) { - struct i2c_msg msg; - s32 ret = -1; - s32 retries = 0; - - msg.flags = !I2C_M_RD; - msg.addr = client->addr; - msg.len = len; - msg.buf = buf; - - while(retries < 2) { - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret == 1) - break; - retries++; - } + struct i2c_msg msg; + s32 ret = -1; + s32 retries = 0; - if(retries >= 2) { - printk("%s:I2C retry timeout, reset chip.", __func__); - } - return ret; + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; + + while(retries < 2) { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1) + break; + retries++; + } + + if(retries >= 2) { + printk("%s:I2C retry timeout, reset chip.", __func__); + } + return ret; } /******************************************************* Function: - Send config Function. +Send config Function. Input: - client: i2c client. +client: i2c client. Output: - Executive outcomes.0--success,non-0--fail. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ s32 gtp_send_cfg(struct i2c_client *client) { - s32 ret = 0; - -#if GTP_DRIVER_SEND_CFG - s32 retry = 0; + s32 ret = 0; - for (retry = 0; retry < 5; retry++) - { - //ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); - // if (ret > 0) - // { - // break; - // } - } +#if GTP_DRIVER_SEND_CFG + s32 retry = 0; + + for (retry = 0; retry < 5; retry++) + { + //ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); + // if (ret > 0) + // { + // break; + // } + } #endif - return ret; + return ret; } /******************************************************* Function: - Disable IRQ Function. +Disable IRQ Function. Input: - ts: i2c client private struct. - +ts: i2c client private struct. + Output: - None. -*******************************************************/ +None. + *******************************************************/ void gtp_irq_disable(struct goodix_ts_data *ts) { - unsigned long irqflags; - int ret; + unsigned long irqflags; + int ret; - dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); - spin_lock_irqsave(&ts->irq_lock, irqflags); - if (!ts->irq_is_disable) { - ts->irq_is_disable = 1; - ret = input_set_int_enable(&(config_info.input_type), 0); - if (ret < 0) - dprintk(DEBUG_OTHERS_INFO,"%s irq disable failed\n", goodix_ts_name); - } - spin_unlock_irqrestore(&ts->irq_lock, irqflags); + dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (!ts->irq_is_disable) { + ts->irq_is_disable = 1; + ret = input_set_int_enable(&(config_info.input_type), 0); + if (ret < 0) + dprintk(DEBUG_OTHERS_INFO,"%s irq disable failed\n", goodix_ts_name); + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); } /******************************************************* Function: - Disable IRQ Function. +Disable IRQ Function. Input: - ts: i2c client private struct. - +ts: i2c client private struct. + Output: - None. -*******************************************************/ +None. + *******************************************************/ void gtp_irq_enable(struct goodix_ts_data *ts) { - unsigned long irqflags = 0; - int ret; + unsigned long irqflags = 0; + int ret; - dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); - - spin_lock_irqsave(&ts->irq_lock, irqflags); - if (ts->irq_is_disable) { - ts->irq_is_disable = 0; - ret = input_set_int_enable(&(config_info.input_type), 1); - if (ret < 0) - dprintk(DEBUG_OTHERS_INFO,"%s irq enable failed\n", goodix_ts_name); - } - spin_unlock_irqrestore(&ts->irq_lock, irqflags); + dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (ts->irq_is_disable) { + ts->irq_is_disable = 0; + ret = input_set_int_enable(&(config_info.input_type), 1); + if (ret < 0) + dprintk(DEBUG_OTHERS_INFO,"%s irq enable failed\n", goodix_ts_name); + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); } /******************************************************* Function: - Touch down report function. +Touch down report function. Input: - ts:private data. - id:tracking id. - x:input x. - y:input y. - w:input weight. - +ts:private data. +id:tracking id. +x:input x. +y:input y. +w:input weight. + Output: - None. -*******************************************************/ +None. + *******************************************************/ static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w) { - dprintk(DEBUG_X_Y_INFO, "source data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); - - if(1 == exchange_x_y_flag){ - swap(x, y); - } - - if(1 == revert_x_flag){ - x = SCREEN_MAX_X - x; - } - - if(1 == revert_y_flag){ - y = SCREEN_MAX_Y - y; - } - - dprintk(DEBUG_X_Y_INFO,"report data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); + dprintk(DEBUG_X_Y_INFO, "source data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); + + //printk(KERN_ERR"revert_x_flag=%d, revert_y_flag=%d, GTP_ICS_SLOT_REPORT=%d V2 SCREEN_MAX_X:SCREEN_MAX_Y=%d:%d\n", revert_x_flag, revert_y_flag, GTP_ICS_SLOT_REPORT, SCREEN_MAX_X, SCREEN_MAX_Y); + printk(KERN_ERR"(%d,%d)--->", x, y); + + if(1 == exchange_x_y_flag){ + swap(x, y); + } + + if(1 == revert_x_flag){ + x = SCREEN_MAX_X - x; + } + + if(1 == revert_y_flag){ + y = SCREEN_MAX_Y - y; + } + printk(KERN_ERR"(%d,%d)\n", x, y); + + dprintk(DEBUG_X_Y_INFO,"report data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); #if GTP_ICS_SLOT_REPORT - input_mt_slot(ts->input_dev, id); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); - 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_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + 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_key(ts->input_dev, BTN_TOUCH, 1); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); 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_mt_sync(ts->input_dev); + 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_mt_sync(ts->input_dev); #endif } /******************************************************* Function: - Touch up report function. +Touch up report function. Input: - ts:private data. - +ts:private data. + Output: - None. -*******************************************************/ +None. + *******************************************************/ static void gtp_touch_up(struct goodix_ts_data* ts, s32 id) { #if GTP_ICS_SLOT_REPORT - input_mt_slot(ts->input_dev, id); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); - dprintk(DEBUG_X_Y_INFO, "Touch id[%2d] release!", id); + input_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); + dprintk(DEBUG_X_Y_INFO, "Touch id[%2d] release!", id); #else input_report_key(ts->input_dev, BTN_TOUCH, 0); - 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); + 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 } /******************************************************* Function: - Goodix touchscreen work function. +Goodix touchscreen work function. Input: - work: work_struct of goodix_wq. - +work: work_struct of goodix_wq. + Output: - None. -*******************************************************/ +None. + *******************************************************/ static void goodix_ts_work_func(struct work_struct *work) { - u8 end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; - u8 point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; - u8 touch_num = 0; - u8 finger = 0; - static u16 pre_touch = 0; - static u8 pre_key = 0; - u8 key_value = 0; - u8* coor_data = NULL; - s32 input_x = 0; - s32 input_y = 0; - s32 input_w = 0; - s32 id = 0; - s32 i = 0; - int j = 0; - s32 ret = -1; - struct goodix_ts_data *ts = NULL; + u8 end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; + u8 point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; + u8 touch_num = 0; + u8 finger = 0; + static u16 pre_touch = 0; + static u8 pre_key = 0; + u8 key_value = 0; + u8* coor_data = NULL; + s32 input_x = 0; + s32 input_y = 0; + s32 input_w = 0; + s32 id = 0; + s32 i = 0; + int j = 0; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; - dprintk(DEBUG_X_Y_INFO,"===enter %s===\n",__func__); + dprintk(DEBUG_X_Y_INFO,"===enter %s===\n",__func__); - ts = container_of(work, struct goodix_ts_data, work); - if (ts->enter_update){ - return; - } + ts = container_of(work, struct goodix_ts_data, work); + if (ts->enter_update){ + return; + } - for(j=0; j<2;j++) - { - ret = gtp_i2c_read(ts->client, point_data, 12); - if (ret < 0){ - printk("I2C transfer error. errno:%d\n ", ret); - goto exit_work_func; - } + for(j=0; j<2;j++) + { + ret = gtp_i2c_read(ts->client, point_data, 12); + if (ret < 0){ + printk("I2C transfer error. errno:%d\n ", ret); + goto exit_work_func; } + } - finger = point_data[GTP_ADDR_LENGTH]; - if((finger & 0x80) == 0) { - goto exit_work_func; - } + finger = point_data[GTP_ADDR_LENGTH]; + if((finger & 0x80) == 0) { + goto exit_work_func; + } - touch_num = finger & 0x0f; - if (touch_num > GTP_MAX_TOUCH) { - goto exit_work_func; - } + touch_num = finger & 0x0f; + if (touch_num > GTP_MAX_TOUCH) { + goto exit_work_func; + } - if (touch_num > 1) { - u8 buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff}; + if (touch_num > 1) { + u8 buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff}; - ret = gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num - 1)); - memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); - } + ret = gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num - 1)); + memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); + } #if GTP_HAVE_TOUCH_KEY - key_value = point_data[3 + 8 * touch_num]; - - if(key_value || pre_key) { - for (i = 0; i < GTP_MAX_KEY_NUM; i++) { - input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<<i)); - } - touch_num = 0; - pre_touch = 0; - } -#endif - pre_key = key_value; + key_value = point_data[3 + 8 * touch_num]; - dprintk(DEBUG_X_Y_INFO, "pre_touch:%02x, finger:%02x.", pre_touch, finger); + if(key_value || pre_key) { + for (i = 0; i < GTP_MAX_KEY_NUM; i++) { + input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<<i)); + } + touch_num = 0; + pre_touch = 0; + } +#endif + pre_key = key_value; + + dprintk(DEBUG_X_Y_INFO, "pre_touch:%02x, finger:%02x.", pre_touch, finger); #if GTP_ICS_SLOT_REPORT - if (pre_touch || touch_num) { - s32 pos = 0; - u16 touch_index = 0; - coor_data = &point_data[3]; - - if(touch_num) { - id = coor_data[pos] & 0x0F; - touch_index |= (0x01<<id); - } + if (pre_touch || touch_num) { + s32 pos = 0; + u16 touch_index = 0; + coor_data = &point_data[3]; - dprintk(DEBUG_X_Y_INFO, - "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 (touch_index & (0x01<<i)) { - input_x = coor_data[pos + 1] | coor_data[pos + 2] << 8; - input_y = coor_data[pos + 3] | coor_data[pos + 4] << 8; - input_w = coor_data[pos + 5] | coor_data[pos + 6] << 8; + if(touch_num) { + id = coor_data[pos] & 0x0F; + touch_index |= (0x01<<id); + } - gtp_touch_down(ts, id, input_x, input_y, input_w); - pre_touch |= 0x01 << i; + dprintk(DEBUG_X_Y_INFO, + "id=%d, touch_index=0x%x, pre_touch=0x%x\n", id, touch_index, pre_touch); - pos += 8; - id = coor_data[pos] & 0x0F; - touch_index |= (0x01<<id); - }else {// if (pre_touch & (0x01 << i)) - - gtp_touch_up(ts, i); - pre_touch &= ~(0x01 << i); - } - } - } + for (i = 0; i < GTP_MAX_TOUCH; i++) { + if (touch_index & (0x01<<i)) { + input_x = coor_data[pos + 1] | coor_data[pos + 2] << 8; + input_y = coor_data[pos + 3] | coor_data[pos + 4] << 8; + input_w = coor_data[pos + 5] | coor_data[pos + 6] << 8; + + gtp_touch_down(ts, id, input_x, input_y, input_w); + pre_touch |= 0x01 << i; + + pos += 8; + id = coor_data[pos] & 0x0F; + touch_index |= (0x01<<id); + }else {// if (pre_touch & (0x01 << i)) + + gtp_touch_up(ts, i); + pre_touch &= ~(0x01 << i); + } + } + } #else - if (touch_num ) { - for (i = 0; i < touch_num; i++) { - coor_data = &point_data[i * 8 + 3]; + if (touch_num ) { + for (i = 0; i < touch_num; i++) { + coor_data = &point_data[i * 8 + 3]; - id = coor_data[0] & 0x0F; - 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; + id = coor_data[0] & 0x0F; + 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; - gtp_touch_down(ts, id, input_x, input_y, input_w); - } - }else if(pre_touch){ - dprintk(DEBUG_X_Y_INFO, "Touch Release!"); - gtp_touch_up(ts, 0); - } - - pre_touch = touch_num; + gtp_touch_down(ts, id, input_x, input_y, input_w); + } + }else if(pre_touch){ + dprintk(DEBUG_X_Y_INFO, "Touch Release!"); + gtp_touch_up(ts, 0); + } + + pre_touch = touch_num; #endif - input_sync(ts->input_dev); + input_sync(ts->input_dev); exit_work_func: - if(!ts->gtp_rawdiff_mode) { - ret = gtp_i2c_write(ts->client, end_cmd, 3); - if (ret < 0) { - printk("I2C write end_cmd error!"); - } - } - return ; + if(!ts->gtp_rawdiff_mode) { + ret = gtp_i2c_write(ts->client, end_cmd, 3); + if (ret < 0) { + printk("I2C write end_cmd error!"); + } + } + return ; } /******************************************************* Function: - External interrupt service routine. +External interrupt service routine. Input: - irq: interrupt number. - dev_id: private data pointer. - +irq: interrupt number. +dev_id: private data pointer. + Output: - irq execute status. -*******************************************************/ +irq execute status. + *******************************************************/ irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) { - struct goodix_ts_data *ts = (struct goodix_ts_data *)dev_id; - dprintk(DEBUG_INT_INFO, "==========------TS Interrupt-----============\n"); + struct goodix_ts_data *ts = (struct goodix_ts_data *)dev_id; + dprintk(DEBUG_INT_INFO, "==========------TS Interrupt-----============\n"); - queue_work(goodix_wq, &ts->work); - return 0; + queue_work(goodix_wq, &ts->work); + return 0; } @@ -659,509 +663,509 @@ /******************************************************* Function: - Eter sleep function. +Eter sleep function. Input: - ts:private data. - +ts:private data. + Output: - Executive outcomes.0--success,non-0--fail. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ #if defined(CONFIG_HAS_EARLYSUSPEND) | defined(CONFIG_PM) static s8 gtp_enter_sleep(struct goodix_ts_data * ts) { - s8 ret = -1; - s8 retry = 0; - u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; - - dprintk(DEBUG_SUSPEND, "%s start!\n", __func__); - - gtp_set_int_value(0); + s8 ret = -1; + s8 retry = 0; + u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; - while(retry++ < 2) { - ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); - if (ret > 0) { - dprintk(DEBUG_SUSPEND, "GTP enter sleep!"); - return ret; - } - msleep(10); - } - dprintk(DEBUG_SUSPEND, "GTP send sleep cmd failed."); - - return ret; + dprintk(DEBUG_SUSPEND, "%s start!\n", __func__); + + gtp_set_int_value(0); + + while(retry++ < 2) { + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret > 0) { + dprintk(DEBUG_SUSPEND, "GTP enter sleep!"); + return ret; + } + msleep(10); + } + dprintk(DEBUG_SUSPEND, "GTP send sleep cmd failed."); + + return ret; } #endif /******************************************************* Function: - Wakeup from sleep mode Function. +Wakeup from sleep mode Function. Input: - ts: private data. - +ts: private data. + Output: - Executive outcomes.0--success,non-0--fail. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ static s8 gtp_wakeup_sleep(struct goodix_ts_data * ts) { - u8 retry = 0; - s8 ret = -1; - - gtp_io_init(20); - gtp_set_io_int(); - + u8 retry = 0; + s8 ret = -1; + + gtp_io_init(20); + gtp_set_io_int(); + #if GTP_POWER_CTRL_SLEEP - while(retry++ < 5) - { - ret = gtp_send_cfg(ts->client); - if (ret > 0) - { - dprintk(DEBUG_SUSPEND, "Wakeup sleep send config success."); - return ret; - } - } - - printk("GTP wakeup sleep failed."); - return ret; -#endif - -} - - -/******************************************************* -Function: - GTP initialize function. - -Input: - ts: i2c client private struct. - -Output: - Executive outcomes.0---succeed. -*******************************************************/ -static s32 gtp_init_panel(struct goodix_ts_data *ts) + while(retry++ < 5) { - s32 ret = -1; - -#if GTP_DRIVER_SEND_CFG - s32 i; - u8 check_sum = 0; - u8 rd_cfg_buf[16]; - int index =0; - -#if 1 - u8 cfg_info_group1[] = CTP_CFG_GROUP1; - u8 cfg_info_group2[] = CTP_CFG_GROUP2; - u8 cfg_info_group3[] = CTP_CFG_GROUP3; - u8 cfg_info_group4[] = CTP_CFG_GROUP4; - u8 cfg_info_group5[] = CTP_CFG_GROUP5; - u8 cfg_info_group6[] = CTP_CFG_GROUP6; -// u8 cfg_info_group7[] = CTP_CFG_GROUP7; -#else - u8 cfg_info_group1[] = {}; - u8 cfg_info_group2[] = {}; - u8 cfg_info_group3[] = {}; - u8 cfg_info_group4[] = {}; - u8 cfg_info_group5[] = {}; - u8 cfg_info_group6[] = {}; -// u8 cfg_info_group7[] = {}; -#endif - - u8 *send_cfg_buf[] = {cfg_info_group1,cfg_info_group2,cfg_info_group3,cfg_info_group4,cfg_info_group5,cfg_info_group6}; - u8 cfg_info_len[] = {sizeof(cfg_info_group1)/sizeof(cfg_info_group1[0]),\ - sizeof(cfg_info_group2)/sizeof(cfg_info_group2[0]),\ - sizeof(cfg_info_group3)/sizeof(cfg_info_group3[0]),\ - sizeof(cfg_info_group4)/sizeof(cfg_info_group4[0]),\ - sizeof(cfg_info_group5)/sizeof(cfg_info_group5[0]),\ - sizeof(cfg_info_group6)/sizeof(cfg_info_group6[0])}; - //sizeof(cfg_info_group7)/sizeof(cfg_info_group7[0])}; -#if 0 //gandy - for(i=0; i<3; i++) - { - if(cfg_info_len[i] > ts->gtp_cfg_len) - { - ts->gtp_cfg_len = cfg_info_len[i]; - } - } -#endif - - GTP_DEBUG("len1=%d,len2=%d,len3=%d,send_len:%d",cfg_info_len[0],cfg_info_len[1],cfg_info_len[2],ts->gtp_cfg_len); -#if 0 - if ((!cfg_info_len[1]) && (!cfg_info_len[2])) - { - rd_cfg_buf[GTP_ADDR_LENGTH] = 0; - } - else -#endif - printk("gtp_i2c_read GTP_REG_SENSOR_ID \n"); - { - rd_cfg_buf[0] = GTP_REG_SENSOR_ID >> 8; - rd_cfg_buf[1] = GTP_REG_SENSOR_ID & 0xff; - ret = gtp_i2c_read(ts->client, rd_cfg_buf, 3); - if (ret < 0) - { - GTP_ERROR("Read SENSOR ID failed,default use group1 config!"); - rd_cfg_buf[GTP_ADDR_LENGTH] = 0; - } - rd_cfg_buf[GTP_ADDR_LENGTH] &= 0x07; - } - -#if 0 - if(screen_max_x == 800 && screen_max_y == 480) - { - if(rd_cfg_buf[GTP_ADDR_LENGTH] == 3) - index = 0; - else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 4) - index = 1; - else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 5) - index = 3; - else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 0) - index = 6; - } - else if(screen_max_x == 1024 && screen_max_y == 600) - { - if(rd_cfg_buf[GTP_ADDR_LENGTH] == 0) - index = 5; - else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 3) - index = 2; - } -#endif - GTP_DEBUG("CTP name : %s\n",config_info.name); - if (!strcmp(config_info.name,"gt911_805d5")){ - index = 0; - GTP_DEBUG("gt9xx:index = %d\n",index); - - } else if (!strcmp(config_info.name,"gt911_g912")){ - index = 2; - GTP_DEBUG("gt9xx:index = %d\n",index); - - } else if (!strcmp(config_info.name,"gt911_xw785")){ - index = 3; - GTP_DEBUG("gt9xx:index = %d\n",index); - - } else {//default gt9xx_ts - index = 1; //default p4 - GTP_DEBUG("gt9xx:index = %d\n",index); - } - - printk("config send_cfg_buf******** \n"); - //index = rd_cfg_buf[GTP_ADDR_LENGTH]; - ts->gtp_cfg_len = cfg_info_len[index]; - GTP_DEBUG("gandy---SENSOR ID:%d\n", rd_cfg_buf[GTP_ADDR_LENGTH]); - memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); - memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[index], ts->gtp_cfg_len); - -#if GTP_CUSTOM_CFG - config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; - config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); - config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; - config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); - - if (GTP_INT_TRIGGER == 0) //RISING - { - config[TRIGGER_LOC] &= 0xfe; - } - else if (GTP_INT_TRIGGER == 1) //FALLING - { - config[TRIGGER_LOC] |= 0x01; - } -#endif //endif GTP_CUSTOM_CFG - - check_sum = 0; - for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) - { - check_sum += config[i]; - } - config[ts->gtp_cfg_len] = (~check_sum) + 1; - -#else //else DRIVER NEED NOT SEND CONFIG - - if(ts->gtp_cfg_len == 0) - { - ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; - } - ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH); - if (ret < 0) - { - GTP_ERROR("GTP read resolution & max_touch_num failed, use default value!"); - ts->abs_x_max = GTP_MAX_WIDTH; - ts->abs_y_max = GTP_MAX_HEIGHT; - ts->int_trigger_type = GTP_INT_TRIGGER; - } -#endif //endif GTP_DRIVER_SEND_CFG - - GTP_DEBUG_FUNC(); - - ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC]; - ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2]; - ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; - if ((!ts->abs_x_max)||(!ts->abs_y_max)) - { - GTP_ERROR("GTP resolution & max_touch_num invalid, use default value!"); - ts->abs_x_max = GTP_MAX_WIDTH; - ts->abs_y_max = GTP_MAX_HEIGHT; - } - - msleep(100); ret = gtp_send_cfg(ts->client); - if (ret < 0) + if (ret > 0) { - printk("\ngandy-----send config error.ret=%d\n",ret); - GTP_ERROR("Send config error."); + dprintk(DEBUG_SUSPEND, "Wakeup sleep send config success."); + return ret; } - printk("X_MAX = %d,Y_MAX = %d,TRIGGER = 0x%02x", - ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); - - msleep(10); - - return 0; } + printk("GTP wakeup sleep failed."); + return ret; +#endif + +} + + /******************************************************* Function: - Read goodix touchscreen version function. +GTP initialize function. Input: - client: i2c client struct. - version:address to store version info - +ts: i2c client private struct. + Output: - Executive outcomes.0---succeed. -*******************************************************/ +Executive outcomes.0---succeed. + *******************************************************/ +static s32 gtp_init_panel(struct goodix_ts_data *ts) +{ + s32 ret = -1; + +#if GTP_DRIVER_SEND_CFG + s32 i; + u8 check_sum = 0; + u8 rd_cfg_buf[16]; + int index =0; + +#if 1 + u8 cfg_info_group1[] = CTP_CFG_GROUP1; + u8 cfg_info_group2[] = CTP_CFG_GROUP2; + u8 cfg_info_group3[] = CTP_CFG_GROUP3; + u8 cfg_info_group4[] = CTP_CFG_GROUP4; + u8 cfg_info_group5[] = CTP_CFG_GROUP5; + u8 cfg_info_group6[] = CTP_CFG_GROUP6; + // u8 cfg_info_group7[] = CTP_CFG_GROUP7; +#else + u8 cfg_info_group1[] = {}; + u8 cfg_info_group2[] = {}; + u8 cfg_info_group3[] = {}; + u8 cfg_info_group4[] = {}; + u8 cfg_info_group5[] = {}; + u8 cfg_info_group6[] = {}; + // u8 cfg_info_group7[] = {}; +#endif + + u8 *send_cfg_buf[] = {cfg_info_group1,cfg_info_group2,cfg_info_group3,cfg_info_group4,cfg_info_group5,cfg_info_group6}; + u8 cfg_info_len[] = {sizeof(cfg_info_group1)/sizeof(cfg_info_group1[0]),\ + sizeof(cfg_info_group2)/sizeof(cfg_info_group2[0]),\ + sizeof(cfg_info_group3)/sizeof(cfg_info_group3[0]),\ + sizeof(cfg_info_group4)/sizeof(cfg_info_group4[0]),\ + sizeof(cfg_info_group5)/sizeof(cfg_info_group5[0]),\ + sizeof(cfg_info_group6)/sizeof(cfg_info_group6[0])}; + //sizeof(cfg_info_group7)/sizeof(cfg_info_group7[0])}; +#if 0 //gandy +for(i=0; i<3; i++) +{ + if(cfg_info_len[i] > ts->gtp_cfg_len) + { + ts->gtp_cfg_len = cfg_info_len[i]; + } +} +#endif + +GTP_DEBUG("len1=%d,len2=%d,len3=%d,send_len:%d",cfg_info_len[0],cfg_info_len[1],cfg_info_len[2],ts->gtp_cfg_len); +#if 0 +if ((!cfg_info_len[1]) && (!cfg_info_len[2])) +{ + rd_cfg_buf[GTP_ADDR_LENGTH] = 0; +} +else +#endif +printk("gtp_i2c_read GTP_REG_SENSOR_ID \n"); +{ + rd_cfg_buf[0] = GTP_REG_SENSOR_ID >> 8; + rd_cfg_buf[1] = GTP_REG_SENSOR_ID & 0xff; + ret = gtp_i2c_read(ts->client, rd_cfg_buf, 3); + if (ret < 0) + { + GTP_ERROR("Read SENSOR ID failed,default use group1 config!"); + rd_cfg_buf[GTP_ADDR_LENGTH] = 0; + } + rd_cfg_buf[GTP_ADDR_LENGTH] &= 0x07; +} + +#if 0 +if(screen_max_x == 800 && screen_max_y == 480) +{ + if(rd_cfg_buf[GTP_ADDR_LENGTH] == 3) + index = 0; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 4) + index = 1; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 5) + index = 3; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 0) + index = 6; +} +else if(screen_max_x == 1024 && screen_max_y == 600) +{ + if(rd_cfg_buf[GTP_ADDR_LENGTH] == 0) + index = 5; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 3) + index = 2; +} +#endif +GTP_DEBUG("CTP name : %s\n",config_info.name); +if (!strcmp(config_info.name,"gt911_805d5")){ + index = 0; + GTP_DEBUG("gt9xx:index = %d\n",index); + +} else if (!strcmp(config_info.name,"gt911_g912")){ + index = 2; + GTP_DEBUG("gt9xx:index = %d\n",index); + +} else if (!strcmp(config_info.name,"gt911_xw785")){ + index = 3; + GTP_DEBUG("gt9xx:index = %d\n",index); + +} else {//default gt9xx_ts + index = 1; //default p4 + GTP_DEBUG("gt9xx:index = %d\n",index); +} + +printk("config send_cfg_buf******** \n"); +//index = rd_cfg_buf[GTP_ADDR_LENGTH]; +ts->gtp_cfg_len = cfg_info_len[index]; +GTP_DEBUG("gandy---SENSOR ID:%d\n", rd_cfg_buf[GTP_ADDR_LENGTH]); +memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); +memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[index], ts->gtp_cfg_len); + +#if GTP_CUSTOM_CFG +config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; +config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); +config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; +config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); + +if (GTP_INT_TRIGGER == 0) //RISING +{ + config[TRIGGER_LOC] &= 0xfe; +} +else if (GTP_INT_TRIGGER == 1) //FALLING +{ + config[TRIGGER_LOC] |= 0x01; +} +#endif //endif GTP_CUSTOM_CFG + +check_sum = 0; +for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) +{ + check_sum += config[i]; +} +config[ts->gtp_cfg_len] = (~check_sum) + 1; + +#else //else DRIVER NEED NOT SEND CONFIG + +if(ts->gtp_cfg_len == 0) +{ + ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; +} +ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH); +if (ret < 0) +{ + GTP_ERROR("GTP read resolution & max_touch_num failed, use default value!"); + ts->abs_x_max = GTP_MAX_WIDTH; + ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; +} +#endif //endif GTP_DRIVER_SEND_CFG + +GTP_DEBUG_FUNC(); + +ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC]; +ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2]; +ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; +if ((!ts->abs_x_max)||(!ts->abs_y_max)) +{ + GTP_ERROR("GTP resolution & max_touch_num invalid, use default value!"); + ts->abs_x_max = GTP_MAX_WIDTH; + ts->abs_y_max = GTP_MAX_HEIGHT; +} + +msleep(100); +ret = gtp_send_cfg(ts->client); +if (ret < 0) +{ + printk("\ngandy-----send config error.ret=%d\n",ret); + GTP_ERROR("Send config error."); +} +printk("X_MAX = %d,Y_MAX = %d,TRIGGER = 0x%02x", + ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + +msleep(10); + +return 0; +} + +/******************************************************* +Function: +Read goodix touchscreen version function. + +Input: +client: i2c client struct. +version:address to store version info + +Output: +Executive outcomes.0---succeed. + *******************************************************/ s32 gtp_read_version(struct i2c_client *client, u16* version) { - s32 ret = -1; - u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; + s32 ret = -1; + u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; - dprintk(DEBUG_INIT, "%s ---start!.---\n", __func__); + dprintk(DEBUG_INIT, "%s ---start!.---\n", __func__); - ret = gtp_i2c_read(client, buf, sizeof(buf)); - if (ret < 0) { - printk("GTP read version failed"); - return ret; - } + ret = gtp_i2c_read(client, buf, sizeof(buf)); + if (ret < 0) { + printk("GTP read version failed"); + return ret; + } - if (version) { - *version = (buf[7] << 8) | buf[6]; - } + if (version) { + *version = (buf[7] << 8) | buf[6]; + } - if (buf[5] == 0x00) { - printk("IC Version: %c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[7], buf[6]); - } - else { - printk("IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); - } - return ret; + if (buf[5] == 0x00) { + printk("IC Version: %c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[7], buf[6]); + } + else { + printk("IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); + } + return ret; } /******************************************************* Function: - I2c test Function. +I2c test Function. Input: - client:i2c client. - +client:i2c client. + Output: - Executive outcomes.0--success,non-0--fail. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ static s8 gtp_i2c_test(struct i2c_client *client) { - u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; - u8 retry = 0; - s8 ret = -1; - - while(retry++ < 2) { - ret = gtp_i2c_read(client, test, 3); - if (ret > 0) { - return ret; - } - printk("GTP i2c test failed time %d.",retry); - msleep(10); - } - return ret; + u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + u8 retry = 0; + s8 ret = -1; + + while(retry++ < 2) { + ret = gtp_i2c_read(client, test, 3); + if (ret > 0) { + return ret; + } + printk("GTP i2c test failed time %d.",retry); + msleep(10); + } + return ret; } /******************************************************* Function: - Request input device Function. +Request input device Function. Input: - ts:private data. - +ts:private data. + Output: - Executive outcomes.0--success,non-0--fail. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ static s8 gtp_request_input_dev(struct goodix_ts_data *ts) { - s8 ret = -1; + s8 ret = -1; #if GTP_HAVE_TOUCH_KEY - u8 index = 0; + u8 index = 0; #endif - - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) { - GTP_ERROR("Failed to allocate input device."); - return -ENOMEM; - } - ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + GTP_ERROR("Failed to allocate input device."); + return -ENOMEM; + } + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; #if GTP_ICS_SLOT_REPORT - __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - input_mt_init_slots(ts->input_dev, 255); + __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + input_mt_init_slots(ts->input_dev, 255, 1); #else - ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); #endif #if GTP_HAVE_TOUCH_KEY - for (index = 0; index < GTP_MAX_KEY_NUM; index++) { - input_set_capability(ts->input_dev,EV_KEY,touch_key_array[index]); - } + for (index = 0; index < GTP_MAX_KEY_NUM; index++) { + input_set_capability(ts->input_dev,EV_KEY,touch_key_array[index]); + } #endif -//#if GTP_CHANGE_X2Y -// GTP_SWAP(ts->abs_x_max, ts->abs_y_max); -//#endif + //#if GTP_CHANGE_X2Y + // GTP_SWAP(ts->abs_x_max, ts->abs_y_max); + //#endif set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit); set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit); set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit); set_bit(ABS_MT_WIDTH_MAJOR, ts->input_dev->absbit); - - - - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); + + + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - - ts->input_dev->name = CTP_NAME; - ts->input_dev->phys = "input/goodix-ts"; - ts->input_dev->id.bustype = BUS_I2C; - ts->input_dev->id.vendor = 0xDEAD; - ts->input_dev->id.product = 0xBEEF; - ts->input_dev->id.version = 10427; - ret = input_register_device(ts->input_dev); - if (ret) { - printk("Register %s input device failed", ts->input_dev->name); - return -ENODEV; - } + + ts->input_dev->name = CTP_NAME; + ts->input_dev->phys = "input/goodix-ts"; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0xDEAD; + ts->input_dev->id.product = 0xBEEF; + ts->input_dev->id.version = 10427; + ret = input_register_device(ts->input_dev); + if (ret) { + printk("Register %s input device failed", ts->input_dev->name); + return -ENODEV; + } #ifdef CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ts->early_suspend.suspend = goodix_ts_early_suspend; - ts->early_suspend.resume = goodix_ts_late_resume; - register_early_suspend(&ts->early_suspend); + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = goodix_ts_early_suspend; + ts->early_suspend.resume = goodix_ts_late_resume; + register_early_suspend(&ts->early_suspend); #endif - return 0; + return 0; } /******************************************************* Function: - Goodix touchscreen probe function. +Goodix touchscreen probe function. Input: - client: i2c device struct. - id:device id. - +client: i2c device struct. +id:device id. + Output: - Executive outcomes. 0---succeed. -*******************************************************/ +Executive outcomes. 0---succeed. + *******************************************************/ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { - s32 ret = -1; - struct goodix_ts_data *ts; - u16 version_info; - - dprintk(DEBUG_INIT, "GTP Driver Version:%s\n",GTP_DRIVER_VERSION); - printk("GTP I2C Address:0x%02x\n", client->addr); + s32 ret = -1; + struct goodix_ts_data *ts; + u16 version_info; - i2c_connect_client = client; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - printk("I2C check functionality failed.\n"); - return -ENODEV; - } - - ts = kzalloc(sizeof(*ts), GFP_KERNEL); - if (ts == NULL) { - printk("Alloc GFP_KERNEL memory failed.\n"); - return -ENOMEM; - } - - memset(ts, 0, sizeof(*ts)); - INIT_WORK(&ts->work, goodix_ts_work_func); - ts->client = client; - i2c_set_clientdata(client, ts); - //ts->irq_lock = SPIN_LOCK_UNLOCKED; - ts->gtp_rawdiff_mode = 0; + dprintk(DEBUG_INIT, "GTP Driver Version:%s\n",GTP_DRIVER_VERSION); + printk("GTP I2C Address:0x%02x\n", client->addr); + + i2c_connect_client = client; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + printk("I2C check functionality failed.\n"); + return -ENODEV; + } + + ts = kzalloc(sizeof(*ts), GFP_KERNEL); + if (ts == NULL) { + printk("Alloc GFP_KERNEL memory failed.\n"); + return -ENOMEM; + } + + memset(ts, 0, sizeof(*ts)); + INIT_WORK(&ts->work, goodix_ts_work_func); + ts->client = client; + i2c_set_clientdata(client, ts); + //ts->irq_lock = SPIN_LOCK_UNLOCKED; + ts->gtp_rawdiff_mode = 0; - ret = gtp_i2c_test(client); - if (ret < 0){ - printk("I2C communication ERROR!\n"); - goto exit_device_detect; - } + ret = gtp_i2c_test(client); + if (ret < 0){ + printk("I2C communication ERROR!\n"); + goto exit_device_detect; + } - printk(KERN_ALERT "create_singlethread_workqueue goodix_resume.\n"); - goodix_resume_wq = create_singlethread_workqueue("goodix_resume"); - if (goodix_resume_wq == NULL) { - printk("create goodix_resume_wq fail!\n"); - return -ENOMEM; - } + printk(KERN_ALERT "create_singlethread_workqueue goodix_resume.\n"); + goodix_resume_wq = create_singlethread_workqueue("goodix_resume"); + if (goodix_resume_wq == NULL) { + printk("create goodix_resume_wq fail!\n"); + return -ENOMEM; + } - printk(KERN_ALERT "create_singlethread_workqueue goodix_wq.\n"); + printk(KERN_ALERT "create_singlethread_workqueue goodix_wq.\n"); - goodix_wq = create_singlethread_workqueue("goodix_wq"); - if (!goodix_wq) { - printk(KERN_ALERT "Creat goodix_wq workqueue failed.\n"); - return -ENOMEM; - } + goodix_wq = create_singlethread_workqueue("goodix_wq"); + if (!goodix_wq) { + printk(KERN_ALERT "Creat goodix_wq workqueue failed.\n"); + return -ENOMEM; + } #if GTP_AUTO_UPDATE - //ret = gup_init_update_proc(ts); - // if (ret < 0) { - // printk("Create update thread error."); - // } + //ret = gup_init_update_proc(ts); + // if (ret < 0) { + // printk("Create update thread error."); + // } #endif - ret = gtp_init_panel(ts); - if (ret < 0) { - printk("GTP init panel failed.\n"); - } + ret = gtp_init_panel(ts); + if (ret < 0) { + printk("GTP init panel failed.\n"); + } - - ret = gtp_request_input_dev(ts); - if (ret < 0) { - printk("GTP request input dev failed\n"); + + ret = gtp_request_input_dev(ts); + if (ret < 0) { + printk("GTP request input dev failed\n"); goto exit_device_detect; - } + } - ret = gtp_read_version(client, &version_info); - if (ret < 0) { - printk("Read version failed."); - } - - config_info.dev = &(ts->input_dev->dev); + ret = gtp_read_version(client, &version_info); + if (ret < 0) { + printk("Read version failed."); + } - ret = input_request_int(&(config_info.input_type), goodix_ts_irq_handler,CTP_IRQ_MODE, ts); - if (ret) { - printk("Request irq fail!.\n"); - } - - - spin_lock_init(&ts->irq_lock); + config_info.dev = &(ts->input_dev->dev); + + ret = input_request_int(&(config_info.input_type), goodix_ts_irq_handler,CTP_IRQ_MODE, ts); + if (ret) { + printk("Request irq fail!.\n"); + } + + + spin_lock_init(&ts->irq_lock); #if GTP_CREATE_WR_NODE - init_wr_node(client); + init_wr_node(client); #endif #if GTP_ESD_PROTECT - INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); - gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); - queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); + INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); + gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); #endif dprintk(DEBUG_INIT, "gt9xx probe success!\n"); - return 0; + return 0; exit_device_detect: i2c_set_clientdata(client, NULL); kfree(ts); @@ -1171,115 +1175,115 @@ /******************************************************* Function: - Goodix touchscreen driver release function. +Goodix touchscreen driver release function. Input: - client: i2c device struct. - +client: i2c device struct. + Output: - Executive outcomes. 0---succeed. -*******************************************************/ +Executive outcomes. 0---succeed. + *******************************************************/ static int goodix_ts_remove(struct i2c_client *client) { - struct goodix_ts_data *ts = i2c_get_clientdata(client); - + struct goodix_ts_data *ts = i2c_get_clientdata(client); + dprintk(DEBUG_INIT,"%s start!\n", __func__); #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ts->early_suspend); + unregister_early_suspend(&ts->early_suspend); #endif #if GTP_CREATE_WR_NODE - uninit_wr_node(); + uninit_wr_node(); #endif #if GTP_ESD_PROTECT - flush_workqueue(gtp_esd_check_workqueue); - if(gtp_esd_check_workqueue) - destroy_workqueue(gtp_esd_check_workqueue); + flush_workqueue(gtp_esd_check_workqueue); + if(gtp_esd_check_workqueue) + destroy_workqueue(gtp_esd_check_workqueue); #endif - input_free_int(&(config_info.input_type), ts); + input_free_int(&(config_info.input_type), ts); flush_workqueue(goodix_wq); //cancel_work_sync(&goodix_init_work); - cancel_work_sync(&goodix_resume_work); + cancel_work_sync(&goodix_resume_work); if(goodix_wq) destroy_workqueue(goodix_wq); - //destroy_workqueue(goodix_init_wq); - if(goodix_resume_wq) - destroy_workqueue(goodix_resume_wq); - i2c_set_clientdata(ts->client, NULL); + //destroy_workqueue(goodix_init_wq); + if(goodix_resume_wq) + destroy_workqueue(goodix_resume_wq); + i2c_set_clientdata(ts->client, NULL); input_unregister_device(ts->input_dev); kfree(ts); - - return 0; + + return 0; } static void goodix_resume_events (struct work_struct *work) { int ret; - struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); - - ret = gtp_wakeup_sleep(ts); - if (ret < 0) - printk("resume power on failed\n"); - gtp_irq_enable(ts); + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + ret = gtp_wakeup_sleep(ts); + if (ret < 0) + printk("resume power on failed\n"); + gtp_irq_enable(ts); } /******************************************************* Function: - Early suspend function. +Early suspend function. Input: - h:early_suspend struct. - +h:early_suspend struct. + Output: - None. -*******************************************************/ +None. + *******************************************************/ #ifdef CONFIG_HAS_EARLYSUSPEND static void goodix_ts_early_suspend(struct early_suspend *h) { - struct goodix_ts_data *ts; - s8 ret = -1; - ts = container_of(h, struct goodix_ts_data, early_suspend); + struct goodix_ts_data *ts; + s8 ret = -1; + ts = container_of(h, struct goodix_ts_data, early_suspend); #if GTP_ESD_PROTECT - ts->gtp_is_suspend = 1; - cancel_delayed_work_sync(>p_esd_check_work); + ts->gtp_is_suspend = 1; + cancel_delayed_work_sync(>p_esd_check_work); #endif - gtp_irq_disable(ts); - - - cancel_work_sync(&goodix_resume_work); - flush_workqueue(goodix_resume_wq); - ret = cancel_work_sync(&ts->work); - flush_workqueue(goodix_wq); - - ret = gtp_enter_sleep(ts); - if (ret < 0) { - printk("GTP early suspend failed."); - } + gtp_irq_disable(ts); + + + cancel_work_sync(&goodix_resume_work); + flush_workqueue(goodix_resume_wq); + ret = cancel_work_sync(&ts->work); + flush_workqueue(goodix_wq); + + ret = gtp_enter_sleep(ts); + if (ret < 0) { + printk("GTP early suspend failed."); + } } /******************************************************* Function: - Late resume function. +Late resume function. Input: - h:early_suspend struct. - +h:early_suspend struct. + Output: - None. -*******************************************************/ +None. + *******************************************************/ static void goodix_ts_late_resume(struct early_suspend *h) { - struct goodix_ts_data *ts; - ts = container_of(h, struct goodix_ts_data, early_suspend); - - queue_work(goodix_resume_wq, &goodix_resume_work);//gandy + struct goodix_ts_data *ts; + ts = container_of(h, struct goodix_ts_data, early_suspend); + + queue_work(goodix_resume_wq, &goodix_resume_work);//gandy #if GTP_ESD_PROTECT - ts->gtp_is_suspend = 0; - queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); + ts->gtp_is_suspend = 0; + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); #endif } #else @@ -1296,10 +1300,10 @@ #endif /* - ret = input_set_int_enable(&(config_info.input_type), 0); - if (ret < 0) - dprintk(DEBUG_SUSPEND,"%s irq disable failed\n", goodix_ts_name); - */ + ret = input_set_int_enable(&(config_info.input_type), 0); + if (ret < 0) + dprintk(DEBUG_SUSPEND,"%s irq disable failed\n", goodix_ts_name); + */ gtp_irq_disable(ts); cancel_work_sync(&goodix_resume_work); flush_workqueue(goodix_resume_wq); @@ -1329,7 +1333,7 @@ #if GTP_ESD_PROTECT struct goodix_ts_data *ts = dev_get_drvdata(dev); ts->gtp_is_suspend = 0; - queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); #endif return 0; } @@ -1339,80 +1343,80 @@ #if GTP_ESD_PROTECT /******************************************************* Function: - Initialize external watchdog for esd protect +Initialize external watchdog for esd protect Input: - client: i2c device. +client: i2c device. Output: - result of i2c write operation. - 1: succeed, otherwise: failed -*********************************************************/ +result of i2c write operation. +1: succeed, otherwise: failed + *********************************************************/ s32 gtp_init_ext_watchdog(struct i2c_client *client) { - u8 opr_buffer[4] = {0x80, 0x40, 0xAA, 0xAA}; - dprintk(DEBUG_INIT, "Init external watchdog..."); - return gtp_i2c_write(client, opr_buffer, 4); + u8 opr_buffer[4] = {0x80, 0x40, 0xAA, 0xAA}; + dprintk(DEBUG_INIT, "Init external watchdog..."); + return gtp_i2c_write(client, opr_buffer, 4); } /******************************************************* Function: - Esd protect function. - Added external watchdog by meta, 2013/03/07 +Esd protect function. +Added external watchdog by meta, 2013/03/07 Input: - work: delayed work +work: delayed work Output: - None. -*******************************************************/ +None. + *******************************************************/ static void gtp_esd_check_func(struct work_struct *work) { - s32 i; - s32 ret = -1; - struct goodix_ts_data *ts = NULL; - u8 test[4] = {0x80, 0x40}; - - dprintk(DEBUG_INIT, "enter %s work!\n", __func__); + s32 i; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; + u8 test[4] = {0x80, 0x40}; - ts = i2c_get_clientdata(i2c_connect_client); + dprintk(DEBUG_INIT, "enter %s work!\n", __func__); - if (ts->gtp_is_suspend || ts->enter_update) { - return; - } - - for (i = 0; i < 3; i++) { - ret = gtp_i2c_read(ts->client, test, 4); - - dprintk(DEBUG_INIT, "0x8040 = 0x%02X, 0x8041 = 0x%02X", test[2], test[3]); - if ((ret < 0)) { - // IC works abnormally.. - continue; - }else { - if ((test[2] == 0xAA) || (test[3] != 0xAA)) { - // IC works abnormally.. - i = 3; - break; - }else { - // IC works normally, Write 0x8040 0xAA - test[2] = 0xAA; - gtp_i2c_write(ts->client, test, 3); - break; - } - } - } - - if (i >= 3) { - GTP_DEBUG("IC Working ABNORMALLY, Resetting Guitar..."); - // gtp_reset_guitar(ts->client, 50); - } + ts = i2c_get_clientdata(i2c_connect_client); - if(!ts->gtp_is_suspend) { - queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); - } + if (ts->gtp_is_suspend || ts->enter_update) { + return; + } - return; + for (i = 0; i < 3; i++) { + ret = gtp_i2c_read(ts->client, test, 4); + + dprintk(DEBUG_INIT, "0x8040 = 0x%02X, 0x8041 = 0x%02X", test[2], test[3]); + if ((ret < 0)) { + // IC works abnormally.. + continue; + }else { + if ((test[2] == 0xAA) || (test[3] != 0xAA)) { + // IC works abnormally.. + i = 3; + break; + }else { + // IC works normally, Write 0x8040 0xAA + test[2] = 0xAA; + gtp_i2c_write(ts->client, test, 3); + break; + } + } + } + + if (i >= 3) { + GTP_DEBUG("IC Working ABNORMALLY, Resetting Guitar..."); + // gtp_reset_guitar(ts->client, 50); + } + + if(!ts->gtp_is_suspend) { + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); + } + + return; } #endif static const struct i2c_device_id goodix_ts_id[] = { - { CTP_NAME, 0 }, - { } + { CTP_NAME, 0 }, + { } }; #ifndef CONFIG_HAS_EARLYSUSPEND @@ -1420,43 +1424,45 @@ static const struct dev_pm_ops gt9xx_pm_ops = { .suspend = goodix_ts_suspend, .resume = goodix_ts_resume, - }; +}; #define GT9XX_PM_OPS (>9xx_pm_ops) #endif #endif static struct i2c_driver goodix_ts_driver = { - .class = I2C_CLASS_HWMON, - .probe = goodix_ts_probe, - .remove = goodix_ts_remove, - .id_table = goodix_ts_id, - .driver = { - .name = CTP_NAME, - .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .probe = goodix_ts_probe, + .remove = goodix_ts_remove, + .id_table = goodix_ts_id, + .driver = { + .name = CTP_NAME, + .owner = THIS_MODULE, #ifndef CONFIG_HAS_EARLYSUSPEND #ifdef CONFIG_PM .pm = GT9XX_PM_OPS, #endif #endif - }, - .address_list = normal_i2c, + }, + .address_list = normal_i2c, }; static int ctp_get_system_config(void) { - ctp_print_info(config_info,DEBUG_INIT); - twi_id = config_info.twi_id; - screen_max_x = config_info.screen_max_x; - screen_max_y = config_info.screen_max_y; - revert_x_flag = config_info.revert_x_flag; - revert_y_flag = config_info.revert_y_flag; - exchange_x_y_flag = config_info.exchange_x_y_flag; - if((screen_max_x == 0) || (screen_max_y == 0)){ - printk("%s:read config error!\n",__func__); - return 0; - } - return 1; + ctp_print_info(config_info,DEBUG_INIT); + twi_id = config_info.twi_id; +/* + screen_max_x = config_info.screen_max_x; + screen_max_y = config_info.screen_max_y; + revert_x_flag = config_info.revert_x_flag; + revert_y_flag = config_info.revert_y_flag; + exchange_x_y_flag = config_info.exchange_x_y_flag; +*/ + if((screen_max_x == 0) || (screen_max_y == 0)){ + printk("%s:read config error!\n",__func__); + return 0; + } + return 1; } /******************************************************* @@ -1469,76 +1475,82 @@ * ********************************************************/ static int __init goodix_ts_init(void) { - s32 ret = -1; + s32 ret = -1; int val = 0; - struct device_node *np = NULL; + struct device_node *np = NULL; - dprintk(DEBUG_INIT,"GTP driver init\n"); + dprintk(DEBUG_INIT,"GTP driver init\n"); if (!input_sensor_startup(&(config_info.input_type))) { ret = input_sensor_init(&(config_info.input_type)); - if (ret != 0) { - pr_err("%s:ctp_ops.input_sensor_init err.\n", __func__); - return ret; - } - input_set_power_enable(&(config_info.input_type), 1); + if (ret != 0) { + pr_err("%s:ctp_ops.input_sensor_init err.\n", __func__); + return ret; + } + input_set_power_enable(&(config_info.input_type), 1); } else { pr_err("%s: input_ctp_startup err.\n", __func__); return 0; } - if(config_info.ctp_used == 0){ - printk("*** ctp_used set to 0 !\n"); - printk("*** if use ctp,please put the sys_config.fex ctp_used set to 1. \n"); - return 0; + if(config_info.ctp_used == 0){ + printk("*** ctp_used set to 0 !\n"); + printk("*** if use ctp,please put the sys_config.fex ctp_used set to 1. \n"); + return 0; } np = of_find_node_by_name(NULL, "ctp"); if (!np) { - pr_err("ERROR! get ctp node failed, func:%s, line:%d\n",__FUNCTION__, __LINE__); - return -1; - } + pr_err("ERROR! get ctp node failed, func:%s, line:%d\n",__FUNCTION__, __LINE__); + return -1; + } ret = of_property_read_u32(np, "ctp_gesture_wakeup", &val); if (ret) { - pr_err("get ctp_screen_max_x is fail, %d\n", ret); - } - msleep(10); + pr_err("get ctp_screen_max_x is fail, %d\n", ret); + } + msleep(10); +#if 0 + if(!ctp_get_system_config()){ + printk("%s:read config fail!\n",__func__); + return ret; + } +#else + //ret = of_property_read_u32(np, "ctp_screen_max_x", &screen_max_x); + //of_property_read_u32(np, "ctp_screen_max_y", &screen_max_y); + //of_property_read_u32(np, "ctp_revert_x_flag", &revert_x_flag); + //of_property_read_u32(np, "ctp_revert_y_flag", &revert_y_flag); + //of_property_read_u32(np, "ctp_exchange_x_y_flag", &exchange_x_y_flag); +#endif + sunxi_gpio_to_name(CTP_IRQ_NUMBER,irq_pin_name); + gtp_io_init(20); - if(!ctp_get_system_config()){ - printk("%s:read config fail!\n",__func__); - return ret; - } - - sunxi_gpio_to_name(CTP_IRQ_NUMBER,irq_pin_name); - gtp_io_init(20); - - goodix_wq = create_singlethread_workqueue("goodix_wq"); - if (!goodix_wq) - { - GTP_ERROR("Creat workqueue failed."); - return -ENOMEM; - } + goodix_wq = create_singlethread_workqueue("goodix_wq"); + if (!goodix_wq) + { + GTP_ERROR("Creat workqueue failed."); + return -ENOMEM; + } #if GTP_ESD_PROTECT - INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); - gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); + INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); + gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); #endif goodix_ts_driver.detect = ctp_detect; - ret = i2c_add_driver(&goodix_ts_driver); - return ret; + ret = i2c_add_driver(&goodix_ts_driver); + return ret; } /******************************************************* Function: - Driver uninstall function. +Driver uninstall function. Input: - None. +None. Output: - Executive Outcomes. 0---succeed. -********************************************************/ +Executive Outcomes. 0---succeed. + ********************************************************/ static void __exit goodix_ts_exit(void) { - printk("GTP driver exited.\n"); - i2c_del_driver(&goodix_ts_driver); + printk("GTP driver exited.\n"); + i2c_del_driver(&goodix_ts_driver); input_sensor_free(&(config_info.input_type)); } diff --git a/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xxnew/gt9xx.c b/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xxnew/gt9xx.c index afa8841..f13e670 100644 --- a/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xxnew/gt9xx.c +++ b/longan/kernel/linux-4.9/drivers/input/touchscreen/gt9xxnew/gt9xx.c @@ -1,102 +1,50 @@ /* drivers/input/touchscreen/gt9xx.c - * - * 2010 - 2013 Goodix Technology. - * + * + * 2010 - 2012 Goodix Technology. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * - * This program is distributed in the hope that it will be a reference - * to you, when you are integrating the GOODiX's CTP IC into your system, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * + * This program is distributed in the hope that it will be a reference + * to you, when you are integrating the GOODiX's CTP IC into your system, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * Version: 2.2 - * Authors: andrew@goodix.com, meta@goodix.com - * Release Date: 2014/01/14 + * + * Version:1.4 + * Author:andrew@goodix.com + * Release Date:2012/12/12 * Revision record: - * V1.0: - * first Release. By Andrew, 2012/08/31 - * V1.2: - * modify gtp_reset_guitar,slot report,tracking_id & 0x0F. By Andrew, 2012/10/15 - * V1.4: - * modify gt9xx_update.c. By Andrew, 2012/12/12 - * V1.6: - * 1. new heartbeat/esd_protect mechanism(add external watchdog) - * 2. doze mode, sliding wakeup - * 3. 3 more cfg_group(GT9 Sensor_ID: 0~5) - * 3. config length verification - * 4. names & comments - * By Meta, 2013/03/11 - * V1.8: - * 1. pen/stylus identification - * 2. read double check & fixed config support - * 3. new esd & slide wakeup optimization - * By Meta, 2013/06/08 - * V2.0: - * 1. compatible with GT9XXF - * 2. send config after resume - * By Meta, 2013/08/06 - * V2.2: - * 1. gt9xx_config for debug - * 2. gesture wakeup - * 3. pen separate input device, active-pen button support - * 4. coordinates & keys optimization - * By Meta, 2014/01/14 + * V1.0:2012/08/31,first Release + * V1.2:2012/10/15,modify gtp_reset_guitar,slot report,tracking_id & 0x0F + * V1.4:2012/12/12,modify gt9xx_update.c + * */ #include <linux/irq.h> -#include "gt9xx.h" -#include <linux/pm_runtime.h> - -#ifdef CONFIG_PM +#include "gt9xx_ts.h" #include <linux/pm.h> -#endif #if GTP_ICS_SLOT_REPORT - #include <linux/input/mt.h> +#include <linux/input/mt.h> #endif -// if use i2c detect, set 1 -#define USE_DETECT 0 -static int gUseDetect; -static int startup(void); - -#define KEY_NUM 8 -static const char *goodix_ts_name = "goodix-ts"; +static const char *goodix_ts_name = "gt9xx"; static struct workqueue_struct *goodix_wq; -struct i2c_client *i2c_connect_client; -u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH] - = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; -unsigned int ctp_key_list[KEY_NUM] = {KEY_SWITCHVIDEOMODE, KEY_KBDILLUMTOGGLE, KEY_KBDILLUMDOWN, KEY_KBDILLUMUP, KEY_SEND, KEY_REPLY, KEY_FORWARDMAIL, KEY_SAVE}; +struct i2c_client * i2c_connect_client = NULL; +static u8 config[GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH] += {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; #if GTP_HAVE_TOUCH_KEY - static const u16 touch_key_array[] = GTP_KEY_TAB; - #define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0])) - -#if GTP_DEBUG_ON - static const int key_codes[] = {KEY_HOME, KEY_BACK, KEY_MENU, KEY_SEARCH}; - static const char *key_names[] = {"Key_Home", "Key_Back", "Key_Menu", "Key_Search"}; -#endif - +static const u16 touch_key_array[] = GTP_KEY_TAB; +#define GTP_MAX_KEY_NUM (sizeof(touch_key_array)/sizeof(touch_key_array[0])) #endif static s8 gtp_i2c_test(struct i2c_client *client); void gtp_reset_guitar(struct i2c_client *client, s32 ms); -s32 gtp_send_cfg(struct i2c_client *client); void gtp_int_sync(s32 ms); - -static ssize_t gt91xx_config_read_proc(struct file *, char __user *, size_t, loff_t *); -static ssize_t gt91xx_config_write_proc(struct file *, const char __user *, size_t, loff_t *); - -static struct proc_dir_entry *gt91xx_config_proc; -static const struct file_operations config_proc_ops = { - .owner = THIS_MODULE, - .read = gt91xx_config_read_proc, - .write = gt91xx_config_write_proc, -}; #ifdef CONFIG_HAS_EARLYSUSPEND static void goodix_ts_early_suspend(struct early_suspend *h); @@ -104,7 +52,8 @@ #endif #if GTP_CREATE_WR_NODE -extern s32 init_wr_node(struct i2c_client *); + +extern s32 init_wr_node(struct i2c_client*); extern void uninit_wr_node(void); #endif @@ -114,63 +63,34 @@ #if GTP_ESD_PROTECT static struct delayed_work gtp_esd_check_work; -static struct workqueue_struct *gtp_esd_check_workqueue; +static struct workqueue_struct * gtp_esd_check_workqueue = NULL; static void gtp_esd_check_func(struct work_struct *); -static s32 gtp_init_ext_watchdog(struct i2c_client *client); -void gtp_esd_switch(struct i2c_client *, s32); +s32 gtp_init_ext_watchdog(struct i2c_client *client); #endif -/*********** For GT9XXF Start **********/ -#if GTP_COMPATIBLE_MODE -extern s32 i2c_read_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len); -extern s32 i2c_write_bytes(struct i2c_client *client, u16 addr, u8 *buf, s32 len); -extern s32 gup_clk_calibration(void); -extern s32 gup_fw_download_proc(void *dir, u8 dwn_mode); -extern u8 gup_check_fs_mounted(char *path_name); +/////////////////////////////////////////////// +//specific tp related macro: need be configured for specific tp -void gtp_recovery_reset(struct i2c_client *client); -static s32 gtp_esd_recovery(struct i2c_client *client); -s32 gtp_fw_startup(struct i2c_client *client); -static s32 gtp_main_clk_proc(struct goodix_ts_data *ts); -static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode); - -#endif -/********** For GT9XXF End **********/ - -/*#if GTP_GESTURE_WAKEUP*/ -static bool gtp_gesture_wakeup; -static bool gtp_power_ctrl_sleep; -static bool g_suspend_flag; - -typedef enum { - DOZE_DISABLED = 0, - DOZE_ENABLED = 1, - DOZE_WAKEUP = 2, -} DOZE_T; -static DOZE_T doze_status = DOZE_DISABLED; -static s8 gtp_enter_doze(struct goodix_ts_data *ts); -/*#endif*/ - -u8 grp_cfg_version = 0; - -/********************Add by zhongjian for sunxi tp***********************/ #define CTP_IRQ_NUMBER (config_info.int_number) #define CTP_IRQ_MODE (IRQF_TRIGGER_FALLING) -#define CTP_NAME ("gt9xxnew_ts") +#define CTP_NAME ("gt9xx_ts") #define SCREEN_MAX_X (screen_max_x) #define SCREEN_MAX_Y (screen_max_y) #define PRESS_MAX (255) -static int screen_max_x; -static int screen_max_y; -static int revert_x_flag; -static int revert_y_flag; -static int exchange_x_y_flag; -static __u32 twi_id; + + +static int screen_max_x = 1024; +static int screen_max_y = 600; +static int revert_x_flag = 0; +static int revert_y_flag = 0; +static int exchange_x_y_flag = 0; +static __u32 twi_id = 0; static char irq_pin_name[8]; -//static u32 debug_mask = 0x1; -static u32 debug_mask; -enum { - DEBUG_INIT = 1U << 0, + +static u32 debug_mask = 0; + +enum{ + DEBUG_INIT = 1U << 0, DEBUG_SUSPEND = 1U << 1, DEBUG_INT_INFO = 1U << 2, DEBUG_X_Y_INFO = 1U << 3, @@ -178,47 +98,58 @@ DEBUG_WAKEUP_INFO = 1U << 5, DEBUG_OTHERS_INFO = 1U << 6, }; -#define dprintk(level_mask, fmt, arg...) if(unlikely(debug_mask & level_mask)) \ - printk("***CTP***"fmt, ## arg) -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); -static const unsigned short normal_i2c[3] = {0x14,0x5d, I2C_CLIENT_END}; + +#define dprintk(level_mask,fmt,arg...) if(unlikely(debug_mask & level_mask)) \ + printk("***CTP***"fmt, ## arg) +module_param_named(debug_mask,debug_mask,int,S_IRUGO | S_IWUSR | S_IWGRP); + +static const unsigned short normal_i2c[3] = {0x14, 0x5d, I2C_CLIENT_END}; +//static const int chip_id_value[3] = {57}; +//static uint8_t read_chip_value[3] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff,0}; struct ctp_config_info config_info = { .input_type = CTP_TYPE, .name = NULL, .int_number = 0, }; +//static void goodix_init_events(struct work_struct *work); +static void goodix_resume_events(struct work_struct *work); +static struct workqueue_struct *goodix_wq; +//static struct workqueue_struct *goodix_init_wq; +static struct workqueue_struct *goodix_resume_wq; +//static DECLARE_WORK(goodix_init_work, goodix_init_events); +static DECLARE_WORK(goodix_resume_work, goodix_resume_events); + /** * ctp_detect - Device detection callback for automatic device creation - * return value: + * return value: * = 0; success; * < 0; err */ static int ctp_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; - int ret = -1; - printk("the adapter number is %d\n", adapter->nr); + int ret = -1; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)){ printk("======return=====\n"); return -ENODEV; - } + } - if(twi_id == adapter->nr) { - printk("%s: addr = %x\n", __func__, client->addr); - ret = gtp_i2c_test(client); + if(twi_id == adapter->nr){ + dprintk(DEBUG_INIT,"%s: addr = %x\n", __func__, client->addr); + ret = gtp_i2c_test(client); printk("detect ret %d\n",ret); - if(!ret) { - printk("%s:I2C connection might be something wrong \n", __func__); - return -ENODEV; - } else { + if(!ret){ + printk("%s:I2C connection might be something wrong \n", __func__); + return -ENODEV; + }else{ strlcpy(info->type, CTP_NAME, I2C_NAME_SIZE); printk("======detect ok !=====\n"); - return 0; - } - } else { - return -ENODEV; + return 0; + } + }else{ + return -ENODEV; } } @@ -229,7 +160,8 @@ */ void ctp_print_info(struct ctp_config_info info,int debug_level) { - if(debug_level == DEBUG_INIT) { + if(debug_level == DEBUG_INIT) + { dprintk(DEBUG_INIT,"info.ctp_used:%d\n",info.ctp_used); dprintk(DEBUG_INIT,"info.twi_id:%d\n",info.twi_id); dprintk(DEBUG_INIT,"info.screen_max_x:%d\n",info.screen_max_x); @@ -276,3237 +208,1354 @@ void gtp_set_int_value(int status) { - long unsigned int config; + long unsigned int config; - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); - pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); + pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); - if (1 != SUNXI_PINCFG_UNPACK_VALUE(config)) { - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,1); - pin_config_set(SUNXI_PINCTRL,irq_pin_name,config);; - } + if (1 != SUNXI_PINCFG_UNPACK_VALUE(config)){ + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,1); + pin_config_set(SUNXI_PINCTRL,irq_pin_name,config);; + } - __gpio_set_value(CTP_IRQ_NUMBER, status); + __gpio_set_value(CTP_IRQ_NUMBER, status); } void gtp_set_io_int(void) { - long unsigned int config; - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); - pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); + long unsigned int config; + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,0xFFFF); + pin_config_get(SUNXI_PINCTRL,irq_pin_name,&config); - if (6 != SUNXI_PINCFG_UNPACK_VALUE(config)) { - config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC,6); - pin_config_set(SUNXI_PINCTRL,irq_pin_name,config); - } + if (6 != SUNXI_PINCFG_UNPACK_VALUE(config)) { + config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, 6); + pin_config_set(SUNXI_PINCTRL, irq_pin_name, config); + } } void gtp_io_init(int ms) -{ +{ ctp_wakeup(0, 0); msleep(ms); + gtp_set_int_value(0); msleep(2); ctp_wakeup(1, 0); msleep(6); - gpio_direction_output(config_info.wakeup_gpio.gpio,1); - gtp_int_sync(50); + + +#if GTP_ESD_PROTECT + // gtp_init_ext_watchdog(client); +#endif + } -/*******************************************************************************/ -static ssize_t gtp_gesture_enable_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count) -{ - unsigned long data; - /*struct input_dev *input = dev_get_drvdata(dev);*/ - /*struct goodix_ts_data *ts = container_of(&input, struct goodix_ts_data, input_dev);*/ - data = simple_strtoul(buf, NULL, 10); - dprintk(DEBUG_INIT,"%s g_suspend_flag=%d,gtp_gesture_wakeup=%d,enable=%ld\n",__func__,g_suspend_flag,gtp_gesture_wakeup,data); - if (!g_suspend_flag) { - if(data) { - gtp_gesture_wakeup = 1; - gtp_power_ctrl_sleep = 0; - dprintk(DEBUG_INIT,"%s gtp_gesture_wakeup=%d,enable=%ld\n", __func__, gtp_gesture_wakeup,data); - } else { - gtp_gesture_wakeup = 0; - gtp_power_ctrl_sleep = 1; - dprintk(DEBUG_INIT,"%s gtp_gesture_wakeup=%d,enable=%ld\n", __func__, gtp_gesture_wakeup,data); - } - } - else - dprintk(DEBUG_INIT,"%s gtp is suspend!!!! gtp_gesture_wakeup cann't be set!! gtp_gesture_wakeup=%d,enable=%ld\n", __func__, gtp_gesture_wakeup, data); - return count; -} -static ssize_t gtp_gesture_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int enable; - if(gtp_gesture_wakeup) - enable = 1; - else - enable = 0; - return sprintf(buf, "%d\n", enable); -} -static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, - gtp_gesture_enable_show, gtp_gesture_enable_store); -static struct attribute *gtp_attributes[] = { - &dev_attr_enable.attr, - NULL -}; -static struct attribute_group gtp_attribute_group = { - .attrs = gtp_attributes -}; - -/******************************************************* +/******************************************************* Function: - Read data from the i2c slave device. +Read data from the i2c slave device. + Input: - client: i2c device. - buf[0~1]: read start address. - buf[2~len-1]: read data buffer. - len: GTP_ADDR_LENGTH + read bytes count +client: i2c device. +buf[0]:operate address. +buf[1]~buf[len]:read data buffer. +len:operate length. + Output: - numbers of i2c_msgs to transfer: - 2: succeed, otherwise: failed -*********************************************************/ +numbers of i2c_msgs to transfer + *********************************************************/ s32 gtp_i2c_read(struct i2c_client *client, u8 *buf, s32 len) { - struct i2c_msg msgs[2]; - s32 ret=-1; - s32 retries = 0; + struct i2c_msg msgs[2]; + s32 ret = -1; + s32 retries = 0; - GTP_DEBUG_FUNC(); + msgs[0].flags = !I2C_M_RD; + msgs[0].addr = client->addr; + msgs[0].len = GTP_ADDR_LENGTH; + msgs[0].buf = &buf[0]; - msgs[0].flags = !I2C_M_RD; - msgs[0].addr = client->addr; - msgs[0].len = GTP_ADDR_LENGTH; - msgs[0].buf = &buf[0]; - /*msgs[0].scl_rate = 300 * 1000;*/ /* for Rockchip, etc.*/ + msgs[1].flags = I2C_M_RD; + msgs[1].addr = client->addr; + msgs[1].len = len - GTP_ADDR_LENGTH; + msgs[1].buf = &buf[GTP_ADDR_LENGTH]; - msgs[1].flags = I2C_M_RD; - msgs[1].addr = client->addr; - msgs[1].len = len - GTP_ADDR_LENGTH; - msgs[1].buf = &buf[GTP_ADDR_LENGTH]; - /*msgs[1].scl_rate = 300 * 1000;*/ + while(retries < 2) { + ret = i2c_transfer(client->adapter, msgs, 2); + if(ret == 2) + break; + retries++; + } - while(retries < 5) - { - ret = i2c_transfer(client->adapter, msgs, 2); - if(ret == 2)break; - retries++; - } - if((retries >= 5)) - { - #if GTP_COMPATIBLE_MODE - struct goodix_ts_data *ts = i2c_get_clientdata(client); - #endif - - /*#if GTP_GESTURE_WAKEUP*/ - if(gtp_gesture_wakeup){ - /* reset chip would quit doze mode*/ - if (DOZE_ENABLED == doze_status) - { - return ret; - } - } - /* #endif*/ - GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); - #if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - gtp_recovery_reset(client); - } - else - #endif - { - gtp_reset_guitar(client, 10); - } - } - return ret; + if(retries >= 2) { + printk("%s:I2C retry timeout, reset chip.", __func__); + } + return ret; } - - -/******************************************************* +/******************************************************* Function: - Write data to the i2c slave device. +write data to the i2c slave device. + Input: - client: i2c device. - buf[0~1]: write start address. - buf[2~len-1]: data buffer - len: GTP_ADDR_LENGTH + write bytes count +client: i2c device. +buf[0]:operate address. +buf[1]~buf[len]:write data buffer. +len:operate length. + Output: - numbers of i2c_msgs to transfer: - 1: succeed, otherwise: failed -*********************************************************/ -s32 gtp_i2c_write(struct i2c_client *client, u8 *buf, s32 len) +numbers of i2c_msgs to transfer. + *********************************************************/ +s32 gtp_i2c_write(struct i2c_client *client,u8 *buf,s32 len) { - struct i2c_msg msg; - s32 ret = -1; - s32 retries = 0; + struct i2c_msg msg; + s32 ret = -1; + s32 retries = 0; - GTP_DEBUG_FUNC(); + msg.flags = !I2C_M_RD; + msg.addr = client->addr; + msg.len = len; + msg.buf = buf; - msg.flags = !I2C_M_RD; - msg.addr = client->addr; - msg.len = len; - msg.buf = buf; - /*msg.scl_rate = 300 * 1000;*/ /* for Rockchip, etc*/ + while(retries < 2) { + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret == 1) + break; + retries++; + } - while(retries < 5) - { - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret == 1)break; - retries++; - } - if((retries >= 5)) { - #if GTP_COMPATIBLE_MODE - struct goodix_ts_data *ts = i2c_get_clientdata(client); - #endif - - /*#if GTP_GESTURE_WAKEUP*/ - if(gtp_gesture_wakeup){ - if (DOZE_ENABLED == doze_status) - { - return ret; - } - } - /*#endif*/ - GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d! Process reset.", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); - #if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - gtp_recovery_reset(client); - } - else - #endif - { - gtp_reset_guitar(client, 10); - } - } - return ret; -} - - -/******************************************************* -Function: - i2c read twice, compare the results -Input: - client: i2c device - addr: operate address - rxbuf: read data to store, if compare successful - len: bytes to read -Output: - FAIL: read failed - SUCCESS: read successful -*********************************************************/ -s32 gtp_i2c_read_dbl_check(struct i2c_client *client, u16 addr, u8 *rxbuf, int len) -{ - u8 buf[16] = {0}; - u8 confirm_buf[16] = {0}; - u8 retry = 0; - - while (retry++ < 3) - { - memset(buf, 0xAA, 16); - buf[0] = (u8)(addr >> 8); - buf[1] = (u8)(addr & 0xFF); - gtp_i2c_read(client, buf, len + 2); - - memset(confirm_buf, 0xAB, 16); - confirm_buf[0] = (u8)(addr >> 8); - confirm_buf[1] = (u8)(addr & 0xFF); - gtp_i2c_read(client, confirm_buf, len + 2); - - if (!memcmp(buf, confirm_buf, len+2)) - { - memcpy(rxbuf, confirm_buf+2, len); - return SUCCESS; - } - } - GTP_ERROR("I2C read 0x%04X, %d bytes, double check failed!", addr, len); - return FAIL; + if(retries >= 2) { + printk("%s:I2C retry timeout, reset chip.", __func__); + } + return ret; } /******************************************************* Function: - Send config. -Input: - client: i2c device. -Output: - result of i2c write operation. - 1: succeed, otherwise: failed -*********************************************************/ +Send config Function. +Input: +client: i2c client. + +Output: +Executive outcomes.0--success,non-0--fail. + *******************************************************/ s32 gtp_send_cfg(struct i2c_client *client) { - s32 ret = 2; + s32 ret = 0; #if GTP_DRIVER_SEND_CFG - s32 retry = 0; - struct goodix_ts_data *ts = i2c_get_clientdata(client); + s32 retry = 0; - if (ts->fixed_cfg) - { - GTP_INFO("Ic fixed config, no config sent!"); - return 0; - } - else if (ts->pnl_init_error) - { - GTP_INFO("Error occured in init_panel, no config sent"); - return 0; - } - - GTP_INFO("Driver send config."); - for (retry = 0; retry < 5; retry++) - { - ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); - if (ret > 0) - { - break; - } - } + for (retry = 0; retry < 5; retry++) + { + //ret = gtp_i2c_write(client, config , GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH); + // if (ret > 0) + // { + // break; + // } + } #endif - return ret; + + return ret; } + /******************************************************* Function: - Disable irq function +Disable IRQ Function. + Input: - ts: goodix i2c_client private data +ts: i2c client private struct. + Output: - None. -*********************************************************/ +None. + *******************************************************/ void gtp_irq_disable(struct goodix_ts_data *ts) { - unsigned long irqflags; + unsigned long irqflags; int ret; - GTP_DEBUG_FUNC(); - - dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); - spin_lock_irqsave(&ts->irq_lock, irqflags); - if (!ts->irq_is_disable) { - ts->irq_is_disable = 1; - ret = input_set_int_enable(&(config_info.input_type), 0); - if (ret < 0) - dprintk(DEBUG_OTHERS_INFO,"%s irq disable failed\n", goodix_ts_name); - } - spin_unlock_irqrestore(&ts->irq_lock, irqflags); + dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (!ts->irq_is_disable) { + ts->irq_is_disable = 1; + ret = input_set_int_enable(&(config_info.input_type), 0); + if (ret < 0) + dprintk(DEBUG_OTHERS_INFO,"%s irq disable failed\n", goodix_ts_name); + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); } /******************************************************* Function: - Enable irq function +Disable IRQ Function. + Input: - ts: goodix i2c_client private data +ts: i2c client private struct. + Output: - None. -*********************************************************/ +None. + *******************************************************/ void gtp_irq_enable(struct goodix_ts_data *ts) { - unsigned long irqflags = 0; - int ret; + unsigned long irqflags = 0; + int ret; - GTP_DEBUG_FUNC(); + dprintk(DEBUG_INT_INFO, "%s ---start!---\n", __func__); - spin_lock_irqsave(&ts->irq_lock, irqflags); - if (ts->irq_is_disable) { - ts->irq_is_disable = 0; - ret = input_set_int_enable(&(config_info.input_type), 1); - if (ret < 0) - dprintk(DEBUG_OTHERS_INFO,"%s irq enable failed\n", goodix_ts_name); - } - spin_unlock_irqrestore(&ts->irq_lock, irqflags); + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (ts->irq_is_disable) { + ts->irq_is_disable = 0; + ret = input_set_int_enable(&(config_info.input_type), 1); + if (ret < 0) + dprintk(DEBUG_OTHERS_INFO,"%s irq enable failed\n", goodix_ts_name); + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); } - /******************************************************* Function: - Report touch point event +Touch down report function. + Input: - ts: goodix i2c_client private data - id: trackId - x: input x coordinate - y: input y coordinate - w: input pressure +ts:private data. +id:tracking id. +x:input x. +y:input y. +w:input weight. + Output: - None. -*********************************************************/ +None. + *******************************************************/ static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w) { - dprintk(DEBUG_X_Y_INFO, "source data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); - if(1 == exchange_x_y_flag){ - swap(x, y); - } - if(1 == revert_x_flag){ - x = SCREEN_MAX_X - x; - } - if(1 == revert_y_flag){ - y = SCREEN_MAX_Y - y; - } - dprintk(DEBUG_X_Y_INFO,"report data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); + dprintk(DEBUG_X_Y_INFO, "source data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); + + //printk(KERN_ERR"revert_x_flag=%d, revert_y_flag=%d, GTP_ICS_SLOT_REPORT=%d V2 SCREEN_MAX_X:SCREEN_MAX_Y=%d:%d\n", revert_x_flag, revert_y_flag, GTP_ICS_SLOT_REPORT, SCREEN_MAX_X, SCREEN_MAX_Y); + + if(1 == exchange_x_y_flag){ + swap(x, y); + } + + if(1 == revert_x_flag){ + x = SCREEN_MAX_X - x; + } + + if(1 == revert_y_flag){ + y = SCREEN_MAX_Y - y; + } + + dprintk(DEBUG_X_Y_INFO,"report data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); #if GTP_ICS_SLOT_REPORT - input_mt_slot(ts->input_dev, id); - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); - 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_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + 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_key(ts->input_dev, BTN_TOUCH, 1); - 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); + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); + 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_mt_sync(ts->input_dev); #endif - GTP_DEBUG("ID:%d, X:%d, Y:%d, W:%d", id, x, y, w); } /******************************************************* Function: - Report touch release event +Touch up report function. + Input: - ts: goodix i2c_client private data +ts:private data. + Output: - None. -*********************************************************/ +None. + *******************************************************/ static void gtp_touch_up(struct goodix_ts_data* ts, s32 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); + input_mt_slot(ts->input_dev, id); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); + dprintk(DEBUG_X_Y_INFO, "Touch id[%2d] release!", id); #else - input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_report_key(ts->input_dev, BTN_TOUCH, 0); + 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 } - -#if GTP_WITH_PEN - -static void gtp_pen_init(struct goodix_ts_data *ts) -{ - s32 ret = 0; - - GTP_INFO("Request input device for pen/stylus."); - - ts->pen_dev = input_allocate_device(); - if (ts->pen_dev == NULL) - { - GTP_ERROR("Failed to allocate input device for pen/stylus."); - return; - } - - ts->pen_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; - -#if GTP_ICS_SLOT_REPORT - input_mt_init_slots(ts->pen_dev, 16); // -#else - ts->pen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); -#endif - - set_bit(BTN_TOOL_PEN, ts->pen_dev->keybit); - set_bit(INPUT_PROP_DIRECT, ts->pen_dev->propbit); - //set_bit(INPUT_PROP_POINTER, ts->pen_dev->propbit); - -#if GTP_PEN_HAVE_BUTTON - input_set_capability(ts->pen_dev, EV_KEY, BTN_STYLUS); - input_set_capability(ts->pen_dev, EV_KEY, BTN_STYLUS2); -#endif - - input_set_abs_params(ts->pen_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); - input_set_abs_params(ts->pen_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); - input_set_abs_params(ts->pen_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); - input_set_abs_params(ts->pen_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->pen_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); - - ts->pen_dev->name = "goodix-pen"; - ts->pen_dev->id.bustype = BUS_I2C; - - ret = input_register_device(ts->pen_dev); - if (ret) - { - GTP_ERROR("Register %s input device failed", ts->pen_dev->name); - return; - } -} - -static void gtp_pen_down(s32 x, s32 y, s32 w, s32 id) -{ - struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); - -#if GTP_CHANGE_X2Y - GTP_SWAP(x, y); -#endif - - input_report_key(ts->pen_dev, BTN_TOOL_PEN, 1); -#if GTP_ICS_SLOT_REPORT - input_mt_slot(ts->pen_dev, id); - input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, id); - input_report_abs(ts->pen_dev, ABS_MT_POSITION_X, x); - input_report_abs(ts->pen_dev, ABS_MT_POSITION_Y, y); - input_report_abs(ts->pen_dev, ABS_MT_PRESSURE, w); - input_report_abs(ts->pen_dev, ABS_MT_TOUCH_MAJOR, w); -#else - input_report_key(ts->pen_dev, BTN_TOUCH, 1); - input_report_abs(ts->pen_dev, ABS_MT_POSITION_X, x); - input_report_abs(ts->pen_dev, ABS_MT_POSITION_Y, y); - input_report_abs(ts->pen_dev, ABS_MT_PRESSURE, w); - input_report_abs(ts->pen_dev, ABS_MT_TOUCH_MAJOR, w); - input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, id); - input_mt_sync(ts->pen_dev); -#endif - GTP_DEBUG("(%d)(%d, %d)[%d]", id, x, y, w); -} - -static void gtp_pen_up(s32 id) -{ - struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); - - input_report_key(ts->pen_dev, BTN_TOOL_PEN, 0); - -#if GTP_ICS_SLOT_REPORT - input_mt_slot(ts->pen_dev, id); - input_report_abs(ts->pen_dev, ABS_MT_TRACKING_ID, -1); -#else - - input_report_key(ts->pen_dev, BTN_TOUCH, 0); -#endif - -} -#endif /******************************************************* Function: - Goodix touchscreen work function +Goodix touchscreen work function. + Input: - work: work struct of goodix_workqueue +work: work_struct of goodix_wq. + Output: - None. -*********************************************************/ +None. + *******************************************************/ static void goodix_ts_work_func(struct work_struct *work) { - u8 end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; - u8 point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; - u8 touch_num = 0; - u8 finger = 0; - static u16 pre_touch = 0; - static u8 pre_key = 0; -#if GTP_WITH_PEN - u8 pen_active = 0; - static u8 pre_pen = 0; -#endif - u8 key_value = 0; - u8* coor_data = NULL; - s32 input_x = 0; - s32 input_y = 0; - s32 input_w = 0; - s32 id = 0; - s32 i = 0; - s32 ret = -1; - struct goodix_ts_data *ts = NULL; + u8 end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0}; + u8 point_data[2 + 1 + 8 * GTP_MAX_TOUCH + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF}; + u8 touch_num = 0; + u8 finger = 0; + static u16 pre_touch = 0; + static u8 pre_key = 0; + u8 key_value = 0; + u8* coor_data = NULL; + s32 input_x = 0; + s32 input_y = 0; + s32 input_w = 0; + s32 id = 0; + s32 i = 0; + int j = 0; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; -#if GTP_COMPATIBLE_MODE - u8 rqst_buf[3] = {0x80, 0x43}; // for GT9XXF -#endif + dprintk(DEBUG_X_Y_INFO,"===enter %s===\n",__func__); -//#if GTP_GESTURE_WAKEUP - u8 doze_buf[3] = {0x81, 0x4B}; -//#endif + ts = container_of(work, struct goodix_ts_data, work); + if (ts->enter_update){ + return; + } - GTP_DEBUG_FUNC(); - dprintk(DEBUG_X_Y_INFO,"===enter %s===\n",__func__); - ts = container_of(work, struct goodix_ts_data, work); - if (ts->enter_update) - { - return; - } -//#if GTP_GESTURE_WAKEUP -if(gtp_gesture_wakeup){ - if (DOZE_ENABLED == doze_status) - { - ret = gtp_i2c_read(i2c_connect_client, doze_buf, 3); - GTP_DEBUG("0x814B = 0x%02X", doze_buf[2]); - if (ret > 0) - { - if ((doze_buf[2] == 'a') || (doze_buf[2] == 'b') || (doze_buf[2] == 'c') || - (doze_buf[2] == 'd') || (doze_buf[2] == 'e') || (doze_buf[2] == 'g') || - (doze_buf[2] == 'h') || (doze_buf[2] == 'm') || (doze_buf[2] == 'o') || - (doze_buf[2] == 'q') || (doze_buf[2] == 's') || (doze_buf[2] == 'v') || - (doze_buf[2] == 'w') || (doze_buf[2] == 'y') || (doze_buf[2] == 'z') || - (doze_buf[2] == 0x5E) /* ^ */ - ) - { - if (doze_buf[2] != 0x5E) - { - GTP_INFO("Wakeup by gesture(%c), light up the screen!", doze_buf[2]); - } - else - { - GTP_INFO("Wakeup by gesture(^), light up the screen!"); - } - doze_status = DOZE_WAKEUP; - input_report_key(ts->input_dev, KEY_POWER, 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, KEY_POWER, 0); - input_sync(ts->input_dev); - switch(doze_buf[2]) { - case 'e': - input_report_key(ts->input_dev, ctp_key_list[0], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[0], 0); - input_sync(ts->input_dev); - break; - case 'o': - input_report_key(ts->input_dev, ctp_key_list[1], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[1], 0); - input_sync(ts->input_dev); - break; - case 'w': - input_report_key(ts->input_dev, ctp_key_list[3], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[3], 0); - input_sync(ts->input_dev); - break; - case 'c': - input_report_key(ts->input_dev, ctp_key_list[2], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[2], 0); - input_sync(ts->input_dev); - break; - default: - break; + for(j=0; j<2;j++) + { + ret = gtp_i2c_read(ts->client, point_data, 12); + if (ret < 0){ + printk("I2C transfer error. errno:%d\n ", ret); + goto exit_work_func; } - // clear 0x814B - doze_buf[2] = 0x00; - gtp_i2c_write(i2c_connect_client, doze_buf, 3); - } - else if ( (doze_buf[2] == 0xAA) || (doze_buf[2] == 0xBB) || - (doze_buf[2] == 0xAB) || (doze_buf[2] == 0xBA) ) - { - char *direction[4] = {"Right", "Down", "Up", "Left"}; - u8 type = ((doze_buf[2] & 0x0F) - 0x0A) + (((doze_buf[2] >> 4) & 0x0F) - 0x0A) * 2; + } - GTP_INFO("%s slide to light up the screen!", direction[type]); - doze_status = DOZE_WAKEUP; - input_report_key(ts->input_dev, KEY_POWER, 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, KEY_POWER, 0); - input_sync(ts->input_dev); - switch(type) { - case 0: - input_report_key(ts->input_dev, ctp_key_list[7], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[7], 0); - input_sync(ts->input_dev); - break; - case 1: - input_report_key(ts->input_dev, ctp_key_list[5], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[5], 0); - input_sync(ts->input_dev); - break; - case 2: - input_report_key(ts->input_dev, ctp_key_list[4], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[4], 0); - input_sync(ts->input_dev); - break; - case 3: - input_report_key(ts->input_dev, ctp_key_list[6], 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, ctp_key_list[6], 0); - input_sync(ts->input_dev); - break; - default: - break; - } - // clear 0x814B - doze_buf[2] = 0x00; - gtp_i2c_write(i2c_connect_client, doze_buf, 3); - } - else if (0xCC == doze_buf[2]) - { - GTP_INFO("Double click to light up the screen!"); - doze_status = DOZE_WAKEUP; - input_report_key(ts->input_dev, KEY_POWER, 1); - input_sync(ts->input_dev); - input_report_key(ts->input_dev, KEY_POWER, 0); - input_sync(ts->input_dev); - // clear 0x814B - doze_buf[2] = 0x00; - gtp_i2c_write(i2c_connect_client, doze_buf, 3); - } - else - { - // clear 0x814B - doze_buf[2] = 0x00; - gtp_i2c_write(i2c_connect_client, doze_buf, 3); - gtp_enter_doze(ts); - } - } - if (ts->use_irq) - { - gtp_irq_enable(ts); - } - return; - } -} -//#endif + finger = point_data[GTP_ADDR_LENGTH]; + if((finger & 0x80) == 0) { + goto exit_work_func; + } - ret = gtp_i2c_read(ts->client, point_data, 12); - if (ret < 0) - { - GTP_ERROR("I2C transfer error. errno:%d\n ", ret); - if (ts->use_irq) - { - gtp_irq_enable(ts); - } - return; - } + touch_num = finger & 0x0f; + if (touch_num > GTP_MAX_TOUCH) { + goto exit_work_func; + } - finger = point_data[GTP_ADDR_LENGTH]; + if (touch_num > 1) { + u8 buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff}; -#if GTP_COMPATIBLE_MODE - // GT9XXF - if ((finger == 0x00) && (CHIP_TYPE_GT9F == ts->chip_type)) // request arrived - { - ret = gtp_i2c_read(ts->client, rqst_buf, 3); - if (ret < 0) - { - GTP_ERROR("Read request status error!"); - goto exit_work_func; - } + ret = gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num - 1)); + memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); + } - switch (rqst_buf[2]) - { - case GTP_RQST_CONFIG: - GTP_INFO("Request for config."); - ret = gtp_send_cfg(ts->client); - if (ret < 0) - { - GTP_ERROR("Request for config unresponded!"); - } - else - { - rqst_buf[2] = GTP_RQST_RESPONDED; - gtp_i2c_write(ts->client, rqst_buf, 3); - GTP_INFO("Request for config responded!"); - } - break; +#if GTP_HAVE_TOUCH_KEY + key_value = point_data[3 + 8 * touch_num]; - case GTP_RQST_BAK_REF: - GTP_INFO("Request for backup reference."); - ts->rqst_processing = 1; - ret = gtp_bak_ref_proc(ts, GTP_BAK_REF_SEND); - if (SUCCESS == ret) - { - rqst_buf[2] = GTP_RQST_RESPONDED; - gtp_i2c_write(ts->client, rqst_buf, 3); - ts->rqst_processing = 0; - GTP_INFO("Request for backup reference responded!"); - } - else - { - GTP_ERROR("Requeset for backup reference unresponed!"); - } - break; - - case GTP_RQST_RESET: - GTP_INFO("Request for reset."); - gtp_recovery_reset(ts->client); - break; - - case GTP_RQST_MAIN_CLOCK: - GTP_INFO("Request for main clock."); - ts->rqst_processing = 1; - ret = gtp_main_clk_proc(ts); - if (FAIL == ret) - { - GTP_ERROR("Request for main clock unresponded!"); - } - else - { - GTP_INFO("Request for main clock responded!"); - rqst_buf[2] = GTP_RQST_RESPONDED; - gtp_i2c_write(ts->client, rqst_buf, 3); - ts->rqst_processing = 0; - ts->clk_chk_fs_times = 0; - } - break; - - default: - GTP_INFO("Undefined request: 0x%02X", rqst_buf[2]); - rqst_buf[2] = GTP_RQST_RESPONDED; - gtp_i2c_write(ts->client, rqst_buf, 3); - break; - } - } + if(key_value || pre_key) { + for (i = 0; i < GTP_MAX_KEY_NUM; i++) { + input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<<i)); + } + touch_num = 0; + pre_touch = 0; + } #endif - if (finger == 0x00) - { - if (ts->use_irq) - { - gtp_irq_enable(ts); - } - return; - } + pre_key = key_value; - if((finger & 0x80) == 0) - { - goto exit_work_func; - } - - touch_num = finger & 0x0f; - if (touch_num > GTP_MAX_TOUCH) - { - goto exit_work_func; - } - - if (touch_num > 1) - { - u8 buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff}; - - ret = gtp_i2c_read(ts->client, buf, 2 + 8 * (touch_num - 1)); - memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); - } - -#if (GTP_HAVE_TOUCH_KEY || GTP_PEN_HAVE_BUTTON) - key_value = point_data[3 + 8 * touch_num]; - - if(key_value || pre_key) - { - #if GTP_PEN_HAVE_BUTTON - if (key_value == 0x40) - { - GTP_DEBUG("BTN_STYLUS & BTN_STYLUS2 Down."); - input_report_key(ts->pen_dev, BTN_STYLUS, 1); - input_report_key(ts->pen_dev, BTN_STYLUS2, 1); - pen_active = 1; - } - else if (key_value == 0x10) - { - GTP_DEBUG("BTN_STYLUS Down, BTN_STYLUS2 Up."); - input_report_key(ts->pen_dev, BTN_STYLUS, 1); - input_report_key(ts->pen_dev, BTN_STYLUS2, 0); - pen_active = 1; - } - else if (key_value == 0x20) - { - GTP_DEBUG("BTN_STYLUS Up, BTN_STYLUS2 Down."); - input_report_key(ts->pen_dev, BTN_STYLUS, 0); - input_report_key(ts->pen_dev, BTN_STYLUS2, 1); - pen_active = 1; - } - else - { - GTP_DEBUG("BTN_STYLUS & BTN_STYLUS2 Up."); - input_report_key(ts->pen_dev, BTN_STYLUS, 0); - input_report_key(ts->pen_dev, BTN_STYLUS2, 0); - if ( (pre_key == 0x40) || (pre_key == 0x20) || - (pre_key == 0x10) - ) - { - pen_active = 1; - } - } - if (pen_active) - { - touch_num = 0; // shield pen point - //pre_touch = 0; // clear last pen status - } - #endif - - #if GTP_HAVE_TOUCH_KEY - if (!pre_touch) - { - for (i = 0; i < GTP_MAX_KEY_NUM; i++) - { - #if GTP_DEBUG_ON - for (ret = 0; ret < 4; ++ret) - { - if (key_codes[ret] == touch_key_array[i]) - { - GTP_DEBUG("Key: %s %s", key_names[ret], (key_value & (0x01 << i)) ? "Down" : "Up"); - break; - } - } - #endif - input_report_key(ts->input_dev, touch_key_array[i], key_value & (0x01<<i)); - } - touch_num = 0; // shield fingers - } - #endif - } -#endif - pre_key = key_value; - - GTP_DEBUG("pre_touch:%02x, finger:%02x.", pre_touch, finger); + dprintk(DEBUG_X_Y_INFO, "pre_touch:%02x, finger:%02x.", pre_touch, finger); #if GTP_ICS_SLOT_REPORT + if (pre_touch || touch_num) { + s32 pos = 0; + u16 touch_index = 0; + coor_data = &point_data[3]; -#if GTP_WITH_PEN - if (pre_pen && (touch_num == 0)) - { - GTP_DEBUG("Pen touch UP(Slot)!"); - gtp_pen_up(0); - pen_active = 1; - pre_pen = 0; - } -#endif - if (pre_touch || touch_num) - { - s32 pos = 0; - u16 touch_index = 0; - u8 report_num = 0; - coor_data = &point_data[3]; + if(touch_num) { + id = coor_data[pos] & 0x0F; + touch_index |= (0x01<<id); + } - if(touch_num) - { - id = coor_data[pos] & 0x0F; + dprintk(DEBUG_X_Y_INFO, + "id=%d, touch_index=0x%x, pre_touch=0x%x\n", id, touch_index, pre_touch); - #if GTP_WITH_PEN - id = coor_data[pos]; - if ((id & 0x80)) - { - GTP_DEBUG("Pen touch DOWN(Slot)!"); - input_x = coor_data[pos + 1] | (coor_data[pos + 2] << 8); - input_y = coor_data[pos + 3] | (coor_data[pos + 4] << 8); - input_w = coor_data[pos + 5] | (coor_data[pos + 6] << 8); + for (i = 0; i < GTP_MAX_TOUCH; i++) { + if (touch_index & (0x01<<i)) { + input_x = coor_data[pos + 1] | coor_data[pos + 2] << 8; + input_y = coor_data[pos + 3] | coor_data[pos + 4] << 8; + input_w = coor_data[pos + 5] | coor_data[pos + 6] << 8; - gtp_pen_down(input_x, input_y, input_w, 0); - pre_pen = 1; - pre_touch = 0; - pen_active = 1; - } - #endif + gtp_touch_down(ts, id, input_x, input_y, input_w); + pre_touch |= 0x01 << i; - touch_index |= (0x01<<id); - } + pos += 8; + id = coor_data[pos] & 0x0F; + touch_index |= (0x01<<id); + }else {// if (pre_touch & (0x01 << i)) - 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) - { - break; - } - #endif + gtp_touch_up(ts, i); + pre_touch &= ~(0x01 << i); + } + } + } - if ((touch_index & (0x01<<i))) - { - input_x = coor_data[pos + 1] | (coor_data[pos + 2] << 8); - input_y = coor_data[pos + 3] | (coor_data[pos + 4] << 8); - input_w = coor_data[pos + 5] | (coor_data[pos + 6] << 8); - - gtp_touch_down(ts, id, input_x, input_y, input_w); - pre_touch |= 0x01 << i; - - report_num++; - if (report_num < touch_num) - { - pos += 8; - id = coor_data[pos] & 0x0F; - touch_index |= (0x01<<id); - } - } - else - { - gtp_touch_up(ts, i); - pre_touch &= ~(0x01 << i); - } - } - } #else + if (touch_num ) { + for (i = 0; i < touch_num; i++) { + coor_data = &point_data[i * 8 + 3]; - if (touch_num) - { - for (i = 0; i < touch_num; i++) - { - coor_data = &point_data[i * 8 + 3]; + id = coor_data[0] & 0x0F; + 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; - id = coor_data[0] & 0x0F; - 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); + gtp_touch_down(ts, id, input_x, input_y, input_w); + } + }else if(pre_touch){ + dprintk(DEBUG_X_Y_INFO, "Touch Release!"); + gtp_touch_up(ts, 0); + } - #if GTP_WITH_PEN - id = coor_data[0]; - if (id & 0x80) - { - GTP_DEBUG("Pen touch DOWN!"); - gtp_pen_down(input_x, input_y, input_w, 0); - pre_pen = 1; - pen_active = 1; - break; - } - else - #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!"); - gtp_pen_up(0); - pre_pen = 0; - pen_active = 1; - } - else - #endif - { - GTP_DEBUG("Touch Release!"); - gtp_touch_up(ts, 0); - } - } + pre_touch = touch_num; - pre_touch = touch_num; #endif -#if GTP_WITH_PEN - if (pen_active) - { - pen_active = 0; - input_sync(ts->pen_dev); - } - else -#endif - { - input_sync(ts->input_dev); - } + input_sync(ts->input_dev); exit_work_func: - if(!ts->gtp_rawdiff_mode) - { - ret = gtp_i2c_write(ts->client, end_cmd, 3); - if (ret < 0) - { - GTP_INFO("I2C write end_cmd error!"); - } - } - if (ts->use_irq) - { - gtp_irq_enable(ts); - } + if(!ts->gtp_rawdiff_mode) { + ret = gtp_i2c_write(ts->client, end_cmd, 3); + if (ret < 0) { + printk("I2C write end_cmd error!"); + } + } + return ; } /******************************************************* Function: - Timer interrupt service routine for polling mode. +External interrupt service routine. + Input: - timer: timer struct pointer +irq: interrupt number. +dev_id: private data 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); +irq execute status. + *******************************************************/ - GTP_DEBUG_FUNC(); +irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) +{ + struct goodix_ts_data *ts = (struct goodix_ts_data *)dev_id; + dprintk(DEBUG_INT_INFO, "==========------TS Interrupt-----============\n"); - queue_work(goodix_wq, &ts->work); - hrtimer_start(&ts->timer, ktime_set(0, (GTP_POLL_TIME+6)*1000000), HRTIMER_MODE_REL); - return HRTIMER_NORESTART; + queue_work(goodix_wq, &ts->work); + return 0; } -/******************************************************* -Function: - External interrupt service routine for interrupt mode. -Input: - irq: interrupt number. - dev_id: private data pointer -Output: - Handle Result. - IRQ_HANDLED: interrupt handled successfully -*********************************************************/ -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(goodix_wq, &ts->work); - - return IRQ_HANDLED; -} -/******************************************************* -Function: - Synchronization. -Input: - ms: synchronization time in millisecond. -Output: - None. -*******************************************************/ -void gtp_int_sync(s32 ms) -{ - gtp_set_int_value(0); - msleep(ms); - gtp_set_io_int(); -} /******************************************************* Function: - Reset chip. +Eter sleep function. + Input: - ms: reset time in millisecond +ts:private data. + Output: - None. -*******************************************************/ -void gtp_reset_guitar(struct i2c_client *client, s32 ms) -{ -#if GTP_COMPATIBLE_MODE - struct goodix_ts_data *ts = i2c_get_clientdata(client); -#endif - - GTP_DEBUG_FUNC(); - GTP_INFO("Guitar reset"); - __gpio_set_value(config_info.wakeup_gpio.gpio, 0); // begin select I2C slave addr - msleep(ms); // T2: > 10ms - // HIGH: 0x28/0x29, LOW: 0xBA/0xBB - if(client->addr == 0x14) - gtp_set_int_value(1); - else - gtp_set_int_value(0); - - msleep(2); // T3: > 100us - __gpio_set_value(config_info.wakeup_gpio.gpio, 1); - - msleep(6); // T4: > 5ms - -// gpio_direction_input(config_info.wakeup_gpio.gpio); // end select I2C slave addr - -#if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - return; - } -#endif - - gtp_int_sync(50); -#if GTP_ESD_PROTECT - gtp_init_ext_watchdog(client); -#endif -} - -//#if GTP_GESTURE_WAKEUP -/******************************************************* -Function: - Enter doze mode for sliding wakeup. -Input: - ts: goodix tp private data -Output: - 1: succeed, otherwise failed -*******************************************************/ -static s8 gtp_enter_doze(struct goodix_ts_data *ts) -{ - s8 ret = -1; - s8 retry = 0; - u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 8}; - - GTP_DEBUG_FUNC(); - - GTP_DEBUG("Entering gesture 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("failed to set doze flag into 0x8046, %d", retry); - continue; - } - i2c_control_buf[0] = 0x80; - i2c_control_buf[1] = 0x40; - ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); - if (ret > 0) - { - doze_status = DOZE_ENABLED; - GTP_INFO("Gesture mode enabled."); - return ret; - } - msleep(10); - } - GTP_ERROR("GTP send gesture cmd failed."); - return ret; -} -//#else -/******************************************************* -Function: - Enter sleep mode. -Input: - ts: private data. -Output: - Executive outcomes. - 1: succeed, otherwise failed. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ +#if defined(CONFIG_HAS_EARLYSUSPEND) | defined(CONFIG_PM) static s8 gtp_enter_sleep(struct goodix_ts_data * ts) { - s8 ret = -1; - s8 retry = 0; - u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; + s8 ret = -1; + s8 retry = 0; + u8 i2c_control_buf[3] = {(u8)(GTP_REG_SLEEP >> 8), (u8)GTP_REG_SLEEP, 5}; -#if GTP_COMPATIBLE_MODE - u8 status_buf[3] = {0x80, 0x44}; -#endif + dprintk(DEBUG_SUSPEND, "%s start!\n", __func__); - GTP_DEBUG_FUNC(); + gtp_set_int_value(0); -#if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - // GT9XXF: host interact with ic - ret = gtp_i2c_read(ts->client, status_buf, 3); - if (ret < 0) - { - GTP_ERROR("failed to get backup-reference status"); - } + while(retry++ < 2) { + ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); + if (ret > 0) { + dprintk(DEBUG_SUSPEND, "GTP enter sleep!"); + return ret; + } + msleep(10); + } + dprintk(DEBUG_SUSPEND, "GTP send sleep cmd failed."); - if (status_buf[2] & 0x80) - { - ret = gtp_bak_ref_proc(ts, GTP_BAK_REF_STORE); - if (FAIL == ret) - { - GTP_ERROR("failed to store bak_ref"); - } - } - } -#endif - - gtp_set_int_value(0); - msleep(5); - - while(retry++ < 5) - { - ret = gtp_i2c_write(ts->client, i2c_control_buf, 3); - if (ret > 0) - { - GTP_INFO("GTP enter sleep!"); - - return ret; - } - msleep(10); - } - GTP_ERROR("GTP send sleep cmd failed."); - return ret; + return ret; } -//#endif +#endif + /******************************************************* Function: - Wakeup from sleep. +Wakeup from sleep mode Function. + Input: - ts: private data. +ts: private data. + Output: - Executive outcomes. - >0: succeed, otherwise: failed. -*******************************************************/ +Executive outcomes.0--success,non-0--fail. + *******************************************************/ static s8 gtp_wakeup_sleep(struct goodix_ts_data * ts) { - u8 retry = 0; - s8 ret = -1; + u8 retry = 0; + s8 ret = -1; - GTP_DEBUG_FUNC(); + gtp_io_init(20); + gtp_set_io_int(); -#if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - u8 opr_buf[3] = {0x41, 0x80}; - - gtp_set_int_value(1); - msleep(5); - - for (retry = 0; retry < 10; ++retry) - { - // hold ss51 & dsp - opr_buf[2] = 0x0C; - ret = gtp_i2c_write(ts->client, opr_buf, 3); - if (FAIL == ret) - { - GTP_ERROR("failed to hold ss51 & dsp!"); - continue; - } - opr_buf[2] = 0x00; - ret = gtp_i2c_read(ts->client, opr_buf, 3); - if (FAIL == ret) - { - GTP_ERROR("failed to get ss51 & dsp status!"); - continue; - } - if (0x0C != opr_buf[2]) - { - GTP_DEBUG("ss51 & dsp not been hold, %d", retry+1); - continue; - } - GTP_DEBUG("ss51 & dsp confirmed hold"); - - ret = gtp_fw_startup(ts->client); - if (FAIL == ret) - { - GTP_ERROR("failed to startup GT9XXF, process recovery"); - gtp_esd_recovery(ts->client); - } - break; - } - if (retry >= 10) - { - GTP_ERROR("failed to wakeup, processing esd recovery"); - gtp_esd_recovery(ts->client); - } - else - { - GTP_INFO("GT9XXF gtp wakeup success"); - } - return ret; - } -#endif -//#if GTP_POWER_CTRL_SLEEP -if(gtp_power_ctrl_sleep) - while(retry++ < 5) - { - gtp_reset_guitar(ts->client, 20); - - GTP_INFO("GTP wakeup sleep."); - return 1; - } -//#else -else { - while(retry++ < 10) - { - //#if GTP_GESTURE_WAKEUP - if(gtp_gesture_wakeup){ - if (DOZE_WAKEUP != doze_status) - { - GTP_INFO("Powerkey wakeup."); - } - else - { - GTP_INFO("Gesture wakeup."); - } - doze_status = DOZE_DISABLED; - gtp_irq_disable(ts); - gtp_reset_guitar(ts->client, 10); - gtp_irq_enable(ts); - } - else { - //#else - gtp_set_int_value(1); - msleep(5); - //#endif - } - - ret = gtp_i2c_test(ts->client); - if (ret > 0) - { - GTP_INFO("GTP wakeup sleep."); - - // #if (!GTP_GESTURE_WAKEUP) - if(!gtp_gesture_wakeup){ - { - gtp_int_sync(25); - #if GTP_ESD_PROTECT - gtp_init_ext_watchdog(ts->client); - #endif - } - } - //#endif - - return ret; - } - gtp_reset_guitar(ts->client, 20); - } -} -//#endif - - GTP_ERROR("GTP wakeup sleep failed."); - return ret; -} - - -#if GTP_DRIVER_SEND_CFG -static s32 gtp_get_info(struct goodix_ts_data *ts) -{ - u8 opr_buf[6] = {0}; - s32 ret = 0; - - ts->abs_x_max = GTP_MAX_WIDTH; - ts->abs_y_max = GTP_MAX_HEIGHT; - ts->int_trigger_type = GTP_INT_TRIGGER; - - opr_buf[0] = (u8)((GTP_REG_CONFIG_DATA+1) >> 8); - opr_buf[1] = (u8)((GTP_REG_CONFIG_DATA+1) & 0xFF); - - ret = gtp_i2c_read(ts->client, opr_buf, 6); - if (ret < 0) - { - return FAIL; - } - - ts->abs_x_max = (opr_buf[3] << 8) + opr_buf[2]; - ts->abs_y_max = (opr_buf[5] << 8) + opr_buf[4]; - - opr_buf[0] = (u8)((GTP_REG_CONFIG_DATA+6) >> 8); - opr_buf[1] = (u8)((GTP_REG_CONFIG_DATA+6) & 0xFF); - - ret = gtp_i2c_read(ts->client, opr_buf, 3); - if (ret < 0) - { - return FAIL; - } - ts->int_trigger_type = opr_buf[2] & 0x03; - - GTP_INFO("X_MAX = %d, Y_MAX = %d, TRIGGER = 0x%02x", - ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); - - return SUCCESS; -} -#endif - -/******************************************************* -Function: - Initialize gtp. -Input: - ts: goodix private data -Output: - Executive outcomes. - 0: succeed, otherwise: failed -*******************************************************/ -static s32 gtp_init_panel(struct goodix_ts_data *ts) -{ - s32 ret = -1; - -#if GTP_DRIVER_SEND_CFG - s32 i = 0; - u8 check_sum = 0; - u8 opr_buf[16] = {0}; - u8 sensor_id = 0; - - u8 cfg_info_group1[] = CTP_CFG_GROUP1; - u8 cfg_info_group2[] = CTP_CFG_GROUP2; - u8 cfg_info_group3[] = CTP_CFG_GROUP3; - u8 cfg_info_group4[] = CTP_CFG_GROUP4; - u8 cfg_info_group5[] = CTP_CFG_GROUP5; - u8 cfg_info_group6[] = CTP_CFG_GROUP6; - u8 cfg_info_group7[] = CTP_CFG_GROUP7; - u8 cfg_info_group8[] = CTP_CFG_GROUP8; - - u8 *send_cfg_buf[] = {cfg_info_group1, cfg_info_group2, cfg_info_group3, - cfg_info_group4, cfg_info_group5, cfg_info_group6, - cfg_info_group7, cfg_info_group8}; - u8 cfg_info_len[] = { CFG_GROUP_LEN(cfg_info_group1), - CFG_GROUP_LEN(cfg_info_group2), - CFG_GROUP_LEN(cfg_info_group3), - CFG_GROUP_LEN(cfg_info_group4), - CFG_GROUP_LEN(cfg_info_group5), - CFG_GROUP_LEN(cfg_info_group6), - CFG_GROUP_LEN(cfg_info_group7), - CFG_GROUP_LEN(cfg_info_group8)}; - - dprintk(DEBUG_INIT,"Config Groups Lengths: %d, %d, %d, %d, %d, %d, %d, %d\n", - cfg_info_len[0], cfg_info_len[1], cfg_info_len[2], cfg_info_len[3], - cfg_info_len[4], cfg_info_len[5], cfg_info_len[6], cfg_info_len[7]); - -#if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - ts->fw_error = 0; - } - else -#endif - { - ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1); - if (SUCCESS == ret) - { - if (opr_buf[0] != 0xBE) - { - ts->fw_error = 1; - printk("Firmware error, no config sent!\n"); - return -1; - } - } - } - - if ((!cfg_info_len[1]) && (!cfg_info_len[2]) && - (!cfg_info_len[3]) && (!cfg_info_len[4]) && - (!cfg_info_len[5]) && (!cfg_info_len[6]) && - (!cfg_info_len[7])) - { - sensor_id = 0; - } - else - { - #if GTP_COMPATIBLE_MODE - msleep(50); - #endif - // ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1); - dprintk(DEBUG_INIT,"CTP name : %s\n",config_info.name); - if (!strcmp(config_info.name,"gt9271_mb976a9")){ - sensor_id = 0; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - - } else if (!strcmp(config_info.name,"gt9110_wt097")){ - sensor_id = 1; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - - } else if (!strcmp(config_info.name,"gt9271_wt097")){ - sensor_id = 2; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - - } else if (!strcmp(config_info.name,"gt9110_g200")){ - sensor_id = 3; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - - } else if (!strcmp(config_info.name,"gt9271_noah")){ - sensor_id = 4; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - } else if (!strcmp(config_info.name,"gt9271_p2")){ - sensor_id = 5; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - } else if (!strcmp(config_info.name, "gt911_1060")) { - sensor_id = 6; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - } else if (!strcmp(config_info.name, "gt911_784")) { - sensor_id = 7; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); - } else { - sensor_id = 0; - dprintk(DEBUG_INIT,"gt9xx:sensor_id = %d\n",sensor_id); +#if GTP_POWER_CTRL_SLEEP + while(retry++ < 5) + { + ret = gtp_send_cfg(ts->client); + if (ret > 0) + { + dprintk(DEBUG_SUSPEND, "Wakeup sleep send config success."); + return ret; } - ret = SUCCESS; - if (SUCCESS == ret) - { - if (sensor_id >= 0x08) - { - printk("Invalid sensor_id(0x%02X), No Config Sent!\n", sensor_id); - ts->pnl_init_error = 1; - return -1; - } - } - else - { - printk("Failed to get sensor_id, No config sent!\n"); - ts->pnl_init_error = 1; - return -1; - } - dprintk(DEBUG_INIT,"Sensor_ID: %d", sensor_id); - } - ts->gtp_cfg_len = cfg_info_len[sensor_id]; - dprintk(DEBUG_INIT,"CTP_CONFIG_GROUP%d used, config length: %d\n", sensor_id + 1, ts->gtp_cfg_len); + } - if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH) - { - printk("Config Group%d is INVALID CONFIG GROUP(Len: %d)! NO Config Sent! You need to check you header file CFG_GROUP section!\n", sensor_id+1, ts->gtp_cfg_len); - ts->pnl_init_error = 1; - return -1; - } - -#if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - ts->fixed_cfg = 0; - } - else + printk("GTP wakeup sleep failed."); + return ret; #endif - { - ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0], 1); - if (ret == SUCCESS) - { - dprintk(DEBUG_INIT,"CFG_GROUP%d Config Version: %d, 0x%02X; IC Config Version: %d, 0x%02X\n", sensor_id+1, - send_cfg_buf[sensor_id][0], send_cfg_buf[sensor_id][0], opr_buf[0], opr_buf[0]); - - if (opr_buf[0] < 155) - { - grp_cfg_version = send_cfg_buf[sensor_id][0]; // backup group config version - send_cfg_buf[sensor_id][0] = 0x00; - ts->fixed_cfg = 0; - } - else // treated as fixed config, not send config - { - dprintk(DEBUG_INIT,"Ic fixed config with config version(%d, 0x%02X)\n", opr_buf[0], opr_buf[0]); - ts->fixed_cfg = 1; - gtp_get_info(ts); - return 0; - } - } - else - { - printk("Failed to get ic config version!No config sent!\n"); - return -1; - } - } - - memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); - memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len); - -#if GTP_CUSTOM_CFG - config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; - config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); - config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; - config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); - - if (GTP_INT_TRIGGER == 0) //RISING - { - config[TRIGGER_LOC] &= 0xfe; - } - else if (GTP_INT_TRIGGER == 1) //FALLING - { - config[TRIGGER_LOC] |= 0x01; - } -#endif // GTP_CUSTOM_CFG - - check_sum = 0; - for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) - { - check_sum += config[i]; - } - config[ts->gtp_cfg_len] = (~check_sum) + 1; - -#else // driver not send config - - ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; - ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH); - if (ret < 0) - { - GTP_ERROR("Read Config Failed, Using Default Resolution & INT Trigger!"); - ts->abs_x_max = GTP_MAX_WIDTH; - ts->abs_y_max = GTP_MAX_HEIGHT; - ts->int_trigger_type = GTP_INT_TRIGGER; - } - -#endif // GTP_DRIVER_SEND_CFG - - if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0)) - { - ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC]; - ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2]; - ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; - } - -#if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - u8 sensor_num = 0; - u8 driver_num = 0; - u8 have_key = 0; - - have_key = (config[GTP_REG_HAVE_KEY - GTP_REG_CONFIG_DATA + 2] & 0x01); - - if (1 == ts->is_950) - { - driver_num = config[GTP_REG_MATRIX_DRVNUM - GTP_REG_CONFIG_DATA + 2]; - sensor_num = config[GTP_REG_MATRIX_SENNUM - GTP_REG_CONFIG_DATA + 2]; - if (have_key) - { - driver_num--; - } - ts->bak_ref_len = (driver_num * (sensor_num - 1) + 2) * 2 * 6; - } - else - { - driver_num = (config[CFG_LOC_DRVA_NUM] & 0x1F) + (config[CFG_LOC_DRVB_NUM]&0x1F); - if (have_key) - { - driver_num--; - } - sensor_num = (config[CFG_LOC_SENS_NUM] & 0x0F) + ((config[CFG_LOC_SENS_NUM] >> 4) & 0x0F); - ts->bak_ref_len = (driver_num * (sensor_num - 2) + 2) * 2; - } - - GTP_INFO("Drv * Sen: %d * %d(key: %d), X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", - driver_num, sensor_num, have_key, ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); - return 0; - } - else -#endif - { - #if GTP_DRIVER_SEND_CFG - ret = gtp_send_cfg(ts->client); - if (ret < 0) - { - GTP_ERROR("Send config error."); - } - // set config version to CTP_CFG_GROUP, for resume to send config - config[GTP_ADDR_LENGTH] = grp_cfg_version; - check_sum = 0; - for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) - { - check_sum += config[i]; - } - config[ts->gtp_cfg_len] = (~check_sum) + 1; - #endif - GTP_INFO("X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); - } - - msleep(10); - return 0; } - -static ssize_t gt91xx_config_read_proc(struct file *file, char __user *page, size_t size, loff_t *ppos) -{ - char *ptr = page; - char temp_data[GTP_CONFIG_MAX_LENGTH + 2] = {0x80, 0x47}; - int i; - - if (*ppos) - { - return 0; - } - ptr += sprintf(ptr, "==== GT9XX config init value====\n"); - - for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++) - { - ptr += sprintf(ptr, "0x%02X ", config[i + 2]); - - if (i % 8 == 7) - ptr += sprintf(ptr, "\n"); - } - - ptr += sprintf(ptr, "\n"); - - ptr += sprintf(ptr, "==== GT9XX config real value====\n"); - gtp_i2c_read(i2c_connect_client, temp_data, GTP_CONFIG_MAX_LENGTH + 2); - for (i = 0 ; i < GTP_CONFIG_MAX_LENGTH ; i++) - { - ptr += sprintf(ptr, "0x%02X ", temp_data[i+2]); - - if (i % 8 == 7) - ptr += sprintf(ptr, "\n"); - } - *ppos += ptr - page; - return (ptr - page); -} - -static ssize_t gt91xx_config_write_proc(struct file *filp, const char __user *buffer, size_t count, loff_t *off) -{ - s32 ret = 0; - - GTP_DEBUG("write count %u\n", count); - - if (count > GTP_CONFIG_MAX_LENGTH) - { - GTP_ERROR("size not match [%d:%u]\n", GTP_CONFIG_MAX_LENGTH, count); - return -EFAULT; - } - - if (copy_from_user(&config[2], buffer, count)) - { - GTP_ERROR("copy from user fail\n"); - return -EFAULT; - } - - ret = gtp_send_cfg(i2c_connect_client); - - if (ret < 0) - { - GTP_ERROR("send config failed."); - } - - return count; -} -/******************************************************* -Function: - Read chip version. -Input: - client: i2c device - version: buffer to keep ic firmware version -Output: - read operation return. - 2: succeed, otherwise: failed -*******************************************************/ -s32 gtp_read_version(struct i2c_client *client, u16* version) -{ - s32 ret = -1; - u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; - - GTP_DEBUG_FUNC(); - - ret = gtp_i2c_read(client, buf, sizeof(buf)); - if (ret < 0) - { - GTP_ERROR("GTP read version failed"); - return ret; - } - - if (version) - { - *version = (buf[7] << 8) | buf[6]; - } - if (buf[5] == 0x00) - { - GTP_INFO("IC Version: %c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[7], buf[6]); - } - else - { - GTP_INFO("IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); - } - return ret; -} /******************************************************* Function: - I2c test Function. +GTP initialize function. + Input: - client:i2c client. +ts: i2c client private struct. + Output: - Executive outcomes. - 2: succeed, otherwise failed. -*******************************************************/ -static s8 gtp_i2c_test(struct i2c_client *client) -{ - u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; - u8 retry = 0; - s8 ret = -1; - - GTP_DEBUG_FUNC(); - - while(retry++ < 5) - { - ret = gtp_i2c_read(client, test, 3); - if (ret > 0) - { - return ret; - } - GTP_ERROR("GTP i2c test failed time %d.",retry); - msleep(10); - } - return ret; -} - -/******************************************************* -Function: - Request interrupt. -Input: - ts: private data. -Output: - Executive outcomes. - 0: succeed, -1: failed. -*******************************************************/ -static s8 gtp_request_irq(struct goodix_ts_data *ts) +Executive outcomes.0---succeed. + *******************************************************/ +static s32 gtp_init_panel(struct goodix_ts_data *ts) { s32 ret = -1; - ret = input_request_int(&(config_info.input_type), goodix_ts_irq_handler, CTP_IRQ_MODE, ts); +#if GTP_DRIVER_SEND_CFG + s32 i; + u8 check_sum = 0; + u8 rd_cfg_buf[16]; + int index =0; - if (ret) { - GTP_ERROR("Request IRQ failed!ERRNO:%d.", ret); - gtp_set_int_value(0); - //input_free_int(&(config_info.input_type), ts); +#if 1 + u8 cfg_info_group1[] = CTP_CFG_GROUP1; + u8 cfg_info_group2[] = CTP_CFG_GROUP2; + u8 cfg_info_group3[] = CTP_CFG_GROUP3; + u8 cfg_info_group4[] = CTP_CFG_GROUP4; + u8 cfg_info_group5[] = CTP_CFG_GROUP5; + u8 cfg_info_group6[] = CTP_CFG_GROUP6; + // u8 cfg_info_group7[] = CTP_CFG_GROUP7; +#else + u8 cfg_info_group1[] = {}; + u8 cfg_info_group2[] = {}; + u8 cfg_info_group3[] = {}; + u8 cfg_info_group4[] = {}; + u8 cfg_info_group5[] = {}; + u8 cfg_info_group6[] = {}; + // u8 cfg_info_group7[] = {}; +#endif - 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); - return -1; - } else { - gtp_irq_disable(ts); - ts->use_irq = 1; - return 0; + u8 *send_cfg_buf[] = {cfg_info_group1,cfg_info_group2,cfg_info_group3,cfg_info_group4,cfg_info_group5,cfg_info_group6}; + u8 cfg_info_len[] = {sizeof(cfg_info_group1)/sizeof(cfg_info_group1[0]),\ + sizeof(cfg_info_group2)/sizeof(cfg_info_group2[0]),\ + sizeof(cfg_info_group3)/sizeof(cfg_info_group3[0]),\ + sizeof(cfg_info_group4)/sizeof(cfg_info_group4[0]),\ + sizeof(cfg_info_group5)/sizeof(cfg_info_group5[0]),\ + sizeof(cfg_info_group6)/sizeof(cfg_info_group6[0])}; + //sizeof(cfg_info_group7)/sizeof(cfg_info_group7[0])}; +#if 0 //gandy +for(i=0; i<3; i++) +{ + if(cfg_info_len[i] > ts->gtp_cfg_len) + { + ts->gtp_cfg_len = cfg_info_len[i]; } } +#endif + +GTP_DEBUG("len1=%d,len2=%d,len3=%d,send_len:%d",cfg_info_len[0],cfg_info_len[1],cfg_info_len[2],ts->gtp_cfg_len); +#if 0 +if ((!cfg_info_len[1]) && (!cfg_info_len[2])) +{ + rd_cfg_buf[GTP_ADDR_LENGTH] = 0; +} +else +#endif +printk("gtp_i2c_read GTP_REG_SENSOR_ID \n"); +{ + rd_cfg_buf[0] = GTP_REG_SENSOR_ID >> 8; + rd_cfg_buf[1] = GTP_REG_SENSOR_ID & 0xff; + ret = gtp_i2c_read(ts->client, rd_cfg_buf, 3); + if (ret < 0) + { + GTP_ERROR("Read SENSOR ID failed,default use group1 config!"); + rd_cfg_buf[GTP_ADDR_LENGTH] = 0; + } + rd_cfg_buf[GTP_ADDR_LENGTH] &= 0x07; +} + +#if 0 +if(screen_max_x == 800 && screen_max_y == 480) +{ + if(rd_cfg_buf[GTP_ADDR_LENGTH] == 3) + index = 0; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 4) + index = 1; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 5) + index = 3; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 0) + index = 6; +} +else if(screen_max_x == 1024 && screen_max_y == 600) +{ + if(rd_cfg_buf[GTP_ADDR_LENGTH] == 0) + index = 5; + else if(rd_cfg_buf[GTP_ADDR_LENGTH] == 3) + index = 2; +} +#endif +GTP_DEBUG("CTP name : %s\n",config_info.name); +if (!strcmp(config_info.name,"gt911_805d5")){ + index = 0; + GTP_DEBUG("gt9xx:index = %d\n",index); + +} else if (!strcmp(config_info.name,"gt911_g912")){ + index = 2; + GTP_DEBUG("gt9xx:index = %d\n",index); + +} else if (!strcmp(config_info.name,"gt911_xw785")){ + index = 3; + GTP_DEBUG("gt9xx:index = %d\n",index); + +} else {//default gt9xx_ts + index = 1; //default p4 + GTP_DEBUG("gt9xx:index = %d\n",index); +} + +printk("config send_cfg_buf******** \n"); +//index = rd_cfg_buf[GTP_ADDR_LENGTH]; +ts->gtp_cfg_len = cfg_info_len[index]; +GTP_DEBUG("gandy---SENSOR ID:%d\n", rd_cfg_buf[GTP_ADDR_LENGTH]); +memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); +memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[index], ts->gtp_cfg_len); + +#if GTP_CUSTOM_CFG +config[RESOLUTION_LOC] = (u8)GTP_MAX_WIDTH; +config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8); +config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT; +config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8); + +if (GTP_INT_TRIGGER == 0) //RISING +{ + config[TRIGGER_LOC] &= 0xfe; +} +else if (GTP_INT_TRIGGER == 1) //FALLING +{ + config[TRIGGER_LOC] |= 0x01; +} +#endif //endif GTP_CUSTOM_CFG + +check_sum = 0; +for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++) +{ + check_sum += config[i]; +} +config[ts->gtp_cfg_len] = (~check_sum) + 1; + +#else //else DRIVER NEED NOT SEND CONFIG + +if(ts->gtp_cfg_len == 0) +{ + ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH; +} +ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH); +if (ret < 0) +{ + GTP_ERROR("GTP read resolution & max_touch_num failed, use default value!"); + ts->abs_x_max = GTP_MAX_WIDTH; + ts->abs_y_max = GTP_MAX_HEIGHT; + ts->int_trigger_type = GTP_INT_TRIGGER; +} +#endif //endif GTP_DRIVER_SEND_CFG + +GTP_DEBUG_FUNC(); + +ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC]; +ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2]; +ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; +if ((!ts->abs_x_max)||(!ts->abs_y_max)) +{ + GTP_ERROR("GTP resolution & max_touch_num invalid, use default value!"); + ts->abs_x_max = GTP_MAX_WIDTH; + ts->abs_y_max = GTP_MAX_HEIGHT; +} + +msleep(100); +ret = gtp_send_cfg(ts->client); +if (ret < 0) +{ + printk("\ngandy-----send config error.ret=%d\n",ret); + GTP_ERROR("Send config error."); +} +printk("X_MAX = %d,Y_MAX = %d,TRIGGER = 0x%02x", + ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type); + +msleep(10); + +return 0; +} /******************************************************* Function: - Request input device Function. +Read goodix touchscreen version function. + Input: - ts:private data. +client: i2c client struct. +version:address to store version info + Output: - Executive outcomes. - 0: succeed, otherwise: failed. -*******************************************************/ +Executive outcomes.0---succeed. + *******************************************************/ +s32 gtp_read_version(struct i2c_client *client, u16* version) +{ + s32 ret = -1; + u8 buf[8] = {GTP_REG_VERSION >> 8, GTP_REG_VERSION & 0xff}; + + dprintk(DEBUG_INIT, "%s ---start!.---\n", __func__); + + ret = gtp_i2c_read(client, buf, sizeof(buf)); + if (ret < 0) { + printk("GTP read version failed"); + return ret; + } + + if (version) { + *version = (buf[7] << 8) | buf[6]; + } + + if (buf[5] == 0x00) { + printk("IC Version: %c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[7], buf[6]); + } + else { + printk("IC Version: %c%c%c%c_%02x%02x", buf[2], buf[3], buf[4], buf[5], buf[7], buf[6]); + } + return ret; +} + +/******************************************************* +Function: +I2c test Function. + +Input: +client:i2c client. + +Output: +Executive outcomes.0--success,non-0--fail. + *******************************************************/ +static s8 gtp_i2c_test(struct i2c_client *client) +{ + u8 test[3] = {GTP_REG_CONFIG_DATA >> 8, GTP_REG_CONFIG_DATA & 0xff}; + u8 retry = 0; + s8 ret = -1; + + while(retry++ < 2) { + ret = gtp_i2c_read(client, test, 3); + if (ret > 0) { + return ret; + } + printk("GTP i2c test failed time %d.",retry); + msleep(10); + } + return ret; +} + + +/******************************************************* +Function: +Request input device Function. + +Input: +ts:private data. + +Output: +Executive outcomes.0--success,non-0--fail. + *******************************************************/ static s8 gtp_request_input_dev(struct goodix_ts_data *ts) { - s8 ret = -1; - s8 phys[32]; - u8 index = 0; - - GTP_DEBUG_FUNC(); - - ts->input_dev = input_allocate_device(); - if (ts->input_dev == NULL) - { - GTP_ERROR("Failed to allocate input device."); - return -ENOMEM; - } - - ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; -#if GTP_ICS_SLOT_REPORT - input_mt_init_slots(ts->input_dev, 16); // in case of "out of memory" -#else - ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + s8 ret = -1; +#if GTP_HAVE_TOUCH_KEY + u8 index = 0; #endif - __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) { + GTP_ERROR("Failed to allocate input device."); + return -ENOMEM; + } + + ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ; +#if GTP_ICS_SLOT_REPORT + __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + input_mt_init_slots(ts->input_dev, 255, 1); +#else + ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); +#endif #if GTP_HAVE_TOUCH_KEY - for (index = 0; index < GTP_MAX_KEY_NUM; index++) - { - input_set_capability(ts->input_dev, EV_KEY, touch_key_array[index]); - } + for (index = 0; index < GTP_MAX_KEY_NUM; index++) { + input_set_capability(ts->input_dev,EV_KEY,touch_key_array[index]); + } #endif -//#if GTP_GESTURE_WAKEUP -if(gtp_gesture_wakeup) - input_set_capability(ts->input_dev, EV_KEY, KEY_POWER); - for (index = 0; index < KEY_NUM; index++) - { - input_set_capability(ts->input_dev, EV_KEY, ctp_key_list[index]); - } -//#endif + //#if GTP_CHANGE_X2Y + // GTP_SWAP(ts->abs_x_max, ts->abs_y_max); + //#endif -if(1 == exchange_x_y_flag) - swap(ts->abs_x_max, ts->abs_y_max); + set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit); + set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit); + set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit); + set_bit(ABS_MT_WIDTH_MAJOR, ts->input_dev->absbit); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); - sprintf(phys, "input/ts"); - ts->input_dev->name = CTP_NAME; - ts->input_dev->phys = phys; - ts->input_dev->id.bustype = BUS_I2C; - ts->input_dev->id.vendor = 0xDEAD; - ts->input_dev->id.product = 0xBEEF; - ts->input_dev->id.version = 10427; + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, 255, 0, 0); + __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); - ret = input_register_device(ts->input_dev); - if (ret) - { - GTP_ERROR("Register %s input device failed", ts->input_dev->name); - return -ENODEV; - } - ret = sysfs_create_group(&ts->input_dev->dev.kobj, >p_attribute_group); - if(ret) { - GTP_ERROR("create sys failed\n"); - } - + ts->input_dev->name = CTP_NAME; + ts->input_dev->phys = "input/goodix-ts"; + ts->input_dev->id.bustype = BUS_I2C; + ts->input_dev->id.vendor = 0xDEAD; + ts->input_dev->id.product = 0xBEEF; + ts->input_dev->id.version = 10427; + ret = input_register_device(ts->input_dev); + if (ret) { + printk("Register %s input device failed", ts->input_dev->name); + return -ENODEV; + } #ifdef CONFIG_HAS_EARLYSUSPEND - ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ts->early_suspend.suspend = goodix_ts_early_suspend; - ts->early_suspend.resume = goodix_ts_late_resume; - register_early_suspend(&ts->early_suspend); + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = goodix_ts_early_suspend; + ts->early_suspend.resume = goodix_ts_late_resume; + register_early_suspend(&ts->early_suspend); #endif - -#if GTP_WITH_PEN - gtp_pen_init(ts); -#endif - - return 0; + return 0; } -//************** For GT9XXF Start *************// -#if GTP_COMPATIBLE_MODE - -s32 gtp_fw_startup(struct i2c_client *client) -{ - u8 opr_buf[4]; - s32 ret = 0; - - //init sw WDT - opr_buf[0] = 0xAA; - ret = i2c_write_bytes(client, 0x8041, opr_buf, 1); - if (ret < 0) - { - return FAIL; - } - - //release SS51 & DSP - opr_buf[0] = 0x00; - ret = i2c_write_bytes(client, 0x4180, opr_buf, 1); - if (ret < 0) - { - return FAIL; - } - //int sync - gtp_int_sync(25); - - //check fw run status - ret = i2c_read_bytes(client, 0x8041, opr_buf, 1); - if (ret < 0) - { - return FAIL; - } - if(0xAA == opr_buf[0]) - { - GTP_ERROR("IC works abnormally,startup failed."); - return FAIL; - } - else - { - GTP_INFO("IC works normally, Startup success."); - opr_buf[0] = 0xAA; - i2c_write_bytes(client, 0x8041, opr_buf, 1); - return SUCCESS; - } -} - -static s32 gtp_esd_recovery(struct i2c_client *client) -{ - s32 retry = 0; - s32 ret = 0; - struct goodix_ts_data *ts; - - ts = i2c_get_clientdata(client); - - gtp_irq_disable(ts); - - GTP_INFO("GT9XXF esd recovery mode"); - for (retry = 0; retry < 5; retry++) - { - ret = gup_fw_download_proc(NULL, GTP_FL_ESD_RECOVERY); - if (FAIL == ret) - { - GTP_ERROR("esd recovery failed %d", retry+1); - continue; - } - ret = gtp_fw_startup(ts->client); - if (FAIL == ret) - { - GTP_ERROR("GT9XXF start up failed %d", retry+1); - continue; - } - break; - } - gtp_irq_enable(ts); - - if (retry >= 5) - { - GTP_ERROR("failed to esd recovery"); - return FAIL; - } - - GTP_INFO("Esd recovery successful"); - return SUCCESS; -} - -void gtp_recovery_reset(struct i2c_client *client) -{ -#if GTP_ESD_PROTECT - gtp_esd_switch(client, SWITCH_OFF); -#endif - GTP_DEBUG_FUNC(); - - gtp_esd_recovery(client); - -#if GTP_ESD_PROTECT - gtp_esd_switch(client, SWITCH_ON); -#endif -} - -static s32 gtp_bak_ref_proc(struct goodix_ts_data *ts, u8 mode) -{ - s32 ret = 0; - s32 i = 0; - s32 j = 0; - u16 ref_sum = 0; - u16 learn_cnt = 0; - u16 chksum = 0; - s32 ref_seg_len = 0; - s32 ref_grps = 0; - struct file *ref_filp = NULL; - u8 *p_bak_ref; - - ret = gup_check_fs_mounted("/data"); - if (FAIL == ret) - { - ts->ref_chk_fs_times++; - GTP_DEBUG("Ref check /data times/MAX_TIMES: %d / %d", ts->ref_chk_fs_times, GTP_CHK_FS_MNT_MAX); - if (ts->ref_chk_fs_times < GTP_CHK_FS_MNT_MAX) - { - msleep(50); - GTP_INFO("/data not mounted."); - return FAIL; - } - GTP_INFO("check /data mount timeout..."); - } - else - { - GTP_INFO("/data mounted!!!(%d/%d)", ts->ref_chk_fs_times, GTP_CHK_FS_MNT_MAX); - } - - p_bak_ref = (u8 *)kzalloc(ts->bak_ref_len, GFP_KERNEL); - - if (NULL == p_bak_ref) - { - GTP_ERROR("Allocate memory for p_bak_ref failed!"); - return FAIL; - } - - if (ts->is_950) - { - ref_seg_len = ts->bak_ref_len / 6; - ref_grps = 6; - } - else - { - ref_seg_len = ts->bak_ref_len; - ref_grps = 1; - } - ref_filp = filp_open(GTP_BAK_REF_PATH, O_RDWR | O_CREAT, 0666); - if (IS_ERR(ref_filp)) - { - GTP_ERROR("Failed to open/create %s.", GTP_BAK_REF_PATH); - if (GTP_BAK_REF_SEND == mode) - { - goto bak_ref_default; - } - else - { - goto bak_ref_exit; - } - } - - switch (mode) - { - case GTP_BAK_REF_SEND: - GTP_INFO("Send backup-reference"); - ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); - ret = ref_filp->f_op->read(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); - if (ret < 0) - { - GTP_ERROR("failed to read bak_ref info from file, sending defualt bak_ref"); - goto bak_ref_default; - } - for (j = 0; j < ref_grps; ++j) - { - ref_sum = 0; - for (i = 0; i < (ref_seg_len); i += 2) - { - ref_sum += (p_bak_ref[i + j * ref_seg_len] << 8) + p_bak_ref[i+1 + j * ref_seg_len]; - } - learn_cnt = (p_bak_ref[j * ref_seg_len + ref_seg_len -4] << 8) + (p_bak_ref[j * ref_seg_len + ref_seg_len -3]); - chksum = (p_bak_ref[j * ref_seg_len + ref_seg_len -2] << 8) + (p_bak_ref[j * ref_seg_len + ref_seg_len -1]); - GTP_DEBUG("learn count = %d", learn_cnt); - GTP_DEBUG("chksum = %d", chksum); - GTP_DEBUG("ref_sum = 0x%04X", ref_sum & 0xFFFF); - // Sum(1~ref_seg_len) == 1 - if (1 != ref_sum) - { - GTP_INFO("wrong chksum for bak_ref, reset to 0x00 bak_ref"); - memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len); - p_bak_ref[ref_seg_len + j * ref_seg_len - 1] = 0x01; - } - else - { - if (j == (ref_grps - 1)) - { - GTP_INFO("backup-reference data in %s used", GTP_BAK_REF_PATH); - } - } - } - ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); - if (FAIL == ret) - { - GTP_ERROR("failed to send bak_ref because of iic comm error"); - goto bak_ref_exit; - } - break; - - case GTP_BAK_REF_STORE: - GTP_INFO("Store backup-reference"); - ret = i2c_read_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); - if (ret < 0) - { - GTP_ERROR("failed to read bak_ref info, sending default back-reference"); - goto bak_ref_default; - } - ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); - ref_filp->f_op->write(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); - break; - - default: - GTP_ERROR("invalid backup-reference request"); - break; - } - ret = SUCCESS; - goto bak_ref_exit; - -bak_ref_default: - - for (j = 0; j < ref_grps; ++j) - { - memset(&p_bak_ref[j * ref_seg_len], 0, ref_seg_len); - p_bak_ref[j * ref_seg_len + ref_seg_len - 1] = 0x01; // checksum = 1 - } - ret = i2c_write_bytes(ts->client, GTP_REG_BAK_REF, p_bak_ref, ts->bak_ref_len); - if (!IS_ERR(ref_filp)) - { - GTP_INFO("write backup-reference data into %s", GTP_BAK_REF_PATH); - ref_filp->f_op->llseek(ref_filp, 0, SEEK_SET); - ref_filp->f_op->write(ref_filp, (char*)p_bak_ref, ts->bak_ref_len, &ref_filp->f_pos); - } - if (ret == FAIL) - { - GTP_ERROR("failed to load the default backup reference"); - } - -bak_ref_exit: - - if (p_bak_ref) - { - kfree(p_bak_ref); - } - if (ref_filp && !IS_ERR(ref_filp)) - { - filp_close(ref_filp, NULL); - } - return ret; -} - - -static s32 gtp_verify_main_clk(u8 *p_main_clk) -{ - u8 chksum = 0; - u8 main_clock = p_main_clk[0]; - s32 i = 0; - - if (main_clock < 50 || main_clock > 120) - { - return FAIL; - } - - for (i = 0; i < 5; ++i) - { - if (main_clock != p_main_clk[i]) - { - return FAIL; - } - chksum += p_main_clk[i]; - } - chksum += p_main_clk[5]; - if ( (chksum) == 0) - { - return SUCCESS; - } - else - { - return FAIL; - } -} - -static s32 gtp_main_clk_proc(struct goodix_ts_data *ts) -{ - s32 ret = 0; - s32 i = 0; - s32 clk_chksum = 0; - struct file *clk_filp = NULL; - u8 p_main_clk[6] = {0}; - - ret = gup_check_fs_mounted("/data"); - if (FAIL == ret) - { - ts->clk_chk_fs_times++; - GTP_DEBUG("Clock check /data times/MAX_TIMES: %d / %d", ts->clk_chk_fs_times, GTP_CHK_FS_MNT_MAX); - if (ts->clk_chk_fs_times < GTP_CHK_FS_MNT_MAX) - { - msleep(50); - GTP_INFO("/data not mounted."); - return FAIL; - } - GTP_INFO("Check /data mount timeout!"); - } - else - { - GTP_INFO("/data mounted!!!(%d/%d)", ts->clk_chk_fs_times, GTP_CHK_FS_MNT_MAX); - } - - clk_filp = filp_open(GTP_MAIN_CLK_PATH, O_RDWR | O_CREAT, 0666); - if (IS_ERR(clk_filp)) - { - GTP_ERROR("%s is unavailable, calculate main clock", GTP_MAIN_CLK_PATH); - } - else - { - clk_filp->f_op->llseek(clk_filp, 0, SEEK_SET); - clk_filp->f_op->read(clk_filp, (char *)p_main_clk, 6, &clk_filp->f_pos); - - ret = gtp_verify_main_clk(p_main_clk); - if (FAIL == ret) - { - // recalculate main clock & rewrite main clock data to file - GTP_ERROR("main clock data in %s is wrong, recalculate main clock", GTP_MAIN_CLK_PATH); - } - else - { - GTP_INFO("main clock data in %s used, main clock freq: %d", GTP_MAIN_CLK_PATH, p_main_clk[0]); - filp_close(clk_filp, NULL); - goto update_main_clk; - } - } - -#if GTP_ESD_PROTECT - gtp_esd_switch(ts->client, SWITCH_OFF); -#endif - ret = gup_clk_calibration(); - gtp_esd_recovery(ts->client); - -#if GTP_ESD_PROTECT - gtp_esd_switch(ts->client, SWITCH_ON); -#endif - - GTP_INFO("calibrate main clock: %d", ret); - if (ret < 50 || ret > 120) - { - GTP_ERROR("wrong main clock: %d", ret); - goto exit_main_clk; - } - - // Sum{0x8020~0x8025} = 0 - for (i = 0; i < 5; ++i) - { - p_main_clk[i] = ret; - clk_chksum += p_main_clk[i]; - } - p_main_clk[5] = 0 - clk_chksum; - - if (!IS_ERR(clk_filp)) - { - GTP_DEBUG("write main clock data into %s", GTP_MAIN_CLK_PATH); - clk_filp->f_op->llseek(clk_filp, 0, SEEK_SET); - clk_filp->f_op->write(clk_filp, (char *)p_main_clk, 6, &clk_filp->f_pos); - filp_close(clk_filp, NULL); - } - -update_main_clk: - ret = i2c_write_bytes(ts->client, GTP_REG_MAIN_CLK, p_main_clk, 6); - if (FAIL == ret) - { - GTP_ERROR("update main clock failed!"); - return FAIL; - } - return SUCCESS; - -exit_main_clk: - if (!IS_ERR(clk_filp)) - { - filp_close(clk_filp, NULL); - } - return FAIL; -} - - -s32 gtp_gt9xxf_init(struct i2c_client *client) -{ - s32 ret = 0; - - ret = gup_fw_download_proc(NULL, GTP_FL_FW_BURN); - if (FAIL == ret) - { - return FAIL; - } - - ret = gtp_fw_startup(client); - if (FAIL == ret) - { - return FAIL; - } - return SUCCESS; -} - -void gtp_get_chip_type(struct goodix_ts_data *ts) -{ - u8 opr_buf[10] = {0x00}; - s32 ret = 0; - - msleep(10); - - ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CHIP_TYPE, opr_buf, 10); - - if (FAIL == ret) - { - GTP_ERROR("Failed to get chip-type, set chip type default: GOODIX_GT9"); - ts->chip_type = CHIP_TYPE_GT9; - return; - } - - if (!memcmp(opr_buf, "GOODIX_GT9", 10)) - { - ts->chip_type = CHIP_TYPE_GT9; - } - else // GT9XXF - { - ts->chip_type = CHIP_TYPE_GT9F; - } - GTP_INFO("Chip Type: %s", (ts->chip_type == CHIP_TYPE_GT9) ? "GOODIX_GT9" : "GOODIX_GT9F"); -} - -#endif -//************* For GT9XXF End ************// /******************************************************* Function: - I2c probe. +Goodix touchscreen probe function. + Input: - client: i2c device struct. - id: device id. +client: i2c device struct. +id:device id. + Output: - Executive outcomes. - 0: succeed. -*******************************************************/ +Executive outcomes. 0---succeed. + *******************************************************/ static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { - s32 ret = -1; - struct goodix_ts_data *ts; - u16 version_info; + s32 ret = -1; + struct goodix_ts_data *ts; + u16 version_info; - //do NOT remove these logs - dprintk(DEBUG_INIT,"GTP Driver Version: %s", GTP_DRIVER_VERSION); - dprintk(DEBUG_INIT,"GTP I2C Address: 0x%02x", client->addr); - config_info.probed = 0; + dprintk(DEBUG_INIT, "GTP Driver Version:%s\n",GTP_DRIVER_VERSION); + printk("GTP I2C Address:0x%02x\n", client->addr); - i2c_connect_client = client; - + i2c_connect_client = client; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk("I2C check functionality failed.\n"); return -ENODEV; } - if (config_info.dev == NULL) - config_info.dev = &client->dev; -#if !USE_DETECT - if (!gUseDetect && startup()) { - printk("can not startup device!\n"); - goto fail; - } -#endif ts = kzalloc(sizeof(*ts), GFP_KERNEL); if (ts == NULL) { printk("Alloc GFP_KERNEL memory failed.\n"); - goto fail; + return -ENOMEM; } - memset(ts, 0, sizeof(*ts)); - INIT_WORK(&ts->work, goodix_ts_work_func); - ts->client = client; - spin_lock_init(&ts->irq_lock); // 2.6.39 later - // ts->irq_lock = SPIN_LOCK_UNLOCKED; // 2.6.39 & before -#if GTP_ESD_PROTECT - ts->clk_tick_cnt = 2 * HZ; // HZ: clock ticks in 1 second generated by system - GTP_DEBUG("Clock ticks for an esd cycle: %d", ts->clk_tick_cnt); - spin_lock_init(&ts->esd_lock); - // ts->esd_lock = SPIN_LOCK_UNLOCKED; -#endif - i2c_set_clientdata(client, ts); + memset(ts, 0, sizeof(*ts)); + INIT_WORK(&ts->work, goodix_ts_work_func); + ts->client = client; + i2c_set_clientdata(client, ts); + //ts->irq_lock = SPIN_LOCK_UNLOCKED; + ts->gtp_rawdiff_mode = 0; - ts->gtp_rawdiff_mode = 0; - ts->gtp_is_suspend = 0; -#if GTP_COMPATIBLE_MODE - gtp_get_chip_type(ts); - - if (CHIP_TYPE_GT9F == ts->chip_type) - { - ret = gtp_gt9xxf_init(ts->client); - if (FAIL == ret) - { - printk("Failed to init GT9XXF."); - } - } -#endif -#if GTP_I2C_TEST - ret = gtp_i2c_test(client); - if (ret < 0) - { - printk("I2C communication ERROR!"); - goto fail; - } -#endif - ret = gtp_read_version(client, &version_info); - if (ret < 0) { - printk("Read version failed."); + ret = gtp_i2c_test(client); + if (ret < 0){ + printk("I2C communication ERROR!\n"); + goto exit_device_detect; } - ret = gtp_init_panel(ts); - if (ret < 0) - { - printk("GTP init panel failed."); - } + printk(KERN_ALERT "create_singlethread_workqueue goodix_resume.\n"); + goodix_resume_wq = create_singlethread_workqueue("goodix_resume"); + if (goodix_resume_wq == NULL) { + printk("create goodix_resume_wq fail!\n"); + return -ENOMEM; + } - // Create proc file system - gt91xx_config_proc = proc_create(GT91XX_CONFIG_PROC_FILE, 0666, NULL, &config_proc_ops); - if (gt91xx_config_proc == NULL) - { - GTP_ERROR("create_proc_entry %s failed\n", GT91XX_CONFIG_PROC_FILE); - } - else - { - GTP_INFO("create proc entry %s success", GT91XX_CONFIG_PROC_FILE); - } + printk(KERN_ALERT "create_singlethread_workqueue goodix_wq.\n"); + + goodix_wq = create_singlethread_workqueue("goodix_wq"); + if (!goodix_wq) { + printk(KERN_ALERT "Creat goodix_wq workqueue failed.\n"); + return -ENOMEM; + } #if GTP_AUTO_UPDATE - ret = gup_init_update_proc(ts); - if (ret < 0) - { - GTP_ERROR("Create update thread error."); - } + //ret = gup_init_update_proc(ts); + // if (ret < 0) { + // printk("Create update thread error."); + // } #endif + ret = gtp_init_panel(ts); + if (ret < 0) { + printk("GTP init panel failed.\n"); + } + ret = gtp_request_input_dev(ts); if (ret < 0) { - GTP_ERROR("GTP request input dev failed"); + printk("GTP request input dev failed\n"); + goto exit_device_detect; } - ret = gtp_request_irq(ts); - if (ret < 0) - { - GTP_INFO("GTP works in polling mode."); - } - else - { - GTP_INFO("GTP works in interrupt mode."); - } + ret = gtp_read_version(client, &version_info); + if (ret < 0) { + printk("Read version failed."); + } - if (ts->use_irq) - { - gtp_irq_enable(ts); - } + config_info.dev = &(ts->input_dev->dev); + + ret = input_request_int(&(config_info.input_type), goodix_ts_irq_handler,CTP_IRQ_MODE, ts); + if (ret) { + printk("Request irq fail!.\n"); + } + + + spin_lock_init(&ts->irq_lock); #if GTP_CREATE_WR_NODE - init_wr_node(client); + init_wr_node(client); #endif #if GTP_ESD_PROTECT - gtp_esd_switch(client, SWITCH_ON); + INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); + gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); #endif - - pm_runtime_set_active(&client->dev); - pm_runtime_get(&client->dev); - pm_runtime_enable(&client->dev); - config_info.probed = 1; - - return 0; - -fail: - input_sensor_free(&(config_info.input_type)); - return -1; + dprintk(DEBUG_INIT, "gt9xx probe success!\n"); + return 0; +exit_device_detect: + i2c_set_clientdata(client, NULL); + kfree(ts); + return ret; } /******************************************************* Function: - Goodix touchscreen driver release function. +Goodix touchscreen driver release function. + Input: - client: i2c device struct. +client: i2c device struct. + Output: - Executive outcomes. 0---succeed. -*******************************************************/ +Executive outcomes. 0---succeed. + *******************************************************/ static int goodix_ts_remove(struct i2c_client *client) { - struct goodix_ts_data *ts = i2c_get_clientdata(client); + struct goodix_ts_data *ts = i2c_get_clientdata(client); - GTP_DEBUG_FUNC(); - + dprintk(DEBUG_INIT,"%s start!\n", __func__); #ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&ts->early_suspend); + unregister_early_suspend(&ts->early_suspend); #endif #if GTP_CREATE_WR_NODE - uninit_wr_node(); + uninit_wr_node(); #endif #if GTP_ESD_PROTECT - destroy_workqueue(gtp_esd_check_workqueue); + flush_workqueue(gtp_esd_check_workqueue); + if(gtp_esd_check_workqueue) + destroy_workqueue(gtp_esd_check_workqueue); #endif - pm_runtime_disable(&client->dev); - pm_runtime_set_suspended(&client->dev); - remove_proc_entry(GT91XX_CONFIG_PROC_FILE,NULL); - sysfs_remove_group(&ts->input_dev->dev.kobj, >p_attribute_group); - - if (ts) - { - if (ts->use_irq) - { - gtp_set_int_value(0); - input_free_int(&(config_info.input_type), ts); - } - else - { - hrtimer_cancel(&ts->timer); - } - } - else { - printk("error!!! ts is null!\n"); - return -1; - } - - - GTP_INFO("GTP driver removing..."); - i2c_set_clientdata(client, NULL); - input_unregister_device(ts->input_dev); - kfree(ts); - - return 0; -} - -#ifdef CONFIG_PM -/******************************************************* -Function: - Early suspend function. -Input: - h: early_suspend struct. -Output: - None. -*******************************************************/ -static void goodix_ts_suspend(struct goodix_ts_data *ts) -{ - s8 ret = -1; - - GTP_DEBUG_FUNC(); - GTP_INFO("System suspend."); - - ts->gtp_is_suspend = 1; - g_suspend_flag = 1; - dprintk(DEBUG_INIT, "%s g_suspend_flag=%d\n", __func__, g_suspend_flag); - -#if GTP_ESD_PROTECT - gtp_esd_switch(ts->client, SWITCH_OFF); -#endif - - if (gtp_gesture_wakeup) - ret = gtp_enter_doze(ts); - else { - if (ts->use_irq) { - gtp_irq_disable(ts); - } - else { - hrtimer_cancel(&ts->timer); - } - ret = gtp_enter_sleep(ts); - } - if (ret < 0) { - GTP_ERROR("GTP suspend failed."); - } - /* to avoid waking up while not sleeping - delay 48 + 10ms to ensure reliability */ - msleep(58); - - if (!gtp_gesture_wakeup) { - printk("ctp power off suspend!!!\n"); - input_set_power_enable(&(config_info.input_type), 0); - __gpio_set_value(config_info.wakeup_gpio.gpio, 0); - } -} - -/******************************************************* -Function: - Late resume function. -Input: - h: early_suspend struct. -Output: - None. -*******************************************************/ -static void goodix_ts_resume(struct goodix_ts_data *ts) -{ - s8 ret = -1; - GTP_DEBUG_FUNC(); - - dprintk(DEBUG_SUSPEND, "System resume\n"); - if (!gtp_gesture_wakeup) { - __gpio_set_value(config_info.wakeup_gpio.gpio, 1); - dprintk(DEBUG_INIT, "ctp power on in goodix_ts_resume!!!\n"); - input_set_power_enable(&(config_info.input_type), 1); - msleep(10); - } - - ret = gtp_wakeup_sleep(ts); - if (gtp_gesture_wakeup) - doze_status = DOZE_DISABLED; - - if (ret < 0) { - dprintk(DEBUG_INIT, "GTP later resume failed."); - } -#if (GTP_COMPATIBLE_MODE) - if (CHIP_TYPE_GT9F == ts->chip_type) { - /* do nothing */ - } - else -#endif - { - gtp_send_cfg(ts->client); - } - printk("ts->use_irq=%d", ts->use_irq); - if (ts->use_irq) { - gtp_irq_enable(ts); - } - else { - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - } - - ts->gtp_is_suspend = 0; - g_suspend_flag = 0; - dprintk(DEBUG_INIT, "%s g_suspend_flag=%d\n", __func__, g_suspend_flag); -#if GTP_ESD_PROTECT - gtp_esd_switch(ts->client, SWITCH_ON); -#endif -} - -static int gtp_pm_suspend(struct device *dev) -{ - struct goodix_ts_data *ts = dev_get_drvdata(dev); - dprintk(DEBUG_SUSPEND, "CONFIG_PM:enter gtp_pm_suspend. \n"); - if (pm_runtime_suspended(dev)) - return 0; - - if (ts) { - goodix_ts_suspend(ts); - } - - return 0; -} -static int gtp_pm_resume(struct device *dev) -{ - struct goodix_ts_data *ts = dev_get_drvdata(dev); - dprintk(DEBUG_SUSPEND, "CONFIG_PM:enter laterresume: goodix_ts_resume. \n"); - if (pm_runtime_suspended(dev)) - return 0; - - if (ts) { - goodix_ts_resume(ts); - } + input_free_int(&(config_info.input_type), ts); + flush_workqueue(goodix_wq); + //cancel_work_sync(&goodix_init_work); + cancel_work_sync(&goodix_resume_work); + if(goodix_wq) + destroy_workqueue(goodix_wq); + //destroy_workqueue(goodix_init_wq); + if(goodix_resume_wq) + destroy_workqueue(goodix_resume_wq); + i2c_set_clientdata(ts->client, NULL); + input_unregister_device(ts->input_dev); + kfree(ts); return 0; } -static struct dev_pm_ops gtp_pm_ops = { - .suspend = gtp_pm_suspend, - .resume = gtp_pm_resume, -}; -#endif +static void goodix_resume_events (struct work_struct *work) +{ + int ret; + struct goodix_ts_data *ts = i2c_get_clientdata(i2c_connect_client); + + ret = gtp_wakeup_sleep(ts); + if (ret < 0) + printk("resume power on failed\n"); + gtp_irq_enable(ts); +} + +/******************************************************* +Function: +Early suspend function. + +Input: +h:early_suspend struct. + +Output: +None. + *******************************************************/ #ifdef CONFIG_HAS_EARLYSUSPEND -/******************************************************* -Function: - Early suspend function. -Input: - h: early_suspend struct. -Output: - None. -*******************************************************/ static void goodix_ts_early_suspend(struct early_suspend *h) { - struct goodix_ts_data *ts; - s8 ret = -1; - ts = container_of(h, struct goodix_ts_data, early_suspend); + struct goodix_ts_data *ts; + s8 ret = -1; + ts = container_of(h, struct goodix_ts_data, early_suspend); - GTP_DEBUG_FUNC(); - - GTP_INFO("System suspend."); - - ts->gtp_is_suspend = 1; - g_suspend_flag = 1; - dprintk(DEBUG_INIT,"%s g_suspend_flag=%d\n",__func__,g_suspend_flag); #if GTP_ESD_PROTECT - gtp_esd_switch(ts->client, SWITCH_OFF); + ts->gtp_is_suspend = 1; + cancel_delayed_work_sync(>p_esd_check_work); #endif -//#if GTP_GESTURE_WAKEUP -if(gtp_gesture_wakeup) - ret = gtp_enter_doze(ts); -else { -//#else - if (ts->use_irq) - { - gtp_irq_disable(ts); - } - else - { - hrtimer_cancel(&ts->timer); - } - ret = gtp_enter_sleep(ts); -} -//#endif - if (ret < 0) - { - GTP_ERROR("GTP early suspend failed."); - } - // to avoid waking up while not sleeping - // delay 48 + 10ms to ensure reliability - msleep(58); -//#if (!GTP_GESTURE_WAKEUP) -if(!gtp_gesture_wakeup){ - printk("ctp power off in early suspend!!!\n"); - input_set_power_enable(&(config_info.input_type), 0); - __gpio_set_value(config_info.wakeup_gpio.gpio, 0); -//#endif -} + gtp_irq_disable(ts); + + + cancel_work_sync(&goodix_resume_work); + flush_workqueue(goodix_resume_wq); + ret = cancel_work_sync(&ts->work); + flush_workqueue(goodix_wq); + + ret = gtp_enter_sleep(ts); + if (ret < 0) { + printk("GTP early suspend failed."); + } } /******************************************************* Function: - Late resume function. +Late resume function. + Input: - h: early_suspend struct. +h:early_suspend struct. + Output: - None. -*******************************************************/ +None. + *******************************************************/ static void goodix_ts_late_resume(struct early_suspend *h) { - struct goodix_ts_data *ts; - s8 ret = -1; - ts = container_of(h, struct goodix_ts_data, early_suspend); + struct goodix_ts_data *ts; + ts = container_of(h, struct goodix_ts_data, early_suspend); - GTP_DEBUG_FUNC(); - - GTP_INFO("System resume."); -//#if (!GTP_GESTURE_WAKEUP) -if(!gtp_gesture_wakeup){ - __gpio_set_value(config_info.wakeup_gpio.gpio, 1); - printk("ctp power on in late resume!!!\n"); - input_set_power_enable(&(config_info.input_type), 1); - msleep(10); -} -//#endif - - ret = gtp_wakeup_sleep(ts); - -//#if GTP_GESTURE_WAKEUP -if(gtp_gesture_wakeup) - doze_status = DOZE_DISABLED; -//#endif - - if (ret < 0) - { - GTP_ERROR("GTP later resume failed."); - } -#if (GTP_COMPATIBLE_MODE) - if (CHIP_TYPE_GT9F == ts->chip_type) - { - // do nothing - } - else -#endif - { - gtp_send_cfg(ts->client); - } - - if (ts->use_irq) - { - gtp_irq_enable(ts); - } - else - { - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - } - - ts->gtp_is_suspend = 0; - g_suspend_flag = 0; - dprintk(DEBUG_INIT,"%s g_suspend_flag=%d\n",__func__,g_suspend_flag); -#if GTP_ESD_PROTECT - gtp_esd_switch(ts->client, SWITCH_ON); -#endif -} -#endif - + queue_work(goodix_resume_wq, &goodix_resume_work);//gandy #if GTP_ESD_PROTECT -s32 gtp_i2c_read_no_rst(struct i2c_client *client, u8 *buf, s32 len) + ts->gtp_is_suspend = 0; + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); +#endif +} +#else +#ifdef CONFIG_PM +static int goodix_ts_suspend(struct device *dev) { - struct i2c_msg msgs[2]; - s32 ret=-1; - s32 retries = 0; + struct goodix_ts_data *ts = dev_get_drvdata(dev); + s8 ret = -1; - GTP_DEBUG_FUNC(); + printk("%s goodix_ts_suspend\n", goodix_ts_name); +#if GTP_ESD_PROTECT + ts->gtp_is_suspend = 1; + cancel_delayed_work_sync(>p_esd_check_work); +#endif - msgs[0].flags = !I2C_M_RD; - msgs[0].addr = client->addr; - msgs[0].len = GTP_ADDR_LENGTH; - msgs[0].buf = &buf[0]; - //msgs[0].scl_rate = 300 * 1000; // for Rockchip, etc. + /* + ret = input_set_int_enable(&(config_info.input_type), 0); + if (ret < 0) + dprintk(DEBUG_SUSPEND,"%s irq disable failed\n", goodix_ts_name); + */ + gtp_irq_disable(ts); + cancel_work_sync(&goodix_resume_work); + flush_workqueue(goodix_resume_wq); + ret = cancel_work_sync(&ts->work); + flush_workqueue(goodix_wq); - msgs[1].flags = I2C_M_RD; - msgs[1].addr = client->addr; - msgs[1].len = len - GTP_ADDR_LENGTH; - msgs[1].buf = &buf[GTP_ADDR_LENGTH]; - //msgs[1].scl_rate = 300 * 1000; + ret = gtp_enter_sleep(ts); + if (ret < 0) { + printk("GTP suspend failed."); + } - while(retries < 5) - { - ret = i2c_transfer(client->adapter, msgs, 2); - if(ret == 2)break; - retries++; - } - if ((retries >= 5)) - { - GTP_ERROR("I2C Read: 0x%04X, %d bytes failed, errcode: %d!", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); - } - return ret; + msleep(58); + + input_set_power_enable(&(config_info.input_type), 0); + __gpio_set_value(config_info.wakeup_gpio.gpio, 0); + return 0; } -s32 gtp_i2c_write_no_rst(struct i2c_client *client,u8 *buf,s32 len) +static int goodix_ts_resume(struct device *dev) { - struct i2c_msg msg; - s32 ret = -1; - s32 retries = 0; + printk("%s goodix_ts_resume\n", goodix_ts_name); + __gpio_set_value(config_info.wakeup_gpio.gpio, 1); + input_set_power_enable(&(config_info.input_type), 1); + msleep(10); + queue_work(goodix_resume_wq, &goodix_resume_work);//gandy - GTP_DEBUG_FUNC(); +#if GTP_ESD_PROTECT + struct goodix_ts_data *ts = dev_get_drvdata(dev); + ts->gtp_is_suspend = 0; + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); +#endif + return 0; +} +#endif +#endif - msg.flags = !I2C_M_RD; - msg.addr = client->addr; - msg.len = len; - msg.buf = buf; - //msg.scl_rate = 300 * 1000; // for Rockchip, etc - - while(retries < 5) - { - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret == 1)break; - retries++; - } - if((retries >= 5)) - { - GTP_ERROR("I2C Write: 0x%04X, %d bytes failed, errcode: %d!", (((u16)(buf[0] << 8)) | buf[1]), len-2, ret); - } - return ret; +#if GTP_ESD_PROTECT +/******************************************************* +Function: +Initialize external watchdog for esd protect +Input: +client: i2c device. +Output: +result of i2c write operation. +1: succeed, otherwise: failed + *********************************************************/ +s32 gtp_init_ext_watchdog(struct i2c_client *client) +{ + u8 opr_buffer[4] = {0x80, 0x40, 0xAA, 0xAA}; + dprintk(DEBUG_INIT, "Init external watchdog..."); + return gtp_i2c_write(client, opr_buffer, 4); } /******************************************************* Function: - switch on & off esd delayed work +Esd protect function. +Added external watchdog by meta, 2013/03/07 Input: - client: i2c device - on: SWITCH_ON / SWITCH_OFF +work: delayed work Output: - void -*********************************************************/ -void gtp_esd_switch(struct i2c_client *client, s32 on) -{ - struct goodix_ts_data *ts; - - ts = i2c_get_clientdata(client); - spin_lock(&ts->esd_lock); - - if (SWITCH_ON == on) // switch on esd - { - if (!ts->esd_running) - { - ts->esd_running = 1; - spin_unlock(&ts->esd_lock); - GTP_INFO("Esd started"); - queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt); - } - else - { - spin_unlock(&ts->esd_lock); - } - } - else // switch off esd - { - if (ts->esd_running) - { - ts->esd_running = 0; - spin_unlock(&ts->esd_lock); - GTP_INFO("Esd cancelled"); - cancel_delayed_work_sync(>p_esd_check_work); - } - else - { - spin_unlock(&ts->esd_lock); - } - } -} - -/******************************************************* -Function: - Initialize external watchdog for esd protect -Input: - client: i2c device. -Output: - result of i2c write operation. - 1: succeed, otherwise: failed -*********************************************************/ -static s32 gtp_init_ext_watchdog(struct i2c_client *client) -{ - u8 opr_buffer[3] = {0x80, 0x41, 0xAA}; - GTP_DEBUG("[Esd]Init external watchdog"); - return gtp_i2c_write_no_rst(client, opr_buffer, 3); -} - -/******************************************************* -Function: - Esd protect function. - External watchdog added by meta, 2013/03/07 -Input: - work: delayed work -Output: - None. -*******************************************************/ +None. + *******************************************************/ static void gtp_esd_check_func(struct work_struct *work) { - s32 i; - s32 ret = -1; - struct goodix_ts_data *ts = NULL; - u8 esd_buf[5] = {0x80, 0x40}; + s32 i; + s32 ret = -1; + struct goodix_ts_data *ts = NULL; + u8 test[4] = {0x80, 0x40}; - GTP_DEBUG_FUNC(); + dprintk(DEBUG_INIT, "enter %s work!\n", __func__); - ts = i2c_get_clientdata(i2c_connect_client); + ts = i2c_get_clientdata(i2c_connect_client); - if (ts->gtp_is_suspend) - { - GTP_INFO("Esd suspended!"); - return; - } + if (ts->gtp_is_suspend || ts->enter_update) { + return; + } - for (i = 0; i < 3; i++) - { - ret = gtp_i2c_read_no_rst(ts->client, esd_buf, 4); + for (i = 0; i < 3; i++) { + ret = gtp_i2c_read(ts->client, test, 4); - GTP_DEBUG("[Esd]0x8040 = 0x%02X, 0x8041 = 0x%02X", esd_buf[2], esd_buf[3]); - if ((ret < 0)) - { - // IIC communication problem - continue; - } - else - { - if ((esd_buf[2] == 0xAA) || (esd_buf[3] != 0xAA)) - { - // IC works abnormally.. - u8 chk_buf[4] = {0x80, 0x40}; + dprintk(DEBUG_INIT, "0x8040 = 0x%02X, 0x8041 = 0x%02X", test[2], test[3]); + if ((ret < 0)) { + // IC works abnormally.. + continue; + }else { + if ((test[2] == 0xAA) || (test[3] != 0xAA)) { + // IC works abnormally.. + i = 3; + break; + }else { + // IC works normally, Write 0x8040 0xAA + test[2] = 0xAA; + gtp_i2c_write(ts->client, test, 3); + break; + } + } + } - gtp_i2c_read_no_rst(ts->client, chk_buf, 4); + if (i >= 3) { + GTP_DEBUG("IC Working ABNORMALLY, Resetting Guitar..."); + // gtp_reset_guitar(ts->client, 50); + } - GTP_DEBUG("[Check]0x8040 = 0x%02X, 0x8041 = 0x%02X", chk_buf[2], chk_buf[3]); + if(!ts->gtp_is_suspend) { + queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, GTP_ESD_CHECK_CIRCLE); + } - if ((chk_buf[2] == 0xAA) || (chk_buf[3] != 0xAA)) - { - i = 3; - break; - } - else - { - continue; - } - } - else - { - // IC works normally, Write 0x8040 0xAA, feed the dog - esd_buf[2] = 0xAA; - gtp_i2c_write_no_rst(ts->client, esd_buf, 3); - break; - } - } - } - if (i >= 3) - { - #if GTP_COMPATIBLE_MODE - if (CHIP_TYPE_GT9F == ts->chip_type) - { - if (ts->rqst_processing) - { - GTP_INFO("Request processing, no esd recovery"); - } - else - { - GTP_ERROR("IC working abnormally! Process esd recovery."); - esd_buf[0] = 0x42; - esd_buf[1] = 0x26; - esd_buf[2] = 0x01; - esd_buf[3] = 0x01; - esd_buf[4] = 0x01; - gtp_i2c_write_no_rst(ts->client, esd_buf, 5); - msleep(50); - gtp_esd_recovery(ts->client); - } - } - else - #endif - { - GTP_ERROR("IC working abnormally! Process reset guitar."); - esd_buf[0] = 0x42; - esd_buf[1] = 0x26; - esd_buf[2] = 0x01; - esd_buf[3] = 0x01; - esd_buf[4] = 0x01; - gtp_i2c_write_no_rst(ts->client, esd_buf, 5); - msleep(50); - gtp_reset_guitar(ts->client, 50); - msleep(50); - gtp_send_cfg(ts->client); - } - } - - if(!ts->gtp_is_suspend) - { - queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt); - } - else - { - GTP_INFO("Esd suspended!"); - } - return; + return; } #endif static const struct i2c_device_id goodix_ts_id[] = { - { CTP_NAME, 0 }, - { } + { CTP_NAME, 0 }, + { } }; -#if !USE_DETECT -static const struct of_device_id goodix_of_match[] = { - {.compatible = "allwinner,goodix"}, - {}, +#ifndef CONFIG_HAS_EARLYSUSPEND +#ifdef CONFIG_PM +static const struct dev_pm_ops gt9xx_pm_ops = { + .suspend = goodix_ts_suspend, + .resume = goodix_ts_resume, }; + +#define GT9XX_PM_OPS (>9xx_pm_ops) +#endif #endif static struct i2c_driver goodix_ts_driver = { - .class = I2C_CLASS_HWMON, - .probe = goodix_ts_probe, - .remove = goodix_ts_remove, - .id_table = goodix_ts_id, + .class = I2C_CLASS_HWMON, + .probe = goodix_ts_probe, + .remove = goodix_ts_remove, + .id_table = goodix_ts_id, .driver = { -#if !USE_DETECT - .of_match_table = goodix_of_match, -#endif .name = CTP_NAME, - .owner = THIS_MODULE, + .owner = THIS_MODULE, #ifndef CONFIG_HAS_EARLYSUSPEND -#if defined(CONFIG_PM) - .pm = >p_pm_ops, +#ifdef CONFIG_PM + .pm = GT9XX_PM_OPS, #endif #endif }, .address_list = normal_i2c, -#if USE_DETECT - .detect = ctp_detect, -#endif }; static int ctp_get_system_config(void) -{ - ctp_print_info(config_info,DEBUG_INIT); - twi_id = config_info.twi_id; - screen_max_x = config_info.screen_max_x; - screen_max_y = config_info.screen_max_y; - revert_x_flag = config_info.revert_x_flag; - revert_y_flag = config_info.revert_y_flag; - exchange_x_y_flag = config_info.exchange_x_y_flag; - if((screen_max_x == 0) || (screen_max_y == 0)){ - printk("%s:read config error!\n",__func__); - return 0; - } - return 1; +{ + ctp_print_info(config_info,DEBUG_INIT); + twi_id = config_info.twi_id; +#if LVDS_1024x600 + screen_max_x = 1024; + screen_max_y = 600; + revert_x_flag = 0; + revert_y_flag = 0; + exchange_x_y_flag = 0; +#else + screen_max_x = config_info.screen_max_x; + screen_max_y = config_info.screen_max_y; + revert_x_flag = config_info.revert_x_flag; + revert_y_flag = config_info.revert_y_flag; + exchange_x_y_flag = config_info.exchange_x_y_flag; +#endif + if((screen_max_x == 0) || (screen_max_y == 0)){ + printk("%s:read config error!\n",__func__); + return 0; + } + return 1; } -static int startup(void) +/******************************************************* + * Function: + * Driver Install function. + * Input: + * None. + * Output: + * Executive Outcomes. 0---succeed. + * ********************************************************/ +static int __init goodix_ts_init(void) { s32 ret = -1; + int val = 0; + struct device_node *np = NULL; - dprintk(DEBUG_INIT, "GTP driver init\n"); + dprintk(DEBUG_INIT,"GTP driver init\n"); if (!input_sensor_startup(&(config_info.input_type))) { ret = input_sensor_init(&(config_info.input_type)); if (ret != 0) { pr_err("%s:ctp_ops.input_sensor_init err.\n", __func__); - return -1; + return ret; } input_set_power_enable(&(config_info.input_type), 1); } else { pr_err("%s: input_ctp_startup err.\n", __func__); - return -1; + return 0; } - if (config_info.ctp_used == 0) { + if(config_info.ctp_used == 0){ printk("*** ctp_used set to 0 !\n"); printk("*** if use ctp,please put the sys_config.fex ctp_used set to 1. \n"); - return -1; - } - - if (config_info.ctp_gesture_wakeup == 1) { - gtp_gesture_wakeup = 1; - dprintk(DEBUG_INIT, "GTP driver gesture wakeup is used!\n"); - } - - if (!gtp_gesture_wakeup) - gtp_power_ctrl_sleep = 1; - - if (!ctp_get_system_config()) { - printk("%s:read config fail!\n", __func__); - return -1; - } - sunxi_gpio_to_name(CTP_IRQ_NUMBER, irq_pin_name); - gtp_io_init(20); - return 0; -} - -/******************************************************* -Function: - Driver Install function. -Input: - None. -Output: - Executive Outcomes. 0---succeed. -********************************************************/ -static int goodix_ts_init(void) -{ -#if !USE_DETECT - struct device_node *np = NULL; - char *p = NULL; -#endif - -#if USE_DETECT - if (startup() != 0) return 0; -#else - np = of_find_node_by_name(NULL, "ctp"); - if (np && np->parent) { - p = (char *) np->parent->name; - if (strncmp(p, "twi", 3) != 0) { - gUseDetect = 1; - if (startup() != 0) - return 0; - goodix_ts_driver.detect = ctp_detect; - } } + + np = of_find_node_by_name(NULL, "ctp"); + if (!np) { + pr_err("ERROR! get ctp node failed, func:%s, line:%d\n",__FUNCTION__, __LINE__); + return -1; + } + + ret = of_property_read_u32(np, "ctp_gesture_wakeup", &val); + if (ret) { + pr_err("get ctp_screen_max_x is fail, %d\n", ret); + } + msleep(10); +#if 0 + if(!ctp_get_system_config()){ + printk("%s:read config fail!\n",__func__); + return ret; + } +#else + //ret = of_property_read_u32(np, "ctp_screen_max_x", &screen_max_x); + //of_property_read_u32(np, "ctp_screen_max_y", &screen_max_y); + //of_property_read_u32(np, "ctp_revert_x_flag", &revert_x_flag); + //of_property_read_u32(np, "ctp_revert_y_flag", &revert_y_flag); + //of_property_read_u32(np, "ctp_exchange_x_y_flag", &exchange_x_y_flag); + printk(KERN_ERR"------------ screen_max_x=%d, screen_max_y=%d, revert_x_flag=%d, revert_y_flag=%d, exchange_x_y_flag=%d\n", screen_max_x, screen_max_y, revert_x_flag, revert_y_flag, exchange_x_y_flag); #endif + sunxi_gpio_to_name(CTP_IRQ_NUMBER,irq_pin_name); + gtp_io_init(20); + goodix_wq = create_singlethread_workqueue("goodix_wq"); - if (!goodix_wq) { + if (!goodix_wq) + { GTP_ERROR("Creat workqueue failed."); return -ENOMEM; } #if GTP_ESD_PROTECT - INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); - gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); + INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); + gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); #endif - - i2c_add_driver(&goodix_ts_driver); - if (config_info.probed) - return 0; - else - return -1; + goodix_ts_driver.detect = ctp_detect; + ret = i2c_add_driver(&goodix_ts_driver); + return ret; } -/******************************************************* + +/******************************************************* Function: - Driver uninstall function. +Driver uninstall function. Input: - None. +None. Output: - Executive Outcomes. 0---succeed. -********************************************************/ +Executive Outcomes. 0---succeed. + ********************************************************/ static void __exit goodix_ts_exit(void) { - dprintk(DEBUG_INIT,"GTP driver exited."); + printk("GTP driver exited.\n"); i2c_del_driver(&goodix_ts_driver); - if (goodix_wq) - { - destroy_workqueue(goodix_wq); - } - input_set_power_enable(&(config_info.input_type), 0); input_sensor_free(&(config_info.input_type)); } @@ -3515,3 +1564,4 @@ MODULE_DESCRIPTION("GTP Series Driver"); MODULE_LICENSE("GPL"); + -- Gitblit v1.6.2