fbdev/fb_notify: fix blank_mode pointer crash
[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 ft5x0x_platform_data *pdata = g_dev->client->dev.platform_data;
242         struct ts_event *event = &data->event;
243         u16 i = 0;
244         u8 buf[32]= {0};//set send addr to 0x00 *important*
245         int ret = -1;
246        int key;
247
248
249         if(Motoenble)
250         {
251                 if(!MotoStart)
252                 {
253                         //printk("the moto is enable!\n");
254                         //gpio_enable1();
255                         MotoStart =1;
256                 }
257         }
258
259
260                 ret = ft5x0x_i2c_rxdata(buf, 32);
261
262         if (ret < 0) {
263                         printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
264                         return ret;
265                 }
266 #if 0   // Just for debug
267                 u8 uc_ecc;
268                 int i;
269                 uc_ecc = buf[2];
270                 for (i=0; i<5; i++)
271                 {
272                         uc_ecc ^= buf[3+6*i];
273                         uc_ecc ^= buf[4+6*i];
274                         uc_ecc ^= buf[5+6*i];
275                         uc_ecc ^= buf[6+6*i];
276                 }
277 //              if (uc_ecc == buf[1])  break;
278 //      }
279
280
281         if (uc_ecc != buf[1])
282         {
283                 printk("ecc check error uc_ecc=0x%x, buf[1]=0x%x.\n",uc_ecc, buf[1]);
284                 return 1;
285         }
286 #endif
287
288
289         memset(event, ~0x00, sizeof(struct ts_event));
290
291 #if USE_POINT
292         event->touch_point = buf[2] & 0x07;// 0000 1111
293 #else
294         event->touch_point = buf[2] >>4;// 0000 1111
295 #endif
296    if (event->touch_point == 0) {
297                 rember_point_into = false;
298 #ifdef LONGPRESS_LOCK_SPECKEY
299                 if(Origin2LockPressCnt)
300                 {//说明按到了search键
301                         if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
302                         {//没有长按
303                                 if(lockflag ==0)
304                                 {//键盘没锁
305                                         input_report_key(data->input_dev,KEY_SEARCH,1);   //158 //MENU
306                                         input_sync(data->input_dev);
307                                         input_report_key(data->input_dev,KEY_SEARCH,0);   //158 //MENU
308                                         input_sync(data->input_dev);
309                                         //printk("menu is up ==========================\n");
310                                 }
311                         }
312                         else
313                         {
314                                 //printk("release long press !!!!!!!!!!!!!!!!!\n");
315                                 input_report_key(data->input_dev, KEY_LOCK, 0);
316                                 //printk("up::KEY_LOCK: %d\n", KEY_LOCK);
317                                 input_sync(data->input_dev);
318                         }
319                         Origin2LockPressCnt = 0;
320                         touch_key_hold_press = 0;
321                 }
322 #endif
323 #ifdef NEW_PAL_DRV
324                 if(touch_key_hold_press)
325                 {
326                         touch_key_hold_press = 0;
327                         for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
328                         {
329                                 if(touch_key_press[key])
330                                 {
331                                         input_report_key(data->input_dev, touch_key_code[key], 0);
332                                         touch_key_press[key] = 0;
333                                          input_sync(data->input_dev);
334                                         //printk("up::KEY: %d\n", touch_key_code[key]);
335                                 }
336                         }
337                 }
338 #endif
339                 gpress = 0;
340                 MotoStart =0;
341                 //printk("release point !!!!!!!!!!!!!!!!!\n");
342                 //ft5x0x_ts_release(data);
343                 #ifdef CHECK_KEY
344                 //event->penddown = Release;
345                 #endif
346                 return 0;
347         }
348
349 #ifdef CONFIG_FT5X0X_MULTITOUCH
350     switch (event->touch_point) {
351                 case 5:
352                         event->point[4].status = (buf[0x1b] & 0xc0)>>6;
353                         event->point[4].id = (buf[0x1d] & 0xf0)>>4;
354                         event->point[4].x = (s16)(buf[0x1b] & 0x07)<<8 | (s16)buf[0x1c];
355                         event->point[4].y = (s16)(buf[0x1d] & 0x07)<<8 | (s16)buf[0x1e];
356                 case 4:
357                         event->point[3].status = (buf[0x15] & 0xc0)>>6;
358                         event->point[3].id = (buf[0x17] & 0xf0)>>4;
359                         event->point[3].x = (s16)(buf[0x15] & 0x07)<<8 | (s16)buf[0x16];
360                         event->point[3].y = (s16)(buf[0x17] & 0x07)<<8 | (s16)buf[0x18];
361                 case 3:
362                         event->point[2].status = (buf[0x0f] & 0xc0)>>6;
363                         event->point[2].id = (buf[0x11] & 0xf0)>>4;
364                         event->point[2].x = (s16)(buf[0x0f] & 0x07)<<8 | (s16)buf[0x10];
365                         event->point[2].y = (s16)(buf[0x11] & 0x07)<<8 | (s16)buf[0x12];
366                 case 2:
367                         event->point[1].status = (buf[0x09] & 0xc0)>>6;
368                         event->point[1].id = (buf[0x0b] & 0xf0)>>4;
369                         event->point[1].x = (s16)(buf[0x09] & 0x07)<<8 | (s16)buf[0x0a];
370                         event->point[1].y = (s16)(buf[0x0b] & 0x07)<<8 | (s16)buf[0x0c];
371                 case 1:
372                         event->point[0].status = (buf[0x03] & 0xc0)>>6;
373                         event->point[0].id = (buf[0x05] & 0xf0)>>4;
374                         event->point[0].x = (s16)(buf[0x03] & 0x0f)<<8 | (s16)buf[0x04];
375                         event->point[0].y = (s16)(buf[0x05] & 0x0f)<<8 | (s16)buf[0x06];
376                         
377                         if(event->point[0].x < 0){
378                                 event->point[0].x = 0;
379                         }
380
381
382                 for(i=0; i<event->touch_point; i++)
383                 {
384                         if(pdata->xy_swap)
385                         {
386                                 swap(event->point[i].x, event->point[i].y);
387                         }
388
389                         if(pdata->x_revert)
390                         {
391                                 event->point[i].x = pdata->max_x - event->point[i].x;   
392                         }
393
394                         if(pdata->y_revert)
395                         {
396                                 event->point[i].y = pdata->max_y - event->point[i].y;
397                         }
398                 }
399
400                 default:
401                     return 0;
402         }
403
404         
405 #endif
406 }
407
408 static void ft5x0x_report_value(void)
409 {
410         struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
411         struct ft5x0x_platform_data *pdata = g_dev->client->dev.platform_data;
412         struct ts_event *event = &data->event;
413         u8 j;
414         u8 i = 0;
415         int key_id = 0xff;
416 #if 0
417         printk("point is %d x0 is %d y0 is %d\n",
418                         //P1 status is %x ID1 is %x x1 is 0x%x y1 is 0x%x\n\n",
419                                         event->touch_point,
420                                         //event->point[0].status,       //event->point[0].id,
421                                         event->point[0].y, event->point[0].x);
422                                         //event->point[1].status, event->point[1].id,
423                                         //event->point[1].x, event->point[1].y);
424 #endif
425 #if USE_POINT
426         down_table = 0;
427
428                 for(i=0; i<event->touch_point; i++) {
429                 //================
430                 //printk("event->x[%d]:%d,event->y[%d]:%d\n", i,event->x[i],i,event->y[i]);
431                 if((event->point[i].y > pdata->key_min_x) && (debug1)/*&&(posx[i]<KEY_MAX_X)*/)
432                                 {
433                                  for(j=0;j<KEY_NUM;j++)
434                                    {
435                                                 //printk("i === %d,event->point[i].x==%d,event->point[i].y===%d\n",i,event->point[i].x,event->point[i].y);
436                                       if((event->point[i].x >touch_key_min[j])&&(event->point[i].x <touch_key_max[j]))
437                                       {
438                                           key_id = j;
439                                                 //  printk("touch_key_hold_press = %d\n",touch_key_hold_press);
440                                               if((touch_key_press[key_id] == 0) && (touch_key_hold_press == 0))
441                                               {
442                                          #ifdef  LONGPRESS_LOCK_SPECKEY
443                                               //        printk("touch_key_code[%d]:%d\n",key_id,touch_key_code[key_id]);
444
445                                                 if(touch_key_code[key_id] == ORIGIN_KEY)
446                                                         {      /*
447                                                                 if(++Origin2LockPressCnt>LOCK_LONG_PRESS_CNT)
448                                                                         {
449                                                                         Origin2LockPressCnt = LOCK_LONG_PRESS_CNT + 2;
450                                                                         input_report_key(data->input_dev, KEY_LOCK, 1);
451                                                                         touch_key_hold_press = 1;
452                                                                         if(lockflag)
453                                                                                 lockflag =0;
454                                                                         else
455                                                                                 lockflag =1;
456                                                                         }*/
457                                                                         Origin2LockPressCnt=1;
458                                                                 break;
459                                                                 }
460                                                    //if(lockflag)
461                                                                 //goto out;
462                                                 #endif
463                                                input_report_key(data->input_dev, touch_key_code[key_id], 1);
464                                                touch_key_press[key_id] = 1;
465                                                touch_key_hold_press = 1;
466                                              //  printk("down::KEY: %d\n", touch_key_code[key_id]);
467                                               }
468                                                   break;
469                                       }
470                                    }
471                                 }
472                 else
473                                 {
474                                 input_mt_slot(data->input_dev, event->point[i].id);
475
476                                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
477
478                                         down_table |= 1 << event->point[i].id;
479                                         input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1);
480                                         input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
481                                         input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
482                                         input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
483                                    //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);
484
485                                 }
486
487
488                         }
489
490         for(i=0; i<MAX_CONTACTS; i++) {
491                 if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
492                 {
493                         input_mt_slot(data->input_dev, i);
494                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
495                          /*printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i]
496 .id,event->point[i].y,event->point[i].x);*/
497                 }
498         }
499         up_table = ~down_table;
500          input_sync(data->input_dev);
501 #else
502
503         for(i=0; i<event->touch_point; i++) {
504                 if(event->point[i].status == 0 || event->point[i].status == 2 ) {
505                         input_mt_slot(data->input_dev, event->point[i].id);
506                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
507                         input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1);
508                         input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x);
509                         input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y);
510                         input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
511                 }
512                 else if(event->point[i].status == 1) {
513                         input_mt_slot(data->input_dev, event->point[i].id);
514                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
515                 }
516         }
517         input_sync(data->input_dev);
518 #endif
519
520
521
522
523  out:
524  ;
525 #ifdef CHECK_KEY
526                                          data->timer.expires    = jiffies +8;
527                                         add_timer(&data->timer);
528                                         down_table = 0;
529
530 #endif
531
532
533
534
535 }       /*end ft5x0x_report_value*/
536
537 static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
538 {
539         int ret = -1;
540         //printk("==ft5x0x_ts_pen_work =\n");
541         ret = ft5x0x_read_data();
542         if (ret == 0) {
543                 ft5x0x_report_value();
544         }
545   enable_irq(g_dev->irq);
546 }
547
548 static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
549 {
550         struct ft5x0x_ts_dev *ft5x0x_ts = dev_id;
551
552 #ifdef CHECK_KEY
553
554                         del_timer(&ft5x0x_ts->timer);
555 #endif
556         disable_irq_nosync(g_dev->irq);
557   //printk("==ft5x0x_ts_interrupt =\n");
558         queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
559
560         return IRQ_HANDLED;
561 }
562
563 #ifdef CONFIG_HAS_EARLYSUSPEND
564 static void ft5x0x_ts_suspend(struct early_suspend *handler)
565 {
566         int ret;
567         struct ft5x0x_ts_dev *ts;
568         ts =  container_of(handler, struct ft5x0x_ts_dev, early_suspend);
569         
570         if(ts->irq)
571                 disable_irq_nosync(ts->irq);
572
573         ret = cancel_work_sync(&ts->pen_event_work);
574         if (ret && ts->irq) /* if work was pending disable-count is now 2 */
575                 enable_irq(ts->irq);
576         // ==set mode ==,
577 //  ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE);
578 }
579
580 static void ft5x0x_ts_resume(struct early_suspend *handler)
581 {
582         struct ft5x0x_ts_dev *ts;
583         ts =  container_of(handler, struct ft5x0x_ts_dev, early_suspend);
584         // wake the mode
585 //      gpio_direction_output(RK29_PIN6_PC3, 0);
586 //      gpio_set_value(RK29_PIN6_PC3,GPIO_LOW);
587 //      msleep(50);
588 //      gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH);
589
590 #if USE_POINT
591         down_table      = 0;
592         up_table        = ~0;
593 #endif
594
595         if(ts->irq)
596                 enable_irq(ts->irq);
597 }
598 #endif  //CONFIG_HAS_EARLYSUSPEND
599 #ifdef CHECK_KEY
600 static void Touch_timer_release(unsigned long ft_ts_pdev)
601 {
602
603         struct ft5x0x_ts_dev *data = ft_ts_pdev;
604         int key, i=0;
605         int inflag =0;
606         /*if(rember_point_into)
607         {
608                for(i=0;i<MAX_CONTACTS;i++)
609                    {
610                       printk("hand to modefy with up !!!!!!\n");
611 #if   1
612                        input_mt_slot(data->input_dev, i);
613                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
614 #endif
615                   }
616
617         input_sync(data->input_dev);
618         rember_point_into = true;
619         }*/
620
621   for(i=0; i<MAX_CONTACTS; i++) {
622                 if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
623                 {
624                       printk("%d is up !!!!!!\n",i);
625                         input_mt_slot(data->input_dev, i);
626                         input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
627                                 inflag =1;
628                 }
629                 }
630   if(inflag==1)input_sync(data->input_dev);
631     inflag = 0;
632 //===================================
633 #ifdef LONGPRESS_LOCK_SPECKEY
634
635                 if(Origin2LockPressCnt)
636                 {//说明按到了search键
637                         if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
638                         {//没有长按
639                                 //if(lockflag ==0)
640                                 {//键盘没锁
641                                         input_report_key(data->input_dev,KEY_SEARCH,1);   //158 //MENU
642                                         input_sync(data->input_dev);
643                                         input_report_key(data->input_dev,KEY_SEARCH,0);   //158 //MENU
644                                         input_sync(data->input_dev);
645                                         //printk("menu is up ==========================\n");
646                                 }
647                         }
648                         else
649                         {
650                                 //printk("release long press !!!!!!!!!!!!!!!!!\n");
651                                 //input_report_key(data->input_dev, KEY_LOCK, 0);
652                                 //printk("up::KEY_LOCK: %d\n", KEY_LOCK);
653                                 //input_sync(data->input_dev);
654                         }
655                         Origin2LockPressCnt = 0;
656                         touch_key_hold_press = 0;
657                 }
658 #endif
659 #ifdef NEW_PAL_DRV
660                 if((touch_key_hold_press)&&(debug1))
661                 {
662                         touch_key_hold_press = 0;
663                         for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
664                         {
665                                 if(touch_key_press[key])
666                                 {
667                                         input_report_key(data->input_dev, touch_key_code[key], 0);
668                                         touch_key_press[key] = 0;
669                                         input_sync(data->input_dev);
670                                         //printk("up::KEY: %d\n", touch_key_code[key]);
671                                 }
672                         }
673                 }
674 #endif
675
676 //===================================
677         
678         
679         
680 }
681
682 #endif
683
684 static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
685 {
686         struct ft5x0x_ts_dev *ft5x0x_ts;
687         struct ft5x0x_platform_data *pdata = client->dev.platform_data;
688         struct input_dev *input_dev;
689         int err = 0;
690         u8 buf_w[1];
691         u8 buf_r[1];
692         u8 buf[3]={0};  //w++
693
694
695         if (pdata == NULL) {
696                 dev_err(&client->dev, "%s: platform data is null\n", __func__);
697                 goto exit_platform_data_null;
698         }
699
700         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
701                 err = -ENODEV;
702                 goto exit_check_functionality_failed;
703         }
704
705         if (pdata->init_platform_hw)                              
706                 pdata->init_platform_hw();
707
708
709        err_ft5X06=i2c_master_reg8_recv(client, 0x02, buf, 2, 200*1000);  //w++6
710         //err_ft5X06 = i2c_master_reg8_recv(client, 0x00, buf, 2, 200 * 1000);  //w++5
711
712         //buf[0] = 0x00;
713         //err_ft5X06 = ft5x0x_i2c_rxdata(buf,1);
714         if(err_ft5X06<0){
715                 printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,err);
716                 return err;
717         }
718         
719         /*pdata->max_x and pdata->max_y should be read from touch*/
720
721         ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
722         if (!ft5x0x_ts) {
723                 err = -ENOMEM;
724                 goto exit_alloc_data_failed;
725         }
726
727         input_dev = input_allocate_device();
728         if (!input_dev) {
729                 err = -ENOMEM;
730                 dev_err(&client->dev, "failed to allocate input device\n");
731                 goto exit_input_dev_alloc_failed;
732         }
733
734         ft5x0x_ts->input_dev = input_dev;
735         ft5x0x_ts->client = client;
736         ft5x0x_ts->irq = client->irq;
737
738         __set_bit(EV_ABS, input_dev->evbit);
739         __set_bit(EV_KEY, input_dev->evbit);
740         __set_bit(EV_REP,  input_dev->evbit);
741         __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
742         set_bit(ABS_MT_POSITION_X, input_dev->absbit);
743         set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
744         set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
745         set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
746
747         input_mt_init_slots(input_dev, MAX_CONTACTS);
748
749         if((pdata->max_x <= 0) || (pdata->max_y <= 0))
750         {
751                 pdata->max_x = SCREEN_MAX_X;
752                 pdata->max_y = SCREEN_MAX_Y;
753         }
754
755         if(pdata->key_min_x <= 0)
756         {
757                 pdata->key_min_x = KEY_MIN_X;
758         }
759
760         input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, pdata->max_x, 0, 0);
761         input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, pdata->max_y, 0, 0);
762         input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
763         input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
764 #if  CONFIG_TOUCH_PANEL_KEY
765         set_bit(KEY_HOMEPAGE, input_dev->keybit);
766         set_bit(KEY_MENU, input_dev->keybit);
767         set_bit(KEY_BACK, input_dev->keybit);
768         set_bit(KEY_SEARCH, input_dev->keybit);
769 #ifdef LONGPRESS_LOCK_SPECKEY
770         //      set_bit(KEY_SEARCH, input_dev->keybit);
771         set_bit(KEY_LOCK, input_dev->keybit);
772 #endif
773 #endif
774
775         input_dev->name         = FT5X0X_NAME;          //dev_name(&client->dev)
776         err = input_register_device(input_dev);
777         if (err) {
778                 dev_err(&client->dev,
779                 "ft5x0x_ts_probe: failed to register input device: %s\n",
780                 dev_name(&client->dev));
781                 goto exit_input_register_device_failed;
782         }
783
784         g_dev = ft5x0x_ts;
785
786         i2c_set_clientdata(client, ft5x0x_ts);
787         INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
788         ft5x0x_ts->ts_workqueue = create_workqueue(FT5X0X_NAME);
789         if (!ft5x0x_ts->ts_workqueue) {
790                 err = -ESRCH;
791                 goto exit_create_singlethread;
792         }
793
794   //if(pdata->init_platform_hw)
795      // pdata->init_platform_hw();
796
797   //ft5x0x_set_reg(0x80,0x64);
798
799   if(!ft5x0x_ts->irq)
800   {
801     dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n");
802     return -ENODEV;
803   }
804   else
805   {
806     ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
807   }
808
809   err = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING/*IRQF_DISABLED*/, "ft5x0x_ts", ft5x0x_ts);
810         if (err < 0) {
811                 dev_err(&client->dev, "ft5x0x_probe: request irq failed\n");
812                 goto exit_irq_request_failed;
813         }
814
815         disable_irq_nosync(g_dev->irq);
816
817 #ifdef CONFIG_HAS_EARLYSUSPEND
818         ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
819         ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_suspend;
820         ft5x0x_ts->early_suspend.resume = ft5x0x_ts_resume;
821         register_early_suspend(&ft5x0x_ts->early_suspend);
822 #endif
823 #ifdef CHECK_KEY
824                 setup_timer(&ft5x0x_ts->timer, Touch_timer_release, (unsigned long)ft5x0x_ts);
825 #endif
826
827 //wake the CTPM
828 //      __gpio_as_output(GPIO_FT5X0X_WAKE);
829 //      __gpio_clear_pin(GPIO_FT5X0X_WAKE);             //set wake = 0,base on system
830 //       msleep(100);
831 //      __gpio_set_pin(GPIO_FT5X0X_WAKE);                       //set wake = 1,base on system
832 //      msleep(100);
833 //      ft5x0x_set_reg(0x88, 0x05); //5, 6,7,8
834 //      ft5x0x_set_reg(0x80, 30);
835 //      msleep(50);
836
837         buf_w[0] = 6;
838         err = ft5x0x_set_reg(0x88,6);
839         //ft5x0x_i2c_txdata(0x88, buf_w, 1);    /* adjust frequency 60Hz */
840
841         buf_r[0] = 0x88;
842         err = ft5x0x_i2c_rxdata(buf_r,1);
843
844     enable_irq(g_dev->irq);
845
846         printk("==ft5x0x_ts_probe = %0x,max_x=%d,max_y=%d\n", buf_r[0],pdata->max_x,pdata->max_y);
847
848     return 0;
849
850 exit_input_register_device_failed:
851         input_free_device(input_dev);
852 exit_input_dev_alloc_failed:
853         free_irq(client->irq, ft5x0x_ts);
854         //free_irq(IRQ_EINT(6), ft5x0x_ts);
855 exit_irq_request_failed:
856 exit_platform_data_null:
857         cancel_work_sync(&ft5x0x_ts->pen_event_work);
858         destroy_workqueue(ft5x0x_ts->ts_workqueue);
859 exit_create_singlethread:
860         printk("==singlethread error =\n");
861         i2c_set_clientdata(client, NULL);
862         kfree(ft5x0x_ts);
863 exit_alloc_data_failed:
864 exit_check_functionality_failed:
865         return err;
866 }
867
868 static int __devexit ft5x0x_ts_remove(struct i2c_client *client)
869 {
870         struct ft5x0x_ts_dev *ft5x0x_ts = i2c_get_clientdata(client);
871         unregister_early_suspend(&ft5x0x_ts->early_suspend);
872         free_irq(client->irq, ft5x0x_ts);
873         input_unregister_device(ft5x0x_ts->input_dev);
874         kfree(ft5x0x_ts);
875         cancel_work_sync(&ft5x0x_ts->pen_event_work);
876         destroy_workqueue(ft5x0x_ts->ts_workqueue);
877         i2c_set_clientdata(client, NULL);
878         return 0;
879 }
880
881 static const struct i2c_device_id ft5x0x_ts_id[] = {
882         { FT5X0X_NAME, 0 },{ }
883 };
884 MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);
885
886 static struct i2c_driver ft5x0x_ts_driver = {
887         .probe          = ft5x0x_ts_probe,
888         .remove         = __devexit_p(ft5x0x_ts_remove),
889         .id_table       = ft5x0x_ts_id,
890         .driver = {
891                 .name   = FT5X0X_NAME,
892                 .owner  = THIS_MODULE,
893         },
894 };
895 #ifdef LONGPRESS_LOCK_SPECKEY
896 static DRIVER_ATTR(get_lock_status, 0777, glock_status_show, NULL);
897 #endif
898 static DRIVER_ATTR(MOTOenable, 0666, Moto_status, Moto_control);
899
900 static int __init ft5x0x_ts_init(void)
901 {
902         int ret;
903 ret = i2c_add_driver(&ft5x0x_ts_driver);
904         if (ret)
905         {
906             printk("Register 5406_ts driver failed.\n");
907             return ret;
908         }
909 #ifdef LONGPRESS_LOCK_SPECKEY
910         if(err_ft5X06>=0)   //w++
911           ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status);
912 #endif
913         if(err_ft5X06>=0)   //
914         ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
915            return ret;
916 }
917
918 static void __exit ft5x0x_ts_exit(void)
919 {
920         i2c_del_driver(&ft5x0x_ts_driver);
921 #ifdef LONGPRESS_LOCK_SPECKEY
922         driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status);
923 #endif
924         driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
925 }
926
927 module_init(ft5x0x_ts_init);
928 module_exit(ft5x0x_ts_exit);
929
930 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
931 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");
932 MODULE_LICENSE("GPL");
933