diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-rw-r--r-- | drivers/hid/hid-multitouch.c | 222 |
1 files changed, 169 insertions, 53 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 24fc4423b937..1d5b94167b52 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 { |
@@ -74,11 +75,15 @@ struct mt_device { | |||
74 | struct mt_class mtclass; /* our mt device class */ | 75 | struct mt_class mtclass; /* our mt device class */ |
75 | unsigned last_field_index; /* last field index of the report */ | 76 | unsigned last_field_index; /* last field index of the report */ |
76 | unsigned last_slot_field; /* the last field of a slot */ | 77 | unsigned last_slot_field; /* the last field of a slot */ |
77 | int last_mt_collection; /* last known mt-related collection */ | ||
78 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 78 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
79 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, | ||
80 | -1 if non-existent */ | ||
79 | __u8 num_received; /* how many contacts we received */ | 81 | __u8 num_received; /* how many contacts we received */ |
80 | __u8 num_expected; /* expected last contact index */ | 82 | __u8 num_expected; /* expected last contact index */ |
81 | __u8 maxcontacts; | 83 | __u8 maxcontacts; |
84 | __u8 touches_by_report; /* how many touches are present in one report: | ||
85 | * 1 means we should use a serial protocol | ||
86 | * > 1 means hybrid (multitouch) protocol */ | ||
82 | bool curvalid; /* is the current contact valid? */ | 87 | bool curvalid; /* is the current contact valid? */ |
83 | struct mt_slot *slots; | 88 | struct mt_slot *slots; |
84 | }; | 89 | }; |
@@ -100,6 +105,8 @@ struct mt_device { | |||
100 | #define MT_CLS_CYPRESS 0x0102 | 105 | #define MT_CLS_CYPRESS 0x0102 |
101 | #define MT_CLS_EGALAX 0x0103 | 106 | #define MT_CLS_EGALAX 0x0103 |
102 | #define MT_CLS_EGALAX_SERIAL 0x0104 | 107 | #define MT_CLS_EGALAX_SERIAL 0x0104 |
108 | #define MT_CLS_TOPSEED 0x0105 | ||
109 | #define MT_CLS_PANASONIC 0x0106 | ||
103 | 110 | ||
104 | #define MT_DEFAULT_MAXCONTACT 10 | 111 | #define MT_DEFAULT_MAXCONTACT 10 |
105 | 112 | ||
@@ -189,6 +196,14 @@ static struct mt_class mt_classes[] = { | |||
189 | .sn_move = 4096, | 196 | .sn_move = 4096, |
190 | .sn_pressure = 32, | 197 | .sn_pressure = 32, |
191 | }, | 198 | }, |
199 | { .name = MT_CLS_TOPSEED, | ||
200 | .quirks = MT_QUIRK_ALWAYS_VALID, | ||
201 | .is_indirect = true, | ||
202 | .maxcontacts = 2, | ||
203 | }, | ||
204 | { .name = MT_CLS_PANASONIC, | ||
205 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, | ||
206 | .maxcontacts = 4 }, | ||
192 | 207 | ||
193 | { } | 208 | { } |
194 | }; | 209 | }; |
@@ -241,6 +256,7 @@ static void mt_feature_mapping(struct hid_device *hdev, | |||
241 | td->inputmode = field->report->id; | 256 | td->inputmode = field->report->id; |
242 | break; | 257 | break; |
243 | case HID_DG_CONTACTMAX: | 258 | case HID_DG_CONTACTMAX: |
259 | td->maxcontact_report_id = field->report->id; | ||
244 | td->maxcontacts = field->value[0]; | 260 | td->maxcontacts = field->value[0]; |
245 | if (td->mtclass.maxcontacts) | 261 | if (td->mtclass.maxcontacts) |
246 | /* check if the maxcontacts is given by the class */ | 262 | /* check if the maxcontacts is given by the class */ |
@@ -259,23 +275,44 @@ static void set_abs(struct input_dev *input, unsigned int code, | |||
259 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); | 275 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); |
260 | } | 276 | } |
261 | 277 | ||
278 | static void set_last_slot_field(struct hid_usage *usage, struct mt_device *td, | ||
279 | struct hid_input *hi) | ||
280 | { | ||
281 | if (!test_bit(usage->hid, hi->input->absbit)) | ||
282 | td->last_slot_field = usage->hid; | ||
283 | } | ||
284 | |||
262 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 285 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
263 | struct hid_field *field, struct hid_usage *usage, | 286 | struct hid_field *field, struct hid_usage *usage, |
264 | unsigned long **bit, int *max) | 287 | unsigned long **bit, int *max) |
265 | { | 288 | { |
266 | struct mt_device *td = hid_get_drvdata(hdev); | 289 | struct mt_device *td = hid_get_drvdata(hdev); |
267 | struct mt_class *cls = &td->mtclass; | 290 | struct mt_class *cls = &td->mtclass; |
291 | int code; | ||
268 | 292 | ||
269 | /* Only map fields from TouchScreen or TouchPad collections. | 293 | /* Only map fields from TouchScreen or TouchPad collections. |
270 | * We need to ignore fields that belong to other collections | 294 | * We need to ignore fields that belong to other collections |
271 | * such as Mouse that might have the same GenericDesktop usages. */ | 295 | * such as Mouse that might have the same GenericDesktop usages. */ |
272 | if (field->application == HID_DG_TOUCHSCREEN) | 296 | if (field->application == HID_DG_TOUCHSCREEN) |
273 | set_bit(INPUT_PROP_DIRECT, hi->input->propbit); | 297 | set_bit(INPUT_PROP_DIRECT, hi->input->propbit); |
274 | else if (field->application == HID_DG_TOUCHPAD) | 298 | else if (field->application != HID_DG_TOUCHPAD) |
275 | set_bit(INPUT_PROP_POINTER, hi->input->propbit); | ||
276 | else | ||
277 | return 0; | 299 | return 0; |
278 | 300 | ||
301 | /* In case of an indirect device (touchpad), we need to add | ||
302 | * specific BTN_TOOL_* to be handled by the synaptics xorg | ||
303 | * driver. | ||
304 | * We also consider that touchscreens providing buttons are touchpads. | ||
305 | */ | ||
306 | if (field->application == HID_DG_TOUCHPAD || | ||
307 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || | ||
308 | cls->is_indirect) { | ||
309 | set_bit(INPUT_PROP_POINTER, hi->input->propbit); | ||
310 | set_bit(BTN_TOOL_FINGER, hi->input->keybit); | ||
311 | set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit); | ||
312 | set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit); | ||
313 | set_bit(BTN_TOOL_QUADTAP, hi->input->keybit); | ||
314 | } | ||
315 | |||
279 | /* eGalax devices provide a Digitizer.Stylus input which overrides | 316 | /* eGalax devices provide a Digitizer.Stylus input which overrides |
280 | * the correct Digitizers.Finger X/Y ranges. | 317 | * the correct Digitizers.Finger X/Y ranges. |
281 | * Let's just ignore this input. */ | 318 | * Let's just ignore this input. */ |
@@ -293,10 +330,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
293 | cls->sn_move); | 330 | cls->sn_move); |
294 | /* touchscreen emulation */ | 331 | /* touchscreen emulation */ |
295 | set_abs(hi->input, ABS_X, field, cls->sn_move); | 332 | set_abs(hi->input, ABS_X, field, cls->sn_move); |
296 | if (td->last_mt_collection == usage->collection_index) { | 333 | set_last_slot_field(usage, td, hi); |
297 | td->last_slot_field = usage->hid; | 334 | td->last_field_index = field->index; |
298 | td->last_field_index = field->index; | ||
299 | } | ||
300 | return 1; | 335 | return 1; |
301 | case HID_GD_Y: | 336 | case HID_GD_Y: |
302 | hid_map_usage(hi, usage, bit, max, | 337 | hid_map_usage(hi, usage, bit, max, |
@@ -305,10 +340,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
305 | cls->sn_move); | 340 | cls->sn_move); |
306 | /* touchscreen emulation */ | 341 | /* touchscreen emulation */ |
307 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | 342 | set_abs(hi->input, ABS_Y, field, cls->sn_move); |
308 | if (td->last_mt_collection == usage->collection_index) { | 343 | set_last_slot_field(usage, td, hi); |
309 | td->last_slot_field = usage->hid; | 344 | td->last_field_index = field->index; |
310 | td->last_field_index = field->index; | ||
311 | } | ||
312 | return 1; | 345 | return 1; |
313 | } | 346 | } |
314 | return 0; | 347 | return 0; |
@@ -316,24 +349,18 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
316 | case HID_UP_DIGITIZER: | 349 | case HID_UP_DIGITIZER: |
317 | switch (usage->hid) { | 350 | switch (usage->hid) { |
318 | case HID_DG_INRANGE: | 351 | case HID_DG_INRANGE: |
319 | if (td->last_mt_collection == usage->collection_index) { | 352 | set_last_slot_field(usage, td, hi); |
320 | td->last_slot_field = usage->hid; | 353 | td->last_field_index = field->index; |
321 | td->last_field_index = field->index; | ||
322 | } | ||
323 | return 1; | 354 | return 1; |
324 | case HID_DG_CONFIDENCE: | 355 | case HID_DG_CONFIDENCE: |
325 | if (td->last_mt_collection == usage->collection_index) { | 356 | set_last_slot_field(usage, td, hi); |
326 | td->last_slot_field = usage->hid; | 357 | td->last_field_index = field->index; |
327 | td->last_field_index = field->index; | ||
328 | } | ||
329 | return 1; | 358 | return 1; |
330 | case HID_DG_TIPSWITCH: | 359 | case HID_DG_TIPSWITCH: |
331 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 360 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
332 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 361 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
333 | if (td->last_mt_collection == usage->collection_index) { | 362 | set_last_slot_field(usage, td, hi); |
334 | td->last_slot_field = usage->hid; | 363 | td->last_field_index = field->index; |
335 | td->last_field_index = field->index; | ||
336 | } | ||
337 | return 1; | 364 | return 1; |
338 | case HID_DG_CONTACTID: | 365 | case HID_DG_CONTACTID: |
339 | if (!td->maxcontacts) | 366 | if (!td->maxcontacts) |
@@ -341,17 +368,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
341 | input_mt_init_slots(hi->input, td->maxcontacts); | 368 | input_mt_init_slots(hi->input, td->maxcontacts); |
342 | td->last_slot_field = usage->hid; | 369 | td->last_slot_field = usage->hid; |
343 | td->last_field_index = field->index; | 370 | td->last_field_index = field->index; |
344 | td->last_mt_collection = usage->collection_index; | 371 | td->touches_by_report++; |
345 | return 1; | 372 | return 1; |
346 | case HID_DG_WIDTH: | 373 | case HID_DG_WIDTH: |
347 | hid_map_usage(hi, usage, bit, max, | 374 | hid_map_usage(hi, usage, bit, max, |
348 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 375 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
349 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 376 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
350 | cls->sn_width); | 377 | cls->sn_width); |
351 | if (td->last_mt_collection == usage->collection_index) { | 378 | set_last_slot_field(usage, td, hi); |
352 | td->last_slot_field = usage->hid; | 379 | td->last_field_index = field->index; |
353 | td->last_field_index = field->index; | ||
354 | } | ||
355 | return 1; | 380 | return 1; |
356 | case HID_DG_HEIGHT: | 381 | case HID_DG_HEIGHT: |
357 | hid_map_usage(hi, usage, bit, max, | 382 | hid_map_usage(hi, usage, bit, max, |
@@ -360,10 +385,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
360 | cls->sn_height); | 385 | cls->sn_height); |
361 | input_set_abs_params(hi->input, | 386 | input_set_abs_params(hi->input, |
362 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 387 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
363 | if (td->last_mt_collection == usage->collection_index) { | 388 | set_last_slot_field(usage, td, hi); |
364 | td->last_slot_field = usage->hid; | 389 | td->last_field_index = field->index; |
365 | td->last_field_index = field->index; | ||
366 | } | ||
367 | return 1; | 390 | return 1; |
368 | case HID_DG_TIPPRESSURE: | 391 | case HID_DG_TIPPRESSURE: |
369 | hid_map_usage(hi, usage, bit, max, | 392 | hid_map_usage(hi, usage, bit, max, |
@@ -373,25 +396,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
373 | /* touchscreen emulation */ | 396 | /* touchscreen emulation */ |
374 | set_abs(hi->input, ABS_PRESSURE, field, | 397 | set_abs(hi->input, ABS_PRESSURE, field, |
375 | cls->sn_pressure); | 398 | cls->sn_pressure); |
376 | if (td->last_mt_collection == usage->collection_index) { | 399 | set_last_slot_field(usage, td, hi); |
377 | td->last_slot_field = usage->hid; | 400 | td->last_field_index = field->index; |
378 | td->last_field_index = field->index; | ||
379 | } | ||
380 | return 1; | 401 | return 1; |
381 | case HID_DG_CONTACTCOUNT: | 402 | case HID_DG_CONTACTCOUNT: |
382 | if (td->last_mt_collection == usage->collection_index) | 403 | td->last_field_index = field->index; |
383 | td->last_field_index = field->index; | ||
384 | return 1; | 404 | return 1; |
385 | case HID_DG_CONTACTMAX: | 405 | case HID_DG_CONTACTMAX: |
386 | /* we don't set td->last_slot_field as contactcount and | 406 | /* we don't set td->last_slot_field as contactcount and |
387 | * contact max are global to the report */ | 407 | * contact max are global to the report */ |
388 | if (td->last_mt_collection == usage->collection_index) | 408 | td->last_field_index = field->index; |
389 | td->last_field_index = field->index; | ||
390 | return -1; | 409 | return -1; |
391 | } | 410 | } |
411 | case HID_DG_TOUCH: | ||
412 | /* Legacy devices use TIPSWITCH and not TOUCH. | ||
413 | * Let's just ignore this field. */ | ||
414 | return -1; | ||
392 | /* let hid-input decide for the others */ | 415 | /* let hid-input decide for the others */ |
393 | return 0; | 416 | return 0; |
394 | 417 | ||
418 | case HID_UP_BUTTON: | ||
419 | code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); | ||
420 | hid_map_usage(hi, usage, bit, max, EV_KEY, code); | ||
421 | input_set_capability(hi->input, EV_KEY, code); | ||
422 | return 1; | ||
423 | |||
395 | case 0xff000000: | 424 | case 0xff000000: |
396 | /* we do not want to map these: no input-oriented meaning */ | 425 | /* we do not want to map these: no input-oriented meaning */ |
397 | return -1; | 426 | return -1; |
@@ -538,15 +567,17 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
538 | if (value) | 567 | if (value) |
539 | td->num_expected = value; | 568 | td->num_expected = value; |
540 | break; | 569 | break; |
570 | case HID_DG_TOUCH: | ||
571 | /* do nothing */ | ||
572 | break; | ||
541 | 573 | ||
542 | default: | 574 | default: |
543 | /* fallback to the generic hidinput handling */ | 575 | /* fallback to the generic hidinput handling */ |
544 | return 0; | 576 | return 0; |
545 | } | 577 | } |
546 | 578 | ||
547 | if (usage->hid == td->last_slot_field) { | 579 | if (usage->hid == td->last_slot_field) |
548 | mt_complete_slot(td); | 580 | mt_complete_slot(td); |
549 | } | ||
550 | 581 | ||
551 | if (field->index == td->last_field_index | 582 | if (field->index == td->last_field_index |
552 | && td->num_received >= td->num_expected) | 583 | && td->num_received >= td->num_expected) |
@@ -578,16 +609,44 @@ static void mt_set_input_mode(struct hid_device *hdev) | |||
578 | } | 609 | } |
579 | } | 610 | } |
580 | 611 | ||
612 | static void mt_set_maxcontacts(struct hid_device *hdev) | ||
613 | { | ||
614 | struct mt_device *td = hid_get_drvdata(hdev); | ||
615 | struct hid_report *r; | ||
616 | struct hid_report_enum *re; | ||
617 | int fieldmax, max; | ||
618 | |||
619 | if (td->maxcontact_report_id < 0) | ||
620 | return; | ||
621 | |||
622 | if (!td->mtclass.maxcontacts) | ||
623 | return; | ||
624 | |||
625 | re = &hdev->report_enum[HID_FEATURE_REPORT]; | ||
626 | r = re->report_id_hash[td->maxcontact_report_id]; | ||
627 | if (r) { | ||
628 | max = td->mtclass.maxcontacts; | ||
629 | fieldmax = r->field[0]->logical_maximum; | ||
630 | max = min(fieldmax, max); | ||
631 | if (r->field[0]->value[0] != max) { | ||
632 | r->field[0]->value[0] = max; | ||
633 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | ||
634 | } | ||
635 | } | ||
636 | } | ||
637 | |||
581 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | 638 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
582 | { | 639 | { |
583 | int ret, i; | 640 | int ret, i; |
584 | struct mt_device *td; | 641 | struct mt_device *td; |
585 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ | 642 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ |
586 | 643 | ||
587 | for (i = 0; mt_classes[i].name ; i++) { | 644 | if (id) { |
588 | if (id->driver_data == mt_classes[i].name) { | 645 | for (i = 0; mt_classes[i].name ; i++) { |
589 | mtclass = &(mt_classes[i]); | 646 | if (id->driver_data == mt_classes[i].name) { |
590 | break; | 647 | mtclass = &(mt_classes[i]); |
648 | break; | ||
649 | } | ||
591 | } | 650 | } |
592 | } | 651 | } |
593 | 652 | ||
@@ -595,6 +654,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
595 | * that emit events over several HID messages. | 654 | * that emit events over several HID messages. |
596 | */ | 655 | */ |
597 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | 656 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
657 | hdev->quirks &= ~HID_QUIRK_MULTITOUCH; | ||
598 | 658 | ||
599 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); | 659 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); |
600 | if (!td) { | 660 | if (!td) { |
@@ -603,7 +663,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
603 | } | 663 | } |
604 | td->mtclass = *mtclass; | 664 | td->mtclass = *mtclass; |
605 | td->inputmode = -1; | 665 | td->inputmode = -1; |
606 | td->last_mt_collection = -1; | 666 | td->maxcontact_report_id = -1; |
607 | hid_set_drvdata(hdev, td); | 667 | hid_set_drvdata(hdev, td); |
608 | 668 | ||
609 | ret = hid_parse(hdev); | 669 | ret = hid_parse(hdev); |
@@ -614,6 +674,15 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
614 | if (ret) | 674 | if (ret) |
615 | goto fail; | 675 | goto fail; |
616 | 676 | ||
677 | if (!id && td->touches_by_report == 1) { | ||
678 | /* the device has been sent by hid-generic */ | ||
679 | mtclass = &td->mtclass; | ||
680 | mtclass->quirks |= MT_QUIRK_ALWAYS_VALID; | ||
681 | mtclass->quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | ||
682 | mtclass->quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | ||
683 | mtclass->quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; | ||
684 | } | ||
685 | |||
617 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), | 686 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), |
618 | GFP_KERNEL); | 687 | GFP_KERNEL); |
619 | if (!td->slots) { | 688 | if (!td->slots) { |
@@ -625,6 +694,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
625 | 694 | ||
626 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); | 695 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); |
627 | 696 | ||
697 | mt_set_maxcontacts(hdev); | ||
628 | mt_set_input_mode(hdev); | 698 | mt_set_input_mode(hdev); |
629 | 699 | ||
630 | return 0; | 700 | return 0; |
@@ -637,6 +707,7 @@ fail: | |||
637 | #ifdef CONFIG_PM | 707 | #ifdef CONFIG_PM |
638 | static int mt_reset_resume(struct hid_device *hdev) | 708 | static int mt_reset_resume(struct hid_device *hdev) |
639 | { | 709 | { |
710 | mt_set_maxcontacts(hdev); | ||
640 | mt_set_input_mode(hdev); | 711 | mt_set_input_mode(hdev); |
641 | return 0; | 712 | return 0; |
642 | } | 713 | } |
@@ -674,6 +745,9 @@ static const struct hid_device_id mt_devices[] = { | |||
674 | { .driver_data = MT_CLS_SERIAL, | 745 | { .driver_data = MT_CLS_SERIAL, |
675 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, | 746 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, |
676 | USB_DEVICE_ID_ATMEL_MULTITOUCH) }, | 747 | USB_DEVICE_ID_ATMEL_MULTITOUCH) }, |
748 | { .driver_data = MT_CLS_SERIAL, | ||
749 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, | ||
750 | USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, | ||
677 | 751 | ||
678 | /* Cando panels */ | 752 | /* Cando panels */ |
679 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 753 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
@@ -716,12 +790,30 @@ static const struct hid_device_id mt_devices[] = { | |||
716 | { .driver_data = MT_CLS_EGALAX, | 790 | { .driver_data = MT_CLS_EGALAX, |
717 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 791 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
718 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, | 792 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, |
793 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
794 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
795 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, | ||
796 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
797 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
798 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, | ||
799 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
800 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
801 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | ||
802 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
803 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
804 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, | ||
719 | { .driver_data = MT_CLS_EGALAX, | 805 | { .driver_data = MT_CLS_EGALAX, |
720 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 806 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
721 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | 807 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, |
808 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
809 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
810 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, | ||
722 | { .driver_data = MT_CLS_EGALAX, | 811 | { .driver_data = MT_CLS_EGALAX, |
723 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 812 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
724 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, | 813 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, |
814 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
815 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
816 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, | ||
725 | { .driver_data = MT_CLS_EGALAX, | 817 | { .driver_data = MT_CLS_EGALAX, |
726 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 818 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
727 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, | 819 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, |
@@ -730,6 +822,9 @@ static const struct hid_device_id mt_devices[] = { | |||
730 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, | 822 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, |
731 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 823 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
732 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 824 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
825 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) }, | ||
826 | { .driver_data = MT_CLS_EGALAX_SERIAL, | ||
827 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
733 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, | 828 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, |
734 | 829 | ||
735 | /* Elo TouchSystems IntelliTouch Plus panel */ | 830 | /* Elo TouchSystems IntelliTouch Plus panel */ |
@@ -742,6 +837,11 @@ static const struct hid_device_id mt_devices[] = { | |||
742 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | 837 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, |
743 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | 838 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, |
744 | 839 | ||
840 | /* Gametel game controller */ | ||
841 | { .driver_data = MT_CLS_DEFAULT, | ||
842 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_FRUCTEL, | ||
843 | USB_DEVICE_ID_GAMETEL_MT_MODE) }, | ||
844 | |||
745 | /* GoodTouch panels */ | 845 | /* GoodTouch panels */ |
746 | { .driver_data = MT_CLS_DEFAULT, | 846 | { .driver_data = MT_CLS_DEFAULT, |
747 | HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, | 847 | HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, |
@@ -756,6 +856,9 @@ static const struct hid_device_id mt_devices[] = { | |||
756 | { .driver_data = MT_CLS_SERIAL, | 856 | { .driver_data = MT_CLS_SERIAL, |
757 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, | 857 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, |
758 | USB_DEVICE_ID_IDEACOM_IDC6650) }, | 858 | USB_DEVICE_ID_IDEACOM_IDC6650) }, |
859 | { .driver_data = MT_CLS_SERIAL, | ||
860 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, | ||
861 | USB_DEVICE_ID_IDEACOM_IDC6651) }, | ||
759 | 862 | ||
760 | /* Ilitek dual touch panel */ | 863 | /* Ilitek dual touch panel */ |
761 | { .driver_data = MT_CLS_DEFAULT, | 864 | { .driver_data = MT_CLS_DEFAULT, |
@@ -791,6 +894,14 @@ static const struct hid_device_id mt_devices[] = { | |||
791 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, | 894 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, |
792 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | 895 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, |
793 | 896 | ||
897 | /* Panasonic panels */ | ||
898 | { .driver_data = MT_CLS_PANASONIC, | ||
899 | HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | ||
900 | USB_DEVICE_ID_PANABOARD_UBT780) }, | ||
901 | { .driver_data = MT_CLS_PANASONIC, | ||
902 | HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | ||
903 | USB_DEVICE_ID_PANABOARD_UBT880) }, | ||
904 | |||
794 | /* PenMount panels */ | 905 | /* PenMount panels */ |
795 | { .driver_data = MT_CLS_CONFIDENCE, | 906 | { .driver_data = MT_CLS_CONFIDENCE, |
796 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, | 907 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, |
@@ -837,6 +948,11 @@ static const struct hid_device_id mt_devices[] = { | |||
837 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, | 948 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, |
838 | USB_DEVICE_ID_MTP_SITRONIX)}, | 949 | USB_DEVICE_ID_MTP_SITRONIX)}, |
839 | 950 | ||
951 | /* TopSeed panels */ | ||
952 | { .driver_data = MT_CLS_TOPSEED, | ||
953 | HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, | ||
954 | USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, | ||
955 | |||
840 | /* Touch International panels */ | 956 | /* Touch International panels */ |
841 | { .driver_data = MT_CLS_DEFAULT, | 957 | { .driver_data = MT_CLS_DEFAULT, |
842 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, | 958 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, |