K97 项目相关修改
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / ntp070.c
1 /* drivers/i2c/chips/ntp070.c - ntp070 compass driver
2  *
3  * Copyright (C) 2007-2008 HTC Corporation.
4  * Author: Hou-Kun Chen <houkun.chen@gmail.com>
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/interrupt.h>
18 #include <linux/i2c.h>
19 #include <linux/slab.h>
20 #include <linux/irq.h>
21 #include <linux/miscdevice.h>
22 #include <linux/gpio.h>
23 #include <asm/uaccess.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/freezer.h>
28 #include <mach/gpio.h>
29 #include <mach/board.h> 
30 #ifdef CONFIG_ANDROID_POWER
31 #include <linux/android_power.h>
32 #endif
33
34 //#define RK28_PRINT
35 //#include <asm/arch/rk28_debug.h>
36 #if 1
37 #define rk28printk(x...) printk(x)
38 #else
39 #define rk28printk(x...)
40 #endif
41
42 #define LCD_MAX_LENGTH                          800
43 #define LCD_MAX_WIDTH                           480
44
45 struct ntp070_data{     
46         struct input_dev *input_dev;
47         struct i2c_client *client;
48         int     irq;
49         struct work_struct work;        
50 };
51
52 #define TP_STATE_IDLE         0
53 #define TP_STATE_DOWN         1
54
55 unsigned char tp_state = TP_STATE_IDLE;
56 static bool irq_finished = true;
57
58 static int  ntp070_probe(struct i2c_client *client, const struct i2c_device_id *id);
59
60
61 /* Addresses to scan -- protected by sense_data_mutex */
62 //static char sense_data[RBUFF_SIZE + 1];
63 static struct i2c_client *this_client;
64 struct ntp070_data *g_ts_dev = NULL;
65
66 #ifdef CONFIG_ANDROID_POWER
67 static android_early_suspend_t ntp070_early_suspend;
68 #endif
69 static int revision = -1;
70
71 //#define TWO_TOUCH_POINT 
72 #define TOUCH_TP20466A //  ±ÈÑǵÏ
73
74 #ifdef TOUCH_TP20466A
75 #define TOUCH_SPEED             UL(250 * 1000)
76 #define TOUCHDATA_LEN    (34)
77 #define TP_MAX_WIDTH                            (0x1dba)//7610
78 #define TP_MAX_LENGTH                           (0x12cc)//4812
79 #define TP_X0  (0xAA)// 170
80 #define TP_Y0  (0x0E)// 14
81 static u8 tp20466a_init_data[] =
82 {
83         0x19,0x05,0x06,0x28,0x02,0x14,0x14,0x10,0x28,0xB0,0x14,0x00,0x1E,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xE1,0x00,0x00,0x00,0x00,0x4D,0xCF,0x20,0x03,0x03,0x83,0x50,0x3C,0x1E,0xB4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
84 };
85 /* write a array of registers  */
86 //static int TP20466A_write_array(struct i2c_client *client, struct reginfo *regarray)
87 static int tp20466a_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], __u16 len)//hym8563_i2c_set_regs
88 {
89         int ret;
90         ret = i2c_master_reg8_send(client, reg, buf, (int)len, TOUCH_SPEED);
91         return ret;
92 }
93 #else
94 #define TOUCH_SPEED             UL(400 * 1000)//
95 #define TP_MAX_WIDTH                            (1266)
96 #define TP_MAX_LENGTH                           (766)
97 #define TOUCHDATA_LEN    (26)
98 #endif
99
100 /* sensor register read */
101 static int ntp070_read(struct i2c_client *client, u8 reg, u8 *val)//sensor_read
102 {
103     int err,cnt,i;
104     u8 buf[TOUCHDATA_LEN];
105     struct i2c_msg msg[1];
106
107     buf[0] = reg & 0xFF;
108
109     msg->addr = client->addr;
110     msg->flags = client->flags;
111     msg->buf = buf;
112     msg->len = 1; //zfl sizeof(buf);
113     msg->scl_rate = TOUCH_SPEED;//40*1000;                                        /* ddl@rock-chips.com : 100kHz */
114     i2c_transfer(client->adapter, msg, 1);
115     msg->addr = client->addr;
116     msg->flags = client->flags|I2C_M_RD;
117     msg->buf = buf;
118     msg->len = TOUCHDATA_LEN; //zfl 1;                                     /* ddl@rock-chips.com : 100kHz */
119
120     cnt = 2;
121     err = -EAGAIN;
122     while ((cnt--) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
123         err = i2c_transfer(client->adapter, msg, 1);
124
125         if (err >= 0) {
126             //zfl *val = buf[0];
127             for(i=0;i<TOUCHDATA_LEN;i++)*(val+i) = buf[i];
128             return 0;
129         } else {
130                 printk("\n ntp070_read write reg failed, try to read again!\n");
131             udelay(10);
132          }
133     }
134
135     return err;
136 }
137 #if 0 
138 static int tp20466a_read_test(struct i2c_client *client, u8 reg, u8 *val)//NO
139 {
140     int err,cnt,i;
141     u8 buf[TOUCHDATA_LEN];
142     struct i2c_msg msg[1];
143
144     buf[0] = reg & 0xFF;
145
146     msg->addr = client->addr;
147     msg->flags = client->flags;
148     msg->buf = buf;
149     msg->len = 1; //zfl sizeof(buf);
150     msg->scl_rate = TOUCH_SPEED;//40*1000;                                        /* ddl@rock-chips.com : 100kHz */
151     i2c_transfer(client->adapter, msg, 1);
152     msg->addr = client->addr;
153     msg->flags = client->flags|I2C_M_RD;
154     msg->buf = buf;
155     msg->len = 1; //zfl 1;                                     /* ddl@rock-chips.com : 100kHz */
156
157     cnt = 5;
158     err = -EAGAIN;
159     while ((cnt--) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
160         err = i2c_transfer(client->adapter, msg, 1);
161
162         if (err >= 0) {
163             //*val = buf[0];
164             //for(i=0;i<1;i++)*(val) = buf[i];
165                 printk("\n tp20466a_read_test read =0x%x\n",buf[0]);
166             return 0;
167         } else {
168                 printk("\n tp20466a_read_test write reg failed, try to read again!\n");
169             udelay(10);
170          }
171     }
172
173     return err;
174 }
175 #endif
176 static void ntp070_work_func(struct work_struct *work)
177 {
178         struct ntp070_data *ts_dev = g_ts_dev;
179         int ak4183_irq_pin_level = 0;
180         int ak4183_input_report_flag = 0;
181         int xpos, ypos,points,pressure_p0,pressure_p1;
182         int ret = 0;    
183         unsigned char buf[TOUCHDATA_LEN];
184         int x2pos,y2pos,temp;
185         int tmpx,tmpy;
186
187 #ifdef TOUCH_TP20466A
188         ret = ntp070_read(this_client,0x00,buf);
189         //if(ret < 0)   goto fake_touch;
190         points = buf[0]&0x01 + (buf[0]>>1)&0x01 + (buf[0]>>2)&0x01 + (buf[0]>>3)&0x01 + (buf[0]>>4)&0x01 ;
191         ypos = ((unsigned int)buf[2])<<8|(unsigned int)buf[3];
192         xpos = ((unsigned int)buf[4])<<8|(unsigned int)buf[5];
193         tmpx=xpos;tmpy=ypos;
194         pressure_p0 = buf[6];
195         if(pressure_p0<2)points=0;
196         y2pos = ((unsigned int)buf[7])<<8|(unsigned int)buf[8];
197         x2pos = ((unsigned int)buf[9])<<8|(unsigned int)buf[10];
198         pressure_p1 = buf[11];
199         if(ypos>TP_MAX_LENGTH) { ypos=TP_MAX_LENGTH;points=0;}
200         else if(ypos<TP_Y0){ ypos=TP_Y0;points=0;}
201         ypos-=TP_Y0;
202         ypos=(ypos*(LCD_MAX_WIDTH-1))/(TP_MAX_LENGTH-TP_Y0);ypos=(LCD_MAX_WIDTH-1)-ypos;
203         if(xpos>TP_MAX_WIDTH) {xpos=TP_MAX_WIDTH;points=0;}
204         else if(xpos<TP_X0) {xpos=TP_X0;points=0;}
205         xpos-=TP_X0;
206         xpos=(xpos*(LCD_MAX_LENGTH-1))/(TP_MAX_WIDTH-TP_X0);
207         rk28printk("buf[0x]=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
208         rk28printk("tmpx=0x%x,tmpy=0x%x,press0=%d,press1=%d\n",tmpx,tmpy,pressure_p0,pressure_p1);
209 #else
210         //zfl ret = i2c_master_reg8_recv(this_client,0xF9, buf, 26, TOUCH_SPEED);
211         ret = ntp070_read(this_client,0xF9,buf);
212         //if(ret < 0)   goto fake_touch;
213         ypos = ((unsigned int)buf[5])<<8|(unsigned int)buf[6];
214         xpos = ((unsigned int)buf[7])<<8|(unsigned int)buf[8];
215         //temp = xpos;//
216         //xpos = ypos*800/1280;//
217         //ypos = (768 - temp)*480/768;//*/
218         y2pos = ((unsigned int)buf[9])<<8|(unsigned int)buf[10];
219         x2pos = ((unsigned int)buf[11])<<8|(unsigned int)buf[12];
220         points=buf[3];
221
222         if(ypos>TP_MAX_LENGTH) ypos=0;
223         else ypos=TP_MAX_LENGTH-ypos;
224         ypos=(ypos*(LCD_MAX_WIDTH-1))/TP_MAX_LENGTH;
225         if(xpos>TP_MAX_WIDTH) xpos=TP_MAX_WIDTH;
226         xpos=(xpos*(LCD_MAX_LENGTH-1))/TP_MAX_WIDTH;
227 #endif
228         if(ret < 0){
229                 goto fake_touch;
230         }
231         if(0==points)
232         {
233                 ak4183_irq_pin_level = 1;
234                 goto fake_touch;
235         }
236         if(tp_state == TP_STATE_IDLE){
237                 input_report_key(ts_dev->input_dev, BTN_TOUCH, 1);
238                 ak4183_input_report_flag = 1;
239                 tp_state = TP_STATE_DOWN;
240         }
241                 
242         if(tp_state == TP_STATE_DOWN){
243                 input_report_abs(ts_dev->input_dev, ABS_X, xpos);
244                 input_report_abs(ts_dev->input_dev, ABS_Y, ypos);
245 #ifdef TOUCH_TP20466A
246                 //input_report_abs(ts_dev->input_dev, ABS_PRESSURE, pressure_p0);
247 #endif
248                 ak4183_input_report_flag = 1;
249         }
250
251 fake_touch:
252         if(ak4183_irq_pin_level == 1 && tp_state == TP_STATE_DOWN){
253                 input_report_key(ts_dev->input_dev, BTN_TOUCH, 0);
254                 ak4183_input_report_flag = 1;
255                 tp_state = TP_STATE_IDLE;
256         }
257
258         if(ak4183_input_report_flag != 0)
259                 input_sync(ts_dev->input_dev);
260         rk28printk("%s-point:%d,x:%d,y:%d,x2:%d,y2:%d,tp_state:%d,flag:%d\n\n",__FUNCTION__,points,xpos,ypos,x2pos,y2pos,tp_state,ak4183_input_report_flag);
261         enable_irq(ts_dev->irq);
262         irq_finished = true;
263 }
264
265 static irqreturn_t ntp070_interrupt(int irq, void *dev_id)
266 {
267         struct ntp070_data *ts_dev = (struct ntp070_data *)dev_id;
268
269         if(!irq_finished)
270                 return IRQ_HANDLED;
271         irq_finished = false;
272         disable_irq(ts_dev->irq);
273         schedule_work(&ts_dev->work);
274         rk28printk("%s:%d\n",__FUNCTION__,__LINE__);
275         
276         return IRQ_HANDLED;
277 }
278
279 static int ntp070_remove(struct i2c_client *client)
280 {
281         struct ntp070_data *ntp070 = i2c_get_clientdata(client);
282         
283     input_unregister_device(ntp070->input_dev);
284     input_free_device(ntp070->input_dev);
285     free_irq(client->irq, ntp070);
286     kfree(ntp070); 
287 #ifdef CONFIG_ANDROID_POWER
288     android_unregister_early_suspend(&ntp070_early_suspend);
289 #endif      
290     this_client = NULL;
291         return 0;
292 }
293
294 #ifdef CONFIG_ANDROID_POWER
295 static int ntp070_suspend(android_early_suspend_t *h)
296 {
297         struct i2c_client *client = container_of(ntp070_device.parent, struct i2c_client, dev);
298         rk28printk("Gsensor mma7760 enter suspend\n");
299         return 0;
300 }
301
302 static int ntp070_resume(android_early_suspend_t *h)
303 {
304         struct i2c_client *client = container_of(ntp070_device.parent, struct i2c_client, dev);
305     struct ntp070_data *ntp070 = (struct ntp070_data *)i2c_get_clientdata(client);
306         rk28printk("Gsensor mma7760 resume!!\n");
307         return 0;
308 }
309 #else
310 static int ntp070_suspend(struct i2c_client *client, pm_message_t mesg)
311 {
312         rk28printk("Gsensor mma7760 enter 2 level  suspend\n");
313         return 0;
314 }
315 static int ntp070_resume(struct i2c_client *client)
316 {
317         struct ntp070_data *ntp070 = (struct ntp070_data *)i2c_get_clientdata(client);
318         rk28printk("Gsensor mma7760 2 level resume!!\n");
319         return 0;
320 }
321 #endif
322
323 static const struct i2c_device_id ntp070_id[] = {
324                 {"ntp070", 0},
325                 { }
326 };
327
328 static struct i2c_driver ntp070_driver = {
329         .driver = {
330                 .name = "ntp070",
331             },
332         .id_table       = ntp070_id,
333         .probe          = ntp070_probe,
334         .remove         = __devexit_p(ntp070_remove),
335 #ifndef CONFIG_ANDROID_POWER    
336         .suspend = &ntp070_suspend,
337         .resume = &ntp070_resume,
338 #endif  
339 };
340
341
342 static int ntp070_init_client(struct i2c_client *client)
343 {
344         struct ntp070_data *ntp070;
345         int ret;
346         ntp070 = i2c_get_clientdata(client);
347         rk28printk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq));
348         if ( !gpio_is_valid(client->irq)) {
349                 rk28printk("+++++++++++gpio_is_invalid\n");
350                 return -EINVAL;
351         }
352         ret = gpio_request(client->irq, "ntp070_int");
353         if (ret) {
354                 rk28printk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq));
355                 return ret;
356         }
357     ret = gpio_direction_input(client->irq);
358     if (ret) {
359         rk28printk("failed to set mma7990_trig GPIO gpio input\n");
360                 return ret;
361     }
362         gpio_pull_updown(client->irq, GPIOPullUp);
363         client->irq = gpio_to_irq(client->irq);
364         ret = request_irq(client->irq, ntp070_interrupt, IRQF_TRIGGER_FALLING, client->dev.driver->name, ntp070);
365         rk28printk("request irq is %d,ret is  0x%x\n",client->irq,ret);
366         if (ret ) {
367                 rk28printk(KERN_ERR "ntp070_init_client: request irq failed,ret is %d\n",ret);
368         return ret;
369         }
370         enable_irq(client->irq);
371  
372         return 0;
373 }
374
375 static int  ntp070_probe(struct i2c_client *client, const struct i2c_device_id *id)
376 {
377         struct ntp070_data *ntp070;
378         int err;
379         
380
381         ntp070 = kzalloc(sizeof(struct ntp070_data), GFP_KERNEL);
382         if (!ntp070) {
383                 rk28printk("[ntp070]:alloc data failed.\n");
384                 err = -ENOMEM;
385                 goto exit_alloc_data_failed;
386         }
387     
388 #ifdef TOUCH_TP20466A
389                 //rk28printk("\n *** tp20466a_i2c_set_regs start *** \n");mdelay(3000);//
390                 err=tp20466a_i2c_set_regs(client, 0x30, tp20466a_init_data, sizeof(tp20466a_init_data)/sizeof(u8));
391                 //rk28printk("\n tp20466a_i2c_set_regs=%d\n",err);
392                 if(err<0) return err;
393                 //tp20466a_read_test(this_client,0x69,NULL);
394 #endif
395         INIT_WORK(&ntp070->work, ntp070_work_func);
396
397         ntp070->client = client;
398         i2c_set_clientdata(client, ntp070);
399
400         this_client = client;
401
402         err = ntp070_init_client(client);
403         if (err < 0) {
404                 rk28printk(KERN_ERR
405                        "ntp070_probe: ntp070_init_client failed\n");
406                 goto exit_request_gpio_irq_failed;
407         }
408                 
409         ntp070->input_dev = input_allocate_device();
410         if (!ntp070->input_dev) {
411                 err = -ENOMEM;
412                 rk28printk(KERN_ERR
413                        "ntp070_probe: Failed to allocate input device\n");
414                 goto exit_input_allocate_device_failed;
415         }
416
417         input_set_abs_params(ntp070->input_dev, ABS_X,0,LCD_MAX_LENGTH-1,0, 0);
418         input_set_abs_params(ntp070->input_dev, ABS_Y,0,LCD_MAX_WIDTH-1,0, 0);
419 #ifdef TOUCH_TP20466A
420         //input_set_abs_params(ntp070->input_dev, ABS_PRESSURE,0,MAX_12BIT,0, 0);
421 #endif
422
423         ntp070->input_dev->name = "ntp070";
424         ntp070->input_dev->dev.parent = &client->dev;
425         ntp070->input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
426         ntp070->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
427
428         g_ts_dev = ntp070;
429
430         err = input_register_device(ntp070->input_dev);
431         if (err < 0) {
432                 rk28printk(KERN_ERR
433                        "ntp070_probe: Unable to register input device: %s\n",
434                        ntp070->input_dev->name);
435                 goto exit_input_register_device_failed;
436         }
437
438 #ifdef CONFIG_ANDROID_POWER
439     ntp070_early_suspend.suspend = ntp070_suspend;
440     ntp070_early_suspend.resume = ntp070_resume;
441     ntp070_early_suspend.level = 0x2;
442     android_register_early_suspend(&ntp070_early_suspend);
443 #endif
444         rk28printk(KERN_INFO "ntp070 probe ok\n");
445         tp_state = TP_STATE_IDLE;
446         printk("%s:%d\n",__FUNCTION__,__LINE__);
447 #if 0   
448         ntp070_start(client, MMA7660_RATE_32);
449 #endif
450         return 0;
451
452 exit_misc_device_register_ntp070_device_failed:
453     input_unregister_device(ntp070->input_dev);
454 exit_input_register_device_failed:
455         input_free_device(ntp070->input_dev);
456 exit_input_allocate_device_failed:
457     free_irq(client->irq, ntp070);
458 exit_request_gpio_irq_failed:
459         kfree(ntp070);  
460 exit_alloc_data_failed:
461     ;
462         printk("%s:%d\n",__FUNCTION__,__LINE__);
463         return err;
464 }
465
466
467 static int __init ntp070_i2c_init(void)
468 {
469         printk("%s:%d\n",__FUNCTION__,__LINE__);
470         return i2c_add_driver(&ntp070_driver);
471 }
472
473 static void __exit ntp070_i2c_exit(void)
474 {
475         printk("%s:%d\n",__FUNCTION__,__LINE__);
476         i2c_del_driver(&ntp070_driver);
477 }
478
479 device_initcall(ntp070_i2c_init);//zfl    module_init        late_initcall_sync
480 module_exit(ntp070_i2c_exit);
481
482
483