hid: egalax: Correct for device resolution report error
[linux-2.6.git] / drivers / hid / hid-quanta.c
1 /*
2  *  HID driver for Quanta Optical Touch dual-touch panels
3  *
4  *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
5  *
6  */
7
8 /*
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by the Free
11  * Software Foundation; either version 2 of the License, or (at your option)
12  * any later version.
13  */
14
15 #include <linux/device.h>
16 #include <linux/hid.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19
20 MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
21 MODULE_DESCRIPTION("Quanta dual-touch panel");
22 MODULE_LICENSE("GPL");
23
24 #include "hid-ids.h"
25
26 struct quanta_data {
27         __u16 x, y;
28         __u8 id;
29         bool valid;             /* valid finger data, or just placeholder? */
30         bool first;             /* is this the first finger in this frame? */
31         bool activity_now;      /* at least one active finger in this frame? */
32         bool activity;          /* at least one active finger previously? */
33 };
34
35 static int quanta_input_mapping(struct hid_device *hdev, struct hid_input *hi,
36                 struct hid_field *field, struct hid_usage *usage,
37                 unsigned long **bit, int *max)
38 {
39         switch (usage->hid & HID_USAGE_PAGE) {
40
41         case HID_UP_GENDESK:
42                 switch (usage->hid) {
43                 case HID_GD_X:
44                         hid_map_usage(hi, usage, bit, max,
45                                         EV_ABS, ABS_MT_POSITION_X);
46                         /* touchscreen emulation */
47                         input_set_abs_params(hi->input, ABS_X,
48                                                 field->logical_minimum,
49                                                 field->logical_maximum, 0, 0);
50                         return 1;
51                 case HID_GD_Y:
52                         hid_map_usage(hi, usage, bit, max,
53                                         EV_ABS, ABS_MT_POSITION_Y);
54                         /* touchscreen emulation */
55                         input_set_abs_params(hi->input, ABS_Y,
56                                                 field->logical_minimum,
57                                                 field->logical_maximum, 0, 0);
58                         return 1;
59                 }
60                 return 0;
61
62         case HID_UP_DIGITIZER:
63                 switch (usage->hid) {
64                 case HID_DG_CONFIDENCE:
65                 case HID_DG_TIPSWITCH:
66                 case HID_DG_INPUTMODE:
67                 case HID_DG_DEVICEINDEX:
68                 case HID_DG_CONTACTCOUNT:
69                 case HID_DG_CONTACTMAX:
70                 case HID_DG_TIPPRESSURE:
71                 case HID_DG_WIDTH:
72                 case HID_DG_HEIGHT:
73                         return -1;
74                 case HID_DG_INRANGE:
75                         /* touchscreen emulation */
76                         hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
77                         return 1;
78                 case HID_DG_CONTACTID:
79                         hid_map_usage(hi, usage, bit, max,
80                                         EV_ABS, ABS_MT_TRACKING_ID);
81                         return 1;
82                 }
83                 return 0;
84
85         case 0xff000000:
86                 /* ignore vendor-specific features */
87                 return -1;
88         }
89
90         return 0;
91 }
92
93 static int quanta_input_mapped(struct hid_device *hdev, struct hid_input *hi,
94                 struct hid_field *field, struct hid_usage *usage,
95                 unsigned long **bit, int *max)
96 {
97         if (usage->type == EV_KEY || usage->type == EV_ABS)
98                 clear_bit(usage->code, *bit);
99
100         return 0;
101 }
102
103 /*
104  * this function is called when a whole finger has been parsed,
105  * so that it can decide what to send to the input layer.
106  */
107 static void quanta_filter_event(struct quanta_data *td, struct input_dev *input)
108 {
109         
110         td->first = !td->first; /* touchscreen emulation */
111
112         if (!td->valid) {
113                 /*
114                  * touchscreen emulation: if no finger in this frame is valid
115                  * and there previously was finger activity, this is a release
116                  */ 
117                 if (!td->first && !td->activity_now && td->activity) {
118                         input_event(input, EV_KEY, BTN_TOUCH, 0);
119                         td->activity = false;
120                 }
121                 return;
122         }
123
124         input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
125         input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
126         input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
127
128         input_mt_sync(input);
129         td->valid = false;
130
131         /* touchscreen emulation: if first active finger in this frame... */
132         if (!td->activity_now) {
133                 /* if there was no previous activity, emit touch event */
134                 if (!td->activity) {
135                         input_event(input, EV_KEY, BTN_TOUCH, 1);
136                         td->activity = true;
137                 }
138                 td->activity_now = true;
139                 /* and in any case this is our preferred finger */
140                 input_event(input, EV_ABS, ABS_X, td->x);
141                 input_event(input, EV_ABS, ABS_Y, td->y);
142         }
143 }
144
145
146 static int quanta_event(struct hid_device *hid, struct hid_field *field,
147                                 struct hid_usage *usage, __s32 value)
148 {
149         struct quanta_data *td = hid_get_drvdata(hid);
150
151         if (hid->claimed & HID_CLAIMED_INPUT) {
152                 struct input_dev *input = field->hidinput->input;
153
154                 switch (usage->hid) {
155                 case HID_DG_INRANGE:
156                         td->valid = !!value;
157                         break;
158                 case HID_GD_X:
159                         td->x = value;
160                         break;
161                 case HID_GD_Y:
162                         td->y = value;
163                         quanta_filter_event(td, input);
164                         break;
165                 case HID_DG_CONTACTID:
166                         td->id = value;
167                         break;
168                 case HID_DG_CONTACTCOUNT:
169                         /* touch emulation: this is the last field in a frame */
170                         td->first = false;
171                         td->activity_now = false;
172                         break;
173                 case HID_DG_CONFIDENCE:
174                 case HID_DG_TIPSWITCH:
175                         /* avoid interference from generic hidinput handling */
176                         break;
177
178                 default:
179                         /* fallback to the generic hidinput handling */
180                         return 0;
181                 }
182         }
183
184         /* we have handled the hidinput part, now remains hiddev */
185         if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
186                 hid->hiddev_hid_event(hid, field, usage, value);
187
188         return 1;
189 }
190
191 static int quanta_probe(struct hid_device *hdev, const struct hid_device_id *id)
192 {
193         int ret;
194         struct quanta_data *td;
195
196         td = kmalloc(sizeof(struct quanta_data), GFP_KERNEL);
197         if (!td) {
198                 dev_err(&hdev->dev, "cannot allocate Quanta Touch data\n");
199                 return -ENOMEM;
200         }
201         td->valid = false;
202         td->activity = false;
203         td->activity_now = false;
204         td->first = false;
205         hid_set_drvdata(hdev, td);
206
207         ret = hid_parse(hdev);
208         if (!ret)
209                 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
210
211         if (ret)
212                 kfree(td);
213
214         return ret;
215 }
216
217 static void quanta_remove(struct hid_device *hdev)
218 {
219         hid_hw_stop(hdev);
220         kfree(hid_get_drvdata(hdev));
221         hid_set_drvdata(hdev, NULL);
222 }
223
224 static const struct hid_device_id quanta_devices[] = {
225         { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
226                         USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
227         { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
228                         USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
229         { }
230 };
231 MODULE_DEVICE_TABLE(hid, quanta_devices);
232
233 static const struct hid_usage_id quanta_grabbed_usages[] = {
234         { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
235         { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
236 };
237
238 static struct hid_driver quanta_driver = {
239         .name = "quanta-touch",
240         .id_table = quanta_devices,
241         .probe = quanta_probe,
242         .remove = quanta_remove,
243         .input_mapping = quanta_input_mapping,
244         .input_mapped = quanta_input_mapped,
245         .usage_table = quanta_grabbed_usages,
246         .event = quanta_event,
247 };
248
249 static int __init quanta_init(void)
250 {
251         return hid_register_driver(&quanta_driver);
252 }
253
254 static void __exit quanta_exit(void)
255 {
256         hid_unregister_driver(&quanta_driver);
257 }
258
259 module_init(quanta_init);
260 module_exit(quanta_exit);
261