diff options
29 files changed, 1468 insertions, 567 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 ffddcba32af6..e9c68fedfcff 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -32,9 +32,13 @@ config HID | |||
| 32 | If unsure, say Y. | 32 | If unsure, say Y. |
| 33 | 33 | ||
| 34 | config HID_BATTERY_STRENGTH | 34 | config HID_BATTERY_STRENGTH |
| 35 | bool | 35 | bool "Battery level reporting for HID devices" |
| 36 | depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY | 36 | depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY |
| 37 | default n | 37 | default n |
| 38 | ---help--- | ||
| 39 | This option adds support of reporting battery strength (for HID devices | ||
| 40 | that support this feature) through power_supply class so that userspace | ||
| 41 | tools, such as upower, can display it. | ||
| 38 | 42 | ||
| 39 | config HIDRAW | 43 | config HIDRAW |
| 40 | bool "/dev/hidraw raw HID device support" | 44 | bool "/dev/hidraw raw HID device support" |
| @@ -60,6 +64,18 @@ source "drivers/hid/usbhid/Kconfig" | |||
| 60 | menu "Special HID drivers" | 64 | menu "Special HID drivers" |
| 61 | depends on HID | 65 | depends on HID |
| 62 | 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 | |||
| 63 | config HID_A4TECH | 79 | config HID_A4TECH |
| 64 | tristate "A4 tech mice" if EXPERT | 80 | tristate "A4 tech mice" if EXPERT |
| 65 | depends on USB_HID | 81 | depends on USB_HID |
| @@ -92,6 +108,12 @@ config HID_APPLE | |||
| 92 | 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, |
| 93 | MacBooks, MacBook Pros and Apple Aluminum. | 109 | MacBooks, MacBook Pros and Apple Aluminum. |
| 94 | 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 | |||
| 95 | config HID_BELKIN | 117 | config HID_BELKIN |
| 96 | tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT | 118 | tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT |
| 97 | depends on USB_HID | 119 | depends on USB_HID |
| @@ -595,16 +617,10 @@ config THRUSTMASTER_FF | |||
| 595 | config HID_WACOM | 617 | config HID_WACOM |
| 596 | tristate "Wacom Bluetooth devices support" | 618 | tristate "Wacom Bluetooth devices support" |
| 597 | depends on BT_HIDP | 619 | depends on BT_HIDP |
| 598 | ---help--- | 620 | depends on LEDS_CLASS |
| 599 | Support for Wacom Graphire Bluetooth tablet. | ||
| 600 | |||
| 601 | config HID_WACOM_POWER_SUPPLY | ||
| 602 | bool "Wacom Bluetooth devices power supply status support" | ||
| 603 | depends on HID_WACOM | ||
| 604 | select POWER_SUPPLY | 621 | select POWER_SUPPLY |
| 605 | ---help--- | 622 | ---help--- |
| 606 | Say Y here if you want to enable power supply status monitoring for | 623 | Support for Wacom Graphire Bluetooth and Intuos4 WL tablets. |
| 607 | Wacom Bluetooth devices. | ||
| 608 | 624 | ||
| 609 | config HID_WIIMOTE | 625 | config HID_WIIMOTE |
| 610 | 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 299d23871122..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) { |
| @@ -458,6 +458,9 @@ static const struct hid_device_id apple_devices[] = { | |||
| 458 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), | 458 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), |
| 459 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 459 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
| 460 | APPLE_ISO_KEYBOARD }, | 460 | APPLE_ISO_KEYBOARD }, |
| 461 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
| 462 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | ||
| 463 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | ||
| 461 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), | 464 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
| 462 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 465 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 463 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 466 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
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 2b56efcbdf61..5e8a7ed42344 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/hid.h> | 26 | #include <linux/hid.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
| 29 | #include <asm/unaligned.h> | ||
| 29 | #include "usbhid/usbhid.h" | 30 | #include "usbhid/usbhid.h" |
| 30 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
| 31 | #include "hid-logitech-dj.h" | 32 | #include "hid-logitech-dj.h" |
| @@ -155,6 +156,14 @@ static const char media_descriptor[] = { | |||
| 155 | /* 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) */ |
| 156 | #define MAX_REPORT_SIZE 8 | 157 | #define MAX_REPORT_SIZE 8 |
| 157 | 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 | |||
| 158 | /* 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. |
| 159 | * | 168 | * |
| 160 | * 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) |
| @@ -265,8 +274,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
| 265 | goto dj_device_allocate_fail; | 274 | goto dj_device_allocate_fail; |
| 266 | } | 275 | } |
| 267 | 276 | ||
| 268 | dj_dev->reports_supported = le32_to_cpu( | 277 | dj_dev->reports_supported = get_unaligned_le32( |
| 269 | dj_report->report_params[DEVICE_PAIRED_RF_REPORT_TYPE]); | 278 | dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE); |
| 270 | dj_dev->hdev = dj_hiddev; | 279 | dj_dev->hdev = dj_hiddev; |
| 271 | dj_dev->dj_receiver_dev = djrcv_dev; | 280 | dj_dev->dj_receiver_dev = djrcv_dev; |
| 272 | dj_dev->device_index = dj_report->device_index; | 281 | dj_dev->device_index = dj_report->device_index; |
| @@ -473,9 +482,17 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | |||
| 473 | return 0; | 482 | return 0; |
| 474 | } | 483 | } |
| 475 | 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 | |||
| 476 | static int logi_dj_ll_parse(struct hid_device *hid) | 491 | static int logi_dj_ll_parse(struct hid_device *hid) |
| 477 | { | 492 | { |
| 478 | struct dj_device *djdev = hid->driver_data; | 493 | struct dj_device *djdev = hid->driver_data; |
| 494 | unsigned int rsize = 0; | ||
| 495 | char *rdesc; | ||
| 479 | int retval; | 496 | int retval; |
| 480 | 497 | ||
| 481 | dbg_hid("%s\n", __func__); | 498 | dbg_hid("%s\n", __func__); |
| @@ -483,70 +500,38 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
| 483 | djdev->hdev->version = 0x0111; | 500 | djdev->hdev->version = 0x0111; |
| 484 | djdev->hdev->country = 0x00; | 501 | djdev->hdev->country = 0x00; |
| 485 | 502 | ||
| 503 | rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL); | ||
| 504 | if (!rdesc) | ||
| 505 | return -ENOMEM; | ||
| 506 | |||
| 486 | if (djdev->reports_supported & STD_KEYBOARD) { | 507 | if (djdev->reports_supported & STD_KEYBOARD) { |
| 487 | dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", | 508 | dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", |
| 488 | __func__, djdev->reports_supported); | 509 | __func__, djdev->reports_supported); |
| 489 | retval = hid_parse_report(hid, | 510 | rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor)); |
| 490 | (u8 *) kbd_descriptor, | ||
| 491 | sizeof(kbd_descriptor)); | ||
| 492 | if (retval) { | ||
| 493 | dbg_hid("%s: sending a kbd descriptor, hid_parse failed" | ||
| 494 | " error: %d\n", __func__, retval); | ||
| 495 | return retval; | ||
| 496 | } | ||
| 497 | } | 511 | } |
| 498 | 512 | ||
| 499 | if (djdev->reports_supported & STD_MOUSE) { | 513 | if (djdev->reports_supported & STD_MOUSE) { |
| 500 | dbg_hid("%s: sending a mouse descriptor, reports_supported: " | 514 | dbg_hid("%s: sending a mouse descriptor, reports_supported: " |
| 501 | "%x\n", __func__, djdev->reports_supported); | 515 | "%x\n", __func__, djdev->reports_supported); |
| 502 | retval = hid_parse_report(hid, | 516 | rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor)); |
| 503 | (u8 *) mse_descriptor, | ||
| 504 | sizeof(mse_descriptor)); | ||
| 505 | if (retval) { | ||
| 506 | dbg_hid("%s: sending a mouse descriptor, hid_parse " | ||
| 507 | "failed error: %d\n", __func__, retval); | ||
| 508 | return retval; | ||
| 509 | } | ||
| 510 | } | 517 | } |
| 511 | 518 | ||
| 512 | if (djdev->reports_supported & MULTIMEDIA) { | 519 | if (djdev->reports_supported & MULTIMEDIA) { |
| 513 | dbg_hid("%s: sending a multimedia report descriptor: %x\n", | 520 | dbg_hid("%s: sending a multimedia report descriptor: %x\n", |
| 514 | __func__, djdev->reports_supported); | 521 | __func__, djdev->reports_supported); |
| 515 | retval = hid_parse_report(hid, | 522 | rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor)); |
| 516 | (u8 *) consumer_descriptor, | ||
| 517 | sizeof(consumer_descriptor)); | ||
| 518 | if (retval) { | ||
| 519 | dbg_hid("%s: sending a consumer_descriptor, hid_parse " | ||
| 520 | "failed error: %d\n", __func__, retval); | ||
| 521 | return retval; | ||
| 522 | } | ||
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | if (djdev->reports_supported & POWER_KEYS) { | 525 | if (djdev->reports_supported & POWER_KEYS) { |
| 526 | dbg_hid("%s: sending a power keys report descriptor: %x\n", | 526 | dbg_hid("%s: sending a power keys report descriptor: %x\n", |
| 527 | __func__, djdev->reports_supported); | 527 | __func__, djdev->reports_supported); |
| 528 | retval = hid_parse_report(hid, | 528 | rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor)); |
| 529 | (u8 *) syscontrol_descriptor, | ||
| 530 | sizeof(syscontrol_descriptor)); | ||
| 531 | if (retval) { | ||
| 532 | dbg_hid("%s: sending a syscontrol_descriptor, " | ||
| 533 | "hid_parse failed error: %d\n", | ||
| 534 | __func__, retval); | ||
| 535 | return retval; | ||
| 536 | } | ||
| 537 | } | 529 | } |
| 538 | 530 | ||
| 539 | if (djdev->reports_supported & MEDIA_CENTER) { | 531 | if (djdev->reports_supported & MEDIA_CENTER) { |
| 540 | dbg_hid("%s: sending a media center report descriptor: %x\n", | 532 | dbg_hid("%s: sending a media center report descriptor: %x\n", |
| 541 | __func__, djdev->reports_supported); | 533 | __func__, djdev->reports_supported); |
| 542 | retval = hid_parse_report(hid, | 534 | rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor)); |
| 543 | (u8 *) media_descriptor, | ||
| 544 | sizeof(media_descriptor)); | ||
| 545 | if (retval) { | ||
| 546 | dbg_hid("%s: sending a media_descriptor, hid_parse " | ||
| 547 | "failed error: %d\n", __func__, retval); | ||
| 548 | return retval; | ||
| 549 | } | ||
| 550 | } | 535 | } |
| 551 | 536 | ||
| 552 | if (djdev->reports_supported & KBD_LEDS) { | 537 | if (djdev->reports_supported & KBD_LEDS) { |
| @@ -554,7 +539,10 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
| 554 | __func__, djdev->reports_supported); | 539 | __func__, djdev->reports_supported); |
| 555 | } | 540 | } |
| 556 | 541 | ||
| 557 | return 0; | 542 | retval = hid_parse_report(hid, rdesc, rsize); |
| 543 | kfree(rdesc); | ||
| 544 | |||
| 545 | return retval; | ||
| 558 | } | 546 | } |
| 559 | 547 | ||
| 560 | 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/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index cac3589b1ed5..84e2fbec5fbb 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
| @@ -769,7 +769,7 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir, | |||
| 769 | 769 | ||
| 770 | /* | 770 | /* |
| 771 | * Basic IR data is encoded into 3 bytes. The first two bytes are the | 771 | * Basic IR data is encoded into 3 bytes. The first two bytes are the |
| 772 | * upper 8 bit of the X/Y data, the 3rd byte contains the lower 2 bits | 772 | * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits |
| 773 | * of both. | 773 | * of both. |
| 774 | * If data is packed, then the 3rd byte is put first and slightly | 774 | * If data is packed, then the 3rd byte is put first and slightly |
| 775 | * reordered. This allows to interleave packed and non-packed data to | 775 | * reordered. This allows to interleave packed and non-packed data to |
| @@ -778,17 +778,11 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir, | |||
| 778 | */ | 778 | */ |
| 779 | 779 | ||
| 780 | if (packed) { | 780 | if (packed) { |
| 781 | x = ir[1] << 2; | 781 | x = ir[1] | ((ir[0] & 0x03) << 8); |
| 782 | y = ir[2] << 2; | 782 | y = ir[2] | ((ir[0] & 0x0c) << 6); |
| 783 | |||
| 784 | x |= ir[0] & 0x3; | ||
| 785 | y |= (ir[0] >> 2) & 0x3; | ||
| 786 | } else { | 783 | } else { |
| 787 | x = ir[0] << 2; | 784 | x = ir[0] | ((ir[2] & 0x30) << 4); |
| 788 | y = ir[1] << 2; | 785 | y = ir[1] | ((ir[2] & 0xc0) << 2); |
| 789 | |||
| 790 | x |= (ir[2] >> 4) & 0x3; | ||
| 791 | y |= (ir[2] >> 6) & 0x3; | ||
| 792 | } | 786 | } |
| 793 | 787 | ||
| 794 | input_report_abs(wdata->ir, xid, x); | 788 | input_report_abs(wdata->ir, xid, x); |
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 340d6ae646ed..482f936fc29b 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 | } |
| @@ -749,7 +757,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | |||
| 749 | int usbhid_open(struct hid_device *hid) | 757 | int usbhid_open(struct hid_device *hid) |
| 750 | { | 758 | { |
| 751 | struct usbhid_device *usbhid = hid->driver_data; | 759 | struct usbhid_device *usbhid = hid->driver_data; |
| 752 | int res; | 760 | int res = 0; |
| 753 | 761 | ||
| 754 | mutex_lock(&hid_open_mut); | 762 | mutex_lock(&hid_open_mut); |
| 755 | if (!hid->open++) { | 763 | if (!hid->open++) { |
| @@ -757,17 +765,27 @@ int usbhid_open(struct hid_device *hid) | |||
| 757 | /* the device must be awake to reliably request remote wakeup */ | 765 | /* the device must be awake to reliably request remote wakeup */ |
| 758 | if (res < 0) { | 766 | if (res < 0) { |
| 759 | hid->open--; | 767 | hid->open--; |
| 760 | mutex_unlock(&hid_open_mut); | 768 | res = -EIO; |
| 761 | return -EIO; | 769 | goto done; |
| 762 | } | 770 | } |
| 763 | usbhid->intf->needs_remote_wakeup = 1; | 771 | usbhid->intf->needs_remote_wakeup = 1; |
| 764 | if (hid_start_in(hid)) | 772 | res = hid_start_in(hid); |
| 765 | hid_io_error(hid); | 773 | if (res) { |
| 766 | 774 | if (res != -ENOSPC) { | |
| 775 | hid_io_error(hid); | ||
| 776 | res = 0; | ||
| 777 | } else { | ||
| 778 | /* no use opening if resources are insufficient */ | ||
| 779 | hid->open--; | ||
| 780 | res = -EBUSY; | ||
| 781 | usbhid->intf->needs_remote_wakeup = 0; | ||
| 782 | } | ||
| 783 | } | ||
| 767 | usb_autopm_put_interface(usbhid->intf); | 784 | usb_autopm_put_interface(usbhid->intf); |
| 768 | } | 785 | } |
| 786 | done: | ||
| 769 | mutex_unlock(&hid_open_mut); | 787 | mutex_unlock(&hid_open_mut); |
| 770 | return 0; | 788 | return res; |
| 771 | } | 789 | } |
| 772 | 790 | ||
| 773 | void usbhid_close(struct hid_device *hid) | 791 | void usbhid_close(struct hid_device *hid) |
| @@ -1396,7 +1414,34 @@ static int hid_post_reset(struct usb_interface *intf) | |||
| 1396 | struct usb_device *dev = interface_to_usbdev (intf); | 1414 | struct usb_device *dev = interface_to_usbdev (intf); |
| 1397 | struct hid_device *hid = usb_get_intfdata(intf); | 1415 | struct hid_device *hid = usb_get_intfdata(intf); |
| 1398 | struct usbhid_device *usbhid = hid->driver_data; | 1416 | struct usbhid_device *usbhid = hid->driver_data; |
| 1417 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
| 1399 | int status; | 1418 | int status; |
| 1419 | char *rdesc; | ||
| 1420 | |||
| 1421 | /* Fetch and examine the HID report descriptor. If this | ||
| 1422 | * has changed, then rebind. Since usbcore's check of the | ||
| 1423 | * configuration descriptors passed, we already know that | ||
| 1424 | * the size of the HID report descriptor has not changed. | ||
| 1425 | */ | ||
| 1426 | rdesc = kmalloc(hid->rsize, GFP_KERNEL); | ||
| 1427 | if (!rdesc) { | ||
| 1428 | dbg_hid("couldn't allocate rdesc memory (post_reset)\n"); | ||
| 1429 | return 1; | ||
| 1430 | } | ||
| 1431 | status = hid_get_class_descriptor(dev, | ||
| 1432 | interface->desc.bInterfaceNumber, | ||
| 1433 | HID_DT_REPORT, rdesc, hid->rsize); | ||
| 1434 | if (status < 0) { | ||
| 1435 | dbg_hid("reading report descriptor failed (post_reset)\n"); | ||
| 1436 | kfree(rdesc); | ||
| 1437 | return 1; | ||
| 1438 | } | ||
| 1439 | status = memcmp(rdesc, hid->rdesc, hid->rsize); | ||
| 1440 | kfree(rdesc); | ||
| 1441 | if (status != 0) { | ||
| 1442 | dbg_hid("report descriptor changed\n"); | ||
| 1443 | return 1; | ||
| 1444 | } | ||
| 1400 | 1445 | ||
| 1401 | spin_lock_irq(&usbhid->lock); | 1446 | spin_lock_irq(&usbhid->lock); |
| 1402 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); | 1447 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
| @@ -1553,28 +1598,15 @@ static struct usb_driver hid_driver = { | |||
| 1553 | .supports_autosuspend = 1, | 1598 | .supports_autosuspend = 1, |
| 1554 | }; | 1599 | }; |
| 1555 | 1600 | ||
| 1556 | static const struct hid_device_id hid_usb_table[] = { | ||
| 1557 | { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, | ||
| 1558 | { } | ||
| 1559 | }; | ||
| 1560 | |||
| 1561 | struct usb_interface *usbhid_find_interface(int minor) | 1601 | struct usb_interface *usbhid_find_interface(int minor) |
| 1562 | { | 1602 | { |
| 1563 | return usb_find_interface(&hid_driver, minor); | 1603 | return usb_find_interface(&hid_driver, minor); |
| 1564 | } | 1604 | } |
| 1565 | 1605 | ||
| 1566 | static struct hid_driver hid_usb_driver = { | ||
| 1567 | .name = "generic-usb", | ||
| 1568 | .id_table = hid_usb_table, | ||
| 1569 | }; | ||
| 1570 | |||
| 1571 | static int __init hid_init(void) | 1606 | static int __init hid_init(void) |
| 1572 | { | 1607 | { |
| 1573 | int retval = -ENOMEM; | 1608 | int retval = -ENOMEM; |
| 1574 | 1609 | ||
| 1575 | retval = hid_register_driver(&hid_usb_driver); | ||
| 1576 | if (retval) | ||
| 1577 | goto hid_register_fail; | ||
| 1578 | retval = usbhid_quirks_init(quirks_param); | 1610 | retval = usbhid_quirks_init(quirks_param); |
| 1579 | if (retval) | 1611 | if (retval) |
| 1580 | goto usbhid_quirks_init_fail; | 1612 | goto usbhid_quirks_init_fail; |
| @@ -1587,8 +1619,6 @@ static int __init hid_init(void) | |||
| 1587 | usb_register_fail: | 1619 | usb_register_fail: |
| 1588 | usbhid_quirks_exit(); | 1620 | usbhid_quirks_exit(); |
| 1589 | usbhid_quirks_init_fail: | 1621 | usbhid_quirks_init_fail: |
| 1590 | hid_unregister_driver(&hid_usb_driver); | ||
| 1591 | hid_register_fail: | ||
| 1592 | return retval; | 1622 | return retval; |
| 1593 | } | 1623 | } |
| 1594 | 1624 | ||
| @@ -1596,7 +1626,6 @@ static void __exit hid_exit(void) | |||
| 1596 | { | 1626 | { |
| 1597 | usb_deregister(&hid_driver); | 1627 | usb_deregister(&hid_driver); |
| 1598 | usbhid_quirks_exit(); | 1628 | usbhid_quirks_exit(); |
| 1599 | hid_unregister_driver(&hid_usb_driver); | ||
| 1600 | } | 1629 | } |
| 1601 | 1630 | ||
| 1602 | module_init(hid_init); | 1631 | 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 44ddaa542db6..5759751a1f61 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 | ||
