aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-multitouch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r--drivers/hid/hid-multitouch.c76
1 files changed, 64 insertions, 12 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 07d3183fdde5..ee01e65e22d6 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -5,6 +5,12 @@
5 * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com> 5 * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6 * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France 6 * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
7 * 7 *
8 * This code is partly based on hid-egalax.c:
9 *
10 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
11 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
12 * Copyright (c) 2010 Canonical, Ltd.
13 *
8 */ 14 */
9 15
10/* 16/*
@@ -24,6 +30,7 @@
24 30
25 31
26MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); 32MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
33MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
27MODULE_DESCRIPTION("HID multitouch panels"); 34MODULE_DESCRIPTION("HID multitouch panels");
28MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
29 36
@@ -36,6 +43,7 @@ MODULE_LICENSE("GPL");
36#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3) 43#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
37#define MT_QUIRK_VALID_IS_INRANGE (1 << 4) 44#define MT_QUIRK_VALID_IS_INRANGE (1 << 4)
38#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) 45#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5)
46#define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6)
39 47
40struct mt_slot { 48struct mt_slot {
41 __s32 x, y, p, w, h; 49 __s32 x, y, p, w, h;
@@ -65,10 +73,11 @@ struct mt_class {
65}; 73};
66 74
67/* classes of device behavior */ 75/* classes of device behavior */
68#define MT_CLS_DEFAULT 1 76#define MT_CLS_DEFAULT 1
69#define MT_CLS_DUAL1 2 77#define MT_CLS_DUAL_INRANGE_CONTACTID 2
70#define MT_CLS_DUAL2 3 78#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3
71#define MT_CLS_CYPRESS 4 79#define MT_CLS_CYPRESS 4
80#define MT_CLS_EGALAX 5
72 81
73/* 82/*
74 * these device-dependent functions determine what slot corresponds 83 * these device-dependent functions determine what slot corresponds
@@ -104,13 +113,13 @@ static int find_slot_from_contactid(struct mt_device *td)
104 113
105struct mt_class mt_classes[] = { 114struct mt_class mt_classes[] = {
106 { .name = MT_CLS_DEFAULT, 115 { .name = MT_CLS_DEFAULT,
107 .quirks = MT_QUIRK_VALID_IS_INRANGE, 116 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
108 .maxcontacts = 10 }, 117 .maxcontacts = 10 },
109 { .name = MT_CLS_DUAL1, 118 { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
110 .quirks = MT_QUIRK_VALID_IS_INRANGE | 119 .quirks = MT_QUIRK_VALID_IS_INRANGE |
111 MT_QUIRK_SLOT_IS_CONTACTID, 120 MT_QUIRK_SLOT_IS_CONTACTID,
112 .maxcontacts = 2 }, 121 .maxcontacts = 2 },
113 { .name = MT_CLS_DUAL2, 122 { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
114 .quirks = MT_QUIRK_VALID_IS_INRANGE | 123 .quirks = MT_QUIRK_VALID_IS_INRANGE |
115 MT_QUIRK_SLOT_IS_CONTACTNUMBER, 124 MT_QUIRK_SLOT_IS_CONTACTNUMBER,
116 .maxcontacts = 2 }, 125 .maxcontacts = 2 },
@@ -119,10 +128,18 @@ struct mt_class mt_classes[] = {
119 MT_QUIRK_CYPRESS, 128 MT_QUIRK_CYPRESS,
120 .maxcontacts = 10 }, 129 .maxcontacts = 10 },
121 130
131 { .name = MT_CLS_EGALAX,
132 .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
133 MT_QUIRK_VALID_IS_INRANGE |
134 MT_QUIRK_EGALAX_XYZ_FIXUP,
135 .maxcontacts = 2,
136 .sn_move = 4096,
137 .sn_pressure = 32,
138 },
122 { } 139 { }
123}; 140};
124 141
125static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi, 142static void mt_feature_mapping(struct hid_device *hdev,
126 struct hid_field *field, struct hid_usage *usage) 143 struct hid_field *field, struct hid_usage *usage)
127{ 144{
128 if (usage->hid == HID_DG_INPUTMODE) { 145 if (usage->hid == HID_DG_INPUTMODE) {
@@ -146,11 +163,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
146{ 163{
147 struct mt_device *td = hid_get_drvdata(hdev); 164 struct mt_device *td = hid_get_drvdata(hdev);
148 struct mt_class *cls = td->mtclass; 165 struct mt_class *cls = td->mtclass;
166 __s32 quirks = cls->quirks;
167
149 switch (usage->hid & HID_USAGE_PAGE) { 168 switch (usage->hid & HID_USAGE_PAGE) {
150 169
151 case HID_UP_GENDESK: 170 case HID_UP_GENDESK:
152 switch (usage->hid) { 171 switch (usage->hid) {
153 case HID_GD_X: 172 case HID_GD_X:
173 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
174 field->logical_maximum = 32760;
154 hid_map_usage(hi, usage, bit, max, 175 hid_map_usage(hi, usage, bit, max,
155 EV_ABS, ABS_MT_POSITION_X); 176 EV_ABS, ABS_MT_POSITION_X);
156 set_abs(hi->input, ABS_MT_POSITION_X, field, 177 set_abs(hi->input, ABS_MT_POSITION_X, field,
@@ -160,6 +181,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
160 td->last_slot_field = usage->hid; 181 td->last_slot_field = usage->hid;
161 return 1; 182 return 1;
162 case HID_GD_Y: 183 case HID_GD_Y:
184 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
185 field->logical_maximum = 32760;
163 hid_map_usage(hi, usage, bit, max, 186 hid_map_usage(hi, usage, bit, max,
164 EV_ABS, ABS_MT_POSITION_Y); 187 EV_ABS, ABS_MT_POSITION_Y);
165 set_abs(hi->input, ABS_MT_POSITION_Y, field, 188 set_abs(hi->input, ABS_MT_POSITION_Y, field,
@@ -203,6 +226,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
203 td->last_slot_field = usage->hid; 226 td->last_slot_field = usage->hid;
204 return 1; 227 return 1;
205 case HID_DG_TIPPRESSURE: 228 case HID_DG_TIPPRESSURE:
229 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
230 field->logical_minimum = 0;
206 hid_map_usage(hi, usage, bit, max, 231 hid_map_usage(hi, usage, bit, max,
207 EV_ABS, ABS_MT_PRESSURE); 232 EV_ABS, ABS_MT_PRESSURE);
208 set_abs(hi->input, ABS_MT_PRESSURE, field, 233 set_abs(hi->input, ABS_MT_PRESSURE, field,
@@ -363,8 +388,11 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
363 return 0; 388 return 0;
364 } 389 }
365 390
366 if (usage->hid == td->last_slot_field) 391 if (usage->hid == td->last_slot_field) {
367 mt_complete_slot(td); 392 mt_complete_slot(td);
393 if (!td->last_field_index)
394 mt_emit_event(td, field->hidinput->input);
395 }
368 396
369 if (field->index == td->last_field_index 397 if (field->index == td->last_field_index
370 && td->num_received >= td->num_expected) 398 && td->num_received >= td->num_expected)
@@ -466,18 +494,42 @@ static const struct hid_device_id mt_devices[] = {
466 USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, 494 USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
467 495
468 /* GeneralTouch panel */ 496 /* GeneralTouch panel */
469 { .driver_data = MT_CLS_DUAL2, 497 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
470 HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 498 HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
471 USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, 499 USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
472 500
501 /* IRTOUCH panels */
502 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
503 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
504 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
505
473 /* PixCir-based panels */ 506 /* PixCir-based panels */
474 { .driver_data = MT_CLS_DUAL1, 507 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
475 HID_USB_DEVICE(USB_VENDOR_ID_HANVON, 508 HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
476 USB_DEVICE_ID_HANVON_MULTITOUCH) }, 509 USB_DEVICE_ID_HANVON_MULTITOUCH) },
477 { .driver_data = MT_CLS_DUAL1, 510 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
478 HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 511 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
479 USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, 512 USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
480 513
514 /* Resistive eGalax devices */
515 { .driver_data = MT_CLS_EGALAX,
516 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
517 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
518 { .driver_data = MT_CLS_EGALAX,
519 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
520 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
521
522 /* Capacitive eGalax devices */
523 { .driver_data = MT_CLS_EGALAX,
524 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
525 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
526 { .driver_data = MT_CLS_EGALAX,
527 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
528 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
529 { .driver_data = MT_CLS_EGALAX,
530 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
531 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
532
481 { } 533 { }
482}; 534};
483MODULE_DEVICE_TABLE(hid, mt_devices); 535MODULE_DEVICE_TABLE(hid, mt_devices);