2 * drivers/input/touchscreen/ft5x0x_ts.c
4 * FocalTech ft5x0x TouchScreen driver.
6 * Copyright (c) 2010 Focal tech Ltd.
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.
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.
18 * note: only support mulititouch Wenfs 2010-10-01
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>
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>
37 #ifdef CONFIG_HAS_EARLYSUSPEND
38 #include <linux/earlysuspend.h>
42 #define CONFIG_FT5X0X_MULTITOUCH 1
43 #define CONFIG_TOUCH_PANEL_KEY 1
46 #define LONGPRESS_LOCK_SPECKEY //是否使用长按某键(如search键)锁住功能键的功能
47 #ifdef LONGPRESS_LOCK_SPECKEY
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;
55 ssize_t glock_status_show(struct device *dev, char *buf)
57 printk("lockflag === %d\n",lockflag);
58 return sprintf(buf, "%d", lockflag);
63 static int err_ft5X06 = 0; //w++记载有没有此设备
65 module_param(debug1, int, S_IRUGO|S_IWUSR);
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;
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
81 uint16_t down_table = 0;
82 uint16_t up_table = ~0;
85 #define SCREEN_MAX_X 480
86 #define SCREEN_MAX_Y 800
89 #define FT5X0X_NAME "ft5x0x_ts"
90 #define MAX_CONTACTS 5
92 FT5X0X_REG_PMODE = 0xA5, /* Power Consume Mode */
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};
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};
108 #define PMODE_ACTIVE 0x00
109 #define PMODE_MONITOR 0x01
110 #define PMODE_STANDBY 0x02
111 #define PMODE_HIBERNATE 0x03
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 */
134 struct point_data point[5];
137 struct ft5x0x_ts_dev {
138 struct i2c_client *client;
139 struct input_dev *input_dev;
141 struct ts_event event;
142 struct work_struct pen_event_work;
143 struct workqueue_struct *ts_workqueue;
144 struct early_suspend early_suspend;
147 struct timer_list timer;
151 static struct ft5x0x_ts_dev *g_dev;
152 static bool rember_point_into = true;
155 static ssize_t Moto_status(struct device_driver *_drv,char *_buf)
157 //printk("Moto_status Motoenble==%d\n", Motoenble);
159 return sprintf(_buf, "Ledlevel is Low\n");
161 return sprintf(_buf, "Ledlevel is High\n");
163 static ssize_t Moto_control(struct device_driver *_drv, const char *_buf, size_t _count)
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);
173 static int ft5x0x_i2c_rxdata(char *rxdata, int length)
177 struct i2c_msg msgs[] = {
179 .addr = g_dev->client->addr,
183 .scl_rate = 200 * 1000,
186 .addr = g_dev->client->addr,
190 .scl_rate = 200 * 1000,
194 ret = i2c_transfer(g_dev->client->adapter, msgs, 2);
196 pr_err("msg %s i2c read error: %d\n", __func__, ret);
201 static int ft5x0x_i2c_txdata(char *txdata, int length)
205 struct i2c_msg msg[] = {
207 .addr = g_dev->client->addr,
211 .scl_rate = 200 * 1000,
215 ret = i2c_transfer(g_dev->client->adapter, msg, 1);
217 pr_err("%s i2c write error: %d\n", __func__, ret);
222 static int ft5x0x_set_reg(u8 addr, u8 para)
229 ret = ft5x0x_i2c_txdata(buf, 2);
231 pr_err("write reg failed! %#x ret: %d", buf[0], ret);
238 static int ft5x0x_read_data(void)
240 struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
241 struct ts_event *event = &data->event;
243 u8 buf[32]= {0};//set send addr to 0x00 *important*
252 //printk("the moto is enable!\n");
259 ret = ft5x0x_i2c_rxdata(buf, 32);
262 printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
265 #if 0 // Just for debug
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];
276 // if (uc_ecc == buf[1]) break;
280 if (uc_ecc != buf[1])
282 printk("ecc check error uc_ecc=0x%x, buf[1]=0x%x.\n",uc_ecc, buf[1]);
288 memset(event, ~0x00, sizeof(struct ts_event));
291 event->touch_point = buf[2] & 0x07;// 0000 1111
293 event->touch_point = buf[2] >>4;// 0000 1111
295 if (event->touch_point == 0) {
296 rember_point_into = false;
297 #ifdef LONGPRESS_LOCK_SPECKEY
298 if(Origin2LockPressCnt)
300 if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
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");
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);
318 Origin2LockPressCnt = 0;
319 touch_key_hold_press = 0;
323 if(touch_key_hold_press)
325 touch_key_hold_press = 0;
326 for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
328 if(touch_key_press[key])
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]);
340 //printk("release point !!!!!!!!!!!!!!!!!\n");
341 //ft5x0x_ts_release(data);
343 //event->penddown = Release;
348 #ifdef CONFIG_FT5X0X_MULTITOUCH
349 switch (event->touch_point) {
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];
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];
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];
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];
371 event->point[0].status = (buf[0x03] & 0xc0)>>6;
372 event->point[0].id = (buf[0x05] & 0xf0)>>4;
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;
387 static void ft5x0x_report_value(void)
389 struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client);
390 struct ts_event *event = &data->event;
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",
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);
406 for(i=0; i<event->touch_point; i++) {
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)*/)
411 for(j=0;j<KEY_NUM;j++)
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]))
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))
420 #ifdef LONGPRESS_LOCK_SPECKEY
421 // printk("touch_key_code[%d]:%d\n",key_id,touch_key_code[key_id]);
423 if(touch_key_code[key_id] == ORIGIN_KEY)
425 if(++Origin2LockPressCnt>LOCK_LONG_PRESS_CNT)
427 Origin2LockPressCnt = LOCK_LONG_PRESS_CNT + 2;
428 input_report_key(data->input_dev, KEY_LOCK, 1);
429 touch_key_hold_press = 1;
435 Origin2LockPressCnt=1;
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]);
452 input_mt_slot(data->input_dev, event->point[i].id);
454 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id);
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);
468 for(i=0; i<MAX_CONTACTS; i++) {
469 if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
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);*/
477 up_table = ~down_table;
478 input_sync(data->input_dev);
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);
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);
495 input_sync(data->input_dev);
504 data->timer.expires = jiffies +8;
505 add_timer(&data->timer);
513 } /*end ft5x0x_report_value*/
515 static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
518 //printk("==ft5x0x_ts_pen_work =\n");
519 ret = ft5x0x_read_data();
521 ft5x0x_report_value();
523 enable_irq(g_dev->irq);
526 static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
528 struct ft5x0x_ts_dev *ft5x0x_ts = dev_id;
532 del_timer(&ft5x0x_ts->timer);
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);
541 #ifdef CONFIG_HAS_EARLYSUSPEND
542 static void ft5x0x_ts_suspend(struct early_suspend *handler)
545 struct ft5x0x_ts_dev *ts;
546 ts = container_of(handler, struct ft5x0x_ts_dev, early_suspend);
549 disable_irq_nosync(ts->irq);
551 ret = cancel_work_sync(&ts->pen_event_work);
552 if (ret && ts->irq) /* if work was pending disable-count is now 2 */
555 // ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE);
558 static void ft5x0x_ts_resume(struct early_suspend *handler)
560 struct ft5x0x_ts_dev *ts;
561 ts = container_of(handler, struct ft5x0x_ts_dev, early_suspend);
563 // gpio_direction_output(RK29_PIN6_PC3, 0);
564 // gpio_set_value(RK29_PIN6_PC3,GPIO_LOW);
566 // gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH);
576 #endif //CONFIG_HAS_EARLYSUSPEND
578 static void Touch_timer_release(unsigned long ft_ts_pdev)
581 struct ft5x0x_ts_dev *data = ft_ts_pdev;
584 /*if(rember_point_into)
586 for(i=0;i<MAX_CONTACTS;i++)
588 printk("hand to modefy with up !!!!!!\n");
590 input_mt_slot(data->input_dev, i);
591 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1);
595 input_sync(data->input_dev);
596 rember_point_into = true;
599 for(i=0; i<MAX_CONTACTS; i++) {
600 if( ( (~down_table) & 1<<i) && !(up_table & 1<<i) )
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);
608 if(inflag==1)input_sync(data->input_dev);
610 //===================================
611 #ifdef LONGPRESS_LOCK_SPECKEY
613 if(Origin2LockPressCnt)
615 if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT)
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");
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);
633 Origin2LockPressCnt = 0;
634 touch_key_hold_press = 0;
638 if((touch_key_hold_press)&&(debug1))
640 touch_key_hold_press = 0;
641 for(key=0; key<sizeof(touch_key_code)/sizeof(touch_key_code[0]); key++)
643 if(touch_key_press[key])
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]);
654 //===================================
662 static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
664 struct ft5x0x_ts_dev *ft5x0x_ts;
665 struct ft5x0x_platform_data *pdata = pdata = client->dev.platform_data;
666 struct input_dev *input_dev;
674 dev_err(&client->dev, "%s: platform data is null\n", __func__);
675 goto exit_platform_data_null;
678 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
680 goto exit_check_functionality_failed;
683 if (pdata->init_platform_hw)
684 pdata->init_platform_hw();
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
691 //err_ft5X06 = ft5x0x_i2c_rxdata(buf,1);
693 printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,err);
698 ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
701 goto exit_alloc_data_failed;
704 input_dev = input_allocate_device();
707 dev_err(&client->dev, "failed to allocate input device\n");
708 goto exit_input_dev_alloc_failed;
711 ft5x0x_ts->input_dev = input_dev;
712 ft5x0x_ts->client = client;
713 ft5x0x_ts->irq = client->irq;
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);
724 input_mt_init_slots(input_dev, MAX_CONTACTS);
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);
741 input_dev->name = FT5X0X_NAME; //dev_name(&client->dev)
742 err = input_register_device(input_dev);
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;
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) {
757 goto exit_create_singlethread;
760 //if(pdata->init_platform_hw)
761 // pdata->init_platform_hw();
763 //ft5x0x_set_reg(0x80,0x64);
767 dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n");
772 ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
775 err = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING/*IRQF_DISABLED*/, "ft5x0x_ts", ft5x0x_ts);
777 dev_err(&client->dev, "ft5x0x_probe: request irq failed\n");
778 goto exit_irq_request_failed;
781 disable_irq_nosync(g_dev->irq);
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);
790 setup_timer(&ft5x0x_ts->timer, Touch_timer_release, (unsigned long)ft5x0x_ts);
794 // __gpio_as_output(GPIO_FT5X0X_WAKE);
795 // __gpio_clear_pin(GPIO_FT5X0X_WAKE); //set wake = 0,base on system
797 // __gpio_set_pin(GPIO_FT5X0X_WAKE); //set wake = 1,base on system
799 // ft5x0x_set_reg(0x88, 0x05); //5, 6,7,8
800 // ft5x0x_set_reg(0x80, 30);
804 err = ft5x0x_set_reg(0x88,6);
805 //ft5x0x_i2c_txdata(0x88, buf_w, 1); /* adjust frequency 60Hz */
808 err = ft5x0x_i2c_rxdata(buf_r,1);
810 enable_irq(g_dev->irq);
812 printk("==ft5x0x_ts_probe = %0x\n", buf_r[0]);
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);
829 exit_alloc_data_failed:
830 exit_check_functionality_failed:
834 static int __devexit ft5x0x_ts_remove(struct i2c_client *client)
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);
841 cancel_work_sync(&ft5x0x_ts->pen_event_work);
842 destroy_workqueue(ft5x0x_ts->ts_workqueue);
843 i2c_set_clientdata(client, NULL);
847 static const struct i2c_device_id ft5x0x_ts_id[] = {
848 { FT5X0X_NAME, 0 },{ }
850 MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);
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,
858 .owner = THIS_MODULE,
861 #ifdef LONGPRESS_LOCK_SPECKEY
862 static DRIVER_ATTR(get_lock_status, 0777, glock_status_show, NULL);
864 static DRIVER_ATTR(MOTOenable, 0666, Moto_status, Moto_control);
866 static int __init ft5x0x_ts_init(void)
869 ret = i2c_add_driver(&ft5x0x_ts_driver);
872 printk("Register 5406_ts driver failed.\n");
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);
880 ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
884 static void __exit ft5x0x_ts_exit(void)
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);
890 driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable);
893 module_init(ft5x0x_ts_init);
894 module_exit(ft5x0x_ts_exit);
896 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
897 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");
898 MODULE_LICENSE("GPL");