rk30_phonepad:add gt828 support for auto touchscreen
authorluowei <lw@rock-chips.com>
Thu, 11 Oct 2012 11:24:36 +0000 (19:24 +0800)
committerluowei <lw@rock-chips.com>
Thu, 11 Oct 2012 11:25:00 +0000 (19:25 +0800)
drivers/input/ts/chips/Kconfig
drivers/input/ts/chips/Makefile
drivers/input/ts/chips/ft5306.c
drivers/input/ts/chips/gt8110.c
drivers/input/ts/chips/gt828.c [new file with mode: 0755]
drivers/input/ts/ts-auto.c
drivers/input/ts/ts-i2c.c
include/linux/ts-auto.h

index 7dc4b2ab2f4835b1406ddbcca86036474725cc82..8dbe1802670dbdd32c325ed37506f58162ac6d5d 100755 (executable)
@@ -1,11 +1,11 @@
 config TS_FT5306\r
   bool "touch screen ft5306"\r
        default n
-config TS_CT360\r
-  bool "touch screen ct360"\r
-       default n
-
\r
 config TS_GT8110\r
   bool "touch screen gt8110"\r
-       default n         
\ No newline at end of file
+       default n       \r
+\r
+config TS_GT828\r
+  bool "touch screen gt828"\r
+       default n
\ No newline at end of file
index aec7f1c31b27162a43b4295926fe10510feeb8c6..7f758978d77383a826c0ab3397bcac7b619cea12 100755 (executable)
@@ -1,3 +1,3 @@
 obj-$(CONFIG_TS_FT5306)                        += ft5306.o\r
-obj-$(CONFIG_TS_CT360)                 += ct360.o\r
-obj-$(CONFIG_TS_GT8110)                        += gt8110.o
\ No newline at end of file
+obj-$(CONFIG_TS_GT8110)                        += gt8110.o\r
+obj-$(CONFIG_TS_GT828)                 += gt828.o
\ No newline at end of file
index cb3a7417f0d6d2279631dbdcb1712816805ef66e..6e005d1adf5006916f24b092af4ff214bd94e786 100755 (executable)
@@ -57,7 +57,7 @@ static int ts_active(struct i2c_client *client, int enable)
        if(enable)\r
        {\r
                gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);\r
-               mdelay(10);\r
+               msleep(10);\r
                gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);\r
                msleep(100);\r
        }\r
