newton:optimize ft5406,modify supend and resume for ft5406 and gt819
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / gt819.c
1 /* drivers/input/touchscreen/goodix_touch.c
2  *
3  * Copyright (C) 2010 - 2011 Goodix, Inc.
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/time.h>
19 #include <linux/delay.h>
20 #include <linux/device.h>
21 #include <linux/earlysuspend.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 <mach/gpio.h>
29 #include <linux/irq.h>
30 #include <linux/syscalls.h>
31 #include <linux/reboot.h>
32 #include <linux/proc_fs.h>
33 #include <linux/vmalloc.h>
34 #include <linux/fs.h>
35 #include <linux/string.h>
36 #include <linux/completion.h>
37 #include <asm/uaccess.h>
38 #include <mach/board.h>
39
40 #define GOODIX_I2C_NAME "Goodix-TS"
41 //define default resolution of the touchscreen
42 #define GOODIX_MULTI_TOUCH
43 #define GT819_IIC_SPEED              400*1000    //400*1000
44 #define TOUCH_MAX_WIDTH              800
45 #define TOUCH_MAX_HEIGHT             480
46 #define TOUCH_MAJOR_MAX              200
47 #define WIDTH_MAJOR_MAX              200
48 #define MAX_POINT                    10
49 #define INT_TRIGGER_EDGE_RISING      0
50 #define INT_TRIGGER_EDGE_FALLING     1
51 #define INT_TRIGGER_EDGE_LOW         2
52 #define INT_TRIGGER_EDGE_HIGH        3
53 #define INT_TRIGGER                  INT_TRIGGER_EDGE_FALLING
54 #define I2C_DELAY                    0x0f
55 struct goodix_ts_data {
56         struct workqueue_struct *goodix_wq;
57         struct i2c_client *client;
58         struct input_dev *input_dev;
59         struct work_struct  work;
60         int irq;
61         int irq_gpio;
62         uint16_t abs_x_max;
63         uint16_t abs_y_max;
64         uint8_t max_touch_num;
65         uint8_t int_trigger_type;
66 };
67
68 static const char *goodix_ts_name = "Goodix Capacitive TouchScreen";
69
70 static int gt819_read_regs(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
71 {
72         int ret; 
73         ret = i2c_master_reg8_recv(client, reg, buf, len, GT819_IIC_SPEED);
74         return ret; 
75 }
76
77
78 static int gt819_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], unsigned short len)
79 {
80         int ret; 
81         ret = i2c_master_reg8_send(client, reg, buf, (int)len, GT819_IIC_SPEED);
82         return ret;
83 }
84
85 static void gt819_queue_work(struct work_struct *work)
86 {
87         struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data, work);
88         uint8_t  point_data[53]={ 0 };
89         int ret,i,offset,points;
90         int x,y,w;
91         
92         ret = gt819_read_regs(ts->client,1, point_data, 1);
93         if (ret < 0) {
94                 dev_err(&ts->client->dev, "i2c_read_bytes fail:%d!\n",ret);
95                 return;
96         }
97         
98         points = point_data[0] & 0x1f;
99         //dev_info(&ts->client->dev, "points = %d\n",points);
100         if (points == 0) {
101                 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
102                 input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
103                 //input_mt_sync(data->input_dev);
104                 input_sync(ts->input_dev);
105                 enable_irq(ts->irq);
106                 dev_info(&ts->client->dev, "touch release\n");
107                 return; 
108         }
109         for(i=0;0!=points;i++)
110                 points>>=1;
111         points = i;
112         ret = gt819_read_regs(ts->client,3, point_data, points*5);
113         if (ret < 0) {
114                 dev_err(&ts->client->dev, "i2c_read_bytes fail:%d!\n",ret);
115                 return;
116         }
117         for(i=0;i<points;i++){
118                 offset = i*5;
119                 x = (((s16)(point_data[offset+0]))<<8) | ((s16)point_data[offset+1]);
120                 y = (((s16)(point_data[offset+2]))<<8) | ((s16)point_data[offset+3]);
121                 w = point_data[offset+4];
122                 //dev_info(&ts->client->dev, "goodix multiple report event[%d]:x = %d,y = %d,w = %d\n",i,x,y,w);
123                 if(x<=TOUCH_MAX_WIDTH && y<=TOUCH_MAX_HEIGHT){
124                         //dev_info(&ts->client->dev, "goodix multiple report event[%d]:x = %d,y = %d,w = %d\n",i,x,y,w);
125                         input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
126                         input_report_abs(ts->input_dev, ABS_MT_POSITION_X,  x);
127                         input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,  y);
128                         input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i);
129                         input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
130                         input_mt_sync(ts->input_dev);
131                 }
132         }
133         input_sync(ts->input_dev);
134         enable_irq(ts->irq);
135         return;
136 }
137
138 /*******************************************************
139 Description:
140         External interrupt service routine.
141
142 Parameter:
143         irq:    interrupt number.
144         dev_id: private data pointer.
145         
146 return:
147         irq execute status.
148 *******************************************************/
149 static irqreturn_t gt819_irq_handler(int irq, void *dev_id)
150 {
151         struct goodix_ts_data *ts = dev_id;
152
153         disable_irq_nosync(ts->client->irq);
154         queue_work(ts->goodix_wq, &ts->work);
155         return IRQ_HANDLED;
156 }
157
158 static int gt819_suspend(struct i2c_client *client, pm_message_t mesg)
159 {
160         struct goodix_platform_data *pdata = client->dev.platform_data;
161         dev_info(&client->dev,"gt819_suspend\n");
162
163         if (pdata->platform_sleep)                              
164                 pdata->platform_sleep();
165         disable_irq(client->irq);
166         return 0;
167 }
168
169 static int gt819_resume(struct i2c_client *client)
170 {
171         struct goodix_platform_data *pdata = client->dev.platform_data;
172         dev_info(&client->dev,"gt819_resume\n");
173
174         enable_irq(client->irq);
175         if (pdata->platform_wakeup)                              
176                 pdata->platform_wakeup();
177         return 0;
178 }
179
180
181 /*******************************************************
182 Description:
183         Goodix touchscreen driver release function.
184
185 Parameter:
186         client: i2c device struct.
187         
188 return:
189         Executive outcomes. 0---succeed.
190 *******************************************************/
191 static int gt819_remove(struct i2c_client *client)
192 {
193         struct goodix_ts_data *ts = i2c_get_clientdata(client);
194 #ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP
195         remove_proc_entry("goodix-update", NULL);
196 #endif
197         //goodix_debug_sysfs_deinit();
198                 gpio_direction_input(ts->irq_gpio);
199                 gpio_free(ts->irq_gpio);
200                 free_irq(client->irq, ts);
201         if(ts->goodix_wq)
202                 destroy_workqueue(ts->goodix_wq); 
203         dev_notice(&client->dev,"The driver is removing...\n");
204         i2c_set_clientdata(client, NULL);
205         input_unregister_device(ts->input_dev);
206         kfree(ts);
207         return 0;
208 }
209
210 static int gt819_init_panel(struct goodix_ts_data *ts)
211 {
212         int ret,I2cDelay;
213         uint8_t rd_cfg_buf[10];
214         #if 0
215         int i;
216         uint8_t config_info[] = {
217         0x02,(TOUCH_MAX_WIDTH>>8),(TOUCH_MAX_WIDTH&0xff),
218         (TOUCH_MAX_HEIGHT>>8),(TOUCH_MAX_HEIGHT&0xff),MAX_POINT,(0xa0 | INT_TRIGGER),
219         0x20,0x00,0x32,0x0f,0x20,0x08,0x14,0x00,
220         0x00,0x20,0x00,0x00,0x88,0x88,0x88,0x00,0x37,0x00,0x00,0x00,0x01,0x02,0x03,0x04,
221         0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0xff,0xff,0x00,0x01,0x02,0x03,0x04,
222         0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0xff,0xff,0xff,0x00,0x00,0x3c,0x64,0x00,
223         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
224         0x00,0x00,0x00,0x00
225         };
226         ret = gt819_set_regs(ts->client, 101, config_info, sizeof(config_info));
227         for (i=0; i<sizeof(config_info); i++) {
228                 //printk("buf[%d] = 0x%x \n", i, config_info[i]);
229         }
230         #endif
231         ret = gt819_read_regs(ts->client, 101, rd_cfg_buf, 10);
232         if (ret < 0)
233                 return ret;
234         ts->abs_x_max = ((((uint16_t)rd_cfg_buf[1])<<8)|rd_cfg_buf[2]);
235         ts->abs_y_max = ((((uint16_t)rd_cfg_buf[3])<<8)|rd_cfg_buf[4]);
236         ts->max_touch_num = rd_cfg_buf[5];
237         ts->int_trigger_type = rd_cfg_buf[6]&0x03;
238         I2cDelay = rd_cfg_buf[9]&0x0f;
239         dev_info(&ts->client->dev,"X_MAX = %d,Y_MAX = %d,MAX_TOUCH_NUM = %d,INT_TRIGGER = %d,I2cDelay = %x\n",
240                 ts->abs_x_max,ts->abs_y_max,ts->max_touch_num,ts->int_trigger_type,I2cDelay);
241         if((ts->abs_x_max!=TOUCH_MAX_WIDTH)||(ts->abs_y_max!=TOUCH_MAX_HEIGHT)||
242                 (MAX_POINT!=ts->max_touch_num)||INT_TRIGGER!=ts->int_trigger_type || I2C_DELAY!=I2cDelay){
243                 ts->abs_x_max = TOUCH_MAX_WIDTH;
244                 ts->abs_y_max = TOUCH_MAX_HEIGHT;
245                 ts->max_touch_num = MAX_POINT;
246                 ts->int_trigger_type = INT_TRIGGER;
247                 rd_cfg_buf[1] = ts->abs_x_max>>8;
248                 rd_cfg_buf[2] = ts->abs_x_max&0xff;
249                 rd_cfg_buf[3] = ts->abs_y_max>>8;
250                 rd_cfg_buf[4] = ts->abs_y_max&0xff;
251                 rd_cfg_buf[5] = ts->max_touch_num;
252                 rd_cfg_buf[6] = ((rd_cfg_buf[6]&0xfc) | INT_TRIGGER);
253                 rd_cfg_buf[9] = ((rd_cfg_buf[9]&0xf0) | I2C_DELAY);
254                 ret = gt819_set_regs(ts->client, 101, rd_cfg_buf, 10);
255                 if (ret < 0)
256                         return ret;
257                 dev_info(&ts->client->dev,"set config\n");
258         }
259         return 0;
260 }
261
262 /*******************************************************
263 Description:
264         Goodix touchscreen probe function.
265
266 Parameter:
267         client: i2c device struct.
268         id:device id.
269         
270 return:
271         Executive outcomes. 0---succeed.
272 *******************************************************/
273 static int gt819_probe(struct i2c_client *client, const struct i2c_device_id *id)
274 {
275         int ret = 0;
276         struct goodix_ts_data *ts;
277         struct goodix_platform_data *pdata = client->dev.platform_data;
278         const char irq_table[4] = {IRQ_TYPE_EDGE_RISING,
279                                                            IRQ_TYPE_EDGE_FALLING,
280                                                            IRQ_TYPE_LEVEL_LOW,
281                                                            IRQ_TYPE_LEVEL_HIGH};
282
283         dev_info(&client->dev,"Install touch driver\n");
284
285         if (!pdata) {
286                 dev_err(&client->dev, "platform data is required!\n");
287                 return -EINVAL;
288         }
289         
290         if (pdata->init_platform_hw)
291                 pdata->init_platform_hw();
292
293         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
294                 dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n");
295                 return -ENODEV;
296         }
297         ts = kzalloc(sizeof(*ts), GFP_KERNEL);
298         if (ts == NULL) {
299                 return -ENOMEM;
300         }
301         ts->client = client;
302
303         ret = gt819_init_panel(ts);
304         if(ret != 0){
305           dev_err(&client->dev,"init panel fail,ret = %d\n",ret);
306           goto err_init_panel_fail;
307         }
308         
309         if (!client->irq){
310                 dev_err(&client->dev,"no irq fail\n");
311                 ret = -ENODEV;
312                 goto err_no_irq_fail;
313         }
314         ts->irq_gpio = client->irq;
315         ts->irq = client->irq = gpio_to_irq(client->irq);
316         ret  = request_irq(client->irq, gt819_irq_handler, irq_table[ts->int_trigger_type],client->name, ts);
317         if (ret != 0) {
318                 dev_err(&client->dev,"request_irq fail:%d\n", ret);
319                 goto err_irq_request_fail;
320         }
321         
322         ts->goodix_wq = create_workqueue("goodix_wq");
323         if (!ts->goodix_wq) {
324                 printk(KERN_ALERT "creat workqueue faiked\n");
325                 ret = -ENOMEM;
326                 goto err_create_work_queue_fail;
327         }
328         //INIT_WORK(&ts->work, goodix_ts_work_func);
329         INIT_WORK(&ts->work, gt819_queue_work);
330
331         ts->input_dev = input_allocate_device();
332         if (ts->input_dev == NULL) {
333                 ret = -ENOMEM;
334                 dev_err(&client->dev,"Failed to allocate input device\n");
335                 goto err_input_dev_alloc_failed;
336         }
337         
338         set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit);
339         set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit);
340         set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit);
341         set_bit(ABS_MT_TRACKING_ID, ts->input_dev->absbit);
342         set_bit(ABS_MT_WIDTH_MAJOR, ts->input_dev->absbit);
343         set_bit(EV_ABS, ts->input_dev->evbit);
344         set_bit(EV_KEY, ts->input_dev->evbit);
345         input_set_abs_params(ts->input_dev,ABS_MT_POSITION_X, 0, TOUCH_MAX_WIDTH, 0, 0);
346         input_set_abs_params(ts->input_dev,ABS_MT_POSITION_Y, 0, TOUCH_MAX_HEIGHT, 0, 0);
347         input_set_abs_params(ts->input_dev,ABS_MT_TOUCH_MAJOR, 0, TOUCH_MAJOR_MAX, 0, 0);
348         input_set_abs_params(ts->input_dev,ABS_MT_TRACKING_ID, 0, MAX_POINT, 0, 0);
349         input_set_abs_params(ts->input_dev,ABS_MT_WIDTH_MAJOR, 0, WIDTH_MAJOR_MAX, 0, 0);
350
351         ts->input_dev->name = goodix_ts_name;
352         ret = input_register_device(ts->input_dev);
353         if (ret) {
354                 dev_err(&client->dev,"Probe: Unable to register %s input device\n", ts->input_dev->name);
355                 goto err_input_register_device_failed;
356         }
357         i2c_set_clientdata(client, ts);
358         
359         return 0;
360         i2c_set_clientdata(client, NULL);
361         input_unregister_device(ts->input_dev);
362 err_input_register_device_failed:
363         input_free_device(ts->input_dev);
364 err_input_dev_alloc_failed:
365         destroy_workqueue(ts->goodix_wq); 
366 err_create_work_queue_fail:
367         free_irq(client->irq,ts);
368 err_irq_request_fail:
369 err_no_irq_fail:
370 err_init_panel_fail:
371         if (pdata->exit_platform_hw)
372                 pdata->exit_platform_hw();
373         kfree(ts);
374         return ret;
375 }
376
377
378
379 static const struct i2c_device_id gt819_id[] = {
380         { GOODIX_I2C_NAME, 0 },
381         { }
382 };
383
384 static struct i2c_driver gt819_driver = {
385         .probe          = gt819_probe,
386         .remove         = gt819_remove,
387         .suspend        = gt819_suspend,
388         .resume     = gt819_resume,
389         .id_table       = gt819_id,
390         .driver = {
391                 .name   = GOODIX_I2C_NAME,
392                 .owner = THIS_MODULE,
393         },
394 };
395
396 /*******************************************************        
397 Description:
398         Driver Install function.
399 return:
400         Executive Outcomes. 0---succeed.
401 ********************************************************/
402 static int __devinit gt819_init(void)
403 {
404         int ret;
405         
406         ret=i2c_add_driver(&gt819_driver);
407         return ret; 
408 }
409
410 /*******************************************************        
411 Description:
412         Driver uninstall function.
413 return:
414         Executive Outcomes. 0---succeed.
415 ********************************************************/
416 static void __exit gt819_exit(void)
417 {
418         printk(KERN_ALERT "Touchscreen driver of guitar exited.\n");
419         i2c_del_driver(&gt819_driver);
420 }
421
422 late_initcall(gt819_init);
423 module_exit(gt819_exit);
424
425 MODULE_DESCRIPTION("Goodix Touchscreen Driver");
426 MODULE_LICENSE("GPL");