Input: touchscreen-gt9xx: enable the gt9xx SLOT REPORT
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / rk29_i2c_goodix.c
index a00966b58ebad2a6b0b9d2345a8d3a868f469fa5..e0d4fe707ae6e6bebf24c53101110db3be724a2b 100755 (executable)
@@ -18,7 +18,6 @@
 #include <linux/time.h>\r
 #include <linux/delay.h>\r
 #include <linux/device.h>\r
-#include <linux/earlysuspend.h>\r
 #include <linux/hrtimer.h>\r
 #include <linux/i2c.h>\r
 #include <linux/input.h>\r
 #include <linux/interrupt.h>\r
 #include <linux/io.h>\r
 #include <linux/platform_device.h>\r
-#include <mach/gpio.h>\r
+#include <linux/gpio.h>\r
+#include <linux/version.h>\r
+#include <linux/slab.h>\r
+#include <linux/of_gpio.h>\r
 \r
 #include <linux/irq.h>\r
 #include <linux/syscalls.h>\r
 #include <linux/reboot.h>\r
 #include <linux/proc_fs.h>\r
 #include <linux/async.h>\r
-#include "rk29_i2c_goodix.h"\r
-\r
 #include <linux/vmalloc.h>\r
 #include <linux/fs.h>\r
 #include <linux/string.h>\r
 #include <linux/completion.h>\r
 #include <asm/uaccess.h>\r
-#include <mach/board.h>\r
+\r
+#include "rk29_i2c_goodix.h"\r
 \r
 #define PEN_DOWN 1\r
 #define PEN_RELEASE 0\r
 #define PEN_DOWN_UP 2 //fjp\r
 \r
-static struct rk_touch_info *info_buf;\r
-\r
 static int dbg_thresd = 0;\r
 #define DBG(x...) do { if(unlikely(dbg_thresd)) printk(KERN_INFO x); } while (0)\r
 \r
@@ -78,14 +77,12 @@ static int goodix_i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int le
        msgs[0].addr=client->addr;\r
        msgs[0].len=1;\r
        msgs[0].buf=&buf[0];\r
-       msgs[0].udelay = client->udelay;\r
        msgs[0].scl_rate=200 * 1000;\r
 \r
        msgs[1].flags = client->flags | I2C_M_RD;\r
        msgs[1].addr=client->addr;\r
        msgs[1].len=len-1;\r
        msgs[1].buf=&buf[1];\r
-       msgs[1].udelay = client->udelay;\r
        msgs[1].scl_rate=200 * 1000;\r
 \r
        //disable_irq(client->irq);\r
