diff options
author | Benjamin Tissoires <benjamin.tissoires@enac.fr> | 2012-02-04 11:08:48 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-02-06 07:22:38 -0500 |
commit | c2ef8f21ea8f7c34dfa0b569fdee431348205955 (patch) | |
tree | 0efcba9bc6b92f8f5eadb8cc861327fea676bc2b /drivers/hid/hid-multitouch.c | |
parent | 7c7ed8ec337bf5f62cc5287a6eb6b2f1b7504c2f (diff) |
HID: multitouch: add support for trackpads
* some multitouch trackpads present the touch usage. This needs to be
filtered as it will conflict with mt-implementation.
* trackpads send BTN_TOOL_* to notify how many fingers are present
(this is used by xorg to use synaptics instead of generic evdev)
* trackpads like Perixx 701 are not different from a hid point of view
from a touchscreen, and we need to manually set them as touchpad.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
Acked-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 24fc4423b937..4c697498fcf9 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * HID driver for multitouch panels | 2 | * HID driver for multitouch panels |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> |
5 | * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com> | 5 | * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> |
6 | * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France | 6 | * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France |
7 | * | 7 | * |
8 | * This code is partly based on hid-egalax.c: | 8 | * This code is partly based on hid-egalax.c: |
9 | * | 9 | * |
@@ -67,6 +67,7 @@ struct mt_class { | |||
67 | __s32 sn_height; /* Signal/noise ratio for height events */ | 67 | __s32 sn_height; /* Signal/noise ratio for height events */ |
68 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ | 68 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ |
69 | __u8 maxcontacts; | 69 | __u8 maxcontacts; |
70 | bool is_indirect; /* true for touchpads */ | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | struct mt_device { | 73 | struct mt_device { |
@@ -265,17 +266,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
265 | { | 266 | { |
266 | struct mt_device *td = hid_get_drvdata(hdev); | 267 | struct mt_device *td = hid_get_drvdata(hdev); |
267 | struct mt_class *cls = &td->mtclass; | 268 | struct mt_class *cls = &td->mtclass; |
269 | int code; | ||
268 | 270 | ||
269 | /* Only map fields from TouchScreen or TouchPad collections. | 271 | /* Only map fields from TouchScreen or TouchPad collections. |
270 | * We need to ignore fields that belong to other collections | 272 | * We need to ignore fields that belong to other collections |
271 | * such as Mouse that might have the same GenericDesktop usages. */ | 273 | * such as Mouse that might have the same GenericDesktop usages. */ |
272 | if (field->application == HID_DG_TOUCHSCREEN) | 274 | if (field->application == HID_DG_TOUCHSCREEN) |
273 | set_bit(INPUT_PROP_DIRECT, hi->input->propbit); | 275 | set_bit(INPUT_PROP_DIRECT, hi->input->propbit); |
274 | else if (field->application == HID_DG_TOUCHPAD) | 276 | else if (field->application != HID_DG_TOUCHPAD) |
275 | set_bit(INPUT_PROP_POINTER, hi->input->propbit); | ||
276 | else | ||
277 | return 0; | 277 | return 0; |
278 | 278 | ||
279 | /* In case of an indirect device (touchpad), we need to add | ||
280 | * specific BTN_TOOL_* to be handled by the synaptics xorg | ||
281 | * driver. | ||
282 | * We also consider that touchscreens providing buttons are touchpads. | ||
283 | */ | ||
284 | if (field->application == HID_DG_TOUCHPAD || | ||
285 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || | ||
286 | cls->is_indirect) { | ||
287 | set_bit(INPUT_PROP_POINTER, hi->input->propbit); | ||
288 | set_bit(BTN_TOOL_FINGER, hi->input->keybit); | ||
289 | set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit); | ||
290 | set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit); | ||
291 | set_bit(BTN_TOOL_QUADTAP, hi->input->keybit); | ||
292 | } | ||
293 | |||
279 | /* eGalax devices provide a Digitizer.Stylus input which overrides | 294 | /* eGalax devices provide a Digitizer.Stylus input which overrides |
280 | * the correct Digitizers.Finger X/Y ranges. | 295 | * the correct Digitizers.Finger X/Y ranges. |
281 | * Let's just ignore this input. */ | 296 | * Let's just ignore this input. */ |
@@ -389,9 +404,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
389 | td->last_field_index = field->index; | 404 | td->last_field_index = field->index; |
390 | return -1; | 405 | return -1; |
391 | } | 406 | } |
407 | case HID_DG_TOUCH: | ||
408 | /* Legacy devices use TIPSWITCH and not TOUCH. | ||
409 | * Let's just ignore this field. */ | ||
410 | return -1; | ||
392 | /* let hid-input decide for the others */ | 411 | /* let hid-input decide for the others */ |
393 | return 0; | 412 | return 0; |
394 | 413 | ||
414 | case HID_UP_BUTTON: | ||
415 | code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); | ||
416 | hid_map_usage(hi, usage, bit, max, EV_KEY, code); | ||
417 | input_set_capability(hi->input, EV_KEY, code); | ||
418 | return 1; | ||
419 | |||
395 | case 0xff000000: | 420 | case 0xff000000: |
396 | /* we do not want to map these: no input-oriented meaning */ | 421 | /* we do not want to map these: no input-oriented meaning */ |
397 | return -1; | 422 | return -1; |
@@ -538,6 +563,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
538 | if (value) | 563 | if (value) |
539 | td->num_expected = value; | 564 | td->num_expected = value; |
540 | break; | 565 | break; |
566 | case HID_DG_TOUCH: | ||
567 | /* do nothing */ | ||
568 | break; | ||
541 | 569 | ||
542 | default: | 570 | default: |
543 | /* fallback to the generic hidinput handling */ | 571 | /* fallback to the generic hidinput handling */ |