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