@@ -122,7 +119,6 @@ static int goodix_i2c_write_bytes(struct i2c_client *client,uint8_t *data,int le
        msg.addr=client->addr;\r
        msg.len=len;\r
        msg.buf=data;           \r
-       msg.udelay = client->udelay;\r
        msg.scl_rate=200 * 1000;\r
        \r
        //disable_irq(client->irq);\r
@@ -151,7 +147,7 @@ static int goodix_config_ok(struct rk_ts_data *ts)
 #ifdef CONFIG_ARCH_RK29\r
         if((ret < 0) || (w != TS_MAX_X) || (h != TS_MAX_Y) || (n != 10))\r
 #else\r
-        if((ret < 0) || (w != TS_MAX_X) || (h != TS_MAX_Y) || (n != 170))\r
+        if((ret < 0) || (w != ts->abs_x_max) || (h != ts->abs_y_max) || (n != 170))\r
 #endif\r
                 return -1;\r
 \r
@@ -177,9 +173,11 @@ static int goodix_init_panel(struct rk_ts_data *ts)
 {\r
        int ret=-1, retry = 10;\r
        uint8_t rd_cfg_buf[7] = {0x66,};\r
+       uint8_t *config_info;\r
+       int config_len;\r
 \r
-#if (TS_MAX_X == 1024)&&(TS_MAX_Y == 768)                      //for malata 10.1\r
-       uint8_t config_info[] = {\r
+       //for malata 10.1\r
+       uint8_t config_info_1024_768[] = {\r
                0x65,0x02,0x04,0x00,0x03,0x00,0x0A,0x22,0x1E,0xE7,0x32,0x05,0x08,0x10,0x4C,\r
                0x41,0x41,0x20,0x09,0x00,0xA0,0xA0,0x3C,0x64,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,\r
                0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x1D,0x1C,0x1B,0x1A,0x19,0x18,\r
@@ -188,9 +186,8 @@ static int goodix_init_panel(struct rk_ts_data *ts)
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
        };\r
              \r
-#elif (TS_MAX_X == 1280)&&(TS_MAX_Y == 800)    \r
 #ifdef CONFIG_ARCH_RK29\r
-       uint8_t config_info[] = {\r
+       uint8_t config_info_1280_800[] = {\r
                0x65,0x02,0x05,0x00,0x03,0x20,0x0A,0x22,0x1E,0xE7,0x32,0x05,0x08,0x10,0x4C,\r
                0x41,0x41,0x20,0x07,0x00,0xA0,0xA0,0x46,0x64,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,\r
                0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x1D,0x1C,0x1B,0x1A,0x19,0x18,\r
@@ -199,7 +196,7 @@ static int goodix_init_panel(struct rk_ts_data *ts)
                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
        };\r
 #else\r
-       uint8_t config_info[] = {\r
+       uint8_t config_info_1280_800[] = {\r
                 0x65,0xA2,0x05,0x00,0x03,0x20,0xAA,0x22,0x1E,0xE7,0x32,0x05,0x08,0x10,0x4C,\r
                 0x42,0x42,0x20,0x00,0x09,0x80,0x80,0x32,0x46,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,\r
                 0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x1D,0x1C,0x1B,0x1A,0x19,0x18,\r
@@ -208,8 +205,7 @@ static int goodix_init_panel(struct rk_ts_data *ts)
                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
         };\r
 #endif\r
-#else\r
-       uint8_t config_info[] = {\r
+       uint8_t config_info_default[] = {\r
                0x65,0x02,0x05,0x00,0x03,0x20,0x0A,0x22,0x1E,0xE7,0x32,0x05,0x08,0x10,0x4C,\r
                0x42,0x42,0x20,0x00,0x00,0x89,0x89,0x3C,0x64,0x0E,0x0D,0x0C,0x0B,\r
                0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x1D,0x1C,\r
@@ -218,15 +214,23 @@ static int goodix_init_panel(struct rk_ts_data *ts)
                0x2B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
                0x00,0x00,0x00,0x00\r
        };\r
-#endif\r
 \r
+       if (ts->abs_x_max == 1280 && ts->abs_y_max == 800) {\r
+               config_info = config_info_1280_800;\r
+               config_len = ARRAY_SIZE(config_info_1280_800);\r
+       } else if (ts->abs_x_max == 1024 && ts->abs_y_max == 786) {\r
+               config_info = config_info_1024_768;\r
+               config_len = ARRAY_SIZE(config_info_1024_768);\r
+       } else {\r
+               config_info = config_info_default;\r
+               config_len = ARRAY_SIZE(config_info_default);\r
+       }\r
         while(--retry && (goodix_config_ok(ts) < 0)){\r
-               ret=goodix_i2c_write_bytes(ts->client,config_info, (sizeof(config_info)/sizeof(config_info[0])));\r
+               ret = goodix_i2c_write_bytes(ts->client, config_info, config_len);\r
                if (ret < 0) {\r
-                       printk("goodix write cfg info err");\r
-                       return ret;\r
+                       printk("goodix write cfg info err, retry %d\n", retry);\r
+                       msleep(100);\r
                }\r
-                msleep(100);\r
         }\r
 \r
         if(retry <= 0){\r
@@ -285,12 +289,11 @@ static int  goodix_read_version(struct rk_ts_data *ts, char **version)
        char *version_data;\r
        char *p;\r
 \r
-       *version = (char *)vmalloc(18);\r
+       *version = (char *)vzalloc(18);\r
        version_data = *version;\r
        if(!version_data)\r
                return -ENOMEM;\r
        p = version_data;\r
-       memset(version_data, 0, sizeof(version_data));\r
        version_data[0]=240;    \r
        ret=goodix_i2c_read_bytes(ts->client,version_data, 17);\r
        if (ret < 0) \r
@@ -398,169 +401,102 @@ static void goodix_get_touch_info(struct rk_ts_data *ts,char *point_num,struct r
        \r
 }\r
 \r
-\r
 /*******************************************************\r
 Description:\r
-       Goodix touchscreen work function.\r
+       External interrupt service routine.\r
 \r
 Parameter:\r
-       ts:     i2c client private struct.\r
+       irq:    interrupt number.\r
+       dev_id: private data pointer.\r
        \r
 return:\r
-       Executive outcomes.0---succeed.\r
+       irq execute status.\r
 *******************************************************/\r
-static void  rk_ts_work_func(struct work_struct *pwork)\r
-{      \r
+static irqreturn_t rk_ts_irq_handler(int irq, void *dev_id)\r
+{\r
+       struct rk_ts_data *ts = (struct rk_ts_data*)dev_id;\r
        int i =0;\r
        char point_num;\r
-       struct rk_ts_data *ts = container_of(to_delayed_work(pwork), struct rk_ts_data, ts_work);\r
-\r
-       if(!ts)\r
-       {\r
-               printk("container of rk_ts_data fail\n");\r
-               return;\r
-       }\r
-       if(!info_buf)\r
-       {\r
-               printk("info_buf fail\n");\r
-               return;\r
-       }\r
+       bool touch_down;\r
 \r
-       if(ts->get_touch_info)\r
-       {\r
-                ts->get_touch_info(ts,&point_num,info_buf);\r
-       }\r
-       for(i=0; i< point_num; i++)\r
-       {\r
-          DBG("info_buf[i].status =====%d\n",info_buf[i].status);\r
-             if(info_buf[i].status==PEN_DOWN_UP)\r
+       do {\r
+               if(ts->get_touch_info)\r
                {\r
-                      info_buf[i].status=PEN_RELEASE;\r
-                          DBG("the key %d is up------\n",i);\r
-                       input_mt_slot(ts->input_dev, i);\r
-                       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
-                       continue;\r
+                       ts->get_touch_info(ts,&point_num,ts->info_buf);\r
                }\r
-               if(info_buf[i].status==PEN_DOWN)\r
+               for(i=0; i< point_num; i++)\r
                {\r
-                       input_mt_slot(ts->input_dev, i);\r
-                       input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
-                       input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, info_buf[i].press);\r
-                       input_report_abs(ts->input_dev, ABS_MT_POSITION_X, info_buf[i].x);\r
-                       input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, info_buf[i].y);\r
-                        DBG("touch point %d %d >>x:%d>>y:%d\n",i,info_buf[i].status,info_buf[i].x,info_buf[i].y);//add by fjp 2010-9-28        \r
+                       DBG("info_buf[i].status =====%d\n",ts->info_buf[i].status);\r
+                       if (ts->info_buf[i].status==PEN_DOWN_UP)\r
+                       {\r
+                               ts->info_buf[i].status=PEN_RELEASE;\r
+                               DBG("the key %d is up------\n",i);\r
+                               input_mt_slot(ts->input_dev, i);\r
+                               input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
+                               continue;\r
+                       }\r
+                       if (ts->info_buf[i].status==PEN_DOWN)\r
+                       {\r
+                               input_mt_slot(ts->input_dev, i);\r
+                               input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
+                               input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, ts->info_buf[i].press);\r
+                               input_report_abs(ts->input_dev, ABS_MT_POSITION_X, ts->info_buf[i].x);\r
+                               input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, ts->info_buf[i].y);\r
+                               DBG("touch point %d %d >>x:%d>>y:%d\n",i,ts->info_buf[i].status,ts->info_buf[i].x,ts->info_buf[i].y);//add by fjp 2010-9-28\r
+                       }\r
                }\r
-               \r
-       \r
-          \r
-               \r
-               \r
-       }\r
-       input_sync(ts->input_dev);\r
-       \r
-    if(gpio_get_value(ts->irq_pin) == GPIO_LOW)\r
-    {\r
-       \r
-        DBG("touch down .............\n");//add by fjp 2010-9-28\r
-               queue_delayed_work(ts->ts_wq, &ts->ts_work,msecs_to_jiffies(20));\r
-       //      goto exit;\r
-               \r
-    }\r
-    else\r
-    {\r
-               \r
-        DBG("touch up>>x:%d>>y:%d\n",info_buf[0].x,info_buf[0].y);//add by fjp 2010-9-28\r
-               /*input_mt_slot(ts->input_dev, 0);\r
-               input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
-               input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
-               \r
-               input_mt_slot(ts->input_dev, 0);\r
-               input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);*/\r
+               input_sync(ts->input_dev);\r
+               touch_down = gpio_get_value(ts->irq_pin) == 0;\r
+               if (touch_down)\r
+               {\r
+                       DBG("touch down .............\n");//add by fjp 2010-9-28\r
+                       usleep_range(10000, 10000);\r
+               }\r
+       } while (touch_down);\r
 \r
-               DBG("point_num+++++++++++ = %d\n", point_num);//add by fjp 2010-9-28\r
-               for(i=0; i< point_num; i++)\r
+       DBG("touch up>>x:%d>>y:%d\n",ts->info_buf[0].x,ts->info_buf[0].y);//add by fjp 2010-9-28\r
+       /*input_mt_slot(ts->input_dev, 0);\r
+         input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
+         input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
+\r
+         input_mt_slot(ts->input_dev, 0);\r
+         input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);*/\r
+\r
+       DBG("point_num+++++++++++ = %d\n", point_num);//add by fjp 2010-9-28\r
+       for(i=0; i< point_num; i++)\r
+       {\r
+               //        printk("info_buf[i].status +++++++%d\n",ts->info_buf[i].status);\r
+               if(ts->info_buf[i].status)\r
                {\r
-       //        printk("info_buf[i].status +++++++%d\n",info_buf[i].status);\r
-                        if(info_buf[i].status)\r
-                       {\r
-                     input_mt_slot(ts->input_dev, i);//°´ÐòºÅÉϱ¨\r
+                       input_mt_slot(ts->input_dev, i);//°´ÐòºÅÉϱ¨\r
                        input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);               \r
                        //input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
-                       info_buf[i].status= PEN_RELEASE;\r
-                       \r
+                       ts->info_buf[i].status= PEN_RELEASE;\r
 \r
                        DBG("release+++++++++++ = %d\n", i);//add by fjp 2010-9-28\r
-\r
-                       }\r
                }\r
-               input_sync(ts->input_dev);\r
-               ts->pendown =PEN_RELEASE;\r
-               last_touch_num = 0;\r
-               \r
-       enable_irq(ts->irq);            \r
-      }\r
-         \r
-      \r
-//exit:\r
-         //kfree(info_buf);\r
-         \r
-  }\r
-       \r
-       \r
-/*******************************************************\r
-Description:\r
-       Timer interrupt service routine.\r
-\r
-Parameter:\r
-       timer:  timer struct pointer.\r
-       \r
-return:\r
-       Timer work mode. HRTIMER_NORESTART---not restart mode\r
-*******************************************************/\r
-static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer)\r
-{\r
-       struct rk_ts_data *ts = container_of(timer, struct rk_ts_data, timer);\r
-       queue_delayed_work(goodix_wq,&ts->ts_work,0);\r
-       hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL);\r
-       return HRTIMER_NORESTART;\r
-}\r
-/*******************************************************\r
-Description:\r
-       External interrupt service routine.\r
-\r
-Parameter:\r
-       irq:    interrupt number.\r
-       dev_id: private data pointer.\r
-       \r
-return:\r
-       irq execute status.\r
-*******************************************************/\r
-static irqreturn_t rk_ts_irq_handler(int irq, void *dev_id)\r
-{\r
+       }\r
+       input_sync(ts->input_dev);\r
+       ts->pendown =PEN_RELEASE;\r
+       last_touch_num = 0;\r
 \r
-       struct rk_ts_data *ts = (struct rk_ts_data*)dev_id;\r
-       disable_irq_nosync(ts->irq);\r
-       queue_delayed_work(ts->ts_wq, &ts->ts_work,0);\r
-       \r
        return IRQ_HANDLED;\r
 }\r
 \r
 static int rk_ts_suspend(struct i2c_client *client, pm_message_t mesg)\r
 {\r
        int ret;\r
-       struct rk_ts_data *ts = i2c_get_clientdata(client);\r
+       struct rk_ts_data *ts = i2c_get_clientdata(client);       \r
+\r
+       disable_irq(ts->irq);   \r
 \r
-       \r
-       \r
-       disable_irq(ts->irq);\r
-       \r
-#if 1\r
        if (ts->power) {\r
+               DBG("%s.....line=%d\n",__func__,__LINE__);\r
                ret = ts->power(ts, 0);\r
                if (ret < 0)\r
                        printk(KERN_ERR "goodix_ts_resume power off failed\n");\r
        }\r
-#endif\r
+\r
        return 0;\r
 }\r
 \r
@@ -568,37 +504,36 @@ static int rk_ts_resume(struct i2c_client *client)
 {\r
        int ret;\r
        struct rk_ts_data *ts = i2c_get_clientdata(client);\r
-       \r
-#if 1\r
+\r
        if (ts->power) {\r
+               DBG("%s.....line=%d\n",__func__,__LINE__);\r
                ret = ts->power(ts, 1);\r
                if (ret < 0)\r
                        printk(KERN_ERR "goodix_ts_resume power on failed\n");\r
        }\r
-#endif\r
-       \r
-       enable_irq(client->irq);\r
 \r
+       enable_irq(ts->irq);\r
        return 0;\r
 }\r
 \r
 \r
 \r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-static void rk_ts_early_suspend(struct early_suspend *h)\r
+static int rk_ts_early_suspend(struct tp_device *tp_d)\r
 {\r
        struct rk_ts_data *ts;\r
-       ts = container_of(h, struct rk_ts_data, early_suspend);\r
+       ts = container_of(tp_d, struct rk_ts_data, tp);\r
        rk_ts_suspend(ts->client, PMSG_SUSPEND);\r
+       return 0;\r
 }\r
 \r
-static void rk_ts_late_resume(struct early_suspend *h)\r
+static int rk_ts_early_resume(struct tp_device *tp_d)\r
 {\r
        struct rk_ts_data *ts;\r
-       ts = container_of(h, struct rk_ts_data, early_suspend);\r
+       ts = container_of(tp_d, struct rk_ts_data, tp);\r
        rk_ts_resume(ts->client);\r
+       return 0;\r
 }\r
-#endif\r
+\r
 \r
 /*******************************************************\r
 Description:\r
@@ -615,21 +550,21 @@ static int goodix_ts_power(struct rk_ts_data * ts, int on)
        int ret = -1;\r
        unsigned char i2c_control_buf[2] = {80,  1};            //suspend cmd\r
        int retry = 0;\r
+\r
        if(on != 0 && on !=1)\r
        {\r
-               printk(KERN_DEBUG "%s: Cant't support this command.", rk_ts_name);\r
+               printk("%s: Cant't support this command.", rk_ts_name);\r
                return -EINVAL;\r
        }\r
-       \r
-       \r
-       if(on == 0)             //suspend\r
+               \r
+       if(on == 0)//suspend\r
        { \r
         while(retry<5)\r
                {\r
                        ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
                        if(ret == 1)\r
                        {\r
-                               printk(KERN_DEBUG "touch goodix Send suspend cmd successed \n");\r
+                               printk("touch goodix Send suspend cmd successed \n");\r
                                break;\r
                        }\r
                       retry++;\r
@@ -638,12 +573,12 @@ static int goodix_ts_power(struct rk_ts_data * ts, int on)
                if(ret > 0)\r
                  ret = 0;\r
        }\r
-       else if(on == 1)                //resume\r
+       else if(on == 1)//resume\r
        {\r
-               printk(KERN_DEBUG "touch goodix int resume\n");\r
-               gpio_set_value(ts->rst_pin,GPIO_LOW);   \r
+               printk("touch goodix int resume\n");\r
+               gpio_set_value(ts->rst_pin, ts->rst_val);\r
                msleep(20);\r
-           gpio_set_value(ts->rst_pin,GPIO_HIGH);\r
+               gpio_set_value(ts->rst_pin, !ts->rst_val);\r
                ret = 0;\r
        }        \r
        return ret;\r
@@ -653,7 +588,7 @@ static int goodix_ts_power(struct rk_ts_data * ts, int on)
 static int goodix_input_params_init(struct rk_ts_data *ts)\r
 {\r
        int ret ;\r
-       ts->input_dev = input_allocate_device();\r
+       ts->input_dev = devm_input_allocate_device(&ts->client->dev);\r
        if (ts->input_dev == NULL) {\r
                ret = -ENOMEM;\r
                printk(KERN_ALERT "Failed to allocate input device\n");\r
@@ -664,7 +599,7 @@ static int goodix_input_params_init(struct rk_ts_data *ts)
        __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);\r
        __set_bit(EV_ABS, ts->input_dev->evbit);\r
 \r
-       input_mt_init_slots(ts->input_dev, ts->max_touch_num);\r
+       input_mt_init_slots(ts->input_dev, ts->max_touch_num, 0);\r
        input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);\r
        input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0);\r
        input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0);\r
@@ -685,7 +620,14 @@ static int goodix_input_params_init(struct rk_ts_data *ts)
        return 0 ;\r
        \r
 }\r
-       \r
+\r
+#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
+static const struct file_operations goodix_proc_fops = {\r
+       .read   = goodix_update_read,\r
+       .write  = goodix_update_write,\r
+};\r
+#endif\r
+\r
 static int goodix_ts_init(struct rk_ts_data *ts)\r
 {\r
        char ret ;\r
@@ -722,7 +664,7 @@ static int goodix_ts_init(struct rk_ts_data *ts)
        }\r
        vfree(version_info);\r
        #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
-       goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL);\r
+       goodix_proc_entry = proc_create("goodix-update", 0666, NULL, &goodix_proc_fops);\r
        if(goodix_proc_entry == NULL)\r
        {\r
                printk("Couldn't create proc entry!\n");\r
@@ -755,38 +697,69 @@ static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id
 {\r
        int ret = 0;\r
        struct rk_ts_data *ts;\r
-       struct goodix_platform_data *pdata ;\r
+       struct device_node *np = client->dev.of_node;\r
+       enum of_gpio_flags rst_flags, pwr_flags;\r
+       unsigned long irq_flags;\r
+       u32 val;\r
        \r
        printk(KERN_INFO "Install touch driver.\n");\r
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) \r
        {\r
                dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");\r
-               ret = -ENODEV;\r
-               goto exit;\r
+               return -ENODEV;\r
        }\r
 \r
-       ts = kzalloc(sizeof(struct rk_ts_data), GFP_KERNEL);\r
+       ts = devm_kzalloc(&client->dev, sizeof(struct rk_ts_data), GFP_KERNEL);\r
        if (ts == NULL) {\r
-               printk(KERN_ALERT "alloc for struct rk_ts_data fail\n");\r
-               ret = -ENOMEM;\r
-               goto exit;\r
+               dev_err(&client->dev, "alloc for struct rk_ts_data fail\n");\r
+               return -ENOMEM;\r
        }\r
 \r
-       pdata = client->dev.platform_data;\r
-       ts->irq_pin = pdata->irq_pin;\r
-       ts->rst_pin = pdata->rest_pin;\r
+       if (!np) {\r
+               dev_err(&client->dev, "no device tree\n");\r
+               return -EINVAL;\r
+       }\r
+       ts->irq_pin = of_get_named_gpio_flags(np, "touch-gpio", 0, (enum of_gpio_flags *)&irq_flags);\r
+       ts->rst_pin = of_get_named_gpio_flags(np, "reset-gpio", 0, &rst_flags);\r
+       ts->pwr_pin = of_get_named_gpio_flags(np, "power-gpio", 0, &pwr_flags);\r
+       if (of_property_read_u32(np, "max-x", &val)) {\r
+               dev_err(&client->dev, "no max-x defined\n");\r
+               return -EINVAL;\r
+       }\r
+       ts->abs_x_max = val;\r
+       if (of_property_read_u32(np, "max-y", &val)) {\r
+               dev_err(&client->dev, "no max-y defined\n");\r
+               return -EINVAL;\r
+       }\r
+       ts->abs_y_max = val;\r
        ts->pendown =PEN_RELEASE;\r
        ts->client = client;\r
        ts->ts_init = goodix_ts_init;   \r
        ts->power = goodix_ts_power;\r
        ts->get_touch_info = goodix_get_touch_info;\r
        ts->input_parms_init = goodix_input_params_init;\r
-       i2c_set_clientdata(client, ts);\r
        \r
+       if (gpio_is_valid(ts->pwr_pin)) {\r
+               ret = devm_gpio_request_one(&client->dev, ts->pwr_pin, (pwr_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, "goodix power pin");\r
+               if (ret != 0) {\r
+                       dev_err(&client->dev, "goodix power error\n");\r
+                       return -EIO;\r
+               }\r
+               //msleep(100);\r
+       } else {\r
+               dev_info(&client->dev, "power pin invalid\n");\r
+       }\r
 \r
-       if (pdata->init_platform_hw)\r
-       {\r
-               pdata->init_platform_hw();\r
+       if (gpio_is_valid(ts->rst_pin)) {\r
+               ts->rst_val = (rst_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;\r
+               ret = devm_gpio_request_one(&client->dev, ts->rst_pin, (rst_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, "goodix reset pin");\r
+               if (ret != 0) {\r
+                       dev_err(&client->dev, "goodix gpio_request error\n");\r
+                       return -EIO;\r
+               }\r
+             //  msleep(100);\r
+       } else {\r
+               dev_info(&client->dev, "reset pin invalid\n");\r
        }\r
 \r
        if(ts->ts_init)\r
@@ -795,71 +768,47 @@ static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id
                if(ret < 0)\r
                {\r
                        printk(KERN_ALERT "rk ts init fail\n");\r
-                       goto exit;\r
+                       return ret;\r
                }\r
        }\r
 \r
+       ts->info_buf= devm_kzalloc(&client->dev, ts->max_touch_num*sizeof(struct rk_touch_info), GFP_KERNEL);\r
+       if(!ts->info_buf)\r
+       {\r
+               dev_err(&client->dev, "alloc for rk_touch_info fail\n");\r
+               return -ENOMEM;\r
+       }\r
+\r
        if(ts->input_parms_init)\r
        {\r
                ts->input_parms_init(ts);\r
        }\r
 \r
        i2c_connect_client = client;\r
-       #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32)\r
-               ts->ts_wq= create_rt_workqueue("rk_ts_wq");             //create a work queue and worker thread\r
-       #else\r
-               ts->ts_wq= create_workqueue("rk_ts_wq"); \r
-       #endif\r
-       if (!ts->ts_wq){\r
-               printk(KERN_ALERT "creat touch screen workqueue failed\n");\r
-           return -ENOMEM;\r
-       }\r
-       \r
-       INIT_DELAYED_WORK(&ts->ts_work, rk_ts_work_func);\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-       ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;\r
-       ts->early_suspend.suspend = rk_ts_early_suspend;\r
-       ts->early_suspend.resume = rk_ts_late_resume;\r
-       register_early_suspend(&ts->early_suspend);\r
-#endif\r
 \r
-       info_buf= kzalloc(ts->max_touch_num*sizeof(struct rk_touch_info), GFP_KERNEL);\r
-       if(!info_buf)\r
-       {\r
-               printk(KERN_ALERT "alloc for rk_touch_info fail\n");\r
-               goto err_input_register_device_failed;\r
-       }\r
+       ts->tp.tp_resume = rk_ts_early_resume;\r
+       ts->tp.tp_suspend = rk_ts_early_suspend;\r
+       tp_register_fb(&ts->tp);\r
+\r
+       i2c_set_clientdata(client, ts);\r
 \r
-       ts->irq=gpio_to_irq(ts->irq_pin)        ;               //If not defined in client\r
+       ts->irq=gpio_to_irq(ts->irq_pin);               //If not defined in client\r
        if (ts->irq)\r
        {\r
-               ret = gpio_request(pdata->irq_pin, "TS_IRQ_PIN");       //Request IO\r
-               if (ret < 0) \r
-               {\r
-                       printk(KERN_ALERT "Failed to request for touch irq\n");\r
-                       goto err_input_register_device_failed;\r
-               }\r
-               else\r
-               {\r
-                       gpio_direction_input(pdata->irq_pin);\r
-               }\r
-\r
-               ret  = request_irq(ts->irq, rk_ts_irq_handler ,IRQ_TYPE_LEVEL_LOW,client->name, ts);\r
+               ret = devm_request_threaded_irq(&client->dev, ts->irq, NULL, rk_ts_irq_handler, irq_flags | IRQF_ONESHOT, client->name, ts);\r
                if (ret != 0) {\r
                        printk(KERN_ALERT "Cannot allocate ts INT!ERRNO:%d\n", ret);\r
-                       gpio_free(ts->irq_pin);\r
-                       goto err_input_register_device_failed;\r
+                       goto err;\r
                }\r
+               //disable_irq(ts->irq);\r
        }\r
        printk("goodix_ts_init: probe successfully!\n");\r
        return 0;\r
 \r
        \r
-err_input_register_device_failed:\r
-       input_free_device(ts->input_dev);\r
+err:\r
+       tp_unregister_fb(&ts->tp);\r
        i2c_set_clientdata(client, NULL);       \r
-       kfree(ts);\r
-exit:\r
        return ret;\r
 }\r
 \r
@@ -877,30 +826,23 @@ return:
 static int rk_ts_remove(struct i2c_client *client)\r
 {\r
        struct rk_ts_data *ts = i2c_get_clientdata(client);\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-       unregister_early_suspend(&ts->early_suspend);\r
-#endif\r
+       tp_unregister_fb(&ts->tp);\r
+\r
 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
        remove_proc_entry("goodix-update", NULL);\r
 #endif\r
        \r
-       gpio_free(ts->irq_pin);\r
-       free_irq(ts->irq, ts);\r
        dev_notice(&client->dev,"The driver is removing...\n");\r
        i2c_set_clientdata(client, NULL);\r
-       input_unregister_device(ts->input_dev);\r
-       if(info_buf)\r
-               kfree(info_buf);\r
-       kfree(ts);\r
        return 0;\r
 }\r
 \r
 static void rk_ts_shutdown(struct i2c_client *client)\r
 {\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
        struct rk_ts_data *ts = i2c_get_clientdata(client);\r
-       unregister_early_suspend(&ts->early_suspend);\r
-#endif\r
+       if (ts)\r
+               tp_unregister_fb(&ts->tp);\r
+\r
 }\r
 \r
 //******************************Begin of firmware update surpport*******************************\r
@@ -1637,18 +1579,20 @@ static const struct i2c_device_id goodix_ts_id[] = {
        { }\r
 };\r
 \r
+static struct of_device_id goodix_ts_dt_ids[] = {\r
+       { .compatible = "goodix,gt8xx" },\r
+       { }\r
+};\r
+\r
 static struct i2c_driver rk_ts_driver = {\r
        .probe          = rk_ts_probe,\r
        .remove         = rk_ts_remove,\r
        .shutdown       = rk_ts_shutdown,\r
-#ifndef CONFIG_HAS_EARLYSUSPEND\r
-       .suspend        = rk_ts_suspend,\r
-       .resume         = rk_ts_resume,\r
-#endif\r
        .id_table       = goodix_ts_id,\r
        .driver = {\r
                .name   = "Goodix-TS",\r
                .owner = THIS_MODULE,\r
+               .of_match_table = of_match_ptr(goodix_ts_dt_ids),\r
        },\r
 };\r
 \r