diff options
28 files changed, 1452 insertions, 553 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-wacom b/Documentation/ABI/testing/sysfs-driver-wacom index 0130d6683c14..56c54558c8a4 100644 --- a/Documentation/ABI/testing/sysfs-driver-wacom +++ b/Documentation/ABI/testing/sysfs-driver-wacom | |||
@@ -9,6 +9,14 @@ Description: | |||
9 | or 0 otherwise. Writing to this file one of these values | 9 | or 0 otherwise. Writing to this file one of these values |
10 | switches reporting speed. | 10 | switches reporting speed. |
11 | 11 | ||
12 | What: /sys/class/leds/0005\:056A\:00BD.0001\:selector\:*/ | ||
13 | Date: May 2012 | ||
14 | Kernel Version: 3.5 | ||
15 | Contact: linux-bluetooth@vger.kernel.org | ||
16 | Description: | ||
17 | LED selector for Intuos4 WL. There are 4 leds, but only one LED | ||
18 | can be lit at a time. Max brightness is 127. | ||
19 | |||
12 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/led | 20 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<cfg>.<intf>/wacom_led/led |
13 | Date: August 2011 | 21 | Date: August 2011 |
14 | Contact: linux-input@vger.kernel.org | 22 | Contact: linux-input@vger.kernel.org |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a6f6b50b67af..e9c68fedfcff 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -64,6 +64,18 @@ source "drivers/hid/usbhid/Kconfig" | |||
64 | menu "Special HID drivers" | 64 | menu "Special HID drivers" |
65 | depends on HID | 65 | depends on HID |
66 | 66 | ||
67 | config HID_GENERIC | ||
68 | tristate "Generic HID driver" | ||
69 | depends on HID | ||
70 | default y | ||
71 | ---help--- | ||
72 | Support for generic HID devices. | ||
73 | |||
74 | To compile this driver as a module, choose M here: the module | ||
75 | will be called hid-generic. | ||
76 | |||
77 | If unsure, say Y. | ||
78 | |||
67 | config HID_A4TECH | 79 | config HID_A4TECH |
68 | tristate "A4 tech mice" if EXPERT | 80 | tristate "A4 tech mice" if EXPERT |
69 | depends on USB_HID | 81 | depends on USB_HID |
@@ -96,6 +108,12 @@ config HID_APPLE | |||
96 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, | 108 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, |
97 | MacBooks, MacBook Pros and Apple Aluminum. | 109 | MacBooks, MacBook Pros and Apple Aluminum. |
98 | 110 | ||
111 | config HID_AUREAL | ||
112 | tristate "Aureal" | ||
113 | depends on USB_HID | ||
114 | ---help--- | ||
115 | Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes. | ||
116 | |||
99 | config HID_BELKIN | 117 | config HID_BELKIN |
100 | tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT | 118 | tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT |
101 | depends on USB_HID | 119 | depends on USB_HID |
@@ -599,16 +617,10 @@ config THRUSTMASTER_FF | |||
599 | config HID_WACOM | 617 | config HID_WACOM |
600 | tristate "Wacom Bluetooth devices support" | 618 | tristate "Wacom Bluetooth devices support" |
601 | depends on BT_HIDP | 619 | depends on BT_HIDP |
602 | ---help--- | 620 | depends on LEDS_CLASS |
603 | Support for Wacom Graphire Bluetooth tablet. | ||
604 | |||
605 | config HID_WACOM_POWER_SUPPLY | ||
606 | bool "Wacom Bluetooth devices power supply status support" | ||
607 | depends on HID_WACOM | ||
608 | select POWER_SUPPLY | 621 | select POWER_SUPPLY |
609 | ---help--- | 622 | ---help--- |
610 | Say Y here if you want to enable power supply status monitoring for | 623 | Support for Wacom Graphire Bluetooth and Intuos4 WL tablets. |
611 | Wacom Bluetooth devices. | ||
612 | 624 | ||
613 | config HID_WIIMOTE | 625 | config HID_WIIMOTE |
614 | tristate "Nintendo Wii Remote support" | 626 | tristate "Nintendo Wii Remote support" |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 22f1d16cd79c..ca6cc9f0485c 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -9,6 +9,8 @@ endif | |||
9 | 9 | ||
10 | obj-$(CONFIG_HID) += hid.o | 10 | obj-$(CONFIG_HID) += hid.o |
11 | 11 | ||
12 | obj-$(CONFIG_HID_GENERIC) += hid-generic.o | ||
13 | |||
12 | hid-$(CONFIG_HIDRAW) += hidraw.o | 14 | hid-$(CONFIG_HIDRAW) += hidraw.o |
13 | 15 | ||
14 | hid-logitech-y := hid-lg.o | 16 | hid-logitech-y := hid-lg.o |
@@ -36,6 +38,7 @@ endif | |||
36 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 38 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
37 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o | 39 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o |
38 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 40 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
41 | obj-$(CONFIG_HID_AUREAL) += hid-aureal.o | ||
39 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 42 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
40 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 43 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
41 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 44 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 9c6a4a328ac0..fa10f847f7db 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
@@ -234,7 +234,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, | |||
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | if (iso_layout) { | 237 | if (iso_layout) { |
238 | if (asc->quirks & APPLE_ISO_KEYBOARD) { | 238 | if (asc->quirks & APPLE_ISO_KEYBOARD) { |
239 | trans = apple_find_translation(apple_iso_keyboard, usage->code); | 239 | trans = apple_find_translation(apple_iso_keyboard, usage->code); |
240 | if (trans) { | 240 | if (trans) { |
diff --git a/drivers/hid/hid-aureal.c b/drivers/hid/hid-aureal.c new file mode 100644 index 000000000000..ba64b041b8bf --- /dev/null +++ b/drivers/hid/hid-aureal.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * HID driver for Aureal Cy se W-01RN USB_V3.1 devices | ||
3 | * | ||
4 | * Copyright (c) 2010 Franco Catrin <fcatrin@gmail.com> | ||
5 | * Copyright (c) 2010 Ben Cropley <bcropley@internode.on.net> | ||
6 | * | ||
7 | * Based on HID sunplus driver by | ||
8 | * Copyright (c) 1999 Andreas Gal | ||
9 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | ||
10 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
11 | * Copyright (c) 2006-2007 Jiri Kosina | ||
12 | * Copyright (c) 2007 Paul Walmsley | ||
13 | * Copyright (c) 2008 Jiri Slaby | ||
14 | */ | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/hid.h> | ||
17 | #include <linux/module.h> | ||
18 | |||
19 | #include "hid-ids.h" | ||
20 | |||
21 | static __u8 *aureal_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
22 | unsigned int *rsize) | ||
23 | { | ||
24 | if (*rsize >= 54 && rdesc[52] == 0x25 && rdesc[53] == 0x01) { | ||
25 | dev_info(&hdev->dev, "fixing Aureal Cy se W-01RN USB_V3.1 report descriptor.\n"); | ||
26 | rdesc[53] = 0x65; | ||
27 | } return rdesc; | ||
28 | } | ||
29 | |||
30 | static const struct hid_device_id aureal_devices[] = { | ||
31 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | ||
32 | { } | ||
33 | }; | ||
34 | MODULE_DEVICE_TABLE(hid, aureal_devices); | ||
35 | |||
36 | static struct hid_driver aureal_driver = { | ||
37 | .name = "aureal", | ||
38 | .id_table = aureal_devices, | ||
39 | .report_fixup = aureal_report_fixup, | ||
40 | }; | ||
41 | |||
42 | static int __init aureal_init(void) | ||
43 | { | ||
44 | return hid_register_driver(&aureal_driver); | ||
45 | } | ||
46 | |||
47 | static void __exit aureal_exit(void) | ||
48 | { | ||
49 | hid_unregister_driver(&aureal_driver); | ||
50 | } | ||
51 | |||
52 | module_init(aureal_init); | ||
53 | module_exit(aureal_exit); | ||
54 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 4da66b4b977c..8e3a6b261477 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -230,9 +230,16 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign | |||
230 | return -1; | 230 | return -1; |
231 | } | 231 | } |
232 | 232 | ||
233 | if (parser->global.logical_maximum < parser->global.logical_minimum) { | 233 | /* Handle both signed and unsigned cases properly */ |
234 | hid_err(parser->device, "logical range invalid %d %d\n", | 234 | if ((parser->global.logical_minimum < 0 && |
235 | parser->global.logical_minimum, parser->global.logical_maximum); | 235 | parser->global.logical_maximum < |
236 | parser->global.logical_minimum) || | ||
237 | (parser->global.logical_minimum >= 0 && | ||
238 | (__u32)parser->global.logical_maximum < | ||
239 | (__u32)parser->global.logical_minimum)) { | ||
240 | dbg_hid("logical range invalid 0x%x 0x%x\n", | ||
241 | parser->global.logical_minimum, | ||
242 | parser->global.logical_maximum); | ||
236 | return -1; | 243 | return -1; |
237 | } | 244 | } |
238 | 245 | ||
@@ -546,12 +553,11 @@ static void hid_free_report(struct hid_report *report) | |||
546 | } | 553 | } |
547 | 554 | ||
548 | /* | 555 | /* |
549 | * Free a device structure, all reports, and all fields. | 556 | * Close report. This function returns the device |
557 | * state to the point prior to hid_open_report(). | ||
550 | */ | 558 | */ |
551 | 559 | static void hid_close_report(struct hid_device *device) | |
552 | static void hid_device_release(struct device *dev) | ||
553 | { | 560 | { |
554 | struct hid_device *device = container_of(dev, struct hid_device, dev); | ||
555 | unsigned i, j; | 561 | unsigned i, j; |
556 | 562 | ||
557 | for (i = 0; i < HID_REPORT_TYPES; i++) { | 563 | for (i = 0; i < HID_REPORT_TYPES; i++) { |
@@ -562,11 +568,34 @@ static void hid_device_release(struct device *dev) | |||
562 | if (report) | 568 | if (report) |
563 | hid_free_report(report); | 569 | hid_free_report(report); |
564 | } | 570 | } |
571 | memset(report_enum, 0, sizeof(*report_enum)); | ||
572 | INIT_LIST_HEAD(&report_enum->report_list); | ||
565 | } | 573 | } |
566 | 574 | ||
567 | kfree(device->rdesc); | 575 | kfree(device->rdesc); |
576 | device->rdesc = NULL; | ||
577 | device->rsize = 0; | ||
578 | |||
568 | kfree(device->collection); | 579 | kfree(device->collection); |
569 | kfree(device); | 580 | device->collection = NULL; |
581 | device->collection_size = 0; | ||
582 | device->maxcollection = 0; | ||
583 | device->maxapplication = 0; | ||
584 | |||
585 | device->status &= ~HID_STAT_PARSED; | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Free a device structure, all reports, and all fields. | ||
590 | */ | ||
591 | |||
592 | static void hid_device_release(struct device *dev) | ||
593 | { | ||
594 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
595 | |||
596 | hid_close_report(hid); | ||
597 | kfree(hid->dev_rdesc); | ||
598 | kfree(hid); | ||
570 | } | 599 | } |
571 | 600 | ||
572 | /* | 601 | /* |
@@ -636,6 +665,60 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) | |||
636 | return NULL; | 665 | return NULL; |
637 | } | 666 | } |
638 | 667 | ||
668 | static void hid_scan_usage(struct hid_device *hid, u32 usage) | ||
669 | { | ||
670 | if (usage == HID_DG_CONTACTID) | ||
671 | hid->group = HID_GROUP_MULTITOUCH; | ||
672 | } | ||
673 | |||
674 | /* | ||
675 | * Scan a report descriptor before the device is added to the bus. | ||
676 | * Sets device groups and other properties that determine what driver | ||
677 | * to load. | ||
678 | */ | ||
679 | static int hid_scan_report(struct hid_device *hid) | ||
680 | { | ||
681 | unsigned int page = 0, delim = 0; | ||
682 | __u8 *start = hid->dev_rdesc; | ||
683 | __u8 *end = start + hid->dev_rsize; | ||
684 | unsigned int u, u_min = 0, u_max = 0; | ||
685 | struct hid_item item; | ||
686 | |||
687 | hid->group = HID_GROUP_GENERIC; | ||
688 | while ((start = fetch_item(start, end, &item)) != NULL) { | ||
689 | if (item.format != HID_ITEM_FORMAT_SHORT) | ||
690 | return -EINVAL; | ||
691 | if (item.type == HID_ITEM_TYPE_GLOBAL) { | ||
692 | if (item.tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE) | ||
693 | page = item_udata(&item) << 16; | ||
694 | } else if (item.type == HID_ITEM_TYPE_LOCAL) { | ||
695 | if (delim > 1) | ||
696 | break; | ||
697 | u = item_udata(&item); | ||
698 | if (item.size <= 2) | ||
699 | u += page; | ||
700 | switch (item.tag) { | ||
701 | case HID_LOCAL_ITEM_TAG_DELIMITER: | ||
702 | delim += !!u; | ||
703 | break; | ||
704 | case HID_LOCAL_ITEM_TAG_USAGE: | ||
705 | hid_scan_usage(hid, u); | ||
706 | break; | ||
707 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: | ||
708 | u_min = u; | ||
709 | break; | ||
710 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: | ||
711 | u_max = u; | ||
712 | for (u = u_min; u <= u_max; u++) | ||
713 | hid_scan_usage(hid, u); | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | |||
719 | return 0; | ||
720 | } | ||
721 | |||
639 | /** | 722 | /** |
640 | * hid_parse_report - parse device report | 723 | * hid_parse_report - parse device report |
641 | * | 724 | * |
@@ -643,15 +726,37 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) | |||
643 | * @start: report start | 726 | * @start: report start |
644 | * @size: report size | 727 | * @size: report size |
645 | * | 728 | * |
729 | * Allocate the device report as read by the bus driver. This function should | ||
730 | * only be called from parse() in ll drivers. | ||
731 | */ | ||
732 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size) | ||
733 | { | ||
734 | hid->dev_rdesc = kmemdup(start, size, GFP_KERNEL); | ||
735 | if (!hid->dev_rdesc) | ||
736 | return -ENOMEM; | ||
737 | hid->dev_rsize = size; | ||
738 | return 0; | ||
739 | } | ||
740 | EXPORT_SYMBOL_GPL(hid_parse_report); | ||
741 | |||
742 | /** | ||
743 | * hid_open_report - open a driver-specific device report | ||
744 | * | ||
745 | * @device: hid device | ||
746 | * | ||
646 | * Parse a report description into a hid_device structure. Reports are | 747 | * Parse a report description into a hid_device structure. Reports are |
647 | * enumerated, fields are attached to these reports. | 748 | * enumerated, fields are attached to these reports. |
648 | * 0 returned on success, otherwise nonzero error value. | 749 | * 0 returned on success, otherwise nonzero error value. |
750 | * | ||
751 | * This function (or the equivalent hid_parse() macro) should only be | ||
752 | * called from probe() in drivers, before starting the device. | ||
649 | */ | 753 | */ |
650 | int hid_parse_report(struct hid_device *device, __u8 *start, | 754 | int hid_open_report(struct hid_device *device) |
651 | unsigned size) | ||
652 | { | 755 | { |
653 | struct hid_parser *parser; | 756 | struct hid_parser *parser; |
654 | struct hid_item item; | 757 | struct hid_item item; |
758 | unsigned int size; | ||
759 | __u8 *start; | ||
655 | __u8 *end; | 760 | __u8 *end; |
656 | int ret; | 761 | int ret; |
657 | static int (*dispatch_type[])(struct hid_parser *parser, | 762 | static int (*dispatch_type[])(struct hid_parser *parser, |
@@ -662,6 +767,14 @@ int hid_parse_report(struct hid_device *device, __u8 *start, | |||
662 | hid_parser_reserved | 767 | hid_parser_reserved |
663 | }; | 768 | }; |
664 | 769 | ||
770 | if (WARN_ON(device->status & HID_STAT_PARSED)) | ||
771 | return -EBUSY; | ||
772 | |||
773 | start = device->dev_rdesc; | ||
774 | if (WARN_ON(!start)) | ||
775 | return -ENODEV; | ||
776 | size = device->dev_rsize; | ||
777 | |||
665 | if (device->driver->report_fixup) | 778 | if (device->driver->report_fixup) |
666 | start = device->driver->report_fixup(device, start, &size); | 779 | start = device->driver->report_fixup(device, start, &size); |
667 | 780 | ||
@@ -679,6 +792,15 @@ int hid_parse_report(struct hid_device *device, __u8 *start, | |||
679 | parser->device = device; | 792 | parser->device = device; |
680 | 793 | ||
681 | end = start + size; | 794 | end = start + size; |
795 | |||
796 | device->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, | ||
797 | sizeof(struct hid_collection), GFP_KERNEL); | ||
798 | if (!device->collection) { | ||
799 | ret = -ENOMEM; | ||
800 | goto err; | ||
801 | } | ||
802 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | ||
803 | |||
682 | ret = -EINVAL; | 804 | ret = -EINVAL; |
683 | while ((start = fetch_item(start, end, &item)) != NULL) { | 805 | while ((start = fetch_item(start, end, &item)) != NULL) { |
684 | 806 | ||
@@ -704,6 +826,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start, | |||
704 | goto err; | 826 | goto err; |
705 | } | 827 | } |
706 | vfree(parser); | 828 | vfree(parser); |
829 | device->status |= HID_STAT_PARSED; | ||
707 | return 0; | 830 | return 0; |
708 | } | 831 | } |
709 | } | 832 | } |
@@ -711,9 +834,10 @@ int hid_parse_report(struct hid_device *device, __u8 *start, | |||
711 | hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); | 834 | hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); |
712 | err: | 835 | err: |
713 | vfree(parser); | 836 | vfree(parser); |
837 | hid_close_report(device); | ||
714 | return ret; | 838 | return ret; |
715 | } | 839 | } |
716 | EXPORT_SYMBOL_GPL(hid_parse_report); | 840 | EXPORT_SYMBOL_GPL(hid_open_report); |
717 | 841 | ||
718 | /* | 842 | /* |
719 | * Convert a signed n-bit integer to signed 32-bit integer. Common | 843 | * Convert a signed n-bit integer to signed 32-bit integer. Common |
@@ -1032,7 +1156,7 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, | |||
1032 | return report; | 1156 | return report; |
1033 | } | 1157 | } |
1034 | 1158 | ||
1035 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 1159 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
1036 | int interrupt) | 1160 | int interrupt) |
1037 | { | 1161 | { |
1038 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1162 | struct hid_report_enum *report_enum = hid->report_enum + type; |
@@ -1040,10 +1164,11 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | |||
1040 | unsigned int a; | 1164 | unsigned int a; |
1041 | int rsize, csize = size; | 1165 | int rsize, csize = size; |
1042 | u8 *cdata = data; | 1166 | u8 *cdata = data; |
1167 | int ret = 0; | ||
1043 | 1168 | ||
1044 | report = hid_get_report(report_enum, data); | 1169 | report = hid_get_report(report_enum, data); |
1045 | if (!report) | 1170 | if (!report) |
1046 | return; | 1171 | goto out; |
1047 | 1172 | ||
1048 | if (report_enum->numbered) { | 1173 | if (report_enum->numbered) { |
1049 | cdata++; | 1174 | cdata++; |
@@ -1063,14 +1188,19 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | |||
1063 | 1188 | ||
1064 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) | 1189 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) |
1065 | hid->hiddev_report_event(hid, report); | 1190 | hid->hiddev_report_event(hid, report); |
1066 | if (hid->claimed & HID_CLAIMED_HIDRAW) | 1191 | if (hid->claimed & HID_CLAIMED_HIDRAW) { |
1067 | hidraw_report_event(hid, data, size); | 1192 | ret = hidraw_report_event(hid, data, size); |
1193 | if (ret) | ||
1194 | goto out; | ||
1195 | } | ||
1068 | 1196 | ||
1069 | for (a = 0; a < report->maxfield; a++) | 1197 | for (a = 0; a < report->maxfield; a++) |
1070 | hid_input_field(hid, report->field[a], cdata, interrupt); | 1198 | hid_input_field(hid, report->field[a], cdata, interrupt); |
1071 | 1199 | ||
1072 | if (hid->claimed & HID_CLAIMED_INPUT) | 1200 | if (hid->claimed & HID_CLAIMED_INPUT) |
1073 | hidinput_report_event(hid, report); | 1201 | hidinput_report_event(hid, report); |
1202 | out: | ||
1203 | return ret; | ||
1074 | } | 1204 | } |
1075 | EXPORT_SYMBOL_GPL(hid_report_raw_event); | 1205 | EXPORT_SYMBOL_GPL(hid_report_raw_event); |
1076 | 1206 | ||
@@ -1147,7 +1277,7 @@ nomem: | |||
1147 | } | 1277 | } |
1148 | } | 1278 | } |
1149 | 1279 | ||
1150 | hid_report_raw_event(hid, type, data, size, interrupt); | 1280 | ret = hid_report_raw_event(hid, type, data, size, interrupt); |
1151 | 1281 | ||
1152 | unlock: | 1282 | unlock: |
1153 | up(&hid->driver_lock); | 1283 | up(&hid->driver_lock); |
@@ -1158,7 +1288,8 @@ EXPORT_SYMBOL_GPL(hid_input_report); | |||
1158 | static bool hid_match_one_id(struct hid_device *hdev, | 1288 | static bool hid_match_one_id(struct hid_device *hdev, |
1159 | const struct hid_device_id *id) | 1289 | const struct hid_device_id *id) |
1160 | { | 1290 | { |
1161 | return id->bus == hdev->bus && | 1291 | return (id->bus == HID_BUS_ANY || id->bus == hdev->bus) && |
1292 | (id->group == HID_GROUP_ANY || id->group == hdev->group) && | ||
1162 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && | 1293 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && |
1163 | (id->product == HID_ANY_ID || id->product == hdev->product); | 1294 | (id->product == HID_ANY_ID || id->product == hdev->product); |
1164 | } | 1295 | } |
@@ -1234,10 +1365,6 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) | |||
1234 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, | 1365 | if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, |
1235 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) | 1366 | connect_mask & HID_CONNECT_HIDINPUT_FORCE)) |
1236 | hdev->claimed |= HID_CLAIMED_INPUT; | 1367 | hdev->claimed |= HID_CLAIMED_INPUT; |
1237 | if (hdev->quirks & HID_QUIRK_MULTITOUCH) { | ||
1238 | /* this device should be handled by hid-multitouch, skip it */ | ||
1239 | return -ENODEV; | ||
1240 | } | ||
1241 | 1368 | ||
1242 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && | 1369 | if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect && |
1243 | !hdev->hiddev_connect(hdev, | 1370 | !hdev->hiddev_connect(hdev, |
@@ -1314,13 +1441,10 @@ EXPORT_SYMBOL_GPL(hid_disconnect); | |||
1314 | 1441 | ||
1315 | /* a list of devices for which there is a specialized driver on HID bus */ | 1442 | /* a list of devices for which there is a specialized driver on HID bus */ |
1316 | static const struct hid_device_id hid_have_special_driver[] = { | 1443 | static const struct hid_device_id hid_have_special_driver[] = { |
1317 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, | ||
1318 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, | ||
1319 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | 1444 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, |
1320 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | 1445 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, |
1321 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, | 1446 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, |
1322 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, | 1447 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, |
1323 | { HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, USB_DEVICE_ID_ACTIONSTAR_1011) }, | ||
1324 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, | 1448 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, |
1325 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | 1449 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, |
1326 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1450 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
@@ -1385,60 +1509,33 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1385 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, | 1509 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, |
1386 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1510 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1387 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1511 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1388 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | 1512 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
1389 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
1390 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1513 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1391 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1514 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
1392 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | 1515 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, |
1393 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, | ||
1394 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | ||
1395 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | ||
1396 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | ||
1397 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | ||
1398 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1516 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
1399 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, | 1517 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, |
1400 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 1518 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
1401 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, | 1519 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, |
1402 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, | 1520 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, |
1403 | { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | ||
1404 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, | 1521 | { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, |
1405 | { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, | ||
1406 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, | 1522 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, |
1407 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, | 1523 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, |
1408 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, | 1524 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, |
1409 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1525 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1410 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, | ||
1411 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1526 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1412 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, | 1527 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, |
1413 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, | ||
1414 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, | ||
1415 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, | ||
1416 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | ||
1417 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, | ||
1418 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | ||
1419 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, | ||
1420 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, | ||
1421 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, | ||
1422 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1528 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1423 | { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) }, | ||
1424 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, | 1529 | { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, |
1425 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1530 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1426 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_FRUCTEL, USB_DEVICE_ID_GAMETEL_MT_MODE) }, | ||
1427 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1531 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1428 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1532 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
1429 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | ||
1430 | { HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, USB_DEVICE_ID_GOODTOUCH_000f) }, | ||
1431 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, | 1533 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, |
1432 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, | 1534 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, |
1433 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1535 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
1434 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1536 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
1435 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1537 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
1436 | { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, | ||
1437 | { HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, | ||
1438 | { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) }, | ||
1439 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, | 1538 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, |
1440 | { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, | ||
1441 | { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, | ||
1442 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1539 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
1443 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, | 1540 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, |
1444 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1541 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
@@ -1447,7 +1544,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1447 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | 1544 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
1448 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1545 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1449 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, | 1546 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, |
1450 | { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) }, | ||
1451 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1547 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, |
1452 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, | 1548 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, |
1453 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, | 1549 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, |
@@ -1480,8 +1576,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1480 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, | 1576 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, |
1481 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, | 1577 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, |
1482 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, | 1578 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, |
1483 | { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) }, | ||
1484 | { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, | ||
1485 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, | 1579 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, |
1486 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, | 1580 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, |
1487 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, | 1581 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, |
@@ -1513,15 +1607,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1513 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, | 1607 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, |
1514 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, | 1608 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, |
1515 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1609 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1516 | { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT780) }, | ||
1517 | { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) }, | ||
1518 | { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, | ||
1519 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1610 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1520 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, | ||
1521 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) }, | ||
1522 | { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) }, | ||
1523 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, | 1611 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, |
1524 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, | ||
1525 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, | 1612 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, |
1526 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, | 1613 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, |
1527 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, | 1614 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, |
@@ -1538,9 +1625,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1538 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, | 1625 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, |
1539 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1626 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1540 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1627 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
1541 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, | ||
1542 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, | ||
1543 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, | ||
1544 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1628 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
1545 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1629 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
1546 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1630 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
@@ -1554,16 +1638,13 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1554 | { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, | 1638 | { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, |
1555 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 1639 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
1556 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, | 1640 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
1557 | { HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, | ||
1558 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, | 1641 | { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, |
1559 | { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | ||
1560 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, | 1642 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, |
1561 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, | 1643 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, |
1562 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, | 1644 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, |
1563 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, | 1645 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, |
1564 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, | 1646 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, |
1565 | { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, | 1647 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) }, |
1566 | { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | ||
1567 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, | 1648 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, |
1568 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) }, | 1649 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) }, |
1569 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, | 1650 | { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) }, |
@@ -1578,16 +1659,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1578 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_PID_0038) }, | 1659 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_PID_0038) }, |
1579 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, | 1660 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, |
1580 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, | 1661 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, |
1581 | { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) }, | 1662 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) }, |
1582 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX) }, | ||
1583 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX) }, | ||
1584 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR) }, | ||
1585 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX1) }, | ||
1586 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX1) }, | ||
1587 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR1) }, | ||
1588 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX2) }, | ||
1589 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX2) }, | ||
1590 | { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) }, | ||
1591 | { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, | 1663 | { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, |
1592 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, | 1664 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, |
1593 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, | 1665 | { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, |
@@ -1631,6 +1703,7 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf, | |||
1631 | return -ENOMEM; | 1703 | return -ENOMEM; |
1632 | 1704 | ||
1633 | dynid->id.bus = bus; | 1705 | dynid->id.bus = bus; |
1706 | dynid->id.group = HID_GROUP_ANY; | ||
1634 | dynid->id.vendor = vendor; | 1707 | dynid->id.vendor = vendor; |
1635 | dynid->id.product = product; | 1708 | dynid->id.product = product; |
1636 | dynid->id.driver_data = driver_data; | 1709 | dynid->id.driver_data = driver_data; |
@@ -1679,18 +1752,7 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv) | |||
1679 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | 1752 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); |
1680 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1753 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
1681 | 1754 | ||
1682 | if ((hdev->quirks & HID_QUIRK_MULTITOUCH) && | 1755 | return hid_match_device(hdev, hdrv) != NULL; |
1683 | !strncmp(hdrv->name, "hid-multitouch", 14)) | ||
1684 | return 1; | ||
1685 | |||
1686 | if (!hid_match_device(hdev, hdrv)) | ||
1687 | return 0; | ||
1688 | |||
1689 | /* generic wants all that don't have specialized driver */ | ||
1690 | if (!strncmp(hdrv->name, "generic-", 8) && !hid_ignore_special_drivers) | ||
1691 | return !hid_match_id(hdev, hid_have_special_driver); | ||
1692 | |||
1693 | return 1; | ||
1694 | } | 1756 | } |
1695 | 1757 | ||
1696 | static int hid_device_probe(struct device *dev) | 1758 | static int hid_device_probe(struct device *dev) |
@@ -1707,23 +1769,22 @@ static int hid_device_probe(struct device *dev) | |||
1707 | if (!hdev->driver) { | 1769 | if (!hdev->driver) { |
1708 | id = hid_match_device(hdev, hdrv); | 1770 | id = hid_match_device(hdev, hdrv); |
1709 | if (id == NULL) { | 1771 | if (id == NULL) { |
1710 | if (!((hdev->quirks & HID_QUIRK_MULTITOUCH) && | 1772 | ret = -ENODEV; |
1711 | !strncmp(hdrv->name, "hid-multitouch", 14))) { | 1773 | goto unlock; |
1712 | ret = -ENODEV; | ||
1713 | goto unlock; | ||
1714 | } | ||
1715 | } | 1774 | } |
1716 | 1775 | ||
1717 | hdev->driver = hdrv; | 1776 | hdev->driver = hdrv; |
1718 | if (hdrv->probe) { | 1777 | if (hdrv->probe) { |
1719 | ret = hdrv->probe(hdev, id); | 1778 | ret = hdrv->probe(hdev, id); |
1720 | } else { /* default probe */ | 1779 | } else { /* default probe */ |
1721 | ret = hid_parse(hdev); | 1780 | ret = hid_open_report(hdev); |
1722 | if (!ret) | 1781 | if (!ret) |
1723 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 1782 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
1724 | } | 1783 | } |
1725 | if (ret) | 1784 | if (ret) { |
1785 | hid_close_report(hdev); | ||
1726 | hdev->driver = NULL; | 1786 | hdev->driver = NULL; |
1787 | } | ||
1727 | } | 1788 | } |
1728 | unlock: | 1789 | unlock: |
1729 | up(&hdev->driver_lock); | 1790 | up(&hdev->driver_lock); |
@@ -1744,6 +1805,7 @@ static int hid_device_remove(struct device *dev) | |||
1744 | hdrv->remove(hdev); | 1805 | hdrv->remove(hdev); |
1745 | else /* default remove */ | 1806 | else /* default remove */ |
1746 | hid_hw_stop(hdev); | 1807 | hid_hw_stop(hdev); |
1808 | hid_close_report(hdev); | ||
1747 | hdev->driver = NULL; | 1809 | hdev->driver = NULL; |
1748 | } | 1810 | } |
1749 | 1811 | ||
@@ -1751,6 +1813,23 @@ static int hid_device_remove(struct device *dev) | |||
1751 | return 0; | 1813 | return 0; |
1752 | } | 1814 | } |
1753 | 1815 | ||
1816 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | ||
1817 | char *buf) | ||
1818 | { | ||
1819 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1820 | int len; | ||
1821 | |||
1822 | len = snprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n", | ||
1823 | hdev->bus, hdev->group, hdev->vendor, hdev->product); | ||
1824 | |||
1825 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | ||
1826 | } | ||
1827 | |||
1828 | static struct device_attribute hid_dev_attrs[] = { | ||
1829 | __ATTR_RO(modalias), | ||
1830 | __ATTR_NULL, | ||
1831 | }; | ||
1832 | |||
1754 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | 1833 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) |
1755 | { | 1834 | { |
1756 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1835 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
@@ -1768,8 +1847,8 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
1768 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) | 1847 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) |
1769 | return -ENOMEM; | 1848 | return -ENOMEM; |
1770 | 1849 | ||
1771 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", | 1850 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xg%04Xv%08Xp%08X", |
1772 | hdev->bus, hdev->vendor, hdev->product)) | 1851 | hdev->bus, hdev->group, hdev->vendor, hdev->product)) |
1773 | return -ENOMEM; | 1852 | return -ENOMEM; |
1774 | 1853 | ||
1775 | return 0; | 1854 | return 0; |
@@ -1777,6 +1856,7 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
1777 | 1856 | ||
1778 | static struct bus_type hid_bus_type = { | 1857 | static struct bus_type hid_bus_type = { |
1779 | .name = "hid", | 1858 | .name = "hid", |
1859 | .dev_attrs = hid_dev_attrs, | ||
1780 | .match = hid_bus_match, | 1860 | .match = hid_bus_match, |
1781 | .probe = hid_device_probe, | 1861 | .probe = hid_device_probe, |
1782 | .remove = hid_device_remove, | 1862 | .remove = hid_device_remove, |
@@ -2075,6 +2155,26 @@ int hid_add_device(struct hid_device *hdev) | |||
2075 | && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE))) | 2155 | && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE))) |
2076 | return -ENODEV; | 2156 | return -ENODEV; |
2077 | 2157 | ||
2158 | /* | ||
2159 | * Read the device report descriptor once and use as template | ||
2160 | * for the driver-specific modifications. | ||
2161 | */ | ||
2162 | ret = hdev->ll_driver->parse(hdev); | ||
2163 | if (ret) | ||
2164 | return ret; | ||
2165 | if (!hdev->dev_rdesc) | ||
2166 | return -ENODEV; | ||
2167 | |||
2168 | /* | ||
2169 | * Scan generic devices for group information | ||
2170 | */ | ||
2171 | if (hid_ignore_special_drivers || | ||
2172 | !hid_match_id(hdev, hid_have_special_driver)) { | ||
2173 | ret = hid_scan_report(hdev); | ||
2174 | if (ret) | ||
2175 | hid_warn(hdev, "bad device descriptor (%d)\n", ret); | ||
2176 | } | ||
2177 | |||
2078 | /* XXX hack, any other cleaner solution after the driver core | 2178 | /* XXX hack, any other cleaner solution after the driver core |
2079 | * is converted to allow more than 20 bytes as the device name? */ | 2179 | * is converted to allow more than 20 bytes as the device name? */ |
2080 | dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, | 2180 | dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, |
@@ -2103,7 +2203,6 @@ EXPORT_SYMBOL_GPL(hid_add_device); | |||
2103 | struct hid_device *hid_allocate_device(void) | 2203 | struct hid_device *hid_allocate_device(void) |
2104 | { | 2204 | { |
2105 | struct hid_device *hdev; | 2205 | struct hid_device *hdev; |
2106 | unsigned int i; | ||
2107 | int ret = -ENOMEM; | 2206 | int ret = -ENOMEM; |
2108 | 2207 | ||
2109 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); | 2208 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); |
@@ -2114,23 +2213,13 @@ struct hid_device *hid_allocate_device(void) | |||
2114 | hdev->dev.release = hid_device_release; | 2213 | hdev->dev.release = hid_device_release; |
2115 | hdev->dev.bus = &hid_bus_type; | 2214 | hdev->dev.bus = &hid_bus_type; |
2116 | 2215 | ||
2117 | hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, | 2216 | hid_close_report(hdev); |
2118 | sizeof(struct hid_collection), GFP_KERNEL); | ||
2119 | if (hdev->collection == NULL) | ||
2120 | goto err; | ||
2121 | hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | ||
2122 | |||
2123 | for (i = 0; i < HID_REPORT_TYPES; i++) | ||
2124 | INIT_LIST_HEAD(&hdev->report_enum[i].report_list); | ||
2125 | 2217 | ||
2126 | init_waitqueue_head(&hdev->debug_wait); | 2218 | init_waitqueue_head(&hdev->debug_wait); |
2127 | INIT_LIST_HEAD(&hdev->debug_list); | 2219 | INIT_LIST_HEAD(&hdev->debug_list); |
2128 | sema_init(&hdev->driver_lock, 1); | 2220 | sema_init(&hdev->driver_lock, 1); |
2129 | 2221 | ||
2130 | return hdev; | 2222 | return hdev; |
2131 | err: | ||
2132 | put_device(&hdev->dev); | ||
2133 | return ERR_PTR(ret); | ||
2134 | } | 2223 | } |
2135 | EXPORT_SYMBOL_GPL(hid_allocate_device); | 2224 | EXPORT_SYMBOL_GPL(hid_allocate_device); |
2136 | 2225 | ||
@@ -2141,6 +2230,9 @@ static void hid_remove_device(struct hid_device *hdev) | |||
2141 | hid_debug_unregister(hdev); | 2230 | hid_debug_unregister(hdev); |
2142 | hdev->status &= ~HID_STAT_ADDED; | 2231 | hdev->status &= ~HID_STAT_ADDED; |
2143 | } | 2232 | } |
2233 | kfree(hdev->dev_rdesc); | ||
2234 | hdev->dev_rdesc = NULL; | ||
2235 | hdev->dev_rsize = 0; | ||
2144 | } | 2236 | } |
2145 | 2237 | ||
2146 | /** | 2238 | /** |
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c new file mode 100644 index 000000000000..a8b3148e03a2 --- /dev/null +++ b/drivers/hid/hid-generic.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * HID support for Linux | ||
3 | * | ||
4 | * Copyright (c) 1999 Andreas Gal | ||
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | ||
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
7 | * Copyright (c) 2007-2008 Oliver Neukum | ||
8 | * Copyright (c) 2006-2012 Jiri Kosina | ||
9 | * Copyright (c) 2012 Henrik Rydberg | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the Free | ||
15 | * Software Foundation; either version 2 of the License, or (at your option) | ||
16 | * any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <asm/unaligned.h> | ||
23 | #include <asm/byteorder.h> | ||
24 | |||
25 | #include <linux/hid.h> | ||
26 | |||
27 | static const struct hid_device_id hid_table[] = { | ||
28 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_GENERIC, HID_ANY_ID, HID_ANY_ID) }, | ||
29 | { } | ||
30 | }; | ||
31 | MODULE_DEVICE_TABLE(hid, hid_table); | ||
32 | |||
33 | static struct hid_driver hid_generic = { | ||
34 | .name = "hid-generic", | ||
35 | .id_table = hid_table, | ||
36 | }; | ||
37 | |||
38 | static int __init hid_init(void) | ||
39 | { | ||
40 | return hid_register_driver(&hid_generic); | ||
41 | } | ||
42 | |||
43 | static void __exit hid_exit(void) | ||
44 | { | ||
45 | hid_unregister_driver(&hid_generic); | ||
46 | } | ||
47 | |||
48 | module_init(hid_init); | ||
49 | module_exit(hid_exit); | ||
50 | |||
51 | MODULE_AUTHOR("Henrik Rydberg"); | ||
52 | MODULE_DESCRIPTION("HID generic driver"); | ||
53 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 406632472c1b..3d62781b8993 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c | |||
@@ -430,6 +430,15 @@ cleanup: | |||
430 | return ret; | 430 | return ret; |
431 | } | 431 | } |
432 | 432 | ||
433 | static int mousevsc_hid_parse(struct hid_device *hid) | ||
434 | { | ||
435 | struct hv_device *dev = hid_get_drvdata(hid); | ||
436 | struct mousevsc_dev *input_dev = hv_get_drvdata(dev); | ||
437 | |||
438 | return hid_parse_report(hid, input_dev->report_desc, | ||
439 | input_dev->report_desc_size); | ||
440 | } | ||
441 | |||
433 | static int mousevsc_hid_open(struct hid_device *hid) | 442 | static int mousevsc_hid_open(struct hid_device *hid) |
434 | { | 443 | { |
435 | return 0; | 444 | return 0; |
@@ -449,6 +458,7 @@ static void mousevsc_hid_stop(struct hid_device *hid) | |||
449 | } | 458 | } |
450 | 459 | ||
451 | static struct hid_ll_driver mousevsc_ll_driver = { | 460 | static struct hid_ll_driver mousevsc_ll_driver = { |
461 | .parse = mousevsc_hid_parse, | ||
452 | .open = mousevsc_hid_open, | 462 | .open = mousevsc_hid_open, |
453 | .close = mousevsc_hid_close, | 463 | .close = mousevsc_hid_close, |
454 | .start = mousevsc_hid_start, | 464 | .start = mousevsc_hid_start, |
@@ -506,13 +516,14 @@ static int mousevsc_probe(struct hv_device *device, | |||
506 | 516 | ||
507 | sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse"); | 517 | sprintf(hid_dev->name, "%s", "Microsoft Vmbus HID-compliant Mouse"); |
508 | 518 | ||
519 | hid_set_drvdata(hid_dev, device); | ||
520 | |||
509 | ret = hid_add_device(hid_dev); | 521 | ret = hid_add_device(hid_dev); |
510 | if (ret) | 522 | if (ret) |
511 | goto probe_err1; | 523 | goto probe_err1; |
512 | 524 | ||
513 | ret = hid_parse_report(hid_dev, input_dev->report_desc, | ||
514 | input_dev->report_desc_size); | ||
515 | 525 | ||
526 | ret = hid_parse(hid_dev); | ||
516 | if (ret) { | 527 | if (ret) { |
517 | hid_err(hid_dev, "parse failed\n"); | 528 | hid_err(hid_dev, "parse failed\n"); |
518 | goto probe_err2; | 529 | goto probe_err2; |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e39aecb1f9f2..9373f535dfe9 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -154,9 +154,15 @@ | |||
154 | #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c | 154 | #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c |
155 | #define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 | 155 | #define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 |
156 | 156 | ||
157 | #define USB_VENDOR_ID_AUREAL 0x0755 | ||
158 | #define USB_DEVICE_ID_AUREAL_W01RN 0x2626 | ||
159 | |||
157 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca | 160 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca |
158 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 | 161 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 |
159 | 162 | ||
163 | #define USB_VENDOR_ID_BAANTO 0x2453 | ||
164 | #define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100 | ||
165 | |||
160 | #define USB_VENDOR_ID_BELKIN 0x050d | 166 | #define USB_VENDOR_ID_BELKIN 0x050d |
161 | #define USB_DEVICE_ID_FLIP_KVM 0x3201 | 167 | #define USB_DEVICE_ID_FLIP_KVM 0x3201 |
162 | 168 | ||
@@ -726,6 +732,7 @@ | |||
726 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 | 732 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 |
727 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 | 733 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 |
728 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064 | 734 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064 |
735 | #define USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850 0x0522 | ||
729 | 736 | ||
730 | #define USB_VENDOR_ID_UNITEC 0x227d | 737 | #define USB_VENDOR_ID_UNITEC 0x227d |
731 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 | 738 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 |
@@ -749,6 +756,7 @@ | |||
749 | #define USB_DEVICE_ID_WALTOP_PID_0038 0x0038 | 756 | #define USB_DEVICE_ID_WALTOP_PID_0038 0x0038 |
750 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501 | 757 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501 |
751 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 | 758 | #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 |
759 | #define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502 | ||
752 | 760 | ||
753 | #define USB_VENDOR_ID_WISEGROUP 0x0925 | 761 | #define USB_VENDOR_ID_WISEGROUP 0x0925 |
754 | #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 | 762 | #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 002781c5a616..132b0019365e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -225,7 +225,10 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
225 | * Verify and convert units. | 225 | * Verify and convert units. |
226 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding | 226 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding |
227 | */ | 227 | */ |
228 | if (code == ABS_X || code == ABS_Y || code == ABS_Z) { | 228 | switch (code) { |
229 | case ABS_X: | ||
230 | case ABS_Y: | ||
231 | case ABS_Z: | ||
229 | if (field->unit == 0x11) { /* If centimeters */ | 232 | if (field->unit == 0x11) { /* If centimeters */ |
230 | /* Convert to millimeters */ | 233 | /* Convert to millimeters */ |
231 | unit_exponent += 1; | 234 | unit_exponent += 1; |
@@ -239,7 +242,13 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
239 | } else { | 242 | } else { |
240 | return 0; | 243 | return 0; |
241 | } | 244 | } |
242 | } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { | 245 | break; |
246 | |||
247 | case ABS_RX: | ||
248 | case ABS_RY: | ||
249 | case ABS_RZ: | ||
250 | case ABS_TILT_X: | ||
251 | case ABS_TILT_Y: | ||
243 | if (field->unit == 0x14) { /* If degrees */ | 252 | if (field->unit == 0x14) { /* If degrees */ |
244 | /* Convert to radians */ | 253 | /* Convert to radians */ |
245 | prev = logical_extents; | 254 | prev = logical_extents; |
@@ -250,7 +259,9 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | |||
250 | } else if (field->unit != 0x12) { /* If not radians */ | 259 | } else if (field->unit != 0x12) { /* If not radians */ |
251 | return 0; | 260 | return 0; |
252 | } | 261 | } |
253 | } else { | 262 | break; |
263 | |||
264 | default: | ||
254 | return 0; | 265 | return 0; |
255 | } | 266 | } |
256 | 267 | ||
@@ -623,6 +634,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
623 | map_key_clear(BTN_TOOL_RUBBER); | 634 | map_key_clear(BTN_TOOL_RUBBER); |
624 | break; | 635 | break; |
625 | 636 | ||
637 | case 0x3d: /* X Tilt */ | ||
638 | map_abs_clear(ABS_TILT_X); | ||
639 | break; | ||
640 | |||
641 | case 0x3e: /* Y Tilt */ | ||
642 | map_abs_clear(ABS_TILT_Y); | ||
643 | break; | ||
644 | |||
626 | case 0x33: /* Touch */ | 645 | case 0x33: /* Touch */ |
627 | case 0x42: /* TipSwitch */ | 646 | case 0x42: /* TipSwitch */ |
628 | case 0x43: /* TipSwitch2 */ | 647 | case 0x43: /* TipSwitch2 */ |
@@ -638,10 +657,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
638 | map_key_clear(BTN_STYLUS2); | 657 | map_key_clear(BTN_STYLUS2); |
639 | break; | 658 | break; |
640 | 659 | ||
641 | case 0x51: /* ContactID */ | ||
642 | device->quirks |= HID_QUIRK_MULTITOUCH; | ||
643 | goto unknown; | ||
644 | |||
645 | default: goto unknown; | 660 | default: goto unknown; |
646 | } | 661 | } |
647 | break; | 662 | break; |
@@ -1208,13 +1223,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
1208 | } | 1223 | } |
1209 | } | 1224 | } |
1210 | 1225 | ||
1211 | if (hid->quirks & HID_QUIRK_MULTITOUCH) { | ||
1212 | /* generic hid does not know how to handle multitouch devices */ | ||
1213 | if (hidinput) | ||
1214 | goto out_cleanup; | ||
1215 | goto out_unwind; | ||
1216 | } | ||
1217 | |||
1218 | if (hidinput && input_register_device(hidinput->input)) | 1226 | if (hidinput && input_register_device(hidinput->input)) |
1219 | goto out_cleanup; | 1227 | goto out_cleanup; |
1220 | 1228 | ||
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index e7a7bd1eb34a..fc37ed6b108c 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -109,23 +109,23 @@ static __u8 dfp_rdesc_fixed[] = { | |||
109 | static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 109 | static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
110 | unsigned int *rsize) | 110 | unsigned int *rsize) |
111 | { | 111 | { |
112 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 112 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev); |
113 | 113 | ||
114 | if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | 114 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && |
115 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 115 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
116 | hid_info(hdev, | 116 | hid_info(hdev, |
117 | "fixing up Logitech keyboard report descriptor\n"); | 117 | "fixing up Logitech keyboard report descriptor\n"); |
118 | rdesc[84] = rdesc[89] = 0x4d; | 118 | rdesc[84] = rdesc[89] = 0x4d; |
119 | rdesc[85] = rdesc[90] = 0x10; | 119 | rdesc[85] = rdesc[90] = 0x10; |
120 | } | 120 | } |
121 | if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && | 121 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && |
122 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && | 122 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && |
123 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { | 123 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { |
124 | hid_info(hdev, | 124 | hid_info(hdev, |
125 | "fixing up rel/abs in Logitech report descriptor\n"); | 125 | "fixing up rel/abs in Logitech report descriptor\n"); |
126 | rdesc[33] = rdesc[50] = 0x02; | 126 | rdesc[33] = rdesc[50] = 0x02; |
127 | } | 127 | } |
128 | if ((quirks & LG_FF4) && *rsize >= 101 && | 128 | if ((drv_data->quirks & LG_FF4) && *rsize >= 101 && |
129 | rdesc[41] == 0x95 && rdesc[42] == 0x0B && | 129 | rdesc[41] == 0x95 && rdesc[42] == 0x0B && |
130 | rdesc[47] == 0x05 && rdesc[48] == 0x09) { | 130 | rdesc[47] == 0x05 && rdesc[48] == 0x09) { |
131 | hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n"); | 131 | hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n"); |
@@ -278,7 +278,7 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
278 | 0, 0, 0, 0, 0,183,184,185,186,187, | 278 | 0, 0, 0, 0, 0,183,184,185,186,187, |
279 | 188,189,190,191,192,193,194, 0, 0, 0 | 279 | 188,189,190,191,192,193,194, 0, 0, 0 |
280 | }; | 280 | }; |
281 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 281 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev); |
282 | unsigned int hid = usage->hid; | 282 | unsigned int hid = usage->hid; |
283 | 283 | ||
284 | if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && | 284 | if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER && |
@@ -289,7 +289,7 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
289 | lg_dinovo_mapping(hi, usage, bit, max)) | 289 | lg_dinovo_mapping(hi, usage, bit, max)) |
290 | return 1; | 290 | return 1; |
291 | 291 | ||
292 | if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) | 292 | if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max)) |
293 | return 1; | 293 | return 1; |
294 | 294 | ||
295 | if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) | 295 | if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON) |
@@ -299,11 +299,11 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
299 | 299 | ||
300 | /* Special handling for Logitech Cordless Desktop */ | 300 | /* Special handling for Logitech Cordless Desktop */ |
301 | if (field->application == HID_GD_MOUSE) { | 301 | if (field->application == HID_GD_MOUSE) { |
302 | if ((quirks & LG_IGNORE_DOUBLED_WHEEL) && | 302 | if ((drv_data->quirks & LG_IGNORE_DOUBLED_WHEEL) && |
303 | (hid == 7 || hid == 8)) | 303 | (hid == 7 || hid == 8)) |
304 | return -1; | 304 | return -1; |
305 | } else { | 305 | } else { |
306 | if ((quirks & LG_EXPANDED_KEYMAP) && | 306 | if ((drv_data->quirks & LG_EXPANDED_KEYMAP) && |
307 | hid < ARRAY_SIZE(e_keymap) && | 307 | hid < ARRAY_SIZE(e_keymap) && |
308 | e_keymap[hid] != 0) { | 308 | e_keymap[hid] != 0) { |
309 | hid_map_usage(hi, usage, bit, max, EV_KEY, | 309 | hid_map_usage(hi, usage, bit, max, EV_KEY, |
@@ -319,13 +319,13 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
319 | struct hid_field *field, struct hid_usage *usage, | 319 | struct hid_field *field, struct hid_usage *usage, |
320 | unsigned long **bit, int *max) | 320 | unsigned long **bit, int *max) |
321 | { | 321 | { |
322 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 322 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev); |
323 | 323 | ||
324 | if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && | 324 | if ((drv_data->quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY && |
325 | (field->flags & HID_MAIN_ITEM_RELATIVE)) | 325 | (field->flags & HID_MAIN_ITEM_RELATIVE)) |
326 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; | 326 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; |
327 | 327 | ||
328 | if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || | 328 | if ((drv_data->quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY || |
329 | usage->type == EV_REL || usage->type == EV_ABS)) | 329 | usage->type == EV_REL || usage->type == EV_ABS)) |
330 | clear_bit(usage->code, *bit); | 330 | clear_bit(usage->code, *bit); |
331 | 331 | ||
@@ -335,9 +335,9 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
335 | static int lg_event(struct hid_device *hdev, struct hid_field *field, | 335 | static int lg_event(struct hid_device *hdev, struct hid_field *field, |
336 | struct hid_usage *usage, __s32 value) | 336 | struct hid_usage *usage, __s32 value) |
337 | { | 337 | { |
338 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 338 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev); |
339 | 339 | ||
340 | if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { | 340 | if ((drv_data->quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { |
341 | input_event(field->hidinput->input, usage->type, usage->code, | 341 | input_event(field->hidinput->input, usage->type, usage->code, |
342 | -value); | 342 | -value); |
343 | return 1; | 343 | return 1; |
@@ -348,13 +348,20 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field, | |||
348 | 348 | ||
349 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | 349 | static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) |
350 | { | 350 | { |
351 | unsigned long quirks = id->driver_data; | ||
352 | unsigned int connect_mask = HID_CONNECT_DEFAULT; | 351 | unsigned int connect_mask = HID_CONNECT_DEFAULT; |
352 | struct lg_drv_data *drv_data; | ||
353 | int ret; | 353 | int ret; |
354 | 354 | ||
355 | hid_set_drvdata(hdev, (void *)quirks); | 355 | drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); |
356 | if (!drv_data) { | ||
357 | hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); | ||
358 | return -ENOMEM; | ||
359 | } | ||
360 | drv_data->quirks = id->driver_data; | ||
361 | |||
362 | hid_set_drvdata(hdev, (void *)drv_data); | ||
356 | 363 | ||
357 | if (quirks & LG_NOGET) | 364 | if (drv_data->quirks & LG_NOGET) |
358 | hdev->quirks |= HID_QUIRK_NOGET; | 365 | hdev->quirks |= HID_QUIRK_NOGET; |
359 | 366 | ||
360 | ret = hid_parse(hdev); | 367 | ret = hid_parse(hdev); |
@@ -363,7 +370,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
363 | goto err_free; | 370 | goto err_free; |
364 | } | 371 | } |
365 | 372 | ||
366 | if (quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4)) | 373 | if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4)) |
367 | connect_mask &= ~HID_CONNECT_FF; | 374 | connect_mask &= ~HID_CONNECT_FF; |
368 | 375 | ||
369 | ret = hid_hw_start(hdev, connect_mask); | 376 | ret = hid_hw_start(hdev, connect_mask); |
@@ -392,27 +399,29 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
392 | } | 399 | } |
393 | } | 400 | } |
394 | 401 | ||
395 | if (quirks & LG_FF) | 402 | if (drv_data->quirks & LG_FF) |
396 | lgff_init(hdev); | 403 | lgff_init(hdev); |
397 | if (quirks & LG_FF2) | 404 | if (drv_data->quirks & LG_FF2) |
398 | lg2ff_init(hdev); | 405 | lg2ff_init(hdev); |
399 | if (quirks & LG_FF3) | 406 | if (drv_data->quirks & LG_FF3) |
400 | lg3ff_init(hdev); | 407 | lg3ff_init(hdev); |
401 | if (quirks & LG_FF4) | 408 | if (drv_data->quirks & LG_FF4) |
402 | lg4ff_init(hdev); | 409 | lg4ff_init(hdev); |
403 | 410 | ||
404 | return 0; | 411 | return 0; |
405 | err_free: | 412 | err_free: |
413 | kfree(drv_data); | ||
406 | return ret; | 414 | return ret; |
407 | } | 415 | } |
408 | 416 | ||
409 | static void lg_remove(struct hid_device *hdev) | 417 | static void lg_remove(struct hid_device *hdev) |
410 | { | 418 | { |
411 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); | 419 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev); |
412 | if(quirks & LG_FF4) | 420 | if (drv_data->quirks & LG_FF4) |
413 | lg4ff_deinit(hdev); | 421 | lg4ff_deinit(hdev); |
414 | 422 | ||
415 | hid_hw_stop(hdev); | 423 | hid_hw_stop(hdev); |
424 | kfree(drv_data); | ||
416 | } | 425 | } |
417 | 426 | ||
418 | static const struct hid_device_id lg_devices[] = { | 427 | static const struct hid_device_id lg_devices[] = { |
diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h index 4b097286dc78..d64cf8d2751e 100644 --- a/drivers/hid/hid-lg.h +++ b/drivers/hid/hid-lg.h | |||
@@ -1,6 +1,11 @@ | |||
1 | #ifndef __HID_LG_H | 1 | #ifndef __HID_LG_H |
2 | #define __HID_LG_H | 2 | #define __HID_LG_H |
3 | 3 | ||
4 | struct lg_drv_data { | ||
5 | unsigned long quirks; | ||
6 | void *device_props; /* Device specific properties */ | ||
7 | }; | ||
8 | |||
4 | #ifdef CONFIG_LOGITECH_FF | 9 | #ifdef CONFIG_LOGITECH_FF |
5 | int lgff_init(struct hid_device *hdev); | 10 | int lgff_init(struct hid_device *hdev); |
6 | #else | 11 | #else |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 6ecc9e220440..f3390ee6105c 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Force feedback support for Logitech Speed Force Wireless | 2 | * Force feedback support for Logitech Gaming Wheels |
3 | * | 3 | * |
4 | * http://wiibrew.org/wiki/Logitech_USB_steering_wheel | 4 | * Including G27, G25, DFP, DFGT, FFEX, Momo, Momo2 & |
5 | * Speed Force Wireless (WiiWheel) | ||
5 | * | 6 | * |
6 | * Copyright (c) 2010 Simon Wood <simon@mungewell.org> | 7 | * Copyright (c) 2010 Simon Wood <simon@mungewell.org> |
7 | */ | 8 | */ |
@@ -51,20 +52,18 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at | |||
51 | 52 | ||
52 | static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store); | 53 | static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store); |
53 | 54 | ||
54 | static bool list_inited; | ||
55 | |||
56 | struct lg4ff_device_entry { | 55 | struct lg4ff_device_entry { |
57 | char *device_id; /* Use name in respective kobject structure's address as the ID */ | ||
58 | __u16 range; | 56 | __u16 range; |
59 | __u16 min_range; | 57 | __u16 min_range; |
60 | __u16 max_range; | 58 | __u16 max_range; |
61 | __u8 leds; | 59 | #ifdef CONFIG_LEDS_CLASS |
60 | __u8 led_state; | ||
61 | struct led_classdev *led[5]; | ||
62 | #endif | ||
62 | struct list_head list; | 63 | struct list_head list; |
63 | void (*set_range)(struct hid_device *hid, u16 range); | 64 | void (*set_range)(struct hid_device *hid, u16 range); |
64 | }; | 65 | }; |
65 | 66 | ||
66 | static struct lg4ff_device_entry device_list; | ||
67 | |||
68 | static const signed short lg4ff_wheel_effects[] = { | 67 | static const signed short lg4ff_wheel_effects[] = { |
69 | FF_CONSTANT, | 68 | FF_CONSTANT, |
70 | FF_AUTOCENTER, | 69 | FF_AUTOCENTER, |
@@ -285,18 +284,20 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n | |||
285 | /* Read current range and display it in terminal */ | 284 | /* Read current range and display it in terminal */ |
286 | static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) | 285 | static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) |
287 | { | 286 | { |
288 | struct lg4ff_device_entry *uninitialized_var(entry); | ||
289 | struct list_head *h; | ||
290 | struct hid_device *hid = to_hid_device(dev); | 287 | struct hid_device *hid = to_hid_device(dev); |
288 | struct lg4ff_device_entry *entry; | ||
289 | struct lg_drv_data *drv_data; | ||
291 | size_t count; | 290 | size_t count; |
292 | 291 | ||
293 | list_for_each(h, &device_list.list) { | 292 | drv_data = hid_get_drvdata(hid); |
294 | entry = list_entry(h, struct lg4ff_device_entry, list); | 293 | if (!drv_data) { |
295 | if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) | 294 | hid_err(hid, "Private driver data not found!\n"); |
296 | break; | 295 | return 0; |
297 | } | 296 | } |
298 | if (h == &device_list.list) { | 297 | |
299 | dbg_hid("Device not found!"); | 298 | entry = drv_data->device_props; |
299 | if (!entry) { | ||
300 | hid_err(hid, "Device properties not found!\n"); | ||
300 | return 0; | 301 | return 0; |
301 | } | 302 | } |
302 | 303 | ||
@@ -308,19 +309,21 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att | |||
308 | * according to the type of the wheel */ | 309 | * according to the type of the wheel */ |
309 | static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 310 | static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
310 | { | 311 | { |
311 | struct lg4ff_device_entry *uninitialized_var(entry); | ||
312 | struct list_head *h; | ||
313 | struct hid_device *hid = to_hid_device(dev); | 312 | struct hid_device *hid = to_hid_device(dev); |
313 | struct lg4ff_device_entry *entry; | ||
314 | struct lg_drv_data *drv_data; | ||
314 | __u16 range = simple_strtoul(buf, NULL, 10); | 315 | __u16 range = simple_strtoul(buf, NULL, 10); |
315 | 316 | ||
316 | list_for_each(h, &device_list.list) { | 317 | drv_data = hid_get_drvdata(hid); |
317 | entry = list_entry(h, struct lg4ff_device_entry, list); | 318 | if (!drv_data) { |
318 | if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) | 319 | hid_err(hid, "Private driver data not found!\n"); |
319 | break; | 320 | return 0; |
320 | } | 321 | } |
321 | if (h == &device_list.list) { | 322 | |
322 | dbg_hid("Device not found!"); | 323 | entry = drv_data->device_props; |
323 | return count; | 324 | if (!entry) { |
325 | hid_err(hid, "Device properties not found!\n"); | ||
326 | return 0; | ||
324 | } | 327 | } |
325 | 328 | ||
326 | if (range == 0) | 329 | if (range == 0) |
@@ -336,6 +339,88 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at | |||
336 | return count; | 339 | return count; |
337 | } | 340 | } |
338 | 341 | ||
342 | #ifdef CONFIG_LEDS_CLASS | ||
343 | static void lg4ff_set_leds(struct hid_device *hid, __u8 leds) | ||
344 | { | ||
345 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
346 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | ||
347 | |||
348 | report->field[0]->value[0] = 0xf8; | ||
349 | report->field[0]->value[1] = 0x12; | ||
350 | report->field[0]->value[2] = leds; | ||
351 | report->field[0]->value[3] = 0x00; | ||
352 | report->field[0]->value[4] = 0x00; | ||
353 | report->field[0]->value[5] = 0x00; | ||
354 | report->field[0]->value[6] = 0x00; | ||
355 | usbhid_submit_report(hid, report, USB_DIR_OUT); | ||
356 | } | ||
357 | |||
358 | static void lg4ff_led_set_brightness(struct led_classdev *led_cdev, | ||
359 | enum led_brightness value) | ||
360 | { | ||
361 | struct device *dev = led_cdev->dev->parent; | ||
362 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
363 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hid); | ||
364 | struct lg4ff_device_entry *entry; | ||
365 | int i, state = 0; | ||
366 | |||
367 | if (!drv_data) { | ||
368 | hid_err(hid, "Device data not found."); | ||
369 | return; | ||
370 | } | ||
371 | |||
372 | entry = (struct lg4ff_device_entry *)drv_data->device_props; | ||
373 | |||
374 | if (!entry) { | ||
375 | hid_err(hid, "Device properties not found."); | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | for (i = 0; i < 5; i++) { | ||
380 | if (led_cdev != entry->led[i]) | ||
381 | continue; | ||
382 | state = (entry->led_state >> i) & 1; | ||
383 | if (value == LED_OFF && state) { | ||
384 | entry->led_state &= ~(1 << i); | ||
385 | lg4ff_set_leds(hid, entry->led_state); | ||
386 | } else if (value != LED_OFF && !state) { | ||
387 | entry->led_state |= 1 << i; | ||
388 | lg4ff_set_leds(hid, entry->led_state); | ||
389 | } | ||
390 | break; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cdev) | ||
395 | { | ||
396 | struct device *dev = led_cdev->dev->parent; | ||
397 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
398 | struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hid); | ||
399 | struct lg4ff_device_entry *entry; | ||
400 | int i, value = 0; | ||
401 | |||
402 | if (!drv_data) { | ||
403 | hid_err(hid, "Device data not found."); | ||
404 | return LED_OFF; | ||
405 | } | ||
406 | |||
407 | entry = (struct lg4ff_device_entry *)drv_data->device_props; | ||
408 | |||
409 | if (!entry) { | ||
410 | hid_err(hid, "Device properties not found."); | ||
411 | return LED_OFF; | ||
412 | } | ||
413 | |||
414 | for (i = 0; i < 5; i++) | ||
415 | if (led_cdev == entry->led[i]) { | ||
416 | value = (entry->led_state >> i) & 1; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | return value ? LED_FULL : LED_OFF; | ||
421 | } | ||
422 | #endif | ||
423 | |||
339 | int lg4ff_init(struct hid_device *hid) | 424 | int lg4ff_init(struct hid_device *hid) |
340 | { | 425 | { |
341 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 426 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); |
@@ -344,6 +429,7 @@ int lg4ff_init(struct hid_device *hid) | |||
344 | struct hid_report *report; | 429 | struct hid_report *report; |
345 | struct hid_field *field; | 430 | struct hid_field *field; |
346 | struct lg4ff_device_entry *entry; | 431 | struct lg4ff_device_entry *entry; |
432 | struct lg_drv_data *drv_data; | ||
347 | struct usb_device_descriptor *udesc; | 433 | struct usb_device_descriptor *udesc; |
348 | int error, i, j; | 434 | int error, i, j; |
349 | __u16 bcdDevice, rev_maj, rev_min; | 435 | __u16 bcdDevice, rev_maj, rev_min; |
@@ -423,28 +509,24 @@ int lg4ff_init(struct hid_device *hid) | |||
423 | dev->ff->set_autocenter(dev, 0); | 509 | dev->ff->set_autocenter(dev, 0); |
424 | } | 510 | } |
425 | 511 | ||
426 | /* Initialize device_list if this is the first device to handle by lg4ff */ | 512 | /* Get private driver data */ |
427 | if (!list_inited) { | 513 | drv_data = hid_get_drvdata(hid); |
428 | INIT_LIST_HEAD(&device_list.list); | 514 | if (!drv_data) { |
429 | list_inited = 1; | 515 | hid_err(hid, "Cannot add device, private driver data not allocated\n"); |
516 | return -1; | ||
430 | } | 517 | } |
431 | 518 | ||
432 | /* Add the device to device_list */ | 519 | /* Initialize device properties */ |
433 | entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL); | 520 | entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL); |
434 | if (!entry) { | 521 | if (!entry) { |
435 | hid_err(hid, "Cannot add device, insufficient memory.\n"); | 522 | hid_err(hid, "Cannot add device, insufficient memory to allocate device properties.\n"); |
436 | return -ENOMEM; | ||
437 | } | ||
438 | entry->device_id = kstrdup((&hid->dev)->kobj.name, GFP_KERNEL); | ||
439 | if (!entry->device_id) { | ||
440 | hid_err(hid, "Cannot set device_id, insufficient memory.\n"); | ||
441 | kfree(entry); | ||
442 | return -ENOMEM; | 523 | return -ENOMEM; |
443 | } | 524 | } |
525 | drv_data->device_props = entry; | ||
526 | |||
444 | entry->min_range = lg4ff_devices[i].min_range; | 527 | entry->min_range = lg4ff_devices[i].min_range; |
445 | entry->max_range = lg4ff_devices[i].max_range; | 528 | entry->max_range = lg4ff_devices[i].max_range; |
446 | entry->set_range = lg4ff_devices[i].set_range; | 529 | entry->set_range = lg4ff_devices[i].set_range; |
447 | list_add(&entry->list, &device_list.list); | ||
448 | 530 | ||
449 | /* Create sysfs interface */ | 531 | /* Create sysfs interface */ |
450 | error = device_create_file(&hid->dev, &dev_attr_range); | 532 | error = device_create_file(&hid->dev, &dev_attr_range); |
@@ -457,32 +539,100 @@ int lg4ff_init(struct hid_device *hid) | |||
457 | if (entry->set_range != NULL) | 539 | if (entry->set_range != NULL) |
458 | entry->set_range(hid, entry->range); | 540 | entry->set_range(hid, entry->range); |
459 | 541 | ||
460 | hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood <simon@mungewell.org>\n"); | 542 | #ifdef CONFIG_LEDS_CLASS |
543 | /* register led subsystem - G27 only */ | ||
544 | entry->led_state = 0; | ||
545 | for (j = 0; j < 5; j++) | ||
546 | entry->led[j] = NULL; | ||
547 | |||
548 | if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) { | ||
549 | struct led_classdev *led; | ||
550 | size_t name_sz; | ||
551 | char *name; | ||
552 | |||
553 | lg4ff_set_leds(hid, 0); | ||
554 | |||
555 | name_sz = strlen(dev_name(&hid->dev)) + 8; | ||
556 | |||
557 | for (j = 0; j < 5; j++) { | ||
558 | led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); | ||
559 | if (!led) { | ||
560 | hid_err(hid, "can't allocate memory for LED %d\n", j); | ||
561 | goto err; | ||
562 | } | ||
563 | |||
564 | name = (void *)(&led[1]); | ||
565 | snprintf(name, name_sz, "%s::RPM%d", dev_name(&hid->dev), j+1); | ||
566 | led->name = name; | ||
567 | led->brightness = 0; | ||
568 | led->max_brightness = 1; | ||
569 | led->brightness_get = lg4ff_led_get_brightness; | ||
570 | led->brightness_set = lg4ff_led_set_brightness; | ||
571 | |||
572 | entry->led[j] = led; | ||
573 | error = led_classdev_register(&hid->dev, led); | ||
574 | |||
575 | if (error) { | ||
576 | hid_err(hid, "failed to register LED %d. Aborting.\n", j); | ||
577 | err: | ||
578 | /* Deregister LEDs (if any) */ | ||
579 | for (j = 0; j < 5; j++) { | ||
580 | led = entry->led[j]; | ||
581 | entry->led[j] = NULL; | ||
582 | if (!led) | ||
583 | continue; | ||
584 | led_classdev_unregister(led); | ||
585 | kfree(led); | ||
586 | } | ||
587 | goto out; /* Let the driver continue without LEDs */ | ||
588 | } | ||
589 | } | ||
590 | } | ||
591 | out: | ||
592 | #endif | ||
593 | hid_info(hid, "Force feedback support for Logitech Gaming Wheels\n"); | ||
461 | return 0; | 594 | return 0; |
462 | } | 595 | } |
463 | 596 | ||
464 | int lg4ff_deinit(struct hid_device *hid) | 597 | int lg4ff_deinit(struct hid_device *hid) |
465 | { | 598 | { |
466 | bool found = 0; | ||
467 | struct lg4ff_device_entry *entry; | 599 | struct lg4ff_device_entry *entry; |
468 | struct list_head *h, *g; | 600 | struct lg_drv_data *drv_data; |
469 | list_for_each_safe(h, g, &device_list.list) { | 601 | |
470 | entry = list_entry(h, struct lg4ff_device_entry, list); | 602 | device_remove_file(&hid->dev, &dev_attr_range); |
471 | if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) { | ||
472 | list_del(h); | ||
473 | kfree(entry->device_id); | ||
474 | kfree(entry); | ||
475 | found = 1; | ||
476 | break; | ||
477 | } | ||
478 | } | ||
479 | 603 | ||
480 | if (!found) { | 604 | drv_data = hid_get_drvdata(hid); |
481 | dbg_hid("Device entry not found!\n"); | 605 | if (!drv_data) { |
606 | hid_err(hid, "Error while deinitializing device, no private driver data.\n"); | ||
607 | return -1; | ||
608 | } | ||
609 | entry = drv_data->device_props; | ||
610 | if (!entry) { | ||
611 | hid_err(hid, "Error while deinitializing device, no device properties data.\n"); | ||
482 | return -1; | 612 | return -1; |
483 | } | 613 | } |
484 | 614 | ||
485 | device_remove_file(&hid->dev, &dev_attr_range); | 615 | #ifdef CONFIG_LEDS_CLASS |
616 | { | ||
617 | int j; | ||
618 | struct led_classdev *led; | ||
619 | |||
620 | /* Deregister LEDs (if any) */ | ||
621 | for (j = 0; j < 5; j++) { | ||
622 | |||
623 | led = entry->led[j]; | ||
624 | entry->led[j] = NULL; | ||
625 | if (!led) | ||
626 | continue; | ||
627 | led_classdev_unregister(led); | ||
628 | kfree(led); | ||
629 | } | ||
630 | } | ||
631 | #endif | ||
632 | |||
633 | /* Deallocate memory */ | ||
634 | kfree(entry); | ||
635 | |||
486 | dbg_hid("Device successfully unregistered\n"); | 636 | dbg_hid("Device successfully unregistered\n"); |
487 | return 0; | 637 | return 0; |
488 | } | 638 | } |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index d44ea58c597e..5e8a7ed42344 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -156,6 +156,14 @@ static const char media_descriptor[] = { | |||
156 | /* Maximum size of all defined hid reports in bytes (including report id) */ | 156 | /* Maximum size of all defined hid reports in bytes (including report id) */ |
157 | #define MAX_REPORT_SIZE 8 | 157 | #define MAX_REPORT_SIZE 8 |
158 | 158 | ||
159 | /* Make sure all descriptors are present here */ | ||
160 | #define MAX_RDESC_SIZE \ | ||
161 | (sizeof(kbd_descriptor) + \ | ||
162 | sizeof(mse_descriptor) + \ | ||
163 | sizeof(consumer_descriptor) + \ | ||
164 | sizeof(syscontrol_descriptor) + \ | ||
165 | sizeof(media_descriptor)) | ||
166 | |||
159 | /* Number of possible hid report types that can be created by this driver. | 167 | /* Number of possible hid report types that can be created by this driver. |
160 | * | 168 | * |
161 | * Right now, RF report types have the same report types (or report id's) | 169 | * Right now, RF report types have the same report types (or report id's) |
@@ -474,9 +482,17 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | |||
474 | return 0; | 482 | return 0; |
475 | } | 483 | } |
476 | 484 | ||
485 | static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size) | ||
486 | { | ||
487 | memcpy(*rdesc + *rsize, data, size); | ||
488 | *rsize += size; | ||
489 | } | ||
490 | |||
477 | static int logi_dj_ll_parse(struct hid_device *hid) | 491 | static int logi_dj_ll_parse(struct hid_device *hid) |
478 | { | 492 | { |
479 | struct dj_device *djdev = hid->driver_data; | 493 | struct dj_device *djdev = hid->driver_data; |
494 | unsigned int rsize = 0; | ||
495 | char *rdesc; | ||
480 | int retval; | 496 | int retval; |
481 | 497 | ||
482 | dbg_hid("%s\n", __func__); | 498 | dbg_hid("%s\n", __func__); |
@@ -484,70 +500,38 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
484 | djdev->hdev->version = 0x0111; | 500 | djdev->hdev->version = 0x0111; |
485 | djdev->hdev->country = 0x00; | 501 | djdev->hdev->country = 0x00; |
486 | 502 | ||
503 | rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL); | ||
504 | if (!rdesc) | ||
505 | return -ENOMEM; | ||
506 | |||
487 | if (djdev->reports_supported & STD_KEYBOARD) { | 507 | if (djdev->reports_supported & STD_KEYBOARD) { |
488 | dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", | 508 | dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", |
489 | __func__, djdev->reports_supported); | 509 | __func__, djdev->reports_supported); |
490 | retval = hid_parse_report(hid, | 510 | rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor)); |
491 | (u8 *) kbd_descriptor, | ||
492 | sizeof(kbd_descriptor)); | ||
493 | if (retval) { | ||
494 | dbg_hid("%s: sending a kbd descriptor, hid_parse failed" | ||
495 | " error: %d\n", __func__, retval); | ||
496 | return retval; | ||
497 | } | ||
498 | } | 511 | } |
499 | 512 | ||
500 | if (djdev->reports_supported & STD_MOUSE) { | 513 | if (djdev->reports_supported & STD_MOUSE) { |
501 | dbg_hid("%s: sending a mouse descriptor, reports_supported: " | 514 | dbg_hid("%s: sending a mouse descriptor, reports_supported: " |
502 | "%x\n", __func__, djdev->reports_supported); | 515 | "%x\n", __func__, djdev->reports_supported); |
503 | retval = hid_parse_report(hid, | 516 | rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor)); |
504 | (u8 *) mse_descriptor, | ||
505 | sizeof(mse_descriptor)); | ||
506 | if (retval) { | ||
507 | dbg_hid("%s: sending a mouse descriptor, hid_parse " | ||
508 | "failed error: %d\n", __func__, retval); | ||
509 | return retval; | ||
510 | } | ||
511 | } | 517 | } |
512 | 518 | ||
513 | if (djdev->reports_supported & MULTIMEDIA) { | 519 | if (djdev->reports_supported & MULTIMEDIA) { |
514 | dbg_hid("%s: sending a multimedia report descriptor: %x\n", | 520 | dbg_hid("%s: sending a multimedia report descriptor: %x\n", |
515 | __func__, djdev->reports_supported); | 521 | __func__, djdev->reports_supported); |
516 | retval = hid_parse_report(hid, | 522 | rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor)); |
517 | (u8 *) consumer_descriptor, | ||
518 | sizeof(consumer_descriptor)); | ||
519 | if (retval) { | ||
520 | dbg_hid("%s: sending a consumer_descriptor, hid_parse " | ||
521 | "failed error: %d\n", __func__, retval); | ||
522 | return retval; | ||
523 | } | ||
524 | } | 523 | } |
525 | 524 | ||
526 | if (djdev->reports_supported & POWER_KEYS) { | 525 | if (djdev->reports_supported & POWER_KEYS) { |
527 | dbg_hid("%s: sending a power keys report descriptor: %x\n", | 526 | dbg_hid("%s: sending a power keys report descriptor: %x\n", |
528 | __func__, djdev->reports_supported); | 527 | __func__, djdev->reports_supported); |
529 | retval = hid_parse_report(hid, | 528 | rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor)); |
530 | (u8 *) syscontrol_descriptor, | ||
531 | sizeof(syscontrol_descriptor)); | ||
532 | if (retval) { | ||
533 | dbg_hid("%s: sending a syscontrol_descriptor, " | ||
534 | "hid_parse failed error: %d\n", | ||
535 | __func__, retval); | ||
536 | return retval; | ||
537 | } | ||
538 | } | 529 | } |
539 | 530 | ||
540 | if (djdev->reports_supported & MEDIA_CENTER) { | 531 | if (djdev->reports_supported & MEDIA_CENTER) { |
541 | dbg_hid("%s: sending a media center report descriptor: %x\n", | 532 | dbg_hid("%s: sending a media center report descriptor: %x\n", |
542 | __func__, djdev->reports_supported); | 533 | __func__, djdev->reports_supported); |
543 | retval = hid_parse_report(hid, | 534 | rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor)); |
544 | (u8 *) media_descriptor, | ||
545 | sizeof(media_descriptor)); | ||
546 | if (retval) { | ||
547 | dbg_hid("%s: sending a media_descriptor, hid_parse " | ||
548 | "failed error: %d\n", __func__, retval); | ||
549 | return retval; | ||
550 | } | ||
551 | } | 535 | } |
552 | 536 | ||
553 | if (djdev->reports_supported & KBD_LEDS) { | 537 | if (djdev->reports_supported & KBD_LEDS) { |
@@ -555,7 +539,10 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
555 | __func__, djdev->reports_supported); | 539 | __func__, djdev->reports_supported); |
556 | } | 540 | } |
557 | 541 | ||
558 | return 0; | 542 | retval = hid_parse_report(hid, rdesc, rsize); |
543 | kfree(rdesc); | ||
544 | |||
545 | return retval; | ||
559 | } | 546 | } |
560 | 547 | ||
561 | static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, | 548 | static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 1d5b94167b52..6e3332a99976 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -70,9 +70,16 @@ struct mt_class { | |||
70 | bool is_indirect; /* true for touchpads */ | 70 | bool is_indirect; /* true for touchpads */ |
71 | }; | 71 | }; |
72 | 72 | ||
73 | struct mt_fields { | ||
74 | unsigned usages[HID_MAX_FIELDS]; | ||
75 | unsigned int length; | ||
76 | }; | ||
77 | |||
73 | struct mt_device { | 78 | struct mt_device { |
74 | struct mt_slot curdata; /* placeholder of incoming data */ | 79 | struct mt_slot curdata; /* placeholder of incoming data */ |
75 | struct mt_class mtclass; /* our mt device class */ | 80 | struct mt_class mtclass; /* our mt device class */ |
81 | struct mt_fields *fields; /* temporary placeholder for storing the | ||
82 | multitouch fields */ | ||
76 | unsigned last_field_index; /* last field index of the report */ | 83 | unsigned last_field_index; /* last field index of the report */ |
77 | unsigned last_slot_field; /* the last field of a slot */ | 84 | unsigned last_slot_field; /* the last field of a slot */ |
78 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 85 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
@@ -110,6 +117,9 @@ struct mt_device { | |||
110 | 117 | ||
111 | #define MT_DEFAULT_MAXCONTACT 10 | 118 | #define MT_DEFAULT_MAXCONTACT 10 |
112 | 119 | ||
120 | #define MT_USB_DEVICE(v, p) HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p) | ||
121 | #define MT_BT_DEVICE(v, p) HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p) | ||
122 | |||
113 | /* | 123 | /* |
114 | * these device-dependent functions determine what slot corresponds | 124 | * these device-dependent functions determine what slot corresponds |
115 | * to a valid contact that was just read. | 125 | * to a valid contact that was just read. |
@@ -275,11 +285,15 @@ static void set_abs(struct input_dev *input, unsigned int code, | |||
275 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); | 285 | input_set_abs_params(input, code, fmin, fmax, fuzz, 0); |
276 | } | 286 | } |
277 | 287 | ||
278 | static void set_last_slot_field(struct hid_usage *usage, struct mt_device *td, | 288 | static void mt_store_field(struct hid_usage *usage, struct mt_device *td, |
279 | struct hid_input *hi) | 289 | struct hid_input *hi) |
280 | { | 290 | { |
281 | if (!test_bit(usage->hid, hi->input->absbit)) | 291 | struct mt_fields *f = td->fields; |
282 | td->last_slot_field = usage->hid; | 292 | |
293 | if (f->length >= HID_MAX_FIELDS) | ||
294 | return; | ||
295 | |||
296 | f->usages[f->length++] = usage->hid; | ||
283 | } | 297 | } |
284 | 298 | ||
285 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 299 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
@@ -330,7 +344,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
330 | cls->sn_move); | 344 | cls->sn_move); |
331 | /* touchscreen emulation */ | 345 | /* touchscreen emulation */ |
332 | set_abs(hi->input, ABS_X, field, cls->sn_move); | 346 | set_abs(hi->input, ABS_X, field, cls->sn_move); |
333 | set_last_slot_field(usage, td, hi); | 347 | mt_store_field(usage, td, hi); |
334 | td->last_field_index = field->index; | 348 | td->last_field_index = field->index; |
335 | return 1; | 349 | return 1; |
336 | case HID_GD_Y: | 350 | case HID_GD_Y: |
@@ -340,7 +354,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
340 | cls->sn_move); | 354 | cls->sn_move); |
341 | /* touchscreen emulation */ | 355 | /* touchscreen emulation */ |
342 | set_abs(hi->input, ABS_Y, field, cls->sn_move); | 356 | set_abs(hi->input, ABS_Y, field, cls->sn_move); |
343 | set_last_slot_field(usage, td, hi); | 357 | mt_store_field(usage, td, hi); |
344 | td->last_field_index = field->index; | 358 | td->last_field_index = field->index; |
345 | return 1; | 359 | return 1; |
346 | } | 360 | } |
@@ -349,24 +363,24 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
349 | case HID_UP_DIGITIZER: | 363 | case HID_UP_DIGITIZER: |
350 | switch (usage->hid) { | 364 | switch (usage->hid) { |
351 | case HID_DG_INRANGE: | 365 | case HID_DG_INRANGE: |
352 | set_last_slot_field(usage, td, hi); | 366 | mt_store_field(usage, td, hi); |
353 | td->last_field_index = field->index; | 367 | td->last_field_index = field->index; |
354 | return 1; | 368 | return 1; |
355 | case HID_DG_CONFIDENCE: | 369 | case HID_DG_CONFIDENCE: |
356 | set_last_slot_field(usage, td, hi); | 370 | mt_store_field(usage, td, hi); |
357 | td->last_field_index = field->index; | 371 | td->last_field_index = field->index; |
358 | return 1; | 372 | return 1; |
359 | case HID_DG_TIPSWITCH: | 373 | case HID_DG_TIPSWITCH: |
360 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 374 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
361 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 375 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
362 | set_last_slot_field(usage, td, hi); | 376 | mt_store_field(usage, td, hi); |
363 | td->last_field_index = field->index; | 377 | td->last_field_index = field->index; |
364 | return 1; | 378 | return 1; |
365 | case HID_DG_CONTACTID: | 379 | case HID_DG_CONTACTID: |
366 | if (!td->maxcontacts) | 380 | if (!td->maxcontacts) |
367 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | 381 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; |
368 | input_mt_init_slots(hi->input, td->maxcontacts); | 382 | input_mt_init_slots(hi->input, td->maxcontacts); |
369 | td->last_slot_field = usage->hid; | 383 | mt_store_field(usage, td, hi); |
370 | td->last_field_index = field->index; | 384 | td->last_field_index = field->index; |
371 | td->touches_by_report++; | 385 | td->touches_by_report++; |
372 | return 1; | 386 | return 1; |
@@ -375,7 +389,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
375 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 389 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
376 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 390 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
377 | cls->sn_width); | 391 | cls->sn_width); |
378 | set_last_slot_field(usage, td, hi); | 392 | mt_store_field(usage, td, hi); |
379 | td->last_field_index = field->index; | 393 | td->last_field_index = field->index; |
380 | return 1; | 394 | return 1; |
381 | case HID_DG_HEIGHT: | 395 | case HID_DG_HEIGHT: |
@@ -385,7 +399,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
385 | cls->sn_height); | 399 | cls->sn_height); |
386 | input_set_abs_params(hi->input, | 400 | input_set_abs_params(hi->input, |
387 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 401 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
388 | set_last_slot_field(usage, td, hi); | 402 | mt_store_field(usage, td, hi); |
389 | td->last_field_index = field->index; | 403 | td->last_field_index = field->index; |
390 | return 1; | 404 | return 1; |
391 | case HID_DG_TIPPRESSURE: | 405 | case HID_DG_TIPPRESSURE: |
@@ -396,7 +410,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
396 | /* touchscreen emulation */ | 410 | /* touchscreen emulation */ |
397 | set_abs(hi->input, ABS_PRESSURE, field, | 411 | set_abs(hi->input, ABS_PRESSURE, field, |
398 | cls->sn_pressure); | 412 | cls->sn_pressure); |
399 | set_last_slot_field(usage, td, hi); | 413 | mt_store_field(usage, td, hi); |
400 | td->last_field_index = field->index; | 414 | td->last_field_index = field->index; |
401 | return 1; | 415 | return 1; |
402 | case HID_DG_CONTACTCOUNT: | 416 | case HID_DG_CONTACTCOUNT: |
@@ -635,6 +649,31 @@ static void mt_set_maxcontacts(struct hid_device *hdev) | |||
635 | } | 649 | } |
636 | } | 650 | } |
637 | 651 | ||
652 | static void mt_post_parse_default_settings(struct mt_device *td) | ||
653 | { | ||
654 | __s32 quirks = td->mtclass.quirks; | ||
655 | |||
656 | /* unknown serial device needs special quirks */ | ||
657 | if (td->touches_by_report == 1) { | ||
658 | quirks |= MT_QUIRK_ALWAYS_VALID; | ||
659 | quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | ||
660 | quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | ||
661 | quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; | ||
662 | } | ||
663 | |||
664 | td->mtclass.quirks = quirks; | ||
665 | } | ||
666 | |||
667 | static void mt_post_parse(struct mt_device *td) | ||
668 | { | ||
669 | struct mt_fields *f = td->fields; | ||
670 | |||
671 | if (td->touches_by_report > 0) { | ||
672 | int field_count_per_touch = f->length / td->touches_by_report; | ||
673 | td->last_slot_field = f->usages[field_count_per_touch - 1]; | ||
674 | } | ||
675 | } | ||
676 | |||
638 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | 677 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
639 | { | 678 | { |
640 | int ret, i; | 679 | int ret, i; |
@@ -654,7 +693,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
654 | * that emit events over several HID messages. | 693 | * that emit events over several HID messages. |
655 | */ | 694 | */ |
656 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | 695 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
657 | hdev->quirks &= ~HID_QUIRK_MULTITOUCH; | ||
658 | 696 | ||
659 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); | 697 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); |
660 | if (!td) { | 698 | if (!td) { |
@@ -666,6 +704,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
666 | td->maxcontact_report_id = -1; | 704 | td->maxcontact_report_id = -1; |
667 | hid_set_drvdata(hdev, td); | 705 | hid_set_drvdata(hdev, td); |
668 | 706 | ||
707 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); | ||
708 | if (!td->fields) { | ||
709 | dev_err(&hdev->dev, "cannot allocate multitouch fields data\n"); | ||
710 | ret = -ENOMEM; | ||
711 | goto fail; | ||
712 | } | ||
713 | |||
669 | ret = hid_parse(hdev); | 714 | ret = hid_parse(hdev); |
670 | if (ret != 0) | 715 | if (ret != 0) |
671 | goto fail; | 716 | goto fail; |
@@ -674,14 +719,10 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
674 | if (ret) | 719 | if (ret) |
675 | goto fail; | 720 | goto fail; |
676 | 721 | ||
677 | if (!id && td->touches_by_report == 1) { | 722 | mt_post_parse(td); |
678 | /* the device has been sent by hid-generic */ | 723 | |
679 | mtclass = &td->mtclass; | 724 | if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) |
680 | mtclass->quirks |= MT_QUIRK_ALWAYS_VALID; | 725 | mt_post_parse_default_settings(td); |
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 | 726 | ||
686 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), | 727 | td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), |
687 | GFP_KERNEL); | 728 | GFP_KERNEL); |
@@ -697,9 +738,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
697 | mt_set_maxcontacts(hdev); | 738 | mt_set_maxcontacts(hdev); |
698 | mt_set_input_mode(hdev); | 739 | mt_set_input_mode(hdev); |
699 | 740 | ||
741 | kfree(td->fields); | ||
742 | td->fields = NULL; | ||
743 | |||
700 | return 0; | 744 | return 0; |
701 | 745 | ||
702 | fail: | 746 | fail: |
747 | kfree(td->fields); | ||
703 | kfree(td); | 748 | kfree(td); |
704 | return ret; | 749 | return ret; |
705 | } | 750 | } |
@@ -727,50 +772,54 @@ static const struct hid_device_id mt_devices[] = { | |||
727 | 772 | ||
728 | /* 3M panels */ | 773 | /* 3M panels */ |
729 | { .driver_data = MT_CLS_3M, | 774 | { .driver_data = MT_CLS_3M, |
730 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | 775 | MT_USB_DEVICE(USB_VENDOR_ID_3M, |
731 | USB_DEVICE_ID_3M1968) }, | 776 | USB_DEVICE_ID_3M1968) }, |
732 | { .driver_data = MT_CLS_3M, | 777 | { .driver_data = MT_CLS_3M, |
733 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | 778 | MT_USB_DEVICE(USB_VENDOR_ID_3M, |
734 | USB_DEVICE_ID_3M2256) }, | 779 | USB_DEVICE_ID_3M2256) }, |
735 | { .driver_data = MT_CLS_3M, | 780 | { .driver_data = MT_CLS_3M, |
736 | HID_USB_DEVICE(USB_VENDOR_ID_3M, | 781 | MT_USB_DEVICE(USB_VENDOR_ID_3M, |
737 | USB_DEVICE_ID_3M3266) }, | 782 | USB_DEVICE_ID_3M3266) }, |
738 | 783 | ||
739 | /* ActionStar panels */ | 784 | /* ActionStar panels */ |
740 | { .driver_data = MT_CLS_DEFAULT, | 785 | { .driver_data = MT_CLS_DEFAULT, |
741 | HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, | 786 | MT_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, |
742 | USB_DEVICE_ID_ACTIONSTAR_1011) }, | 787 | USB_DEVICE_ID_ACTIONSTAR_1011) }, |
743 | 788 | ||
744 | /* Atmel panels */ | 789 | /* Atmel panels */ |
745 | { .driver_data = MT_CLS_SERIAL, | 790 | { .driver_data = MT_CLS_SERIAL, |
746 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, | 791 | MT_USB_DEVICE(USB_VENDOR_ID_ATMEL, |
747 | USB_DEVICE_ID_ATMEL_MULTITOUCH) }, | 792 | USB_DEVICE_ID_ATMEL_MULTITOUCH) }, |
748 | { .driver_data = MT_CLS_SERIAL, | 793 | { .driver_data = MT_CLS_SERIAL, |
749 | HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, | 794 | MT_USB_DEVICE(USB_VENDOR_ID_ATMEL, |
750 | USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, | 795 | USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, |
751 | 796 | ||
797 | /* Baanto multitouch devices */ | ||
798 | { .driver_data = MT_CLS_DEFAULT, | ||
799 | MT_USB_DEVICE(USB_VENDOR_ID_BAANTO, | ||
800 | USB_DEVICE_ID_BAANTO_MT_190W2) }, | ||
752 | /* Cando panels */ | 801 | /* Cando panels */ |
753 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 802 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
754 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 803 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
755 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 804 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
756 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 805 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
757 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 806 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
758 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | 807 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, |
759 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 808 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
760 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 809 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
761 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 810 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
762 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 811 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
763 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 812 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
764 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 813 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
765 | 814 | ||
766 | /* Chunghwa Telecom touch panels */ | 815 | /* Chunghwa Telecom touch panels */ |
767 | { .driver_data = MT_CLS_DEFAULT, | 816 | { .driver_data = MT_CLS_DEFAULT, |
768 | HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | 817 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, |
769 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | 818 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, |
770 | 819 | ||
771 | /* CVTouch panels */ | 820 | /* CVTouch panels */ |
772 | { .driver_data = MT_CLS_DEFAULT, | 821 | { .driver_data = MT_CLS_DEFAULT, |
773 | HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | 822 | MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, |
774 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, | 823 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, |
775 | 824 | ||
776 | /* Cypress panel */ | 825 | /* Cypress panel */ |
@@ -780,225 +829,227 @@ static const struct hid_device_id mt_devices[] = { | |||
780 | 829 | ||
781 | /* eGalax devices (resistive) */ | 830 | /* eGalax devices (resistive) */ |
782 | { .driver_data = MT_CLS_EGALAX, | 831 | { .driver_data = MT_CLS_EGALAX, |
783 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 832 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
784 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, | 833 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, |
785 | { .driver_data = MT_CLS_EGALAX, | 834 | { .driver_data = MT_CLS_EGALAX, |
786 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 835 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
787 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, | 836 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, |
788 | 837 | ||
789 | /* eGalax devices (capacitive) */ | 838 | /* eGalax devices (capacitive) */ |
790 | { .driver_data = MT_CLS_EGALAX, | 839 | { .driver_data = MT_CLS_EGALAX, |
791 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 840 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
792 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, | 841 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, |
793 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 842 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
794 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 843 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
795 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, | 844 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, |
796 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 845 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
797 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 846 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
798 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, | 847 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, |
799 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 848 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
800 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 849 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
801 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, | 850 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, |
802 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 851 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
803 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 852 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
804 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, | 853 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, |
805 | { .driver_data = MT_CLS_EGALAX, | 854 | { .driver_data = MT_CLS_EGALAX, |
806 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 855 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
807 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, | 856 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, |
808 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 857 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
809 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 858 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
810 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, | 859 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, |
811 | { .driver_data = MT_CLS_EGALAX, | 860 | { .driver_data = MT_CLS_EGALAX, |
812 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 861 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
813 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, | 862 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, |
814 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 863 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
815 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 864 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
816 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, | 865 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, |
817 | { .driver_data = MT_CLS_EGALAX, | 866 | { .driver_data = MT_CLS_EGALAX, |
818 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 867 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
819 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, | 868 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, |
820 | { .driver_data = MT_CLS_EGALAX, | 869 | { .driver_data = MT_CLS_EGALAX, |
821 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 870 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
822 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, | 871 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, |
823 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 872 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
824 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 873 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
825 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) }, | 874 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) }, |
826 | { .driver_data = MT_CLS_EGALAX_SERIAL, | 875 | { .driver_data = MT_CLS_EGALAX_SERIAL, |
827 | HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 876 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
828 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, | 877 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, |
829 | 878 | ||
830 | /* Elo TouchSystems IntelliTouch Plus panel */ | 879 | /* Elo TouchSystems IntelliTouch Plus panel */ |
831 | { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, | 880 | { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, |
832 | HID_USB_DEVICE(USB_VENDOR_ID_ELO, | 881 | MT_USB_DEVICE(USB_VENDOR_ID_ELO, |
833 | USB_DEVICE_ID_ELO_TS2515) }, | 882 | USB_DEVICE_ID_ELO_TS2515) }, |
834 | 883 | ||
835 | /* GeneralTouch panel */ | 884 | /* GeneralTouch panel */ |
836 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 885 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
837 | HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | 886 | MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, |
838 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, | 887 | USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, |
839 | 888 | ||
840 | /* Gametel game controller */ | 889 | /* Gametel game controller */ |
841 | { .driver_data = MT_CLS_DEFAULT, | 890 | { .driver_data = MT_CLS_DEFAULT, |
842 | HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_FRUCTEL, | 891 | MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL, |
843 | USB_DEVICE_ID_GAMETEL_MT_MODE) }, | 892 | USB_DEVICE_ID_GAMETEL_MT_MODE) }, |
844 | 893 | ||
845 | /* GoodTouch panels */ | 894 | /* GoodTouch panels */ |
846 | { .driver_data = MT_CLS_DEFAULT, | 895 | { .driver_data = MT_CLS_DEFAULT, |
847 | HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, | 896 | MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, |
848 | USB_DEVICE_ID_GOODTOUCH_000f) }, | 897 | USB_DEVICE_ID_GOODTOUCH_000f) }, |
849 | 898 | ||
850 | /* Hanvon panels */ | 899 | /* Hanvon panels */ |
851 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 900 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
852 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, | 901 | MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, |
853 | USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, | 902 | USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, |
854 | 903 | ||
855 | /* Ideacom panel */ | 904 | /* Ideacom panel */ |
856 | { .driver_data = MT_CLS_SERIAL, | 905 | { .driver_data = MT_CLS_SERIAL, |
857 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, | 906 | MT_USB_DEVICE(USB_VENDOR_ID_IDEACOM, |
858 | USB_DEVICE_ID_IDEACOM_IDC6650) }, | 907 | USB_DEVICE_ID_IDEACOM_IDC6650) }, |
859 | { .driver_data = MT_CLS_SERIAL, | 908 | { .driver_data = MT_CLS_SERIAL, |
860 | HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, | 909 | MT_USB_DEVICE(USB_VENDOR_ID_IDEACOM, |
861 | USB_DEVICE_ID_IDEACOM_IDC6651) }, | 910 | USB_DEVICE_ID_IDEACOM_IDC6651) }, |
862 | 911 | ||
863 | /* Ilitek dual touch panel */ | 912 | /* Ilitek dual touch panel */ |
864 | { .driver_data = MT_CLS_DEFAULT, | 913 | { .driver_data = MT_CLS_DEFAULT, |
865 | HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, | 914 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
866 | USB_DEVICE_ID_ILITEK_MULTITOUCH) }, | 915 | USB_DEVICE_ID_ILITEK_MULTITOUCH) }, |
867 | 916 | ||
868 | /* IRTOUCH panels */ | 917 | /* IRTOUCH panels */ |
869 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 918 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
870 | HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, | 919 | MT_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, |
871 | USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, | 920 | USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, |
872 | 921 | ||
873 | /* LG Display panels */ | 922 | /* LG Display panels */ |
874 | { .driver_data = MT_CLS_DEFAULT, | 923 | { .driver_data = MT_CLS_DEFAULT, |
875 | HID_USB_DEVICE(USB_VENDOR_ID_LG, | 924 | MT_USB_DEVICE(USB_VENDOR_ID_LG, |
876 | USB_DEVICE_ID_LG_MULTITOUCH) }, | 925 | USB_DEVICE_ID_LG_MULTITOUCH) }, |
877 | 926 | ||
878 | /* Lumio panels */ | 927 | /* Lumio panels */ |
879 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 928 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
880 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, | 929 | MT_USB_DEVICE(USB_VENDOR_ID_LUMIO, |
881 | USB_DEVICE_ID_CRYSTALTOUCH) }, | 930 | USB_DEVICE_ID_CRYSTALTOUCH) }, |
882 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 931 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
883 | HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, | 932 | MT_USB_DEVICE(USB_VENDOR_ID_LUMIO, |
884 | USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, | 933 | USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, |
885 | 934 | ||
886 | /* MosArt panels */ | 935 | /* MosArt panels */ |
887 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 936 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
888 | HID_USB_DEVICE(USB_VENDOR_ID_ASUS, | 937 | MT_USB_DEVICE(USB_VENDOR_ID_ASUS, |
889 | USB_DEVICE_ID_ASUS_T91MT)}, | 938 | USB_DEVICE_ID_ASUS_T91MT)}, |
890 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 939 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
891 | HID_USB_DEVICE(USB_VENDOR_ID_ASUS, | 940 | MT_USB_DEVICE(USB_VENDOR_ID_ASUS, |
892 | USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | 941 | USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, |
893 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 942 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
894 | HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, | 943 | MT_USB_DEVICE(USB_VENDOR_ID_TURBOX, |
895 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | 944 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, |
896 | 945 | ||
897 | /* Panasonic panels */ | 946 | /* Panasonic panels */ |
898 | { .driver_data = MT_CLS_PANASONIC, | 947 | { .driver_data = MT_CLS_PANASONIC, |
899 | HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | 948 | MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, |
900 | USB_DEVICE_ID_PANABOARD_UBT780) }, | 949 | USB_DEVICE_ID_PANABOARD_UBT780) }, |
901 | { .driver_data = MT_CLS_PANASONIC, | 950 | { .driver_data = MT_CLS_PANASONIC, |
902 | HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | 951 | MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, |
903 | USB_DEVICE_ID_PANABOARD_UBT880) }, | 952 | USB_DEVICE_ID_PANABOARD_UBT880) }, |
904 | 953 | ||
905 | /* PenMount panels */ | 954 | /* PenMount panels */ |
906 | { .driver_data = MT_CLS_CONFIDENCE, | 955 | { .driver_data = MT_CLS_CONFIDENCE, |
907 | HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, | 956 | MT_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, |
908 | USB_DEVICE_ID_PENMOUNT_PCI) }, | 957 | USB_DEVICE_ID_PENMOUNT_PCI) }, |
909 | 958 | ||
910 | /* PixArt optical touch screen */ | 959 | /* PixArt optical touch screen */ |
911 | { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, | 960 | { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, |
912 | HID_USB_DEVICE(USB_VENDOR_ID_PIXART, | 961 | MT_USB_DEVICE(USB_VENDOR_ID_PIXART, |
913 | USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, | 962 | USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, |
914 | { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, | 963 | { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, |
915 | HID_USB_DEVICE(USB_VENDOR_ID_PIXART, | 964 | MT_USB_DEVICE(USB_VENDOR_ID_PIXART, |
916 | USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) }, | 965 | USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) }, |
917 | { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, | 966 | { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, |
918 | HID_USB_DEVICE(USB_VENDOR_ID_PIXART, | 967 | MT_USB_DEVICE(USB_VENDOR_ID_PIXART, |
919 | USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) }, | 968 | USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) }, |
920 | 969 | ||
921 | /* PixCir-based panels */ | 970 | /* PixCir-based panels */ |
922 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 971 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
923 | HID_USB_DEVICE(USB_VENDOR_ID_HANVON, | 972 | MT_USB_DEVICE(USB_VENDOR_ID_HANVON, |
924 | USB_DEVICE_ID_HANVON_MULTITOUCH) }, | 973 | USB_DEVICE_ID_HANVON_MULTITOUCH) }, |
925 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, | 974 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, |
926 | HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 975 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
927 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, | 976 | USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, |
928 | 977 | ||
929 | /* Quanta-based panels */ | 978 | /* Quanta-based panels */ |
930 | { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, | 979 | { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, |
931 | HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, | 980 | MT_USB_DEVICE(USB_VENDOR_ID_QUANTA, |
932 | USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, | 981 | USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, |
933 | { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, | 982 | { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, |
934 | HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, | 983 | MT_USB_DEVICE(USB_VENDOR_ID_QUANTA, |
935 | USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) }, | 984 | USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) }, |
936 | { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, | 985 | { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, |
937 | HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, | 986 | MT_USB_DEVICE(USB_VENDOR_ID_QUANTA, |
938 | USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) }, | 987 | USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) }, |
939 | 988 | ||
940 | /* Stantum panels */ | 989 | /* Stantum panels */ |
941 | { .driver_data = MT_CLS_CONFIDENCE, | 990 | { .driver_data = MT_CLS_CONFIDENCE, |
942 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, | 991 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM, |
943 | USB_DEVICE_ID_MTP)}, | 992 | USB_DEVICE_ID_MTP)}, |
944 | { .driver_data = MT_CLS_CONFIDENCE, | 993 | { .driver_data = MT_CLS_CONFIDENCE, |
945 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, | 994 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, |
946 | USB_DEVICE_ID_MTP_STM)}, | 995 | USB_DEVICE_ID_MTP_STM)}, |
947 | { .driver_data = MT_CLS_CONFIDENCE, | 996 | { .driver_data = MT_CLS_CONFIDENCE, |
948 | HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, | 997 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, |
949 | USB_DEVICE_ID_MTP_SITRONIX)}, | 998 | USB_DEVICE_ID_MTP_SITRONIX)}, |
950 | 999 | ||
951 | /* TopSeed panels */ | 1000 | /* TopSeed panels */ |
952 | { .driver_data = MT_CLS_TOPSEED, | 1001 | { .driver_data = MT_CLS_TOPSEED, |
953 | HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, | 1002 | MT_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, |
954 | USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, | 1003 | USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, |
955 | 1004 | ||
956 | /* Touch International panels */ | 1005 | /* Touch International panels */ |
957 | { .driver_data = MT_CLS_DEFAULT, | 1006 | { .driver_data = MT_CLS_DEFAULT, |
958 | HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, | 1007 | MT_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, |
959 | USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, | 1008 | USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, |
960 | 1009 | ||
961 | /* Unitec panels */ | 1010 | /* Unitec panels */ |
962 | { .driver_data = MT_CLS_DEFAULT, | 1011 | { .driver_data = MT_CLS_DEFAULT, |
963 | HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, | 1012 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, |
964 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, | 1013 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, |
965 | { .driver_data = MT_CLS_DEFAULT, | 1014 | { .driver_data = MT_CLS_DEFAULT, |
966 | HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, | 1015 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, |
967 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | 1016 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, |
968 | /* XAT */ | 1017 | /* XAT */ |
969 | { .driver_data = MT_CLS_DEFAULT, | 1018 | { .driver_data = MT_CLS_DEFAULT, |
970 | HID_USB_DEVICE(USB_VENDOR_ID_XAT, | 1019 | MT_USB_DEVICE(USB_VENDOR_ID_XAT, |
971 | USB_DEVICE_ID_XAT_CSR) }, | 1020 | USB_DEVICE_ID_XAT_CSR) }, |
972 | 1021 | ||
973 | /* Xiroku */ | 1022 | /* Xiroku */ |
974 | { .driver_data = MT_CLS_DEFAULT, | 1023 | { .driver_data = MT_CLS_DEFAULT, |
975 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1024 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
976 | USB_DEVICE_ID_XIROKU_SPX) }, | 1025 | USB_DEVICE_ID_XIROKU_SPX) }, |
977 | { .driver_data = MT_CLS_DEFAULT, | 1026 | { .driver_data = MT_CLS_DEFAULT, |
978 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1027 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
979 | USB_DEVICE_ID_XIROKU_MPX) }, | 1028 | USB_DEVICE_ID_XIROKU_MPX) }, |
980 | { .driver_data = MT_CLS_DEFAULT, | 1029 | { .driver_data = MT_CLS_DEFAULT, |
981 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1030 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
982 | USB_DEVICE_ID_XIROKU_CSR) }, | 1031 | USB_DEVICE_ID_XIROKU_CSR) }, |
983 | { .driver_data = MT_CLS_DEFAULT, | 1032 | { .driver_data = MT_CLS_DEFAULT, |
984 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1033 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
985 | USB_DEVICE_ID_XIROKU_SPX1) }, | 1034 | USB_DEVICE_ID_XIROKU_SPX1) }, |
986 | { .driver_data = MT_CLS_DEFAULT, | 1035 | { .driver_data = MT_CLS_DEFAULT, |
987 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1036 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
988 | USB_DEVICE_ID_XIROKU_MPX1) }, | 1037 | USB_DEVICE_ID_XIROKU_MPX1) }, |
989 | { .driver_data = MT_CLS_DEFAULT, | 1038 | { .driver_data = MT_CLS_DEFAULT, |
990 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1039 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
991 | USB_DEVICE_ID_XIROKU_CSR1) }, | 1040 | USB_DEVICE_ID_XIROKU_CSR1) }, |
992 | { .driver_data = MT_CLS_DEFAULT, | 1041 | { .driver_data = MT_CLS_DEFAULT, |
993 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1042 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
994 | USB_DEVICE_ID_XIROKU_SPX2) }, | 1043 | USB_DEVICE_ID_XIROKU_SPX2) }, |
995 | { .driver_data = MT_CLS_DEFAULT, | 1044 | { .driver_data = MT_CLS_DEFAULT, |
996 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1045 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
997 | USB_DEVICE_ID_XIROKU_MPX2) }, | 1046 | USB_DEVICE_ID_XIROKU_MPX2) }, |
998 | { .driver_data = MT_CLS_DEFAULT, | 1047 | { .driver_data = MT_CLS_DEFAULT, |
999 | HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1048 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
1000 | USB_DEVICE_ID_XIROKU_CSR2) }, | 1049 | USB_DEVICE_ID_XIROKU_CSR2) }, |
1001 | 1050 | ||
1051 | /* Generic MT device */ | ||
1052 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, | ||
1002 | { } | 1053 | { } |
1003 | }; | 1054 | }; |
1004 | MODULE_DEVICE_TABLE(hid, mt_devices); | 1055 | MODULE_DEVICE_TABLE(hid, mt_devices); |
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c index 1f1128910337..3aba02be1f26 100644 --- a/drivers/hid/hid-uclogic.c +++ b/drivers/hid/hid-uclogic.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/hid.h> | 15 | #include <linux/hid.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/usb.h> | ||
17 | 18 | ||
18 | #include "hid-ids.h" | 19 | #include "hid-ids.h" |
19 | 20 | ||
@@ -352,9 +353,125 @@ static __u8 pf1209_rdesc_fixed[] = { | |||
352 | 0xC0 /* End Collection */ | 353 | 0xC0 /* End Collection */ |
353 | }; | 354 | }; |
354 | 355 | ||
356 | /* | ||
357 | * See TWHL850 description, device and HID report descriptors at | ||
358 | * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Wireless_Tablet_TWHL850 | ||
359 | */ | ||
360 | |||
361 | /* Size of the original descriptors of TWHL850 tablet */ | ||
362 | #define TWHL850_RDESC_ORIG_SIZE0 182 | ||
363 | #define TWHL850_RDESC_ORIG_SIZE1 161 | ||
364 | #define TWHL850_RDESC_ORIG_SIZE2 92 | ||
365 | |||
366 | /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */ | ||
367 | static __u8 twhl850_rdesc_fixed0[] = { | ||
368 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
369 | 0x09, 0x02, /* Usage (Pen), */ | ||
370 | 0xA1, 0x01, /* Collection (Application), */ | ||
371 | 0x85, 0x09, /* Report ID (9), */ | ||
372 | 0x09, 0x20, /* Usage (Stylus), */ | ||
373 | 0xA0, /* Collection (Physical), */ | ||
374 | 0x14, /* Logical Minimum (0), */ | ||
375 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
376 | 0x75, 0x01, /* Report Size (1), */ | ||
377 | 0x95, 0x03, /* Report Count (3), */ | ||
378 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
379 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
380 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
381 | 0x81, 0x02, /* Input (Variable), */ | ||
382 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
383 | 0x95, 0x01, /* Report Count (1), */ | ||
384 | 0x09, 0x32, /* Usage (In Range), */ | ||
385 | 0x81, 0x02, /* Input (Variable), */ | ||
386 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
387 | 0x75, 0x10, /* Report Size (16), */ | ||
388 | 0xA4, /* Push, */ | ||
389 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
390 | 0x65, 0x13, /* Unit (Inch), */ | ||
391 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
392 | 0x34, /* Physical Minimum (0), */ | ||
393 | 0x09, 0x30, /* Usage (X), */ | ||
394 | 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ | ||
395 | 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */ | ||
396 | 0x81, 0x02, /* Input (Variable), */ | ||
397 | 0x09, 0x31, /* Usage (Y), */ | ||
398 | 0x46, 0x88, 0x13, /* Physical Maximum (5000), */ | ||
399 | 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ | ||
400 | 0x81, 0x02, /* Input (Variable), */ | ||
401 | 0xB4, /* Pop, */ | ||
402 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
403 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
404 | 0x81, 0x02, /* Input (Variable), */ | ||
405 | 0xC0, /* End Collection, */ | ||
406 | 0xC0 /* End Collection */ | ||
407 | }; | ||
408 | |||
409 | /* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */ | ||
410 | static __u8 twhl850_rdesc_fixed1[] = { | ||
411 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
412 | 0x09, 0x02, /* Usage (Mouse), */ | ||
413 | 0xA1, 0x01, /* Collection (Application), */ | ||
414 | 0x85, 0x01, /* Report ID (1), */ | ||
415 | 0x09, 0x01, /* Usage (Pointer), */ | ||
416 | 0xA0, /* Collection (Physical), */ | ||
417 | 0x05, 0x09, /* Usage Page (Button), */ | ||
418 | 0x75, 0x01, /* Report Size (1), */ | ||
419 | 0x95, 0x03, /* Report Count (3), */ | ||
420 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
421 | 0x29, 0x03, /* Usage Maximum (03h), */ | ||
422 | 0x14, /* Logical Minimum (0), */ | ||
423 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
424 | 0x81, 0x02, /* Input (Variable), */ | ||
425 | 0x95, 0x05, /* Report Count (5), */ | ||
426 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
427 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
428 | 0x09, 0x30, /* Usage (X), */ | ||
429 | 0x09, 0x31, /* Usage (Y), */ | ||
430 | 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ | ||
431 | 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */ | ||
432 | 0x75, 0x10, /* Report Size (16), */ | ||
433 | 0x95, 0x02, /* Report Count (2), */ | ||
434 | 0x81, 0x06, /* Input (Variable, Relative), */ | ||
435 | 0x09, 0x38, /* Usage (Wheel), */ | ||
436 | 0x15, 0xFF, /* Logical Minimum (-1), */ | ||
437 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
438 | 0x95, 0x01, /* Report Count (1), */ | ||
439 | 0x75, 0x08, /* Report Size (8), */ | ||
440 | 0x81, 0x06, /* Input (Variable, Relative), */ | ||
441 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
442 | 0xC0, /* End Collection, */ | ||
443 | 0xC0 /* End Collection */ | ||
444 | }; | ||
445 | |||
446 | /* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */ | ||
447 | static __u8 twhl850_rdesc_fixed2[] = { | ||
448 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
449 | 0x09, 0x06, /* Usage (Keyboard), */ | ||
450 | 0xA1, 0x01, /* Collection (Application), */ | ||
451 | 0x85, 0x03, /* Report ID (3), */ | ||
452 | 0x05, 0x07, /* Usage Page (Keyboard), */ | ||
453 | 0x14, /* Logical Minimum (0), */ | ||
454 | 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */ | ||
455 | 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */ | ||
456 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
457 | 0x75, 0x01, /* Report Size (1), */ | ||
458 | 0x95, 0x08, /* Report Count (8), */ | ||
459 | 0x81, 0x02, /* Input (Variable), */ | ||
460 | 0x18, /* Usage Minimum (None), */ | ||
461 | 0x29, 0xFF, /* Usage Maximum (FFh), */ | ||
462 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
463 | 0x75, 0x08, /* Report Size (8), */ | ||
464 | 0x95, 0x06, /* Report Count (6), */ | ||
465 | 0x80, /* Input, */ | ||
466 | 0xC0 /* End Collection */ | ||
467 | }; | ||
468 | |||
355 | static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 469 | static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
356 | unsigned int *rsize) | 470 | unsigned int *rsize) |
357 | { | 471 | { |
472 | struct usb_interface *iface = to_usb_interface(hdev->dev.parent); | ||
473 | __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; | ||
474 | |||
358 | switch (hdev->product) { | 475 | switch (hdev->product) { |
359 | case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209: | 476 | case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209: |
360 | if (*rsize == PF1209_RDESC_ORIG_SIZE) { | 477 | if (*rsize == PF1209_RDESC_ORIG_SIZE) { |
@@ -386,6 +503,28 @@ static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
386 | *rsize = sizeof(wp1062_rdesc_fixed); | 503 | *rsize = sizeof(wp1062_rdesc_fixed); |
387 | } | 504 | } |
388 | break; | 505 | break; |
506 | case USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850: | ||
507 | switch (iface_num) { | ||
508 | case 0: | ||
509 | if (*rsize == TWHL850_RDESC_ORIG_SIZE0) { | ||
510 | rdesc = twhl850_rdesc_fixed0; | ||
511 | *rsize = sizeof(twhl850_rdesc_fixed0); | ||
512 | } | ||
513 | break; | ||
514 | case 1: | ||
515 | if (*rsize == TWHL850_RDESC_ORIG_SIZE1) { | ||
516 | rdesc = twhl850_rdesc_fixed1; | ||
517 | *rsize = sizeof(twhl850_rdesc_fixed1); | ||
518 | } | ||
519 | break; | ||
520 | case 2: | ||
521 | if (*rsize == TWHL850_RDESC_ORIG_SIZE2) { | ||
522 | rdesc = twhl850_rdesc_fixed2; | ||
523 | *rsize = sizeof(twhl850_rdesc_fixed2); | ||
524 | } | ||
525 | break; | ||
526 | } | ||
527 | break; | ||
389 | } | 528 | } |
390 | 529 | ||
391 | return rdesc; | 530 | return rdesc; |
@@ -402,6 +541,8 @@ static const struct hid_device_id uclogic_devices[] = { | |||
402 | USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, | 541 | USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, |
403 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, | 542 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, |
404 | USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, | 543 | USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, |
544 | { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, | ||
545 | USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) }, | ||
405 | { } | 546 | { } |
406 | }; | 547 | }; |
407 | MODULE_DEVICE_TABLE(hid, uclogic_devices); | 548 | MODULE_DEVICE_TABLE(hid, uclogic_devices); |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 067e2963314c..fe23a1eb586b 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
@@ -24,15 +24,16 @@ | |||
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/hid.h> | 25 | #include <linux/hid.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/leds.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
29 | #include <linux/power_supply.h> | 29 | #include <linux/power_supply.h> |
30 | #endif | ||
31 | 30 | ||
32 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
33 | 32 | ||
34 | #define PAD_DEVICE_ID 0x0F | 33 | #define PAD_DEVICE_ID 0x0F |
35 | 34 | ||
35 | #define WAC_CMD_LED_CONTROL 0x20 | ||
36 | |||
36 | struct wacom_data { | 37 | struct wacom_data { |
37 | __u16 tool; | 38 | __u16 tool; |
38 | __u16 butstate; | 39 | __u16 butstate; |
@@ -41,16 +42,20 @@ struct wacom_data { | |||
41 | __u32 id; | 42 | __u32 id; |
42 | __u32 serial; | 43 | __u32 serial; |
43 | unsigned char high_speed; | 44 | unsigned char high_speed; |
44 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 45 | __u8 battery_capacity; |
45 | int battery_capacity; | 46 | __u8 power_raw; |
47 | __u8 ps_connected; | ||
46 | struct power_supply battery; | 48 | struct power_supply battery; |
47 | struct power_supply ac; | 49 | struct power_supply ac; |
48 | #endif | 50 | __u8 led_selector; |
51 | struct led_classdev *leds[4]; | ||
49 | }; | 52 | }; |
50 | 53 | ||
51 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 54 | /*percent of battery capacity for Graphire |
52 | /*percent of battery capacity, 0 means AC online*/ | 55 | 8th value means AC online and show 100% capacity */ |
53 | static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 }; | 56 | static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 }; |
57 | /*percent of battery capacity for Intuos4 WL, AC has a separate bit*/ | ||
58 | static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 }; | ||
54 | 59 | ||
55 | static enum power_supply_property wacom_battery_props[] = { | 60 | static enum power_supply_property wacom_battery_props[] = { |
56 | POWER_SUPPLY_PROP_PRESENT, | 61 | POWER_SUPPLY_PROP_PRESENT, |
@@ -64,13 +69,123 @@ static enum power_supply_property wacom_ac_props[] = { | |||
64 | POWER_SUPPLY_PROP_SCOPE, | 69 | POWER_SUPPLY_PROP_SCOPE, |
65 | }; | 70 | }; |
66 | 71 | ||
72 | static void wacom_leds_set_brightness(struct led_classdev *led_dev, | ||
73 | enum led_brightness value) | ||
74 | { | ||
75 | struct device *dev = led_dev->dev->parent; | ||
76 | struct hid_device *hdev; | ||
77 | struct wacom_data *wdata; | ||
78 | unsigned char *buf; | ||
79 | __u8 led = 0; | ||
80 | int i; | ||
81 | |||
82 | hdev = container_of(dev, struct hid_device, dev); | ||
83 | wdata = hid_get_drvdata(hdev); | ||
84 | for (i = 0; i < 4; ++i) { | ||
85 | if (wdata->leds[i] == led_dev) | ||
86 | wdata->led_selector = i; | ||
87 | } | ||
88 | |||
89 | led = wdata->led_selector | 0x04; | ||
90 | buf = kzalloc(9, GFP_KERNEL); | ||
91 | if (buf) { | ||
92 | buf[0] = WAC_CMD_LED_CONTROL; | ||
93 | buf[1] = led; | ||
94 | buf[2] = value; | ||
95 | hdev->hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT); | ||
96 | kfree(buf); | ||
97 | } | ||
98 | |||
99 | return; | ||
100 | } | ||
101 | |||
102 | static enum led_brightness wacom_leds_get_brightness(struct led_classdev *led_dev) | ||
103 | { | ||
104 | struct wacom_data *wdata; | ||
105 | struct device *dev = led_dev->dev->parent; | ||
106 | int value = 0; | ||
107 | int i; | ||
108 | |||
109 | wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev)); | ||
110 | |||
111 | for (i = 0; i < 4; ++i) { | ||
112 | if (wdata->leds[i] == led_dev) { | ||
113 | value = wdata->leds[i]->brightness; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | return value; | ||
119 | } | ||
120 | |||
121 | |||
122 | static int wacom_initialize_leds(struct hid_device *hdev) | ||
123 | { | ||
124 | struct wacom_data *wdata = hid_get_drvdata(hdev); | ||
125 | struct led_classdev *led; | ||
126 | struct device *dev = &hdev->dev; | ||
127 | size_t namesz = strlen(dev_name(dev)) + 12; | ||
128 | char *name; | ||
129 | int i, ret; | ||
130 | |||
131 | wdata->led_selector = 0; | ||
132 | |||
133 | for (i = 0; i < 4; i++) { | ||
134 | led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL); | ||
135 | if (!led) { | ||
136 | hid_warn(hdev, | ||
137 | "can't allocate memory for LED selector\n"); | ||
138 | ret = -ENOMEM; | ||
139 | goto err; | ||
140 | } | ||
141 | |||
142 | name = (void *)&led[1]; | ||
143 | snprintf(name, namesz, "%s:selector:%d", dev_name(dev), i); | ||
144 | led->name = name; | ||
145 | led->brightness = 0; | ||
146 | led->max_brightness = 127; | ||
147 | led->brightness_get = wacom_leds_get_brightness; | ||
148 | led->brightness_set = wacom_leds_set_brightness; | ||
149 | |||
150 | wdata->leds[i] = led; | ||
151 | |||
152 | ret = led_classdev_register(dev, wdata->leds[i]); | ||
153 | |||
154 | if (ret) { | ||
155 | wdata->leds[i] = NULL; | ||
156 | kfree(led); | ||
157 | hid_warn(hdev, "can't register LED\n"); | ||
158 | goto err; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | err: | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static void wacom_destroy_leds(struct hid_device *hdev) | ||
167 | { | ||
168 | struct wacom_data *wdata = hid_get_drvdata(hdev); | ||
169 | struct led_classdev *led; | ||
170 | int i; | ||
171 | |||
172 | for (i = 0; i < 4; ++i) { | ||
173 | if (wdata->leds[i]) { | ||
174 | led = wdata->leds[i]; | ||
175 | wdata->leds[i] = NULL; | ||
176 | led_classdev_unregister(led); | ||
177 | kfree(led); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | } | ||
182 | |||
67 | static int wacom_battery_get_property(struct power_supply *psy, | 183 | static int wacom_battery_get_property(struct power_supply *psy, |
68 | enum power_supply_property psp, | 184 | enum power_supply_property psp, |
69 | union power_supply_propval *val) | 185 | union power_supply_propval *val) |
70 | { | 186 | { |
71 | struct wacom_data *wdata = container_of(psy, | 187 | struct wacom_data *wdata = container_of(psy, |
72 | struct wacom_data, battery); | 188 | struct wacom_data, battery); |
73 | int power_state = batcap[wdata->battery_capacity]; | ||
74 | int ret = 0; | 189 | int ret = 0; |
75 | 190 | ||
76 | switch (psp) { | 191 | switch (psp) { |
@@ -81,11 +196,7 @@ static int wacom_battery_get_property(struct power_supply *psy, | |||
81 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | 196 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; |
82 | break; | 197 | break; |
83 | case POWER_SUPPLY_PROP_CAPACITY: | 198 | case POWER_SUPPLY_PROP_CAPACITY: |
84 | /* show 100% battery capacity when charging */ | 199 | val->intval = wdata->battery_capacity; |
85 | if (power_state == 0) | ||
86 | val->intval = 100; | ||
87 | else | ||
88 | val->intval = power_state; | ||
89 | break; | 200 | break; |
90 | default: | 201 | default: |
91 | ret = -EINVAL; | 202 | ret = -EINVAL; |
@@ -99,17 +210,13 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
99 | union power_supply_propval *val) | 210 | union power_supply_propval *val) |
100 | { | 211 | { |
101 | struct wacom_data *wdata = container_of(psy, struct wacom_data, ac); | 212 | struct wacom_data *wdata = container_of(psy, struct wacom_data, ac); |
102 | int power_state = batcap[wdata->battery_capacity]; | ||
103 | int ret = 0; | 213 | int ret = 0; |
104 | 214 | ||
105 | switch (psp) { | 215 | switch (psp) { |
106 | case POWER_SUPPLY_PROP_PRESENT: | 216 | case POWER_SUPPLY_PROP_PRESENT: |
107 | /* fall through */ | 217 | /* fall through */ |
108 | case POWER_SUPPLY_PROP_ONLINE: | 218 | case POWER_SUPPLY_PROP_ONLINE: |
109 | if (power_state == 0) | 219 | val->intval = wdata->ps_connected; |
110 | val->intval = 1; | ||
111 | else | ||
112 | val->intval = 0; | ||
113 | break; | 220 | break; |
114 | case POWER_SUPPLY_PROP_SCOPE: | 221 | case POWER_SUPPLY_PROP_SCOPE: |
115 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; | 222 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; |
@@ -120,41 +227,16 @@ static int wacom_ac_get_property(struct power_supply *psy, | |||
120 | } | 227 | } |
121 | return ret; | 228 | return ret; |
122 | } | 229 | } |
123 | #endif | ||
124 | |||
125 | static void wacom_set_features(struct hid_device *hdev) | ||
126 | { | ||
127 | int ret; | ||
128 | __u8 rep_data[2]; | ||
129 | |||
130 | /*set high speed, tablet mode*/ | ||
131 | rep_data[0] = 0x03; | ||
132 | rep_data[1] = 0x20; | ||
133 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
134 | HID_FEATURE_REPORT); | ||
135 | return; | ||
136 | } | ||
137 | 230 | ||
138 | static void wacom_poke(struct hid_device *hdev, u8 speed) | 231 | static void wacom_set_features(struct hid_device *hdev, u8 speed) |
139 | { | 232 | { |
140 | struct wacom_data *wdata = hid_get_drvdata(hdev); | 233 | struct wacom_data *wdata = hid_get_drvdata(hdev); |
141 | int limit, ret; | 234 | int limit, ret; |
142 | char rep_data[2]; | 235 | __u8 rep_data[2]; |
143 | |||
144 | rep_data[0] = 0x03 ; rep_data[1] = 0x00; | ||
145 | limit = 3; | ||
146 | do { | ||
147 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
148 | HID_FEATURE_REPORT); | ||
149 | } while (ret < 0 && limit-- > 0); | ||
150 | |||
151 | if (ret >= 0) { | ||
152 | if (speed == 0) | ||
153 | rep_data[0] = 0x05; | ||
154 | else | ||
155 | rep_data[0] = 0x06; | ||
156 | 236 | ||
157 | rep_data[1] = 0x00; | 237 | switch (hdev->product) { |
238 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | ||
239 | rep_data[0] = 0x03 ; rep_data[1] = 0x00; | ||
158 | limit = 3; | 240 | limit = 3; |
159 | do { | 241 | do { |
160 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | 242 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, |
@@ -162,17 +244,47 @@ static void wacom_poke(struct hid_device *hdev, u8 speed) | |||
162 | } while (ret < 0 && limit-- > 0); | 244 | } while (ret < 0 && limit-- > 0); |
163 | 245 | ||
164 | if (ret >= 0) { | 246 | if (ret >= 0) { |
165 | wdata->high_speed = speed; | 247 | if (speed == 0) |
166 | return; | 248 | rep_data[0] = 0x05; |
249 | else | ||
250 | rep_data[0] = 0x06; | ||
251 | |||
252 | rep_data[1] = 0x00; | ||
253 | limit = 3; | ||
254 | do { | ||
255 | ret = hdev->hid_output_raw_report(hdev, | ||
256 | rep_data, 2, HID_FEATURE_REPORT); | ||
257 | } while (ret < 0 && limit-- > 0); | ||
258 | |||
259 | if (ret >= 0) { | ||
260 | wdata->high_speed = speed; | ||
261 | return; | ||
262 | } | ||
167 | } | 263 | } |
264 | |||
265 | /* | ||
266 | * Note that if the raw queries fail, it's not a hard failure | ||
267 | * and it is safe to continue | ||
268 | */ | ||
269 | hid_warn(hdev, "failed to poke device, command %d, err %d\n", | ||
270 | rep_data[0], ret); | ||
271 | break; | ||
272 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
273 | if (speed == 1) | ||
274 | wdata->features &= ~0x20; | ||
275 | else | ||
276 | wdata->features |= 0x20; | ||
277 | |||
278 | rep_data[0] = 0x03; | ||
279 | rep_data[1] = wdata->features; | ||
280 | |||
281 | ret = hdev->hid_output_raw_report(hdev, rep_data, 2, | ||
282 | HID_FEATURE_REPORT); | ||
283 | if (ret >= 0) | ||
284 | wdata->high_speed = speed; | ||
285 | break; | ||
168 | } | 286 | } |
169 | 287 | ||
170 | /* | ||
171 | * Note that if the raw queries fail, it's not a hard failure and it | ||
172 | * is safe to continue | ||
173 | */ | ||
174 | hid_warn(hdev, "failed to poke device, command %d, err %d\n", | ||
175 | rep_data[0], ret); | ||
176 | return; | 288 | return; |
177 | } | 289 | } |
178 | 290 | ||
@@ -196,7 +308,7 @@ static ssize_t wacom_store_speed(struct device *dev, | |||
196 | return -EINVAL; | 308 | return -EINVAL; |
197 | 309 | ||
198 | if (new_speed == 0 || new_speed == 1) { | 310 | if (new_speed == 0 || new_speed == 1) { |
199 | wacom_poke(hdev, new_speed); | 311 | wacom_set_features(hdev, new_speed); |
200 | return strnlen(buf, PAGE_SIZE); | 312 | return strnlen(buf, PAGE_SIZE); |
201 | } else | 313 | } else |
202 | return -EINVAL; | 314 | return -EINVAL; |
@@ -310,12 +422,16 @@ static int wacom_gr_parse_report(struct hid_device *hdev, | |||
310 | input_sync(input); | 422 | input_sync(input); |
311 | } | 423 | } |
312 | 424 | ||
313 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | 425 | /* Store current battery capacity and power supply state*/ |
314 | /* Store current battery capacity */ | ||
315 | rw = (data[7] >> 2 & 0x07); | 426 | rw = (data[7] >> 2 & 0x07); |
316 | if (rw != wdata->battery_capacity) | 427 | if (rw != wdata->power_raw) { |
317 | wdata->battery_capacity = rw; | 428 | wdata->power_raw = rw; |
318 | #endif | 429 | wdata->battery_capacity = batcap_gr[rw]; |
430 | if (rw == 7) | ||
431 | wdata->ps_connected = 1; | ||
432 | else | ||
433 | wdata->ps_connected = 0; | ||
434 | } | ||
319 | return 1; | 435 | return 1; |
320 | } | 436 | } |
321 | 437 | ||
@@ -369,6 +485,7 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | |||
369 | { | 485 | { |
370 | __u16 x, y, pressure; | 486 | __u16 x, y, pressure; |
371 | __u8 distance; | 487 | __u8 distance; |
488 | __u8 tilt_x, tilt_y; | ||
372 | 489 | ||
373 | switch (data[1]) { | 490 | switch (data[1]) { |
374 | case 0x80: /* Out of proximity report */ | 491 | case 0x80: /* Out of proximity report */ |
@@ -405,6 +522,8 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | |||
405 | pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | 522 | pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5) |
406 | | (data[1] & 0x01); | 523 | | (data[1] & 0x01); |
407 | distance = (data[9] >> 2) & 0x3f; | 524 | distance = (data[9] >> 2) & 0x3f; |
525 | tilt_x = ((data[7] << 1) & 0x7e) | (data[8] >> 7); | ||
526 | tilt_y = data[8] & 0x7f; | ||
408 | 527 | ||
409 | input_report_key(input, BTN_TOUCH, pressure > 1); | 528 | input_report_key(input, BTN_TOUCH, pressure > 1); |
410 | 529 | ||
@@ -415,6 +534,8 @@ static void wacom_i4_parse_pen_report(struct wacom_data *wdata, | |||
415 | input_report_abs(input, ABS_Y, y); | 534 | input_report_abs(input, ABS_Y, y); |
416 | input_report_abs(input, ABS_PRESSURE, pressure); | 535 | input_report_abs(input, ABS_PRESSURE, pressure); |
417 | input_report_abs(input, ABS_DISTANCE, distance); | 536 | input_report_abs(input, ABS_DISTANCE, distance); |
537 | input_report_abs(input, ABS_TILT_X, tilt_x); | ||
538 | input_report_abs(input, ABS_TILT_Y, tilt_y); | ||
418 | input_report_abs(input, ABS_MISC, wdata->id); | 539 | input_report_abs(input, ABS_MISC, wdata->id); |
419 | input_event(input, EV_MSC, MSC_SERIAL, wdata->serial); | 540 | input_event(input, EV_MSC, MSC_SERIAL, wdata->serial); |
420 | input_report_key(input, wdata->tool, 1); | 541 | input_report_key(input, wdata->tool, 1); |
@@ -455,6 +576,7 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
455 | struct input_dev *input; | 576 | struct input_dev *input; |
456 | unsigned char *data = (unsigned char *) raw_data; | 577 | unsigned char *data = (unsigned char *) raw_data; |
457 | int i; | 578 | int i; |
579 | __u8 power_raw; | ||
458 | 580 | ||
459 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) | 581 | if (!(hdev->claimed & HID_CLAIMED_INPUT)) |
460 | return 0; | 582 | return 0; |
@@ -462,13 +584,15 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
462 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); | 584 | hidinput = list_entry(hdev->inputs.next, struct hid_input, list); |
463 | input = hidinput->input; | 585 | input = hidinput->input; |
464 | 586 | ||
465 | /* Check if this is a tablet report */ | ||
466 | if (data[0] != 0x03) | ||
467 | return 0; | ||
468 | |||
469 | switch (hdev->product) { | 587 | switch (hdev->product) { |
470 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | 588 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: |
471 | return wacom_gr_parse_report(hdev, wdata, input, data); | 589 | if (data[0] == 0x03) { |
590 | return wacom_gr_parse_report(hdev, wdata, input, data); | ||
591 | } else { | ||
592 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", | ||
593 | data[0], data[1], size); | ||
594 | return 0; | ||
595 | } | ||
472 | break; | 596 | break; |
473 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | 597 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: |
474 | i = 1; | 598 | i = 1; |
@@ -482,6 +606,13 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
482 | wacom_i4_parse_report(hdev, wdata, input, data + i); | 606 | wacom_i4_parse_report(hdev, wdata, input, data + i); |
483 | i += 10; | 607 | i += 10; |
484 | wacom_i4_parse_report(hdev, wdata, input, data + i); | 608 | wacom_i4_parse_report(hdev, wdata, input, data + i); |
609 | power_raw = data[i+10]; | ||
610 | if (power_raw != wdata->power_raw) { | ||
611 | wdata->power_raw = power_raw; | ||
612 | wdata->battery_capacity = batcap_i4[power_raw & 0x07]; | ||
613 | wdata->ps_connected = power_raw & 0x08; | ||
614 | } | ||
615 | |||
485 | break; | 616 | break; |
486 | default: | 617 | default: |
487 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", | 618 | hid_err(hdev, "Unknown report: %d,%d size:%d\n", |
@@ -546,6 +677,8 @@ static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
546 | input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); | 677 | input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0); |
547 | input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); | 678 | input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0); |
548 | input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0); | 679 | input_set_abs_params(input, ABS_DISTANCE, 0, 63, 0, 0); |
680 | input_set_abs_params(input, ABS_TILT_X, 0, 127, 0, 0); | ||
681 | input_set_abs_params(input, ABS_TILT_Y, 0, 127, 0, 0); | ||
549 | break; | 682 | break; |
550 | } | 683 | } |
551 | 684 | ||
@@ -584,19 +717,19 @@ static int wacom_probe(struct hid_device *hdev, | |||
584 | hid_warn(hdev, | 717 | hid_warn(hdev, |
585 | "can't create sysfs speed attribute err: %d\n", ret); | 718 | "can't create sysfs speed attribute err: %d\n", ret); |
586 | 719 | ||
587 | switch (hdev->product) { | 720 | wdata->features = 0; |
588 | case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH: | 721 | wacom_set_features(hdev, 1); |
589 | /* Set Wacom mode 2 with high reporting speed */ | 722 | |
590 | wacom_poke(hdev, 1); | 723 | if (hdev->product == USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) { |
591 | break; | ||
592 | case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH: | ||
593 | sprintf(hdev->name, "%s", "Wacom Intuos4 WL"); | 724 | sprintf(hdev->name, "%s", "Wacom Intuos4 WL"); |
594 | wdata->features = 0; | 725 | ret = wacom_initialize_leds(hdev); |
595 | wacom_set_features(hdev); | 726 | if (ret) { |
596 | break; | 727 | hid_warn(hdev, |
728 | "can't create led attribute, err: %d\n", ret); | ||
729 | goto destroy_leds; | ||
730 | } | ||
597 | } | 731 | } |
598 | 732 | ||
599 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
600 | wdata->battery.properties = wacom_battery_props; | 733 | wdata->battery.properties = wacom_battery_props; |
601 | wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props); | 734 | wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props); |
602 | wdata->battery.get_property = wacom_battery_get_property; | 735 | wdata->battery.get_property = wacom_battery_get_property; |
@@ -629,16 +762,15 @@ static int wacom_probe(struct hid_device *hdev, | |||
629 | } | 762 | } |
630 | 763 | ||
631 | power_supply_powers(&wdata->ac, &hdev->dev); | 764 | power_supply_powers(&wdata->ac, &hdev->dev); |
632 | #endif | ||
633 | return 0; | 765 | return 0; |
634 | 766 | ||
635 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
636 | err_ac: | 767 | err_ac: |
637 | power_supply_unregister(&wdata->battery); | 768 | power_supply_unregister(&wdata->battery); |
638 | err_battery: | 769 | err_battery: |
639 | device_remove_file(&hdev->dev, &dev_attr_speed); | 770 | device_remove_file(&hdev->dev, &dev_attr_speed); |
640 | hid_hw_stop(hdev); | 771 | hid_hw_stop(hdev); |
641 | #endif | 772 | destroy_leds: |
773 | wacom_destroy_leds(hdev); | ||
642 | err_free: | 774 | err_free: |
643 | kfree(wdata); | 775 | kfree(wdata); |
644 | return ret; | 776 | return ret; |
@@ -646,16 +778,14 @@ err_free: | |||
646 | 778 | ||
647 | static void wacom_remove(struct hid_device *hdev) | 779 | static void wacom_remove(struct hid_device *hdev) |
648 | { | 780 | { |
649 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
650 | struct wacom_data *wdata = hid_get_drvdata(hdev); | 781 | struct wacom_data *wdata = hid_get_drvdata(hdev); |
651 | #endif | 782 | |
783 | wacom_destroy_leds(hdev); | ||
652 | device_remove_file(&hdev->dev, &dev_attr_speed); | 784 | device_remove_file(&hdev->dev, &dev_attr_speed); |
653 | hid_hw_stop(hdev); | 785 | hid_hw_stop(hdev); |
654 | 786 | ||
655 | #ifdef CONFIG_HID_WACOM_POWER_SUPPLY | ||
656 | power_supply_unregister(&wdata->battery); | 787 | power_supply_unregister(&wdata->battery); |
657 | power_supply_unregister(&wdata->ac); | 788 | power_supply_unregister(&wdata->ac); |
658 | #endif | ||
659 | kfree(hid_get_drvdata(hdev)); | 789 | kfree(hid_get_drvdata(hdev)); |
660 | } | 790 | } |
661 | 791 | ||
@@ -693,5 +823,5 @@ static void __exit wacom_exit(void) | |||
693 | 823 | ||
694 | module_init(wacom_init); | 824 | module_init(wacom_init); |
695 | module_exit(wacom_exit); | 825 | module_exit(wacom_exit); |
826 | MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); | ||
696 | MODULE_LICENSE("GPL"); | 827 | MODULE_LICENSE("GPL"); |
697 | |||
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c index 2cfd95c4467b..745e4e9a8cf2 100644 --- a/drivers/hid/hid-waltop.c +++ b/drivers/hid/hid-waltop.c | |||
@@ -502,28 +502,146 @@ static __u8 media_tablet_14_1_inch_rdesc_fixed[] = { | |||
502 | 0xC0 /* End Collection */ | 502 | 0xC0 /* End Collection */ |
503 | }; | 503 | }; |
504 | 504 | ||
505 | struct waltop_state { | 505 | /* |
506 | u8 pressure0; | 506 | * See Sirius Battery Free Tablet description, device and HID report descriptors |
507 | u8 pressure1; | 507 | * at |
508 | * http://sf.net/apps/mediawiki/digimend/?title=Waltop_Sirius_Battery_Free_Tablet | ||
509 | */ | ||
510 | |||
511 | /* Size of the original report descriptor of Sirius Battery Free Tablet */ | ||
512 | #define SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE 335 | ||
513 | |||
514 | /* Fixed Sirius Battery Free Tablet descriptor */ | ||
515 | static __u8 sirius_battery_free_tablet_rdesc_fixed[] = { | ||
516 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
517 | 0x09, 0x02, /* Usage (Pen), */ | ||
518 | 0xA1, 0x01, /* Collection (Application), */ | ||
519 | 0x85, 0x10, /* Report ID (16), */ | ||
520 | 0x09, 0x20, /* Usage (Stylus), */ | ||
521 | 0xA0, /* Collection (Physical), */ | ||
522 | 0x95, 0x01, /* Report Count (1), */ | ||
523 | 0x15, 0x01, /* Logical Minimum (1), */ | ||
524 | 0x25, 0x03, /* Logical Maximum (3), */ | ||
525 | 0x75, 0x02, /* Report Size (2), */ | ||
526 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
527 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
528 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
529 | 0x80, /* Input, */ | ||
530 | 0x14, /* Logical Minimum (0), */ | ||
531 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
532 | 0x75, 0x01, /* Report Size (1), */ | ||
533 | 0x09, 0x3C, /* Usage (Invert), */ | ||
534 | 0x81, 0x02, /* Input (Variable), */ | ||
535 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
536 | 0x09, 0x32, /* Usage (In Range), */ | ||
537 | 0x81, 0x02, /* Input (Variable), */ | ||
538 | 0x95, 0x03, /* Report Count (3), */ | ||
539 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
540 | 0xA4, /* Push, */ | ||
541 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
542 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
543 | 0x65, 0x13, /* Unit (Inch), */ | ||
544 | 0x34, /* Physical Minimum (0), */ | ||
545 | 0x14, /* Logical Minimum (0), */ | ||
546 | 0x75, 0x10, /* Report Size (16), */ | ||
547 | 0x95, 0x01, /* Report Count (1), */ | ||
548 | 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ | ||
549 | 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */ | ||
550 | 0x09, 0x30, /* Usage (X), */ | ||
551 | 0x81, 0x02, /* Input (Variable), */ | ||
552 | 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ | ||
553 | 0x26, 0xE0, 0x2E, /* Logical Maximum (12000), */ | ||
554 | 0x09, 0x31, /* Usage (Y), */ | ||
555 | 0x81, 0x02, /* Input (Variable), */ | ||
556 | 0xB4, /* Pop, */ | ||
557 | 0x75, 0x10, /* Report Size (16), */ | ||
558 | 0x95, 0x01, /* Report Count (1), */ | ||
559 | 0x14, /* Logical Minimum (0), */ | ||
560 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
561 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
562 | 0x81, 0x02, /* Input (Variable), */ | ||
563 | 0xA4, /* Push, */ | ||
564 | 0x55, 0xFE, /* Unit Exponent (-2), */ | ||
565 | 0x65, 0x12, /* Unit (Radians), */ | ||
566 | 0x35, 0x97, /* Physical Minimum (-105), */ | ||
567 | 0x45, 0x69, /* Physical Maximum (105), */ | ||
568 | 0x15, 0x97, /* Logical Minimum (-105), */ | ||
569 | 0x25, 0x69, /* Logical Maximum (105), */ | ||
570 | 0x75, 0x08, /* Report Size (8), */ | ||
571 | 0x95, 0x02, /* Report Count (2), */ | ||
572 | 0x09, 0x3D, /* Usage (X Tilt), */ | ||
573 | 0x09, 0x3E, /* Usage (Y Tilt), */ | ||
574 | 0x81, 0x02, /* Input (Variable), */ | ||
575 | 0xB4, /* Pop, */ | ||
576 | 0xC0, /* End Collection, */ | ||
577 | 0xC0, /* End Collection, */ | ||
578 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
579 | 0x09, 0x02, /* Usage (Mouse), */ | ||
580 | 0xA1, 0x01, /* Collection (Application), */ | ||
581 | 0x85, 0x01, /* Report ID (1), */ | ||
582 | 0x09, 0x01, /* Usage (Pointer), */ | ||
583 | 0xA0, /* Collection (Physical), */ | ||
584 | 0x75, 0x08, /* Report Size (8), */ | ||
585 | 0x95, 0x03, /* Report Count (3), */ | ||
586 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
587 | 0x09, 0x38, /* Usage (Wheel), */ | ||
588 | 0x15, 0xFF, /* Logical Minimum (-1), */ | ||
589 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
590 | 0x75, 0x08, /* Report Size (8), */ | ||
591 | 0x95, 0x01, /* Report Count (1), */ | ||
592 | 0x81, 0x06, /* Input (Variable, Relative), */ | ||
593 | 0x75, 0x08, /* Report Size (8), */ | ||
594 | 0x95, 0x03, /* Report Count (3), */ | ||
595 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
596 | 0xC0, /* End Collection, */ | ||
597 | 0xC0, /* End Collection, */ | ||
598 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
599 | 0x09, 0x06, /* Usage (Keyboard), */ | ||
600 | 0xA1, 0x01, /* Collection (Application), */ | ||
601 | 0x85, 0x0D, /* Report ID (13), */ | ||
602 | 0x05, 0x07, /* Usage Page (Keyboard), */ | ||
603 | 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */ | ||
604 | 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */ | ||
605 | 0x14, /* Logical Minimum (0), */ | ||
606 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
607 | 0x75, 0x01, /* Report Size (1), */ | ||
608 | 0x95, 0x08, /* Report Count (8), */ | ||
609 | 0x81, 0x02, /* Input (Variable), */ | ||
610 | 0x75, 0x08, /* Report Size (8), */ | ||
611 | 0x95, 0x01, /* Report Count (1), */ | ||
612 | 0x81, 0x01, /* Input (Constant), */ | ||
613 | 0x18, /* Usage Minimum (None), */ | ||
614 | 0x29, 0x65, /* Usage Maximum (KB Application), */ | ||
615 | 0x14, /* Logical Minimum (0), */ | ||
616 | 0x25, 0x65, /* Logical Maximum (101), */ | ||
617 | 0x75, 0x08, /* Report Size (8), */ | ||
618 | 0x95, 0x05, /* Report Count (5), */ | ||
619 | 0x80, /* Input, */ | ||
620 | 0xC0, /* End Collection, */ | ||
621 | 0x05, 0x0C, /* Usage Page (Consumer), */ | ||
622 | 0x09, 0x01, /* Usage (Consumer Control), */ | ||
623 | 0xA1, 0x01, /* Collection (Application), */ | ||
624 | 0x85, 0x0C, /* Report ID (12), */ | ||
625 | 0x09, 0xE9, /* Usage (Volume Inc), */ | ||
626 | 0x09, 0xEA, /* Usage (Volume Dec), */ | ||
627 | 0x14, /* Logical Minimum (0), */ | ||
628 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
629 | 0x75, 0x01, /* Report Size (1), */ | ||
630 | 0x95, 0x02, /* Report Count (2), */ | ||
631 | 0x81, 0x02, /* Input (Variable), */ | ||
632 | 0x75, 0x06, /* Report Size (6), */ | ||
633 | 0x95, 0x01, /* Report Count (1), */ | ||
634 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
635 | 0x75, 0x10, /* Report Size (16), */ | ||
636 | 0x95, 0x03, /* Report Count (3), */ | ||
637 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
638 | 0xC0 /* End Collection */ | ||
508 | }; | 639 | }; |
509 | 640 | ||
510 | static int waltop_probe(struct hid_device *hdev, | 641 | static int waltop_probe(struct hid_device *hdev, |
511 | const struct hid_device_id *id) | 642 | const struct hid_device_id *id) |
512 | { | 643 | { |
513 | int ret; | 644 | int ret; |
514 | struct waltop_state *s; | ||
515 | |||
516 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
517 | if (s == NULL) { | ||
518 | hid_err(hdev, "can't allocate device state\n"); | ||
519 | ret = -ENOMEM; | ||
520 | goto err; | ||
521 | } | ||
522 | |||
523 | s->pressure0 = 0; | ||
524 | s->pressure1 = 0; | ||
525 | |||
526 | hid_set_drvdata(hdev, s); | ||
527 | 645 | ||
528 | ret = hid_parse(hdev); | 646 | ret = hid_parse(hdev); |
529 | if (ret) { | 647 | if (ret) { |
@@ -539,7 +657,6 @@ static int waltop_probe(struct hid_device *hdev, | |||
539 | 657 | ||
540 | return 0; | 658 | return 0; |
541 | err: | 659 | err: |
542 | kfree(s); | ||
543 | return ret; | 660 | return ret; |
544 | } | 661 | } |
545 | 662 | ||
@@ -583,6 +700,12 @@ static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
583 | *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed); | 700 | *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed); |
584 | } | 701 | } |
585 | break; | 702 | break; |
703 | case USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET: | ||
704 | if (*rsize == SIRIUS_BATTERY_FREE_TABLET_RDESC_ORIG_SIZE) { | ||
705 | rdesc = sirius_battery_free_tablet_rdesc_fixed; | ||
706 | *rsize = sizeof(sirius_battery_free_tablet_rdesc_fixed); | ||
707 | } | ||
708 | break; | ||
586 | } | 709 | } |
587 | return rdesc; | 710 | return rdesc; |
588 | } | 711 | } |
@@ -590,39 +713,72 @@ static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
590 | static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report, | 713 | static int waltop_raw_event(struct hid_device *hdev, struct hid_report *report, |
591 | u8 *data, int size) | 714 | u8 *data, int size) |
592 | { | 715 | { |
593 | /* If this is a pen input report of a tablet with PID 0038 */ | 716 | /* If this is a pen input report */ |
594 | if (hdev->product == USB_DEVICE_ID_WALTOP_PID_0038 && | 717 | if (report->type == HID_INPUT_REPORT && report->id == 16 && size >= 8) { |
595 | report->type == HID_INPUT_REPORT && | ||
596 | report->id == 16 && | ||
597 | size == 8) { | ||
598 | struct waltop_state *s = hid_get_drvdata(hdev); | ||
599 | |||
600 | /* | 718 | /* |
601 | * Ignore maximum pressure reported when a barrel button is | 719 | * Ignore reported pressure when a barrel button is pressed, |
602 | * pressed. | 720 | * because it is rarely correct. |
603 | */ | 721 | */ |
604 | 722 | ||
605 | /* If a barrel button is pressed */ | 723 | /* If a barrel button is pressed */ |
606 | if ((data[1] & 0xF) > 1) { | 724 | if ((data[1] & 0xF) > 1) { |
607 | /* Use the last known pressure */ | 725 | /* Report zero pressure */ |
608 | data[6] = s->pressure0; | 726 | data[6] = 0; |
609 | data[7] = s->pressure1; | 727 | data[7] = 0; |
610 | } else { | ||
611 | /* Remember reported pressure */ | ||
612 | s->pressure0 = data[6]; | ||
613 | s->pressure1 = data[7]; | ||
614 | } | 728 | } |
615 | } | 729 | } |
616 | 730 | ||
731 | /* If this is a pen input report of Sirius Battery Free Tablet */ | ||
732 | if (hdev->product == USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET && | ||
733 | report->type == HID_INPUT_REPORT && | ||
734 | report->id == 16 && | ||
735 | size == 10) { | ||
736 | /* | ||
737 | * The tablet reports tilt as roughly sin(a)*21 (18 means 60 | ||
738 | * degrees). | ||
739 | * | ||
740 | * This array stores angles as radians * 100, corresponding to | ||
741 | * reported values up to 60 degrees, as expected by userspace. | ||
742 | */ | ||
743 | static const s8 tilt_to_radians[] = { | ||
744 | 0, 5, 10, 14, 19, 24, 29, 34, 40, 45, | ||
745 | 50, 56, 62, 68, 74, 81, 88, 96, 105 | ||
746 | }; | ||
747 | |||
748 | s8 tilt_x = (s8)data[8]; | ||
749 | s8 tilt_y = (s8)data[9]; | ||
750 | s8 sign_x = tilt_x >= 0 ? 1 : -1; | ||
751 | s8 sign_y = tilt_y >= 0 ? 1 : -1; | ||
752 | |||
753 | tilt_x *= sign_x; | ||
754 | tilt_y *= sign_y; | ||
755 | |||
756 | /* | ||
757 | * Reverse the Y Tilt direction to match the HID standard and | ||
758 | * userspace expectations. See HID Usage Tables v1.12 16.3.2 | ||
759 | * Tilt Orientation. | ||
760 | */ | ||
761 | sign_y *= -1; | ||
762 | |||
763 | /* | ||
764 | * This effectively clamps reported tilt to 60 degrees - the | ||
765 | * range expected by userspace | ||
766 | */ | ||
767 | if (tilt_x > ARRAY_SIZE(tilt_to_radians) - 1) | ||
768 | tilt_x = ARRAY_SIZE(tilt_to_radians) - 1; | ||
769 | if (tilt_y > ARRAY_SIZE(tilt_to_radians) - 1) | ||
770 | tilt_y = ARRAY_SIZE(tilt_to_radians) - 1; | ||
771 | |||
772 | data[8] = tilt_to_radians[tilt_x] * sign_x; | ||
773 | data[9] = tilt_to_radians[tilt_y] * sign_y; | ||
774 | } | ||
775 | |||
617 | return 0; | 776 | return 0; |
618 | } | 777 | } |
619 | 778 | ||
620 | static void waltop_remove(struct hid_device *hdev) | 779 | static void waltop_remove(struct hid_device *hdev) |
621 | { | 780 | { |
622 | struct waltop_state *s = hid_get_drvdata(hdev); | ||
623 | |||
624 | hid_hw_stop(hdev); | 781 | hid_hw_stop(hdev); |
625 | kfree(s); | ||
626 | } | 782 | } |
627 | 783 | ||
628 | static const struct hid_device_id waltop_devices[] = { | 784 | static const struct hid_device_id waltop_devices[] = { |
@@ -638,6 +794,8 @@ static const struct hid_device_id waltop_devices[] = { | |||
638 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, | 794 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, |
639 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, | 795 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, |
640 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, | 796 | USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, |
797 | { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, | ||
798 | USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET) }, | ||
641 | { } | 799 | { } |
642 | }; | 800 | }; |
643 | MODULE_DEVICE_TABLE(hid, waltop_devices); | 801 | MODULE_DEVICE_TABLE(hid, waltop_devices); |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index cf7d6d58e79f..36fa77b40ffb 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -87,11 +87,13 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, | |||
87 | len = list->buffer[list->tail].len > count ? | 87 | len = list->buffer[list->tail].len > count ? |
88 | count : list->buffer[list->tail].len; | 88 | count : list->buffer[list->tail].len; |
89 | 89 | ||
90 | if (copy_to_user(buffer, list->buffer[list->tail].value, len)) { | 90 | if (list->buffer[list->tail].value) { |
91 | ret = -EFAULT; | 91 | if (copy_to_user(buffer, list->buffer[list->tail].value, len)) { |
92 | goto out; | 92 | ret = -EFAULT; |
93 | goto out; | ||
94 | } | ||
95 | ret = len; | ||
93 | } | 96 | } |
94 | ret = len; | ||
95 | 97 | ||
96 | kfree(list->buffer[list->tail].value); | 98 | kfree(list->buffer[list->tail].value); |
97 | list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); | 99 | list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); |
@@ -437,19 +439,24 @@ static const struct file_operations hidraw_ops = { | |||
437 | .llseek = noop_llseek, | 439 | .llseek = noop_llseek, |
438 | }; | 440 | }; |
439 | 441 | ||
440 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) | 442 | int hidraw_report_event(struct hid_device *hid, u8 *data, int len) |
441 | { | 443 | { |
442 | struct hidraw *dev = hid->hidraw; | 444 | struct hidraw *dev = hid->hidraw; |
443 | struct hidraw_list *list; | 445 | struct hidraw_list *list; |
446 | int ret = 0; | ||
444 | 447 | ||
445 | list_for_each_entry(list, &dev->list, node) { | 448 | list_for_each_entry(list, &dev->list, node) { |
446 | list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC); | 449 | if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) { |
450 | ret = -ENOMEM; | ||
451 | break; | ||
452 | } | ||
447 | list->buffer[list->head].len = len; | 453 | list->buffer[list->head].len = len; |
448 | list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1); | 454 | list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1); |
449 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 455 | kill_fasync(&list->fasync, SIGIO, POLL_IN); |
450 | } | 456 | } |
451 | 457 | ||
452 | wake_up_interruptible(&dev->wait); | 458 | wake_up_interruptible(&dev->wait); |
459 | return ret; | ||
453 | } | 460 | } |
454 | EXPORT_SYMBOL_GPL(hidraw_report_event); | 461 | EXPORT_SYMBOL_GPL(hidraw_report_event); |
455 | 462 | ||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 5bf91dbad59d..df3789f5d9a5 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/wait.h> | 29 | #include <linux/wait.h> |
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/string.h> | ||
31 | 32 | ||
32 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
33 | 34 | ||
@@ -86,8 +87,13 @@ static int hid_start_in(struct hid_device *hid) | |||
86 | !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && | 87 | !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && |
87 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { | 88 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { |
88 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); | 89 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); |
89 | if (rc != 0) | 90 | if (rc != 0) { |
90 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 91 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
92 | if (rc == -ENOSPC) | ||
93 | set_bit(HID_NO_BANDWIDTH, &usbhid->iofl); | ||
94 | } else { | ||
95 | clear_bit(HID_NO_BANDWIDTH, &usbhid->iofl); | ||
96 | } | ||
91 | } | 97 | } |
92 | spin_unlock_irqrestore(&usbhid->lock, flags); | 98 | spin_unlock_irqrestore(&usbhid->lock, flags); |
93 | return rc; | 99 | return rc; |
@@ -173,8 +179,10 @@ static void hid_io_error(struct hid_device *hid) | |||
173 | 179 | ||
174 | if (time_after(jiffies, usbhid->stop_retry)) { | 180 | if (time_after(jiffies, usbhid->stop_retry)) { |
175 | 181 | ||
176 | /* Retries failed, so do a port reset */ | 182 | /* Retries failed, so do a port reset unless we lack bandwidth*/ |
177 | if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { | 183 | if (test_bit(HID_NO_BANDWIDTH, &usbhid->iofl) |
184 | && !test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { | ||
185 | |||
178 | schedule_work(&usbhid->reset_work); | 186 | schedule_work(&usbhid->reset_work); |
179 | goto done; | 187 | goto done; |
180 | } | 188 | } |
@@ -700,7 +708,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | |||
700 | int usbhid_open(struct hid_device *hid) | 708 | int usbhid_open(struct hid_device *hid) |
701 | { | 709 | { |
702 | struct usbhid_device *usbhid = hid->driver_data; | 710 | struct usbhid_device *usbhid = hid->driver_data; |
703 | int res; | 711 | int res = 0; |
704 | 712 | ||
705 | mutex_lock(&hid_open_mut); | 713 | mutex_lock(&hid_open_mut); |
706 | if (!hid->open++) { | 714 | if (!hid->open++) { |
@@ -708,17 +716,27 @@ int usbhid_open(struct hid_device *hid) | |||
708 | /* the device must be awake to reliably request remote wakeup */ | 716 | /* the device must be awake to reliably request remote wakeup */ |
709 | if (res < 0) { | 717 | if (res < 0) { |
710 | hid->open--; | 718 | hid->open--; |
711 | mutex_unlock(&hid_open_mut); | 719 | res = -EIO; |
712 | return -EIO; | 720 | goto done; |
713 | } | 721 | } |
714 | usbhid->intf->needs_remote_wakeup = 1; | 722 | usbhid->intf->needs_remote_wakeup = 1; |
715 | if (hid_start_in(hid)) | 723 | res = hid_start_in(hid); |
716 | hid_io_error(hid); | 724 | if (res) { |
717 | 725 | if (res != -ENOSPC) { | |
726 | hid_io_error(hid); | ||
727 | res = 0; | ||
728 | } else { | ||
729 | /* no use opening if resources are insufficient */ | ||
730 | hid->open--; | ||
731 | res = -EBUSY; | ||
732 | usbhid->intf->needs_remote_wakeup = 0; | ||
733 | } | ||
734 | } | ||
718 | usb_autopm_put_interface(usbhid->intf); | 735 | usb_autopm_put_interface(usbhid->intf); |
719 | } | 736 | } |
737 | done: | ||
720 | mutex_unlock(&hid_open_mut); | 738 | mutex_unlock(&hid_open_mut); |
721 | return 0; | 739 | return res; |
722 | } | 740 | } |
723 | 741 | ||
724 | void usbhid_close(struct hid_device *hid) | 742 | void usbhid_close(struct hid_device *hid) |
@@ -1347,7 +1365,34 @@ static int hid_post_reset(struct usb_interface *intf) | |||
1347 | struct usb_device *dev = interface_to_usbdev (intf); | 1365 | struct usb_device *dev = interface_to_usbdev (intf); |
1348 | struct hid_device *hid = usb_get_intfdata(intf); | 1366 | struct hid_device *hid = usb_get_intfdata(intf); |
1349 | struct usbhid_device *usbhid = hid->driver_data; | 1367 | struct usbhid_device *usbhid = hid->driver_data; |
1368 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
1350 | int status; | 1369 | int status; |
1370 | char *rdesc; | ||
1371 | |||
1372 | /* Fetch and examine the HID report descriptor. If this | ||
1373 | * has changed, then rebind. Since usbcore's check of the | ||
1374 | * configuration descriptors passed, we already know that | ||
1375 | * the size of the HID report descriptor has not changed. | ||
1376 | */ | ||
1377 | rdesc = kmalloc(hid->rsize, GFP_KERNEL); | ||
1378 | if (!rdesc) { | ||
1379 | dbg_hid("couldn't allocate rdesc memory (post_reset)\n"); | ||
1380 | return 1; | ||
1381 | } | ||
1382 | status = hid_get_class_descriptor(dev, | ||
1383 | interface->desc.bInterfaceNumber, | ||
1384 | HID_DT_REPORT, rdesc, hid->rsize); | ||
1385 | if (status < 0) { | ||
1386 | dbg_hid("reading report descriptor failed (post_reset)\n"); | ||
1387 | kfree(rdesc); | ||
1388 | return 1; | ||
1389 | } | ||
1390 | status = memcmp(rdesc, hid->rdesc, hid->rsize); | ||
1391 | kfree(rdesc); | ||
1392 | if (status != 0) { | ||
1393 | dbg_hid("report descriptor changed\n"); | ||
1394 | return 1; | ||
1395 | } | ||
1351 | 1396 | ||
1352 | spin_lock_irq(&usbhid->lock); | 1397 | spin_lock_irq(&usbhid->lock); |
1353 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | 1398 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
@@ -1504,28 +1549,15 @@ static struct usb_driver hid_driver = { | |||
1504 | .supports_autosuspend = 1, | 1549 | .supports_autosuspend = 1, |
1505 | }; | 1550 | }; |
1506 | 1551 | ||
1507 | static const struct hid_device_id hid_usb_table[] = { | ||
1508 | { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, | ||
1509 | { } | ||
1510 | }; | ||
1511 | |||
1512 | struct usb_interface *usbhid_find_interface(int minor) | 1552 | struct usb_interface *usbhid_find_interface(int minor) |
1513 | { | 1553 | { |
1514 | return usb_find_interface(&hid_driver, minor); | 1554 | return usb_find_interface(&hid_driver, minor); |
1515 | } | 1555 | } |
1516 | 1556 | ||
1517 | static struct hid_driver hid_usb_driver = { | ||
1518 | .name = "generic-usb", | ||
1519 | .id_table = hid_usb_table, | ||
1520 | }; | ||
1521 | |||
1522 | static int __init hid_init(void) | 1557 | static int __init hid_init(void) |
1523 | { | 1558 | { |
1524 | int retval = -ENOMEM; | 1559 | int retval = -ENOMEM; |
1525 | 1560 | ||
1526 | retval = hid_register_driver(&hid_usb_driver); | ||
1527 | if (retval) | ||
1528 | goto hid_register_fail; | ||
1529 | retval = usbhid_quirks_init(quirks_param); | 1561 | retval = usbhid_quirks_init(quirks_param); |
1530 | if (retval) | 1562 | if (retval) |
1531 | goto usbhid_quirks_init_fail; | 1563 | goto usbhid_quirks_init_fail; |
@@ -1538,8 +1570,6 @@ static int __init hid_init(void) | |||
1538 | usb_register_fail: | 1570 | usb_register_fail: |
1539 | usbhid_quirks_exit(); | 1571 | usbhid_quirks_exit(); |
1540 | usbhid_quirks_init_fail: | 1572 | usbhid_quirks_init_fail: |
1541 | hid_unregister_driver(&hid_usb_driver); | ||
1542 | hid_register_fail: | ||
1543 | return retval; | 1573 | return retval; |
1544 | } | 1574 | } |
1545 | 1575 | ||
@@ -1547,7 +1577,6 @@ static void __exit hid_exit(void) | |||
1547 | { | 1577 | { |
1548 | usb_deregister(&hid_driver); | 1578 | usb_deregister(&hid_driver); |
1549 | usbhid_quirks_exit(); | 1579 | usbhid_quirks_exit(); |
1550 | hid_unregister_driver(&hid_usb_driver); | ||
1551 | } | 1580 | } |
1552 | 1581 | ||
1553 | module_init(hid_init); | 1582 | module_init(hid_init); |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 782c63955f29..0597ee604f6e 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -88,6 +88,7 @@ static const struct hid_blacklist { | |||
88 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, | 88 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, |
89 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, | 89 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, |
90 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, | 90 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, |
91 | { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT }, | ||
91 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 92 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
92 | 93 | ||
93 | { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 94 | { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index b1ec0e2aeb57..14599e256791 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/hid.h> | 34 | #include <linux/hid.h> |
35 | #include <linux/hiddev.h> | 35 | #include <linux/hiddev.h> |
36 | #include <linux/compat.h> | 36 | #include <linux/compat.h> |
37 | #include <linux/vmalloc.h> | ||
37 | #include "usbhid.h" | 38 | #include "usbhid.h" |
38 | 39 | ||
39 | #ifdef CONFIG_USB_DYNAMIC_MINORS | 40 | #ifdef CONFIG_USB_DYNAMIC_MINORS |
@@ -250,13 +251,13 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
250 | } else { | 251 | } else { |
251 | mutex_unlock(&list->hiddev->existancelock); | 252 | mutex_unlock(&list->hiddev->existancelock); |
252 | kfree(list->hiddev); | 253 | kfree(list->hiddev); |
253 | kfree(list); | 254 | vfree(list); |
254 | return 0; | 255 | return 0; |
255 | } | 256 | } |
256 | } | 257 | } |
257 | 258 | ||
258 | mutex_unlock(&list->hiddev->existancelock); | 259 | mutex_unlock(&list->hiddev->existancelock); |
259 | kfree(list); | 260 | vfree(list); |
260 | 261 | ||
261 | return 0; | 262 | return 0; |
262 | } | 263 | } |
@@ -278,7 +279,7 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
278 | hid = usb_get_intfdata(intf); | 279 | hid = usb_get_intfdata(intf); |
279 | hiddev = hid->hiddev; | 280 | hiddev = hid->hiddev; |
280 | 281 | ||
281 | if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) | 282 | if (!(list = vzalloc(sizeof(struct hiddev_list)))) |
282 | return -ENOMEM; | 283 | return -ENOMEM; |
283 | mutex_init(&list->thread_lock); | 284 | mutex_init(&list->thread_lock); |
284 | list->hiddev = hiddev; | 285 | list->hiddev = hiddev; |
@@ -322,7 +323,7 @@ bail_unlock: | |||
322 | mutex_unlock(&hiddev->existancelock); | 323 | mutex_unlock(&hiddev->existancelock); |
323 | bail: | 324 | bail: |
324 | file->private_data = NULL; | 325 | file->private_data = NULL; |
325 | kfree(list); | 326 | vfree(list); |
326 | return res; | 327 | return res; |
327 | } | 328 | } |
328 | 329 | ||
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index cb8f703efde5..1883d7b94870 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -55,6 +55,7 @@ struct usb_interface *usbhid_find_interface(int minor); | |||
55 | #define HID_STARTED 8 | 55 | #define HID_STARTED 8 |
56 | #define HID_REPORTED_IDLE 9 | 56 | #define HID_REPORTED_IDLE 9 |
57 | #define HID_KEYS_PRESSED 10 | 57 | #define HID_KEYS_PRESSED 10 |
58 | #define HID_NO_BANDWIDTH 11 | ||
58 | 59 | ||
59 | /* | 60 | /* |
60 | * USB-specific HID struct, to be pointed to | 61 | * USB-specific HID struct, to be pointed to |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 3a95da60fd3e..449fa385703d 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -317,7 +317,6 @@ struct hid_item { | |||
317 | #define HID_QUIRK_BADPAD 0x00000020 | 317 | #define HID_QUIRK_BADPAD 0x00000020 |
318 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 318 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
319 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 | 319 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 |
320 | #define HID_QUIRK_MULTITOUCH 0x00000100 | ||
321 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 320 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
322 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 | 321 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
323 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 | 322 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 |
@@ -325,6 +324,12 @@ struct hid_item { | |||
325 | #define HID_QUIRK_NO_INPUT_SYNC 0x80000000 | 324 | #define HID_QUIRK_NO_INPUT_SYNC 0x80000000 |
326 | 325 | ||
327 | /* | 326 | /* |
327 | * HID device groups | ||
328 | */ | ||
329 | #define HID_GROUP_GENERIC 0x0001 | ||
330 | #define HID_GROUP_MULTITOUCH 0x0002 | ||
331 | |||
332 | /* | ||
328 | * This is the global environment of the parser. This information is | 333 | * This is the global environment of the parser. This information is |
329 | * persistent for main-items. The global environment can be saved and | 334 | * persistent for main-items. The global environment can be saved and |
330 | * restored with PUSH/POP statements. | 335 | * restored with PUSH/POP statements. |
@@ -467,6 +472,8 @@ struct hid_driver; | |||
467 | struct hid_ll_driver; | 472 | struct hid_ll_driver; |
468 | 473 | ||
469 | struct hid_device { /* device report descriptor */ | 474 | struct hid_device { /* device report descriptor */ |
475 | __u8 *dev_rdesc; | ||
476 | unsigned dev_rsize; | ||
470 | __u8 *rdesc; | 477 | __u8 *rdesc; |
471 | unsigned rsize; | 478 | unsigned rsize; |
472 | struct hid_collection *collection; /* List of HID collections */ | 479 | struct hid_collection *collection; /* List of HID collections */ |
@@ -474,6 +481,7 @@ struct hid_device { /* device report descriptor */ | |||
474 | unsigned maxcollection; /* Number of parsed collections */ | 481 | unsigned maxcollection; /* Number of parsed collections */ |
475 | unsigned maxapplication; /* Number of applications */ | 482 | unsigned maxapplication; /* Number of applications */ |
476 | __u16 bus; /* BUS ID */ | 483 | __u16 bus; /* BUS ID */ |
484 | __u16 group; /* Report group */ | ||
477 | __u32 vendor; /* Vendor ID */ | 485 | __u32 vendor; /* Vendor ID */ |
478 | __u32 product; /* Product ID */ | 486 | __u32 product; /* Product ID */ |
479 | __u32 version; /* HID version */ | 487 | __u32 version; /* HID version */ |
@@ -578,12 +586,12 @@ struct hid_descriptor { | |||
578 | struct hid_class_descriptor desc[1]; | 586 | struct hid_class_descriptor desc[1]; |
579 | } __attribute__ ((packed)); | 587 | } __attribute__ ((packed)); |
580 | 588 | ||
581 | #define HID_DEVICE(b, ven, prod) \ | 589 | #define HID_DEVICE(b, g, ven, prod) \ |
582 | .bus = (b), \ | 590 | .bus = (b), .group = (g), .vendor = (ven), .product = (prod) |
583 | .vendor = (ven), .product = (prod) | 591 | #define HID_USB_DEVICE(ven, prod) \ |
584 | 592 | .bus = BUS_USB, .vendor = (ven), .product = (prod) | |
585 | #define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) | 593 | #define HID_BLUETOOTH_DEVICE(ven, prod) \ |
586 | #define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) | 594 | .bus = BUS_BLUETOOTH, .vendor = (ven), .product = (prod) |
587 | 595 | ||
588 | #define HID_REPORT_ID(rep) \ | 596 | #define HID_REPORT_ID(rep) \ |
589 | .report_type = (rep) | 597 | .report_type = (rep) |
@@ -735,6 +743,7 @@ void hid_output_report(struct hid_report *report, __u8 *data); | |||
735 | struct hid_device *hid_allocate_device(void); | 743 | struct hid_device *hid_allocate_device(void); |
736 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); | 744 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); |
737 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | 745 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); |
746 | int hid_open_report(struct hid_device *device); | ||
738 | int hid_check_keys_pressed(struct hid_device *hid); | 747 | int hid_check_keys_pressed(struct hid_device *hid); |
739 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); | 748 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); |
740 | void hid_disconnect(struct hid_device *hid); | 749 | void hid_disconnect(struct hid_device *hid); |
@@ -805,16 +814,7 @@ static inline void hid_map_usage_clear(struct hid_input *hidinput, | |||
805 | */ | 814 | */ |
806 | static inline int __must_check hid_parse(struct hid_device *hdev) | 815 | static inline int __must_check hid_parse(struct hid_device *hdev) |
807 | { | 816 | { |
808 | int ret; | 817 | return hid_open_report(hdev); |
809 | |||
810 | if (hdev->status & HID_STAT_PARSED) | ||
811 | return 0; | ||
812 | |||
813 | ret = hdev->ll_driver->parse(hdev); | ||
814 | if (!ret) | ||
815 | hdev->status |= HID_STAT_PARSED; | ||
816 | |||
817 | return ret; | ||
818 | } | 818 | } |
819 | 819 | ||
820 | /** | 820 | /** |
@@ -896,7 +896,7 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) | |||
896 | return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; | 896 | return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; |
897 | } | 897 | } |
898 | 898 | ||
899 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 899 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
900 | int interrupt); | 900 | int interrupt); |
901 | 901 | ||
902 | extern int hid_generic_init(void); | 902 | extern int hid_generic_init(void); |
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h index 4b88e697c4e9..45e9fcb8d877 100644 --- a/include/linux/hidraw.h +++ b/include/linux/hidraw.h | |||
@@ -76,13 +76,13 @@ struct hidraw_list { | |||
76 | #ifdef CONFIG_HIDRAW | 76 | #ifdef CONFIG_HIDRAW |
77 | int hidraw_init(void); | 77 | int hidraw_init(void); |
78 | void hidraw_exit(void); | 78 | void hidraw_exit(void); |
79 | void hidraw_report_event(struct hid_device *, u8 *, int); | 79 | int hidraw_report_event(struct hid_device *, u8 *, int); |
80 | int hidraw_connect(struct hid_device *); | 80 | int hidraw_connect(struct hid_device *); |
81 | void hidraw_disconnect(struct hid_device *); | 81 | void hidraw_disconnect(struct hid_device *); |
82 | #else | 82 | #else |
83 | static inline int hidraw_init(void) { return 0; } | 83 | static inline int hidraw_init(void) { return 0; } |
84 | static inline void hidraw_exit(void) { } | 84 | static inline void hidraw_exit(void) { } |
85 | static inline void hidraw_report_event(struct hid_device *hid, u8 *data, int len) { } | 85 | static inline int hidraw_report_event(struct hid_device *hid, u8 *data, int len) { return 0; } |
86 | static inline int hidraw_connect(struct hid_device *hid) { return -1; } | 86 | static inline int hidraw_connect(struct hid_device *hid) { return -1; } |
87 | static inline void hidraw_disconnect(struct hid_device *hid) { } | 87 | static inline void hidraw_disconnect(struct hid_device *hid) { } |
88 | #endif | 88 | #endif |
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 501da4cb8a6d..5db93821f9c7 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -132,10 +132,12 @@ struct usb_device_id { | |||
132 | #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 | 132 | #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 |
133 | 133 | ||
134 | #define HID_ANY_ID (~0) | 134 | #define HID_ANY_ID (~0) |
135 | #define HID_BUS_ANY 0xffff | ||
136 | #define HID_GROUP_ANY 0x0000 | ||
135 | 137 | ||
136 | struct hid_device_id { | 138 | struct hid_device_id { |
137 | __u16 bus; | 139 | __u16 bus; |
138 | __u16 pad1; | 140 | __u16 group; |
139 | __u32 vendor; | 141 | __u32 vendor; |
140 | __u32 product; | 142 | __u32 product; |
141 | kernel_ulong_t driver_data | 143 | kernel_ulong_t driver_data |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index d478be11d562..2c20d765b394 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -1195,41 +1195,16 @@ int hidp_get_conninfo(struct hidp_conninfo *ci) | |||
1195 | return err; | 1195 | return err; |
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | static const struct hid_device_id hidp_table[] = { | ||
1199 | { HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) }, | ||
1200 | { } | ||
1201 | }; | ||
1202 | |||
1203 | static struct hid_driver hidp_driver = { | ||
1204 | .name = "generic-bluetooth", | ||
1205 | .id_table = hidp_table, | ||
1206 | }; | ||
1207 | |||
1208 | static int __init hidp_init(void) | 1198 | static int __init hidp_init(void) |
1209 | { | 1199 | { |
1210 | int ret; | ||
1211 | |||
1212 | BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); | 1200 | BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); |
1213 | 1201 | ||
1214 | ret = hid_register_driver(&hidp_driver); | 1202 | return hidp_init_sockets(); |
1215 | if (ret) | ||
1216 | goto err; | ||
1217 | |||
1218 | ret = hidp_init_sockets(); | ||
1219 | if (ret) | ||
1220 | goto err_drv; | ||
1221 | |||
1222 | return 0; | ||
1223 | err_drv: | ||
1224 | hid_unregister_driver(&hidp_driver); | ||
1225 | err: | ||
1226 | return ret; | ||
1227 | } | 1203 | } |
1228 | 1204 | ||
1229 | static void __exit hidp_exit(void) | 1205 | static void __exit hidp_exit(void) |
1230 | { | 1206 | { |
1231 | hidp_cleanup_sockets(); | 1207 | hidp_cleanup_sockets(); |
1232 | hid_unregister_driver(&hidp_driver); | ||
1233 | } | 1208 | } |
1234 | 1209 | ||
1235 | module_init(hidp_init); | 1210 | module_init(hidp_init); |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8e730ccc3f2b..056de3104e75 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -336,10 +336,13 @@ static int do_hid_entry(const char *filename, | |||
336 | struct hid_device_id *id, char *alias) | 336 | struct hid_device_id *id, char *alias) |
337 | { | 337 | { |
338 | id->bus = TO_NATIVE(id->bus); | 338 | id->bus = TO_NATIVE(id->bus); |
339 | id->group = TO_NATIVE(id->group); | ||
339 | id->vendor = TO_NATIVE(id->vendor); | 340 | id->vendor = TO_NATIVE(id->vendor); |
340 | id->product = TO_NATIVE(id->product); | 341 | id->product = TO_NATIVE(id->product); |
341 | 342 | ||
342 | sprintf(alias, "hid:b%04X", id->bus); | 343 | sprintf(alias, "hid:"); |
344 | ADD(alias, "b", id->bus != HID_BUS_ANY, id->bus); | ||
345 | ADD(alias, "g", id->group != HID_GROUP_ANY, id->group); | ||
343 | ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor); | 346 | ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor); |
344 | ADD(alias, "p", id->product != HID_ANY_ID, id->product); | 347 | ADD(alias, "p", id->product != HID_ANY_ID, id->product); |
345 | 348 | ||