ts: rk29_i2c_goodix: porting to 3.10
author黄涛 <huangtao@rock-chips.com>
Thu, 13 Feb 2014 10:11:01 +0000 (18:11 +0800)
committer黄涛 <huangtao@rock-chips.com>
Thu, 13 Feb 2014 10:11:01 +0000 (18:11 +0800)
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/rk29_i2c_goodix.c
drivers/input/touchscreen/rk29_i2c_goodix.h

index f9a5fd89bc022bd50c19c571441490056d0e9d83..9de854e141dc5172253a908a3ba044b5d416b527 100644 (file)
@@ -11,6 +11,14 @@ menuconfig INPUT_TOUCHSCREEN
 
 if INPUT_TOUCHSCREEN
 
+config TOUCHSCREEN_GT8XX
+       tristate "Goodix touch screen gt801X2 support for rockchip based platform"
+       help
+         Say Y here if you have a touchscreen interface using the
+         two goodix gt801  , and your board-specific initialization
+         code includes that in its table of IIC devices.
+         If unsure, say N.
+
 config TOUCHSCREEN_88PM860X
        tristate "Marvell 88PM860x touchscreen"
        depends on MFD_88PM860X
index 6bfbeab67c9ffc93489283cb88d8ea773e291719..a7f0e13f71859320d2305358fc60d6d01f935779 100644 (file)
@@ -6,6 +6,7 @@
 
 wm97xx-ts-y := wm97xx-core.o
 
+obj-$(CONFIG_TOUCHSCREEN_GT8XX)                += rk29_i2c_goodix.o
 obj-$(CONFIG_TOUCHSCREEN_88PM860X)     += 88pm860x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_AD7877)       += ad7877.o
 obj-$(CONFIG_TOUCHSCREEN_AD7879)       += ad7879.o
index 1919c66044975e441a7a009015b64dc73dedcbf6..ab3dced65309ff331efba5efb31987b30516ff6b 100755 (executable)
@@ -18,7 +18,9 @@
 #include <linux/time.h>\r
 #include <linux/delay.h>\r
 #include <linux/device.h>\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
 #include <linux/earlysuspend.h>\r
+#endif\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/string.h>\r
 #include <linux/completion.h>\r
 #include <asm/uaccess.h>\r
-#include <mach/board.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 +80,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 +122,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 +150,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 +176,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 +189,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 +199,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 +208,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,10 +217,19 @@ 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, retry %d\n", retry);\r
                        msleep(100);\r
@@ -397,150 +405,85 @@ 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
+       bool touch_down;\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
-\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
@@ -640,9 +583,9 @@ static int goodix_ts_power(struct rk_ts_data * ts, int on)
        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
+               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
@@ -652,7 +595,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
@@ -663,7 +606,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
@@ -684,7 +627,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
@@ -721,7 +671,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
@@ -754,34 +704,41 @@ 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
-       #ifdef CONFIG_MACH_RK_FAC\r
-               struct tp_platform_data *pdata;  \r
-       #else \r
-               struct goodix_platform_data *pdata ;\r
-       #endif\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
-#ifdef CONFIG_MACH_RK_FAC\r
-       ts->rst_pin = pdata->reset_pin;\r
-#else\r
-       ts->rst_pin = pdata->rest_pin;\r
-#endif\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
@@ -789,10 +746,27 @@ static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id
        ts->get_touch_info = goodix_get_touch_info;\r
        ts->input_parms_init = goodix_input_params_init;\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
@@ -801,27 +775,24 @@ 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
+\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
@@ -830,46 +801,24 @@ static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id
 #endif\r
        i2c_set_clientdata(client, ts);\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
-\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
        }\r
        printk("goodix_ts_init: probe successfully!\n");\r
        return 0;\r
 \r
        \r
-err_input_register_device_failed:\r
+err:\r
 #ifdef CONFIG_HAS_EARLYSUSPEND\r
        unregister_early_suspend(&ts->early_suspend);\r
 #endif\r
-       input_free_device(ts->input_dev);\r
        i2c_set_clientdata(client, NULL);       \r
-       kfree(ts);\r
-exit:\r
        return ret;\r
 }\r
 \r
@@ -886,22 +835,16 @@ return:
 *******************************************************/\r
 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
+       struct rk_ts_data *ts = i2c_get_clientdata(client);\r
        unregister_early_suspend(&ts->early_suspend);\r
 #endif\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
@@ -1648,6 +1591,11 @@ 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
@@ -1660,6 +1608,7 @@ static struct i2c_driver rk_ts_driver = {
        .driver = {\r
                .name   = "Goodix-TS",\r
                .owner = THIS_MODULE,\r
+               .of_match_table = of_match_ptr(goodix_ts_dt_ids),\r
        },\r
 };\r
 \r
index 338aaa961eb2fc391bdf74842401b4825e0b6dac..d04b6a6d6b7a32edc19fdf7a8515da09ea0d4fd7 100755 (executable)
@@ -18,7 +18,9 @@
 #ifndef        _LINUX_GOODIX_TOUCH_H
 #define                _LINUX_GOODIX_TOUCH_H
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
+#endif
 #include <linux/hrtimer.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
@@ -71,12 +73,12 @@ struct rk_ts_data{
        int irq_pin;
        int pwr_pin;
        int rst_pin;
+       int rst_val;
        int read_mode;                                  //read moudle mode,20110221 by andrew
-       struct hrtimer timer;
-       struct workqueue_struct *ts_wq;
-       struct delayed_work  ts_work;
        char phys[32];
+#ifdef CONFIG_HAS_EARLYSUSPEND
        struct early_suspend early_suspend;
+#endif
        int (*power)(struct rk_ts_data * ts, int on);
        int (*ts_init)(struct rk_ts_data*ts);
        int (*input_parms_init)(struct rk_ts_data *ts);
@@ -85,6 +87,7 @@ struct rk_ts_data{
        uint16_t abs_y_max;
        uint8_t max_touch_num;
        bool            pendown;
+       struct rk_touch_info *info_buf;
 };
 
 
@@ -101,7 +104,9 @@ struct goodix_ts_data {
        struct delayed_work  work;
        char phys[32];
        int retry;
+#ifdef CONFIG_HAS_EARLYSUSPEND
        struct early_suspend early_suspend;
+#endif
        int (*power)(struct goodix_ts_data * ts, int on);
        uint16_t abs_x_max;
        uint16_t abs_y_max;
@@ -111,7 +116,6 @@ struct goodix_ts_data {
 };
 
 static const char *rk_ts_name = "Goodix Capacitive TouchScreen";
-static struct workqueue_struct *goodix_wq;
 struct i2c_client * i2c_connect_client = NULL; 
 static struct proc_dir_entry *goodix_proc_entry;
 //static struct kobject *goodix_debug_kobj;
@@ -137,7 +141,7 @@ static struct proc_dir_entry *goodix_proc_entry;
 //*****************************End of Part II*********************************
 #if 1
 //*************************Firmware Update part*******************************
-#define CONFIG_TOUCHSCREEN_GOODIX_IAP
+//#define CONFIG_TOUCHSCREEN_GOODIX_IAP
 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
 #define UPDATE_NEW_PROTOCOL