Merge tag 'v4.4-rc6'
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / gt8110_ts.c
1 /* drivers/input/touchscreen/goodix_touch.c\r
2  *\r
3  * Copyright (C) 2010 - 2011 Goodix, Inc.\r
4  * \r
5  * This program is free software; you can redistribute it and/or modify\r
6  * it under the terms of the GNU General Public License as published by\r
7  * the Free Software Foundation; either version 2 of the License, or\r
8  * (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but WITHOUT\r
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
13  * more details.\r
14  *\r
15  */\r
16 #include <linux/kernel.h>\r
17 #include <linux/module.h>\r
18 #include <linux/time.h>\r
19 #include <linux/delay.h>\r
20 #include <linux/device.h>\r
21 #include <linux/earlysuspend.h>\r
22 #include <linux/hrtimer.h>\r
23 #include <linux/i2c.h>\r
24 #include <linux/input.h>\r
25 #include <linux/input/mt.h>\r
26 \r
27 #include <linux/interrupt.h>\r
28 #include <linux/io.h>\r
29 #include <linux/platform_device.h>\r
30 #include <mach/gpio.h>\r
31 \r
32 #include <linux/irq.h>\r
33 #include <linux/syscalls.h>\r
34 #include <linux/reboot.h>\r
35 #include <linux/proc_fs.h>\r
36 #include <linux/async.h>\r
37 #include <linux/gt8110.h>
38 \r
39 #include <linux/vmalloc.h>\r
40 #include <linux/fs.h>\r
41 #include <linux/string.h>\r
42 #include <linux/completion.h>\r
43 #include <asm/uaccess.h>\r
44 #include <mach/board.h>\r
45 \r
46 #define PEN_DOWN 1\r
47 #define PEN_RELEASE 0\r
48 #define PEN_DOWN_UP 2\r
49
50
51 #define GOODIX_I2C_NAME "Goodix-TS"
52
53 #define POLL_TIME               10      //actual query spacing interval:POLL_TIME+6
54
55 #define MAX_FINGER_NUM   10
56
57 struct rk_touch_info
58 {
59         u32 press;
60         u32 x ;
61         u32 y ;
62         int status ; // 0 1
63 } ;\r
64
65 struct rk_ts_data{
66         struct i2c_client *client;
67         struct input_dev *input_dev;
68         int irq;
69         int irq_pin;
70         int pwr_pin;
71         int rst_pin;
72         int read_mode;
73         struct hrtimer timer;
74         struct workqueue_struct *ts_wq;
75         struct delayed_work  ts_work;
76         char phys[32];
77         struct early_suspend early_suspend;
78         int (*power)(struct rk_ts_data * ts, int on);
79         int (*ts_init)(struct rk_ts_data*ts);
80         int (*input_parms_init)(struct rk_ts_data *ts);
81         void (*get_touch_info)(struct rk_ts_data *ts,char *point_num,struct rk_touch_info *info_buf);  //get touch data info
82         uint16_t abs_x_max;
83         uint16_t abs_y_max;
84         uint8_t max_touch_num;
85         bool            pendown;
86 };
87
88 struct goodix_ts_data {
89         uint16_t addr;
90         uint8_t bad_data;
91         struct i2c_client *client;
92         struct input_dev *input_dev;
93         int use_reset;
94         int use_irq;
95         int read_mode;
96         struct hrtimer timer;
97         struct delayed_work  work;
98         char phys[32];
99         int retry;
100         struct early_suspend early_suspend;
101         int (*power)(struct goodix_ts_data * ts, int on);
102         uint16_t abs_x_max;
103         uint16_t abs_y_max;
104         uint8_t max_touch_num;
105         uint8_t int_trigger_type;
106         bool            pendown;
107 };
108
109 static const char *rk_ts_name = "Goodix Capacitive TouchScreen";
110 static struct workqueue_struct *goodix_wq;
111 static struct i2c_client * i2c_connect_client = NULL;
112 static struct proc_dir_entry *goodix_proc_entry;
113
114
115 #define READ_COOR_ADDR 0x01
116
117
118
119 //*************************Firmware Update part*******************************
120 #define CONFIG_TOUCHSCREEN_GOODIX_IAP
121 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
122 #define UPDATE_NEW_PROTOCOL
123
124 static unsigned int oldcrc32 = 0xFFFFFFFF;
125 static unsigned int crc32_table[256];
126 static unsigned int ulPolynomial = 0x04c11db7;
127 static unsigned char rd_cfg_addr;
128 static unsigned char rd_cfg_len;
129 static unsigned char g_enter_isp = 0;
130
131 static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data);
132 static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data );
133
134 #define PACK_SIZE                                       64                                      //update file package size
135 #define MAX_TIMEOUT                                     60000                           //update time out conut
136 #define MAX_I2C_RETRIES                         20                                      //i2c retry times
137
138 //I2C buf address
139 #define ADDR_CMD                                        80
140 #define ADDR_STA                                        81
141 #ifdef UPDATE_NEW_PROTOCOL
142         #define ADDR_DAT                                0
143 #else
144         #define ADDR_DAT                                82
145 #endif
146
147 //moudle state
148 #define NEW_UPDATE_START                        0x01
149 #define UPDATE_START                            0x02
150 #define SLAVE_READY                                     0x08
151 #define UNKNOWN_ERROR                           0x00
152 #define FRAME_ERROR                                     0x10
153 #define CHECKSUM_ERROR                          0x20
154 #define TRANSLATE_ERROR                         0x40
155 #define FLASH_ERROR                                     0X80
156
157 //error no
158 #define ERROR_NO_FILE                           2       //ENOENT
159 #define ERROR_FILE_READ                         23      //ENFILE
160 #define ERROR_FILE_TYPE                         21      //EISDIR
161 #define ERROR_GPIO_REQUEST                      4       //EINTR
162 #define ERROR_I2C_TRANSFER                      5       //EIO
163 #define ERROR_NO_RESPONSE                       16      //EBUSY
164 #define ERROR_TIMEOUT                           110     //ETIMEDOUT
165
166 //update steps
167 #define STEP_SET_PATH              1
168 #define STEP_CHECK_FILE            2
169 #define STEP_WRITE_SYN             3
170 #define STEP_WAIT_SYN              4
171 #define STEP_WRITE_LENGTH          5
172 #define STEP_WAIT_READY            6
173 #define STEP_WRITE_DATA            7
174 #define STEP_READ_STATUS           8
175 #define FUN_CLR_VAL                9
176 #define FUN_CMD                    10
177 #define FUN_WRITE_CONFIG           11
178
179 //fun cmd
180 #define CMD_DISABLE_TP             0
181 #define CMD_ENABLE_TP              1
182 #define CMD_READ_VER               2
183 #define CMD_READ_RAW               3
184 #define CMD_READ_DIF               4
185 #define CMD_READ_CFG               5
186 #define CMD_SYS_REBOOT             101
187
188 //read mode
189 #define MODE_RD_VER                1
190 #define MODE_RD_RAW                2
191 #define MODE_RD_DIF                3
192 #define MODE_RD_CFG                4
193 #endif
194 \r
195 static struct rk_touch_info *info_buf;\r
196 \r
197 static int dbg_thresd = 0;\r
198 #define DBG(x...) do { if(unlikely(dbg_thresd)) printk(KERN_INFO x); } while (0)\r
199 \r
200 \r
201 /*******************************************************        \r
202 Description:\r
203         Read data from the i2c slave device;\r
204         This operation consisted of 2 i2c_msgs,the first msg used\r
205         to write the operate address,the second msg used to read data.\r
206 \r
207 Parameter:\r
208         client: i2c device.\r
209         buf[0]:operate address.\r
210         buf[1]~buf[len]:read data buffer.\r
211         len:operate length.\r
212         \r
213 return:\r
214         numbers of i2c_msgs to transfer\r
215 *********************************************************/\r
216 static int goodix_i2c_read_bytes(struct i2c_client *client, uint8_t *buf, int len)\r
217 {\r
218         struct i2c_msg msgs[2];\r
219         int ret=-1;\r
220         int retries = 0;\r
221 \r
222         msgs[0].flags = client->flags;\r
223         msgs[0].addr=client->addr;\r
224         msgs[0].len=1;\r
225         msgs[0].buf=&buf[0];\r
226         msgs[0].udelay = client->udelay;\r
227         msgs[0].scl_rate=200 * 1000;\r
228 \r
229         msgs[1].flags = client->flags | I2C_M_RD;\r
230         msgs[1].addr=client->addr;\r
231         msgs[1].len=len-1;\r
232         msgs[1].buf=&buf[1];\r
233         msgs[1].udelay = client->udelay;\r
234         msgs[0].scl_rate=200 * 1000;\r
235 \r
236         while(retries<5)\r
237         {\r
238                 ret=i2c_transfer(client->adapter,msgs, 2);\r
239                 if(ret == 2)break;\r
240                 retries++;\r
241         }\r
242         return ret;\r
243 }\r
244 \r
245 /*******************************************************        \r
246 Description:\r
247         write data to the i2c slave device.\r
248 \r
249 Parameter:\r
250         client: i2c device.\r
251         buf[0]:operate address.\r
252         buf[1]~buf[len]:write data buffer.\r
253         len:operate length.\r
254         \r
255 return:\r
256         numbers of i2c_msgs to transfer.\r
257 *********************************************************/\r
258 static int goodix_i2c_write_bytes(struct i2c_client *client,uint8_t *data,int len)\r
259 {\r
260         struct i2c_msg msg;\r
261         int ret=-1;\r
262         int retries = 0;\r
263 \r
264         msg.flags=!I2C_M_RD;\r
265         msg.addr=client->addr;\r
266         msg.len=len;\r
267         msg.buf=data;           \r
268         msg.udelay = client->udelay;\r
269         msg.scl_rate=200 * 1000;\r
270         \r
271         while(retries<5)\r
272         {\r
273                 ret=i2c_transfer(client->adapter,&msg, 1);\r
274                 if(ret == 1)break;\r
275                 retries++;\r
276         }\r
277         return ret;\r
278 }\r
279 \r
280 static int goodix_config_ok(struct rk_ts_data *ts)\r
281 {\r
282         int ret = 0;\r
283         unsigned int w,h, n;\r
284         uint8_t rd_cfg_buf[7] = {0x66,};\r
285         \r
286         ret = goodix_i2c_read_bytes(ts->client, rd_cfg_buf, 7);\r
287 \r
288         w = (rd_cfg_buf[2]<<8) + rd_cfg_buf[1];\r
289         h = (rd_cfg_buf[4]<<8) + rd_cfg_buf[3];\r
290         n = rd_cfg_buf[5];\r
291 \r
292 \r
293         ts->abs_x_max = w;\r
294         ts->abs_y_max = h;\r
295         ts->max_touch_num = n;\r
296         \r
297         printk("goodix_ts_init: X_MAX = %d,Y_MAX = %d,MAX_TOUCH_NUM = %d\n",ts->abs_x_max,ts->abs_y_max,ts->max_touch_num);\r
298 \r
299         return 0;\r
300 }\r
301 /*******************************************************\r
302 Description:\r
303         Goodix touchscreen initialize function.\r
304 \r
305 Parameter:\r
306         ts:     i2c client private struct.\r
307         \r
308 return:\r
309         Executive outcomes.0---succeed.\r
310 *******************************************************/\r
311 static int goodix_init_panel(struct rk_ts_data *ts)\r
312 {\r
313         int ret=-1, retry = 10;\r
314         uint8_t rd_cfg_buf[7] = {0x66,};\r
315         char test_data = 0;\r
316 \r
317         uint8_t config_info[] = {\r
318         0x65,0x02,0x00,0x10,0x00,0x10,0x0A,0x62,0x4A,0x00,
319         0x0F,0x28,0x02,0x10,0x10,0x00,0x00,0x20,0x00,0x00,
320         0x10,0x10,0x10,0x00,0x37,0x00,0x00,0x00,0x01,0x02,
321         0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,
322         0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
323         0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,
324         0x00,0x3C,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
325         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
326         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
327         0x00,0x00,0x00,0x00,0x00\r
328         };\r
329 \r
330         ret=goodix_i2c_write_bytes(ts->client,config_info,95);
331         if( ret == 1)
332         {
333                 printk("GT8110 send config para successfully!\n");
334         }
335         else
336         {
337                 printk("GT8110 send config para failed!\n");
338         }       \r
339         ts->abs_x_max = 4096;\r
340         ts->abs_y_max = 4096;\r
341         ts->max_touch_num = 10;\r
342         \r
343         return 0;\r
344 \r
345 }\r
346 \r
347 //fjp add ===============================\r
348 static bool goodix_get_status(char *p1,int*p2)\r
349 {\r
350         bool status = PEN_DOWN;\r
351         if((*p2==PEN_DOWN) && (*p1==PEN_RELEASE))\r
352                 {\r
353                         *p2 = PEN_DOWN_UP; //¸Õ¸Õµ¯Æð\r
354                          status = PEN_RELEASE; \r
355                 }\r
356         else if((*p2==PEN_RELEASE) && (*p1==PEN_RELEASE))\r
357                 {\r
358                    *p2 = PEN_RELEASE;\r
359                         status = PEN_RELEASE; \r
360                 }\r
361         else\r
362                 {\r
363                         *p2 = PEN_DOWN;\r
364                 }\r
365         return status;\r
366 }\r
367 \r
368 //===================================\r
369 /*******************************************************\r
370 Description:\r
371         Read goodix touchscreen version function.\r
372 \r
373 Parameter:\r
374         ts:     i2c client private struct.\r
375         \r
376 return:\r
377         Executive outcomes.0---succeed.\r
378 *******************************************************/\r
379 static int  goodix_read_version(struct rk_ts_data *ts, char **version)\r
380 {\r
381         int ret = -1, count = 0;\r
382         char *version_data;\r
383         char *p;\r
384 \r
385         *version = (char *)vmalloc(18);\r
386         version_data = *version;\r
387         if(!version_data)\r
388                 return -ENOMEM;\r
389         p = version_data;\r
390         memset(version_data, 0, 18);\r
391         version_data[0]=240;    \r
392         ret=goodix_i2c_read_bytes(ts->client,version_data, 17);\r
393         if (ret < 0) \r
394                 return ret;\r
395         version_data[17]='\0';\r
396         \r
397         if(*p == '\0')\r
398                 return 0;       \r
399         do                                      \r
400         {\r
401                 if((*p > 122) || (*p < 48 && *p != 32) || (*p >57 && *p  < 65) \r
402                         ||(*p > 90 && *p < 97 && *p  != '_'))           //check illeqal character\r
403                         count++;\r
404         }while(*++p != '\0' );\r
405         if(count > 2)\r
406                 return 0;\r
407         else \r
408                 return 1;       \r
409 }\r
410 \r
411 static int last_touch_num = -1;\r
412 static void goodix_get_touch_info(struct rk_ts_data *ts,char *point_num,struct rk_touch_info* info_buf)\r
413 {\r
414         uint8_t  point_data[(1-READ_COOR_ADDR)+1+2+5*MAX_FINGER_NUM+1]={ 0 };  //read address(1byte)+key index(1byte)+point mask(2bytes)+5bytes*MAX_FINGER_NUM+coor checksum(1byte)\r
415         uint8_t  check_sum = 0;\r
416         int ret ;\r
417         uint16_t  finger_current = 0;\r
418         uint16_t  finger_bit = 0;\r
419         unsigned int  count = 0, point_count = 0;\r
420         unsigned char touch_num = 0;\r
421         uint8_t chksum_err = 0;\r
422         unsigned int position = 0;      \r
423         uint8_t track_id[MAX_FINGER_NUM] = {0};\r
424         u8 index;\r
425         u8 temp =0;\r
426         point_data[0] =  0;//READ_COOR_ADDR;//0x65;//READ_COOR_ADDR;            //read coor address\r
427         \r
428         if(!ts||!info_buf)\r
429         {\r
430                 printk("goodix ts or info_buf is null\n");\r
431                 return;\r
432         }\r
433 \r
434         ret=goodix_i2c_read_bytes(ts->client, point_data, sizeof(point_data)/sizeof(point_data[0]));\r
435         if(ret != 2)    \r
436         {\r
437             printk("goodix read error\n");\r
438         }       \r
439         finger_current =  (point_data[2]<<8) + point_data[1];\r
440         \r
441         DBG("finger_current:%d ==== max_touch_num:%d\n", finger_current,ts->max_touch_num);//add by fjp 2010-9-28\r
442         \r
443         /*printk(" GT8110 read point data info\n");\r
444         for(index = 0 ; index < 20 ; index++)\r
445         {\r
446                 printk("  %x ",point_data[index]);\r
447         }*/\r
448         \r
449         if(finger_current)\r
450         {       \r
451                 point_count = 0;\r
452                 finger_bit = finger_current;\r
453                 for(count = 0; (finger_bit != 0) && (count < ts->max_touch_num); count++)//cal how many point touch currntly\r
454                 {\r
455                         if(finger_bit & 0x01)\r
456                         {\r
457                                 track_id[count] = PEN_DOWN;\r
458                                 point_count++;\r
459                         }\r
460                         finger_bit >>= 1;\r
461                 }\r
462                 touch_num = point_count;\r
463 \r
464                 check_sum = point_data[2 - READ_COOR_ADDR] + point_data[3 - READ_COOR_ADDR];                    //cal coor checksum\r
465                 count = 4 - READ_COOR_ADDR;\r
466                 for(point_count *= 5; point_count > 0; point_count--)\r
467                         check_sum += point_data[count++];\r
468                 check_sum += point_data[count];\r
469                 //if(check_sum  != 0)                   //checksum verify error\r
470                 if(0)\r
471                 {\r
472                         printk("coor checksum error!\n");\r
473                 }\r
474                 else\r
475                 {\r
476                         chksum_err = 0;\r
477                 }\r
478         }\r
479 \r
480         //printk("current point num:%d\n",touch_num);\r
481         *point_num = touch_num;\r
482         if(touch_num < last_touch_num)  //some flinger release\r
483         {\r
484                 //printk("%d flinger release\n",last_touch_num-touch_num);\r
485                 /*for(index = touch_num; index < last_touch_num; index++)\r
486                         info_buf[index].status = 0;*/\r
487                 *point_num = last_touch_num;\r
488                  touch_num = last_touch_num;\r
489         }\r
490         last_touch_num = touch_num;\r
491         //printk(" X and Y point value is\n");  \r
492         for(index = 0; index < touch_num; index++)\r
493         {\r
494              if(goodix_get_status(&track_id[index],&info_buf[index].status))\r
495                 {\r
496                 position = 3 + 4*(temp++);\r
497                 info_buf[index].x = (unsigned int) (point_data[position+1]<<8) + (unsigned int)( point_data[position]);\r
498                 info_buf[index].y  = (unsigned int)(point_data[position+3]<<8) + (unsigned int) (point_data[position+2]);\r
499                 info_buf[index].press = (unsigned int) (point_data[position+4]);\r
500                 //printk(" x = %d , y = %d , p =  %d ",         info_buf[index].x,info_buf[index].y, info_buf[index].press);\r
501                 }\r
502         }\r
503         \r
504 }\r
505 \r
506 \r
507 /*******************************************************\r
508 Description:\r
509         Goodix touchscreen work function.\r
510 \r
511 Parameter:\r
512         ts:     i2c client private struct.\r
513         \r
514 return:\r
515         Executive outcomes.0---succeed.\r
516 *******************************************************/\r
517 static void  rk_ts_work_func(struct work_struct *pwork)\r
518 {       \r
519         int i =0;\r
520         char point_num;\r
521         struct rk_ts_data *ts = container_of(to_delayed_work(pwork), struct rk_ts_data, ts_work);\r
522 \r
523         if(!ts)\r
524         {\r
525                 printk("container of rk_ts_data fail\n");\r
526                 return;\r
527         }\r
528         if(!info_buf)\r
529         {\r
530                 printk("info_buf fail\n");\r
531                 return;\r
532         }\r
533 \r
534         if(ts->get_touch_info)\r
535         {\r
536                  ts->get_touch_info(ts,&point_num,info_buf);\r
537         }\r
538         for(i=0; i< point_num; i++)\r
539         {\r
540            DBG("info_buf[i].status =====%d\n",info_buf[i].status);\r
541               if(info_buf[i].status==PEN_DOWN_UP)\r
542                 {\r
543                        info_buf[i].status=PEN_RELEASE;\r
544                            DBG("the key %d is up------\n",i);\r
545                         input_mt_slot(ts->input_dev, i);\r
546                         input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);\r
547                         continue;\r
548                 }\r
549                 if(info_buf[i].status==PEN_DOWN)\r
550                 {\r
551                         input_mt_slot(ts->input_dev, i);\r
552                         input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
553                         input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, info_buf[i].press);\r
554                         input_report_abs(ts->input_dev, ABS_MT_POSITION_X, info_buf[i].x);\r
555                         input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, info_buf[i].y);\r
556                         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
557                 }\r
558                 \r
559        \r
560           \r
561                 \r
562                 \r
563         }\r
564         input_sync(ts->input_dev);\r
565         \r
566     if(gpio_get_value(ts->irq_pin) == GPIO_LOW)\r
567     //if(point_num)\r
568     {\r
569        \r
570         DBG("touch down .............\n");//add by fjp 2010-9-28\r
571         queue_delayed_work(ts->ts_wq, &ts->ts_work,msecs_to_jiffies(20));\r
572         //      goto exit;\r
573                 \r
574     }\r
575     else\r
576     {\r
577                 \r
578         DBG("touch up>>x:%d>>y:%d\n",info_buf[0].x,info_buf[0].y);//add by fjp 2010-9-28\r
579                 /*input_mt_slot(ts->input_dev, 0);\r
580                 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);\r
581                 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
582                 \r
583                 input_mt_slot(ts->input_dev, 0);\r
584                 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);*/\r
585 \r
586                 DBG("point_num+++++++++++ = %d\n", point_num);//add by fjp 2010-9-28\r
587                 for(i=0; i< point_num; i++)\r
588                 {\r
589         //        printk("info_buf[i].status +++++++%d\n",info_buf[i].status);\r
590                          if(info_buf[i].status)\r
591                         {\r
592                       input_mt_slot(ts->input_dev, i);//°´ÐòºÅÉϱ¨\r
593                         input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);               \r
594                         //input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
595                         info_buf[i].status= PEN_RELEASE;\r
596                         \r
597 \r
598                         DBG("release+++++++++++ = %d\n", i);//add by fjp 2010-9-28\r
599 \r
600                         }\r
601                 }\r
602                 input_sync(ts->input_dev);\r
603                 ts->pendown =PEN_RELEASE;\r
604                 last_touch_num = 0;\r
605                 \r
606         enable_irq(ts->irq);            \r
607       }\r
608          \r
609       \r
610 //exit:\r
611           //kfree(info_buf);\r
612           \r
613   }\r
614         \r
615         \r
616 /*******************************************************\r
617 Description:\r
618         Timer interrupt service routine.\r
619 \r
620 Parameter:\r
621         timer:  timer struct pointer.\r
622         \r
623 return:\r
624         Timer work mode. HRTIMER_NORESTART---not restart mode\r
625 *******************************************************/\r
626 static enum hrtimer_restart goodix_ts_timer_func(struct hrtimer *timer)\r
627 {\r
628         struct rk_ts_data *ts = container_of(timer, struct rk_ts_data, timer);\r
629         queue_delayed_work(goodix_wq,&ts->ts_work,0);\r
630         hrtimer_start(&ts->timer, ktime_set(0, (POLL_TIME+6)*1000000), HRTIMER_MODE_REL);\r
631         return HRTIMER_NORESTART;\r
632 }\r
633 /*******************************************************\r
634 Description:\r
635         External interrupt service routine.\r
636 \r
637 Parameter:\r
638         irq:    interrupt number.\r
639         dev_id: private data pointer.\r
640         \r
641 return:\r
642         irq execute status.\r
643 *******************************************************/\r
644 static irqreturn_t rk_ts_irq_handler(int irq, void *dev_id)\r
645 {\r
646 \r
647         struct rk_ts_data *ts = (struct rk_ts_data*)dev_id;\r
648         disable_irq_nosync(ts->irq);\r
649         queue_delayed_work(ts->ts_wq, &ts->ts_work,0);\r
650         \r
651         return IRQ_HANDLED;\r
652 }\r
653 \r
654 static int rk_ts_suspend(struct i2c_client *client, pm_message_t mesg)\r
655 {\r
656         int ret;\r
657         struct rk_ts_data *ts = i2c_get_clientdata(client);\r
658 \r
659        \r
660         \r
661         disable_irq(ts->irq);\r
662         \r
663 #if 1\r
664         if (ts->power) {\r
665                 ret = ts->power(ts, 0);\r
666                 if (ret < 0)\r
667                         printk(KERN_ERR "goodix_ts_resume power off failed\n");\r
668         }\r
669 #endif\r
670         return 0;\r
671 }\r
672 \r
673 static int rk_ts_resume(struct i2c_client *client)\r
674 {\r
675         int ret;\r
676         struct rk_ts_data *ts = i2c_get_clientdata(client);\r
677         \r
678 #if 1\r
679         if (ts->power) {\r
680                 ret = ts->power(ts, 1);\r
681                 if (ret < 0)\r
682                         printk(KERN_ERR "goodix_ts_resume power on failed\n");\r
683         }\r
684 #endif\r
685         \r
686         enable_irq(client->irq);\r
687 \r
688         return 0;\r
689 }\r
690 \r
691 \r
692 \r
693 #ifdef CONFIG_HAS_EARLYSUSPEND\r
694 static void rk_ts_early_suspend(struct early_suspend *h)\r
695 {\r
696         struct rk_ts_data *ts;\r
697         ts = container_of(h, struct rk_ts_data, early_suspend);\r
698         rk_ts_suspend(ts->client, PMSG_SUSPEND);\r
699 }\r
700 \r
701 static void rk_ts_late_resume(struct early_suspend *h)\r
702 {\r
703         struct rk_ts_data *ts;\r
704         ts = container_of(h, struct rk_ts_data, early_suspend);\r
705         rk_ts_resume(ts->client);\r
706 }\r
707 #endif\r
708 \r
709 /*******************************************************\r
710 Description:\r
711         Goodix touchscreen power manage function.\r
712 \r
713 Parameter:\r
714         on:     power status.0---suspend;1---resume.\r
715         \r
716 return:\r
717         Executive outcomes.-1---i2c transfer error;0---succeed.\r
718 *******************************************************/\r
719 static int goodix_ts_power(struct rk_ts_data * ts, int on)\r
720 {\r
721         int ret = -1;\r
722         unsigned char i2c_control_buf[2] = {0x38,  0x56};               //suspend cmd\r
723         int retry = 0;\r
724         if(on != 0 && on !=1)\r
725         {\r
726                 printk(KERN_DEBUG "%s: Cant't support this command.", rk_ts_name);\r
727                 return -EINVAL;\r
728         }\r
729         \r
730         \r
731         if(on == 0)             //suspend\r
732         { 
733                 gpio_set_value(ts->rst_pin,GPIO_LOW);\r
734                 msleep(20);\r
735                 gpio_set_value(ts->rst_pin,GPIO_HIGH);
736                 msleep(200);\r
737         while(retry<5)\r
738                 {\r
739                         ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
740                         if(ret == 1)\r
741                         {\r
742                                 printk(KERN_DEBUG "touch goodix Send suspend cmd successed \n");\r
743                                 break;\r
744                         }\r
745                        retry++;\r
746                         msleep(10);\r
747                 }\r
748                 if(ret > 0)\r
749                   ret = 0;\r
750         }\r
751         else if(on == 1)                //resume\r
752         {\r
753                 printk(KERN_DEBUG "touch goodix int resume\n");\r
754                 gpio_set_value(ts->rst_pin,GPIO_LOW);   \r
755                 msleep(20);\r
756             gpio_set_value(ts->rst_pin,GPIO_HIGH);\r
757                 ret = 0;\r
758         }        \r
759         return ret;\r
760 }\r
761 \r
762 \r
763 static int goodix_input_params_init(struct rk_ts_data *ts)\r
764 {\r
765         int ret ;\r
766         ts->input_dev = input_allocate_device();\r
767         if (ts->input_dev == NULL) {\r
768                 ret = -ENOMEM;\r
769                 printk(KERN_ALERT "Failed to allocate input device\n");\r
770                 return ret;\r
771         }\r
772 \r
773 \r
774         __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);\r
775         __set_bit(EV_ABS, ts->input_dev->evbit);\r
776 \r
777         input_mt_init_slots(ts->input_dev, ts->max_touch_num);\r
778         input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);\r
779         input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, /*ts->abs_x_max*/4096, 0, 0);\r
780         input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, /*ts->abs_y_max*/4096, 0, 0);\r
781         sprintf(ts->phys, "input/rkts");\r
782         ts->input_dev->name = rk_ts_name;\r
783         ts->input_dev->phys = ts->phys;\r
784         ts->input_dev->id.bustype = BUS_I2C;\r
785         ts->input_dev->id.vendor = 0xDEAD;\r
786         ts->input_dev->id.product = 0xBEEF;\r
787         ts->input_dev->id.version = 10427;      //screen firmware version\r
788         \r
789         ret = input_register_device(ts->input_dev);\r
790         if (ret) {\r
791                 printk(KERN_ALERT "Probe: Unable to register %s input device\n", ts->input_dev->name);\r
792                 return -1;\r
793         }\r
794 \r
795         return 0 ;\r
796         \r
797 }\r
798         \r
799 static int goodix_ts_init(struct rk_ts_data *ts)\r
800 {\r
801         int ret ;\r
802         char *version_info = NULL;\r
803 #if 1\r
804         char test_data = 1;\r
805         char retry;\r
806         for(retry=0;retry < 30; retry++)    //test goodix\r
807         {\r
808                 ret =goodix_i2c_write_bytes(ts->client, &test_data, 1);\r
809                 if (ret > 0)\r
810                         break;\r
811         }\r
812         if(ret <= 0)\r
813         {\r
814                 printk(KERN_INFO "I2C communication ERROR!Goodix touchscreen driver become invalid\n");\r
815                 return -1;\r
816         }       \r
817 #endif  \r
818         \r
819         ret = goodix_read_version(ts, &version_info);\r
820         if(ret <= 0)\r
821         {\r
822                 printk(KERN_INFO"Read version data failed!\n");\r
823         }\r
824         else\r
825         {\r
826                 printk("goodix_ts_init: version %s\n", (version_info+1));\r
827         }\r
828         \r
829         ret=goodix_init_panel(ts);\r
830         if(ret != 0) {\r
831                 printk("goodix panel init fail\n");\r
832                 return -1;\r
833         }\r
834 \r
835         vfree(version_info);\r
836         #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
837         goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL);\r
838         if(goodix_proc_entry == NULL)\r
839         {\r
840                 printk("Couldn't create proc entry!\n");\r
841                 ret = -ENOMEM;\r
842                 return ret ;\r
843         }\r
844         else\r
845         {\r
846                 printk("goodix_ts_init: create proc entry success!\n");\r
847                 goodix_proc_entry->write_proc = goodix_update_write;\r
848                 goodix_proc_entry->read_proc = goodix_update_read;\r
849 \r
850         }\r
851 #endif\r
852 \r
853         return 0;\r
854 }\r
855 /*******************************************************\r
856 Description:\r
857         Goodix touchscreen probe function.\r
858 \r
859 Parameter:\r
860         client: i2c device struct.\r
861         id:device id.\r
862         \r
863 return:\r
864         Executive outcomes. 0---succeed.\r
865 *******************************************************/\r
866 static int rk_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)\r
867 {\r
868         int ret = 0;\r
869         struct rk_ts_data *ts;\r
870         struct goodix_8110_platform_data *pdata ;\r
871         \r
872         printk(KERN_INFO "Install touch driver.\n");\r
873         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) \r
874         {\r
875                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");\r
876                 ret = -ENODEV;\r
877                 goto exit;\r
878         }\r
879 \r
880         ts = kzalloc(sizeof(struct rk_ts_data), GFP_KERNEL);\r
881         if (ts == NULL) {\r
882                 printk(KERN_ALERT "alloc for struct rk_ts_data fail\n");\r
883                 ret = -ENOMEM;\r
884                 goto exit;\r
885         }
886 \r
887 \r
888         pdata = client->dev.platform_data;\r
889         ts->irq_pin = pdata->irq_pin;\r
890         ts->rst_pin = pdata->reset;\r
891         ts->pendown =PEN_RELEASE;\r
892         ts->client = client;\r
893         ts->ts_init = goodix_ts_init;   \r
894         ts->power = goodix_ts_power;\r
895         ts->get_touch_info = goodix_get_touch_info;\r
896         ts->input_parms_init = goodix_input_params_init;\r
897         i2c_set_clientdata(client, ts);
898
899    if(pdata->hw_init)
900        pdata->hw_init();
901 \r
902 \r
903         gpio_set_value(pdata->reset, 1);\r
904         msleep(200);\r
905         \r
906         if(ts->ts_init)\r
907         {\r
908                 ret = ts->ts_init(ts);\r
909                 if(ret < 0)\r
910                 {\r
911                         printk(KERN_ALERT "rk ts init fail\n");\r
912                         goto exit;\r
913                 }\r
914         }\r
915 \r
916         if(ts->input_parms_init)\r
917         {\r
918                 ts->input_parms_init(ts);\r
919         }\r
920 \r
921         i2c_connect_client = client;\r
922         #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32)\r
923                 ts->ts_wq= create_rt_workqueue("rk_ts_wq");             //create a work queue and worker thread\r
924         #else\r
925                 ts->ts_wq= create_workqueue("rk_ts_wq"); \r
926         #endif\r
927         if (!ts->ts_wq){\r
928                 printk(KERN_ALERT "creat touch screen workqueue failed\n");\r
929             return -ENOMEM;\r
930         }\r
931         \r
932         INIT_DELAYED_WORK(&ts->ts_work, rk_ts_work_func);\r
933 #ifdef CONFIG_HAS_EARLYSUSPEND\r
934         ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;\r
935         ts->early_suspend.suspend = rk_ts_early_suspend;\r
936         ts->early_suspend.resume = rk_ts_late_resume;\r
937         register_early_suspend(&ts->early_suspend);\r
938 #endif\r
939 \r
940         info_buf= kzalloc(ts->max_touch_num*sizeof(struct rk_touch_info), GFP_KERNEL);\r
941         if(!info_buf)\r
942         {\r
943                 printk(KERN_ALERT "alloc for rk_touch_info fail\n");\r
944                 goto err_input_register_device_failed;\r
945         }\r
946 \r
947         ts->irq=gpio_to_irq(ts->irq_pin)        ;               //If not defined in client\r
948         if (ts->irq)\r
949         {\r
950                 ret = gpio_request(pdata->irq_pin, "TS_IRQ_PIN");       //Request IO\r
951                 if (ret < 0) \r
952                 {\r
953                         printk(KERN_ALERT "Failed to request for touch irq\n");\r
954                         goto err_input_register_device_failed;\r
955                 }\r
956                 else\r
957                 {\r
958                         gpio_direction_input(pdata->irq_pin);\r
959                 }\r
960 \r
961                 ret  = request_irq(ts->irq, rk_ts_irq_handler ,IRQ_TYPE_LEVEL_LOW/*IRQF_TRIGGER_FALLING*/,client->name, ts);\r
962                 if (ret != 0) {\r
963                         printk(KERN_ALERT "Cannot allocate ts INT!ERRNO:%d\n", ret);\r
964                         gpio_free(ts->irq_pin);\r
965                         goto err_input_register_device_failed;\r
966                 }\r
967         }\r
968         printk("goodix_ts_init: probe successfully!\n");\r
969         return 0;\r
970 \r
971         \r
972 err_input_register_device_failed:\r
973         input_free_device(ts->input_dev);\r
974         i2c_set_clientdata(client, NULL);       \r
975         kfree(ts);\r
976 exit:\r
977         return ret;\r
978 }\r
979 \r
980 \r
981 /*******************************************************\r
982 Description:\r
983         Goodix touchscreen driver release function.\r
984 \r
985 Parameter:\r
986         client: i2c device struct.\r
987         \r
988 return:\r
989         Executive outcomes. 0---succeed.\r
990 *******************************************************/\r
991 static int rk_ts_remove(struct i2c_client *client)\r
992 {\r
993         struct rk_ts_data *ts = i2c_get_clientdata(client);\r
994 #ifdef CONFIG_HAS_EARLYSUSPEND\r
995         unregister_early_suspend(&ts->early_suspend);\r
996 #endif\r
997 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
998         remove_proc_entry("goodix-update", NULL);\r
999 #endif\r
1000         \r
1001         gpio_free(ts->irq_pin);\r
1002         free_irq(ts->irq, ts);\r
1003         dev_notice(&client->dev,"The driver is removing...\n");\r
1004         i2c_set_clientdata(client, NULL);\r
1005         input_unregister_device(ts->input_dev);\r
1006         if(info_buf)\r
1007                 kfree(info_buf);\r
1008         kfree(ts);\r
1009         return 0;\r
1010 }\r
1011 \r
1012 static void rk_ts_shutdown(struct i2c_client *client)\r
1013 {\r
1014 #ifdef CONFIG_HAS_EARLYSUSPEND\r
1015         struct rk_ts_data *ts = i2c_get_clientdata(client);\r
1016         unregister_early_suspend(&ts->early_suspend);\r
1017 #endif\r
1018 }\r
1019 \r
1020 //******************************Begin of firmware update surpport*******************************\r
1021 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP\r
1022 /**\r
1023 @brief CRC cal proc,include : Reflect,init_crc32_table,GenerateCRC32\r
1024 @param global var oldcrc32\r
1025 @return states\r
1026 */\r
1027 static unsigned int Reflect(unsigned long int ref, char ch)\r
1028 {\r
1029         unsigned int value=0;\r
1030         int i;\r
1031         for(i = 1; i < (ch + 1); i++)\r
1032         {\r
1033                 if(ref & 1)\r
1034                         value |= 1 << (ch - i);\r
1035                 ref >>= 1;\r
1036         }\r
1037         return value;\r
1038 }\r
1039 /*---------------------------------------------------------------------------------------------------------*/\r
1040 /*  CRC Check Program INIT                                                                                                                         */\r
1041 /*---------------------------------------------------------------------------------------------------------*/\r
1042 static void init_crc32_table(void)\r
1043 {\r
1044         unsigned int temp;\r
1045         unsigned int t1,t2;\r
1046         unsigned int flag;\r
1047         int i,j;\r
1048         for(i = 0; i <= 0xFF; i++)\r
1049         {\r
1050                 temp=Reflect(i, 8);\r
1051                 crc32_table[i]= temp<< 24;\r
1052                 for (j = 0; j < 8; j++)\r
1053                 {\r
1054 \r
1055                         flag=crc32_table[i]&0x80000000;\r
1056                         t1=(crc32_table[i] << 1);\r
1057                         if(flag==0)\r
1058                                 t2=0;\r
1059                         else\r
1060                                 t2=ulPolynomial;\r
1061                         crc32_table[i] =t1^t2 ;\r
1062 \r
1063                 }\r
1064                 crc32_table[i] = Reflect(crc32_table[i], 32);\r
1065         }\r
1066 }\r
1067 /*---------------------------------------------------------------------------------------------------------*/\r
1068 /*  CRC main Program                                                                                                                               */\r
1069 /*---------------------------------------------------------------------------------------------------------*/\r
1070 static void GenerateCRC32(unsigned char * buf, unsigned int len)\r
1071 {\r
1072         unsigned int i;\r
1073         unsigned int t;\r
1074 \r
1075         for (i = 0; i != len; ++i)\r
1076         {\r
1077                 t = (oldcrc32 ^ buf[i]) & 0xFF;\r
1078                 oldcrc32 = ((oldcrc32 >> 8) & 0xFFFFFF) ^ crc32_table[t];\r
1079         }\r
1080 }\r
1081 \r
1082 static struct file * update_file_open(char * path, mm_segment_t * old_fs_p)\r
1083 {\r
1084         struct file * filp = NULL;\r
1085         int errno = -1;\r
1086                 \r
1087         filp = filp_open(path, O_RDONLY, 0644);\r
1088         \r
1089         if(!filp || IS_ERR(filp))\r
1090         {\r
1091                 if(!filp)\r
1092                         errno = -ENOENT;\r
1093                 else \r
1094                         errno = PTR_ERR(filp);                                  \r
1095                 printk(KERN_ERR "The update file for Guitar open error.\n");\r
1096                 return NULL;\r
1097         }\r
1098         *old_fs_p = get_fs();\r
1099         set_fs(get_ds());\r
1100 \r
1101         filp->f_op->llseek(filp,0,0);\r
1102         return filp ;\r
1103 }\r
1104 \r
1105 static void update_file_close(struct file * filp, mm_segment_t old_fs)\r
1106 {\r
1107         set_fs(old_fs);\r
1108         if(filp)\r
1109                 filp_close(filp, NULL);\r
1110 }\r
1111 static int update_get_flen(char * path)\r
1112 {\r
1113         struct file * file_ck = NULL;\r
1114         mm_segment_t old_fs;\r
1115         int length ;\r
1116         \r
1117         file_ck = update_file_open(path, &old_fs);\r
1118         if(file_ck == NULL)\r
1119                 return 0;\r
1120 \r
1121         length = file_ck->f_op->llseek(file_ck, 0, SEEK_END);\r
1122         //printk("File length: %d\n", length);\r
1123         if(length < 0)\r
1124                 length = 0;\r
1125         update_file_close(file_ck, old_fs);\r
1126         return length;  \r
1127 }\r
1128 static int update_file_check(char * path)\r
1129 {\r
1130         unsigned char buffer[64] = { 0 } ;\r
1131         struct file * file_ck = NULL;\r
1132         mm_segment_t old_fs;\r
1133         int count, ret, length ;\r
1134         \r
1135         file_ck = update_file_open(path, &old_fs);\r
1136         \r
1137         if(path != NULL)\r
1138                 printk("File Path:%s\n", path);\r
1139         \r
1140         if(file_ck == NULL)\r
1141                 return -ERROR_NO_FILE;\r
1142 \r
1143         length = file_ck->f_op->llseek(file_ck, 0, SEEK_END);\r
1144 #ifdef GUITAR_MESSAGE\r
1145         printk(KERN_INFO "gt801 update: File length: %d\n",length);\r
1146 #endif  \r
1147         if(length <= 0 || (length%4) != 0)\r
1148         {\r
1149                 update_file_close(file_ck, old_fs);\r
1150                 return -ERROR_FILE_TYPE;\r
1151         }\r
1152         \r
1153         //set file point to the begining of the file\r
1154         file_ck->f_op->llseek(file_ck, 0, SEEK_SET);    \r
1155         oldcrc32 = 0xFFFFFFFF;\r
1156         init_crc32_table();\r
1157         while(length > 0)\r
1158         {\r
1159                 ret = file_ck->f_op->read(file_ck, buffer, sizeof(buffer), &file_ck->f_pos);\r
1160                 if(ret > 0)\r
1161                 {\r
1162                         for(count = 0; count < ret;  count++)   \r
1163                                 GenerateCRC32(&buffer[count],1);                        \r
1164                 }\r
1165                 else \r
1166                 {\r
1167                         update_file_close(file_ck, old_fs);\r
1168                         return -ERROR_FILE_READ;\r
1169                 }\r
1170                 length -= ret;\r
1171         }\r
1172         oldcrc32 = ~oldcrc32;\r
1173 #ifdef GUITAR_MESSAGE   \r
1174         printk("CRC_Check: %u\n", oldcrc32);\r
1175 #endif  \r
1176         update_file_close(file_ck, old_fs);\r
1177         return 1;       \r
1178 }\r
1179 \r
1180 unsigned char wait_slave_ready(struct rk_ts_data *ts, unsigned short *timeout)\r
1181 {\r
1182         unsigned char i2c_state_buf[2] = {ADDR_STA, UNKNOWN_ERROR};\r
1183         int ret;\r
1184         while(*timeout < MAX_TIMEOUT)\r
1185         {\r
1186                 ret = goodix_i2c_read_bytes(ts->client, i2c_state_buf, 2);\r
1187                 if(ret <= 0)\r
1188                         return ERROR_I2C_TRANSFER;\r
1189                 if(i2c_state_buf[1] & SLAVE_READY)\r
1190                 {\r
1191                         return i2c_state_buf[1];\r
1192                         //return 1;\r
1193                 }\r
1194                 msleep(10);\r
1195                 *timeout += 5;\r
1196         }\r
1197         return 0;\r
1198 }\r
1199 \r
1200 static int goodix_update_write(struct file *filp, const char __user *buff, unsigned long len, void *data)\r
1201 {\r
1202         unsigned char cmd[220];\r
1203         int ret = -1;\r
1204 \r
1205         static unsigned char update_path[100];\r
1206         static unsigned short time_count = 0;\r
1207         static unsigned int file_len = 0;\r
1208         \r
1209         unsigned char i2c_control_buf[2] = {ADDR_CMD, 0};\r
1210         unsigned char i2c_states_buf[2] = {ADDR_STA, 0};\r
1211         unsigned char i2c_data_buf[PACK_SIZE+1+8] = {ADDR_DAT,};\r
1212         //unsigned char i2c_rd_buf[1+4+PACK_SIZE+4];\r
1213         unsigned char i2c_rd_buf[160];\r
1214         unsigned char retries = 0;\r
1215         unsigned int rd_len;\r
1216         unsigned char i = 0;\r
1217         static unsigned char update_need_config = 0;\r
1218 \r
1219         unsigned char checksum_error_times = 0;\r
1220 #ifdef UPDATE_NEW_PROTOCOL\r
1221         unsigned int frame_checksum = 0;\r
1222         unsigned int frame_number = 0;\r
1223 #else\r
1224         unsigned char send_crc = 0;\r
1225 #endif\r
1226 \r
1227         struct file * file_data = NULL;\r
1228         mm_segment_t old_fs;\r
1229         struct rk_ts_data *ts;\r
1230         \r
1231         ts = i2c_get_clientdata(i2c_connect_client);\r
1232         if(ts==NULL)\r
1233                 return 0;\r
1234         \r
1235         if(copy_from_user(&cmd, buff, len))\r
1236         {\r
1237                 return -EFAULT;\r
1238         }\r
1239         switch(cmd[0])\r
1240         {\r
1241                 case STEP_SET_PATH:\r
1242                         printk(KERN_INFO"Write cmd is:%d,cmd arg is:%s,write len is:%ld\n",cmd[0], &cmd[1], len);\r
1243                         memset(update_path, 0, 100);\r
1244                         strncpy(update_path, cmd+1, 100);\r
1245                         if(update_path[0] == 0)\r
1246                                 return 0;\r
1247                         else\r
1248                                 return 1;\r
1249                 case STEP_CHECK_FILE:\r
1250                         printk(KERN_INFO"Begin to firmware update ......\n");\r
1251                         ret = update_file_check(update_path);\r
1252                         if(ret <= 0)\r
1253                         {\r
1254                                 printk(KERN_INFO"fialed to check update file!\n");\r
1255                                 return ret;\r
1256                         }\r
1257                         msleep(500);\r
1258                         printk(KERN_INFO"Update check file success!\n");\r
1259                         return 1;\r
1260                 case STEP_WRITE_SYN:\r
1261                         printk(KERN_INFO"STEP1:Write synchronization signal!\n");\r
1262                         i2c_control_buf[1] = UPDATE_START;\r
1263                         ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
1264                         if(ret <= 0)\r
1265                         {\r
1266                                 ret = ERROR_I2C_TRANSFER;\r
1267                                 return ret;\r
1268                         }\r
1269                         //the time include time(APROM -> LDROM) and time(LDROM init)\r
1270                         msleep(1000);\r
1271                         return 1;\r
1272                 case STEP_WAIT_SYN:\r
1273                         printk(KERN_INFO"STEP2:Wait synchronization signal!\n");\r
1274                         while(retries < MAX_I2C_RETRIES)\r
1275                         {\r
1276                                 i2c_states_buf[1] = UNKNOWN_ERROR;\r
1277                                 ret = goodix_i2c_read_bytes(ts->client, i2c_states_buf, 2);\r
1278                                 printk(KERN_INFO"The read byte is:%d\n", i2c_states_buf[1]);\r
1279                                 if(i2c_states_buf[1] & UPDATE_START)\r
1280                                 {\r
1281                                         if(i2c_states_buf[1] & NEW_UPDATE_START)\r
1282                                         {\r
1283                                         #ifdef UPDATE_NEW_PROTOCOL\r
1284                                                 update_need_config = 1;\r
1285                                                 return 2;\r
1286                                         #else\r
1287                                                 return 1;\r
1288                                         #endif\r
1289                                         }\r
1290                                         break;\r
1291                                 }\r
1292                                 msleep(5);\r
1293                                 retries++;\r
1294                                 time_count += 10;\r
1295                         }\r
1296                         if((retries >= MAX_I2C_RETRIES) && (!(i2c_states_buf[1] & UPDATE_START)))\r
1297                         {\r
1298                                 if(ret <= 0)\r
1299                                         return 0;\r
1300                                 else\r
1301                                         return -1;\r
1302                         }\r
1303                         return 1;\r
1304                 case STEP_WRITE_LENGTH:\r
1305                         printk(KERN_INFO"STEP3:Write total update file length!\n");\r
1306                         file_len = update_get_flen(update_path);\r
1307                         if(file_len <= 0)\r
1308                         {\r
1309                                 printk(KERN_INFO"get update file length failed!\n");\r
1310                                 return -1;\r
1311                         }\r
1312                         file_len += 4;\r
1313                         i2c_data_buf[1] = (file_len>>24) & 0xff;\r
1314                         i2c_data_buf[2] = (file_len>>16) & 0xff;\r
1315                         i2c_data_buf[3] = (file_len>>8) & 0xff;\r
1316                         i2c_data_buf[4] = file_len & 0xff;\r
1317                         file_len -= 4;\r
1318                         ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, 5);\r
1319                         if(ret <= 0)\r
1320                         {\r
1321                                 ret = ERROR_I2C_TRANSFER;\r
1322                                 return 0;\r
1323                         }\r
1324                         return 1;\r
1325                 case STEP_WAIT_READY:\r
1326                         printk(KERN_INFO"STEP4:Wait slave ready!\n");\r
1327                         ret = wait_slave_ready(ts, &time_count);\r
1328                         if(ret == ERROR_I2C_TRANSFER)\r
1329                                 return 0;\r
1330                         if(!ret)\r
1331                         {\r
1332                                 return -1;\r
1333                         }\r
1334                         printk(KERN_INFO"Slave ready!\n");\r
1335                         return 1;\r
1336                 case STEP_WRITE_DATA:\r
1337 #ifdef UPDATE_NEW_PROTOCOL\r
1338                         printk(KERN_INFO"STEP5:Begin to send file data use NEW protocol!\n");\r
1339                         file_data = update_file_open(update_path, &old_fs);\r
1340                         if(file_data == NULL)\r
1341                         {\r
1342                                 return -1;\r
1343                         }\r
1344                         frame_number = 0;\r
1345                         while(file_len >= 0)\r
1346                         {\r
1347                                 i2c_data_buf[0] = ADDR_DAT;\r
1348                                 rd_len = (file_len >= PACK_SIZE) ? PACK_SIZE : file_len;\r
1349                                 frame_checksum = 0;\r
1350                                 if(file_len)\r
1351                                 {\r
1352                                         ret = file_data->f_op->read(file_data, i2c_data_buf+1+4, rd_len, &file_data->f_pos);\r
1353                                         if(ret <= 0)\r
1354                                         {\r
1355                                                 printk("[GOODiX_ISP_NEW]:Read File Data Failed!\n");\r
1356                                                 return -1;\r
1357                                         }\r
1358                                         i2c_data_buf[1] = (frame_number>>24)&0xff;\r
1359                                         i2c_data_buf[2] = (frame_number>>16)&0xff;\r
1360                                         i2c_data_buf[3] = (frame_number>>8)&0xff;\r
1361                                         i2c_data_buf[4] = frame_number&0xff;\r
1362                                         frame_number++;\r
1363                                         frame_checksum = 0;\r
1364                                         for(i=0; i<rd_len; i++)\r
1365                                         {\r
1366                                                 frame_checksum += i2c_data_buf[5+i];\r
1367                                         }\r
1368                                         frame_checksum = 0 - frame_checksum;\r
1369                                         i2c_data_buf[5+rd_len+0] = frame_checksum&0xff;\r
1370                                         i2c_data_buf[5+rd_len+1] = (frame_checksum>>8)&0xff;\r
1371                                         i2c_data_buf[5+rd_len+2] = (frame_checksum>>16)&0xff;\r
1372                                         i2c_data_buf[5+rd_len+3] = (frame_checksum>>24)&0xff;\r
1373                                 }\r
1374 rewrite:\r
1375                                 printk(KERN_INFO"[GOODiX_ISP_NEW]:%d\n", file_len);                             \r
1376                                 ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, 1+4+rd_len+4);\r
1377                                         //if(ret <= 0)\r
1378                                 if(ret != 1)\r
1379                                 {\r
1380                                         printk("[GOODiX_ISP_NEW]:Write File Data Failed!Return:%d\n", ret);\r
1381                                         return 0;\r
1382                                 }\r
1383 \r
1384                                 memset(i2c_rd_buf, 0x00, 1+4+rd_len+4);\r
1385                                 ret = goodix_i2c_read_bytes(ts->client, i2c_rd_buf, 1+4+rd_len+4);\r
1386                                 if(ret != 2)\r
1387                                 {\r
1388                                         printk("[GOODiX_ISP_NEW]:Read File Data Failed!Return:%d\n", ret);\r
1389                                         return 0;\r
1390                                 }\r
1391                                 for(i=1; i<(1+4+rd_len+4); i++)                                         //check communication\r
1392                                 {\r
1393                                         if(i2c_rd_buf[i] != i2c_data_buf[i])\r
1394                                         {\r
1395                                                 i = 0;\r
1396                                                 break;\r
1397                                         }\r
1398                                 }\r
1399                                 if(!i)\r
1400                                 {\r
1401                                         i2c_control_buf[0] = ADDR_CMD;\r
1402                                         i2c_control_buf[1] = 0x03;\r
1403                                         goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);         //communication error\r
1404                                         printk("[GOODiX_ISP_NEW]:File Data Frame readback check Error!\n");\r
1405                                 }\r
1406                                 else\r
1407                                 {\r
1408                                         i2c_control_buf[1] = 0x04;                                                                                                      //let LDROM write flash\r
1409                                         goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
1410                                 }\r
1411                                 \r
1412                                 //Wait for slave ready signal.and read the checksum\r
1413                                 ret = wait_slave_ready(ts, &time_count);\r
1414                                 if((ret & CHECKSUM_ERROR)||(!i))\r
1415                                 {\r
1416                                         if(i)\r
1417                                         {\r
1418                                                 printk("[GOODiX_ISP_NEW]:File Data Frame checksum Error!\n");\r
1419                                         }\r
1420                                         checksum_error_times++;\r
1421                                         msleep(20);\r
1422                                         if(checksum_error_times > 20)                           //max retry times.\r
1423                                                 return 0;\r
1424                                         goto rewrite;\r
1425                                 }\r
1426                                 checksum_error_times = 0;\r
1427                                 if(ret & (FRAME_ERROR))\r
1428                                 {\r
1429                                         printk("[GOODiX_ISP_NEW]:File Data Frame Miss!\n");\r
1430                                         return 0;\r
1431                                 }\r
1432                                 if(ret == ERROR_I2C_TRANSFER)\r
1433                                         return 0;\r
1434                                 if(!ret)\r
1435                                 {\r
1436                                         return -1;\r
1437                                 }\r
1438                                 if(file_len < PACK_SIZE)\r
1439                                 {\r
1440                                         update_file_close(file_data, old_fs);\r
1441                                         break;\r
1442                                 }\r
1443                                 file_len -= rd_len;\r
1444                         }//end of while((file_len >= 0))\r
1445                         return 1;\r
1446 #else\r
1447                         printk(KERN_INFO"STEP5:Begin to send file data use OLD protocol!\n");\r
1448                         file_data = update_file_open(update_path, &old_fs);\r
1449                         if(file_data == NULL)   //file_data has been opened at the last time\r
1450                         {\r
1451                                 return -1;\r
1452                         }\r
1453                         while((file_len >= 0) && (!send_crc))\r
1454                         {\r
1455                                 printk(KERN_INFO"[GOODiX_ISP_OLD]:%d\n", file_len);\r
1456                                 i2c_data_buf[0] = ADDR_DAT;\r
1457                                 rd_len = (file_len >= PACK_SIZE) ? PACK_SIZE : file_len;\r
1458                                 if(file_len)\r
1459                                 {\r
1460                                         ret = file_data->f_op->read(file_data, i2c_data_buf+1, rd_len, &file_data->f_pos);\r
1461                                         if(ret <= 0)\r
1462                                         {\r
1463                                                 return -1;\r
1464                                         }\r
1465                                 }\r
1466                                 if(file_len < PACK_SIZE)\r
1467                                 {\r
1468                                         send_crc = 1;\r
1469                                         update_file_close(file_data, old_fs);\r
1470                                         i2c_data_buf[file_len+1] = oldcrc32&0xff;\r
1471                                         i2c_data_buf[file_len+2] = (oldcrc32>>8)&0xff;\r
1472                                         i2c_data_buf[file_len+3] = (oldcrc32>>16)&0xff;\r
1473                                         i2c_data_buf[file_len+4] = (oldcrc32>>24)&0xff;\r
1474                                         ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, (file_len+1+4));\r
1475                                         //if(ret <= 0)\r
1476                                         if(ret != 1)\r
1477                                         {\r
1478                                                 printk("[GOODiX_ISP_OLD]:Write File Data Failed!Return:%d\n", ret);\r
1479                                                 return 0;\r
1480                                         }\r
1481                                         break;\r
1482                                 }\r
1483                                 else\r
1484                                 {\r
1485                                         ret = goodix_i2c_write_bytes(ts->client, i2c_data_buf, PACK_SIZE+1);\r
1486                                         //if(ret <= 0)\r
1487                                         if(ret != 1)\r
1488                                         {\r
1489                                                 printk("[GOODiX_ISP_OLD]:Write File Data Failed!Return:%d\n", ret);\r
1490                                                 return 0;\r
1491                                         }\r
1492                                 }\r
1493                                 file_len -= rd_len;\r
1494                         \r
1495                                 //Wait for slave ready signal.\r
1496                                 ret = wait_slave_ready(ts, &time_count);\r
1497                                 if(ret == ERROR_I2C_TRANSFER)\r
1498                                         return 0;\r
1499                                 if(!ret)\r
1500                                 {\r
1501                                         return -1;\r
1502                                 }\r
1503                                 //Slave is ready.\r
1504                         }//end of while((file_len >= 0) && (!send_crc))\r
1505                         return 1;\r
1506 #endif\r
1507                 case STEP_READ_STATUS:\r
1508                         printk(KERN_INFO"STEP6:Read update status!\n");\r
1509                         while(time_count < MAX_TIMEOUT)\r
1510                         {\r
1511                                 ret = goodix_i2c_read_bytes(ts->client, i2c_states_buf, 2);\r
1512                                 if(ret <= 0)\r
1513                                 {\r
1514                                         return 0;\r
1515                                 }\r
1516                                 if(i2c_states_buf[1] & SLAVE_READY)\r
1517                                 {\r
1518                                         if(!(i2c_states_buf[1] &0xf0))\r
1519                                         {\r
1520                                                 printk(KERN_INFO"The firmware updating succeed!update state:0x%x\n",i2c_states_buf[1]);\r
1521                                                 return 1;\r
1522                                         }\r
1523                                         else\r
1524                                         {\r
1525                                                 printk(KERN_INFO"The firmware updating failed!update state:0x%x\n",i2c_states_buf[1]);\r
1526                                                 return 0;\r
1527 \r
1528                                         }\r
1529                                 }\r
1530                                 msleep(1);\r
1531                                 time_count += 5;\r
1532                         }\r
1533                         return -1;\r
1534                 case FUN_CLR_VAL:                                                               //clear the static val\r
1535                         time_count = 0;\r
1536                         file_len = 0;\r
1537                         update_need_config = 0;\r
1538                         return 1;\r
1539                 case FUN_CMD:                                                   //functional command\r
1540                         if(cmd[1] == CMD_DISABLE_TP)\r
1541                         {\r
1542                                 printk(KERN_INFO"Disable TS int!\n");\r
1543                                 g_enter_isp = 1;\r
1544                                 disable_irq(ts->irq);\r
1545                         }\r
1546                         else if(cmd[1] == CMD_ENABLE_TP)\r
1547                         {\r
1548                                 printk(KERN_INFO"Enable TS int!\n");\r
1549                                 g_enter_isp = 0;\r
1550                                 enable_irq(ts->irq);\r
1551                         }\r
1552                         else if(cmd[1] == CMD_READ_VER)\r
1553                         {\r
1554                                 printk(KERN_INFO"Read version!\n");\r
1555                                 ts->read_mode = MODE_RD_VER;\r
1556                         }\r
1557                         else if(cmd[1] == CMD_READ_RAW)\r
1558                         {\r
1559                                 printk(KERN_INFO"Read raw data!\n");\r
1560                                 ts->read_mode = MODE_RD_RAW;\r
1561                                 i2c_control_buf[1] = 201;\r
1562                                 ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);                   //read raw data cmd\r
1563                                 if(ret <= 0)\r
1564                                 {\r
1565                                         printk(KERN_INFO"Write read raw data cmd failed!\n");\r
1566                                         return 0;\r
1567                                 }\r
1568                                 msleep(200);\r
1569                         }\r
1570                         else if(cmd[1] == CMD_READ_DIF)\r
1571                         {\r
1572                                 printk(KERN_INFO"Read diff data!\n");\r
1573                                 ts->read_mode = MODE_RD_DIF;\r
1574                                 i2c_control_buf[1] = 202;\r
1575                                 ret = goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);                   //read diff data cmd\r
1576                                 if(ret <= 0)\r
1577                                 {\r
1578                                         printk(KERN_INFO"Write read raw data cmd failed!\n");\r
1579                                         return 0;\r
1580                                 }\r
1581                                 msleep(200);\r
1582                         }\r
1583                         else if(cmd[1] == CMD_READ_CFG)\r
1584                         {\r
1585                                 printk(KERN_INFO"Read config info!\n");\r
1586                                 ts->read_mode = MODE_RD_CFG;\r
1587                                 rd_cfg_addr = cmd[2];\r
1588                                 rd_cfg_len = cmd[3];\r
1589                         }\r
1590                         else if(cmd[1] == CMD_SYS_REBOOT)\r
1591                         {\r
1592                                 printk(KERN_INFO"System reboot!\n");\r
1593                                 sys_sync();\r
1594                                 msleep(200);\r
1595                                 kernel_restart(NULL);\r
1596                         }\r
1597                         return 1;\r
1598                 case FUN_WRITE_CONFIG:\r
1599                         \r
1600                         printk(KERN_INFO"Begin write config info!Config length:%d\n",cmd[1]);\r
1601                         for(i=3; i<cmd[1];i++)\r
1602                         {\r
1603                                 //if((i-3)%5 == 0)printk("\n");\r
1604                                 printk("(%d):0x%x ", i-3, cmd[i]);\r
1605                         }\r
1606                         printk("\n");\r
1607 \r
1608                         if((cmd[2]>83)&&(cmd[2]<240)&&cmd[1])\r
1609                         {\r
1610                                 checksum_error_times = 0;\r
1611 reconfig:\r
1612                                 ret = goodix_i2c_write_bytes(ts->client, cmd+2, cmd[1]); \r
1613                                 if(ret != 1)\r
1614                                 {\r
1615                                         printk("Write Config failed!return:%d\n",ret);\r
1616                                         return -1;\r
1617                                 }\r
1618                                 if(!update_need_config)return 1;\r
1619                                 \r
1620                                 i2c_rd_buf[0] = cmd[2];\r
1621                                 ret = goodix_i2c_read_bytes(ts->client, i2c_rd_buf, cmd[1]);\r
1622                                 if(ret != 2)\r
1623                                 {\r
1624                                         printk("Read Config failed!return:%d\n",ret);\r
1625                                         return -1;\r
1626                                 }\r
1627                                 for(i=0; i<cmd[1]; i++)\r
1628                                 {\r
1629                                         if(i2c_rd_buf[i] != cmd[i+2])\r
1630                                         {\r
1631                                                 printk("Config readback check failed!\n");\r
1632                                                 i = 0;\r
1633                                                 break;\r
1634                                         }\r
1635                                 }\r
1636                                 if(!i)\r
1637                                 {\r
1638                                         i2c_control_buf[0] = ADDR_CMD;\r
1639                                         i2c_control_buf[1] = 0x03;\r
1640                                         goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);         //communication error\r
1641                                         checksum_error_times++;\r
1642                                         msleep(20);\r
1643                                         if(checksum_error_times > 20)                           //max retry times.\r
1644                                                 return 0;\r
1645                                         goto reconfig;\r
1646                                 }\r
1647                                 else\r
1648                                 {\r
1649                                         i2c_control_buf[0] = ADDR_CMD;\r
1650                                         i2c_control_buf[1] = 0x04;                                      //let LDROM write flash\r
1651                                         goodix_i2c_write_bytes(ts->client, i2c_control_buf, 2);\r
1652                                         return 1;\r
1653                                 }\r
1654                                 \r
1655                         }\r
1656                         else\r
1657                         {\r
1658                                 printk(KERN_INFO"Invalid config addr!\n");\r
1659                                 return -1;\r
1660                         }\r
1661                 default:\r
1662                         return -ENOSYS;\r
1663         }\r
1664         return 0;\r
1665 }\r
1666 \r
1667 static int goodix_update_read( char *page, char **start, off_t off, int count, int *eof, void *data )\r
1668 {\r
1669         int ret = -1;\r
1670         struct rk_ts_data *ts;\r
1671         int len = 0;\r
1672         char *version_info = NULL;\r
1673         static unsigned char read_data[1201] = {80, };\r
1674 \r
1675         ts = i2c_get_clientdata(i2c_connect_client);\r
1676         if(ts==NULL)\r
1677                 return 0;\r
1678 \r
1679         if(ts->read_mode == MODE_RD_VER)                //read version data\r
1680         {\r
1681                 ret = goodix_read_version(ts, &version_info);\r
1682                 if(ret <= 0)\r
1683                 {\r
1684                         printk(KERN_INFO"Read version data failed!\n");\r
1685                         vfree(version_info);\r
1686                         return 0;\r
1687                 }\r
1688 \r
1689                 for(len=0;len<100;len++)\r
1690                 {\r
1691                         if(*(version_info + len) == '\0')\r
1692                                 break;\r
1693                 }\r
1694                 printk(KERN_INFO"GOODiX Touchscreen Version is:%s\n", (version_info+1));\r
1695                 strncpy(page, version_info+1, len + 1);\r
1696                 vfree(version_info);\r
1697                 *eof = 1;\r
1698                 return len+1;\r
1699         }\r
1700         else if((ts->read_mode == MODE_RD_RAW)||(ts->read_mode == MODE_RD_DIF))         //read raw data or diff\r
1701         {\r
1702                 //printk(KERN_INFO"Read raw data\n");\r
1703                 ret = goodix_i2c_read_bytes(ts->client, read_data, 1201);\r
1704                 if(ret <= 0)\r
1705                 {\r
1706                         if(ts->read_mode == 2)\r
1707                                 printk(KERN_INFO"Read raw data failed!\n");\r
1708                         if(ts->read_mode == 3)\r
1709                                 printk(KERN_INFO"Read diff data failed!\n");\r
1710                         return 0;\r
1711                 }\r
1712                 memcpy(page, read_data+1, 1200);\r
1713                 *eof = 1;\r
1714                 *start = NULL;\r
1715                 return 1200;\r
1716         }\r
1717         else if(ts->read_mode == MODE_RD_CFG)\r
1718         {\r
1719                 if((rd_cfg_addr>83)&&(rd_cfg_addr<240))\r
1720                 {\r
1721                         read_data[0] = rd_cfg_addr;\r
1722                         printk("read config addr is:%d\n", rd_cfg_addr);\r
1723                 }\r
1724                 else\r
1725                 {\r
1726                         read_data[0] = 101;\r
1727                         printk("invalid read config addr,use default!\n");\r
1728                 }\r
1729                 if((rd_cfg_len<0)||(rd_cfg_len>156))\r
1730                 {\r
1731                         printk("invalid read config length,use default!\n");\r
1732                         rd_cfg_len = 239 - read_data[0];\r
1733                 }\r
1734                 printk("read config length is:%d\n", rd_cfg_len);\r
1735                 ret = goodix_i2c_read_bytes(ts->client, read_data, rd_cfg_len);\r
1736                 if(ret <= 0)\r
1737                 {\r
1738                         printk(KERN_INFO"Read config info failed!\n");\r
1739                         return 0;\r
1740                 }\r
1741                 memcpy(page, read_data+1, rd_cfg_len);\r
1742                 return rd_cfg_len;\r
1743         }\r
1744         return len;\r
1745 }\r
1746               \r
1747 #endif\r
1748 //******************************End of firmware update surpport*******************************\r
1749 static const struct i2c_device_id goodix_ts_id[] = {\r
1750         { "Goodix-TS", 0 },\r
1751         { }\r
1752 };\r
1753 \r
1754 static struct i2c_driver rk_ts_driver = {\r
1755         .probe          = rk_ts_probe,\r
1756         .remove         = rk_ts_remove,\r
1757         .shutdown       = rk_ts_shutdown,\r
1758 #ifndef CONFIG_HAS_EARLYSUSPEND\r
1759         .suspend        = rk_ts_suspend,\r
1760         .resume         = rk_ts_resume,\r
1761 #endif\r
1762         .id_table       = goodix_ts_id,\r
1763         .driver = {\r
1764                 .name   = "Goodix-TS",\r
1765                 .owner = THIS_MODULE,\r
1766         },\r
1767 };\r
1768 \r
1769 \r
1770 static struct class *ts_debug_class = NULL;\r
1771 static ssize_t dbg_mode_show(struct class *cls,struct class_attribute *attr, char *_buf)\r
1772 {\r
1773        printk("%s>>>>>>>>\n",__func__);\r
1774        return 0;\r
1775 }\r
1776 \r
1777 static ssize_t dbg_mode_store(struct class *cls,struct class_attribute *attr, const char *buf, size_t _count)\r
1778 {\r
1779         dbg_thresd = simple_strtol(buf,NULL,10);\r
1780         if(dbg_thresd)\r
1781         {\r
1782                 printk(KERN_INFO "ts debug open\n");\r
1783         }\r
1784         else\r
1785         {\r
1786                 printk(KERN_INFO "ts debug close");\r
1787         }\r
1788       \r
1789     return _count;\r
1790 }\r
1791 static CLASS_ATTR(debug, 0664, dbg_mode_show, dbg_mode_store);\r
1792 \r
1793 static int dbg_sys_init(void)\r
1794 {\r
1795         int ret ;\r
1796         ts_debug_class = class_create(THIS_MODULE, "ts_debug");\r
1797         ret =  class_create_file(ts_debug_class, &class_attr_debug);\r
1798     if (ret)\r
1799     {\r
1800        printk("Fail to creat class hkrkfb.\n");\r
1801     }\r
1802    return 0;\r
1803 }\r
1804 \r
1805 \r
1806 /*******************************************************        \r
1807 Description:\r
1808         Driver Install function.\r
1809 return:\r
1810         Executive Outcomes. 0---succeed.\r
1811 ********************************************************/\r
1812 \r
1813 static void __init rk_ts_init_async(void *unused, async_cookie_t cookie)\r
1814 {\r
1815         i2c_add_driver(&rk_ts_driver);\r
1816         dbg_sys_init();  //for debug\r
1817 }\r
1818 \r
1819 static int __init rk_ts_init(void)\r
1820 {\r
1821         async_schedule(rk_ts_init_async, NULL);\r
1822         return 0;\r
1823 }\r
1824 \r
1825 /*******************************************************        \r
1826 Description:\r
1827         Driver uninstall function.\r
1828 return:\r
1829         Executive Outcomes. 0---succeed.\r
1830 ********************************************************/\r
1831 static void __exit rk_ts_exit(void)\r
1832 {\r
1833         printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");\r
1834         i2c_del_driver(&rk_ts_driver);\r
1835 }\r
1836 \r
1837 module_init(rk_ts_init);\r
1838 module_exit(rk_ts_exit);\r
1839 \r
1840 MODULE_DESCRIPTION("Goodix Touchscreen Driver");\r
1841 MODULE_LICENSE("GPL");\r
1842 \r