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 0
92 #define TOUCH_RESET_PIN RK29_PIN6_PC3
115 struct ft5x0x_ts_data {
116 struct i2c_client *client;
117 struct input_dev *input_dev;
119 struct ts_event event;
120 struct work_struct pen_event_work;
121 struct workqueue_struct *ts_workqueue;
125 //#define FT5X0X_I2C_ADDR 0x70
128 static int ft5x0x_ts_probe(struct i2c_adapter *bus, int address, int kind);
129 static unsigned short ft5x0x_normal_i2c[] = {FT5X0X_I2C_ADDR>>1, I2C_CLIENT_END};
130 static unsigned short ft5x0x_ignore = I2C_CLIENT_END;
131 static struct i2c_client_address_data ft5x0x_addr_data={
132 .normal_i2c = ft5x0x_normal_i2c,
133 .probe = &ft5x0x_ignore,
134 .ignore =&ft5x0x_ignore,
137 static int ft5x0x_attach_adapter(struct i2c_adapter *adap)
139 return i2c_probe(adap, &ft5x0x_addr_data, ft5x0x_ts_probe);
142 static struct i2c_driver ft5x0x_ts_driver = {
145 .owner = THIS_MODULE,
147 .id = FT5X0X_I2C_ADDR,
148 .attach_adapter = &ft5x0x_attach_adapter,
153 static struct i2c_client ft5x0x_client = {
154 .driver = &ft5x0x_ts_driver,
158 /*read the it7260 register ,used i2c bus*/
160 #define FT5406_IIC_SPEED 200*1000 //300*1000
161 static int ft5406_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
164 ret = i2c_master_reg8_recv(client, reg, buf, len, FT5406_IIC_SPEED);
169 /* set the it7260 registe,used i2c bus*/
170 static int ft5406_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
173 ret = i2c_master_reg8_send(client, reg, buf, (int)len, FT5406_IIC_SPEED);
181 static int ft5x0x_i2c_rxdata(u8 reg, u8 rxdata[], int length)
184 struct i2c_msg msg[1];
186 msg->addr = ft5x0x_client.addr;
187 msg->flags |= I2C_M_RD;
191 //printk("ft50x0_client.addr = 0x%x\n", ft5x0x_client.addr);
194 ret = i2c_transfer(ft5x0x_client.adapter, msg, 1);
197 printk("error at ft5x0x_read_regs !!! \n");
203 static int ft5x0x_i2c_txdata(u8 reg, u8 txdata[], int length)
206 struct i2c_msg msg[1];
207 static u8 i2c_buf[128];
209 msg->addr = ft5x0x_client.addr;
212 msg->len = length + 1;
216 memcpy(&i2c_buf[1], &txdata[0], length);
217 ret = i2c_transfer(ft5x0x_client.adapter, msg, 1);
220 printk("error at gt800_write_regs !!! \n");
227 static void ft5x0x_ts_release(struct ft5x0x_ts_data *data)
229 //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client);
230 //struct ts_event *event = &data->event;
232 #if CONFIG_FT5X0X_MULTITOUCH // #ifdef
233 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0);
234 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0);
236 input_report_abs(data->input_dev, ABS_PRESSURE, 0);
237 input_report_key(data->input_dev, BTN_TOUCH, 0);
239 input_sync(data->input_dev);
242 static int ft5x0x_read_data(struct ft5x0x_ts_data *data )
244 //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client);
245 struct ts_event *event = &data->event;
255 ret = ft5x0x_i2c_rxdata(start_reg, buf, 2);
257 printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
260 for (i=0; i<2; i++) {
261 printk("=========buf[%d] = 0x%x \n", i, buf[i]);
270 #if CONFIG_FT5X0X_MULTITOUCH // #ifdef
271 if (MAX_POINT == 5) {
272 ret = ft5406_read_regs(data->client,start_reg, buf, 31);
274 ret = ft5406_read_regs(data->client,start_reg, buf, 13);
277 ret = ft5406_read_regs(data->client,start_reg, buf, 7);
280 // printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);
284 for (i=0; i<32; i++) {
285 printk("buf[%d] = 0x%x \n", i, buf[i]);
289 memset(event, 0, sizeof(struct ts_event));
291 if (MAX_POINT == 5) {
292 event->touch_point = buf[2] & 0x07;// 000 0111
294 event->touch_point = buf[2] & 0x03;// 0000 0011
297 // printk("touch_point = %d\n", event->touch_point);
298 if (event->touch_point == 0) {
299 // printk("release point !!!!!!!!!!!!!!!!!\n");
300 ft5x0x_ts_release(data);
304 #if CONFIG_FT5X0X_MULTITOUCH // #ifdef
305 switch (event->touch_point) {
306 if (MAX_POINT == 5) {
308 event->x5 = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c];
309 event->y5 = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e];
310 status = (s16)((buf[0x1b] & 0xc0) >> 6);
311 event->touch_ID5=(s16)(buf[0x1D] & 0xF0)>>4;
314 // printk("read ID5 = %d\n",event->touch_ID5,status);
315 // printk("read status5= %d\n",status);
318 printk("point 5 release!\n");
319 ft5x0x_ts_release(data);
323 event->x4 = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16];
324 event->y4 = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18];
325 status = (s16)((buf[0x15] & 0xc0) >> 6);
326 //event->touch_ID4=(s16)(buf[0x17] & 0xF0);
327 event->touch_ID4=(s16)(buf[0x17] & 0xF0)>>4;
328 // printk("read ID4 = %d,read status4 = %d\n",event->touch_ID4,status);
331 printk("point 4 release!\n");
332 ft5x0x_ts_release(data);
338 event->x3 = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10];
339 event->y3 = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12];
340 status = (s16)((buf[0x0f] & 0xc0) >> 6);
341 // event->touch_ID3=(s16)(buf[0x11] & 0xF0);
342 event->touch_ID3=(s16)(buf[0x11] & 0xF0)>>4;
343 // printk("read ID3 = %d,read status3 = %d\n",event->touch_ID3,status);
346 printk("point 3 release!\n");
347 ft5x0x_ts_release(data);
354 event->x2 = (s16)(buf[9] & 0x0F)<<8 | (s16)buf[10];
355 event->y2 = (s16)(buf[11] & 0x0F)<<8 | (s16)buf[12];
356 status = (s16)((buf[0x9] & 0xc0) >> 6);
357 // event->touch_ID2=(s16)(buf[0x0b] & 0xF0);
358 event->touch_ID2=(s16)(buf[0x0b] & 0xF0)>>4;
359 // printk("read ID2 = %d,read status2 = %d\n",event->touch_ID2,status);
362 printk("point 2 release!\n");
363 ft5x0x_ts_release(data);
369 event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
370 event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
371 status = ((buf[0x3] & 0xc0) >> 6);
372 event->status= status ;
373 // event->touch_ID1=(s16)(buf[5] & 0xF0);
374 event->touch_ID1=(s16)(buf[0x05] & 0xF0)>>4;
375 //printk("status1= %d\n",event->status);
378 printk("point 1 release!\n");
379 ft5x0x_ts_release(data);
391 if((event->touch_point ==1)
392 &&((event->y1<BACK_KEY_MIN) ||(event->y2>MENU_KEY_MAX)))
394 ft5x0x_ts_release(data);
398 if(((event->touch_point - cnt) ==0)&&(event->touch_point >1))
400 ft5x0x_ts_release(data);
405 if (event->touch_point == 1) {
406 event->x1 = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4];
407 event->y1 = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6];
410 event->pressure =200; //200;
412 // printk("status2= %d\n",event->status);
417 static void ft5x0x_report_value(struct ft5x0x_ts_data *data )
419 //struct ft5x0x_ts_data *data = i2c_get_clientdata(&ft5x0x_client);
420 struct ts_event *event = &data->event;
422 #if CONFIG_FT5X0X_MULTITOUCH //#ifdef
423 switch(event->touch_point) {
427 if(event->x5 <= 1024)
429 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID5);
430 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
431 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x5);
432 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y5);
433 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
434 input_mt_sync(data->input_dev);
436 // printk("===x5 = %d,y5 = %d ====\n",event->x5,event->y5);
438 if(event->x4 <= 1024)
440 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID4);
441 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
442 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x4);
443 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y4);
444 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
445 input_mt_sync(data->input_dev);
447 // printk("===x4 = %d,y4 = %d ====\n",event->x4, event->y4);
449 if(event->x3 <= 1024)
451 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID3);
452 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
453 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x3);
454 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y3);
455 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
456 input_mt_sync(data->input_dev);
458 // printk("===x3 = %d,y3 = %d ====\n",event->x3, event->y3);
461 if(event->x2 <= 1024)
463 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID2);
464 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
465 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x2);
466 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y2);
467 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
468 input_mt_sync(data->input_dev);
470 // printk("===x2 = %d,y2 = %d ====\n",event->x2,event->y2);
472 input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID1);
473 input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
474 input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x1);
475 input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y1);
476 input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1);
477 input_mt_sync(data->input_dev);
478 // printk("===x1 = %d,y1 = %d ====\n",event->x1,event->y1);
480 // printk("==touch_point default =\n");
481 // printk("read status0= %d\n",event->status);
482 // if (event->status== 1) {
483 // printk("point 0 release!\n");
484 // ft5x0x_ts_release(data);
488 #else /* CONFIG_FT5X0X_MULTITOUCH*/
489 //if (event->touch_point == 1) {
490 input_report_abs(data->input_dev, ABS_X, event->x1);
491 input_report_abs(data->input_dev, ABS_Y, event->y1);
492 input_report_abs(data->input_dev, ABS_PRESSURE, event->pressure);
494 //printk("x = %d,y = %d\n",event->x1,event->y1);
495 input_report_key(data->input_dev, BTN_TOUCH, 1);
496 #endif /* CONFIG_FT5X0X_MULTITOUCH*/
497 input_sync(data->input_dev);
499 // printk("status3= %d\n",event->status);
502 } /*end ft5x0x_report_value*/
504 static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
507 // printk("==work 1=\n");
509 struct ft5x0x_ts_data *ft5x0x_ts =
510 container_of(work, struct ft5x0x_ts_data, pen_event_work);
513 ret = ft5x0x_read_data(ft5x0x_ts);
515 ft5x0x_report_value(ft5x0x_ts);
516 // printk("==work 2=\n");
518 // else printk("data package read error\n");
519 // printk("==work 2=\n");
521 enable_irq(ft5x0x_ts->irq);
523 // gpio_irq_enable(TOUCH_INT_IOPIN);
526 static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id)
529 struct ft5x0x_ts_data *ft5x0x_ts = dev_id;
531 //printk("ft5x0x_ts irq =%d",ft5x0x_ts->irq);
533 disable_irq_nosync(ft5x0x_ts->irq);
534 // disable_irq(ft5x0x_ts->irq);
536 //gpio_irq_disable(ft5x0x_ts->irq);
538 if (!work_pending(&ft5x0x_ts->pen_event_work))
540 queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work);
541 // printk("ft5x0x_ts_work!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
548 static int __devexit ft5406_remove(struct i2c_client *client)
550 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
552 // printk("==ft5x0x_ts_remove=\n");
554 // free_irq(client->irq, ft5x0x_ts);
555 // free_irq(7, ft5x0x_ts);
556 free_irq(ft5x0x_ts->irq, ft5x0x_ts);
558 input_unregister_device(ft5x0x_ts->input_dev);
560 cancel_work_sync(&ft5x0x_ts->pen_event_work);
561 destroy_workqueue(ft5x0x_ts->ts_workqueue);
562 i2c_set_clientdata(client, NULL);
563 #ifdef CONFIG_HAS_EARLYSUSPEND
564 unregister_early_suspend(&ft5406_early_suspend);
572 #ifdef CONFIG_HAS_EARLYSUSPEND
573 static int ft5x0x_ts_suspend(struct early_suspend *h)
581 // printk("==ft5x0x_ts_suspend=\n");
584 // struct ft5x0x_ts_data *ts;
585 // ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);
587 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
588 if (device_may_wakeup(&client->dev))
589 enable_irq_wake(ft5x0x_ts->irq);
591 // disable_irq(ft5x0x_client->irq);
592 // cancel_work_sync(&ts->pen_event_work);
593 // flush_workqueue(ts->ts_workqueue);
597 buf[0]=PMODE_HIBERNATE;
600 err=ft5406_set_regs(this_client,FT5X0X_REG_PMODE, buf,1);
601 // printk("==ft5406 suspend write 111=%d\n",buf[0]);
609 // printk("==ft5406 suspend write222=%d\n",buf[0]);
610 ft5406_set_regs(this_client,FT5X0X_REG_PMODE, buf,1);
614 // printk("==ft5406 suspend write=%d\n",buf[0]);
615 // printk("==ft5406 suspend write err=%d\n",err);
616 // msleep(50); //harry 2011.04.20
617 // err = ft5406_read_regs(this_client,FT5X0X_REG_PMODE,buf_r,1);
618 // printk("==ft5406 suspend read=%d\n",buf_r[0]);
619 // printk("==ft5406 suspend read err=%d\n",err);
628 static int ft5x0x_ts_resume(struct early_suspend *h)
630 //printk("==ft5x0x_ts_resume=\n");
632 struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
633 if (device_may_wakeup(&client->dev))
634 disable_irq_wake(ft5x0x_ts->irq);
637 // __gpio_as_output(GPIO_FT5X0X_WAKE);
638 // __gpio_clear_pin(GPIO_FT5X0X_WAKE); //set wake = 0,base on system
640 // __gpio_set_pin(GPIO_FT5X0X_WAKE); //set wake = 1,base on system
642 // enable_irq(IRQ_EINT(6));
645 gpio_direction_output(TOUCH_RESET_PIN, 0);
646 gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
647 msleep(20); //harry 2011.04.20
648 gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
655 static int ft5406_probe(struct i2c_client *client ,const struct i2c_device_id *id)
657 struct ft5x0x_ts_data *ft5x0x_ts;
658 struct input_dev *input_dev;
659 struct ft5406_platform_data *pdata = pdata = client->dev.platform_data;
666 //printk("==ft5x0x_ts_probe=\n");
669 dev_err(&client->dev, "platform data is required!\n");
673 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
677 ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL);
680 goto exit_alloc_data_failed;
683 ft5x0x_client.adapter = bus;
684 ft5x0x_client.addr= address;
685 ft5x0x_client.mode = NORMALMODE; //NORMALNOSTOPMODE;// DIRECTMODE;
686 ft5x0x_client.Channel = I2C_CH0;
687 ft5x0x_client.speed = 300;
688 ft5x0x_client.addressBit=I2C_7BIT_ADDRESS_8BIT_REG;
689 ft5x0x_ts->client=&ft5x0x_client;
691 i2c_set_clientdata(&ft5x0x_client, ft5x0x_ts);
693 err = i2c_attach_client(&ft5x0x_client);
696 printk("ft5x0x attach client failed!!!!\n");
697 goto exit_alloc_data_failed;
700 INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
701 ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts");
702 if (!ft5x0x_ts->ts_workqueue) {
704 goto exit_create_singlethread;
707 rockchip_mux_api_set(TOUCH_INT_IOMUX_PINNAME,TOUCH_INT_IOMUX_PINDIR);
708 GPIOSetPinDirection(TOUCH_INT_IOPIN, GPIO_IN);
709 GPIOPullUpDown(TOUCH_INT_IOPIN, GPIOPullUp);
710 err = request_gpio_irq(TOUCH_INT_IOPIN, ft5x0x_ts_interrupt, GPIOEdgelFalling, ft5x0x_ts);
713 printk("ft5x0x_probe: request irq failed\n");
714 goto exit_irq_request_failed;
717 input_dev = input_allocate_device();
720 printk("failed to allocate input device\n");
721 goto exit_input_dev_alloc_failed;
724 this_client = client;
725 ft5x0x_ts->client = client;
726 ft5x0x_ts->irq = client->irq;
727 ft5x0x_ts->input_dev = input_dev;
729 #if CONFIG_FT5X0X_MULTITOUCH //#ifdef
730 set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
731 set_bit(ABS_MT_POSITION_X, input_dev->absbit);
732 set_bit(ABS_MT_POSITION_Y, input_dev->absbit);
733 set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
735 //input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN); //harry 03.21
736 #if CONFIG_TOUCH_PANEL_KEY
737 set_bit(KEY_HOME, input_dev->keybit);
738 set_bit(KEY_MENU, input_dev->keybit);
739 set_bit(KEY_BACK, input_dev->keybit);
742 input_set_abs_params(input_dev,
743 ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
744 input_set_abs_params(input_dev,
745 ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
746 input_set_abs_params(input_dev,
747 ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
748 input_set_abs_params(input_dev,
749 ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
750 input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0);
752 set_bit(ABS_X, input_dev->absbit);
753 set_bit(ABS_Y, input_dev->absbit);
754 set_bit(ABS_PRESSURE, input_dev->absbit);
755 set_bit(BTN_TOUCH, input_dev->keybit);
757 input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);
758 input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);
759 input_set_abs_params(input_dev,
760 ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);
764 set_bit(EV_ABS, input_dev->evbit);
765 set_bit(EV_KEY, input_dev->evbit);
767 input_dev->name = FT5X0X_NAME; //dev_name(&client->dev)
768 err = input_register_device(input_dev);
770 // printk("ft5x0x_ts_probe: failed to register input device: \n");
771 goto exit_input_register_device_failed;
774 // printk("==probe over =\n");
775 if (pdata->init_platform_hw)
776 pdata->init_platform_hw();
778 if (!ft5x0x_ts->irq) {
779 dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n");
782 ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq);
785 //printk("ft5x0x_ts irq =%d", ft5x0x_ts->irq);
788 INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);
789 ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts");
790 if (!ft5x0x_ts->ts_workqueue) {
792 goto exit_create_singlethread;
797 //printk("client->dev.driver->name %s ,%d \n",client->dev.driver->name,ft5x0x_ts->irq);
800 ret = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, /*IRQF_TRIGGER_LOW*/IRQF_TRIGGER_FALLING, //IRQF_DISABLED|IRQF_TRIGGER_FALLING,
801 client->dev.driver->name, ft5x0x_ts);
804 dev_err(&client->dev, "irq %d busy?\n", ft5x0x_ts->irq);
809 ret = input_register_device(input_dev);
812 // printk("ft5406 register input device failed!!!!\n");
813 goto exit_irq_request_failed;
817 #ifdef CONFIG_HAS_EARLYSUSPEND
818 ft5406_early_suspend.suspend =ft5x0x_ts_suspend;
819 ft5406_early_suspend.resume =ft5x0x_ts_resume;
820 ft5406_early_suspend.level = 0x2;
821 register_early_suspend(&ft5406_early_suspend);
824 //buf_w[0] = 6; //harry 04.07
827 err = ft5406_set_regs(client,0x88,buf_w,1);
828 //ft5x0x_i2c_txdata(0x88, buf_w, 1); /* adjust frequency 60Hz */
831 err = ft5406_read_regs(client,0x88,buf_r,1);
832 //ft5x0x_i2c_rxdata(0x88, buf_r, 1);
833 // printk("read buf[0x88] = %d\n", buf_r[0]);
837 free_irq(ft5x0x_ts->irq,ft5x0x_ts);
838 i2c_set_clientdata(client, NULL); //harry
839 destroy_workqueue(ft5x0x_ts->ts_workqueue); //harry
840 exit_input_register_device_failed:
841 input_free_device(input_dev);
842 // i2c_set_clientdata(client, NULL);
845 exit_input_dev_alloc_failed:
846 // free_irq(7, ft5x0x_ts);
847 free_irq(ft5x0x_ts->irq, ft5x0x_ts);
848 exit_irq_request_failed:
849 exit_platform_data_null:
850 cancel_work_sync(&ft5x0x_ts->pen_event_work);
851 destroy_workqueue(ft5x0x_ts->ts_workqueue);
852 exit_create_singlethread:
853 printk("==singlethread error =\n");
855 exit_alloc_data_failed:
861 static struct i2c_device_id ft5406_idtable[] = {
866 MODULE_DEVICE_TABLE(i2c, ft5406_idtable);
868 static struct i2c_driver ft5406_driver = {
870 .owner = THIS_MODULE,
873 .id_table = ft5406_idtable,
874 .probe = ft5406_probe,
875 #ifndef CONFIG_HAS_EARLYSUSPEND
876 .suspend = ft5x0x_ts_suspend,
877 .resume = ft5x0x_ts_resume,
879 .remove = __devexit_p(ft5406_remove),
882 static int __init ft5x0x_ts_init(void)
884 return i2c_add_driver(&ft5406_driver);
887 static void __exit ft5x0x_ts_exit(void)
889 i2c_del_driver(&ft5406_driver);
892 module_init(ft5x0x_ts_init);
893 module_exit(ft5x0x_ts_exit);
895 MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
896 MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");