#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
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
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
#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
{\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
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
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
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
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
\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
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
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
__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
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
}\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
{\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
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
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
#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
*******************************************************/\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
{ }\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
.driver = {\r
.name = "Goodix-TS",\r
.owner = THIS_MODULE,\r
+ .of_match_table = of_match_ptr(goodix_ts_dt_ids),\r
},\r
};\r
\r