diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 264 |
1 files changed, 217 insertions, 47 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ee01e65e22d6..ecd4d2db9e80 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -11,6 +11,12 @@ | |||
11 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | 11 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> |
12 | * Copyright (c) 2010 Canonical, Ltd. | 12 | * Copyright (c) 2010 Canonical, Ltd. |
13 | * | 13 | * |
14 | * This code is partly based on hid-3m-pct.c: | ||
15 | * | ||
16 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> | ||
17 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | ||
18 | * Copyright (c) 2010 Canonical, Ltd. | ||
19 | * | ||
14 | */ | 20 | */ |
15 | 21 | ||
16 | /* | 22 | /* |
@@ -44,6 +50,7 @@ MODULE_LICENSE("GPL"); | |||
44 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) | 50 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) |
45 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) | 51 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) |
46 | #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) | 52 | #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) |
53 | #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7) | ||
47 | 54 | ||
48 | struct mt_slot { | 55 | struct mt_slot { |
49 | __s32 x, y, p, w, h; | 56 | __s32 x, y, p, w, h; |
@@ -60,24 +67,36 @@ struct mt_device { | |||
60 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 67 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
61 | __u8 num_received; /* how many contacts we received */ | 68 | __u8 num_received; /* how many contacts we received */ |
62 | __u8 num_expected; /* expected last contact index */ | 69 | __u8 num_expected; /* expected last contact index */ |
70 | __u8 maxcontacts; | ||
63 | bool curvalid; /* is the current contact valid? */ | 71 | bool curvalid; /* is the current contact valid? */ |
64 | struct mt_slot slots[0]; /* first slot */ | 72 | struct mt_slot *slots; |
65 | }; | 73 | }; |
66 | 74 | ||
67 | struct mt_class { | 75 | struct mt_class { |
68 | __s32 name; /* MT_CLS */ | 76 | __s32 name; /* MT_CLS */ |
69 | __s32 quirks; | 77 | __s32 quirks; |
70 | __s32 sn_move; /* Signal/noise ratio for move events */ | 78 | __s32 sn_move; /* Signal/noise ratio for move events */ |
79 | __s32 sn_width; /* Signal/noise ratio for width events */ | ||
80 | __s32 sn_height; /* Signal/noise ratio for height events */ | ||
71 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ | 81 | __s32 sn_pressure; /* Signal/noise ratio for pressure events */ |
72 | __u8 maxcontacts; | 82 | __u8 maxcontacts; |
73 | }; | 83 | }; |
74 | 84 | ||
75 | /* classes of device behavior */ | 85 | /* classes of device behavior */ |
76 | #define MT_CLS_DEFAULT 1 | 86 | #define MT_CLS_DEFAULT 0x0001 |
77 | #define MT_CLS_DUAL_INRANGE_CONTACTID 2 | 87 | |
78 | #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 | 88 | #define MT_CLS_CONFIDENCE 0x0002 |
79 | #define MT_CLS_CYPRESS 4 | 89 | #define MT_CLS_CONFIDENCE_MINUS_ONE 0x0003 |
80 | #define MT_CLS_EGALAX 5 | 90 | #define MT_CLS_DUAL_INRANGE_CONTACTID 0x0004 |
91 | #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0005 | ||
92 | #define MT_CLS_DUAL_NSMU_CONTACTID 0x0006 | ||
93 | |||
94 | /* vendor specific classes */ | ||
95 | #define MT_CLS_3M 0x0101 | ||
96 | #define MT_CLS_CYPRESS 0x0102 | ||
97 | #define MT_CLS_EGALAX 0x0103 | ||
98 | |||
99 | #define MT_DEFAULT_MAXCONTACT 10 | ||
81 | 100 | ||
82 | /* | 101 | /* |
83 | * these device-dependent functions determine what slot corresponds | 102 | * these device-dependent functions determine what slot corresponds |
@@ -95,12 +114,12 @@ static int cypress_compute_slot(struct mt_device *td) | |||
95 | static int find_slot_from_contactid(struct mt_device *td) | 114 | static int find_slot_from_contactid(struct mt_device *td) |
96 | { | 115 | { |
97 | int i; | 116 | int i; |
98 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | 117 | for (i = 0; i < td->maxcontacts; ++i) { |
99 | if (td->slots[i].contactid == td->curdata.contactid && | 118 | if (td->slots[i].contactid == td->curdata.contactid && |
100 | td->slots[i].touch_state) | 119 | td->slots[i].touch_state) |
101 | return i; | 120 | return i; |
102 | } | 121 | } |
103 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | 122 | for (i = 0; i < td->maxcontacts; ++i) { |
104 | if (!td->slots[i].seen_in_this_frame && | 123 | if (!td->slots[i].seen_in_this_frame && |
105 | !td->slots[i].touch_state) | 124 | !td->slots[i].touch_state) |
106 | return i; | 125 | return i; |
@@ -113,8 +132,12 @@ static int find_slot_from_contactid(struct mt_device *td) | |||
113 | 132 | ||
114 | struct mt_class mt_classes[] = { | 133 | struct mt_class mt_classes[] = { |
115 | { .name = MT_CLS_DEFAULT, | 134 | { .name = MT_CLS_DEFAULT, |
116 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, | 135 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, |
117 | .maxcontacts = 10 }, | 136 | { .name = MT_CLS_CONFIDENCE, |
137 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, | ||
138 | { .name = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
139 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | | ||
140 | MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, | ||
118 | { .name = MT_CLS_DUAL_INRANGE_CONTACTID, | 141 | { .name = MT_CLS_DUAL_INRANGE_CONTACTID, |
119 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | 142 | .quirks = MT_QUIRK_VALID_IS_INRANGE | |
120 | MT_QUIRK_SLOT_IS_CONTACTID, | 143 | MT_QUIRK_SLOT_IS_CONTACTID, |
@@ -123,11 +146,24 @@ struct mt_class mt_classes[] = { | |||
123 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | 146 | .quirks = MT_QUIRK_VALID_IS_INRANGE | |
124 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, | 147 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, |
125 | .maxcontacts = 2 }, | 148 | .maxcontacts = 2 }, |
149 | { .name = MT_CLS_DUAL_NSMU_CONTACTID, | ||
150 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | | ||
151 | MT_QUIRK_SLOT_IS_CONTACTID, | ||
152 | .maxcontacts = 2 }, | ||
153 | |||
154 | /* | ||
155 | * vendor specific classes | ||
156 | */ | ||
157 | { .name = MT_CLS_3M, | ||
158 | .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | | ||
159 | MT_QUIRK_SLOT_IS_CONTACTID, | ||
160 | .sn_move = 2048, | ||
161 | .sn_width = 128, | ||
162 | .sn_height = 128 }, | ||
126 | { .name = MT_CLS_CYPRESS, | 163 | { .name = MT_CLS_CYPRESS, |
127 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | | 164 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | |
128 | MT_QUIRK_CYPRESS, | 165 | MT_QUIRK_CYPRESS, |
129 | .maxcontacts = 10 }, | 166 | .maxcontacts = 10 }, |
130 | |||
131 | { .name = MT_CLS_EGALAX, | 167 | { .name = MT_CLS_EGALAX, |
132 | .quirks = MT_QUIRK_SLOT_IS_CONTACTID | | 168 | .quirks = MT_QUIRK_SLOT_IS_CONTACTID | |
133 | MT_QUIRK_VALID_IS_INRANGE | | 169 | MT_QUIRK_VALID_IS_INRANGE | |
@@ -136,15 +172,26 @@ struct mt_class mt_classes[] = { | |||
136 | .sn_move = 4096, | 172 | .sn_move = 4096, |
137 | .sn_pressure = 32, | 173 | .sn_pressure = 32, |
138 | }, | 174 | }, |
175 | |||
139 | { } | 176 | { } |
140 | }; | 177 | }; |
141 | 178 | ||
142 | static void mt_feature_mapping(struct hid_device *hdev, | 179 | static void mt_feature_mapping(struct hid_device *hdev, |
143 | struct hid_field *field, struct hid_usage *usage) | 180 | struct hid_field *field, struct hid_usage *usage) |
144 | { | 181 | { |
145 | if (usage->hid == HID_DG_INPUTMODE) { | 182 | struct mt_device *td = hid_get_drvdata(hdev); |
146 | struct mt_device *td = hid_get_drvdata(hdev); | 183 | |
184 | switch (usage->hid) { | ||
185 | case HID_DG_INPUTMODE: | ||
147 | td->inputmode = field->report->id; | 186 | td->inputmode = field->report->id; |
187 | break; | ||
188 | case HID_DG_CONTACTMAX: | ||
189 | td->maxcontacts = field->value[0]; | ||
190 | if (td->mtclass->maxcontacts) | ||
191 | /* check if the maxcontacts is given by the class */ | ||
192 | td->maxcontacts = td->mtclass->maxcontacts; | ||
193 | |||
194 | break; | ||
148 | } | 195 | } |
149 | } | 196 | } |
150 | 197 | ||
@@ -179,6 +226,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
179 | /* touchscreen emulation */ | 226 | /* touchscreen emulation */ |
180 | set_abs(hi->input, ABS_X, field, cls->sn_move); | 227 | set_abs(hi->input, ABS_X, field, cls->sn_move); |
181 | td->last_slot_field = usage->hid; | 228 | td->last_slot_field = usage->hid; |
229 | td->last_field_index = field->index; | ||
182 | return 1; | 230 | return 1; |
183 | case HID_GD_Y: | 231 | case HID_GD_Y: |
184 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 232 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -190,6 +238,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
190 | /* touchscreen emulation */ | 238 | /* touchscreen emulation */ |
191 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | 239 | set_abs(hi->input, ABS_Y, field, cls->sn_move); |
192 | td->last_slot_field = usage->hid; | 240 | td->last_slot_field = usage->hid; |
241 | td->last_field_index = field->index; | ||
193 | return 1; | 242 | return 1; |
194 | } | 243 | } |
195 | return 0; | 244 | return 0; |
@@ -198,32 +247,40 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
198 | switch (usage->hid) { | 247 | switch (usage->hid) { |
199 | case HID_DG_INRANGE: | 248 | case HID_DG_INRANGE: |
200 | td->last_slot_field = usage->hid; | 249 | td->last_slot_field = usage->hid; |
250 | td->last_field_index = field->index; | ||
201 | return 1; | 251 | return 1; |
202 | case HID_DG_CONFIDENCE: | 252 | case HID_DG_CONFIDENCE: |
203 | td->last_slot_field = usage->hid; | 253 | td->last_slot_field = usage->hid; |
254 | td->last_field_index = field->index; | ||
204 | return 1; | 255 | return 1; |
205 | case HID_DG_TIPSWITCH: | 256 | case HID_DG_TIPSWITCH: |
206 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 257 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
207 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 258 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
208 | td->last_slot_field = usage->hid; | 259 | td->last_slot_field = usage->hid; |
260 | td->last_field_index = field->index; | ||
209 | return 1; | 261 | return 1; |
210 | case HID_DG_CONTACTID: | 262 | case HID_DG_CONTACTID: |
211 | input_mt_init_slots(hi->input, | 263 | input_mt_init_slots(hi->input, td->maxcontacts); |
212 | td->mtclass->maxcontacts); | ||
213 | td->last_slot_field = usage->hid; | 264 | td->last_slot_field = usage->hid; |
265 | td->last_field_index = field->index; | ||
214 | return 1; | 266 | return 1; |
215 | case HID_DG_WIDTH: | 267 | case HID_DG_WIDTH: |
216 | hid_map_usage(hi, usage, bit, max, | 268 | hid_map_usage(hi, usage, bit, max, |
217 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 269 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
270 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | ||
271 | cls->sn_width); | ||
218 | td->last_slot_field = usage->hid; | 272 | td->last_slot_field = usage->hid; |
273 | td->last_field_index = field->index; | ||
219 | return 1; | 274 | return 1; |
220 | case HID_DG_HEIGHT: | 275 | case HID_DG_HEIGHT: |
221 | hid_map_usage(hi, usage, bit, max, | 276 | hid_map_usage(hi, usage, bit, max, |
222 | EV_ABS, ABS_MT_TOUCH_MINOR); | 277 | EV_ABS, ABS_MT_TOUCH_MINOR); |
223 | field->logical_maximum = 1; | 278 | set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, |
224 | field->logical_minimum = 0; | 279 | cls->sn_height); |
225 | set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); | 280 | input_set_abs_params(hi->input, |
281 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | ||
226 | td->last_slot_field = usage->hid; | 282 | td->last_slot_field = usage->hid; |
283 | td->last_field_index = field->index; | ||
227 | return 1; | 284 | return 1; |
228 | case HID_DG_TIPPRESSURE: | 285 | case HID_DG_TIPPRESSURE: |
229 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) | 286 | if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) |
@@ -236,13 +293,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
236 | set_abs(hi->input, ABS_PRESSURE, field, | 293 | set_abs(hi->input, ABS_PRESSURE, field, |
237 | cls->sn_pressure); | 294 | cls->sn_pressure); |
238 | td->last_slot_field = usage->hid; | 295 | td->last_slot_field = usage->hid; |
296 | td->last_field_index = field->index; | ||
239 | return 1; | 297 | return 1; |
240 | case HID_DG_CONTACTCOUNT: | 298 | case HID_DG_CONTACTCOUNT: |
241 | td->last_field_index = field->report->maxfield - 1; | 299 | td->last_field_index = field->index; |
242 | return 1; | 300 | return 1; |
243 | case HID_DG_CONTACTMAX: | 301 | case HID_DG_CONTACTMAX: |
244 | /* we don't set td->last_slot_field as contactcount and | 302 | /* we don't set td->last_slot_field as contactcount and |
245 | * contact max are global to the report */ | 303 | * contact max are global to the report */ |
304 | td->last_field_index = field->index; | ||
246 | return -1; | 305 | return -1; |
247 | } | 306 | } |
248 | /* let hid-input decide for the others */ | 307 | /* let hid-input decide for the others */ |
@@ -279,6 +338,9 @@ static int mt_compute_slot(struct mt_device *td) | |||
279 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) | 338 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) |
280 | return td->num_received; | 339 | return td->num_received; |
281 | 340 | ||
341 | if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) | ||
342 | return td->curdata.contactid - 1; | ||
343 | |||
282 | return find_slot_from_contactid(td); | 344 | return find_slot_from_contactid(td); |
283 | } | 345 | } |
284 | 346 | ||
@@ -292,7 +354,7 @@ static void mt_complete_slot(struct mt_device *td) | |||
292 | if (td->curvalid) { | 354 | if (td->curvalid) { |
293 | int slotnum = mt_compute_slot(td); | 355 | int slotnum = mt_compute_slot(td); |
294 | 356 | ||
295 | if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) | 357 | if (slotnum >= 0 && slotnum < td->maxcontacts) |
296 | td->slots[slotnum] = td->curdata; | 358 | td->slots[slotnum] = td->curdata; |
297 | } | 359 | } |
298 | td->num_received++; | 360 | td->num_received++; |
@@ -307,7 +369,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) | |||
307 | { | 369 | { |
308 | int i; | 370 | int i; |
309 | 371 | ||
310 | for (i = 0; i < td->mtclass->maxcontacts; ++i) { | 372 | for (i = 0; i < td->maxcontacts; ++i) { |
311 | struct mt_slot *s = &(td->slots[i]); | 373 | struct mt_slot *s = &(td->slots[i]); |
312 | if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && | 374 | if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && |
313 | !s->seen_in_this_frame) { | 375 | !s->seen_in_this_frame) { |
@@ -318,11 +380,18 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) | |||
318 | input_mt_report_slot_state(input, MT_TOOL_FINGER, | 380 | input_mt_report_slot_state(input, MT_TOOL_FINGER, |
319 | s->touch_state); | 381 | s->touch_state); |
320 | if (s->touch_state) { | 382 | if (s->touch_state) { |
383 | /* this finger is on the screen */ | ||
384 | int wide = (s->w > s->h); | ||
385 | /* divided by two to match visual scale of touch */ | ||
386 | int major = max(s->w, s->h) >> 1; | ||
387 | int minor = min(s->w, s->h) >> 1; | ||
388 | |||
321 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); | 389 | input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); |
322 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); | 390 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); |
391 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | ||
323 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); | 392 | input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); |
324 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); | 393 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
325 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); | 394 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); |
326 | } | 395 | } |
327 | s->seen_in_this_frame = false; | 396 | s->seen_in_this_frame = false; |
328 | 397 | ||
@@ -341,7 +410,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
341 | struct mt_device *td = hid_get_drvdata(hid); | 410 | struct mt_device *td = hid_get_drvdata(hid); |
342 | __s32 quirks = td->mtclass->quirks; | 411 | __s32 quirks = td->mtclass->quirks; |
343 | 412 | ||
344 | if (hid->claimed & HID_CLAIMED_INPUT) { | 413 | if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { |
345 | switch (usage->hid) { | 414 | switch (usage->hid) { |
346 | case HID_DG_INRANGE: | 415 | case HID_DG_INRANGE: |
347 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) | 416 | if (quirks & MT_QUIRK_VALID_IS_INRANGE) |
@@ -390,8 +459,6 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
390 | 459 | ||
391 | if (usage->hid == td->last_slot_field) { | 460 | if (usage->hid == td->last_slot_field) { |
392 | mt_complete_slot(td); | 461 | mt_complete_slot(td); |
393 | if (!td->last_field_index) | ||
394 | mt_emit_event(td, field->hidinput->input); | ||
395 | } | 462 | } |
396 | 463 | ||
397 | if (field->index == td->last_field_index | 464 | if (field->index == td->last_field_index |
@@ -442,9 +509,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
442 | */ | 509 | */ |
443 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | 510 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
444 | 511 | ||
445 | td = kzalloc(sizeof(struct mt_device) + | 512 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); |
446 | mtclass->maxcontacts * sizeof(struct mt_slot), | ||
447 | GFP_KERNEL); | ||
448 | if (!td) { | 513 | if (!td) { |
449 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); | 514 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); |
450 | return -ENOMEM; | 515 | return -ENOMEM; |
@@ -461,6 +526,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
461 | if (ret) | 526 | if (ret) |
462 | goto fail; | 527 | goto fail; |
463 | 528 | ||
529 | if (!td->maxcontacts) | ||
530 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
531 | |||
532 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), | ||
533 | GFP_KERNEL); | ||
534 | if (!td->slots) { | ||
535 | dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); | ||
536 | hid_hw_stop(hdev); | ||
537 | ret = -ENOMEM; | ||
538 | goto fail; | ||
539 | } | ||
540 | |||
464 | mt_set_input_mode(hdev); | 541 | mt_set_input_mode(hdev); |
465 | 542 | ||
466 | return 0; | 543 | return 0; |
@@ -482,27 +559,115 @@ static void mt_remove(struct hid_device *hdev) | |||
482 | { | 559 | { |
483 | struct mt_device *td = hid_get_drvdata(hdev); | 560 | struct mt_device *td = hid_get_drvdata(hdev); |
484 | hid_hw_stop(hdev); | 561 | hid_hw_stop(hdev); |
562 | kfree(td->slots); | ||
485 | kfree(td); | 563 | kfree(td); |
486 | hid_set_drvdata(hdev, NULL); | 564 | hid_set_drvdata(hdev, NULL); |
487 | } | 565 | } |
488 | 566 | ||
489 | static const struct hid_device_id mt_devices[] = { | 567 | static const struct hid_device_id mt_devices[] = { |
490 | 568 | ||
569 | /* 3M panels */ | ||
570 | { .driver_data = MT_CLS_3M, | ||
571 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | ||
572 | USB_DEVICE_ID_3M1968) }, | ||
573 | { .driver_data = MT_CLS_3M, | ||
574 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | ||
575 | USB_DEVICE_ID_3M2256) }, | ||
576 | |||
577 | /* ActionStar panels */ | ||
578 | { .driver_data = MT_CLS_DEFAULT, | ||
579 | HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, | ||
580 | USB_DEVICE_ID_ACTIONSTAR_1011) }, | ||
581 | |||
582 | /* Cando panels */ | ||
583 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
584 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
585 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | ||
586 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
587 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
588 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | ||
589 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
590 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
591 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | ||
592 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | ||
593 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
594 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | ||
595 | |||
596 | /* CVTouch panels */ | ||
597 | { .driver_data = MT_CLS_DEFAULT, | ||
598 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | ||
599 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, | ||
600 | |||
491 | /* Cypress panel */ | 601 | /* Cypress panel */ |
492 | { .driver_data = MT_CLS_CYPRESS, | 602 | { .driver_data = MT_CLS_CYPRESS, |
493 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, | 603 | HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, |
494 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, | 604 | USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, |
495 | 605 | ||
606 | /* eGalax devices (resistive) */ | ||
607 | { .driver_data = MT_CLS_EGALAX, | ||
608 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
609 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | ||
610 | { .driver_data = MT_CLS_EGALAX, | ||
611 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
612 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | ||
613 | |||
614 | /* eGalax devices (capacitive) */ | ||
615 | { .driver_data = MT_CLS_EGALAX, | ||
616 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
617 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | ||
618 | { .driver_data = MT_CLS_EGALAX, | ||
619 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
620 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, | ||
621 | { .driver_data = MT_CLS_EGALAX, | ||
622 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
623 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | ||
624 | |||
625 | /* Elo TouchSystems IntelliTouch Plus panel */ | ||
626 | { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, | ||
627 | HID_USB_DEVICE(USB_VENDOR_ID_ELO, | ||
628 | USB_DEVICE_ID_ELO_TS2515) }, | ||
629 | |||
496 | /* GeneralTouch panel */ | 630 | /* GeneralTouch panel */ |
497 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 631 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
498 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | 632 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, |
499 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | 633 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, |
500 | 634 | ||
635 | /* GoodTouch panels */ | ||
636 | { .driver_data = MT_CLS_DEFAULT, | ||
637 | HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, | ||
638 | USB_DEVICE_ID_GOODTOUCH_000f) }, | ||
639 | |||
640 | /* Ilitek dual touch panel */ | ||
641 | { .driver_data = MT_CLS_DEFAULT, | ||
642 | HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, | ||
643 | USB_DEVICE_ID_ILITEK_MULTITOUCH) }, | ||
644 | |||
501 | /* IRTOUCH panels */ | 645 | /* IRTOUCH panels */ |
502 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 646 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
503 | HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, | 647 | HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, |
504 | USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, | 648 | USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, |
505 | 649 | ||
650 | /* Lumio panels */ | ||
651 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
652 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, | ||
653 | USB_DEVICE_ID_CRYSTALTOUCH) }, | ||
654 | |||
655 | /* MosArt panels */ | ||
656 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
657 | HID_USB_DEVICE(USB_VENDOR_ID_ASUS, | ||
658 | USB_DEVICE_ID_ASUS_T91MT)}, | ||
659 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
660 | HID_USB_DEVICE(USB_VENDOR_ID_ASUS, | ||
661 | USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
662 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | ||
663 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, | ||
664 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | ||
665 | |||
666 | /* PenMount panels */ | ||
667 | { .driver_data = MT_CLS_CONFIDENCE, | ||
668 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, | ||
669 | USB_DEVICE_ID_PENMOUNT_PCI) }, | ||
670 | |||
506 | /* PixCir-based panels */ | 671 | /* PixCir-based panels */ |
507 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 672 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
508 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON, | 673 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON, |
@@ -511,24 +676,29 @@ static const struct hid_device_id mt_devices[] = { | |||
511 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 676 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
512 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, | 677 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, |
513 | 678 | ||
514 | /* Resistive eGalax devices */ | 679 | /* Stantum panels */ |
515 | { .driver_data = MT_CLS_EGALAX, | 680 | { .driver_data = MT_CLS_CONFIDENCE, |
516 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 681 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
517 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 682 | USB_DEVICE_ID_MTP)}, |
518 | { .driver_data = MT_CLS_EGALAX, | 683 | { .driver_data = MT_CLS_CONFIDENCE, |
519 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 684 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
520 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, | 685 | USB_DEVICE_ID_MTP_STM)}, |
521 | 686 | { .driver_data = MT_CLS_CONFIDENCE, | |
522 | /* Capacitive eGalax devices */ | 687 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
523 | { .driver_data = MT_CLS_EGALAX, | 688 | USB_DEVICE_ID_MTP_SITRONIX)}, |
524 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 689 | |
525 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | 690 | /* Touch International panels */ |
526 | { .driver_data = MT_CLS_EGALAX, | 691 | { .driver_data = MT_CLS_DEFAULT, |
527 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 692 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, |
528 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, | 693 | USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, |
529 | { .driver_data = MT_CLS_EGALAX, | 694 | |
530 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 695 | /* Unitec panels */ |
531 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, | 696 | { .driver_data = MT_CLS_DEFAULT, |
697 | HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, | ||
698 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, | ||
699 | { .driver_data = MT_CLS_DEFAULT, | ||
700 | HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, | ||
701 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | ||
532 | 702 | ||
533 | { } | 703 | { } |
534 | }; | 704 | }; |