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.c93
1 files changed, 79 insertions, 14 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 58d0e7aaf088..fa5d7a1ffa9e 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -47,10 +47,11 @@ MODULE_LICENSE("GPL");
47#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1) 47#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1)
48#define MT_QUIRK_CYPRESS (1 << 2) 48#define MT_QUIRK_CYPRESS (1 << 2)
49#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3) 49#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
50#define MT_QUIRK_VALID_IS_INRANGE (1 << 4) 50#define MT_QUIRK_ALWAYS_VALID (1 << 4)
51#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) 51#define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
52#define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) 52#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7) 53#define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 7)
54#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
54 55
55struct mt_slot { 56struct mt_slot {
56 __s32 x, y, p, w, h; 57 __s32 x, y, p, w, h;
@@ -86,11 +87,12 @@ struct mt_class {
86/* classes of device behavior */ 87/* classes of device behavior */
87#define MT_CLS_DEFAULT 0x0001 88#define MT_CLS_DEFAULT 0x0001
88 89
89#define MT_CLS_CONFIDENCE 0x0002 90#define MT_CLS_SERIAL 0x0002
90#define MT_CLS_CONFIDENCE_MINUS_ONE 0x0003 91#define MT_CLS_CONFIDENCE 0x0003
91#define MT_CLS_DUAL_INRANGE_CONTACTID 0x0004 92#define MT_CLS_CONFIDENCE_MINUS_ONE 0x0004
92#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0005 93#define MT_CLS_DUAL_INRANGE_CONTACTID 0x0005
93#define MT_CLS_DUAL_NSMU_CONTACTID 0x0006 94#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0006
95#define MT_CLS_DUAL_NSMU_CONTACTID 0x0007
94 96
95/* vendor specific classes */ 97/* vendor specific classes */
96#define MT_CLS_3M 0x0101 98#define MT_CLS_3M 0x0101
@@ -134,6 +136,8 @@ static int find_slot_from_contactid(struct mt_device *td)
134struct mt_class mt_classes[] = { 136struct mt_class mt_classes[] = {
135 { .name = MT_CLS_DEFAULT, 137 { .name = MT_CLS_DEFAULT,
136 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, 138 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
139 { .name = MT_CLS_SERIAL,
140 .quirks = MT_QUIRK_ALWAYS_VALID},
137 { .name = MT_CLS_CONFIDENCE, 141 { .name = MT_CLS_CONFIDENCE,
138 .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, 142 .quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
139 { .name = MT_CLS_CONFIDENCE_MINUS_ONE, 143 { .name = MT_CLS_CONFIDENCE_MINUS_ONE,
@@ -213,6 +217,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
213 struct mt_class *cls = td->mtclass; 217 struct mt_class *cls = td->mtclass;
214 __s32 quirks = cls->quirks; 218 __s32 quirks = cls->quirks;
215 219
220 /* Only map fields from TouchScreen or TouchPad collections.
221 * We need to ignore fields that belong to other collections
222 * such as Mouse that might have the same GenericDesktop usages. */
223 if (field->application == HID_DG_TOUCHSCREEN)
224 set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
225 else if (field->application == HID_DG_TOUCHPAD)
226 set_bit(INPUT_PROP_POINTER, hi->input->propbit);
227 else
228 return 0;
229
216 switch (usage->hid & HID_USAGE_PAGE) { 230 switch (usage->hid & HID_USAGE_PAGE) {
217 231
218 case HID_UP_GENDESK: 232 case HID_UP_GENDESK:
@@ -277,6 +291,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
277 td->last_slot_field = usage->hid; 291 td->last_slot_field = usage->hid;
278 td->last_field_index = field->index; 292 td->last_field_index = field->index;
279 td->last_mt_collection = usage->collection_index; 293 td->last_mt_collection = usage->collection_index;
294 hdev->quirks &= ~HID_QUIRK_MULTITOUCH;
280 return 1; 295 return 1;
281 case HID_DG_WIDTH: 296 case HID_DG_WIDTH:
282 hid_map_usage(hi, usage, bit, max, 297 hid_map_usage(hi, usage, bit, max,
@@ -435,7 +450,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
435 if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { 450 if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
436 switch (usage->hid) { 451 switch (usage->hid) {
437 case HID_DG_INRANGE: 452 case HID_DG_INRANGE:
438 if (quirks & MT_QUIRK_VALID_IS_INRANGE) 453 if (quirks & MT_QUIRK_ALWAYS_VALID)
454 td->curvalid = true;
455 else if (quirks & MT_QUIRK_VALID_IS_INRANGE)
439 td->curvalid = value; 456 td->curvalid = value;
440 break; 457 break;
441 case HID_DG_TIPSWITCH: 458 case HID_DG_TIPSWITCH:
@@ -513,12 +530,44 @@ static void mt_set_input_mode(struct hid_device *hdev)
513 } 530 }
514} 531}
515 532
533/* a list of devices for which there is a specialized multitouch driver */
534static const struct hid_device_id mt_have_special_driver[] = {
535 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, 0x0001) },
536 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, 0x0006) },
537 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
538 USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
539 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
540 USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
541 { }
542};
543
544static bool mt_match_one_id(struct hid_device *hdev,
545 const struct hid_device_id *id)
546{
547 return id->bus == hdev->bus &&
548 (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) &&
549 (id->product == HID_ANY_ID || id->product == hdev->product);
550}
551
552static const struct hid_device_id *mt_match_id(struct hid_device *hdev,
553 const struct hid_device_id *id)
554{
555 for (; id->bus; id++)
556 if (mt_match_one_id(hdev, id))
557 return id;
558
559 return NULL;
560}
561
516static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 562static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
517{ 563{
518 int ret, i; 564 int ret, i;
519 struct mt_device *td; 565 struct mt_device *td;
520 struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ 566 struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
521 567
568 if (mt_match_id(hdev, mt_have_special_driver))
569 return -ENODEV;
570
522 for (i = 0; mt_classes[i].name ; i++) { 571 for (i = 0; mt_classes[i].name ; i++) {
523 if (id->driver_data == mt_classes[i].name) { 572 if (id->driver_data == mt_classes[i].name) {
524 mtclass = &(mt_classes[i]); 573 mtclass = &(mt_classes[i]);
@@ -526,10 +575,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
526 } 575 }
527 } 576 }
528 577
529 /* This allows the driver to correctly support devices
530 * that emit events over several HID messages.
531 */
532 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
533 578
534 td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); 579 td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
535 if (!td) { 580 if (!td) {
@@ -545,10 +590,16 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
545 if (ret != 0) 590 if (ret != 0)
546 goto fail; 591 goto fail;
547 592
593 hdev->quirks |= HID_QUIRK_MULTITOUCH;
548 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 594 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
549 if (ret) 595 if (ret)
550 goto fail; 596 goto fail;
551 597
598 /* This allows the driver to correctly support devices
599 * that emit events over several HID messages.
600 */
601 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
602
552 td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), 603 td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
553 GFP_KERNEL); 604 GFP_KERNEL);
554 if (!td->slots) { 605 if (!td->slots) {
@@ -662,6 +713,11 @@ static const struct hid_device_id mt_devices[] = {
662 HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, 713 HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
663 USB_DEVICE_ID_GOODTOUCH_000f) }, 714 USB_DEVICE_ID_GOODTOUCH_000f) },
664 715
716 /* Ideacom panel */
717 { .driver_data = MT_CLS_SERIAL,
718 HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
719 USB_DEVICE_ID_IDEACOM_IDC6650) },
720
665 /* Ilitek dual touch panel */ 721 /* Ilitek dual touch panel */
666 { .driver_data = MT_CLS_DEFAULT, 722 { .driver_data = MT_CLS_DEFAULT,
667 HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, 723 HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
@@ -672,6 +728,11 @@ static const struct hid_device_id mt_devices[] = {
672 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, 728 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
673 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, 729 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
674 730
731 /* LG Display panels */
732 { .driver_data = MT_CLS_DEFAULT,
733 HID_USB_DEVICE(USB_VENDOR_ID_LG,
734 USB_DEVICE_ID_LG_MULTITOUCH) },
735
675 /* Lumio panels */ 736 /* Lumio panels */
676 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 737 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
677 HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, 738 HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
@@ -732,6 +793,10 @@ static const struct hid_device_id mt_devices[] = {
732 HID_USB_DEVICE(USB_VENDOR_ID_XAT, 793 HID_USB_DEVICE(USB_VENDOR_ID_XAT,
733 USB_DEVICE_ID_XAT_CSR) }, 794 USB_DEVICE_ID_XAT_CSR) },
734 795
796 /* Rest of the world */
797 { .driver_data = MT_CLS_DEFAULT,
798 HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) },
799
735 { } 800 { }
736}; 801};
737MODULE_DEVICE_TABLE(hid, mt_devices); 802MODULE_DEVICE_TABLE(hid, mt_devices);