rk29phonesdk:touch screen:add reconfiguration TP when configurate fail and delet...
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / gt818_ts.c
1 /* drivers/input/touchscreen/gt818_ts.c\r
2  *\r
3  * Copyright (C) 2011 Rockcip, Inc.\r
4  * \r
5  * This software is licensed under the terms of the GNU General Public\r
6  * License version 2, as published by the Free Software Foundation, and\r
7  * may be copied, distributed, and modified under those terms.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * Author: hhb@rock-chips.com\r
15  * Date: 2011.06.20\r
16  */\r
17 #include <linux/kernel.h>\r
18 #include <linux/module.h>\r
19 #include <linux/time.h>\r
20 #include <linux/delay.h>\r
21 #include <linux/device.h>\r
22 #include <linux/earlysuspend.h>\r
23 #include <linux/hrtimer.h>\r
24 #include <linux/i2c.h>\r
25 #include <linux/input.h>\r
26 #include <linux/interrupt.h>\r
27 #include <linux/io.h>\r
28 #include <linux/platform_device.h>\r
29 \r
30 #include <linux/gpio.h>\r
31 #include <mach/iomux.h>\r
32 \r
33 #include <linux/irq.h>\r
34 #include <linux/syscalls.h>\r
35 #include <linux/reboot.h>\r
36 #include <linux/proc_fs.h>\r
37 \r
38 #include <linux/vmalloc.h>\r
39 #include <linux/fs.h>\r
40 #include <linux/string.h>\r
41 #include <linux/completion.h>\r
42 #include <asm/uaccess.h>\r
43 \r
44 #include "gt818_ts.h"\r
45 \r
46 \r
47 \r
48 #if !defined(GT801_PLUS) && !defined(GT801_NUVOTON)\r
49 #error The code does not match this touchscreen.\r
50 #endif\r
51 \r
52 static struct workqueue_struct *goodix_wq;\r
53 \r
54 static const char *gt818_ts_name = "Goodix Capacitive TouchScreen";\r
55 \r
56 static struct point_queue finger_list;\r
57 \r
58 struct i2c_client * i2c_connect_client = NULL;\r
59 \r
60 //EXPORT_SYMBOL(i2c_connect_client);\r
61 \r
62 static struct proc_dir_entry *goodix_proc_entry;\r
63         \r
64 #ifdef CONFIG_HAS_EARLYSUSPEND\r
65 static void goodix_ts_early_suspend(struct early_suspend *h);\r
66 static void goodix_ts_late_resume(struct early_suspend *h);\r
67 #endif\r
68 \r
69 #ifdef HAVE_TOUCH_KEY\r
70         const uint16_t gt818_key_array[]={\r
71                                                                           KEY_MENU,\r
72                                                                           KEY_HOME,\r
73                                                                           KEY_BACK,\r
74                                                                           KEY_SEARCH\r
75                                                                          };\r
76         #define MAX_KEY_NUM      (sizeof(gt818_key_array)/sizeof(gt818_key_array[0]))\r
77 #endif\r
78 \r
79 \r
80 /*Function as i2c_master_send */\r
81 static int i2c_read_bytes(struct i2c_client *client, u8 *buf, int len)\r
82 {\r
83         struct i2c_msg msgs[2];\r
84         int ret = -1;\r
85 \r
86         msgs[0].addr = client->addr;\r
87         msgs[0].flags = client->flags;\r
88         msgs[0].len = 2;\r
89         msgs[0].buf = &buf[0];\r
90         msgs[0].scl_rate = GT818_I2C_SCL;\r
91         msgs[0].udelay = client->udelay;\r
92 \r
93         msgs[1].addr = client->addr;\r
94         msgs[1].flags = client->flags | I2C_M_RD;\r
95         msgs[1].len = len-2;\r
96         msgs[1].buf = &buf[2];\r
97         msgs[1].scl_rate = GT818_I2C_SCL;\r
98         msgs[1].udelay = client->udelay;\r
99 \r
100         ret = i2c_transfer(client->adapter, msgs, 2);\r
101         if(ret < 0)\r
102                 printk("%s:i2c_transfer fail =%d\n",__func__, ret);\r
103 \r
104         return ret;\r
105 }\r
106 \r
107 /*Function as i2c_master_send */\r
108 static int i2c_write_bytes(struct i2c_client *client,u8 *data,int len)\r
109 {\r
110         struct i2c_msg msg;\r
111         int ret = -1;\r
112 \r
113         msg.addr = client->addr;\r
114         msg.flags = client->flags;\r
115         msg.len = len;\r
116         msg.buf = data;\r
117         msg.scl_rate = GT818_I2C_SCL;\r
118         msg.udelay = client->udelay;\r
119 \r
120         ret = i2c_transfer(client->adapter, &msg, 1);\r
121         if(ret < 0)\r
122                 printk("%s:i2c_transfer fail =%d\n",__func__, ret);\r
123 \r
124         return ret;\r
125 }\r
126 \r
127 \r
128 static int i2c_pre_cmd(struct gt818_ts_data *ts)\r
129 {\r
130         int ret;\r
131         u8 pre_cmd_data[2] = {0};\r
132         pre_cmd_data[0] = 0x0f;\r
133         pre_cmd_data[1] = 0xff;\r
134         ret = i2c_write_bytes(ts->client,pre_cmd_data,2);\r
135         udelay(20);\r
136         return ret;\r
137 }\r
138 \r
139 \r
140 static int i2c_end_cmd(struct gt818_ts_data *ts)\r
141 {\r
142         int ret;\r
143         u8 end_cmd_data[2] = {0};\r
144         end_cmd_data[0] = 0x80;\r
145         end_cmd_data[1] = 0x00;\r
146         ret = i2c_write_bytes(ts->client,end_cmd_data,2);\r
147         udelay(20);\r
148         return ret;\r
149 }\r
150 \r
151 \r
152 \r
153 static int goodix_init_panel(struct gt818_ts_data *ts)\r
154 {\r
155         int ret = -1;\r
156         int i = 0;\r
157 #if 1\r
158         u8 config_info[] = {\r
159         0x06,0xA2,\r
160         0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,\r
161         0x10,0x12,0x00,0x00,0x10,0x00,0x20,0x00,\r
162         0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,\r
163         0xE0,0x00,0xD0,0x00,0xC0,0x00,0xB0,0x00,\r
164         0xA0,0x00,0x90,0x00,0x80,0x00,0x70,0x00,\r
165         0xF0,0x00,0x13,0x13,0x90,0x90,0x90,0x27,\r
166         0x27,0x27,0x0F,0x0E,0x0A,0x40,0x30,0x01,\r
167         0x03,0x00,MAX_FINGER_NUM,0x00,0x14,0xFA,0x1B,0x00,\r
168         0x00,0x66,0x5A,0x6A,0x5E,0x00,0x00,0x05,\r
169         0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
170         0x14,0x10,0xEF,0x03,0x00,0x00,0x00,0x00,\r
171         0x00,0x00,0x20,0x40,0x70,0x90,0x0F,0x40,\r
172         0x30,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,\r
173         0x00,0x01\r
174         };\r
175 #endif\r
176         u8 read_config_info[sizeof(config_info)] = {0};\r
177         read_config_info[0] = 0x06;\r
178         read_config_info[1] = 0xa2;\r
179 \r
180         ret = i2c_write_bytes(ts->client, config_info, (sizeof(config_info)/sizeof(config_info[0])));\r
181         if (ret < 0) {\r
182                 printk("config gt818 fail\n");\r
183                 return ret;\r
184         }\r
185 \r
186         ret = i2c_read_bytes(ts->client, read_config_info, (sizeof(config_info)/sizeof(config_info[0])));\r
187         if (ret < 0){\r
188                 printk("read gt818 config fail\n");\r
189                 return ret;\r
190         }\r
191 \r
192         for(i = 2; i < 106; i++){\r
193                 if(read_config_info[i] != config_info[i]){\r
194                         printk("write gt818 config error\n");\r
195                         ret = -1;\r
196                         return ret;\r
197                 }\r
198         }\r
199         msleep(10);\r
200         return 0;\r
201 \r
202 }\r
203 \r
204 static int  goodix_read_version(struct gt818_ts_data *ts)\r
205 {\r
206         int ret;\r
207         u8 version_data[5] = {0};       //store touchscreen version infomation\r
208         memset(version_data, 0, 5);\r
209         version_data[0] = 0x07;\r
210         version_data[1] = 0x17;\r
211         msleep(2);\r
212         ret = i2c_read_bytes(ts->client, version_data, 4);\r
213         if (ret < 0) \r
214                 return ret;\r
215         dev_info(&ts->client->dev," Guitar Version: %d.%d\n",version_data[3],version_data[2]);\r
216         return 0;\r
217         \r
218 }\r
219 \r
220 \r
221 \r
222 static void goodix_ts_work_func(struct work_struct *work)\r
223 {       \r
224         u8  touch_status[8*MAX_FINGER_NUM + 18] = {READ_TOUCH_ADDR_H, READ_TOUCH_ADDR_L, 0};\r
225         u8  *key_value = NULL;\r
226         u8  *point_data = NULL;\r
227         static u8 finger_last[MAX_FINGER_NUM + 1]={0};\r
228         u8  finger_current[MAX_FINGER_NUM + 1] = {0};\r
229         u8  coor_data[6*MAX_FINGER_NUM] = {0};\r
230         static u8  last_key = 0;\r
231 \r
232         u8  finger = 0;\r
233         u8  key = 0;\r
234         u8 retry = 0;\r
235         unsigned int  count = 0;\r
236         unsigned int position = 0;      \r
237         int temp = 0;\r
238         int x = 0, y = 0 , pressure;\r
239 \r
240         u16 *coor_point;\r
241 \r
242         int syn_flag = 0;\r
243 \r
244         struct gt818_ts_data *ts = container_of(work, struct gt818_ts_data, work);\r
245 \r
246         i2c_pre_cmd(ts);\r
247         i2c_read_bytes(ts->client, touch_status, sizeof(touch_status)/sizeof(touch_status[0]));\r
248         i2c_end_cmd(ts);\r
249 \r
250         //judge whether the data is ready\r
251         if((touch_status[2] & 0x30) != 0x20)\r
252         {\r
253                 printk("%s:DATA_NO_READY\n", __func__);\r
254                 goto DATA_NO_READY;\r
255         }\r
256         //judge whether it is large area touch\r
257         if(touch_status[13] & 0x0f)\r
258         {\r
259                 goto DATA_NO_READY;\r
260         }\r
261 \r
262         ts->bad_data = 0;\r
263         finger = touch_status[2] & 0x07;\r
264         key_value = touch_status + 15;\r
265         key = key_value[2] & 0x0f;\r
266 \r
267         if(finger > 0)\r
268         {\r
269                 point_data = key_value + 3;\r
270 \r
271                 for(position = 0; position < (finger*8); position += 8)\r
272                 {\r
273                         temp = point_data[position];\r
274                         //printk("track:%d\n", temp);\r
275                         if(temp < (MAX_FINGER_NUM + 1))\r
276                         {\r
277                                 finger_current[temp] = 1;\r
278                                 for(count = 0; count < 6; count++)\r
279                                 {\r
280                                         coor_data[(temp - 1) * 6 + count] = point_data[position+1+count];\r
281                                 }\r
282                         }\r
283                         else\r
284                         {\r
285                                 //dev_err(&(ts->client->dev),"Track Id error:%d\n ",);\r
286                                 ts->bad_data = 1;\r
287                                 ts->retry++;\r
288                                 goto XFER_ERROR;\r
289                         }               \r
290                 }\r
291         \r
292         }\r
293         \r
294         else\r
295         {\r
296                 for(position = 1; position < MAX_FINGER_NUM+1; position++)\r
297                 {\r
298                         finger_current[position] = 0;\r
299                 }\r
300         }\r
301 \r
302         coor_point = (u16 *)coor_data;\r
303 \r
304         for(position = 1; position < MAX_FINGER_NUM + 1; position++)\r
305         {\r
306                 //printk("%s:positon:%d\n", __func__, position);\r
307                 if((finger_current[position] == 0) && (finger_last[position] != 0))\r
308                 {\r
309                         input_report_abs(ts->input_dev, ABS_MT_POSITION_X, 0);\r
310                         input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, 0);\r
311                         input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
312                         input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);\r
313                         input_mt_sync(ts->input_dev);\r
314                         syn_flag = 1;\r
315                 }\r
316                 else if(finger_current[position])\r
317                 {\r
318 \r
319                         x = (*(coor_point+3*(position-1)))*SCREEN_MAX_WIDTH/(TOUCH_MAX_WIDTH);\r
320                         y = (*(coor_point+3*(position-1)+1))*SCREEN_MAX_HEIGHT/(TOUCH_MAX_HEIGHT);\r
321                         pressure = (*(coor_point+3*(position-1)+2));\r
322                         if(x < SCREEN_MAX_WIDTH){\r
323                                 x = SCREEN_MAX_WIDTH - x;\r
324                         }\r
325 \r
326                         if(y < SCREEN_MAX_HEIGHT){\r
327                         //      y = SCREEN_MAX_HEIGHT-y;\r
328                         }\r
329                         input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, position - 1);\r
330                         input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);\r
331                         input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);\r
332                         input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);\r
333                         input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure);\r
334                         input_mt_sync(ts->input_dev);\r
335                         syn_flag = 1;\r
336                 }\r
337         }\r
338 \r
339 \r
340 #ifdef HAVE_TOUCH_KEY\r
341         if((last_key == 0) && (key == 0)){\r
342                 goto NO_KEY_PRESS;\r
343         }\r
344         else{\r
345                 syn_flag = 1;\r
346                 switch(key){\r
347                         case 1:\r
348                                 key = 4;\r
349                                 break;\r
350                         case 2:\r
351                                 key = 3;\r
352                                 break;\r
353                         case 4:\r
354                                 key = 2;\r
355                                 break;\r
356                         case 8:\r
357                                 key = 1;\r
358                                 break;\r
359                         default:\r
360                                 key = 0;\r
361                                 break;\r
362                 }\r
363                 if(key != 0){\r
364                         input_report_key(ts->input_dev, gt818_key_array[key - 1], 1);\r
365                 }\r
366                 else{\r
367                         input_report_key(ts->input_dev, gt818_key_array[last_key - 1], 0);\r
368                 }\r
369                 last_key = key;\r
370         }               \r
371 \r
372 #endif\r
373 \r
374 \r
375 NO_KEY_PRESS:\r
376         if(syn_flag){\r
377                 input_sync(ts->input_dev);\r
378         }\r
379 \r
380         for(position = 1; position < MAX_FINGER_NUM + 1; position++)\r
381         {\r
382                 finger_last[position] = finger_current[position];\r
383         }\r
384 \r
385 DATA_NO_READY:\r
386 XFER_ERROR:\r
387 //      i2c_end_cmd(ts);\r
388         if(ts->use_irq)\r
389                 enable_irq(ts->client->irq);\r
390 \r
391 }\r
392 \r
393 static int test_suspend_resume(struct gt818_ts_data *ts){\r
394         while(1){\r
395                 ts->power(ts, 0);\r
396                 msleep(5000);\r
397                 ts->power(ts, 1);\r
398                 msleep(5000);\r
399         }\r
400         return 0;\r
401 }\r
402 \r
403 \r
404 static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer)\r
405 {\r
406         struct gt818_ts_data *ts = container_of(timer, struct gt818_ts_data, timer);\r
407         queue_work(goodix_wq, &ts->work);\r
408         hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL);\r
409         return HRTIMER_NORESTART;\r
410 }\r
411 \r
412 \r
413 static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)\r
414 {\r
415         struct gt818_ts_data *ts = dev_id;\r
416         disable_irq_nosync(ts->client->irq);\r
417         queue_work(goodix_wq, &ts->work);\r
418         return IRQ_HANDLED;\r
419 }\r
420 \r
421 static int goodix_ts_power(struct gt818_ts_data * ts, int on)\r
422 {\r
423         int ret = -1;\r
424         struct gt818_platform_data      *pdata = ts->client->dev.platform_data;\r
425         unsigned char i2c_control_buf[3] = {0x06,0x92,0x01};            //suspend cmd\r
426         if(ts != NULL && !ts->use_irq)\r
427                 return -2;\r
428         switch(on)\r
429         {\r
430                 case 0:\r
431                         i2c_pre_cmd(ts);\r
432                         // set the io port high level to avoid level change which might stop gt818 from sleeping\r
433                         gpio_direction_output(pdata->gpio_reset, 1);\r
434                         gpio_direction_output(pdata->gpio_pendown, 1);\r
435                         msleep(5);\r
436                         ret = i2c_write_bytes(ts->client, i2c_control_buf, 3);\r
437                         if(ret < 0)\r
438                         {\r
439                                 printk(KERN_INFO"**gt818 suspend fail**\n");\r
440                         }\r
441                         else\r
442                         {\r
443                                 //printk(KERN_INFO"**gt818 suspend**\n");\r
444                                 ret = 0;\r
445                         }\r
446 //                      i2c_end_cmd(ts);\r
447                         return ret;\r
448                         \r
449                 case 1:\r
450 \r
451                         gpio_pull_updown(pdata->gpio_pendown, 1);\r
452                         gpio_direction_output(pdata->gpio_pendown, 0);\r
453                         msleep(1);\r
454                         gpio_direction_output(pdata->gpio_pendown, 1);\r
455                         msleep(1);\r
456                         gpio_direction_input(pdata->gpio_pendown);\r
457                         gpio_pull_updown(pdata->gpio_pendown, 0);\r
458 \r
459 /*\r
460                         msleep(2);\r
461                         gpio_pull_updown(pdata->gpio_reset, 1);\r
462                         gpio_direction_output(pdata->gpio_reset, 0);\r
463                         msleep(2);\r
464                         gpio_direction_input(pdata->gpio_reset);\r
465                         gpio_pull_updown(pdata->gpio_reset, 0);\r
466                         msleep(30);\r
467 */\r
468                         msleep(1);\r
469                         ret = i2c_pre_cmd(ts);\r
470                         //printk(KERN_INFO"**gt818 reusme**\n");\r
471                         ret = i2c_end_cmd(ts);\r
472 \r
473                         return ret;\r
474                                 \r
475                 default:\r
476                         printk(KERN_DEBUG "%s: Cant't support this command.", gt818_ts_name);\r
477                         return -EINVAL;\r
478         }\r
479 \r
480 }\r
481 \r
482 \r
483 static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)\r
484 {\r
485         int ret = 0;\r
486         int retry=0;\r
487         u8 goodix_id[3] = {0,0xff,0};\r
488         struct gt818_ts_data *ts;\r
489 \r
490         struct gt818_platform_data *pdata;\r
491         dev_dbg(&client->dev,"Install touch driver.\n");\r
492         printk("gt818: Install touch driver.\n");\r
493         //Check I2C function\r
494         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) \r
495         {\r
496                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");\r
497                 ret = -ENODEV;\r
498                 goto err_check_functionality_failed;\r
499         }\r
500 \r
501         ts = kzalloc(sizeof(*ts), GFP_KERNEL);\r
502         if (ts == NULL) {\r
503                 ret = -ENOMEM;\r
504                 goto err_alloc_data_failed;\r
505         }\r
506 \r
507         i2c_connect_client = client;    //used by Guitar_Update\r
508         pdata = client->dev.platform_data;\r
509         ts->client = client;\r
510         i2c_set_clientdata(client, ts);\r
511 \r
512         //init int and reset ports\r
513         ret = gpio_request(pdata->gpio_pendown, "TS_INT");      //Request IO\r
514         if (ret){\r
515                 dev_err(&client->dev, "Failed to request GPIO:%d, ERRNO:%d\n",(int)pdata->gpio_pendown, ret);\r
516                 goto err_gpio_request_failed;\r
517         }\r
518         rk29_mux_api_set(pdata->pendown_iomux_name, pdata->pendown_iomux_mode);\r
519         gpio_direction_input(pdata->gpio_pendown);\r
520         gpio_pull_updown(pdata->gpio_pendown, 0);\r
521 \r
522         ret = gpio_request(pdata->gpio_reset, "gt818_resetPin");\r
523         if(ret){\r
524                 dev_err(&client->dev, "failed to request resetPin GPIO%d\n", pdata->gpio_reset);\r
525                 goto err_gpio_request_failed;\r
526         }\r
527         rk29_mux_api_set(pdata->resetpin_iomux_name, pdata->resetpin_iomux_mode);\r
528 \r
529 #if 1\r
530         for(retry = 0; retry < 4; retry++)\r
531         {\r
532                 gpio_pull_updown(pdata->gpio_reset, 1);\r
533                 gpio_direction_output(pdata->gpio_reset, 0);\r
534                 msleep(1);     //delay at least 1ms\r
535                 gpio_direction_input(pdata->gpio_reset);\r
536                 gpio_pull_updown(pdata->gpio_reset, 0);\r
537                 msleep(25);   //delay at least 20ms\r
538                 ret = i2c_pre_cmd(ts);\r
539                 if (ret > 0)\r
540                         break;\r
541                 msleep(50);\r
542         }\r
543 \r
544         if(ret <= 0)\r
545         {\r
546                 dev_err(&client->dev, "Warnning: I2C communication might be ERROR!\n");\r
547                 goto err_i2c_failed;\r
548         }       \r
549 #endif\r
550 \r
551         for(retry = 0; retry < 3; retry++)\r
552         {\r
553                 ret = goodix_init_panel(ts);\r
554 \r
555                 dev_info(&client->dev,"the config ret is :%d\n", ret);\r
556                 msleep(20);\r
557                 if(ret < 0)     //Initiall failed\r
558                         continue;\r
559                 else\r
560                         break;\r
561         }\r
562 \r
563         if(ret < 0) {\r
564                 ts->bad_data = 1;\r
565                 goto err_init_godix_ts;\r
566         }\r
567 \r
568         goodix_read_version(ts);\r
569 \r
570 \r
571         INIT_WORK(&ts->work, goodix_ts_work_func);              //init work_struct\r
572         ts->input_dev = input_allocate_device();\r
573         if (ts->input_dev == NULL) {\r
574                 ret = -ENOMEM;\r
575                 dev_dbg(&client->dev,"goodix_ts_probe: Failed to allocate input device\n");\r
576                 goto err_input_dev_alloc_failed;\r
577         }\r
578 \r
579         ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;\r
580         ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);\r
581         ts->input_dev->absbit[0] = BIT_MASK(ABS_MT_POSITION_X) | BIT_MASK(ABS_MT_POSITION_Y) |\r
582                         BIT_MASK(ABS_MT_TOUCH_MAJOR) | BIT_MASK(ABS_MT_WIDTH_MAJOR);  // for android\r
583 \r
584 \r
585 #ifdef HAVE_TOUCH_KEY\r
586         for(retry = 0; retry < MAX_KEY_NUM; retry++)\r
587         {\r
588                 input_set_capability(ts->input_dev, EV_KEY, gt818_key_array[retry]);\r
589         }\r
590 #endif\r
591 \r
592         snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev));\r
593         snprintf(ts->name, sizeof(ts->name), "gt818-touchscreen");\r
594 \r
595         ts->input_dev->name = "gt818_ts";//ts->name;\r
596         ts->input_dev->phys = ts->phys;\r
597         ts->input_dev->dev.parent = &client->dev;\r
598         ts->input_dev->id.bustype = BUS_I2C;\r
599         ts->input_dev->id.vendor = 0xDEAD;\r
600         ts->input_dev->id.product = 0xBEEF;\r
601         ts->input_dev->id.version = 10427;      //screen firmware version\r
602 \r
603 #ifdef GOODIX_MULTI_TOUCH\r
604 \r
605         input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);\r
606         input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);\r
607         input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_WIDTH, 0, 0);\r
608         input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_HEIGHT, 0, 0);\r
609         input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, MAX_FINGER_NUM, 0, 0);\r
610 #else\r
611         input_set_abs_params(ts->input_dev, ABS_X, 0, SCREEN_MAX_HEIGHT, 0, 0);\r
612         input_set_abs_params(ts->input_dev, ABS_Y, 0, SCREEN_MAX_WIDTH, 0, 0);\r
613         input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);\r
614 #endif  \r
615         \r
616         ret = input_register_device(ts->input_dev);\r
617         if (ret) {\r
618                 dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name);\r
619                 goto err_input_register_device_failed;\r
620         }\r
621         ts->bad_data = 0;\r
622 //      finger_list.length = 0;\r
623 \r
624         client->irq = gpio_to_irq(pdata->gpio_pendown);         //If not defined in client\r
625         if (client->irq)\r
626         {\r
627 \r
628         #if INT_TRIGGER==0\r
629                 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_EDGE_RISING\r
630         #elif INT_TRIGGER==1\r
631                 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_EDGE_FALLING\r
632         #elif INT_TRIGGER==2\r
633                 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_LEVEL_LOW\r
634         #elif INT_TRIGGER==3\r
635                 #define GT801_PLUS_IRQ_TYPE IRQ_TYPE_LEVEL_HIGH\r
636         #endif\r
637 \r
638                 ret = request_irq(client->irq, goodix_ts_irq_handler, GT801_PLUS_IRQ_TYPE,\r
639                         client->name, ts);\r
640                 if (ret != 0) {\r
641                         dev_err(&client->dev,"Cannot allocate ts INT!ERRNO:%d\n", ret);\r
642                         gpio_direction_input(pdata->gpio_pendown);\r
643                         gpio_free(pdata->gpio_pendown);\r
644                         goto err_gpio_request_failed;\r
645                 }\r
646                 else \r
647                 {       \r
648                         disable_irq(client->irq);\r
649                         ts->use_irq = 1;\r
650                         dev_dbg(&client->dev,"Reques EIRQ %d succesd on GPIO:%d\n", client->irq, pdata->gpio_pendown);\r
651                 }       \r
652         }\r
653 \r
654 err_gpio_request_failed:\r
655         ts->power = goodix_ts_power;\r
656 #ifdef CONFIG_HAS_EARLYSUSPEND\r
657         ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;\r
658         ts->early_suspend.suspend = goodix_ts_early_suspend;\r
659         ts->early_suspend.resume = goodix_ts_late_resume;\r
660         register_early_suspend(&ts->early_suspend);\r
661 #endif\r
662         dev_info(&client->dev,"Start %s in %s mode\n",\r
663                 ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");\r
664 \r
665         if (ts->use_irq)\r
666         {\r
667                 enable_irq(client->irq);\r
668         }\r
669         else\r
670         {\r
671                 hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);\r
672                 ts->timer.function = goodix_ts_timer_func;\r
673                 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);\r
674         }\r
675 \r
676         i2c_end_cmd(ts);\r
677         return 0;\r
678 \r
679 err_init_godix_ts:\r
680         i2c_end_cmd(ts);\r
681         if(ts->use_irq)\r
682         {\r
683                 ts->use_irq = 0;\r
684                 free_irq(client->irq,ts);\r
685                 gpio_direction_input(pdata->gpio_pendown);\r
686                 gpio_free(pdata->gpio_pendown);\r
687         }\r
688         else \r
689                 hrtimer_cancel(&ts->timer);\r
690 \r
691 err_input_register_device_failed:\r
692         input_free_device(ts->input_dev);\r
693 \r
694 err_input_dev_alloc_failed:\r
695         i2c_set_clientdata(client, NULL);\r
696 err_i2c_failed: \r
697         kfree(ts);\r
698 err_alloc_data_failed:\r
699 err_check_functionality_failed:\r
700 err_create_proc_entry:\r
701         return ret;\r
702 }\r
703 \r
704 \r
705 static int goodix_ts_remove(struct i2c_client *client)\r
706 {\r
707         struct gt818_ts_data *ts = i2c_get_clientdata(client);\r
708         struct gt818_platform_data      *pdata = client->dev.platform_data;\r
709 \r
710 #ifdef CONFIG_HAS_EARLYSUSPEND\r
711         unregister_early_suspend(&ts->early_suspend);\r
712 #endif\r
713 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
714         remove_proc_entry("goodix-update", NULL);\r
715 #endif\r
716         if (ts && ts->use_irq) \r
717         {\r
718                 gpio_direction_input(pdata->gpio_pendown);\r
719                 gpio_free(pdata->gpio_pendown);\r
720                 free_irq(client->irq, ts);\r
721         }       \r
722         else if(ts)\r
723                 hrtimer_cancel(&ts->timer);\r
724         \r
725         dev_notice(&client->dev,"The driver is removing...\n");\r
726         i2c_set_clientdata(client, NULL);\r
727         input_unregister_device(ts->input_dev);\r
728         kfree(ts);\r
729         return 0;\r
730 }\r
731 \r
732 \r
733 static int goodix_ts_suspend(struct i2c_client *client, pm_message_t mesg)\r
734 {\r
735         int ret;\r
736         struct gt818_ts_data *ts = i2c_get_clientdata(client);\r
737 \r
738         if (ts->use_irq)\r
739                 disable_irq(client->irq);\r
740         else\r
741                 hrtimer_cancel(&ts->timer);\r
742         //ret = cancel_work_sync(&ts->work);\r
743         //if(ret && ts->use_irq)        \r
744                 //enable_irq(client->irq);\r
745         if (ts->power) {\r
746                 ret = ts->power(ts, 0);\r
747                 if (ret < 0)\r
748                         printk(KERN_ERR "goodix_ts_resume power off failed\n");\r
749         }\r
750         return 0;\r
751 }\r
752 \r
753 \r
754 static int goodix_ts_resume(struct i2c_client *client)\r
755 {\r
756         int ret;\r
757         struct gt818_ts_data *ts = i2c_get_clientdata(client);\r
758 \r
759         if (ts->power) {\r
760                 ret = ts->power(ts, 1);\r
761                 if (ret < 0)\r
762                         printk(KERN_ERR "goodix_ts_resume power on failed\n");\r
763         }\r
764 \r
765         if (ts->use_irq)\r
766                 enable_irq(client->irq);\r
767         else\r
768                 hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);\r
769 \r
770         return 0;\r
771 }\r
772 \r
773 #ifdef CONFIG_HAS_EARLYSUSPEND\r
774 static void goodix_ts_early_suspend(struct early_suspend *h)\r
775 {\r
776         struct gt818_ts_data *ts;\r
777         ts = container_of(h, struct gt818_ts_data, early_suspend);\r
778         goodix_ts_suspend(ts->client, PMSG_SUSPEND);\r
779 }\r
780 \r
781 static void goodix_ts_late_resume(struct early_suspend *h)\r
782 {\r
783         struct gt818_ts_data *ts;\r
784         ts = container_of(h, struct gt818_ts_data, early_suspend);\r
785         goodix_ts_resume(ts->client);\r
786 }\r
787 #endif\r
788 \r
789 \r
790 //only one client\r
791 static const struct i2c_device_id goodix_ts_id[] = {\r
792         { GOODIX_I2C_NAME, 0 },\r
793         { }\r
794 };\r
795 \r
796 \r
797 static struct i2c_driver goodix_ts_driver = {\r
798         .probe          = goodix_ts_probe,\r
799         .remove         = goodix_ts_remove,\r
800 #ifndef CONFIG_HAS_EARLYSUSPEND\r
801         .suspend        = goodix_ts_suspend,\r
802         .resume         = goodix_ts_resume,\r
803 #endif\r
804         .id_table       = goodix_ts_id,\r
805         .driver = {\r
806                 .name   = GOODIX_I2C_NAME,\r
807                 .owner = THIS_MODULE,\r
808         },\r
809 };\r
810 \r
811 \r
812 static int __devinit goodix_ts_init(void)\r
813 {\r
814         int ret;\r
815         goodix_wq = create_singlethread_workqueue("goodix_wq");         //create a work queue and worker thread\r
816         if (!goodix_wq) {\r
817                 printk(KERN_ALERT "creat workqueue faiked\n");\r
818                 return -ENOMEM;\r
819         }\r
820         ret = i2c_add_driver(&goodix_ts_driver);\r
821         return ret; \r
822 }\r
823 \r
824 \r
825 static void __exit goodix_ts_exit(void)\r
826 {\r
827         printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");\r
828         i2c_del_driver(&goodix_ts_driver);\r
829         if (goodix_wq)\r
830                 destroy_workqueue(goodix_wq);           //release our work queue\r
831 }\r
832 \r
833 late_initcall(goodix_ts_init);\r
834 module_exit(goodix_ts_exit);\r
835 \r
836 MODULE_DESCRIPTION("Goodix Touchscreen Driver");\r
837 MODULE_AUTHOR("hhb@rock-chips.com")\r
838 MODULE_LICENSE("GPL");\r
839 \r