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