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
21 #include <linux/input.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/interrupt.h>
25 #include <linux/kernel.h>
26 #include <linux/platform_device.h>
27 #include <linux/spi/spi.h>
28 #include <linux/slab.h>
29 #include <linux/fcntl.h>
30 #include <linux/delay.h>
31 #include <linux/device.h>
32 #include <linux/timer.h>
33 #include <linux/jiffies.h>
34 #include <linux/miscdevice.h>
35 #include <linux/types.h>
37 #include <linux/delay.h>
38 //#include <arch/api_intc.h>
39 //#include <arch/typedef.h>
40 //#include <arch/gpio.h>
41 //#include <arch/api_intc.h>
42 //#include <arch/hw_define.h>
43 //#include <arch/hardware.h>
44 //#include <arch/gpio.h>
45 //#include <arch/iomux.h>
46 //#include <asm-arm/uaccess.h>
47 #include <linux/ioport.h>
48 #include <linux/input-polldev.h>
49 #include <linux/i2c.h>
50 #include <linux/workqueue.h>
51 #ifdef CONFIG_ANDROID_POWER
52 #include <linux/android_power.h>
56 #include <mach/hardware.h>
57 #include <asm/setup.h>
58 #include <asm/mach-types.h>
59 #include <asm/mach/arch.h>
60 #include <asm/mach/map.h>
61 #include <asm/mach/flash.h>
62 #include <asm/hardware/gic.h>
64 #include <mach/iomux.h>
65 #include <mach/gpio.h>
66 #include <mach/irqs.h>
67 #include <mach/rk29_iomap.h>
68 #include <mach/board.h>
69 #include <mach/rk29_nand.h>
70 #include <mach/rk29_camera.h> /* ddl@rock-chips.com : camera support */
71 #include <media/soc_camera.h> /* ddl@rock-chips.com : camera support */
72 #include <mach/vpu_mem.h>
73 #include <mach/sram.h>
75 #ifdef CONFIG_HAS_EARLYSUSPEND
76 #include <linux/earlysuspend.h>
79 //#include <asm/arch/api_i2c.h>
80 #include "ft5406_ts.h"
83 #ifdef CONFIG_HAS_EARLYSUSPEND
84 static struct early_suspend ft5406_early_suspend;
87 static struct i2c_client *this_client;
91 #define CONFIG_FT5X0X_MULTITOUCH 1
93 #define CONFIG_TOUCH_PANEL_KEY 1 //harry 2011.03.15
95 #define M8_TP_KEY 0 // 1
99 #define HOME_KEY_MIN 260
100 #define HOME_KEY_MAX 330
102 #define MENU_KEY_MIN 380
103 #define MENU_KEY_MAX 460
105 #define BACK_KEY_MIN 130
106 #define BACK_KEY_MAX 210
109 #define HOME_KEY_MIN 115
110 #define HOME_KEY_MAX 185
112 #define MENU_KEY_MIN 215
113 #define MENU_KEY_MAX 295
115 #define BACK_KEY_MIN 10
116 #define BACK_KEY_MAX 85
120 #define CONFIG_TOUCH_PANEL_LED 1
121 #if CONFIG_TOUCH_PANEL_LED
122 #define RK29SDK_PANEL_LED_GPIO_SITCH RK29_PIN6_PB4
125 #define TOUCH_RESET_PIN RK29_PIN6_PC3
148 struct ft5x0x_ts_data {
149 struct i2c_client *client;
150 struct input_dev *input_dev;
152 struct ts_event event;
153 struct work_struct pen_event_work;
154 struct workqueue_struct *ts_workqueue;
158 //#define FT5X0X_I2C_ADDR 0x70
161 static int ft5x0x_ts_probe(struct i2c_adapter *bus, int address, int kind);
162 static unsigned short ft5x0x_normal_i2c[] = {FT5X0X_I2C_ADDR>>1, I2C_CLIENT_END};
163 static unsigned short ft5x0x_ignore = I2C_CLIENT_END;
164 static struct i2c_client_address_data ft5x0x_addr_data={
165 .normal_i2c = ft5x0x_normal_i2c,
166 .probe = &ft5x0x_ignore,
167 .ignore =&ft5x0x_ignore,
170 static int ft5x0x_attach_adapter(struct i2c_adapter *adap)
172 return i2c_probe(adap, &ft5x0x_addr_data, ft5x0x_ts_probe);
175 static struct i2c_driver ft5x0x_ts_driver = {
178 .owner = THIS_MODULE,
180 .id = FT5X0X_I2C_ADDR,
181 .attach_adapter = &ft5x0x_attach_adapter,
186 static struct i2c_client ft5x0x_client = {
187 .driver = &ft5x0x_ts_driver,
191 /*read the it7260 register ,used i2c bus*/
193 #define FT5406_IIC_SPEED 200*1000 //300*1000
194 static int ft5406_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
197 ret = i2c_master_reg8_recv(client, reg, buf, len, FT5406_IIC_SPEED);
202 /* set the it7260 registe,used i2c bus*/
203 static int ft5406_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
206 ret = i2c_master_reg8_send(client, reg, buf, (int)len, FT5406_IIC_SPEED);
214 static int ft5x0x_i2c_rxdata(u8 reg, u8 rxdata[], int length)
217 struct i2c_msg msg[1];
219 msg->addr = ft5x0x_client.addr;
220 msg->flags |= I2C_M_RD;
224 //printk("ft50x0_client.addr = 0x%x\n", ft5x0x_client.addr);
227 ret = i2c_transfer(ft5x0x_client.adapter, msg, 1);
230 printk("error at ft5x0x_read_regs !!! \n");
236 static int ft5x0x_i2c_txdata(u8 reg, u8 txdata[], int length)
239 struct i2c_msg msg[1];
240 static u8 i2c_buf[128];
242 msg->addr = ft5x0x_client.addr;
245 msg->len = length + 1;
249 memcpy(&i2c_buf[1], &txdata[0], length);
250 ret = i2c_transfer(ft5x0x_client.adapter, msg, 1);
253 printk("error at gt800_write_regs !!! \n");
260 static void ft5x0x_ts_release(struct ft5x0x_ts_data *data)
262 //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client);
263 //struct ts_event *event = &data->event;
265 #if CONFIG_FT5X0X_MULTITOUCH // #ifdef
266 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);
267 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0);
269 input_report_abs(data->input_dev, ABS_PRESSURE, 0);
270 input_report_key(data->input_dev, BTN_TOUCH, 0);
272 input_sync(data->input_dev);
275 static int ft5x0x_read_data(struct ft5x0x_ts_data *data )
277 //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client);
278 struct ts_event *event = &data->event;
288 ret = ft5x0x_i2c_rxdata(start_reg, buf, 2);
290 printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
293 for (i=0; i<2; i++) {
294 printk("=========buf[%d] = 0x%x \n", i, buf[i]);
303 #if CONFIG_FT5X0X_MULTITOUCH // #ifdef
304 if (MAX_POINT == 5) {
305 ret = ft5406_read_regs(data->client,start_reg, buf, 31);
307 ret = ft5406_read_regs(data->client,start_reg, buf, 13);
310 ret = ft5406_read_regs(data->client,start_reg, buf, 7);
313 // printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
317 for (i=0; i<32; i++) {
318 printk("buf[%d] = 0x%x \n", i, buf[i]);
322 memset(event, 0, sizeof(struct ts_event));
324 if (MAX_POINT == 5) {
325 event->touch_point = buf[2] & 0x07;// 000 0111
327 event->touch_point = buf[2] & 0x03;// 0000 0011
330 // printk("touch_point = %d\n", event->touch_point);
331 if (event->touch_point == 0) {
332 // printk("release point !!!!!!!!!!!!!!!!!\n");
333 ft5x0x_ts_release(data);
337 #if CONFIG_FT5X0X_MULTITOUCH // #ifdef
338 switch (event->touch_point) {
339 if (MAX_POINT == 5) {
341 event->x5 = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c];
342 event->y5 = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e];
343 status = (s16)((buf[0x1b] & 0xc0) >> 6);
344 event->touch_ID5=(s16)(buf[0x1D] & 0xF0)>>4;
347 // printk("read ID5 = %d\n",event->touch_ID5,status);
348 // printk("read status5= %d\n",status);
351 printk("point 5 release!\n");
352 ft5x0x_ts_release(data);
356 event->x4 = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16];
357 event->y4 = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18];
358 status = (s16)((buf[0x15] & 0xc0) >> 6);
359 //event->touch_ID4=(s16)(buf[0x17] & 0xF0);
360 event->touch_ID4=(s16)(buf[0x17] & 0xF0)>>4;
361 // printk("read ID4 = %d,read status4 = %d\n",event->touch_ID4,status);
364 printk("point 4 release!\n");
365 ft5x0x_ts_release(data);
371 event->x3 = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10];
372 event->y3 = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12];
373 status = (s16)((buf[0x0f] & 0xc0) >> 6);
374 // event->touch_ID3=(s16)(buf[0x11] & 0xF0);
375 event->touch_ID3=(s16)(buf[0x11] & 0xF0)>>4;
376 // printk("read ID3 = %d,read status3 = %d\n",event->touch_ID3,status);
379 printk("point 3 release!\n");
380 ft5x0x_ts_release(data);
387 event->x2 = (s16)(buf[9] & 0x0F)<<8 | (s16)buf[10];
388 event->y2 = (s16)(buf[11] & 0x0F)<<8 | (s16)buf[12];
389 status = (s16)((buf[0x9] & 0xc0) >> 6);
390 // event->touch_ID2=(s16)(buf[0x0b] & 0xF0);
391 event->touch_ID2=(s16)(buf[0x0b] & 0xF0)>>4;
392 // printk("read ID2 = %d,read status2 = %d\n",event->touch_ID2,status);
395 printk("point 2 release!\n");
396 ft5x0x_ts_release(data);
402 event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
403 event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
404 status = ((buf[0x3] & 0xc0) >> 6);
405 event->status= status ;
406 // event->touch_ID1=(s16)(buf[5] & 0xF0);
407 event->touch_ID1=(s16)(buf[0x05] & 0xF0)>>4;
408 //printk("status1= %d\n",event->status);
411 printk("point 1 release!\n");
412 ft5x0x_ts_release(data);
424 if((event->touch_point ==1)
425 &&((event->y1<BACK_KEY_MIN) ||(event->y2>MENU_KEY_MAX)))
427 ft5x0x_ts_release(data);
431 if(((event->touch_point - cnt) ==0)&&(event->touch_point >1))
433 ft5x0x_ts_release(data);
438 if (event->touch_point == 1) {
439 event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
440 event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
443 event->pressure =200; //200;
445 // printk("status2= %d\n",event->status);
450 static void ft5x0x_report_value(struct ft5x0x_ts_data *data )
452 //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client);
453 struct ts_event *event = &data->event;
455 #if CONFIG_TOUCH_PANEL_KEY
457 // static u16 point_data=0;
461 #if CONFIG_FT5X0X_MULTITOUCH //#ifdef
462 switch(event->touch_point) {
466 if(event->x5 <= 1024)
468 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID5);
469 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
470 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x5);
471 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y5);
472 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
473 input_mt_sync(data->input_dev);
475 // printk("===x5 = %d,y5 = %d ====\n",event->x5,event->y5);
477 if(event->x4 <= 1024)
479 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID4);
480 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
481 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x4);
482 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y4);
483 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
484 input_mt_sync(data->input_dev);
486 // printk("===x4 = %d,y4 = %d ====\n",event->x4, event->y4);
488 if(event->x3 <= 1024)
490 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID3);
491 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
492 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x3);
493 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y3);
494 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
495 input_mt_sync(data->input_dev);
497 // printk("===x3 = %d,y3 = %d ====\n",event->x3, event->y3);
500 if(event->x2 <= 1024)
502 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID2);
503 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
504 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x2);
505 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y2);
506 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
507 input_mt_sync(data->input_dev);
509 // printk("===x2 = %d,y2 = %d ====\n",event->x2,event->y2);
511 #if CONFIG_TOUCH_PANEL_KEY
519 // printk("point 1 key1\n");
520 // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1);
523 if((event->y1>BACK_KEY_MIN)&&(event->y1<BACK_KEY_MAX)) // M6 10 - 90
525 input_report_key(data->input_dev,KEY_BACK,1); //158 //MENU
526 input_sync(data->input_dev);
527 input_report_key(data->input_dev,KEY_BACK,0); //158 //MENU
528 input_sync(data->input_dev);
529 #if CONFIG_TOUCH_PANEL_LED //#ifdef
530 // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){
531 // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH);
532 // printk("panel Key LED error\n");
535 gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0);
536 gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_HIGH);
538 // printk("point 1 key2\n");
540 else if((event->y1>HOME_KEY_MIN)&&(event->y1<HOME_KEY_MAX)) //M6 110 - 190
542 input_report_key(data->input_dev,KEY_HOME,1); //102 //Home
543 input_sync(data->input_dev);
544 input_report_key(data->input_dev,KEY_HOME,0); //102 //Home
545 input_sync(data->input_dev);
546 #if CONFIG_TOUCH_PANEL_LED // #ifdef
547 // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){
548 // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH);
549 // printk("panel Key LED error\n");
552 gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0);
553 gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_HIGH);
555 // printk("point 1 key3\n");
557 else if((event->y1>MENU_KEY_MIN)&&(event->y1<MENU_KEY_MAX)) // M6 210 -290
559 input_report_key(data->input_dev,KEY_MENU,1); //59 //esc
560 input_sync(data->input_dev);
561 input_report_key(data->input_dev,KEY_MENU,0); //59 //esc
562 input_sync(data->input_dev);
563 #if CONFIG_TOUCH_PANEL_LED // #ifdef
564 // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){
565 // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH);
566 // printk("panel Key LED error\n");
569 gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0);
570 gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_HIGH);
572 // printk("point 1 key4\n");
576 ft5x0x_ts_release(data);
582 ft5x0x_ts_release(data);
588 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID1);
589 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
590 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1);
591 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1);
592 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
593 input_mt_sync(data->input_dev);
594 // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1);
597 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID1);
598 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
599 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1);
600 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1);
601 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
602 input_mt_sync(data->input_dev);
603 // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1);
606 // printk("==touch_point default =\n");
607 // printk("read status0= %d\n",event->status);
608 // if (event->status== 1) {
609 // printk("point 0 release!\n");
610 // ft5x0x_ts_release(data);
612 #if CONFIG_TOUCH_PANEL_KEY
617 #else /* CONFIG_FT5X0X_MULTITOUCH*/
618 if (event->touch_point == 1) {
619 input_report_abs(data->input_dev, ABS_X, event->x1);
620 input_report_abs(data->input_dev, ABS_Y, event->y1);
621 input_report_abs(data->input_dev, ABS_PRESSURE, event->pressure);
623 input_report_key(data->input_dev, BTN_TOUCH, 1);
624 #endif /* CONFIG_FT5X0X_MULTITOUCH*/
625 input_sync(data->input_dev);
627 // printk("status3= %d\n",event->status);
630 } /*end ft5x0x_report_value*/
632 static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
635 // printk("==work 1=\n");
637 struct ft5x0x_ts_data *ft5x0x_ts =
638 container_of(work, struct ft5x0x_ts_data, pen_event_work);
641 ret = ft5x0x_read_data(ft5x0x_ts);
643 ft5x0x_report_value(ft5x0x_ts);
644 // printk("==work 2=\n");
646 // else printk("data package read error\n");
647 // printk("==work 2=\n");
649 enable_irq(ft5x0x_ts->irq);
651 // gpio_irq_enable(TOUCH_INT_IOPIN);
654 static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
657 struct ft5x0x_ts_data *ft5x0x_ts = dev_id;
659 //printk("ft5x0x_ts irq =%d",ft5x0x_ts->irq);
661 disable_irq_nosync(ft5x0x_ts->irq);
662 // disable_irq(ft5x0x_ts->irq);
664 //gpio_irq_disable(ft5x0x_ts->irq);
666 if (!work_pending(&ft5x0x_ts->pen_event_work))
668 queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
669 // printk("ft5x0x_ts_work!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
676 static int __devexit ft5406_remove(struct i2c_client *client)
678 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
680 // printk("==ft5x0x_ts_remove=\n");
682 // free_irq(client->irq, ft5x0x_ts);
683 // free_irq(7, ft5x0x_ts);
684 free_irq(ft5x0x_ts->irq, ft5x0x_ts);
686 input_unregister_device(ft5x0x_ts->input_dev);
688 cancel_work_sync(&ft5x0x_ts->pen_event_work);
689 destroy_workqueue(ft5x0x_ts->ts_workqueue);
690 i2c_set_clientdata(client, NULL);
691 #ifdef CONFIG_HAS_EARLYSUSPEND
692 unregister_early_suspend(&ft5406_early_suspend);
700 #ifdef CONFIG_HAS_EARLYSUSPEND
701 static int ft5x0x_ts_suspend(struct early_suspend *h)
709 // printk("==ft5x0x_ts_suspend=\n");
712 // struct ft5x0x_ts_data *ts;
713 // ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);
715 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
716 if (device_may_wakeup(&client->dev))
717 enable_irq_wake(ft5x0x_ts->irq);
719 // disable_irq(ft5x0x_client->irq);
720 // cancel_work_sync(&ts->pen_event_work);
721 // flush_workqueue(ts->ts_workqueue);
725 buf[0]=PMODE_HIBERNATE;
728 err=ft5406_set_regs(this_client,FT5X0X_REG_PMODE, buf,1);
729 // printk("==ft5406 suspend write 111=%d\n",buf[0]);
737 // printk("==ft5406 suspend write222=%d\n",buf[0]);
738 ft5406_set_regs(this_client,FT5X0X_REG_PMODE, buf,1);
742 // printk("==ft5406 suspend write=%d\n",buf[0]);
743 // printk("==ft5406 suspend write err=%d\n",err);
744 // msleep(50); //harry 2011.04.20
745 // err = ft5406_read_regs(this_client,FT5X0X_REG_PMODE,buf_r,1);
746 // printk("==ft5406 suspend read=%d\n",buf_r[0]);
747 // printk("==ft5406 suspend read err=%d\n",err);
751 #if CONFIG_TOUCH_PANEL_LED
752 // if(gpio_request(RK29SDK_PANEL_LED_GPIO_SITCH,NULL) != 0){
753 // gpio_free(RK29SDK_PANEL_LED_GPIO_SITCH);
754 // printk("panel Key LED error\n");
757 gpio_direction_output(RK29SDK_PANEL_LED_GPIO_SITCH, 0);
758 gpio_set_value(RK29SDK_PANEL_LED_GPIO_SITCH,GPIO_LOW);
759 // printk("suspend led 2\n");
766 static int ft5x0x_ts_resume(struct early_suspend *h)
768 //printk("==ft5x0x_ts_resume=\n");
770 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
771 if (device_may_wakeup(&client->dev))
772 disable_irq_wake(ft5x0x_ts->irq);
775 // __gpio_as_output(GPIO_FT5X0X_WAKE);
776 // __gpio_clear_pin(GPIO_FT5X0X_WAKE); //set wake = 0,base on system
778 // __gpio_set_pin(GPIO_FT5X0X_WAKE); //set wake = 1,base on system
780 // enable_irq(IRQ_EINT(6));
783 gpio_direction_output(TOUCH_RESET_PIN, 0);
784 gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
785 msleep(20); //harry 2011.04.20
786 gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
793 static int ft5406_probe(struct i2c_client *client ,const struct i2c_device_id *id)
795 struct ft5x0x_ts_data *ft5x0x_ts;
796 struct input_dev *input_dev;
797 struct ft5406_platform_data *pdata = pdata = client->dev.platform_data;
804 //printk("==ft5x0x_ts_probe=\n");
807 dev_err(&client->dev, "platform data is required!\n");
811 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
815 ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
818 goto exit_alloc_data_failed;
821 ft5x0x_client.adapter = bus;
822 ft5x0x_client.addr= address;
823 ft5x0x_client.mode = NORMALMODE; //NORMALNOSTOPMODE;// DIRECTMODE;
824 ft5x0x_client.Channel = I2C_CH0;
825 ft5x0x_client.speed = 300;
826 ft5x0x_client.addressBit=I2C_7BIT_ADDRESS_8BIT_REG;
827 ft5x0x_ts->client=&ft5x0x_client;
829 i2c_set_clientdata(&ft5x0x_client, ft5x0x_ts);
831 err = i2c_attach_client(&ft5x0x_client);
834 printk("ft5x0x attach client failed!!!!\n");
835 goto exit_alloc_data_failed;
838 INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
839 ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts");
840 if (!ft5x0x_ts->ts_workqueue) {
842 goto exit_create_singlethread;
845 rockchip_mux_api_set(TOUCH_INT_IOMUX_PINNAME,TOUCH_INT_IOMUX_PINDIR);
846 GPIOSetPinDirection(TOUCH_INT_IOPIN, GPIO_IN);
847 GPIOPullUpDown(TOUCH_INT_IOPIN, GPIOPullUp);
848 err = request_gpio_irq(TOUCH_INT_IOPIN, ft5x0x_ts_interrupt, GPIOEdgelFalling, ft5x0x_ts);
851 printk("ft5x0x_probe: request irq failed\n");
852 goto exit_irq_request_failed;
855 input_dev = input_allocate_device();
858 printk("failed to allocate input device\n");
859 goto exit_input_dev_alloc_failed;
862 this_client = client;
863 ft5x0x_ts->client = client;
864 ft5x0x_ts->irq = client->irq;
865 ft5x0x_ts->input_dev = input_dev;
867 #if CONFIG_FT5X0X_MULTITOUCH //#ifdef
868 set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
869 set_bit(ABS_MT_POSITION_X, input_dev->absbit);
870 set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
871 set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
873 //input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN); //harry 03.21
874 #if CONFIG_TOUCH_PANEL_KEY
875 set_bit(KEY_HOME, input_dev->keybit);
876 set_bit(KEY_MENU, input_dev->keybit);
877 set_bit(KEY_BACK, input_dev->keybit);
880 input_set_abs_params(input_dev,
881 ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
882 input_set_abs_params(input_dev,
883 ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
884 input_set_abs_params(input_dev,
885 ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
886 input_set_abs_params(input_dev,
887 ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
888 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0);
890 set_bit(ABS_X, input_dev->absbit);
891 set_bit(ABS_Y, input_dev->absbit);
892 set_bit(ABS_PRESSURE, input_dev->absbit);
893 set_bit(BTN_TOUCH, input_dev->keybit);
895 input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);
896 input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);
897 input_set_abs_params(input_dev,
898 ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);
902 set_bit(EV_ABS, input_dev->evbit);
903 set_bit(EV_KEY, input_dev->evbit);
905 #if CONFIG_TOUCH_PANEL_KEY
906 set_bit(EV_SYN, input_dev->evbit); //harry 03.21
909 input_dev->name = FT5X0X_NAME; //dev_name(&client->dev)
910 err = input_register_device(input_dev);
912 // printk("ft5x0x_ts_probe: failed to register input device: \n");
913 goto exit_input_register_device_failed;
916 // printk("==probe over =\n");
917 if (pdata->init_platform_hw)
918 pdata->init_platform_hw();
920 if (!ft5x0x_ts->irq) {
921 dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n");
924 ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
927 //printk("ft5x0x_ts irq =%d", ft5x0x_ts->irq);
930 INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
931 ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts");
932 if (!ft5x0x_ts->ts_workqueue) {
934 goto exit_create_singlethread;
939 //printk("client->dev.driver->name %s ,%d \n",client->dev.driver->name,ft5x0x_ts->irq);
942 ret = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, /*IRQF_TRIGGER_LOW*/IRQF_TRIGGER_FALLING, //IRQF_DISABLED|IRQF_TRIGGER_FALLING,
943 client->dev.driver->name, ft5x0x_ts);
946 dev_err(&client->dev, "irq %d busy?\n", ft5x0x_ts->irq);
951 ret = input_register_device(input_dev);
954 // printk("ft5406 register input device failed!!!!\n");
955 goto exit_irq_request_failed;
959 #ifdef CONFIG_HAS_EARLYSUSPEND
960 ft5406_early_suspend.suspend =ft5x0x_ts_suspend;
961 ft5406_early_suspend.resume =ft5x0x_ts_resume;
962 ft5406_early_suspend.level = 0x2;
963 register_early_suspend(&ft5406_early_suspend);
966 //buf_w[0] = 6; //harry 04.07
969 err = ft5406_set_regs(client,0x88,buf_w,1);
970 //ft5x0x_i2c_txdata(0x88, buf_w, 1); /* adjust frequency 60Hz */
973 err = ft5406_read_regs(client,0x88,buf_r,1);
974 //ft5x0x_i2c_rxdata(0x88, buf_r, 1);
975 // printk("read buf[0x88] = %d\n", buf_r[0]);
979 free_irq(ft5x0x_ts->irq,ft5x0x_ts);
980 i2c_set_clientdata(client, NULL); //harry
981 destroy_workqueue(ft5x0x_ts->ts_workqueue); //harry
982 exit_input_register_device_failed:
983 input_free_device(input_dev);
984 // i2c_set_clientdata(client, NULL);
987 exit_input_dev_alloc_failed:
988 // free_irq(7, ft5x0x_ts);
989 free_irq(ft5x0x_ts->irq, ft5x0x_ts);
990 exit_irq_request_failed:
991 exit_platform_data_null:
992 cancel_work_sync(&ft5x0x_ts->pen_event_work);
993 destroy_workqueue(ft5x0x_ts->ts_workqueue);
994 exit_create_singlethread:
995 printk("==singlethread error =\n");
997 exit_alloc_data_failed:
1003 static struct i2c_device_id ft5406_idtable[] = {
1008 MODULE_DEVICE_TABLE(i2c, ft5406_idtable);
1010 static struct i2c_driver ft5406_driver = {
1012 .owner = THIS_MODULE,
1015 .id_table = ft5406_idtable,
1016 .probe = ft5406_probe,
1017 #ifndef CONFIG_HAS_EARLYSUSPEND
1018 .suspend = ft5x0x_ts_suspend,
1019 .resume = ft5x0x_ts_resume,
1021 .remove = __devexit_p(ft5406_remove),
1024 static int __init ft5x0x_ts_init(void)
1026 return i2c_add_driver(&ft5406_driver);
1029 static void __exit ft5x0x_ts_exit(void)
1031 i2c_del_driver(&ft5406_driver);
1034 module_init(ft5x0x_ts_init);
1035 module_exit(ft5x0x_ts_exit);
1037 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
1038 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");