Merge tag 'lsk-v4.4-16.07-android'
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / ft5306_ts_av.c
1 /* \r
2  * drivers/input/touchscreen/ft5x0x_ts.c\r
3  *\r
4  * FocalTech ft5x0x TouchScreen driver. \r
5  *\r
6  * Copyright (c) 2010  Focal tech Ltd.\r
7  *\r
8  * This software is licensed under the terms of the GNU General Public\r
9  * License version 2, as published by the Free Software Foundation, and\r
10  * may be copied, distributed, and modified under those terms.\r
11  *\r
12  * This program is distributed in the hope that it will be useful,\r
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  * GNU General Public License for more details.\r
16  *\r
17  *\r
18  *      note: only support mulititouch  Wenfs 2010-10-01\r
19  */\r
20 \r
21 #include <linux/input.h>\r
22 #include <linux/module.h>\r
23 #include <linux/init.h>\r
24 #include <linux/interrupt.h>\r
25 #include <linux/kernel.h>\r
26 #include <linux/platform_device.h>\r
27 #include <linux/spi/spi.h>\r
28 #include <linux/slab.h>\r
29 #include <linux/fcntl.h>\r
30 #include <linux/delay.h>\r
31 #include <linux/device.h>\r
32 #include <linux/timer.h>\r
33 #include <linux/jiffies.h>\r
34 #include <linux/miscdevice.h>\r
35 #include <linux/types.h>\r
36 #include <linux/io.h>\r
37 #include <linux/delay.h>\r
38 #include <linux/ioport.h>\r
39 #include <linux/input-polldev.h>\r
40 #include <linux/i2c.h>\r
41 #include <linux/workqueue.h>\r
42 #ifdef CONFIG_ANDROID_POWER\r
43 #include <linux/android_power.h>\r
44 #endif\r
45 #include <mach/hardware.h>\r
46 #include <asm/setup.h>\r
47 #include <asm/mach-types.h>\r
48 #include <asm/mach/arch.h>\r
49 #include <asm/mach/map.h>\r
50 #include <asm/mach/flash.h>\r
51 #include <asm/hardware/gic.h>\r
52 #include <mach/iomux.h>\r
53 #include <mach/gpio.h>\r
54 #include <mach/irqs.h>\r
55 //#include <mach/rk29_iomap.h>\r
56 #include <mach/board.h>\r
57 //#include <mach/rk29_nand.h>\r
58 //#include <mach/rk29_camera.h>                          /* ddl@rock-chips.com : camera support */\r
59 #include <media/soc_camera.h>                               /* ddl@rock-chips.com : camera support */\r
60 //#include <mach/vpu_mem.h>\r
61 #include <mach/sram.h>\r
62 #ifdef CONFIG_HAS_EARLYSUSPEND\r
63 #include <linux/earlysuspend.h>\r
64 #endif\r
65 #include <linux/input/mt.h>\r
66 \r
67 \r
68 #if 0\r
69 #define FTprintk(x...) printk(x)\r
70 #else\r
71 #define FTprintk(x...) do{} while(0)\r
72 #endif\r
73 \r
74 #define CONFIG_FT5X0X_MULTITOUCH  1\r
75 #define MAX_POINT                 5\r
76 #define FT5306_IIC_SPEED          100*1000    //300*1000\r
77 //#define TOUCH_RESET_PIN           RK30_PIN1_PC0\r
78 #define FT5X0X_REG_THRES          0x80         /* Thresshold, the threshold be low, the sensitivy will be high */\r
79 #define FT5X0X_REG_REPORT_RATE    0x88         /* **************report rate, in unit of 10Hz **************/\r
80 #define FT5X0X_REG_PMODE          0xA5         /* Power Consume Mode 0 -- active, 1 -- monitor, 3 -- sleep */    \r
81 #define FT5X0X_REG_FIRMID         0xA6         /* ***************firmware version **********************/\r
82 #define FT5X0X_REG_NOISE_MODE     0xb2         /* to enable or disable power noise, 1 -- enable, 0 -- disable */\r
83 #define SCREEN_MAX_X              1024\r
84 #define SCREEN_MAX_Y              600\r
85 #define PRESS_MAX                 255\r
86 #define FT5X0X_NAME                   "ft5x0x_ts"\r
87 #define TOUCH_MAJOR_MAX           200\r
88 #define WIDTH_MAJOR_MAX           200\r
89 //FT5X0X_REG_PMODE\r
90 #define PMODE_ACTIVE              0x00\r
91 #define PMODE_MONITOR             0x01\r
92 #define PMODE_STANDBY             0x02\r
93 #define PMODE_HIBERNATE           0x03\r
94 \r
95 /* zhengxing@rock-chips: avoid to firmwarm upgrade directly cause barrage when startup. */\r
96 #define FT5X0X_FW_UPGRADE_ASYNC         (1)\r
97 #define FT5X0X_FW_UPGRADE_DIRECTLY      (2)\r
98 \r
99 #ifdef CONFIG_MACH_RK3066B_M701\r
100 #define FT5X0X_FW_UPGRADE_MODE          FT5X0X_FW_UPGRADE_ASYNC\r
101 #else\r
102 #define FT5X0X_FW_UPGRADE_MODE          FT5X0X_FW_UPGRADE_DIRECTLY\r
103 #endif\r
104 \r
105 struct ts_event {\r
106         u16     x1;\r
107         u16     y1;\r
108         u16     x2;\r
109         u16     y2;\r
110         u16     x3;\r
111         u16     y3;\r
112         u16     x4;\r
113         u16     y4;\r
114         u16     x5;\r
115         u16     y5;\r
116         u16     pressure;\r
117     s16  touch_ID1;\r
118         s16  touch_ID2;\r
119     s16  touch_ID3;\r
120     s16  touch_ID4;\r
121         s16  touch_ID5;\r
122         u8   touch_point;\r
123         u8   status;\r
124 };\r
125 \r
126 struct tp_event {\r
127         u16     x;\r
128         u16     y;\r
129     s16 id;\r
130         u16     pressure;\r
131         u8  touch_point;\r
132         u8  flag;\r
133 };\r
134 \r
135 struct ft5x0x_ts_data {\r
136         struct i2c_client *client;\r
137         struct input_dev        *input_dev;\r
138         int    irq;\r
139         int     (*platform_sleep)(void);\r
140     int     (*platform_wakeup)(void);\r
141         struct ts_event         event;\r
142         struct work_struct      pen_event_work;\r
143         struct workqueue_struct *ts_workqueue;\r
144 #ifdef CONFIG_HAS_EARLYSUSPEND\r
145         struct early_suspend ft5306_early_suspend;\r
146 #endif\r
147 #if (FT5X0X_FW_UPGRADE_MODE == FT5X0X_FW_UPGRADE_ASYNC)\r
148     struct work_struct  fw_upgrade_work;\r
149     struct workqueue_struct *fw_workqueue;\r
150 #endif\r
151 };\r
152 static struct i2c_client *this_client;\r
153 \r
154 /***********************************************************************/\r
155 \r
156 #define    FTS_PACKET_LENGTH        128\r
157 \r
158 \r
159 static u8 CTPM_FW[]=\r
160 {\r
161 #include "ft5306_ts_av.cfg"\r
162 };\r
163 \r
164 typedef enum\r
165 {\r
166     ERR_OK,\r
167     ERR_MODE,\r
168     ERR_READID,\r
169     ERR_ERASE,\r
170     ERR_STATUS,\r
171     ERR_ECC,\r
172     ERR_DL_ERASE_FAIL,\r
173     ERR_DL_PROGRAM_FAIL,\r
174     ERR_DL_VERIFY_FAIL\r
175 }E_UPGRADE_ERR_TYPE;\r
176 \r
177 /***********************************************************************/\r
178 \r
179 /***********************************************************************\r
180     [function]: \r
181                            callback:                send data to ctpm by i2c interface;\r
182     [parameters]:\r
183                             txdata[in]:              data buffer which is used to send data;\r
184                             length[in]:              the length of the data buffer;\r
185     [return]:\r
186                             FTS_TRUE:              success;\r
187                             FTS_FALSE:             fail;\r
188 ************************************************************************/\r
189 static int fts_i2c_txdata(u8 *txdata, int length)\r
190 {\r
191         int ret;\r
192 \r
193         struct i2c_msg msg;\r
194 \r
195       msg.addr = this_client->addr;\r
196       msg.flags = 0;\r
197       msg.len = length;\r
198       msg.buf = txdata;\r
199       msg.scl_rate = FT5306_IIC_SPEED;\r
200         ret = i2c_transfer(this_client->adapter, &msg, 1);\r
201         if (ret < 0)\r
202                 pr_err("%s i2c write error: %d\n", __func__, ret);\r
203 \r
204         return ret;\r
205 }\r
206 \r
207 /***********************************************************************\r
208     [function]: \r
209                            callback:               write data to ctpm by i2c interface;\r
210     [parameters]:\r
211                             buffer[in]:             data buffer;\r
212                             length[in]:            the length of the data buffer;\r
213     [return]:\r
214                             FTS_TRUE:            success;\r
215                             FTS_FALSE:           fail;\r
216 ************************************************************************/\r
217 static bool  i2c_write_interface(u8* pbt_buf, int dw_lenth)\r
218 {\r
219     int ret;\r
220     ret=i2c_master_send(this_client, pbt_buf, dw_lenth);\r
221     if(ret<=0)\r
222     {\r
223         FTprintk("[TSP]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret);\r
224         return false;\r
225     }\r
226 \r
227     return true;\r
228 }\r
229 \r
230 /***********************************************************************\r
231     [function]: \r
232                            callback:                read register value ftom ctpm by i2c interface;\r
233     [parameters]:\r
234                         reg_name[in]:         the register which you want to write;\r
235                             tx_buf[in]:              buffer which is contained of the writing value;\r
236     [return]:\r
237                             FTS_TRUE:              success;\r
238                             FTS_FALSE:             fail;\r
239 ************************************************************************/\r
240 static bool fts_register_write(u8 reg_name, u8* tx_buf)\r
241 {\r
242         u8 write_cmd[2] = {0};\r
243 \r
244         write_cmd[0] = reg_name;\r
245         write_cmd[1] = *tx_buf;\r
246 \r
247         /*call the write callback function*/\r
248         return i2c_write_interface(write_cmd, 2);\r
249 }\r
250 \r
251 /***********************************************************************\r
252 [function]: \r
253                       callback:         send a command to ctpm.\r
254 [parameters]:\r
255                           btcmd[in]:       command code;\r
256                           btPara1[in]:     parameter 1;    \r
257                           btPara2[in]:     parameter 2;    \r
258                           btPara3[in]:     parameter 3;    \r
259                       num[in]:         the valid input parameter numbers, \r
260                                            if only command code needed and no \r
261                                            parameters followed,then the num is 1;    \r
262 [return]:\r
263                           FTS_TRUE:      success;\r
264                           FTS_FALSE:     io fail;\r
265 ************************************************************************/\r
266 static bool cmd_write(u8 btcmd,u8 btPara1,u8 btPara2,u8 btPara3,u8 num)\r
267 {\r
268     u8 write_cmd[4] = {0};\r
269 \r
270     write_cmd[0] = btcmd;\r
271     write_cmd[1] = btPara1;\r
272     write_cmd[2] = btPara2;\r
273     write_cmd[3] = btPara3;\r
274     return i2c_write_interface(write_cmd, num);\r
275 }\r
276 \r
277 /***********************************************************************\r
278     [function]: \r
279                            callback:              read data from ctpm by i2c interface;\r
280     [parameters]:\r
281                             buffer[in]:            data buffer;\r
282                             length[in]:           the length of the data buffer;\r
283     [return]:\r
284                             FTS_TRUE:            success;\r
285                             FTS_FALSE:           fail;\r
286 ************************************************************************/\r
287 static bool i2c_read_interface(u8* pbt_buf, int dw_lenth)\r
288 {\r
289     int ret;\r
290     \r
291     ret=i2c_master_recv(this_client, pbt_buf, dw_lenth);\r
292 \r
293     if(ret<=0)\r
294     {\r
295         FTprintk("[TSP]i2c_read_interface error\n");\r
296         return false;\r
297     }\r
298   \r
299     return true;\r
300 }\r
301 \r
302 \r
303 /***********************************************************************\r
304 [function]: \r
305                       callback:         read a byte data  from ctpm;\r
306 [parameters]:\r
307                           buffer[in]:       read buffer;\r
308                           length[in]:      the size of read data;    \r
309 [return]:\r
310                           FTS_TRUE:      success;\r
311                           FTS_FALSE:     io fail;\r
312 ************************************************************************/\r
313 static bool byte_read(u8* buffer, int length)\r
314 {\r
315     return i2c_read_interface(buffer, length);\r
316 }\r
317 \r
318 /***********************************************************************\r
319 [function]: \r
320                       callback:         write a byte data  to ctpm;\r
321 [parameters]:\r
322                           buffer[in]:       write buffer;\r
323                           length[in]:      the size of write data;    \r
324 [return]:\r
325                           FTS_TRUE:      success;\r
326                           FTS_FALSE:     io fail;\r
327 ************************************************************************/\r
328 static bool byte_write(u8* buffer, int length)\r
329 {\r
330     \r
331     return i2c_write_interface(buffer, length);\r
332 }\r
333 \r
334 /***********************************************************************\r
335     [function]: \r
336                            callback:                 read register value ftom ctpm by i2c interface;\r
337     [parameters]:\r
338                         reg_name[in]:         the register which you want to read;\r
339                             rx_buf[in]:              data buffer which is used to store register value;\r
340                             rx_length[in]:          the length of the data buffer;\r
341     [return]:\r
342                             FTS_TRUE:              success;\r
343                             FTS_FALSE:             fail;\r
344 ************************************************************************/\r
345 static bool fts_register_read(u8 reg_name, u8* rx_buf, int rx_length)\r
346 {\r
347         u8 read_cmd[2]= {0};\r
348         u8 cmd_len      = 0;\r
349 \r
350         read_cmd[0] = reg_name;\r
351         cmd_len = 1;    \r
352 \r
353         /*send register addr*/\r
354         if(!i2c_write_interface(&read_cmd[0], cmd_len))\r
355         {\r
356                 return false;\r
357         }\r
358 \r
359         /*call the read callback function to get the register value*/           \r
360         if(!i2c_read_interface(rx_buf, rx_length))\r
361         {\r
362                 return false;\r
363         }\r
364         return true;\r
365 }\r
366 \r
367 \r
368 \r
369 /***********************************************************************\r
370 [function]: \r
371                         callback:          burn the FW to ctpm.\r
372 [parameters]:\r
373                             pbt_buf[in]:     point to Head+FW ;\r
374                             dw_lenth[in]:   the length of the FW + 6(the Head length);    \r
375 [return]:\r
376                             ERR_OK:          no error;\r
377                             ERR_MODE:      fail to switch to UPDATE mode;\r
378                             ERR_READID:   read id fail;\r
379                             ERR_ERASE:     erase chip fail;\r
380                             ERR_STATUS:   status error;\r
381                             ERR_ECC:        ecc error.\r
382 ************************************************************************/\r
383 E_UPGRADE_ERR_TYPE  fts_ctpm_fw_upgrade(u8* pbt_buf, int dw_lenth)\r
384 {\r
385     u8  cmd,reg_val[2] = {0};\r
386         u8  buffer[2] = {0};\r
387     u8  packet_buf[FTS_PACKET_LENGTH + 6];\r
388     u8  auc_i2c_write_buf[10];\r
389     u8  bt_ecc;\r
390         \r
391     int  j,temp,lenght,i_ret,packet_number, i = 0;\r
392     int  i_is_new_protocol = 0;\r
393         \r
394 \r
395     /******write 0xaa to register 0xfc******/\r
396     cmd=0xaa;\r
397     fts_register_write(0xfc,&cmd);\r
398     mdelay(50);\r
399         \r
400      /******write 0x55 to register 0xfc******/\r
401     cmd=0x55;\r
402     fts_register_write(0xfc,&cmd);\r
403     FTprintk("[TSP] Step 1: Reset CTPM test\n");\r
404    \r
405     mdelay(10);   \r
406 \r
407 \r
408     /*******Step 2:Enter upgrade mode ****/\r
409     FTprintk("\n[TSP] Step 2:enter new update mode\n");\r
410     auc_i2c_write_buf[0] = 0x55;\r
411     auc_i2c_write_buf[1] = 0xaa;\r
412     do\r
413     {\r
414         i ++;\r
415         i_ret = fts_i2c_txdata(auc_i2c_write_buf, 2);\r
416         mdelay(5);\r
417     }while(i_ret <= 0 && i < 10 );\r
418 \r
419     if (i > 1)\r
420     {\r
421         i_is_new_protocol = 1;\r
422     }\r
423 \r
424     /********Step 3:check READ-ID********/        \r
425     cmd_write(0x90,0x00,0x00,0x00,4);\r
426     byte_read(reg_val,2);\r
427     if (reg_val[0] == 0x79 && reg_val[1] == 0x3)\r
428     {\r
429         FTprintk("[TSP] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]);\r
430     }\r
431     else\r
432     {\r
433         return ERR_READID;\r
434         //i_is_new_protocol = 1;\r
435     }\r
436     \r
437 \r
438      /*********Step 4:erase app**********/\r
439     if (i_is_new_protocol)\r
440     {\r
441         cmd_write(0x61,0x00,0x00,0x00,1);\r
442     }\r
443     else\r
444     {\r
445         cmd_write(0x60,0x00,0x00,0x00,1);\r
446     }\r
447     mdelay(1500);\r
448     FTprintk("[TSP] Step 4: erase. \n");\r
449 \r
450 \r
451 \r
452     /*Step 5:write firmware(FW) to ctpm flash*/\r
453     bt_ecc = 0;\r
454     FTprintk("[TSP] Step 5: start upgrade. \n");\r
455     dw_lenth = dw_lenth - 8;\r
456     packet_number = (dw_lenth) / FTS_PACKET_LENGTH;\r
457     packet_buf[0] = 0xbf;\r
458     packet_buf[1] = 0x00;\r
459         FTprintk("[TSP]  packet_number = %d\n",packet_number);\r
460     for (j=0;j<packet_number;j++)\r
461     {\r
462         temp = j * FTS_PACKET_LENGTH;\r
463         packet_buf[2] = (u8)(temp>>8);\r
464         packet_buf[3] = (u8)temp;\r
465         lenght = FTS_PACKET_LENGTH;\r
466         packet_buf[4] = (u8)(lenght>>8);\r
467         packet_buf[5] = (u8)lenght;\r
468 \r
469         for (i=0;i<FTS_PACKET_LENGTH;i++)\r
470         {\r
471             packet_buf[6+i] = pbt_buf[j*FTS_PACKET_LENGTH + i]; \r
472             bt_ecc ^= packet_buf[6+i];\r
473         }\r
474         \r
475         byte_write(&packet_buf[0],FTS_PACKET_LENGTH + 6);\r
476         mdelay(FTS_PACKET_LENGTH/6 + 1);\r
477         if ((j * FTS_PACKET_LENGTH % 1024) == 0)\r
478         {\r
479               FTprintk("[TSP] upgrade the 0x%x th byte.\n", ((unsigned int)j) * FTS_PACKET_LENGTH);\r
480         }\r
481     }\r
482 \r
483     if ((dw_lenth) % FTS_PACKET_LENGTH > 0)\r
484     {\r
485         temp = packet_number * FTS_PACKET_LENGTH;\r
486         packet_buf[2] = (u8)(temp>>8);\r
487         packet_buf[3] = (u8)temp;\r
488 \r
489         temp = (dw_lenth) % FTS_PACKET_LENGTH;\r
490         packet_buf[4] = (u8)(temp>>8);\r
491         packet_buf[5] = (u8)temp;\r
492 \r
493         for (i=0;i<temp;i++)\r
494         {\r
495             packet_buf[6+i] = pbt_buf[ packet_number*FTS_PACKET_LENGTH + i]; \r
496             bt_ecc ^= packet_buf[6+i];\r
497         }\r
498 \r
499         byte_write(&packet_buf[0],temp+6);    \r
500         mdelay(20);\r
501     }\r
502 \r
503     /***********send the last six byte**********/\r
504     for (i = 0; i<6; i++)\r
505     {\r
506         temp = 0x6ffa + i;\r
507         packet_buf[2] = (u8)(temp>>8);\r
508         packet_buf[3] = (u8)temp;\r
509         temp =1;\r
510         packet_buf[4] = (u8)(temp>>8);\r
511         packet_buf[5] = (u8)temp;\r
512         packet_buf[6] = pbt_buf[ dw_lenth + i]; \r
513         bt_ecc ^= packet_buf[6];\r
514 \r
515         byte_write(&packet_buf[0],7);  \r
516         mdelay(20);\r
517     }\r
518 \r
519     /********send the opration head************/\r
520     cmd_write(0xcc,0x00,0x00,0x00,1);\r
521     byte_read(reg_val,1);\r
522     FTprintk("[TSP] Step 6:  ecc read 0x%x, new firmware 0x%x. \n", reg_val[0], bt_ecc);\r
523     if(reg_val[0] != bt_ecc)\r
524     {\r
525         return ERR_ECC;\r
526     }\r
527 \r
528     /*******Step 7: reset the new FW**********/\r
529     cmd_write(0x07,0x00,0x00,0x00,1);\r
530         mdelay(100);//100ms     \r
531         fts_register_read(0xfc, buffer, 1);     \r
532         if (buffer[0] == 1)\r
533         {\r
534         cmd=4;\r
535         fts_register_write(0xfc, &cmd);\r
536         mdelay(2500);//2500ms   \r
537          do     \r
538          {      \r
539          fts_register_read(0xfc, buffer, 1);    \r
540          mdelay(100);//100ms    \r
541          }while (buffer[0] != 1);                       \r
542         }\r
543     return ERR_OK;\r
544 }\r
545 \r
546 \r
547 /***********************************************************************/\r
548 \r
549 int fts_ctpm_fw_upgrade_with_i_file(void)\r
550 {\r
551    u8*     pbt_buf = 0;\r
552    int i_ret;\r
553     \r
554    pbt_buf = CTPM_FW;\r
555    i_ret =  fts_ctpm_fw_upgrade(pbt_buf,sizeof(CTPM_FW));\r
556    \r
557    return i_ret;\r
558 }\r
559 \r
560 /***********************************************************************/\r
561 \r
562 unsigned char fts_ctpm_get_upg_ver(void)\r
563 {\r
564     unsigned int ui_sz;\r
565         \r
566     ui_sz = sizeof(CTPM_FW);\r
567     if (ui_sz > 2)\r
568     {\r
569         return CTPM_FW[ui_sz - 2];\r
570     }\r
571     else\r
572         return 0xff; \r
573  \r
574 }\r
575 \r
576 /*read the it7260 register ,used i2c bus*/\r
577 static int ft5306_read_regs(struct i2c_client *client, u8 reg, u8 *buf, unsigned len)\r
578 {\r
579         int ret; \r
580         ret = i2c_master_reg8_recv(client, reg, buf, len, FT5306_IIC_SPEED);\r
581         return ret; \r
582 }\r
583 \r
584 /* set the it7260 registe,used i2c bus*/\r
585 static int ft5306_set_regs(struct i2c_client *client, u8 reg, u8 *buf, unsigned short len)\r
586 {\r
587         int ret; \r
588         ret = i2c_master_reg8_send(client, reg, buf, (int)len, FT5306_IIC_SPEED);\r
589         return ret;\r
590 }\r
591 \r
592 #if (FT5X0X_FW_UPGRADE_MODE == FT5X0X_FW_UPGRADE_ASYNC)\r
593 static void ft5306_firmware_upgrade_work(struct work_struct *work)\r
594 {\r
595     struct ft5x0x_ts_data *data = container_of(work, struct ft5x0x_ts_data, fw_upgrade_work);\r
596     int err = 0;\r
597     unsigned char reg_value;\r
598     unsigned char reg_version;\r
599 \r
600     printk("<-- %s --> enter\n", __FUNCTION__);\r
601 \r
602     fts_register_read(FT5X0X_REG_FIRMID, &reg_version,1);\r
603     printk("cdy == [TSP] firmware version = 0x%2x\n", reg_version);\r
604 \r
605     fts_register_read(FT5X0X_REG_FIRMID, &reg_version,1);\r
606     FTprintk("[TSP] firmware version = 0x%2x\n", reg_version);\r
607     if (fts_ctpm_get_upg_ver() != reg_version)  \r
608     {\r
609       FTprintk("[TSP] start upgrade new verison 0x%2x\n", fts_ctpm_get_upg_ver());\r
610       msleep(200);\r
611       err =  fts_ctpm_fw_upgrade_with_i_file();\r
612       if (err == 0)\r
613       {\r
614           FTprintk("[TSP] ugrade successfuly.\n");\r
615           msleep(300);\r
616           fts_register_read(FT5X0X_REG_FIRMID, &reg_value,1);\r
617           FTprintk("FTS_DBG from old version 0x%2x to new version = 0x%2x\n", reg_version, reg_value);\r
618       }\r
619       else\r
620       {\r
621           FTprintk("[TSP]  ugrade fail err=%d, line = %d.\n",err, __LINE__);\r
622       }\r
623       msleep(4000);\r
624     }\r
625     cancel_work_sync(&data->fw_upgrade_work);\r
626     destroy_workqueue(data->fw_workqueue);\r
627 }\r
628 #endif\r
629 \r
630 static void ft5306_queue_work(struct work_struct *work)\r
631 {\r
632         struct ft5x0x_ts_data *data = container_of(work, struct ft5x0x_ts_data, pen_event_work);\r
633         struct tp_event event;\r
634         u8 start_reg=0x0;\r
635         u8 buf[32] = {0};\r
636         int ret,i,offset,points;\r
637         static u8 points_last_flag[MAX_POINT]={0};\r
638         struct tp_event  current_events[MAX_POINT];\r
639                 \r
640 #if CONFIG_FT5X0X_MULTITOUCH\r
641         ret = ft5306_read_regs(data->client,start_reg, buf, 6*MAX_POINT+1);\r
642 #else\r
643         ret = ft5306_read_regs(data->client,start_reg, buf, 7);\r
644 #endif\r
645         if (ret < 0) {\r
646                 dev_err(&data->client->dev, "ft5306_read_regs fail:%d!\n",ret);\r
647                 enable_irq(data->irq);\r
648                 return;\r
649         }\r
650 #if 0\r
651         for (i=0; i<32; i++) {\r
652                 FTprintk("buf[%d] = 0x%x \n", i, buf[i]);\r
653         }\r
654 #endif\r
655         \r
656         points = buf[2] & 0x07;\r
657         //dev_info(&data->client->dev, "ft5306_read_and_report_data points = %d\n",points);\r
658         if (points == 0) {\r
659 #if   CONFIG_FT5X0X_MULTITOUCH\r
660                 //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);\r
661                 //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0);\r
662                 \r
663                 for(i=0;i<MAX_POINT;i++)\r
664                 {\r
665                         if(points_last_flag[i]!=0)\r
666                         {\r
667                                 FTprintk("Point UP event.id=%d\n",i);\r
668                                 input_mt_slot(data->input_dev, i);\r
669                                 input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false);                                     \r
670                         }\r
671                 }\r
672 \r
673                 memset(points_last_flag, 0, sizeof(points_last_flag));\r
674                 //input_mt_sync(data->input_dev);\r
675 #else\r
676                 input_report_abs(data->input_dev, ABS_PRESSURE, 0);\r
677                 input_report_key(data->input_dev, BTN_TOUCH, 0);\r
678 #endif\r
679                 input_sync(data->input_dev);\r
680                 enable_irq(data->irq);\r
681                 return; \r
682         }\r
683         memset(&event, 0, sizeof(struct tp_event));\r
684 #if CONFIG_FT5X0X_MULTITOUCH\r
685   memset(current_events, 0, sizeof(current_events));\r
686   \r
687         for(i=0;i<points;i++){\r
688                 offset = i*6+3;\r
689                 event.x = (((s16)(buf[offset+0] & 0x0F))<<8) | ((s16)buf[offset+1]);\r
690                 event.y = (((s16)(buf[offset+2] & 0x0F))<<8) | ((s16)buf[offset+3]);\r
691                 event.id = (s16)(buf[offset+2] & 0xF0)>>4;\r
692                 event.flag = ((buf[offset+0] & 0xc0) >> 6);\r
693                 event.pressure = 200;\r
694                 FTprintk("x=%d, y=%d event.id=%d event.flag=%d\n",event.x,event.y,event.id,event.flag);\r
695                 if(event.x<=SCREEN_MAX_X && event.y<=SCREEN_MAX_Y+60){\r
696                         //dev_info(&data->client->dev, \r
697                         //      "ft5306 multiple report event[%d]:x = %d,y = %d,id = %d,flag = %d,pressure = %d\n",\r
698                         //      i,event.x,event.y,event.id,event.flag,event.pressure);\r
699                 if(event.flag)\r
700                         memcpy(&current_events[event.id], &event, sizeof(event));\r
701                         //points_current[event.id] = event.flag;                        \r
702                 }\r
703         }\r
704         \r
705         for(i=0;i<MAX_POINT;i++)\r
706         {\r
707                   if((current_events[i].flag == 0) && (points_last_flag[i] != 0))\r
708                         {\r
709                 FTprintk("Point UP event.id=%d\n",i);\r
710                                         input_mt_slot(data->input_dev, i);\r
711                                         input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false);                                             \r
712                         }\r
713                         else  if(current_events[i].flag)        \r
714                         {       \r
715                                 FTprintk("Point DN event.id=%d\n",i);\r
716                                         input_mt_slot(data->input_dev, i);\r
717                                         input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true);\r
718                                         input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1);\r
719                                         //input_report_abs(data->input_dev, ABS_MT_PRESSURE, event.pressure);\r
720                                         input_report_abs(data->input_dev, ABS_MT_POSITION_X,  current_events[i].x);\r
721                                         input_report_abs(data->input_dev, ABS_MT_POSITION_Y,  current_events[i].y);                                                                     \r
722                         }               \r
723                         points_last_flag[i] =   current_events[i].flag;\r
724         }\r
725 #else\r
726         event.x = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];\r
727         event.y = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];\r
728         event.pressure =200;\r
729         input_report_abs(data->input_dev, ABS_X, event.x);\r
730         input_report_abs(data->input_dev, ABS_Y, event.y);\r
731         //input_report_abs(data->input_dev, ABS_PRESSURE, event.pressure);\r
732         input_report_key(data->input_dev, BTN_TOUCH, 1);\r
733         \r
734         \r
735         //dev_info(&data->client->dev, "ft5306 single report event:x = %d,y = %d\n",event.x,event.y);\r
736 #endif\r
737         //printk("ft5306 sync  x = %d ,y = %d\n",event.x,event.y);\r
738         input_sync(data->input_dev);\r
739         enable_irq(data->irq);\r
740         return;\r
741 }\r
742 \r
743 static irqreturn_t ft5306_interrupt(int irq, void *dev_id)\r
744 {\r
745         struct ft5x0x_ts_data *ft5x0x_ts = dev_id;\r
746         FTprintk("[TSP]  ft5306_interrupt\n");\r
747         disable_irq_nosync(ft5x0x_ts->irq);\r
748         if (!work_pending(&ft5x0x_ts->pen_event_work)) \r
749                 queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);\r
750         return IRQ_HANDLED;\r
751 }\r
752 #ifdef CONFIG_HAS_EARLYSUSPEND\r
753 \r
754 static void ft5306_suspend(struct early_suspend *h)\r
755 {\r
756         struct ft5x0x_ts_data *ft5x0x_ts;\r
757         char buf_w[1] = {3};\r
758         int err;\r
759     ft5x0x_ts = container_of(h, struct ft5x0x_ts_data, ft5306_early_suspend);\r
760         FTprintk("TSP ft5306_suspend\n");\r
761     err = ft5306_set_regs(this_client, 0xA5, buf_w, 1);\r
762     if (err > 0)\r
763         printk("ft5306_set_regs OK!!\n");\r
764 \r
765     msleep(20);\r
766 \r
767         if (ft5x0x_ts->platform_sleep){ \r
768                 ft5x0x_ts->platform_sleep();\r
769         }\r
770 \r
771         disable_irq(ft5x0x_ts->irq);\r
772 }\r
773 \r
774 \r
775 static void ft5306_resume(struct early_suspend *h)\r
776 {\r
777         struct ft5x0x_ts_data *ft5x0x_ts;       \r
778         int trytimes;\r
779         u8 val = 0;\r
780         ft5x0x_ts = container_of(h, struct ft5x0x_ts_data, ft5306_early_suspend);\r
781         FTprintk("TSP ft5306_resume\n");\r
782         enable_irq(ft5x0x_ts->irq);\r
783         if (ft5x0x_ts->platform_wakeup)                              \r
784                 ft5x0x_ts->platform_wakeup();\r
785 \r
786         for(trytimes = 0 ;trytimes < 5; trytimes++){\r
787                 if(ft5306_read_regs(this_client, 0x00,  &val,1)<0){\r
788                         if (ft5x0x_ts->platform_sleep) \r
789                                 ft5x0x_ts->platform_sleep();\r
790                         if (ft5x0x_ts->platform_wakeup)                              \r
791                                 ft5x0x_ts->platform_wakeup();\r
792                 }else{\r
793                         break;\r
794                 }\r
795         }\r
796 \r
797         //gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);\r
798         //mdelay(100);\r
799         //gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);\r
800 }\r
801 #endif\r
802 \r
803 static int __devexit ft5306_remove(struct i2c_client *client)\r
804 {\r
805         struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);\r
806 \r
807         free_irq(ft5x0x_ts->irq, ft5x0x_ts);\r
808         input_unregister_device(ft5x0x_ts->input_dev);\r
809         kfree(ft5x0x_ts);\r
810         cancel_work_sync(&ft5x0x_ts->pen_event_work);\r
811         destroy_workqueue(ft5x0x_ts->ts_workqueue);\r
812         i2c_set_clientdata(client, NULL);\r
813 #ifdef CONFIG_HAS_EARLYSUSPEND\r
814     unregister_early_suspend(&ft5x0x_ts->ft5306_early_suspend);\r
815 #endif \r
816     this_client = NULL;\r
817         return 0;\r
818 }\r
819 \r
820 static int  ft5306_probe(struct i2c_client *client ,const struct i2c_device_id *id)\r
821 {\r
822         struct ft5x0x_ts_data *ft5x0x_ts;\r
823         struct input_dev *input_dev;\r
824         struct ft5606_platform_data *pdata = client->dev.platform_data;\r
825         int err = 0;\r
826         int ret = 0;\r
827         int retry = 0;\r
828         u8 buf_w[1];\r
829         u8 buf_r[1];\r
830         u8 buf_test[1] = {0};\r
831     unsigned char reg_value;\r
832     unsigned char reg_version;\r
833 \r
834         dev_info(&client->dev, "ft5306_ts_probe!\n");\r
835         if (!pdata) {\r
836                 dev_err(&client->dev, "platform data is required!\n");\r
837                 return -EINVAL;\r
838         }\r
839 \r
840         if (pdata->init_platform_hw)                              \r
841                 pdata->init_platform_hw();\r
842         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){\r
843                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");\r
844                 return -ENODEV;\r
845         }\r
846         \r
847         ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);\r
848         ft5x0x_ts->platform_wakeup = pdata->platform_wakeup;\r
849         ft5x0x_ts->platform_sleep = pdata->platform_sleep;      \r
850         if (!ft5x0x_ts) {\r
851                 return -ENOMEM;\r
852         }\r
853 \r
854     while(retry < 5) \r
855     {    \r
856         ret = ft5306_set_regs(client,FT5X0X_REG_PMODE, buf_test, 1);\r
857         if(ret > 0) \r
858             break;\r
859         retry++;\r
860 \r
861         printk("FT5306 I2C TEST FAILED, retry = %d, ret = %d, will again...\n", retry, ret);\r
862 \r
863         if (pdata->exit_platform_hw)     \r
864             pdata->exit_platform_hw();\r
865         if (pdata->init_platform_hw)     \r
866             pdata->init_platform_hw();\r
867     }    \r
868     printk("FT5306 I2C TEST OK, retry = %d, ret = %d\n", retry, ret);\r
869 \r
870     if(ret <= 0)\r
871     {    \r
872         printk("FT5306 I2C TEST ERROR! retry = %d, ret = %d\n", retry, ret);\r
873         err = -ENODEV;\r
874         goto exit_i2c_test_fail;\r
875     }\r
876         \r
877         input_dev = input_allocate_device();\r
878         if (!input_dev) {\r
879                 err = -ENOMEM;\r
880                 printk("failed to allocate input device\n");\r
881                 goto exit_input_dev_alloc_failed;\r
882         }\r
883         ft5x0x_ts->client = this_client = client;\r
884         ft5x0x_ts->irq = client->irq;\r
885         ft5x0x_ts->input_dev = input_dev;\r
886 \r
887   #if   CONFIG_FT5X0X_MULTITOUCH\r
888         __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);\r
889         __set_bit(EV_ABS, input_dev->evbit);    \r
890 \r
891         input_mt_init_slots(input_dev, MAX_POINT);\r
892         input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);      \r
893         input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);\r
894         input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);\r
895         //input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, MAX_POINT, 0, 0);\r
896         //input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);\r
897         \r
898 #else\r
899         set_bit(ABS_X, input_dev->absbit);\r
900         set_bit(ABS_Y, input_dev->absbit);\r
901         set_bit(ABS_PRESSURE, input_dev->absbit);\r
902         set_bit(BTN_TOUCH, input_dev->keybit);\r
903         input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);\r
904         input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);\r
905         //input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);\r
906 #endif\r
907 \r
908         //input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); \r
909         //input_dev->keybit[BIT_WORD(BTN_START)] = BIT_MASK(BTN_START);\r
910         //set_bit(EV_ABS, input_dev->evbit);\r
911         //set_bit(EV_KEY, input_dev->evbit);\r
912         \r
913         input_dev->name         = "ft5x0x_ts-touchscreen";              //dev_name(&client->dev)\r
914         err = input_register_device(input_dev);\r
915         if (err) {\r
916                 printk("ft5306_ts_probe: failed to register input device: \n");\r
917                 goto exit_input_register_device_failed;\r
918         }\r
919 \r
920         if (!ft5x0x_ts->irq) {\r
921                 err = -ENODEV;\r
922                 dev_err(&ft5x0x_ts->client->dev, "no IRQ?\n");\r
923                 goto exit_no_irq_fail;\r
924         }else{\r
925                 ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);\r
926         }\r
927 \r
928         INIT_WORK(&ft5x0x_ts->pen_event_work, ft5306_queue_work);\r
929         ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts");\r
930         if (!ft5x0x_ts->ts_workqueue) {\r
931                 err = -ESRCH;\r
932                 goto exit_create_singlethread;\r
933         }\r
934 \r
935         /***wait CTP to bootup normally***/\r
936         msleep(200); \r
937 \r
938 //write firmware \r
939 #if (FT5X0X_FW_UPGRADE_MODE == FT5X0X_FW_UPGRADE_ASYNC)\r
940 /* zhengxing: will upgrade firmware async */\r
941     printk("will create ft tp firmware upgrade workqueue...\n");\r
942     ft5x0x_ts->fw_workqueue = create_singlethread_workqueue("ft5x0x_fw");\r
943     if (!ft5x0x_ts->fw_workqueue) {\r
944         err = -ESRCH;\r
945         goto exit_create_singlethread;\r
946     }\r
947     INIT_WORK(&ft5x0x_ts->fw_upgrade_work, ft5306_firmware_upgrade_work);    \r
948 #else\r
949 /* zhengxing: will upgrade firmware directly */\r
950     fts_register_read(FT5X0X_REG_FIRMID, &reg_version,1);\r
951     printk("cdy == [TSP] firmware version = 0x%2x\n", reg_version);\r
952 \r
953         fts_register_read(FT5X0X_REG_FIRMID, &reg_version,1);\r
954         FTprintk("[TSP] firmware version = 0x%2x\n", reg_version);\r
955         if (fts_ctpm_get_upg_ver() != reg_version)  \r
956         {\r
957           FTprintk("[TSP] start upgrade new verison 0x%2x\n", fts_ctpm_get_upg_ver());\r
958           msleep(200);\r
959           err =  fts_ctpm_fw_upgrade_with_i_file();\r
960           if (err == 0)\r
961           {\r
962                   FTprintk("[TSP] ugrade successfuly.\n");\r
963                   msleep(300);\r
964                   fts_register_read(FT5X0X_REG_FIRMID, &reg_value,1);\r
965                   FTprintk("FTS_DBG from old version 0x%2x to new version = 0x%2x\n", reg_version, reg_value);\r
966           }\r
967           else\r
968           {\r
969                   FTprintk("[TSP]  ugrade fail err=%d, line = %d.\n",err, __LINE__);\r
970           }\r
971           msleep(4000);\r
972         }\r
973 #endif\r
974         ret = request_irq(ft5x0x_ts->irq, ft5306_interrupt, IRQF_TRIGGER_FALLING, client->dev.driver->name, ft5x0x_ts);\r
975         if (ret < 0) {\r
976                 dev_err(&client->dev, "irq %d busy?\n", ft5x0x_ts->irq);\r
977                 goto exit_irq_request_fail;\r
978         }\r
979         i2c_set_clientdata(client, ft5x0x_ts);\r
980 #ifdef CONFIG_HAS_EARLYSUSPEND\r
981         ft5x0x_ts->ft5306_early_suspend.suspend =ft5306_suspend;\r
982         ft5x0x_ts->ft5306_early_suspend.resume =ft5306_resume;\r
983         ft5x0x_ts->ft5306_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;;\r
984         register_early_suspend(&ft5x0x_ts->ft5306_early_suspend);\r
985 #endif\r
986         buf_w[0] = 6;\r
987         err = ft5306_set_regs(client,0x88,buf_w,1);\r
988         buf_r[0] = 0;\r
989         err = ft5306_read_regs(client,0x88,buf_r,1);\r
990         FTprintk("read buf[0x88] = %d\n", buf_r[0]);\r
991 \r
992 #if (FT5X0X_FW_UPGRADE_MODE == FT5X0X_FW_UPGRADE_ASYNC) \r
993     queue_work(ft5x0x_ts->fw_workqueue, &ft5x0x_ts->fw_upgrade_work);\r
994 #endif\r
995 \r
996     return 0;\r
997 \r
998         i2c_set_clientdata(client, NULL);\r
999         free_irq(ft5x0x_ts->irq,ft5x0x_ts);\r
1000 exit_irq_request_fail:\r
1001         cancel_work_sync(&ft5x0x_ts->pen_event_work);\r
1002         destroy_workqueue(ft5x0x_ts->ts_workqueue);\r
1003 exit_create_singlethread:\r
1004 exit_no_irq_fail:\r
1005         input_unregister_device(input_dev);\r
1006 exit_input_register_device_failed:\r
1007         input_free_device(input_dev);\r
1008 exit_input_dev_alloc_failed:\r
1009 exit_i2c_test_fail:\r
1010         if (pdata->exit_platform_hw)                              \r
1011                 pdata->exit_platform_hw();\r
1012         kfree(ft5x0x_ts);\r
1013         return err;\r
1014 }\r
1015 \r
1016 \r
1017 \r
1018 static struct i2c_device_id ft5306_idtable[] = {\r
1019         { FT5X0X_NAME, 0 },\r
1020         { }\r
1021 };\r
1022 \r
1023 MODULE_DEVICE_TABLE(i2c, ft5306_idtable);\r
1024 \r
1025 static struct i2c_driver ft5306_driver  = {\r
1026         .driver = {\r
1027                 .owner  = THIS_MODULE,\r
1028                 .name   = FT5X0X_NAME\r
1029         },\r
1030         .id_table       = ft5306_idtable,\r
1031         .probe      = ft5306_probe,\r
1032     //.suspend  = ft5306_suspend,\r
1033         //.resume           = ft5306_resume,\r
1034         .remove         = __devexit_p(ft5306_remove),\r
1035 };\r
1036 \r
1037 static int __init ft5306_ts_init(void)\r
1038 {\r
1039         return i2c_add_driver(&ft5306_driver);\r
1040 }\r
1041 \r
1042 static void __exit ft5306_ts_exit(void)\r
1043 {\r
1044         FTprintk("Touchscreen driver of ft5306 exited.\n");\r
1045         i2c_del_driver(&ft5306_driver);\r
1046 }\r
1047 \r
1048 \r
1049 /***********************************************************************/\r
1050 \r
1051 module_init(ft5306_ts_init);\r
1052 module_exit(ft5306_ts_exit);\r
1053 \r
1054 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");\r
1055 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");\r
1056 \r