diff options
Diffstat (limited to 'drivers/hid/hid-ntrig.c')
-rw-r--r-- | drivers/hid/hid-ntrig.c | 72 |
1 files changed, 34 insertions, 38 deletions
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 9b24fc510712..4777bbfa1cc2 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * HID driver for N-Trig touchscreens | 2 | * HID driver for N-Trig touchscreens |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Rafi Rubin | 4 | * Copyright (c) 2008-2010 Rafi Rubin |
5 | * Copyright (c) 2009 Stephane Chatty | 5 | * Copyright (c) 2009-2010 Stephane Chatty |
6 | * | 6 | * |
7 | */ | 7 | */ |
8 | 8 | ||
@@ -15,6 +15,8 @@ | |||
15 | 15 | ||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
18 | #include <linux/usb.h> | ||
19 | #include "usbhid/usbhid.h" | ||
18 | #include <linux/module.h> | 20 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
20 | 22 | ||
@@ -22,17 +24,16 @@ | |||
22 | 24 | ||
23 | #define NTRIG_DUPLICATE_USAGES 0x001 | 25 | #define NTRIG_DUPLICATE_USAGES 0x001 |
24 | 26 | ||
25 | #define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | ||
26 | EV_KEY, (c)) | ||
27 | |||
28 | struct ntrig_data { | 27 | struct ntrig_data { |
29 | /* Incoming raw values for a single contact */ | 28 | /* Incoming raw values for a single contact */ |
30 | __u16 x, y, w, h; | 29 | __u16 x, y, w, h; |
31 | __u16 id; | 30 | __u16 id; |
32 | __u8 confidence; | 31 | |
32 | bool tipswitch; | ||
33 | bool confidence; | ||
34 | bool first_contact_touch; | ||
33 | 35 | ||
34 | bool reading_mt; | 36 | bool reading_mt; |
35 | __u8 first_contact_confidence; | ||
36 | 37 | ||
37 | __u8 mt_footer[4]; | 38 | __u8 mt_footer[4]; |
38 | __u8 mt_foot_count; | 39 | __u8 mt_foot_count; |
@@ -139,9 +140,10 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
139 | case 0xff000001: | 140 | case 0xff000001: |
140 | /* Tag indicating the start of a multitouch group */ | 141 | /* Tag indicating the start of a multitouch group */ |
141 | nd->reading_mt = 1; | 142 | nd->reading_mt = 1; |
142 | nd->first_contact_confidence = 0; | 143 | nd->first_contact_touch = 0; |
143 | break; | 144 | break; |
144 | case HID_DG_TIPSWITCH: | 145 | case HID_DG_TIPSWITCH: |
146 | nd->tipswitch = value; | ||
145 | /* Prevent emission of touch until validated */ | 147 | /* Prevent emission of touch until validated */ |
146 | return 1; | 148 | return 1; |
147 | case HID_DG_CONFIDENCE: | 149 | case HID_DG_CONFIDENCE: |
@@ -169,8 +171,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
169 | * to emit a normal (X, Y) position | 171 | * to emit a normal (X, Y) position |
170 | */ | 172 | */ |
171 | if (!nd->reading_mt) { | 173 | if (!nd->reading_mt) { |
174 | /* | ||
175 | * TipSwitch indicates the presence of a | ||
176 | * finger in single touch mode. | ||
177 | */ | ||
178 | input_report_key(input, BTN_TOUCH, | ||
179 | nd->tipswitch); | ||
172 | input_report_key(input, BTN_TOOL_DOUBLETAP, | 180 | input_report_key(input, BTN_TOOL_DOUBLETAP, |
173 | (nd->confidence != 0)); | 181 | nd->tipswitch); |
174 | input_event(input, EV_ABS, ABS_X, nd->x); | 182 | input_event(input, EV_ABS, ABS_X, nd->x); |
175 | input_event(input, EV_ABS, ABS_Y, nd->y); | 183 | input_event(input, EV_ABS, ABS_Y, nd->y); |
176 | } | 184 | } |
@@ -209,7 +217,13 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
209 | 217 | ||
210 | /* emit a normal (X, Y) for the first point only */ | 218 | /* emit a normal (X, Y) for the first point only */ |
211 | if (nd->id == 0) { | 219 | if (nd->id == 0) { |
212 | nd->first_contact_confidence = nd->confidence; | 220 | /* |
221 | * TipSwitch is superfluous in multitouch | ||
222 | * mode. The footer events tell us | ||
223 | * if there is a finger on the screen or | ||
224 | * not. | ||
225 | */ | ||
226 | nd->first_contact_touch = nd->confidence; | ||
213 | input_event(input, EV_ABS, ABS_X, nd->x); | 227 | input_event(input, EV_ABS, ABS_X, nd->x); |
214 | input_event(input, EV_ABS, ABS_Y, nd->y); | 228 | input_event(input, EV_ABS, ABS_Y, nd->y); |
215 | } | 229 | } |
@@ -239,30 +253,11 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, | |||
239 | 253 | ||
240 | nd->reading_mt = 0; | 254 | nd->reading_mt = 0; |
241 | 255 | ||
242 | if (nd->first_contact_confidence) { | 256 | if (nd->first_contact_touch) { |
243 | switch (value) { | 257 | input_report_key(input, BTN_TOOL_DOUBLETAP, 1); |
244 | case 0: /* for single touch devices */ | ||
245 | case 1: | ||
246 | input_report_key(input, | ||
247 | BTN_TOOL_DOUBLETAP, 1); | ||
248 | break; | ||
249 | case 2: | ||
250 | input_report_key(input, | ||
251 | BTN_TOOL_TRIPLETAP, 1); | ||
252 | break; | ||
253 | case 3: | ||
254 | default: | ||
255 | input_report_key(input, | ||
256 | BTN_TOOL_QUADTAP, 1); | ||
257 | } | ||
258 | input_report_key(input, BTN_TOUCH, 1); | 258 | input_report_key(input, BTN_TOUCH, 1); |
259 | } else { | 259 | } else { |
260 | input_report_key(input, | 260 | input_report_key(input, BTN_TOOL_DOUBLETAP, 0); |
261 | BTN_TOOL_DOUBLETAP, 0); | ||
262 | input_report_key(input, | ||
263 | BTN_TOOL_TRIPLETAP, 0); | ||
264 | input_report_key(input, | ||
265 | BTN_TOOL_QUADTAP, 0); | ||
266 | input_report_key(input, BTN_TOUCH, 0); | 261 | input_report_key(input, BTN_TOUCH, 0); |
267 | } | 262 | } |
268 | break; | 263 | break; |
@@ -286,6 +281,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
286 | struct ntrig_data *nd; | 281 | struct ntrig_data *nd; |
287 | struct hid_input *hidinput; | 282 | struct hid_input *hidinput; |
288 | struct input_dev *input; | 283 | struct input_dev *input; |
284 | struct hid_report *report; | ||
289 | 285 | ||
290 | if (id->driver_data) | 286 | if (id->driver_data) |
291 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | 287 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; |
@@ -327,13 +323,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
327 | __clear_bit(BTN_TOOL_PEN, input->keybit); | 323 | __clear_bit(BTN_TOOL_PEN, input->keybit); |
328 | __clear_bit(BTN_TOOL_FINGER, input->keybit); | 324 | __clear_bit(BTN_TOOL_FINGER, input->keybit); |
329 | __clear_bit(BTN_0, input->keybit); | 325 | __clear_bit(BTN_0, input->keybit); |
330 | /* | ||
331 | * A little something special to enable | ||
332 | * two and three finger taps. | ||
333 | */ | ||
334 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | 326 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); |
335 | __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); | ||
336 | __set_bit(BTN_TOOL_QUADTAP, input->keybit); | ||
337 | /* | 327 | /* |
338 | * The physical touchscreen (single touch) | 328 | * The physical touchscreen (single touch) |
339 | * input has a value for physical, whereas | 329 | * input has a value for physical, whereas |
@@ -349,6 +339,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
349 | } | 339 | } |
350 | } | 340 | } |
351 | 341 | ||
342 | /* This is needed for devices with more recent firmware versions */ | ||
343 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; | ||
344 | if (report) | ||
345 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | ||
346 | |||
347 | |||
352 | return 0; | 348 | return 0; |
353 | err_free: | 349 | err_free: |
354 | kfree(nd); | 350 | kfree(nd); |