726cdd030c6e44b55e96a28631a261a4747e71bd
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / hannstar_p1003.c
1 /****************************************************************************************
2  * driver/input/touchscreen/hannstar_p1003.c
3  *Copyright     :ROCKCHIP  Inc
4  *Author        :       sfm
5  *Date          :  2010.2.5
6  *This driver use for rk28 chip extern touchscreen. Use i2c IF ,the chip is Hannstar
7  *description£º
8  ********************************************************************************************/
9 #include <linux/module.h>
10 #include <linux/delay.h>
11 #include <linux/earlysuspend.h>
12 #include <linux/hrtimer.h>
13 #include <linux/i2c.h>
14 #include <linux/input.h>
15 #include <linux/interrupt.h>
16 #include <linux/io.h>
17 #include <linux/platform_device.h>
18 #include <mach/gpio.h>
19 #include <linux/irq.h>
20 #include <mach/board.h>
21
22 #define MAX_SUPPORT_POINT       2// //  4
23 //#define Singltouch_Mode
24 #define SAKURA_DBG                  0
25 #if SAKURA_DBG 
26 #define sakura_dbg_msg(fmt,...)       do {                                      \
27                                    printk("sakura dbg msg------>"                       \
28                                           " (func-->%s ; line-->%d) " fmt, __func__, __LINE__ , ##__VA_ARGS__); \
29                                   } while(0)
30 #define sakura_dbg_report_key_msg(fmt,...)      do{                                                     \
31                                                     printk("sakura report " fmt,##__VA_ARGS__);          \
32                                                 }while(0)
33 #else
34 #define sakura_dbg_msg(fmt,...)       do {} while(0)
35 #define sakura_dbg_report_key_msg(fmt,...)      do{}while(0)
36 #endif
37 struct point_data {     
38         short status;   
39         short x;        
40         short y;
41     short z;
42 };
43
44 struct multitouch_event{
45         struct point_data point_data[MAX_SUPPORT_POINT];
46         int contactid;
47     int validtouch;
48 };
49
50 struct ts_p1003 {
51         struct input_dev        *input;
52         char                    phys[32];
53         struct delayed_work     work;
54
55         struct i2c_client       *client;
56     struct multitouch_event mt_event;
57         u16                     model;
58
59         bool            pendown;
60         bool            status;
61         int                     irq;
62         int             has_relative_report;
63         int                     (*get_pendown_state)(void);
64         void            (*clear_penirq)(void);
65 };
66
67 int p1003_get_pendown_state(void)
68 {
69         return 0;
70 }
71
72 static void p1003_report_event(struct ts_p1003 *ts,struct multitouch_event *tc)
73 {
74         struct input_dev *input = ts->input;
75     int i,pandown = 0;
76         dev_dbg(&ts->client->dev, "UP\n");
77                 
78     for(i=0; i<MAX_SUPPORT_POINT;i++){                  
79         if(tc->point_data[i].status >= 0){
80             pandown |= tc->point_data[i].status;
81             input_report_abs(input, ABS_MT_TRACKING_ID, i);                                                     
82             input_report_abs(input, ABS_MT_TOUCH_MAJOR, tc->point_data[i].status);                              
83             input_report_abs(input, ABS_MT_WIDTH_MAJOR, 0);     
84             input_report_abs(input, ABS_MT_POSITION_X, tc->point_data[i].x);                            
85             input_report_abs(input, ABS_MT_POSITION_Y, tc->point_data[i].y);                            
86             input_mt_sync(input);       
87
88             sakura_dbg_report_key_msg("ABS_MT_TRACKING_ID = %x, ABS_MT_TOUCH_MAJOR = %x\n",
89                 " ABS_MT_POSITION_X = %x, ABS_MT_POSITION_Y = %x\n",i,tc->point_data[i].status,tc->point_data[i].x,tc->point_data[i].y);
90
91             if(tc->point_data[i].status == 0)                                   
92                 tc->point_data[i].status--;                     
93         }
94         
95     }   
96     ts->pendown = pandown;
97     input_sync(input);
98 }
99 static void p1003_report_single_event(struct ts_p1003 *ts,struct multitouch_event *tc)
100 {
101         struct input_dev *input = ts->input;
102     int cid;
103
104     cid = tc->contactid;
105     if (ts->status) {
106         input_report_abs(input, ABS_X, tc->point_data[cid].x);
107         input_report_abs(input, ABS_Y, tc->point_data[cid].y);
108         input_sync(input);
109     }
110     if(ts->pendown != ts->status){
111         ts->pendown = ts->status;
112         input_report_key(input, BTN_TOUCH, ts->status);
113         input_sync(input);
114         sakura_dbg_report_key_msg("%s x =0x%x,y = 0x%x \n",ts->status?"down":"up",tc->point_data[cid].x,tc->point_data[cid].y);
115     }
116 }
117 static inline int p1003_read_values(struct ts_p1003 *ts, struct multitouch_event *tc)
118 {
119     s32 data;
120     int len = 10;
121     char buf[10];
122     short contactid=0;
123
124     data = i2c_master_normal_recv(ts->client, buf,len, 200*1000);
125
126     if (data < 0 || (buf[0]!=0x04)) {
127                 int i;
128                 dev_err(&ts->client->dev, "i2c io error: %d or Hannstar read reg failed\n", data);
129                 for(i = 0; i < 10 ; i++)
130                         dev_err(&ts->client->dev," hannstar reg[%d] = 0x%x\n",i,buf[i]);
131         enable_irq(ts->irq);
132         return data;
133     }
134
135     contactid = (buf[1]&0x7C)>>2;
136     tc->contactid = contactid;
137     tc->point_data[contactid].status = buf[1]&0x01; 
138     tc->point_data[contactid].x = ((buf[3]<<8) + buf[2])>>4;
139     tc->point_data[contactid].y = ((buf[5]<<8) + buf[4])>>4;
140     tc->validtouch = buf[1]&0x80;
141     ts->status = tc->point_data[contactid].status;
142 //    printk("validtouch =%d,status= %d,contactid =%d\n",tc->validtouch,tc->point_data[contactid].status,contactid);
143     return data;
144 }
145
146
147 static void p1003_work(struct work_struct *work)
148 {
149         struct ts_p1003 *ts =
150                 container_of(to_delayed_work(work), struct ts_p1003, work);
151         struct multitouch_event *tc = &ts->mt_event;
152         u32 rt;
153     
154         rt = p1003_read_values(ts,tc);
155     
156     if(rt < 0)
157         goto out;
158         
159 #if defined (Singltouch_Mode)
160     p1003_report_single_event(ts,tc);
161 #else
162     p1003_report_event(ts,tc);
163 #endif
164      
165         if (ts->pendown)
166                 schedule_delayed_work(&ts->work,
167                                       msecs_to_jiffies(10));
168         else
169                 enable_irq(ts->irq);
170         
171 out:
172         return;
173 }
174
175 static irqreturn_t p1003_irq(int irq, void *handle)
176 {
177         struct ts_p1003 *ts = handle;
178 #if 1
179         if (!ts->get_pendown_state || likely(ts->get_pendown_state())) {
180                 disable_irq_nosync(ts->irq);
181                 schedule_delayed_work(&ts->work,
182                                       msecs_to_jiffies(10));
183         }
184
185 #endif
186         return IRQ_HANDLED;
187 }
188
189 static void p1003_free_irq(struct ts_p1003 *ts)
190 {
191         free_irq(ts->irq, ts);
192         if (cancel_delayed_work_sync(&ts->work)) {
193                 /*
194                  * Work was pending, therefore we need to enable
195                  * IRQ here to balance the disable_irq() done in the
196                  * interrupt handler.
197                  */
198                 enable_irq(ts->irq);
199         }
200 }
201
202 static int __devinit p1003_probe(struct i2c_client *client,
203                                    const struct i2c_device_id *id)
204 {
205         struct ts_p1003 *ts;
206         struct p1003_platform_data *pdata = pdata = client->dev.platform_data;
207         struct input_dev *input_dev;
208         int err;
209
210         if (!pdata) {
211                 dev_err(&client->dev, "platform data is required!\n");
212                 return -EINVAL;
213         }
214
215         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
216                 return -EIO;
217
218         ts = kzalloc(sizeof(struct ts_p1003), GFP_KERNEL);
219         input_dev = input_allocate_device();
220         if (!ts || !input_dev) {
221                 err = -ENOMEM;
222                 goto err_free_mem;
223         }
224
225         ts->client = client;
226         ts->irq = client->irq;
227         ts->input = input_dev;
228         ts->status =0 ;// fjp add by 2010-9-30
229         ts->pendown = 0; // fjp add by 2010-10-06
230         
231         INIT_DELAYED_WORK(&ts->work, p1003_work);
232
233         ts->model             = pdata->model;
234
235         snprintf(ts->phys, sizeof(ts->phys),
236                  "%s/input0", dev_name(&client->dev));
237
238         input_dev->name = "p1003 Touchscreen";
239         input_dev->phys = ts->phys;
240         input_dev->id.bustype = BUS_I2C;
241
242 #if defined (Singltouch_Mode)
243         set_bit(EV_SYN, input_dev->evbit);
244         set_bit(EV_KEY, input_dev->evbit);
245         set_bit(BTN_TOUCH, input_dev->keybit);
246         set_bit(BTN_2, input_dev->keybit);
247         set_bit(EV_ABS, input_dev->evbit);
248         input_set_abs_params(input_dev,ABS_X,0,1087,0,0);
249         input_set_abs_params(input_dev,ABS_Y,0,800,0,0);
250 #else
251         ts->has_relative_report = 0;
252         input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY)|BIT_MASK(EV_SYN);
253         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
254         input_dev->keybit[BIT_WORD(BTN_2)] = BIT_MASK(BTN_2); //jaocbchen for dual
255         input_set_abs_params(input_dev, ABS_X, 0, 1087, 0, 0);
256         input_set_abs_params(input_dev, ABS_Y, 0, 800, 0, 0);
257         input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
258         input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
259         input_set_abs_params(input_dev, ABS_HAT0X, 0, 1087, 0, 0);
260         input_set_abs_params(input_dev, ABS_HAT0Y, 0, 800, 0, 0);
261         input_set_abs_params(input_dev, ABS_MT_POSITION_X,0, 1087, 0, 0);
262         input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 800, 0, 0);
263         input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
264         input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
265         input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0);   
266 #endif
267
268         if (pdata->init_platform_hw)
269                 pdata->init_platform_hw();
270
271         if (!ts->irq) {
272                 dev_dbg(&ts->client->dev, "no IRQ?\n");
273                 return -ENODEV;
274         }else{
275                 ts->irq = gpio_to_irq(ts->irq);
276         }
277
278         err = request_irq(ts->irq, p1003_irq, 0,
279                         client->dev.driver->name, ts);
280         
281         if (err < 0) {
282                 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
283                 goto err_free_mem;
284         }
285         
286         if (err < 0)
287                 goto err_free_irq;
288 #if 0
289         err = set_irq_type(ts->irq,IRQ_TYPE_LEVEL_LOW);
290         if (err < 0) {
291                 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
292                 goto err_free_mem;
293         }
294         if (err < 0)
295                 goto err_free_irq;
296 #endif
297         err = input_register_device(input_dev);
298         if (err)
299                 goto err_free_irq;
300
301         i2c_set_clientdata(client, ts);
302
303         return 0;
304
305  err_free_irq:
306         p1003_free_irq(ts);
307         if (pdata->exit_platform_hw)
308                 pdata->exit_platform_hw();
309  err_free_mem:
310         input_free_device(input_dev);
311         kfree(ts);
312         return err;
313 }
314
315 static int __devexit p1003_remove(struct i2c_client *client)
316 {
317         struct ts_p1003 *ts = i2c_get_clientdata(client);
318         struct p1003_platform_data *pdata = client->dev.platform_data;
319
320         p1003_free_irq(ts);
321
322         if (pdata->exit_platform_hw)
323                 pdata->exit_platform_hw();
324
325         input_unregister_device(ts->input);
326         kfree(ts);
327
328         return 0;
329 }
330
331 static struct i2c_device_id p1003_idtable[] = {
332         { "p1003_touch", 0 },
333         { }
334 };
335
336 MODULE_DEVICE_TABLE(i2c, p1003_idtable);
337
338 static struct i2c_driver p1003_driver = {
339         .driver = {
340                 .owner  = THIS_MODULE,
341                 .name   = "p1003_touch"
342         },
343         .id_table       = p1003_idtable,
344         .probe          = p1003_probe,
345         .remove         = __devexit_p(p1003_remove),
346 };
347
348 static int __init p1003_init(void)
349 {
350         printk("--------> %s <-------------\n",__func__);
351         return i2c_add_driver(&p1003_driver);
352 }
353
354 static void __exit p1003_exit(void)
355 {
356         return i2c_del_driver(&p1003_driver);
357 }
358 module_init(p1003_init);
359 module_exit(p1003_exit);
360 MODULE_LICENSE("GPL");
361