aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@gmail.com>2013-01-31 11:22:25 -0500
committerJiri Kosina <jkosina@suse.cz>2013-02-05 06:07:40 -0500
commitc2517f62dac608e43b652dc6ed1e478e8447e029 (patch)
tree05c65f2a91e5364ff0ca257faecbe08068f42ccc /drivers/hid
parent55978fa9dc4c57f8249617c35d28c0599de850df (diff)
HID: multitouch: add support for Nexio 42" panel
This device is the worst device I saw. It keeps TipSwitch and InRange at 1 for fingers that are not touching the panel. The solution is to rely on the field ContactCount, which is accurate as the correct information are packed at the begining of the frame. Unfortunately, CountactCount is most of the time at the end of the report. The solution is to pick it when we have the whole report in raw_event. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-multitouch.c36
2 files changed, 33 insertions, 6 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 34e25471aeaa..8311380c76f6 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -597,6 +597,9 @@
597#define USB_VENDOR_ID_NEC 0x073e 597#define USB_VENDOR_ID_NEC 0x073e
598#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 598#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
599 599
600#define USB_VENDOR_ID_NEXIO 0x1870
601#define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d
602
600#define USB_VENDOR_ID_NEXTWINDOW 0x1926 603#define USB_VENDOR_ID_NEXTWINDOW 0x1926
601#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 604#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
602 605
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 13b94619b5d0..87690e2726ac 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -54,6 +54,7 @@ MODULE_LICENSE("GPL");
54#define MT_QUIRK_NO_AREA (1 << 9) 54#define MT_QUIRK_NO_AREA (1 << 9)
55#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) 55#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10)
56#define MT_QUIRK_HOVERING (1 << 11) 56#define MT_QUIRK_HOVERING (1 << 11)
57#define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12)
57 58
58struct mt_slot { 59struct mt_slot {
59 __s32 x, y, cx, cy, p, w, h; 60 __s32 x, y, cx, cy, p, w, h;
@@ -83,6 +84,7 @@ struct mt_device {
83 struct mt_class mtclass; /* our mt device class */ 84 struct mt_class mtclass; /* our mt device class */
84 struct mt_fields *fields; /* temporary placeholder for storing the 85 struct mt_fields *fields; /* temporary placeholder for storing the
85 multitouch fields */ 86 multitouch fields */
87 __s32 *contactcount; /* contact count value in the report */
86 unsigned last_field_index; /* last field index of the report */ 88 unsigned last_field_index; /* last field index of the report */
87 unsigned last_slot_field; /* the last field of a slot */ 89 unsigned last_slot_field; /* the last field of a slot */
88 unsigned mt_report_id; /* the report ID of the multitouch device */ 90 unsigned mt_report_id; /* the report ID of the multitouch device */
@@ -112,6 +114,7 @@ struct mt_device {
112#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007 114#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007
113#define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 115#define MT_CLS_DUAL_NSMU_CONTACTID 0x0008
114#define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 116#define MT_CLS_INRANGE_CONTACTNUMBER 0x0009
117#define MT_CLS_ALWAYS_TRUE 0x000a
115 118
116/* vendor specific classes */ 119/* vendor specific classes */
117#define MT_CLS_3M 0x0101 120#define MT_CLS_3M 0x0101
@@ -171,6 +174,9 @@ static struct mt_class mt_classes[] = {
171 { .name = MT_CLS_INRANGE_CONTACTNUMBER, 174 { .name = MT_CLS_INRANGE_CONTACTNUMBER,
172 .quirks = MT_QUIRK_VALID_IS_INRANGE | 175 .quirks = MT_QUIRK_VALID_IS_INRANGE |
173 MT_QUIRK_SLOT_IS_CONTACTNUMBER }, 176 MT_QUIRK_SLOT_IS_CONTACTNUMBER },
177 { .name = MT_CLS_ALWAYS_TRUE,
178 .quirks = MT_QUIRK_ALWAYS_VALID |
179 MT_QUIRK_CONTACT_CNT_ACCURATE },
174 180
175 /* 181 /*
176 * vendor specific classes 182 * vendor specific classes
@@ -251,6 +257,9 @@ static ssize_t mt_set_quirks(struct device *dev,
251 257
252 td->mtclass.quirks = val; 258 td->mtclass.quirks = val;
253 259
260 if (!td->contactcount)
261 td->mtclass.quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
262
254 return count; 263 return count;
255} 264}
256 265
@@ -461,6 +470,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
461 td->last_field_index = field->index; 470 td->last_field_index = field->index;
462 return 1; 471 return 1;
463 case HID_DG_CONTACTCOUNT: 472 case HID_DG_CONTACTCOUNT:
473 td->contactcount = field->value + usage->usage_index;
464 td->last_field_index = field->index; 474 td->last_field_index = field->index;
465 return 1; 475 return 1;
466 case HID_DG_CONTACTMAX: 476 case HID_DG_CONTACTMAX:
@@ -525,6 +535,10 @@ static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
525 */ 535 */
526static void mt_complete_slot(struct mt_device *td, struct input_dev *input) 536static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
527{ 537{
538 if ((td->mtclass.quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) &&
539 td->num_received >= td->num_expected)
540 return;
541
528 if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { 542 if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
529 int slotnum = mt_compute_slot(td, input); 543 int slotnum = mt_compute_slot(td, input);
530 struct mt_slot *s = &td->curdata; 544 struct mt_slot *s = &td->curdata;
@@ -635,12 +649,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
635 td->curdata.h = value; 649 td->curdata.h = value;
636 break; 650 break;
637 case HID_DG_CONTACTCOUNT: 651 case HID_DG_CONTACTCOUNT:
638 /*
639 * Includes multi-packet support where subsequent
640 * packets are sent with zero contactcount.
641 */
642 if (value)
643 td->num_expected = value;
644 break; 652 break;
645 case HID_DG_TOUCH: 653 case HID_DG_TOUCH:
646 /* do nothing */ 654 /* do nothing */
@@ -676,6 +684,13 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
676 if (!(hid->claimed & HID_CLAIMED_INPUT)) 684 if (!(hid->claimed & HID_CLAIMED_INPUT))
677 return; 685 return;
678 686
687 /*
688 * Includes multi-packet support where subsequent
689 * packets are sent with zero contactcount.
690 */
691 if (td->contactcount && *td->contactcount)
692 td->num_expected = *td->contactcount;
693
679 for (r = 0; r < report->maxfield; r++) { 694 for (r = 0; r < report->maxfield; r++) {
680 field = report->field[r]; 695 field = report->field[r];
681 count = field->report_count; 696 count = field->report_count;
@@ -750,11 +765,15 @@ static void mt_post_parse_default_settings(struct mt_device *td)
750static void mt_post_parse(struct mt_device *td) 765static void mt_post_parse(struct mt_device *td)
751{ 766{
752 struct mt_fields *f = td->fields; 767 struct mt_fields *f = td->fields;
768 struct mt_class *cls = &td->mtclass;
753 769
754 if (td->touches_by_report > 0) { 770 if (td->touches_by_report > 0) {
755 int field_count_per_touch = f->length / td->touches_by_report; 771 int field_count_per_touch = f->length / td->touches_by_report;
756 td->last_slot_field = f->usages[field_count_per_touch - 1]; 772 td->last_slot_field = f->usages[field_count_per_touch - 1];
757 } 773 }
774
775 if (!td->contactcount)
776 cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
758} 777}
759 778
760static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) 779static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
@@ -1087,6 +1106,11 @@ static const struct hid_device_id mt_devices[] = {
1087 MT_USB_DEVICE(USB_VENDOR_ID_TURBOX, 1106 MT_USB_DEVICE(USB_VENDOR_ID_TURBOX,
1088 USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, 1107 USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
1089 1108
1109 /* Nexio panels */
1110 { .driver_data = MT_CLS_ALWAYS_TRUE,
1111 MT_USB_DEVICE(USB_VENDOR_ID_NEXIO,
1112 USB_DEVICE_ID_NEXIO_MULTITOUCH_420)},
1113
1090 /* Panasonic panels */ 1114 /* Panasonic panels */
1091 { .driver_data = MT_CLS_PANASONIC, 1115 { .driver_data = MT_CLS_PANASONIC,
1092 MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, 1116 MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,