@@ -208,9 +208,13 @@ struct ts_operate ts_ft5306_ops = {
        .name                           = "ft5306",\r
        .slave_addr                     = 0x3e,\r
        .id_i2c                         = TS_ID_FT5306,                 //i2c id number\r
+       .reg_size                       = 1,\r
        .pixel                          = {1024,768},\r
        .id_reg                         = FT5306_ID_REG,\r
-       .id_data                        = TS_UNKNOW_DATA,       \r
+       .id_data                        = TS_UNKNOW_DATA,\r
+       .version_reg                    = TS_UNKNOW_DATA,\r
+       .version_len                    = 0,\r
+       .version_data                   = NULL,\r
        .read_reg                       = FT5306_DATA_REG,              //read data\r
        .read_len                       = 32,                           //data length\r
        .trig                           = IRQF_TRIGGER_FALLING,         \r
index 301bb273d838d4492d6e9f813c748d1318107d0e..de04d89925e4adbb084c644bc27912f3cb53efa3 100755 (executable)
@@ -329,9 +329,13 @@ struct ts_operate ts_gt8110_ops = {
        .name                           = "gt8110",\r
        .slave_addr                     = 0x5c,\r
        .id_i2c                         = TS_ID_GT8110,                 //i2c id number\r
+       .reg_size                       = 1,\r
        .pixel                          = {1280,800},\r
        .id_reg                         = GT8110_ID_REG,\r
-       .id_data                        = TS_UNKNOW_DATA,       \r
+       .id_data                        = TS_UNKNOW_DATA,\r
+       .version_reg                    = TS_UNKNOW_DATA,\r
+       .version_len                    = 0,\r
+       .version_data                   = NULL,\r
        .read_reg                       = GT8110_DATA_REG,              //read data\r
        .read_len                       = 5*10+3+1,                     //data length\r
        .trig                           = IRQ_TYPE_LEVEL_LOW,           \r
diff --git a/drivers/input/ts/chips/gt828.c b/drivers/input/ts/chips/gt828.c
new file mode 100755 (executable)
index 0000000..bee168e
--- /dev/null
@@ -0,0 +1,322 @@
+/* drivers/input/ts/chips/gt828.c\r
+ *\r
+ * Copyright (C) 2012-2015 ROCKCHIP.\r
+ * Author: luowei <lw@rock-chips.com>\r
+ *\r
+ * This software is licensed under the terms of the GNU General Public\r
+ * License version 2, as published by the Free Software Foundation, and\r
+ * may be copied, distributed, and modified under those terms.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ */\r
+#include <linux/interrupt.h>\r
+#include <linux/i2c.h>\r
+#include <linux/slab.h>\r
+#include <linux/irq.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/gpio.h>\r
+#include <asm/uaccess.h>\r
+#include <asm/atomic.h>\r
+#include <linux/delay.h>\r
+#include <linux/input.h>\r
+#include <linux/workqueue.h>\r
+#include <linux/freezer.h>\r
+#include <linux/input/mt.h>\r
+#include <mach/gpio.h>\r
+#include <mach/board.h> \r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+#include <linux/earlysuspend.h>\r
+#endif  \r
+#include <linux/ts-auto.h>\r
+        \r
+        \r
+#if 0\r
+#define DBG(x...)  printk(x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+\r
+\r
+//Register define\r
+#define GTP_READ_COOR_ADDR    0x0F40\r
+#define GTP_REG_SLEEP         0x0FF2\r
+#define GTP_REG_SENSOR_ID     0x0FF5\r
+#define GTP_REG_CONFIG_DATA   0x0F80\r
+#define GTP_REG_VERSION       0x0F7D\r
+\r
+\r
+\r
+/****************operate according to ts chip:start************/\r
+\r
+int ts_i2c_end_cmd(struct i2c_client *client)\r
+{\r
+       int result  = -1;\r
+       char end_cmd_data[2]={0x80, 0x00};\r
+\r
+       result = ts_tx_data(client, end_cmd_data, 2);\r
+       if(result < 0)\r
+       {\r
+               printk("%s:fail to init ts\n",__func__);\r
+               return result;\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+\r
+static int ts_active(struct i2c_client *client, int enable)\r
+{\r
+       struct ts_private_data *ts =\r
+           (struct ts_private_data *) i2c_get_clientdata(client);      \r
+       int result = 0;\r
+\r
+       if(enable)\r
+       {\r
+               gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);\r
+               msleep(10);\r
+               gpio_direction_output(ts->pdata->reset_pin, GPIO_HIGH);\r
+               msleep(100);\r
+       }\r
+       else\r
+       {\r
+               gpio_direction_output(ts->pdata->reset_pin, GPIO_LOW);  \r
+       }\r
+               \r
+       \r
+       return result;\r
+}\r
+\r
+static int ts_init(struct i2c_client *client)\r
+{\r
+       struct ts_private_data *ts =\r
+           (struct ts_private_data *) i2c_get_clientdata(client);\r
+       int result = 0;\r
+       char version_data[4] = {ts->ops->version_reg >> 8, ts->ops->version_reg & 0xff};\r
+       \r
+       //read version\r
+       result = ts_rx_data(client, version_data, 4);\r
+       if(result < 0)\r
+       {\r
+               printk("%s:fail to init ts\n",__func__);\r
+               return result;\r
+       }\r
+       version_data[4]='\0';\r
+       \r
+       result = ts_i2c_end_cmd(client);\r
+       if(result < 0)\r
+       {\r
+               printk("%s:fail to end ts\n",__func__);\r
+               //return result;\r
+       }\r
+       \r
+       printk("%s:%s version is %s\n",__func__,ts->ops->name, version_data);\r
+\r
+       //init some register\r
+       //to do\r
+       \r
+       return result;\r
+}\r
+\r
+\r
+static int ts_report_value(struct i2c_client *client)\r
+{\r
+       struct ts_private_data *ts =\r
+               (struct ts_private_data *) i2c_get_clientdata(client);  \r
+       struct ts_platform_data *pdata = ts->pdata;\r
+       struct ts_event *event = &ts->event;\r
+       unsigned char buf[2 + 2 + 5 * 5 + 1] = {0};\r
+       int result = 0 , i = 0, off = 0, id = 0;\r
+       int finger = 0;\r
+       int checksum = 0;\r
+\r
+       buf[0] = ts->ops->read_reg >> 8;\r
+       buf[1] = ts->ops->read_reg & 0xff;\r
+       result = ts_rx_data_word(client, buf, ts->ops->read_len);\r
+       if(result < 0)\r
+       {\r
+               printk("%s:fail to init ts\n",__func__);\r
+               return result;\r
+       }\r
+\r
+       result = ts_i2c_end_cmd(client);\r
+       if(result < 0)\r
+       {\r
+               printk("%s:fail to end ts\n",__func__);\r
+               return result;\r
+       }\r
+       \r
+       //for(i=0; i<ts->ops->read_len; i++)\r
+       //DBG("buf[%d]=0x%x\n",i,buf[i]);\r
+       finger = buf[0];\r
+       if((finger & 0xc0) != 0x80)\r
+       {\r
+               DBG("%s:data not ready!\n",__func__);\r
+               return -1;\r
+       }\r
+\r
+\r
+#if 0  \r
+       event->touch_point = 0;\r
+       for(i=0; i<ts->ops->max_point; i++)\r
+       {\r
+               if(finger & (1<<i))\r
+                       event->touch_point++;\r
+       }\r
+\r
+       check_sum = 0;\r
+       for ( i = 0; i < 5 * event->touch_point; i++)\r
+       {\r
+               check_sum += buf[2+i];\r
+       }\r
+       if (check_sum != buf[5 * event->touch_point])\r
+       {\r
+               DBG("%s:check sum error!\n",__func__);\r
+               return -1;\r
+       }\r
+#endif\r
+       \r
+       for(i = 0; i<ts->ops->max_point; i++)\r
+       {\r
+               off = i*5+2;\r
+\r
+               id = i;                         \r
+               event->point[id].id = id;\r
+               event->point[id].status = !!(finger & (1 << i));\r
+               event->point[id].x = (buf[off+0]<<8) | buf[off+1];\r
+               event->point[id].y = (buf[off+2]<<8) | buf[off+3];\r
+               event->point[id].press = buf[off+4];    \r
+               \r
+               if(ts->ops->xy_swap)\r
+               {\r
+                       swap(event->point[id].x, event->point[id].y);\r
+               }\r
+\r
+               if(ts->ops->x_revert)\r
+               {\r
+                       event->point[id].x = ts->ops->pixel.max_x - event->point[id].x; \r
+               }\r
+\r
+               if(ts->ops->y_revert)\r
+               {\r
+                       event->point[id].y = ts->ops->pixel.max_y - event->point[id].y;\r
+               }\r
+\r
+               if(event->point[id].status != 0)\r
+               {               \r
+                       input_mt_slot(ts->input_dev, event->point[id].id);\r
+                       input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, event->point[id].id);\r
+                       input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, event->point[id].press);\r
+                       input_report_abs(ts->input_dev, ABS_MT_POSITION_X, event->point[id].x);\r
+                       input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, event->point[id].y);\r
+                       input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 1);\r
+                       DBG("%s:%s press down,id=%d,x=%d,y=%d\n",__func__,ts->ops->name, event->point[id].id, event->point[id].x,event->point[id].y);\r
+               }\r
+               else if ((event->point[id].status == 0) && (event->point[id].last_status != 0))\r
+               {                       \r
+                       input_mt_slot(ts->input_dev, event->point[i].id);                               \r
+                       input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);\r
+                       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
+                       DBG("%s:%s press up,id=%d\n",__func__,ts->ops->name, event->point[i].id);\r
+               }\r
+\r
+               event->point[i].last_status = event->point[i].status;   \r
+               \r
+       }\r
+       \r
+       input_sync(ts->input_dev);\r
+\r
+       return 0;\r
+}\r
+\r
+static int ts_suspend(struct i2c_client *client)\r
+{\r
+       struct ts_private_data *ts =\r
+               (struct ts_private_data *) i2c_get_clientdata(client);  \r
+       struct ts_platform_data *pdata = ts->pdata;\r
+\r
+       if(ts->ops->active)\r
+               ts->ops->active(client, 0);\r
+       \r
+       return 0;\r
+}\r
+\r
+\r
+\r
+\r
+static int ts_resume(struct i2c_client *client)\r
+{\r
+       struct ts_private_data *ts =\r
+               (struct ts_private_data *) i2c_get_clientdata(client);  \r
+       struct ts_platform_data *pdata = ts->pdata;\r
+       \r
+       if(ts->ops->active)\r
+               ts->ops->active(client, 1);\r
+       return 0;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+struct ts_operate ts_gt828_ops = {\r
+       .name                           = "gt828",\r
+       .slave_addr                     = 0x5d,\r
+       .id_i2c                         = TS_ID_GT828,                  //i2c id number\r
+       .reg_size                       = 2,\r
+       .pixel                          = {1024,600},\r
+       .id_reg                         = GTP_REG_SENSOR_ID,\r
+       .id_data                        = TS_UNKNOW_DATA,\r
+       .version_reg                    = 0x0F7D,\r
+       .version_len                    = 0,\r
+       .version_data                   = NULL,\r
+       .read_reg                       = GTP_READ_COOR_ADDR,           //read data\r
+       .read_len                       = 2 + 2 + 5 * 5 + 1,            //data length\r
+       .trig                           = IRQF_TRIGGER_FALLING,         \r
+       .max_point                      = 5,\r
+       .xy_swap                        = 0,\r
+       .x_revert                       = 0,\r
+       .y_revert                       = 0,\r
+       .range                          = {1024,600},\r
+       .irq_enable                     = 1,\r
+       .poll_delay_ms                  = 0,\r
+       .active                         = ts_active,    \r
+       .init                           = ts_init,\r
+       .check_irq                      = NULL,\r
+       .report                         = ts_report_value,\r
+       .firmware                       = NULL,\r
+       .suspend                        = ts_suspend,\r
+       .resume                         = ts_resume,\r
+};\r
+\r
+/****************operate according to ts chip:end************/\r
+\r
+//function name should not be changed\r
+static struct ts_operate *ts_get_ops(void)\r
+{\r
+       return &ts_gt828_ops;\r
+}\r
+\r
+\r
+static int __init ts_gt828_init(void)\r
+{\r
+       struct ts_operate *ops = ts_get_ops();\r
+       int result = 0;\r
+       result = ts_register_slave(NULL, NULL, ts_get_ops);     \r
+       DBG("%s\n",__func__);\r
+       return result;\r
+}\r
+\r
+static void __exit ts_gt828_exit(void)\r
+{\r
+       struct ts_operate *ops = ts_get_ops();\r
+       ts_unregister_slave(NULL, NULL, ts_get_ops);\r
+}\r
+\r
+\r
+subsys_initcall(ts_gt828_init);\r
+module_exit(ts_gt828_exit);\r
+\r
index 2eff50e2748f35e6e247198aa62d8161432ff44f..fc305cb30ecd0d710ce4f9afec1d192de4598413 100755 (executable)
@@ -51,18 +51,29 @@ static int ts_get_id(struct ts_operate *ops, struct i2c_client *client, int *val
        struct ts_private_data *ts =\r
            (struct ts_private_data *) i2c_get_clientdata(client);      \r
        int result = 0;\r
-       char temp = ops->id_reg;\r
+       char temp[4] = {ops->id_reg & 0xff};\r
        int i = 0;\r
        \r
        DBG("%s:start\n",__func__);\r
        if(ops->id_reg >= 0)\r
        {\r
-               for(i=0; i<1; i++)\r
+               for(i=0; i<2; i++)\r
                {\r
-                       result = ts_rx_data(client, &temp, 1);\r
-                       *value = temp;\r
+                       if(ops->reg_size == 2)\r
+                       {\r
+                               temp[0] = ops->id_reg >> 8;\r
+                               temp[1] = ops->id_reg & 0xff;\r
+                               result = ts_rx_data_word(client, &temp, 2);\r
+                               *value = (temp[0] << 8) | temp[1];\r
+                       }\r
+                       else\r
+                       {\r
+                               result = ts_rx_data(client, &temp, 1);\r
+                               *value = temp[0];\r
+                       }\r
                        if(!result)\r
                        break;\r
+\r
                }\r
 \r
                if(result)\r
@@ -81,6 +92,55 @@ static int ts_get_id(struct ts_operate *ops, struct i2c_client *client, int *val
 }\r
 \r
 \r
+static int ts_get_version(struct ts_operate *ops, struct i2c_client *client)\r
+{\r
+       struct ts_private_data *ts =\r
+           (struct ts_private_data *) i2c_get_clientdata(client);      \r
+       int result = 0;\r
+       char temp[TS_MAX_VER_LEN + 1] = {0};\r
+       int i = 0;\r
+       \r
+       DBG("%s:start\n",__func__);\r
+       \r
+       if(ops->version_reg >= 0)\r
+       {\r
+               if((ops->version_len < 0) || (ops->version_len > TS_MAX_VER_LEN))\r
+               {\r
+                       printk("%s:version_len is error\n",__func__,ops->version_len);\r
+                       ops->version_len = TS_MAX_VER_LEN;\r
+               }\r
+       \r
+               if(ops->reg_size == 2)\r
+               {\r
+                       result = ts_rx_data_word(client, temp, ops->version_len);\r
+               }\r
+               else\r
+               {\r
+                       result = ts_rx_data(client, temp, ops->version_len);\r
+               }\r
+       \r
+\r
+               if(result)\r
+                       return result;\r
+               \r
+               if(ops->version_data)\r
+               {\r
+                       for(i=0; i<ops->version_len; i++)\r
+                       {\r
+                               if(temp[i] == ops->version_data[i])\r
+                                       continue;\r
+                               printk("%s:version %s is not %s\n",__func__,temp, ops->version_data);\r
+                               result = -1;\r
+                       }\r
+               }\r
+                       \r
+               DBG("%s:%s version: %s\n",__func__,ops->name, temp);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+\r
 static int ts_chip_init(struct i2c_client *client)\r
 {\r
        struct ts_private_data *ts =\r
@@ -110,23 +170,30 @@ static int ts_chip_init(struct i2c_client *client)
                }\r
 \r
                client->addr = ops->slave_addr; //use slave_addr of ops\r
-               \r
+#if 0          \r
                if(ops->active)\r
                {\r
                        result = ops->active(client, TS_ENABLE);\r
                        if(result < 0)\r
                        {\r
-                               printk("%s:fail to init ts\n",__func__);\r
+                               printk("%s:fail to active ts\n",__func__);\r
                                continue;\r
                        }\r
                }\r
-\r
+#endif\r
                result = ts_get_id(ops, client, &ts->devid);//get id\r
                if(result < 0)\r
                {       \r
                        printk("%s:fail to read %s devid:0x%x\n",__func__, ops->name, ts->devid);       \r
                        continue;\r
                }\r
+\r
+               result = ts_get_version(ops, client);   //get version\r
+               if(result < 0)\r
+               {       \r
+                       printk("%s:fail to read %s version\n",__func__, ops->name);     \r
+                       continue;\r
+               }\r
        \r
                ts->ops = ops;  //save ops\r
 \r
index 8c00ff7d7ea38bfbea2b3a5916557c5903931e03..c7e4d9695098651c3f4a3cf37b71a379e4bf0274 100755 (executable)
@@ -71,7 +71,7 @@ static int ts_i2c_write(struct i2c_adapter *i2c_adap,
 \r
 static int senosr_i2c_read(struct i2c_adapter *i2c_adap,\r
                           unsigned char address, unsigned char reg,\r
-                          unsigned int len, unsigned char *data)\r
+                          unsigned int tx_len, unsigned int rx_len, unsigned char *data)\r
 {\r
        struct i2c_msg msgs[2];\r
        int res;\r
@@ -84,13 +84,13 @@ static int senosr_i2c_read(struct i2c_adapter *i2c_adap,
        msgs[0].addr = address;\r
        msgs[0].flags = 0;      /* write */\r
        msgs[0].buf = &reg;\r
-       msgs[0].len = 1;\r
+       msgs[0].len = tx_len;\r
        msgs[0].scl_rate = TS_I2C_RATE;\r
        \r
        msgs[1].addr = address;\r
        msgs[1].flags = I2C_M_RD;\r
        msgs[1].buf = data;\r
-       msgs[1].len = len;\r
+       msgs[1].len = rx_len;\r
        msgs[1].scl_rate = TS_I2C_RATE; \r
 \r
        res = i2c_transfer(i2c_adap, msgs, 2);\r
@@ -113,7 +113,7 @@ int ts_rx_data(struct i2c_client *client, char *rxData, int length)
 #endif\r
        int ret = 0;\r
        char reg = rxData[0];\r
-       ret = senosr_i2c_read(client->adapter, client->addr, reg, length, rxData);\r
+       ret = senosr_i2c_read(client->adapter, client->addr, reg, 1, length, rxData);\r
        \r
 #ifdef TS_DEBUG_ENABLE\r
        DBG("addr=0x%x,len=%d,rxdata:",reg,length);\r
@@ -125,6 +125,28 @@ int ts_rx_data(struct i2c_client *client, char *rxData, int length)
 }\r
 EXPORT_SYMBOL(ts_rx_data);\r
 \r
+int ts_rx_data_word(struct i2c_client *client, char *rxData, int length)\r
+{\r
+#ifdef TS_DEBUG_ENABLE\r
+       struct ts_private_data* ts = \r
+               (struct ts_private_data *)i2c_get_clientdata(client);\r
+       int i = 0;\r
+#endif\r
+       int ret = 0;\r
+       char reg = rxData[0];\r
+       ret = senosr_i2c_read(client->adapter, client->addr, reg, 2, length, rxData);\r
+       \r
+#ifdef TS_DEBUG_ENABLE\r
+       DBG("addr=0x%x,len=%d,rxdata:",reg,length);\r
+       for(i=0; i<length; i++)\r
+               DBG("0x%x,",rxData[i]);\r
+       DBG("\n");\r
+#endif \r
+       return ret;\r
+}\r
+EXPORT_SYMBOL(ts_rx_data_word);\r
+\r
+\r
 int ts_tx_data(struct i2c_client *client, char *txData, int length)\r
 {\r
 #ifdef TS_DEBUG_ENABLE \r
index c5af819f39f40652ad7f967553624bf3914f9025..3d5661997d1ac36e0391a3da4f70f68cd27fe81b 100755 (executable)
@@ -6,6 +6,8 @@
 #define        TS_DISABLE      0\r
 #define TS_UNKNOW_DATA -1\r
 #define        TS_MAX_POINT    20\r
+#define        TS_MAX_VER_LEN  64\r
+\r
 \r
 enum ts_id {\r
        TS_ID_INVALID = 0,\r
@@ -13,6 +15,7 @@ enum ts_id {
        TS_ID_FT5306,\r
        TS_ID_CT360,\r
        TS_ID_GT8110,\r
+       TS_ID_GT828,\r
        \r
        TS_NUM_ID,\r
 };\r
@@ -51,9 +54,13 @@ struct ts_operate {
        char *name;\r
        char slave_addr;\r
        int id_i2c;\r
-       struct ts_max_pixel pixel;      \r
+       struct ts_max_pixel pixel;\r
+       int reg_size;\r
        int id_reg;\r
        int id_data;\r
+       int version_reg;\r
+       char *version_data;\r
+       int version_len;        //<64\r
        int read_reg;\r
        int read_len;\r
        int trig;       //intterupt trigger\r
@@ -65,7 +72,7 @@ struct ts_operate {
        int irq_enable;         //if irq_enable=1 then use irq else use polling  \r
        int poll_delay_ms;      //polling\r
        int gpio_level_no_int;\r
-       int (*active)(struct i2c_client *client, int enable);   \r
+       int (*active)(struct i2c_client *client, int enable);\r
        int (*init)(struct i2c_client *client); \r
        int (*check_irq)(struct i2c_client *client);\r
        int (*report)(struct i2c_client *client);\r
@@ -111,6 +118,7 @@ extern int ts_unregister_slave(struct i2c_client *client,
 \r
 extern int ts_rx_data(struct i2c_client *client, char *rxData, int length);\r
 extern int ts_tx_data(struct i2c_client *client, char *txData, int length);\r
+extern int ts_rx_data_word(struct i2c_client *client, char *rxData, int length);\r
 extern int ts_write_reg(struct i2c_client *client, int addr, int value);\r
 extern int ts_read_reg(struct i2c_client *client, int addr);\r
 extern int ts_tx_data_normal(struct i2c_client *client, char *buf, int num);\r