1 /****************************************************************************************
\r
2 * driver/input/touchscreen/i2cpca955x.c
\r
3 *Copyright :ROCKCHIP Inc
\r
6 *This driver use for rk28 chip extern touchscreen. Use i2c IF ,the chip is pca955x
\r
8 ********************************************************************************************/
\r
9 #include <linux/module.h>
\r
10 #include <linux/delay.h>
\r
11 #include <linux/earlysuspend.h>
\r
12 #include <linux/hrtimer.h>
\r
13 #include <linux/i2c.h>
\r
14 #include <linux/input.h>
\r
15 #include <linux/interrupt.h>
\r
16 #include <linux/io.h>
\r
17 #include <linux/platform_device.h>
\r
18 #include <linux/async.h>
\r
19 #include <linux/workqueue.h>
\r
20 #include <mach/gpio.h>
\r
21 #include <linux/irq.h>
\r
22 #include <mach/board.h>
\r
24 #ifdef CONFIG_ANDROID_POWER
\r
25 #include <linux/android_power.h>
\r
28 #define IT7260_DEBUG 0
\r
31 #define it7250_debug(msg...) printk(msg)
\r
33 #define it7250_debug(msg...)
\r
36 /******************************************
\r
38 *** ***************************************/
\r
39 #define IT7260_IIC_SPEED 200*1000
\r
41 #define IT7260_MAX_X 800//1024//1020//800
\r
42 #define IT7260_MAX_Y 600//768//600//480
\r
44 #define Mulitouch_Mode 1
\r
45 #define Singltouch_Mode 0
\r
51 struct MultiTouch_event{
\r
59 #define TS_POLL_DELAY (10*1000000) /* ns delay before the first sample */
\r
60 #define TS_POLL_PERIOD (15*1000000) /* ns delay between samples */
\r
63 struct i2c_client *client;
\r
64 struct input_dev *input;
\r
69 struct touch_event point;
\r
71 struct MultiTouch_event point;
\r
76 struct delayed_work work;
\r
77 struct workqueue_struct *wq;
\r
81 struct timer_list timer;//hrtimer timer;
\r
82 int has_relative_report;
\r
86 #define COMMAND_BUFFER_INDEX 0x20
\r
87 #define QUERY_BUFFER_INDEX 0x80
\r
88 #define COMMAND_RESPONSE_BUFFER_INDEX 0xA0
\r
89 #define POINT_BUFFER_INDEX 0xE0
\r
90 #define QUERY_SUCCESS 0x00
\r
91 #define QUERY_BUSY 0x01
\r
92 #define QUERY_ERROR 0x02
\r
93 #define QUERY_POINT 0x80
\r
96 static char cal_status = 0;
\r
98 /*read the it7260 register ,used i2c bus*/
\r
99 static int it7260_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
\r
102 ret = i2c_master_reg8_recv(client, reg, buf, len, IT7260_IIC_SPEED);
\r
107 /* set the it7260 registe,used i2c bus*/
\r
108 static int it7260_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
\r
111 ret = i2c_master_reg8_send(client, reg, buf, (int)len, IT7260_IIC_SPEED);
\r
115 void ReadQueryBuffer(struct i2c_client *client,u8 pucData[])
\r
117 it7260_read_regs(client,QUERY_BUFFER_INDEX,pucData,1);
\r
120 bool ReadCommandResponseBuffer(struct i2c_client *client,u8 pucData[], unsigned int unDataLength)
\r
122 return it7260_read_regs(client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,unDataLength);
\r
126 bool ReadPointBuffer(struct i2c_client *client,u8 pucData[])
\r
128 return it7260_read_regs(client,POINT_BUFFER_INDEX,pucData,14);
\r
133 int WriteCommandBuffer(struct i2c_client *client,u8 pucData[], unsigned int unDataLength)
\r
135 return it7260_set_regs(client,COMMAND_BUFFER_INDEX,pucData,unDataLength);
\r
143 static void it7260_chip_sleep(void)
\r
146 u8 pucPoint1[12] ={0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
\r
147 u8 pucPoint2[12] ={0x11,0x01,0x01};
\r
149 aaa = WriteCommandBuffer(ts_dev->client,pucPoint1, 10);
\r
152 printk("set mode err\n");
\r
154 aaa = WriteCommandBuffer(ts_dev->client,pucPoint2, 3);
\r
160 static void it7260_chip_wakeup(void)
\r
166 struct it7260_dev *g_dev;
\r
171 u8 ucWriteLength, ucReadLength;
\r
175 ucReadLength = 0x0A;
\r
182 ReadQueryBuffer(g_dev->client,&ucQuery);
\r
185 }while(ucQuery & QUERY_BUSY);
\r
187 //IdentifyCapSensor
\r
188 WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);
\r
190 it7260_read_regs(g_dev->client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,10);
\r
191 printk("[%c][%c][%c][%c][%c][%c][%c]\n",pucData[1],pucData[2],pucData[3],pucData[4],pucData[5],pucData[6],pucData[7]);
\r
197 WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);
\r
199 it7260_read_regs(g_dev->client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,2);
\r
200 printk("[%x][%x]\n",pucData[0],pucData[1]);
\r
207 WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);
\r
212 WriteCommandBuffer(g_dev->client,pucData, ucWriteLength);
\r
214 it7260_read_regs(g_dev->client,COMMAND_RESPONSE_BUFFER_INDEX,pucData,2);
\r
216 printk("[%x][%x]\n",pucData[0],pucData[1]);
\r
217 // printk("[%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x]\n",pucData[0],pucData[1],pucData[2],pucData[3],pucData[4],pucData[5],pucData[6],
\r
218 // pucData[7],pucData[8],pucData[9],pucData[10],pucData[11],pucData[12],pucData[13]);
\r
221 /* if(pucData[1] != 'I'
\r
222 || pucData[2] != 'T'
\r
223 || pucData[3] != 'E'
\r
224 || pucData[4] != '7'
\r
225 || pucData[5] != '2'
\r
226 || pucData[6] != '6'
\r
227 || pucData[7] != '0')
\r
229 // firmware signature is not match
\r
241 static int set_mode(struct it7260_dev *ts_dev)
\r
243 u8 pucPoint[12] ={0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
\r
245 printk("start to calibration......\n");
\r
246 ret = WriteCommandBuffer(ts_dev->client,pucPoint, 12);
\r
249 printk("set mode err\n");
\r
254 printk("it7260 set mode ok\n");
\r
260 static int set_sleep_mode(struct it7260_dev *ts_dev)
\r
262 u8 pucPoint[3] ={0x04,0x00,0x02};
\r
263 u8 pucPoint1[2] ={0x11,0x01};
\r
265 aaa = WriteCommandBuffer(ts_dev->client,pucPoint1, 2);
\r
266 //aaa = WriteCommandBuffer(ts_dev->client,pucPoint, 3);
\r
269 printk("set mode err\n");
\r
274 static int set_active_mode(struct it7260_dev *ts_dev)
\r
276 u8 pucPoint[12] ={0x04,0x00,0x00};
\r
278 aaa = WriteCommandBuffer(ts_dev->client,pucPoint, 3);
\r
281 printk("set mode err\n");
\r
286 static int read_point(struct it7260_dev *ts_dev )
\r
294 int xraw, yraw, xtmp, ytmp;
\r
295 char pressure_point,z,w;
\r
296 int finger2_pressed=0;
\r
299 ReadQueryBuffer(ts_dev->client,&ucQuery);
\r
300 it7250_debug("ucQuery = 0x%x\n",ucQuery);
\r
303 it7250_debug("ucQuery == 0 return \n");
\r
311 ReadCommandResponseBuffer(ts_dev->client,readbuf, 2);
\r
312 it7250_debug(" read buf [0] = 0x0%x , buf [1] = 0x0%x\n",readbuf[0],readbuf[1]);
\r
313 it7260_read_regs(ts_dev->client,POINT_BUFFER_INDEX,pucPoint,14);
\r
321 it7260_read_regs(ts_dev->client,POINT_BUFFER_INDEX,pucPoint,14);
\r
323 if(pucPoint[0] & 0xF0)
\r
325 it7250_debug("a\n");
\r
329 if(pucPoint[1] & 0x01)
\r
331 it7250_debug("b\n");
\r
337 if(((pucPoint[0] & 0x07)==0)/*|| GPIOGetPinLevel(it7260_IRQ_PIN)*/)
\r
339 //sisdbg("=Read_Point pull= [%d][%d]\n",pucPoint[0] & 0x07,GPIOGetPinLevel(it7260_IRQ_PIN));
\r
340 #if Singltouch_Mode
\r
341 ts_dev->status = 0;
\r
344 input_report_key(ts_dev->input, BTN_TOUCH, 0);
\r
345 //input_report_abs(ts_dev->input, ABS_PRESSURE, 0);
\r
346 input_sync(ts_dev->input);
\r
350 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, 0);
\r
351 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, 15);
\r
352 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, ts_dev->point.x1);
\r
353 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ts_dev->point.y1);
\r
354 input_report_key(ts_dev->input, BTN_TOUCH, 0);
\r
355 input_mt_sync(ts_dev->input);
\r
356 it7250_debug("TP up\n");
\r
357 if(ts_dev->has_relative_report ==2)
\r
359 ts_dev->has_relative_report = 0;
\r
360 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, 0);
\r
361 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, 15);
\r
362 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, ts_dev->point.x2);
\r
363 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ts_dev->point.y2);
\r
364 input_report_key(ts_dev->input, BTN_2, 0);
\r
365 it7250_debug("TP up\n");
\r
366 input_mt_sync(ts_dev->input);
\r
368 input_sync(ts_dev->input);
\r
376 if(pucPoint[0] & 0x01)
\r
379 xraw = ((pucPoint[3] & 0x0F) << 8) + pucPoint[2];
\r
380 yraw = ((pucPoint[3] & 0xF0) << 4) + pucPoint[4];
\r
381 pressure_point=pucPoint[5]&0x0f;
\r
385 ts_dev->point.x1 = xtmp;
\r
386 ts_dev->point.y1 = ytmp;
\r
387 ts_dev->has_relative_report = 1;
\r
389 if(pressure_point==4)
\r
399 it7250_debug("=Read_Point1 x=%d y=%d p=%d=\n",xtmp,ytmp,pressure_point);
\r
401 #if Singltouch_Mode
\r
402 if(ts_dev->pass == 1)
\r
408 if(ts_dev->status == 0)
\r
410 ts_dev->status = 1;
\r
411 input_report_abs(ts_dev->input, ABS_X, xtmp);
\r
412 input_report_abs(ts_dev->input, ABS_Y, ytmp);
\r
413 input_report_key(ts_dev->input, BTN_TOUCH, 1);
\r
415 input_report_abs(ts_dev->input, ABS_X, xtmp);
\r
416 input_report_abs(ts_dev->input, ABS_Y, ytmp);
\r
419 input_report_abs(ts_dev->input, ABS_PRESSURE, 1);
\r
420 ts_dev->pendown = 1;
\r
421 input_sync(ts_dev->input);
\r
424 if(ts_dev->pass == 1)
\r
430 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, z);
\r
431 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, w);
\r
432 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, xtmp);
\r
433 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ytmp);
\r
434 input_report_key(ts_dev->input, BTN_TOUCH, 1);
\r
435 ts_dev->pendown = 1;
\r
436 it7250_debug("TP down\n");
\r
437 input_mt_sync(ts_dev->input);
\r
443 if(pucPoint[0] & 0x02)
\r
445 xraw = ((pucPoint[7] & 0x0F) << 8) + pucPoint[6];
\r
446 yraw = ((pucPoint[7] & 0xF0) << 4) + pucPoint[8];
\r
447 pressure_point=pucPoint[9]&0x0f;
\r
450 ts_dev->point.x2 = xtmp;
\r
451 ts_dev->point.y2 = ytmp;
\r
452 ts_dev->has_relative_report = 2;
\r
453 it7250_debug("=Read_Point2 x=%d y=%d p=%d=\n",xtmp,ytmp,pressure_point);
\r
454 if(pressure_point==4)
\r
464 #if Singltouch_Mode
\r
465 if(ts_dev->pass == 1)
\r
471 input_report_abs(ts_dev->input, ABS_X, xtmp);
\r
472 input_report_abs(ts_dev->input, ABS_Y, ytmp);
\r
473 input_report_key(ts_dev->input, BTN_TOUCH, 1);
\r
474 ts_dev->pendown = 1;
\r
475 input_sync(ts_dev->input);
\r
477 if(ts_dev->pass == 1)
\r
483 input_report_abs(ts_dev->input, ABS_MT_TOUCH_MAJOR, z);
\r
484 input_report_abs(ts_dev->input, ABS_MT_WIDTH_MAJOR, w);
\r
485 input_report_abs(ts_dev->input, ABS_MT_POSITION_X, xtmp);
\r
486 input_report_abs(ts_dev->input, ABS_MT_POSITION_Y, ytmp);
\r
487 input_report_key(ts_dev->input, BTN_2, 1);
\r
488 ts_dev->pendown = 1;
\r
489 it7250_debug("TP down\n");
\r
490 input_mt_sync(ts_dev->input);
\r
497 input_sync(ts_dev->input);
\r
504 static void it7260_dostimer(unsigned long data)
\r
506 struct it7260_dev *ts_dev = (struct it7260_dev *)data;
\r
507 read_point(ts_dev);
\r
511 static void it7260_work(struct work_struct *work)
\r
513 struct it7260_dev *ts_dev =
\r
514 container_of(to_delayed_work(work), struct it7260_dev, work);
\r
515 read_point(ts_dev);
\r
518 if (ts_dev->pendown){
\r
519 queue_delayed_work(ts_dev->wq, &ts_dev->work, msecs_to_jiffies(10));
\r
520 ts_dev->pendown = 0;
\r
523 enable_irq(ts_dev->irq);
\r
527 static irqreturn_t it7260_irq_hander(int irq, void *handle)
\r
529 struct it7260_dev *ts_dev = handle;
\r
531 if (1/*!ts_dev->get_pendown || likely(ts_dev->get_pendown_state())*/) {
\r
532 disable_irq_nosync(ts_dev->irq);
\r
533 queue_delayed_work(ts_dev->wq, &ts_dev->work, 0);
\r
539 static int it7260_detach_client(struct i2c_client *client)
\r
541 printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);
\r
545 static void it7260_shutdown(struct i2c_client *client)
\r
547 printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);
\r
549 #ifdef CONFIG_ANDROID_POWER
\r
550 static void suspend(android_early_suspend_t *h)
\r
552 printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);
\r
554 static void resume(android_early_suspend_t *h)
\r
556 printk("************>%s.....%s.....\n",__FILE__,__FUNCTION__);
\r
558 static android_early_suspend_t ts_early_suspend;
\r
561 ssize_t tp_cal_show(struct kobject *kobj, struct kobj_attribute *attr,
\r
562 const char *buf, size_t count)
\r
566 return sprintf(buf,"successful");
\r
568 return sprintf(buf,"fail");
\r
571 ssize_t tp_cal_store(struct kobject *kobj, struct kobj_attribute *attr,
\r
572 const char *buf, size_t count)
\r
575 if( !strncmp(buf,"tp_cal" , strlen("tp_cal")) )
\r
583 struct kobj_attribute tp_cal_attrs =
\r
586 .name = "tp_calibration",
\r
588 .show = tp_cal_show,
\r
589 .store = tp_cal_store,
\r
592 struct attribute *tp_attrs[] =
\r
594 &tp_cal_attrs.attr,
\r
598 static struct kobj_type tp_kset_ktype = {
\r
599 .sysfs_ops = &kobj_sysfs_ops,
\r
600 .default_attrs = &tp_attrs[0],
\r
602 static int tp_cal_add_attr(struct it7260_dev *ts_dev)
\r
605 struct input_dev *input;
\r
606 struct kobject *parentkobject;
\r
607 struct kobject * me = kmalloc(sizeof(struct kobject) , GFP_KERNEL );
\r
610 memset(me ,0,sizeof(struct kobject));
\r
611 kobject_init( me , &tp_kset_ktype );
\r
612 parentkobject = &ts_dev->input->dev.kobj ;
\r
613 result = kobject_add( me , parentkobject->parent->parent->parent, "%s", "tp_calibration" );
\r
617 static void it7260_remove(struct i2c_client * client)
\r
621 static int it7260_probe(struct i2c_client *client ,const struct i2c_device_id *id)
\r
623 struct it7260_dev *ts_dev;
\r
624 struct input_dev *input;
\r
625 struct it7260_platform_data *pdata = pdata = client->dev.platform_data;
\r
630 dev_err(&client->dev, "platform data is required!\n");
\r
634 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
\r
637 ts_dev=kzalloc(sizeof(struct it7260_dev), GFP_KERNEL);
\r
640 printk("it7260 failed to allocate memory!!\n");
\r
644 input = input_allocate_device();
\r
647 printk("it7260 allocate input device failed!!!\n");
\r
651 ts_dev->client = client;
\r
652 ts_dev->status = 0;
\r
653 ts_dev->pendown = 0;
\r
655 ts_dev->input = input;
\r
656 ts_dev->irq = client->irq;
\r
657 ts_dev->has_relative_report = 0;
\r
658 snprintf(ts_dev->phys, sizeof(ts_dev->phys),
\r
659 "%s/input0", dev_name(&client->dev));
\r
660 input->name = "it7260 touchscreen";
\r
661 input->phys = ts_dev->phys;
\r
662 input->id.bustype = BUS_I2C;
\r
665 ts_dev->wq = create_rt_workqueue("it7260_wq");
\r
666 INIT_DELAYED_WORK(&ts_dev->work, it7260_work);
\r
668 #if Singltouch_Mode
\r
669 input->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN);
\r
670 input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
\r
671 input_set_abs_params(input, ABS_X, 0, IT7260_MAX_X, 0, 0);
\r
672 input_set_abs_params(input, ABS_Y, 35, IT7260_MAX_Y , 0, 0);
\r
674 input->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN);
\r
675 input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
\r
676 input->keybit[BIT_WORD(BTN_2)] = BIT_MASK(BTN_2); //jaocbchen for dual
\r
678 input_set_abs_params(input, ABS_X, 0, IT7260_MAX_X, 0, 0);
\r
679 input_set_abs_params(input, ABS_Y, 0, IT7260_MAX_Y, 0, 0);
\r
680 input_set_abs_params(input, ABS_PRESSURE, 0, 255, 0, 0);
\r
681 input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 15, 0, 0);
\r
682 input_set_abs_params(input, ABS_HAT0X, 0, IT7260_MAX_X, 0, 0);
\r
683 input_set_abs_params(input, ABS_HAT0Y, 0, IT7260_MAX_Y, 0, 0);
\r
684 input_set_abs_params(input, ABS_MT_POSITION_X,0, IT7260_MAX_X, 0, 0);
\r
685 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, IT7260_MAX_Y, 0, 0);
\r
686 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
\r
687 input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
\r
689 for (i = 0; i < (BITS_TO_LONGS(ABS_CNT)); i++)
\r
690 printk("%s::input->absbit[%d] = 0x%x \n",__FUNCTION__,i,input->absbit[i]);
\r
693 if (pdata->init_platform_hw)
\r
694 pdata->init_platform_hw();
\r
696 if (!ts_dev->irq) {
\r
697 dev_dbg(&ts_dev->client->dev, "no IRQ?\n");
\r
700 ts_dev->irq = gpio_to_irq(ts_dev->irq);
\r
703 printk("client->dev.driver->name %s\n",client->dev.driver->name);
\r
704 ret = request_irq(ts_dev->irq, it7260_irq_hander, IRQF_TRIGGER_LOW,
\r
705 client->dev.driver->name, ts_dev);
\r
708 dev_err(&client->dev, "irq %d busy?\n", ts_dev->irq);
\r
712 ret = input_register_device(input);
\r
715 printk("it7260 register input device failed!!!!\n");
\r
719 #ifdef CONFIG_ANDROID_POWER
\r
720 ts_early_suspend.suspend = suspend;
\r
721 ts_early_suspend.resume = resume;
\r
722 android_register_early_suspend(&ts_early_suspend);
\r
728 printk("it7260 register input device ok!!!!\n");
\r
732 free_irq(ts_dev->irq,ts_dev);
\r
735 input_unregister_device(input);
\r
738 input_free_device(input);
\r
746 static struct i2c_device_id it7260_idtable[] = {
\r
747 { "it7260_touch", 0 },
\r
751 MODULE_DEVICE_TABLE(i2c, it7260_idtable);
\r
753 static struct i2c_driver it7260_driver = {
\r
755 .owner = THIS_MODULE,
\r
756 .name = "it7260_touch"
\r
758 .id_table = it7260_idtable,
\r
759 .probe = it7260_probe,
\r
760 .remove = __devexit_p(it7260_remove),
\r
763 static int __init it7260_init(void)
\r
765 return i2c_add_driver(&it7260_driver);
\r
768 static void __exit it7260_exit(void)
\r
770 i2c_del_driver(&it7260_driver);
\r
772 module_init(it7260_init);
\r
773 module_exit(it7260_exit);
\r
774 MODULE_DESCRIPTION ("it7260 touchscreen driver");
\r
775 MODULE_AUTHOR("llx<llx@rockchip.com>");
\r
776 MODULE_LICENSE("GPL");
\r