aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-core.c16
-rw-r--r--drivers/hid/hid-multitouch.c24
-rw-r--r--include/linux/hid.h4
3 files changed, 31 insertions, 13 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index ddd95f3e33c0..660dce964162 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -685,6 +685,13 @@ static void hid_scan_input_usage(struct hid_parser *parser, u32 usage)
685 hid->group = HID_GROUP_MULTITOUCH; 685 hid->group = HID_GROUP_MULTITOUCH;
686} 686}
687 687
688static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
689{
690 if (usage == 0xff0000c5 && parser->global.report_count == 256 &&
691 parser->global.report_size == 8)
692 parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8;
693}
694
688static void hid_scan_collection(struct hid_parser *parser, unsigned type) 695static void hid_scan_collection(struct hid_parser *parser, unsigned type)
689{ 696{
690 struct hid_device *hid = parser->device; 697 struct hid_device *hid = parser->device;
@@ -714,6 +721,8 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
714 case HID_MAIN_ITEM_TAG_OUTPUT: 721 case HID_MAIN_ITEM_TAG_OUTPUT:
715 break; 722 break;
716 case HID_MAIN_ITEM_TAG_FEATURE: 723 case HID_MAIN_ITEM_TAG_FEATURE:
724 for (i = 0; i < parser->local.usage_index; i++)
725 hid_scan_feature_usage(parser, parser->local.usage[i]);
717 break; 726 break;
718 } 727 }
719 728
@@ -757,6 +766,13 @@ static int hid_scan_report(struct hid_device *hid)
757 while ((start = fetch_item(start, end, &item)) != NULL) 766 while ((start = fetch_item(start, end, &item)) != NULL)
758 dispatch_type[item.type](parser, &item); 767 dispatch_type[item.type](parser, &item);
759 768
769 /*
770 * Handle special flags set during scanning.
771 */
772 if ((parser->scan_flags & HID_SCAN_FLAG_MT_WIN_8) &&
773 (hid->group == HID_GROUP_MULTITOUCH))
774 hid->group = HID_GROUP_MULTITOUCH_WIN_8;
775
760 vfree(parser); 776 vfree(parser);
761 return 0; 777 return 0;
762} 778}
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 0fe00e2552f2..c28ef86c7c67 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -133,6 +133,7 @@ static void mt_post_parse(struct mt_device *td);
133#define MT_CLS_NSMU 0x000a 133#define MT_CLS_NSMU 0x000a
134#define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 134#define MT_CLS_DUAL_CONTACT_NUMBER 0x0010
135#define MT_CLS_DUAL_CONTACT_ID 0x0011 135#define MT_CLS_DUAL_CONTACT_ID 0x0011
136#define MT_CLS_WIN_8 0x0012
136 137
137/* vendor specific classes */ 138/* vendor specific classes */
138#define MT_CLS_3M 0x0101 139#define MT_CLS_3M 0x0101
@@ -205,6 +206,11 @@ static struct mt_class mt_classes[] = {
205 MT_QUIRK_CONTACT_CNT_ACCURATE | 206 MT_QUIRK_CONTACT_CNT_ACCURATE |
206 MT_QUIRK_SLOT_IS_CONTACTID, 207 MT_QUIRK_SLOT_IS_CONTACTID,
207 .maxcontacts = 2 }, 208 .maxcontacts = 2 },
209 { .name = MT_CLS_WIN_8,
210 .quirks = MT_QUIRK_ALWAYS_VALID |
211 MT_QUIRK_IGNORE_DUPLICATES |
212 MT_QUIRK_HOVERING |
213 MT_QUIRK_CONTACT_CNT_ACCURATE },
208 214
209 /* 215 /*
210 * vendor specific classes 216 * vendor specific classes
@@ -332,19 +338,6 @@ static void mt_feature_mapping(struct hid_device *hdev,
332 td->maxcontacts = td->mtclass.maxcontacts; 338 td->maxcontacts = td->mtclass.maxcontacts;
333 339
334 break; 340 break;
335 case 0xff0000c5:
336 if (field->report_count == 256 && field->report_size == 8) {
337 /* Win 8 devices need special quirks */
338 __s32 *quirks = &td->mtclass.quirks;
339 *quirks |= MT_QUIRK_ALWAYS_VALID;
340 *quirks |= MT_QUIRK_IGNORE_DUPLICATES;
341 *quirks |= MT_QUIRK_HOVERING;
342 *quirks |= MT_QUIRK_CONTACT_CNT_ACCURATE;
343 *quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
344 *quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
345 *quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE;
346 }
347 break;
348 } 341 }
349} 342}
350 343
@@ -1346,6 +1339,11 @@ static const struct hid_device_id mt_devices[] = {
1346 1339
1347 /* Generic MT device */ 1340 /* Generic MT device */
1348 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, 1341 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
1342
1343 /* Generic Win 8 certified MT device */
1344 { .driver_data = MT_CLS_WIN_8,
1345 HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8,
1346 HID_ANY_ID, HID_ANY_ID) },
1349 { } 1347 { }
1350}; 1348};
1351MODULE_DEVICE_TABLE(hid, mt_devices); 1349MODULE_DEVICE_TABLE(hid, mt_devices);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 0c48991b0402..cef1e9b86cc4 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -295,6 +295,7 @@ struct hid_item {
295#define HID_GROUP_GENERIC 0x0001 295#define HID_GROUP_GENERIC 0x0001
296#define HID_GROUP_MULTITOUCH 0x0002 296#define HID_GROUP_MULTITOUCH 0x0002
297#define HID_GROUP_SENSOR_HUB 0x0003 297#define HID_GROUP_SENSOR_HUB 0x0003
298#define HID_GROUP_MULTITOUCH_WIN_8 0x0004
298 299
299/* 300/*
300 * This is the global environment of the parser. This information is 301 * This is the global environment of the parser. This information is
@@ -532,6 +533,8 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data)
532#define HID_GLOBAL_STACK_SIZE 4 533#define HID_GLOBAL_STACK_SIZE 4
533#define HID_COLLECTION_STACK_SIZE 4 534#define HID_COLLECTION_STACK_SIZE 4
534 535
536#define HID_SCAN_FLAG_MT_WIN_8 0x00000001
537
535struct hid_parser { 538struct hid_parser {
536 struct hid_global global; 539 struct hid_global global;
537 struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; 540 struct hid_global global_stack[HID_GLOBAL_STACK_SIZE];
@@ -540,6 +543,7 @@ struct hid_parser {
540 unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; 543 unsigned collection_stack[HID_COLLECTION_STACK_SIZE];
541 unsigned collection_stack_ptr; 544 unsigned collection_stack_ptr;
542 struct hid_device *device; 545 struct hid_device *device;
546 unsigned scan_flags;
543}; 547};
544 548
545struct hid_class_descriptor { 549struct hid_class_descriptor {