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