ts: rk29_i2c_goodix: goodix_init_panel retry write cfg info when error
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / ft5306_ts.c
1 /* 
2  * drivers/input/touchscreen/ft5x0x_ts.c
3  *
4  * FocalTech ft5x0x TouchScreen driver. 
5  *
6  * Copyright (c) 2010  Focal tech Ltd.
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  *
18  *      note: only support mulititouch  Wenfs 2010-10-01
19  */
20 #include <linux/module.h>
21 #include <linux/delay.h>
22 #include <linux/hrtimer.h>
23 #include <linux/i2c.h>
24 #include <linux/input.h>
25 #include <linux/interrupt.h>
26 #include <linux/io.h>
27 #include <linux/platform_device.h>
28 #include <linux/async.h>
29 #include <linux/workqueue.h>
30 #include <linux/slab.h>
31 #include <mach/gpio.h>
32 #include <linux/irq.h>
33 #include <mach/board.h>
34 #include <linux/input/mt.h>
35
36
37 #ifdef CONFIG_HAS_EARLYSUSPEND
38 #include <linux/earlysuspend.h>
39 #endif
40
41
42 #define CONFIG_FT5X0X_MULTITOUCH 1
43 #define CONFIG_TOUCH_PANEL_KEY    1
44 #define NEW_PAL_DRV
45 #define CHECK_KEY
46 #define LONGPRESS_LOCK_SPECKEY   //是否使用长按某键(如search键)锁住功能键的功能
47 #ifdef LONGPRESS_LOCK_SPECKEY
48 #define KEY_LOCK 195
49 #define ORIGIN_KEY KEY_SEARCH
50 #define LOCK_LONG_PRESS_CNT 100
51 static int Origin2LockPressCnt = 0;
52 static int lockflag =0;
53 static int touch_key_hold_press = 0;
54
55 ssize_t glock_status_show(struct device *dev, char *buf)
56 {
57          printk("lockflag === %d\n",lockflag);
58         return sprintf(buf, "%d", lockflag);
59 }
60 #endif
61
62
63 static int err_ft5X06 = 0;      //w++记载有没有此设备
64 static int debug1=1;
65 module_param(debug1, int, S_IRUGO|S_IWUSR);
66
67 static int gpress = 0;
68 extern void gpio_enable1();
69 static int Motoenble = 0;
70 module_param(Motoenble, int, S_IRUGO|S_IWUSR);
71 static int MotoStart = 0;
72
73 /*
74  * Added by yick @RockChip
75  * Compatible with both types of firmware
76  * default: point - only pressdown finger num
77  *                      event - both down and up event
78  */
79 #define USE_POINT 1
80 #if USE_POINT
81 uint16_t down_table     = 0;
82 uint16_t up_table       = ~0;
83 #endif
84
85 #define SCREEN_MAX_X    480
86 #define SCREEN_MAX_Y    800
87 #define PRESS_MAX       255
88
89 #define FT5X0X_NAME     "ft5x0x_ts"
90 #define MAX_CONTACTS 5
91 enum ft5x0x_ts_regs {
92         FT5X0X_REG_PMODE        = 0xA5, /* Power Consume Mode           */
93 };
94
95 #define KEY_MIN_X       800
96 #define KEY_NUM         4
97
98 int touch_key_press[] = {0, 0, 0, 0};
99 //int touch_key_code[] = { KEY_BACK,KEY_HOME, KEY_MENU};
100 //int touch_key_min[KEY_NUM] ={-1,59,105};
101 //int touch_key_max[KEY_NUM] ={2,73,121};
102
103 int touch_key_code[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK, KEY_SEARCH};
104 int touch_key_min[KEY_NUM] ={30,150,270,390};
105 int touch_key_max[KEY_NUM] ={90,210,330,450};
106
107 //FT5X0X_REG_PMODE
108 #define PMODE_ACTIVE        0x00
109 #define PMODE_MONITOR       0x01
110 #define PMODE_STANDBY       0x02
111 #define PMODE_HIBERNATE     0x03
112
113 #ifndef ABS_MT_TOUCH_MAJOR
114 #define ABS_MT_TOUCH_MAJOR      0x30    /* touching ellipse */
115 #define ABS_MT_TOUCH_MINOR      0x31    /* (omit if circular) */
116 #define ABS_MT_WIDTH_MAJOR      0x32    /* approaching ellipse */
117 #define ABS_MT_WIDTH_MINOR      0x33    /* (omit if circular) */
118 #define ABS_MT_ORIENTATION      0x34    /* Ellipse orientation */
119 #define ABS_MT_POSITION_X         0x35  /* Center X ellipse position */
120 #define ABS_MT_POSITION_Y         0x36  /* Center Y ellipse position */
121 #define ABS_MT_TOOL_TYPE          0x37  /* Type of touching device */
122 #define ABS_MT_BLOB_ID            0x38  /* Group set of pkts as blob */
123 #endif /* ABS_MT_TOUCH_MAJOR */
124
125 struct point_data {
126         u8 status;
127         u8 id;
128         u16 x;
129         u16 y;
130 };
131
132 struct ts_event {
133   u16  touch_point;
134   struct point_data point[5];
135 };
136
137 struct ft5x0x_ts_dev {
138   struct i2c_client *client;
139         struct input_dev        *input_dev;
140         int    irq;
141         struct ts_event         event;
142         struct work_struct      pen_event_work;
143         struct workqueue_struct *ts_workqueue;
144         struct early_suspend    early_suspend;
145
146 #ifdef CHECK_KEY
147                         struct timer_list timer;
148 #endif
149 };
150
151 static struct ft5x0x_ts_dev *g_dev;
152 static bool rember_point_into = true;
153
154
155 static ssize_t Moto_status(struct device_driver *_drv,char *_buf)
156 {
157         //printk("Moto_status Motoenble==%d\n", Motoenble);
158    if(Motoenble)
159        return sprintf(_buf, "Ledlevel is Low\n");
160    else
161            return sprintf(_buf, "Ledlevel is High\n");
162 }
163 static ssize_t Moto_control(struct device_driver *_drv, const char *_buf, size_t _count)
164 {
165                 char temp[5];
166                 //printk("Read data from Android: %s\n", _buf);
167                 strncpy(temp, _buf, 1);
168                 Motoenble = simple_strtol(temp, NULL, 10);
169                 //printk("Moto_control Motoenble=%d\n", Motoenble);
170 }
171
172
173 static int ft5x0x_i2c_rxdata(char *rxdata, int length)
174 {
175         int ret;
176
177         struct i2c_msg msgs[] = {
178                 {
179                         .addr   = g_dev->client->addr,
180                         .flags  = 0,
181                         .len    = 1,
182                         .buf    = rxdata,
183                         .scl_rate = 200 * 1000,
184                 },
185                 {
186                         .addr   = g_dev->client->addr,
187                         .flags  = I2C_M_RD,
188                         .len    = length,
189                         .buf    = rxdata,
190                         .scl_rate = 200 * 1000,
191                 },
192         };
193
194         ret = i2c_transfer(g_dev->client->adapter, msgs, 2);
195         if (ret < 0)
196                 pr_err("msg %s i2c read error: %d\n", __func__, ret);
197
198         return ret;
199 }
200
201 static int ft5x0x_i2c_txdata(char *txdata, int length)
202 {
203         int ret;
204
205         struct i2c_msg msg[] = {
206                 {
207                         .addr   = g_dev->client->addr,
208                         .flags  = 0,
209                         .len    = length,
210                         .buf    = txdata,
211                         .scl_rate = 200 * 1000,
212                 },
213         };
214
215         ret = i2c_transfer(g_dev->client->adapter, msg, 1);
216         if (ret < 0)
217                 pr_err("%s i2c write error: %d\n", __func__, ret);
218
219         return ret;
220 }
221
222 static int ft5x0x_set_reg(u8 addr, u8 para)
223 {
224     u8 buf[3];
225     int ret = -1;
226
227     buf[0] = addr;
228     buf[1] = para;
229     ret = ft5x0x_i2c_txdata(buf, 2);
230     if (ret < 0) {
231         pr_err("write reg failed! %#x ret: %d", buf[0], ret);
232         return -1;
233     }
234     
235     return 0;
236 }
237
238 static int ft5x0x_read_data(void)
239 {
240         struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
241         struct ts_event *event = &data->event;
242
243         u8 buf[32]= {0};//set send addr to 0x00 *important*
244         int ret = -1;
245        int key;
246
247
248         if(Motoenble)
249         {
250                 if(!MotoStart)
251                 {
252                         //printk("the moto is enable!\n");
253                         //gpio_enable1();
254                         MotoStart =1;
255                 }
256         }
257
258
259                 ret = ft5x0x_i2c_rxdata(buf, 32);
260
261         if (ret < 0) {
262                         printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
263                         return ret;
264                 }
265 #if 0   // Just for debug
266                 u8 uc_ecc;
267                 int i;
268                 uc_ecc = buf[2];
269                 for (i=0; i<5; i++)
270                 {
271                         uc_ecc ^= buf[3+6*i];
272                         uc_ecc ^= buf[4+6*i];
273                         uc_ecc ^= buf[5+6*i];
274                         uc_ecc ^= buf[6+6*i];
275                 }
276 //              if (uc_ecc == buf[1])  break;
277 //      }
278
279
280         if (uc_ecc != buf[1])
281         {
282                 printk("ecc check error uc_ecc=0x%x, buf[1]=0x%x.\n",uc_ecc, buf[1]);
283                 return 1;
284         }
285 #endif
286
287
288         memset(event, ~0x00, sizeof(struct ts_event));
289
290 #if USE_POINT
291         event->touch_point = buf[2] & 0x07;// 0000 1111
292 #else
293         event->touch_point = buf[2] >>4;// 0000 1111
294 #endif
295    if (event->touch_point == 0) {
296                 rember_point_into = false;
297 #ifdef LONGPRESS_LOCK_SPECKEY
298                 if(Origin2LockPressCnt)
299                 {//说明按到了search键
300                         if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
301                         {//没有长按
302                                 if(lockflag ==0)
303                                 {//键盘没锁
304                                         input_report_key(data->input_dev,KEY_SEARCH,1);   //158 //MENU
305                                         input_sync(data->input_dev);
306                                         input_report_key(data->input_dev,KEY_SEARCH,0);   //158 //MENU
307                                         input_sync(data->input_dev);
308                                         //printk("menu is up ==========================\n");
309                                 }
310                         }
311                         else
312                         {
313                                 //printk("release long press !!!!!!!!!!!!!!!!!\n");
314                                 input_report_key(data->input_dev, KEY_LOCK, 0);
315                                 //printk("up::KEY_LOCK: %d\n", KEY_LOCK);
316                                 input_sync(data->input_dev);
317                         }
318                         Origin2LockPressCnt = 0;
319                         touch_key_hold_press = 0;
320                 }
321 #endif
322 #ifdef NEW_PAL_DRV
323                 if(touch_key_hold_press)
324                 {
325                         touch_key_hold_press = 0;
326                         for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
327                         {
328                                 if(touch_key_press[key])
329                                 {
330                                         input_report_key(data->input_dev, touch_key_code[key], 0);
331                                         touch_key_press[key] = 0;
332                                          input_sync(data->input_dev);
333                                         //printk("up::KEY: %d\n", touch_key_code[key]);
334                                 }
335                         }
336                 }
337 #endif
338                 gpress = 0;
339                 MotoStart =0;
340                 //printk("release point !!!!!!!!!!!!!!!!!\n");
341                 //ft5x0x_ts_release(data);
342                 #ifdef CHECK_KEY
343                 //event->penddown = Release;
344                 #endif
345                 return 0;
346         }
347
348 #ifdef CONFIG_FT5X0X_MULTITOUCH
349     switch (event->touch_point) {
350                 case 5:
351                         event->point[4].status = (buf[0x1b] & 0xc0)>>6;
352                         event->point[4].id = (buf[0x1d] & 0xf0)>>4;
353                         event->point[4].x = (s16)(buf[0x1b] & 0x07)<<8 | (s16)buf[0x1c];
354                         event->point[4].y = (s16)(buf[0x1d] & 0x07)<<8 | (s16)buf[0x1e];
355                 case 4:
356                         event->point[3].status = (buf[0x15] & 0xc0)>>6;
357                         event->point[3].id = (buf[0x17] & 0xf0)>>4;
358                         event->point[3].x = (s16)(buf[0x15] & 0x07)<<8 | (s16)buf[0x16];
359                         event->point[3].y = (s16)(buf[0x17] & 0x07)<<8 | (s16)buf[0x18];
360                 case 3:
361                         event->point[2].status = (buf[0x0f] & 0xc0)>>6;
362                         event->point[2].id = (buf[0x11] & 0xf0)>>4;
363                         event->point[2].x = (s16)(buf[0x0f] & 0x07)<<8 | (s16)buf[0x10];
364                         event->point[2].y = (s16)(buf[0x11] & 0x07)<<8 | (s16)buf[0x12];
365                 case 2:
366                         event->point[1].status = (buf[0x09] & 0xc0)>>6;
367                         event->point[1].id = (buf[0x0b] & 0xf0)>>4;
368                         event->point[1].x = (s16)(buf[0x09] & 0x07)<<8 | (s16)buf[0x0a];
369                         event->point[1].y = (s16)(buf[0x0b] & 0x07)<<8 | (s16)buf[0x0c];
370                 case 1:
371                         event->point[0].status = (buf[0x03] & 0xc0)>>6;
372                         event->point[0].id = (buf[0x05] & 0xf0)>>4;
373
374                         event->point[0].y = (s16)(buf[0x03] & 0x0f)<<8 | (s16)buf[0x04];
375                         event->point[0].x = (s16)(buf[0x05] & 0x0f)<<8 | (s16)buf[0x06];
376                         event->point[0].x = 480 - event->point[0].x;
377                         if(event->point[0].x < 0){
378                                 event->point[0].x = 0;
379                         }
380
381         default:
382                     return 0;
383         }
384 #endif
385 }
386
387 static void ft5x0x_report_value(void)
388 {
389         struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
390         struct ts_event *event = &data->event;
391         u8 j;
392         u8 i = 0;
393         int key_id = 0xff;
394 #if 0
395         printk("point is %d x0 is %d y0 is %d\n",
396                         //P1 status is %x ID1 is %x x1 is 0x%x y1 is 0x%x\n\n",
397                                         event->touch_point,
398                                         //event->point[0].status,       //event->point[0].id,
399                                         event->point[0].y, event->point[0].x);
400                                         //event->point[1].status, event->point[1].id,
401                                         //event->point[1].x, event->point[1].y);
402 #endif
403 #if USE_POINT
404         down_table = 0;
405
406                 for(i=0; i<event->touch_point; i++) {
407                 //================
408                 //printk("event->x[%d]:%d,event->y[%d]:%d\n", i,event->x[i],i,event->y[i]);
409                 if((event->point[i].y > KEY_MIN_X) && (debug1)/*&&(posx[i]<KEY_MAX_X)*/)
410                                 {
411                                  for(j=0;j<KEY_NUM;j++)
412                                    {
413                                                 //printk("i === %d,event->point[i].x==%d,event->point[i].y===%d\n",i,event->point[i].x,event->point[i].y);
414                                       if((event->point[i].x >touch_key_min[j])&&(event->point[i].x <touch_key_max[j]))
415                                       {
416                                           key_id = j;
417                                                 //  printk("touch_key_hold_press = %d\n",touch_key_hold_press);
418                                               if((touch_key_press[key_id] == 0) && (touch_key_hold_press == 0))
419                                               {
420                                          #ifdef  LONGPRESS_LOCK_SPECKEY
421                                               //        printk("touch_key_code[%d]:%d\n",key_id,touch_key_code[key_id]);
422
423                                                 if(touch_key_code[key_id] == ORIGIN_KEY)
424                                                         {      /*
425                                                                 if(++Origin2LockPressCnt>LOCK_LONG_PRESS_CNT)
426                                                                         {
427                                                                         Origin2LockPressCnt = LOCK_LONG_PRESS_CNT + 2;
428                                                                         input_report_key(data->input_dev, KEY_LOCK, 1);
429                                                                         touch_key_hold_press = 1;
430                                                                         if(lockflag)
431                                                                                 lockflag =0;
432                                                                         else
433                                                                                 lockflag =1;
434                                                                         }*/
435                                                                         Origin2LockPressCnt=1;
436                                                                 break;
437                                                                 }
438                                                    //if(lockflag)
439                                                                 //goto out;
440                                                 #endif
441                                                input_report_key(data->input_dev, touch_key_code[key_id], 1);
442                                                touch_key_press[key_id] = 1;
443                                                touch_key_hold_press = 1;
444                                              //  printk("down::KEY: %d\n", touch_key_code[key_id]);
445                                               }
446                                                   break;
447                                       }
448                                    }
449                                 }
450                 else
451                                 {
452                                 input_mt_slot(data->input_dev, event->point[i].id);
453
454                                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
455
456                                         down_table |= 1 << event->point[i].id;
457                                         input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 100);
458                                         input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
459                                         input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
460                                         input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100);
461                                   // printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i].id,event->point[i].x,event->point[i].y);
462
463                                 }
464
465
466                         }
467
468         for(i=0; i<MAX_CONTACTS; i++) {
469                 if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
470                 {
471                         input_mt_slot(data->input_dev, i);
472                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
473                          /*printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i]
474 .id,event->point[i].y,event->point[i].x);*/
475                 }
476         }
477         up_table = ~down_table;
478          input_sync(data->input_dev);
479 #else
480
481         for(i=0; i<event->touch_point; i++) {
482                 if(event->point[i].status == 0 || event->point[i].status == 2 ) {
483                         input_mt_slot(data->input_dev, event->point[i].id);
484                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
485                         input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 200);
486                         input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
487                         input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
488                         input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100);
489                 }
490                 else if(event->point[i].status == 1) {
491                         input_mt_slot(data->input_dev, event->point[i].id);
492                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
493                 }
494         }
495         input_sync(data->input_dev);
496 #endif
497
498
499
500
501  out:
502  ;
503 #ifdef CHECK_KEY
504                                          data->timer.expires    = jiffies +8;
505                                         add_timer(&data->timer);
506                                         down_table = 0;
507
508 #endif
509
510
511
512
513 }       /*end ft5x0x_report_value*/
514
515 static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
516 {
517         int ret = -1;
518         //printk("==ft5x0x_ts_pen_work =\n");
519         ret = ft5x0x_read_data();
520         if (ret == 0) {
521                 ft5x0x_report_value();
522         }
523   enable_irq(g_dev->irq);
524 }
525
526 static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
527 {
528         struct ft5x0x_ts_dev *ft5x0x_ts = dev_id;
529
530 #ifdef CHECK_KEY
531
532                         del_timer(&ft5x0x_ts->timer);
533 #endif
534         disable_irq_nosync(g_dev->irq);
535   //printk("==ft5x0x_ts_interrupt =\n");
536         queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
537
538         return IRQ_HANDLED;
539 }
540
541 #ifdef CONFIG_HAS_EARLYSUSPEND
542 static void ft5x0x_ts_suspend(struct early_suspend *handler)
543 {
544         int ret;
545         struct ft5x0x_ts_dev *ts;
546         ts =  container_of(handler, struct ft5x0x_ts_dev, early_suspend);
547         
548         if(ts->irq)
549                 disable_irq_nosync(ts->irq);
550
551         ret = cancel_work_sync(&ts->pen_event_work);
552         if (ret && ts->irq) /* if work was pending disable-count is now 2 */
553                 enable_irq(ts->irq);
554         // ==set mode ==,
555 //  ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE);
556 }
557
558 static void ft5x0x_ts_resume(struct early_suspend *handler)
559 {
560         struct ft5x0x_ts_dev *ts;
561         ts =  container_of(handler, struct ft5x0x_ts_dev, early_suspend);
562         // wake the mode
563 //      gpio_direction_output(RK29_PIN6_PC3, 0);
564 //      gpio_set_value(RK29_PIN6_PC3,GPIO_LOW);
565 //      msleep(50);
566 //      gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH);
567
568 #if USE_POINT
569         down_table      = 0;
570         up_table        = ~0;
571 #endif
572
573         if(ts->irq)
574                 enable_irq(ts->irq);
575 }
576 #endif  //CONFIG_HAS_EARLYSUSPEND
577 #ifdef CHECK_KEY
578 static void Touch_timer_release(unsigned long ft_ts_pdev)
579 {
580
581         struct ft5x0x_ts_dev *data = ft_ts_pdev;
582         int key, i=0;
583         int inflag =0;
584         /*if(rember_point_into)
585         {
586                for(i=0;i<MAX_CONTACTS;i++)
587                    {
588                       printk("hand to modefy with up !!!!!!\n");
589 #if   1
590                        input_mt_slot(data->input_dev, i);
591                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
592 #endif
593                   }
594
595         input_sync(data->input_dev);
596         rember_point_into = true;
597         }*/
598
599   for(i=0; i<MAX_CONTACTS; i++) {
600                 if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
601                 {
602                       printk("%d is up !!!!!!\n",i);
603                         input_mt_slot(data->input_dev, i);
604                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
605                                 inflag =1;
606                 }
607                 }
608   if(inflag==1)input_sync(data->input_dev);
609     inflag = 0;
610 //===================================
611 #ifdef LONGPRESS_LOCK_SPECKEY
612
613                 if(Origin2LockPressCnt)
614                 {//说明按到了search键
615                         if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
616                         {//没有长按
617                                 //if(lockflag ==0)
618                                 {//键盘没锁
619                                         input_report_key(data->input_dev,KEY_SEARCH,1);   //158 //MENU
620                                         input_sync(data->input_dev);
621                                         input_report_key(data->input_dev,KEY_SEARCH,0);   //158 //MENU
622                                         input_sync(data->input_dev);
623                                         //printk("menu is up ==========================\n");
624                                 }
625                         }
626                         else
627                         {
628                                 //printk("release long press !!!!!!!!!!!!!!!!!\n");
629                                 //input_report_key(data->input_dev, KEY_LOCK, 0);
630                                 //printk("up::KEY_LOCK: %d\n", KEY_LOCK);
631                                 //input_sync(data->input_dev);
632                         }
633                         Origin2LockPressCnt = 0;
634                         touch_key_hold_press = 0;
635                 }
636 #endif
637 #ifdef NEW_PAL_DRV
638                 if((touch_key_hold_press)&&(debug1))
639                 {
640                         touch_key_hold_press = 0;
641                         for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
642                         {
643                                 if(touch_key_press[key])
644                                 {
645                                         input_report_key(data->input_dev, touch_key_code[key], 0);
646                                         touch_key_press[key] = 0;
647                                         input_sync(data->input_dev);
648                                         //printk("up::KEY: %d\n", touch_key_code[key]);
649                                 }
650                         }
651                 }
652 #endif
653
654 //===================================
655         
656         
657         
658 }
659
660 #endif
661
662 static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
663 {
664         struct ft5x0x_ts_dev *ft5x0x_ts;
665         struct ft5x0x_platform_data *pdata = pdata = client->dev.platform_data;
666         struct input_dev *input_dev;
667         int err = 0;
668         u8 buf_w[1];
669         u8 buf_r[1];
670         u8 buf[3]={0};  //w++
671
672
673         if (pdata == NULL) {
674                 dev_err(&client->dev, "%s: platform data is null\n", __func__);
675                 goto exit_platform_data_null;
676         }
677
678         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
679                 err = -ENODEV;
680                 goto exit_check_functionality_failed;
681         }
682
683         if (pdata->init_platform_hw)                              
684                 pdata->init_platform_hw();
685
686
687        err_ft5X06=i2c_master_reg8_recv(client, 0x02, buf, 2, 200*1000);  //w++6
688         //err_ft5X06 = i2c_master_reg8_recv(client, 0x00, buf, 2, 200 * 1000);  //w++5
689
690         //buf[0] = 0x00;
691         //err_ft5X06 = ft5x0x_i2c_rxdata(buf,1);
692         if(err_ft5X06<0){
693                 printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,err);
694                 return err;
695         }
696
697
698         ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
699         if (!ft5x0x_ts) {
700                 err = -ENOMEM;
701                 goto exit_alloc_data_failed;
702         }
703
704         input_dev = input_allocate_device();
705         if (!input_dev) {
706                 err = -ENOMEM;
707                 dev_err(&client->dev, "failed to allocate input device\n");
708                 goto exit_input_dev_alloc_failed;
709         }
710
711         ft5x0x_ts->input_dev = input_dev;
712         ft5x0x_ts->client = client;
713         ft5x0x_ts->irq = client->irq;
714
715         __set_bit(EV_ABS, input_dev->evbit);
716         __set_bit(EV_KEY, input_dev->evbit);
717         __set_bit(EV_REP,  input_dev->evbit);
718         __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
719         set_bit(ABS_MT_POSITION_X, input_dev->absbit);
720         set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
721         set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
722         set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
723
724         input_mt_init_slots(input_dev, MAX_CONTACTS);
725
726         input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
727         input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
728         input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
729         input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
730 #if  CONFIG_TOUCH_PANEL_KEY
731         set_bit(KEY_HOMEPAGE, input_dev->keybit);
732         set_bit(KEY_MENU, input_dev->keybit);
733         set_bit(KEY_BACK, input_dev->keybit);
734         set_bit(KEY_SEARCH, input_dev->keybit);
735 #ifdef LONGPRESS_LOCK_SPECKEY
736         //      set_bit(KEY_SEARCH, input_dev->keybit);
737         set_bit(KEY_LOCK, input_dev->keybit);
738 #endif
739 #endif
740
741         input_dev->name         = FT5X0X_NAME;          //dev_name(&client->dev)
742         err = input_register_device(input_dev);
743         if (err) {
744                 dev_err(&client->dev,
745                 "ft5x0x_ts_probe: failed to register input device: %s\n",
746                 dev_name(&client->dev));
747                 goto exit_input_register_device_failed;
748         }
749
750         g_dev = ft5x0x_ts;
751
752         i2c_set_clientdata(client, ft5x0x_ts);
753         INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
754         ft5x0x_ts->ts_workqueue = create_workqueue(FT5X0X_NAME);
755         if (!ft5x0x_ts->ts_workqueue) {
756                 err = -ESRCH;
757                 goto exit_create_singlethread;
758         }
759
760   //if(pdata->init_platform_hw)
761      // pdata->init_platform_hw();
762
763   //ft5x0x_set_reg(0x80,0x64);
764
765   if(!ft5x0x_ts->irq)
766   {
767     dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n");
768     return -ENODEV;
769   }
770   else
771   {
772     ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
773   }
774
775   err = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING/*IRQF_DISABLED*/, "ft5x0x_ts", ft5x0x_ts);
776         if (err < 0) {
777                 dev_err(&client->dev, "ft5x0x_probe: request irq failed\n");
778                 goto exit_irq_request_failed;
779         }
780
781         disable_irq_nosync(g_dev->irq);
782
783 #ifdef CONFIG_HAS_EARLYSUSPEND
784         ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
785         ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_suspend;
786         ft5x0x_ts->early_suspend.resume = ft5x0x_ts_resume;
787         register_early_suspend(&ft5x0x_ts->early_suspend);
788 #endif
789 #ifdef CHECK_KEY
790                 setup_timer(&ft5x0x_ts->timer, Touch_timer_release, (unsigned long)ft5x0x_ts);
791 #endif
792
793 //wake the CTPM
794 //      __gpio_as_output(GPIO_FT5X0X_WAKE);
795 //      __gpio_clear_pin(GPIO_FT5X0X_WAKE);             //set wake = 0,base on system
796 //       msleep(100);
797 //      __gpio_set_pin(GPIO_FT5X0X_WAKE);                       //set wake = 1,base on system
798 //      msleep(100);
799 //      ft5x0x_set_reg(0x88, 0x05); //5, 6,7,8
800 //      ft5x0x_set_reg(0x80, 30);
801 //      msleep(50);
802
803         buf_w[0] = 6;
804         err = ft5x0x_set_reg(0x88,6);
805         //ft5x0x_i2c_txdata(0x88, buf_w, 1);    /* adjust frequency 60Hz */
806
807         buf_r[0] = 0x88;
808         err = ft5x0x_i2c_rxdata(buf_r,1);
809
810     enable_irq(g_dev->irq);
811
812 printk("==ft5x0x_ts_probe = %0x\n", buf_r[0]);
813
814     return 0;
815
816 exit_input_register_device_failed:
817         input_free_device(input_dev);
818 exit_input_dev_alloc_failed:
819         free_irq(client->irq, ft5x0x_ts);
820         //free_irq(IRQ_EINT(6), ft5x0x_ts);
821 exit_irq_request_failed:
822 exit_platform_data_null:
823         cancel_work_sync(&ft5x0x_ts->pen_event_work);
824         destroy_workqueue(ft5x0x_ts->ts_workqueue);
825 exit_create_singlethread:
826         printk("==singlethread error =\n");
827         i2c_set_clientdata(client, NULL);
828         kfree(ft5x0x_ts);
829 exit_alloc_data_failed:
830 exit_check_functionality_failed:
831         return err;
832 }
833
834 static int __devexit ft5x0x_ts_remove(struct i2c_client *client)
835 {
836         struct ft5x0x_ts_dev *ft5x0x_ts = i2c_get_clientdata(client);
837         unregister_early_suspend(&ft5x0x_ts->early_suspend);
838         free_irq(client->irq, ft5x0x_ts);
839         input_unregister_device(ft5x0x_ts->input_dev);
840         kfree(ft5x0x_ts);
841         cancel_work_sync(&ft5x0x_ts->pen_event_work);
842         destroy_workqueue(ft5x0x_ts->ts_workqueue);
843         i2c_set_clientdata(client, NULL);
844         return 0;
845 }
846
847 static const struct i2c_device_id ft5x0x_ts_id[] = {
848         { FT5X0X_NAME, 0 },{ }
849 };
850 MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);
851
852 static struct i2c_driver ft5x0x_ts_driver = {
853         .probe          = ft5x0x_ts_probe,
854         .remove         = __devexit_p(ft5x0x_ts_remove),
855         .id_table       = ft5x0x_ts_id,
856         .driver = {
857                 .name   = FT5X0X_NAME,
858                 .owner  = THIS_MODULE,
859         },
860 };
861 #ifdef LONGPRESS_LOCK_SPECKEY
862 static DRIVER_ATTR(get_lock_status, 0777, glock_status_show, NULL);
863 #endif
864 static DRIVER_ATTR(MOTOenable, 0666, Moto_status, Moto_control);
865
866 static int __init ft5x0x_ts_init(void)
867 {
868         int ret;
869 ret = i2c_add_driver(&ft5x0x_ts_driver);
870         if (ret)
871         {
872             printk("Register 5406_ts driver failed.\n");
873             return ret;
874         }
875 #ifdef LONGPRESS_LOCK_SPECKEY
876         if(err_ft5X06>=0)   //w++
877           ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status);
878 #endif
879         if(err_ft5X06>=0)   //
880         ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
881            return ret;
882 }
883
884 static void __exit ft5x0x_ts_exit(void)
885 {
886         i2c_del_driver(&ft5x0x_ts_driver);
887 #ifdef LONGPRESS_LOCK_SPECKEY
888         driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status);
889 #endif
890         driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
891 }
892
893 module_init(ft5x0x_ts_init);
894 module_exit(ft5x0x_ts_exit);
895
896 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
897 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");
898 MODULE_LICENSE("GPL");
899