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