diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 20:41:38 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 20:41:38 -0500 |
| commit | 48a732dfaa77a4dfec803aa8f248373998704f76 (patch) | |
| tree | b8ea89d3f48bc82fcc1b14d8cd356241e7ef2d37 | |
| parent | 9afa3195b96da7d2320ec44d19fbfbded7a15571 (diff) | |
| parent | 0d69a3c731e120b05b7da9fb976830475a3fbc01 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID subsystem updates from Jiri Kosina:
"HID subsystem and drivers update. Highlights:
- new support of a group of Win7/Win8 multitouch devices, from
Benjamin Tissoires
- fix for compat interface brokenness in uhid, from Dmitry Torokhov
- conversion of drivers to use hid_driver helper, by H Hartley
Sweeten
- HID over I2C transport received ACPI enumeration support, written
by Mika Westerberg
- there is an ongoing effort to make HID sensor hubs independent of
USB transport. The first self-contained part of this work is
provided here, done by Mika Westerberg
- a few smaller fixes here and there, support for a couple new
devices added"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (43 commits)
HID: Correct Logitech order in hid-ids.h
HID: LG4FF: Remove unnecessary deadzone code
HID: LG: Prevent the Logitech Gaming Wheels deadzone
HID: LG: Fix detection of Logitech Speed Force Wireless (WiiWheel)
HID: LG: Add support for Logitech Momo Force (Red) Wheel
HID: hidraw: print message when succesfully initialized
HID: logitech: split accel, brake for Driving Force wheel
HID: logitech: add report descriptor for Driving Force wheel
HID: add ThingM blink(1) USB RGB LED support
HID: uhid: make creating devices work on 64/32 systems
HID: wiimote: fix nunchuck button parser
HID: blacklist Velleman data acquisition boards
HID: sensor-hub: don't limit the driver only to USB bus
HID: sensor-hub: get rid of unused sensor_hub_grabbed_usages[] table
HID: extend autodetect to handle I2C sensors as well
HID: ntrig: use input_configured() callback to set the name
HID: multitouch: do not use pointers towards hid-core
HID: add missing GENERIC_HARDIRQ dependency
HID: multitouch: make MT_CLS_ALWAYS_TRUE the new default class
HID: multitouch: fix protocol for Elo panels
...
71 files changed, 1405 insertions, 824 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-srws1 b/Documentation/ABI/testing/sysfs-driver-hid-srws1 new file mode 100644 index 000000000000..d0eba70c7d40 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-srws1 | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | What: /sys/class/leds/SRWS1::<serial>::RPM1 | ||
| 2 | What: /sys/class/leds/SRWS1::<serial>::RPM2 | ||
| 3 | What: /sys/class/leds/SRWS1::<serial>::RPM3 | ||
| 4 | What: /sys/class/leds/SRWS1::<serial>::RPM4 | ||
| 5 | What: /sys/class/leds/SRWS1::<serial>::RPM5 | ||
| 6 | What: /sys/class/leds/SRWS1::<serial>::RPM6 | ||
| 7 | What: /sys/class/leds/SRWS1::<serial>::RPM7 | ||
| 8 | What: /sys/class/leds/SRWS1::<serial>::RPM8 | ||
| 9 | What: /sys/class/leds/SRWS1::<serial>::RPM9 | ||
| 10 | What: /sys/class/leds/SRWS1::<serial>::RPM10 | ||
| 11 | What: /sys/class/leds/SRWS1::<serial>::RPM11 | ||
| 12 | What: /sys/class/leds/SRWS1::<serial>::RPM12 | ||
| 13 | What: /sys/class/leds/SRWS1::<serial>::RPM13 | ||
| 14 | What: /sys/class/leds/SRWS1::<serial>::RPM14 | ||
| 15 | What: /sys/class/leds/SRWS1::<serial>::RPM15 | ||
| 16 | What: /sys/class/leds/SRWS1::<serial>::RPMALL | ||
| 17 | Date: Jan 2013 | ||
| 18 | KernelVersion: 3.9 | ||
| 19 | Contact: Simon Wood <simon@mungewell.org> | ||
| 20 | Description: Provides a control for turning on/off the LEDs which form | ||
| 21 | an RPM meter on the front of the controller | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-thingm b/Documentation/ABI/testing/sysfs-driver-hid-thingm new file mode 100644 index 000000000000..abcffeedd20a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-thingm | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | What: /sys/class/leds/blink1::<serial>/rgb | ||
| 2 | Date: January 2013 | ||
| 3 | Contact: Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
| 4 | Description: The ThingM blink1 is an USB RGB LED. The color notation is | ||
| 5 | 3-byte hexadecimal. Read this attribute to get the last set | ||
| 6 | color. Write the 24-bit hexadecimal color to change the current | ||
| 7 | LED color. The default color is full white (0xFFFFFF). | ||
| 8 | For instance, set the color to green with: echo 00FF00 > rgb | ||
| 9 | |||
| 10 | What: /sys/class/leds/blink1::<serial>/fade | ||
| 11 | Date: January 2013 | ||
| 12 | Contact: Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
| 13 | Description: This attribute allows to set a fade time in milliseconds for | ||
| 14 | the next color change. Read the attribute to know the current | ||
| 15 | fade time. The default value is set to 0 (no fade time). For | ||
| 16 | instance, set a fade time of 2 seconds with: echo 2000 > fade | ||
| 17 | |||
| 18 | What: /sys/class/leds/blink1::<serial>/play | ||
| 19 | Date: January 2013 | ||
| 20 | Contact: Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
| 21 | Description: This attribute is used to play/pause the light patterns. Write 1 | ||
| 22 | to start playing, 0 to stop. Reading this attribute returns the | ||
| 23 | current playing status. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 81e4ad85dd5c..db061e961d37 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -7611,6 +7611,11 @@ S: Supported | |||
| 7611 | F: drivers/thermal/ | 7611 | F: drivers/thermal/ |
| 7612 | F: include/linux/thermal.h | 7612 | F: include/linux/thermal.h |
| 7613 | 7613 | ||
| 7614 | THINGM BLINK(1) USB RGB LED DRIVER | ||
| 7615 | M: Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
| 7616 | S: Maintained | ||
| 7617 | F: drivers/hid/hid-thingm.c | ||
| 7618 | |||
| 7614 | THINKPAD ACPI EXTRAS DRIVER | 7619 | THINKPAD ACPI EXTRAS DRIVER |
| 7615 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> | 7620 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> |
| 7616 | L: ibm-acpi-devel@lists.sourceforge.net | 7621 | L: ibm-acpi-devel@lists.sourceforge.net |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index eae0c7e468cf..5f07d85c4189 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -596,6 +596,12 @@ config HID_SPEEDLINK | |||
| 596 | ---help--- | 596 | ---help--- |
| 597 | Support for Speedlink Vicious and Divine Cezanne mouse. | 597 | Support for Speedlink Vicious and Divine Cezanne mouse. |
| 598 | 598 | ||
| 599 | config HID_STEELSERIES | ||
| 600 | tristate "Steelseries SRW-S1 steering wheel support" | ||
| 601 | depends on USB_HID | ||
| 602 | ---help--- | ||
| 603 | Support for Steelseries SRW-S1 steering wheel | ||
| 604 | |||
| 599 | config HID_SUNPLUS | 605 | config HID_SUNPLUS |
| 600 | tristate "Sunplus wireless desktop" | 606 | tristate "Sunplus wireless desktop" |
| 601 | depends on USB_HID | 607 | depends on USB_HID |
| @@ -655,6 +661,16 @@ config HID_TOPSEED | |||
| 655 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic | 661 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic |
| 656 | CLLRCMCE remote control. | 662 | CLLRCMCE remote control. |
| 657 | 663 | ||
| 664 | config HID_THINGM | ||
| 665 | tristate "ThingM blink(1) USB RGB LED" | ||
| 666 | depends on USB_HID | ||
| 667 | depends on LEDS_CLASS | ||
| 668 | ---help--- | ||
| 669 | Support for the ThingM blink(1) USB RGB LED. This driver registers a | ||
| 670 | Linux LED class instance, plus additional sysfs attributes to control | ||
| 671 | RGB colors, fade time and playing. The device is exposed through hidraw | ||
| 672 | to access other functions. | ||
| 673 | |||
| 658 | config HID_THRUSTMASTER | 674 | config HID_THRUSTMASTER |
| 659 | tristate "ThrustMaster devices support" | 675 | tristate "ThrustMaster devices support" |
| 660 | depends on USB_HID | 676 | depends on USB_HID |
| @@ -719,7 +735,7 @@ config HID_ZYDACRON | |||
| 719 | 735 | ||
| 720 | config HID_SENSOR_HUB | 736 | config HID_SENSOR_HUB |
| 721 | tristate "HID Sensors framework support" | 737 | tristate "HID Sensors framework support" |
| 722 | depends on USB_HID | 738 | depends on USB_HID && GENERIC_HARDIRQS |
| 723 | select MFD_CORE | 739 | select MFD_CORE |
| 724 | default n | 740 | default n |
| 725 | -- help--- | 741 | -- help--- |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index b62215716b2f..72d1b0bc0a97 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
| @@ -101,8 +101,10 @@ obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | |||
| 101 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 101 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
| 102 | obj-$(CONFIG_HID_SONY) += hid-sony.o | 102 | obj-$(CONFIG_HID_SONY) += hid-sony.o |
| 103 | obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o | 103 | obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o |
| 104 | obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o | ||
| 104 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o | 105 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o |
| 105 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o | 106 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o |
| 107 | obj-$(CONFIG_HID_THINGM) += hid-thingm.o | ||
| 106 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o | 108 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o |
| 107 | obj-$(CONFIG_HID_TIVO) += hid-tivo.o | 109 | obj-$(CONFIG_HID_TIVO) += hid-tivo.o |
| 108 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o | 110 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o |
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 0a239885e67c..7c5507e94820 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c | |||
| @@ -146,17 +146,6 @@ static struct hid_driver a4_driver = { | |||
| 146 | .probe = a4_probe, | 146 | .probe = a4_probe, |
| 147 | .remove = a4_remove, | 147 | .remove = a4_remove, |
| 148 | }; | 148 | }; |
| 149 | module_hid_driver(a4_driver); | ||
| 149 | 150 | ||
| 150 | static int __init a4_init(void) | ||
| 151 | { | ||
| 152 | return hid_register_driver(&a4_driver); | ||
| 153 | } | ||
| 154 | |||
| 155 | static void __exit a4_exit(void) | ||
| 156 | { | ||
| 157 | hid_unregister_driver(&a4_driver); | ||
| 158 | } | ||
| 159 | |||
| 160 | module_init(a4_init); | ||
| 161 | module_exit(a4_exit); | ||
| 162 | MODULE_LICENSE("GPL"); | 151 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index d0f7662aacca..320a958d4139 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
| @@ -555,23 +555,6 @@ static struct hid_driver apple_driver = { | |||
| 555 | .input_mapping = apple_input_mapping, | 555 | .input_mapping = apple_input_mapping, |
| 556 | .input_mapped = apple_input_mapped, | 556 | .input_mapped = apple_input_mapped, |
| 557 | }; | 557 | }; |
| 558 | module_hid_driver(apple_driver); | ||
| 558 | 559 | ||
| 559 | static int __init apple_init(void) | ||
| 560 | { | ||
| 561 | int ret; | ||
| 562 | |||
| 563 | ret = hid_register_driver(&apple_driver); | ||
| 564 | if (ret) | ||
| 565 | pr_err("can't register apple driver\n"); | ||
| 566 | |||
| 567 | return ret; | ||
| 568 | } | ||
| 569 | |||
| 570 | static void __exit apple_exit(void) | ||
| 571 | { | ||
| 572 | hid_unregister_driver(&apple_driver); | ||
| 573 | } | ||
| 574 | |||
| 575 | module_init(apple_init); | ||
| 576 | module_exit(apple_exit); | ||
| 577 | MODULE_LICENSE("GPL"); | 560 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-aureal.c b/drivers/hid/hid-aureal.c index 7968187ddf7b..340ba9d394a0 100644 --- a/drivers/hid/hid-aureal.c +++ b/drivers/hid/hid-aureal.c | |||
| @@ -37,17 +37,6 @@ static struct hid_driver aureal_driver = { | |||
| 37 | .id_table = aureal_devices, | 37 | .id_table = aureal_devices, |
| 38 | .report_fixup = aureal_report_fixup, | 38 | .report_fixup = aureal_report_fixup, |
| 39 | }; | 39 | }; |
| 40 | module_hid_driver(aureal_driver); | ||
| 40 | 41 | ||
| 41 | static int __init aureal_init(void) | ||
| 42 | { | ||
| 43 | return hid_register_driver(&aureal_driver); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void __exit aureal_exit(void) | ||
| 47 | { | ||
| 48 | hid_unregister_driver(&aureal_driver); | ||
| 49 | } | ||
| 50 | |||
| 51 | module_init(aureal_init); | ||
| 52 | module_exit(aureal_exit); | ||
| 53 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index 5be858dd9a15..62f0cee032ba 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c | |||
| @@ -192,19 +192,7 @@ static struct hid_driver ax_driver = { | |||
| 192 | .probe = ax_probe, | 192 | .probe = ax_probe, |
| 193 | .remove = ax_remove, | 193 | .remove = ax_remove, |
| 194 | }; | 194 | }; |
| 195 | 195 | module_hid_driver(ax_driver); | |
| 196 | static int __init ax_init(void) | ||
| 197 | { | ||
| 198 | return hid_register_driver(&ax_driver); | ||
| 199 | } | ||
| 200 | |||
| 201 | static void __exit ax_exit(void) | ||
| 202 | { | ||
| 203 | hid_unregister_driver(&ax_driver); | ||
| 204 | } | ||
| 205 | |||
| 206 | module_init(ax_init); | ||
| 207 | module_exit(ax_exit); | ||
| 208 | 196 | ||
| 209 | MODULE_AUTHOR("Sergei Kolzun"); | 197 | MODULE_AUTHOR("Sergei Kolzun"); |
| 210 | MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers"); | 198 | MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers"); |
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c index a1a5a12c3a6b..cc4cf138bef5 100644 --- a/drivers/hid/hid-belkin.c +++ b/drivers/hid/hid-belkin.c | |||
| @@ -86,17 +86,6 @@ static struct hid_driver belkin_driver = { | |||
| 86 | .input_mapping = belkin_input_mapping, | 86 | .input_mapping = belkin_input_mapping, |
| 87 | .probe = belkin_probe, | 87 | .probe = belkin_probe, |
| 88 | }; | 88 | }; |
| 89 | module_hid_driver(belkin_driver); | ||
| 89 | 90 | ||
| 90 | static int __init belkin_init(void) | ||
| 91 | { | ||
| 92 | return hid_register_driver(&belkin_driver); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void __exit belkin_exit(void) | ||
| 96 | { | ||
| 97 | hid_unregister_driver(&belkin_driver); | ||
| 98 | } | ||
| 99 | |||
| 100 | module_init(belkin_init); | ||
| 101 | module_exit(belkin_exit); | ||
| 102 | MODULE_LICENSE("GPL"); | 91 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index af034d3d9256..1bdcccc54a1d 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c | |||
| @@ -69,17 +69,6 @@ static struct hid_driver ch_driver = { | |||
| 69 | .report_fixup = ch_report_fixup, | 69 | .report_fixup = ch_report_fixup, |
| 70 | .input_mapping = ch_input_mapping, | 70 | .input_mapping = ch_input_mapping, |
| 71 | }; | 71 | }; |
| 72 | module_hid_driver(ch_driver); | ||
| 72 | 73 | ||
| 73 | static int __init ch_init(void) | ||
| 74 | { | ||
| 75 | return hid_register_driver(&ch_driver); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void __exit ch_exit(void) | ||
| 79 | { | ||
| 80 | hid_unregister_driver(&ch_driver); | ||
| 81 | } | ||
| 82 | |||
| 83 | module_init(ch_init); | ||
| 84 | module_exit(ch_exit); | ||
| 85 | MODULE_LICENSE("GPL"); | 74 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index a2abb8e15727..b613d5a79684 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c | |||
| @@ -70,17 +70,6 @@ static struct hid_driver ch_driver = { | |||
| 70 | .id_table = ch_devices, | 70 | .id_table = ch_devices, |
| 71 | .input_mapping = ch_input_mapping, | 71 | .input_mapping = ch_input_mapping, |
| 72 | }; | 72 | }; |
| 73 | module_hid_driver(ch_driver); | ||
| 73 | 74 | ||
| 74 | static int __init ch_init(void) | ||
| 75 | { | ||
| 76 | return hid_register_driver(&ch_driver); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void __exit ch_exit(void) | ||
| 80 | { | ||
| 81 | hid_unregister_driver(&ch_driver); | ||
| 82 | } | ||
| 83 | |||
| 84 | module_init(ch_init); | ||
| 85 | module_exit(ch_exit); | ||
| 86 | MODULE_LICENSE("GPL"); | 75 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index eb2ee11b6412..ff75cabf7393 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -729,7 +729,7 @@ static int hid_scan_report(struct hid_device *hid) | |||
| 729 | item.type == HID_ITEM_TYPE_MAIN && | 729 | item.type == HID_ITEM_TYPE_MAIN && |
| 730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && | 730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && |
| 731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && | 731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && |
| 732 | hid->bus == BUS_USB) | 732 | (hid->bus == BUS_USB || hid->bus == BUS_I2C)) |
| 733 | hid->group = HID_GROUP_SENSOR_HUB; | 733 | hid->group = HID_GROUP_SENSOR_HUB; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| @@ -1195,6 +1195,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | |||
| 1195 | { | 1195 | { |
| 1196 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1196 | struct hid_report_enum *report_enum = hid->report_enum + type; |
| 1197 | struct hid_report *report; | 1197 | struct hid_report *report; |
| 1198 | struct hid_driver *hdrv; | ||
| 1198 | unsigned int a; | 1199 | unsigned int a; |
| 1199 | int rsize, csize = size; | 1200 | int rsize, csize = size; |
| 1200 | u8 *cdata = data; | 1201 | u8 *cdata = data; |
| @@ -1231,6 +1232,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | |||
| 1231 | if (hid->claimed != HID_CLAIMED_HIDRAW) { | 1232 | if (hid->claimed != HID_CLAIMED_HIDRAW) { |
| 1232 | for (a = 0; a < report->maxfield; a++) | 1233 | for (a = 0; a < report->maxfield; a++) |
| 1233 | hid_input_field(hid, report->field[a], cdata, interrupt); | 1234 | hid_input_field(hid, report->field[a], cdata, interrupt); |
| 1235 | hdrv = hid->driver; | ||
| 1236 | if (hdrv && hdrv->report) | ||
| 1237 | hdrv->report(hid, report); | ||
| 1234 | } | 1238 | } |
| 1235 | 1239 | ||
| 1236 | if (hid->claimed & HID_CLAIMED_INPUT) | 1240 | if (hid->claimed & HID_CLAIMED_INPUT) |
| @@ -1599,6 +1603,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1599 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1603 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
| 1600 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, | 1604 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, |
| 1601 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, | 1605 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, |
| 1606 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, | ||
| 1602 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, | 1607 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, |
| 1603 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1608 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
| 1604 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, | 1609 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, |
| @@ -1697,7 +1702,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1697 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, | 1702 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, |
| 1698 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1703 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
| 1699 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1704 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
| 1705 | { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, | ||
| 1700 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1706 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
| 1707 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, | ||
| 1701 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1708 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
| 1702 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1709 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
| 1703 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, | 1710 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, |
| @@ -2228,6 +2235,14 @@ bool hid_ignore(struct hid_device *hdev) | |||
| 2228 | hdev->type != HID_TYPE_USBMOUSE) | 2235 | hdev->type != HID_TYPE_USBMOUSE) |
| 2229 | return true; | 2236 | return true; |
| 2230 | break; | 2237 | break; |
| 2238 | case USB_VENDOR_ID_VELLEMAN: | ||
| 2239 | /* These are not HID devices. They are handled by comedi. */ | ||
| 2240 | if ((hdev->product >= USB_DEVICE_ID_VELLEMAN_K8055_FIRST && | ||
| 2241 | hdev->product <= USB_DEVICE_ID_VELLEMAN_K8055_LAST) || | ||
| 2242 | (hdev->product >= USB_DEVICE_ID_VELLEMAN_K8061_FIRST && | ||
| 2243 | hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST)) | ||
| 2244 | return true; | ||
| 2245 | break; | ||
| 2231 | } | 2246 | } |
| 2232 | 2247 | ||
| 2233 | if (hdev->type == HID_TYPE_USBMOUSE && | 2248 | if (hdev->type == HID_TYPE_USBMOUSE && |
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c index 3e159a50dac7..c4ef3bc726e3 100644 --- a/drivers/hid/hid-cypress.c +++ b/drivers/hid/hid-cypress.c | |||
| @@ -144,17 +144,6 @@ static struct hid_driver cp_driver = { | |||
| 144 | .event = cp_event, | 144 | .event = cp_event, |
| 145 | .probe = cp_probe, | 145 | .probe = cp_probe, |
| 146 | }; | 146 | }; |
| 147 | module_hid_driver(cp_driver); | ||
| 147 | 148 | ||
| 148 | static int __init cp_init(void) | ||
| 149 | { | ||
| 150 | return hid_register_driver(&cp_driver); | ||
| 151 | } | ||
| 152 | |||
| 153 | static void __exit cp_exit(void) | ||
| 154 | { | ||
| 155 | hid_unregister_driver(&cp_driver); | ||
| 156 | } | ||
| 157 | |||
| 158 | module_init(cp_init); | ||
| 159 | module_exit(cp_exit); | ||
| 160 | MODULE_LICENSE("GPL"); | 149 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index e832f44ae383..0fe8f65ef01a 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c | |||
| @@ -297,17 +297,6 @@ static struct hid_driver dr_driver = { | |||
| 297 | .report_fixup = dr_report_fixup, | 297 | .report_fixup = dr_report_fixup, |
| 298 | .probe = dr_probe, | 298 | .probe = dr_probe, |
| 299 | }; | 299 | }; |
| 300 | module_hid_driver(dr_driver); | ||
| 300 | 301 | ||
| 301 | static int __init dr_init(void) | ||
| 302 | { | ||
| 303 | return hid_register_driver(&dr_driver); | ||
| 304 | } | ||
| 305 | |||
| 306 | static void __exit dr_exit(void) | ||
| 307 | { | ||
| 308 | hid_unregister_driver(&dr_driver); | ||
| 309 | } | ||
| 310 | |||
| 311 | module_init(dr_init); | ||
| 312 | module_exit(dr_exit); | ||
| 313 | MODULE_LICENSE("GPL"); | 302 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index 79d0c61e7214..d0bd13b62dc2 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c | |||
| @@ -41,17 +41,6 @@ static struct hid_driver elecom_driver = { | |||
| 41 | .id_table = elecom_devices, | 41 | .id_table = elecom_devices, |
| 42 | .report_fixup = elecom_report_fixup | 42 | .report_fixup = elecom_report_fixup |
| 43 | }; | 43 | }; |
| 44 | module_hid_driver(elecom_driver); | ||
| 44 | 45 | ||
| 45 | static int __init elecom_init(void) | ||
| 46 | { | ||
| 47 | return hid_register_driver(&elecom_driver); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void __exit elecom_exit(void) | ||
| 51 | { | ||
| 52 | hid_unregister_driver(&elecom_driver); | ||
| 53 | } | ||
| 54 | |||
| 55 | module_init(elecom_init); | ||
| 56 | module_exit(elecom_exit); | ||
| 57 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 2630d483d262..2e093ab99b43 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c | |||
| @@ -150,18 +150,7 @@ static struct hid_driver ems_driver = { | |||
| 150 | .id_table = ems_devices, | 150 | .id_table = ems_devices, |
| 151 | .probe = ems_probe, | 151 | .probe = ems_probe, |
| 152 | }; | 152 | }; |
| 153 | module_hid_driver(ems_driver); | ||
| 153 | 154 | ||
| 154 | static int ems_init(void) | ||
| 155 | { | ||
| 156 | return hid_register_driver(&ems_driver); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void ems_exit(void) | ||
| 160 | { | ||
| 161 | hid_unregister_driver(&ems_driver); | ||
| 162 | } | ||
| 163 | |||
| 164 | module_init(ems_init); | ||
| 165 | module_exit(ems_exit); | ||
| 166 | MODULE_LICENSE("GPL"); | 155 | MODULE_LICENSE("GPL"); |
| 167 | 156 | ||
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c index 6540af2871a7..212ac6be2451 100644 --- a/drivers/hid/hid-ezkey.c +++ b/drivers/hid/hid-ezkey.c | |||
| @@ -76,17 +76,6 @@ static struct hid_driver ez_driver = { | |||
| 76 | .input_mapping = ez_input_mapping, | 76 | .input_mapping = ez_input_mapping, |
| 77 | .event = ez_event, | 77 | .event = ez_event, |
| 78 | }; | 78 | }; |
| 79 | module_hid_driver(ez_driver); | ||
| 79 | 80 | ||
| 80 | static int __init ez_init(void) | ||
| 81 | { | ||
| 82 | return hid_register_driver(&ez_driver); | ||
| 83 | } | ||
| 84 | |||
| 85 | static void __exit ez_exit(void) | ||
| 86 | { | ||
| 87 | hid_unregister_driver(&ez_driver); | ||
| 88 | } | ||
| 89 | |||
| 90 | module_init(ez_init); | ||
| 91 | module_exit(ez_exit); | ||
| 92 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index f1e1bcf67427..04d2e6aca778 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c | |||
| @@ -176,17 +176,6 @@ static struct hid_driver ga_driver = { | |||
| 176 | .id_table = ga_devices, | 176 | .id_table = ga_devices, |
| 177 | .probe = ga_probe, | 177 | .probe = ga_probe, |
| 178 | }; | 178 | }; |
| 179 | module_hid_driver(ga_driver); | ||
| 179 | 180 | ||
| 180 | static int __init ga_init(void) | ||
| 181 | { | ||
| 182 | return hid_register_driver(&ga_driver); | ||
| 183 | } | ||
| 184 | |||
| 185 | static void __exit ga_exit(void) | ||
| 186 | { | ||
| 187 | hid_unregister_driver(&ga_driver); | ||
| 188 | } | ||
| 189 | |||
| 190 | module_init(ga_init); | ||
| 191 | module_exit(ga_exit); | ||
| 192 | MODULE_LICENSE("GPL"); | 181 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index a8b3148e03a2..e288a4a06fe8 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c | |||
| @@ -34,19 +34,7 @@ static struct hid_driver hid_generic = { | |||
| 34 | .name = "hid-generic", | 34 | .name = "hid-generic", |
| 35 | .id_table = hid_table, | 35 | .id_table = hid_table, |
| 36 | }; | 36 | }; |
| 37 | 37 | module_hid_driver(hid_generic); | |
| 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 | 38 | ||
| 51 | MODULE_AUTHOR("Henrik Rydberg"); | 39 | MODULE_AUTHOR("Henrik Rydberg"); |
| 52 | MODULE_DESCRIPTION("HID generic driver"); | 40 | MODULE_DESCRIPTION("HID generic driver"); |
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c index 4442c30ef531..288d61c9748e 100644 --- a/drivers/hid/hid-gyration.c +++ b/drivers/hid/hid-gyration.c | |||
| @@ -88,17 +88,6 @@ static struct hid_driver gyration_driver = { | |||
| 88 | .input_mapping = gyration_input_mapping, | 88 | .input_mapping = gyration_input_mapping, |
| 89 | .event = gyration_event, | 89 | .event = gyration_event, |
| 90 | }; | 90 | }; |
| 91 | module_hid_driver(gyration_driver); | ||
| 91 | 92 | ||
| 92 | static int __init gyration_init(void) | ||
| 93 | { | ||
| 94 | return hid_register_driver(&gyration_driver); | ||
| 95 | } | ||
| 96 | |||
| 97 | static void __exit gyration_exit(void) | ||
| 98 | { | ||
| 99 | hid_unregister_driver(&gyration_driver); | ||
| 100 | } | ||
| 101 | |||
| 102 | module_init(gyration_init); | ||
| 103 | module_exit(gyration_exit); | ||
| 104 | MODULE_LICENSE("GPL"); | 93 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c index e0a5d1739fc3..6e1a4a4fc0c1 100644 --- a/drivers/hid/hid-holtek-kbd.c +++ b/drivers/hid/hid-holtek-kbd.c | |||
| @@ -167,17 +167,6 @@ static struct hid_driver holtek_kbd_driver = { | |||
| 167 | .report_fixup = holtek_kbd_report_fixup, | 167 | .report_fixup = holtek_kbd_report_fixup, |
| 168 | .probe = holtek_kbd_probe | 168 | .probe = holtek_kbd_probe |
| 169 | }; | 169 | }; |
| 170 | module_hid_driver(holtek_kbd_driver); | ||
| 170 | 171 | ||
| 171 | static int __init holtek_kbd_init(void) | ||
| 172 | { | ||
| 173 | return hid_register_driver(&holtek_kbd_driver); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void __exit holtek_kbd_exit(void) | ||
| 177 | { | ||
| 178 | hid_unregister_driver(&holtek_kbd_driver); | ||
| 179 | } | ||
| 180 | |||
| 181 | module_exit(holtek_kbd_exit); | ||
| 182 | module_init(holtek_kbd_init); | ||
| 183 | MODULE_LICENSE("GPL"); | 172 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index ff295e60059b..f34d1186a3e1 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c | |||
| @@ -224,17 +224,4 @@ static struct hid_driver holtek_driver = { | |||
| 224 | .id_table = holtek_devices, | 224 | .id_table = holtek_devices, |
| 225 | .probe = holtek_probe, | 225 | .probe = holtek_probe, |
| 226 | }; | 226 | }; |
| 227 | 227 | module_hid_driver(holtek_driver); | |
| 228 | static int __init holtek_init(void) | ||
| 229 | { | ||
| 230 | return hid_register_driver(&holtek_driver); | ||
| 231 | } | ||
| 232 | |||
| 233 | static void __exit holtek_exit(void) | ||
| 234 | { | ||
| 235 | hid_unregister_driver(&holtek_driver); | ||
| 236 | } | ||
| 237 | |||
| 238 | module_init(holtek_init); | ||
| 239 | module_exit(holtek_exit); | ||
| 240 | |||
diff --git a/drivers/hid/hid-icade.c b/drivers/hid/hid-icade.c index 1d6565e37ba3..09dcc04595f3 100644 --- a/drivers/hid/hid-icade.c +++ b/drivers/hid/hid-icade.c | |||
| @@ -235,25 +235,8 @@ static struct hid_driver icade_driver = { | |||
| 235 | .input_mapped = icade_input_mapped, | 235 | .input_mapped = icade_input_mapped, |
| 236 | .input_mapping = icade_input_mapping, | 236 | .input_mapping = icade_input_mapping, |
| 237 | }; | 237 | }; |
| 238 | module_hid_driver(icade_driver); | ||
| 238 | 239 | ||
| 239 | static int __init icade_init(void) | ||
| 240 | { | ||
| 241 | int ret; | ||
| 242 | |||
| 243 | ret = hid_register_driver(&icade_driver); | ||
| 244 | if (ret) | ||
| 245 | pr_err("can't register icade driver\n"); | ||
| 246 | |||
| 247 | return ret; | ||
| 248 | } | ||
| 249 | |||
| 250 | static void __exit icade_exit(void) | ||
| 251 | { | ||
| 252 | hid_unregister_driver(&icade_driver); | ||
| 253 | } | ||
| 254 | |||
| 255 | module_init(icade_init); | ||
| 256 | module_exit(icade_exit); | ||
| 257 | MODULE_LICENSE("GPL"); | 240 | MODULE_LICENSE("GPL"); |
| 258 | MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); | 241 | MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); |
| 259 | MODULE_DESCRIPTION("ION iCade input driver"); | 242 | MODULE_DESCRIPTION("ION iCade input driver"); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 34e25471aeaa..6e5c2ffa8d96 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -445,6 +445,9 @@ | |||
| 445 | #define USB_VENDOR_ID_JESS 0x0c45 | 445 | #define USB_VENDOR_ID_JESS 0x0c45 |
| 446 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 | 446 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 |
| 447 | 447 | ||
| 448 | #define USB_VENDOR_ID_JESS2 0x0f30 | ||
| 449 | #define USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD 0x0111 | ||
| 450 | |||
| 448 | #define USB_VENDOR_ID_KBGEAR 0x084e | 451 | #define USB_VENDOR_ID_KBGEAR 0x084e |
| 449 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 452 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
| 450 | 453 | ||
| @@ -525,8 +528,8 @@ | |||
| 525 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 | 528 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 |
| 526 | #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 | 529 | #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 |
| 527 | #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 | 530 | #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 |
| 528 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 | ||
| 529 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 | 531 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 |
| 532 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 | ||
| 530 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 | 533 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 |
| 531 | #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 | 534 | #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 |
| 532 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 | 535 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 |
| @@ -597,6 +600,9 @@ | |||
| 597 | #define USB_VENDOR_ID_NEC 0x073e | 600 | #define USB_VENDOR_ID_NEC 0x073e |
| 598 | #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 | 601 | #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 |
| 599 | 602 | ||
| 603 | #define USB_VENDOR_ID_NEXIO 0x1870 | ||
| 604 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d | ||
| 605 | |||
| 600 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 | 606 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 |
| 601 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 | 607 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 |
| 602 | 608 | ||
| @@ -709,6 +715,7 @@ | |||
| 709 | 715 | ||
| 710 | #define USB_VENDOR_ID_SONY 0x054c | 716 | #define USB_VENDOR_ID_SONY 0x054c |
| 711 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b | 717 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b |
| 718 | #define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374 | ||
| 712 | #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 | 719 | #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 |
| 713 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 720 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
| 714 | #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f | 721 | #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f |
| @@ -726,6 +733,9 @@ | |||
| 726 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 | 733 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 |
| 727 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 | 734 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 |
| 728 | 735 | ||
| 736 | #define USB_VENDOR_ID_STEELSERIES 0x1038 | ||
| 737 | #define USB_DEVICE_ID_STEELSERIES_SRWS1 0x1410 | ||
| 738 | |||
| 729 | #define USB_VENDOR_ID_SUN 0x0430 | 739 | #define USB_VENDOR_ID_SUN 0x0430 |
| 730 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab | 740 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab |
| 731 | 741 | ||
| @@ -747,6 +757,9 @@ | |||
| 747 | #define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 | 757 | #define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 |
| 748 | #define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 | 758 | #define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 |
| 749 | 759 | ||
| 760 | #define USB_VENDOR_ID_THINGM 0x27b8 | ||
| 761 | #define USB_DEVICE_ID_BLINK1 0x01ed | ||
| 762 | |||
| 750 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f | 763 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f |
| 751 | 764 | ||
| 752 | #define USB_VENDOR_ID_TIVO 0x150a | 765 | #define USB_VENDOR_ID_TIVO 0x150a |
| @@ -794,6 +807,12 @@ | |||
| 794 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 | 807 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 |
| 795 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19 | 808 | #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19 |
| 796 | 809 | ||
| 810 | #define USB_VENDOR_ID_VELLEMAN 0x10cf | ||
| 811 | #define USB_DEVICE_ID_VELLEMAN_K8055_FIRST 0x5500 | ||
| 812 | #define USB_DEVICE_ID_VELLEMAN_K8055_LAST 0x5503 | ||
| 813 | #define USB_DEVICE_ID_VELLEMAN_K8061_FIRST 0x8061 | ||
| 814 | #define USB_DEVICE_ID_VELLEMAN_K8061_LAST 0x8068 | ||
| 815 | |||
| 797 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 816 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
| 798 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 817 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
| 799 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | 818 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 |
diff --git a/drivers/hid/hid-kensington.c b/drivers/hid/hid-kensington.c index a5b4016e9bd7..fe9a99dd8d08 100644 --- a/drivers/hid/hid-kensington.c +++ b/drivers/hid/hid-kensington.c | |||
| @@ -47,17 +47,6 @@ static struct hid_driver ks_driver = { | |||
| 47 | .id_table = ks_devices, | 47 | .id_table = ks_devices, |
| 48 | .input_mapping = ks_input_mapping, | 48 | .input_mapping = ks_input_mapping, |
| 49 | }; | 49 | }; |
| 50 | module_hid_driver(ks_driver); | ||
| 50 | 51 | ||
| 51 | static int __init ks_init(void) | ||
| 52 | { | ||
| 53 | return hid_register_driver(&ks_driver); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void __exit ks_exit(void) | ||
| 57 | { | ||
| 58 | hid_unregister_driver(&ks_driver); | ||
| 59 | } | ||
| 60 | |||
| 61 | module_init(ks_init); | ||
| 62 | module_exit(ks_exit); | ||
| 63 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-keytouch.c b/drivers/hid/hid-keytouch.c index 07cd825f6f01..3074671b7d6a 100644 --- a/drivers/hid/hid-keytouch.c +++ b/drivers/hid/hid-keytouch.c | |||
| @@ -49,18 +49,7 @@ static struct hid_driver keytouch_driver = { | |||
| 49 | .id_table = keytouch_devices, | 49 | .id_table = keytouch_devices, |
| 50 | .report_fixup = keytouch_report_fixup, | 50 | .report_fixup = keytouch_report_fixup, |
| 51 | }; | 51 | }; |
| 52 | module_hid_driver(keytouch_driver); | ||
| 52 | 53 | ||
| 53 | static int __init keytouch_init(void) | ||
| 54 | { | ||
| 55 | return hid_register_driver(&keytouch_driver); | ||
| 56 | } | ||
| 57 | |||
| 58 | static void __exit keytouch_exit(void) | ||
| 59 | { | ||
| 60 | hid_unregister_driver(&keytouch_driver); | ||
| 61 | } | ||
| 62 | |||
| 63 | module_init(keytouch_init); | ||
| 64 | module_exit(keytouch_exit); | ||
| 65 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
| 66 | MODULE_AUTHOR("Jiri Kosina"); | 55 | MODULE_AUTHOR("Jiri Kosina"); |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index b4f0d8216fd0..ef72daecfa16 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
| @@ -419,17 +419,6 @@ static struct hid_driver kye_driver = { | |||
| 419 | .probe = kye_probe, | 419 | .probe = kye_probe, |
| 420 | .report_fixup = kye_report_fixup, | 420 | .report_fixup = kye_report_fixup, |
| 421 | }; | 421 | }; |
| 422 | module_hid_driver(kye_driver); | ||
| 422 | 423 | ||
| 423 | static int __init kye_init(void) | ||
| 424 | { | ||
| 425 | return hid_register_driver(&kye_driver); | ||
| 426 | } | ||
| 427 | |||
| 428 | static void __exit kye_exit(void) | ||
| 429 | { | ||
| 430 | hid_unregister_driver(&kye_driver); | ||
| 431 | } | ||
| 432 | |||
| 433 | module_init(kye_init); | ||
| 434 | module_exit(kye_exit); | ||
| 435 | MODULE_LICENSE("GPL"); | 424 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-lcpower.c b/drivers/hid/hid-lcpower.c index 22bc14abdfa3..6424cfdb7737 100644 --- a/drivers/hid/hid-lcpower.c +++ b/drivers/hid/hid-lcpower.c | |||
| @@ -54,17 +54,6 @@ static struct hid_driver ts_driver = { | |||
| 54 | .id_table = ts_devices, | 54 | .id_table = ts_devices, |
| 55 | .input_mapping = ts_input_mapping, | 55 | .input_mapping = ts_input_mapping, |
| 56 | }; | 56 | }; |
| 57 | module_hid_driver(ts_driver); | ||
| 57 | 58 | ||
| 58 | static int __init ts_init(void) | ||
| 59 | { | ||
| 60 | return hid_register_driver(&ts_driver); | ||
| 61 | } | ||
| 62 | |||
| 63 | static void __exit ts_exit(void) | ||
| 64 | { | ||
| 65 | hid_unregister_driver(&ts_driver); | ||
| 66 | } | ||
| 67 | |||
| 68 | module_init(ts_init); | ||
| 69 | module_exit(ts_exit); | ||
| 70 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c index cea016e94f43..956c3b135f64 100644 --- a/drivers/hid/hid-lenovo-tpkbd.c +++ b/drivers/hid/hid-lenovo-tpkbd.c | |||
| @@ -468,18 +468,6 @@ static struct hid_driver tpkbd_driver = { | |||
| 468 | .probe = tpkbd_probe, | 468 | .probe = tpkbd_probe, |
| 469 | .remove = tpkbd_remove, | 469 | .remove = tpkbd_remove, |
| 470 | }; | 470 | }; |
| 471 | 471 | module_hid_driver(tpkbd_driver); | |
| 472 | static int __init tpkbd_init(void) | ||
| 473 | { | ||
| 474 | return hid_register_driver(&tpkbd_driver); | ||
| 475 | } | ||
| 476 | |||
| 477 | static void __exit tpkbd_exit(void) | ||
| 478 | { | ||
| 479 | hid_unregister_driver(&tpkbd_driver); | ||
| 480 | } | ||
| 481 | |||
| 482 | module_init(tpkbd_init); | ||
| 483 | module_exit(tpkbd_exit); | ||
| 484 | 472 | ||
| 485 | MODULE_LICENSE("GPL"); | 473 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a2f8e88b9fa2..6f12ecd36c88 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
| @@ -21,8 +21,10 @@ | |||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/usb.h> | ||
| 24 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
| 25 | 26 | ||
| 27 | #include "usbhid/usbhid.h" | ||
| 26 | #include "hid-ids.h" | 28 | #include "hid-ids.h" |
| 27 | #include "hid-lg.h" | 29 | #include "hid-lg.h" |
| 28 | 30 | ||
| @@ -40,17 +42,86 @@ | |||
| 40 | #define LG_FF3 0x1000 | 42 | #define LG_FF3 0x1000 |
| 41 | #define LG_FF4 0x2000 | 43 | #define LG_FF4 0x2000 |
| 42 | 44 | ||
| 43 | /* Size of the original descriptor of the Driving Force Pro wheel */ | 45 | /* Size of the original descriptors of the Driving Force (and Pro) wheels */ |
| 46 | #define DF_RDESC_ORIG_SIZE 130 | ||
| 44 | #define DFP_RDESC_ORIG_SIZE 97 | 47 | #define DFP_RDESC_ORIG_SIZE 97 |
| 48 | #define MOMO_RDESC_ORIG_SIZE 87 | ||
| 45 | 49 | ||
| 46 | /* Fixed report descriptor for Logitech Driving Force Pro wheel controller | 50 | /* Fixed report descriptors for Logitech Driving Force (and Pro) |
| 51 | * wheel controllers | ||
| 47 | * | 52 | * |
| 48 | * The original descriptor hides the separate throttle and brake axes in | 53 | * The original descriptors hide the separate throttle and brake axes in |
| 49 | * a custom vendor usage page, providing only a combined value as | 54 | * a custom vendor usage page, providing only a combined value as |
| 50 | * GenericDesktop.Y. | 55 | * GenericDesktop.Y. |
| 51 | * This descriptor removes the combined Y axis and instead reports | 56 | * These descriptors remove the combined Y axis and instead report |
| 52 | * separate throttle (Y) and brake (RZ). | 57 | * separate throttle (Y) and brake (RZ). |
| 53 | */ | 58 | */ |
| 59 | static __u8 df_rdesc_fixed[] = { | ||
| 60 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 61 | 0x09, 0x04, /* Usage (Joystik), */ | ||
| 62 | 0xA1, 0x01, /* Collection (Application), */ | ||
| 63 | 0xA1, 0x02, /* Collection (Logical), */ | ||
| 64 | 0x95, 0x01, /* Report Count (1), */ | ||
| 65 | 0x75, 0x0A, /* Report Size (10), */ | ||
| 66 | 0x14, /* Logical Minimum (0), */ | ||
| 67 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
| 68 | 0x34, /* Physical Minimum (0), */ | ||
| 69 | 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ | ||
| 70 | 0x09, 0x30, /* Usage (X), */ | ||
| 71 | 0x81, 0x02, /* Input (Variable), */ | ||
| 72 | 0x95, 0x0C, /* Report Count (12), */ | ||
| 73 | 0x75, 0x01, /* Report Size (1), */ | ||
| 74 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
| 75 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
| 76 | 0x05, 0x09, /* Usage (Buttons), */ | ||
| 77 | 0x19, 0x01, /* Usage Minimum (1), */ | ||
| 78 | 0x29, 0x0c, /* Usage Maximum (12), */ | ||
| 79 | 0x81, 0x02, /* Input (Variable), */ | ||
| 80 | 0x95, 0x02, /* Report Count (2), */ | ||
| 81 | 0x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */ | ||
| 82 | 0x09, 0x01, /* Usage (?: 1), */ | ||
| 83 | 0x81, 0x02, /* Input (Variable), */ | ||
| 84 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 85 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
| 86 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
| 87 | 0x95, 0x01, /* Report Count (1), */ | ||
| 88 | 0x75, 0x08, /* Report Size (8), */ | ||
| 89 | 0x81, 0x02, /* Input (Variable), */ | ||
| 90 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
| 91 | 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ | ||
| 92 | 0x75, 0x04, /* Report Size (4), */ | ||
| 93 | 0x65, 0x14, /* Unit (Degrees), */ | ||
| 94 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
| 95 | 0x81, 0x42, /* Input (Variable, Null State), */ | ||
| 96 | 0x75, 0x01, /* Report Size (1), */ | ||
| 97 | 0x95, 0x04, /* Report Count (4), */ | ||
| 98 | 0x65, 0x00, /* Unit (none), */ | ||
| 99 | 0x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */ | ||
| 100 | 0x09, 0x01, /* Usage (?: 1), */ | ||
| 101 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
| 102 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
| 103 | 0x81, 0x02, /* Input (Variable), */ | ||
| 104 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 105 | 0x95, 0x01, /* Report Count (1), */ | ||
| 106 | 0x75, 0x08, /* Report Size (8), */ | ||
| 107 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
| 108 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
| 109 | 0x09, 0x31, /* Usage (Y), */ | ||
| 110 | 0x81, 0x02, /* Input (Variable), */ | ||
| 111 | 0x09, 0x35, /* Usage (Rz), */ | ||
| 112 | 0x81, 0x02, /* Input (Variable), */ | ||
| 113 | 0xC0, /* End Collection, */ | ||
| 114 | 0xA1, 0x02, /* Collection (Logical), */ | ||
| 115 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
| 116 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
| 117 | 0x95, 0x07, /* Report Count (7), */ | ||
| 118 | 0x75, 0x08, /* Report Size (8), */ | ||
| 119 | 0x09, 0x03, /* Usage (?: 3), */ | ||
| 120 | 0x91, 0x02, /* Output (Variable), */ | ||
| 121 | 0xC0, /* End Collection, */ | ||
| 122 | 0xC0 /* End Collection */ | ||
| 123 | }; | ||
| 124 | |||
| 54 | static __u8 dfp_rdesc_fixed[] = { | 125 | static __u8 dfp_rdesc_fixed[] = { |
| 55 | 0x05, 0x01, /* Usage Page (Desktop), */ | 126 | 0x05, 0x01, /* Usage Page (Desktop), */ |
| 56 | 0x09, 0x04, /* Usage (Joystik), */ | 127 | 0x09, 0x04, /* Usage (Joystik), */ |
| @@ -99,6 +170,51 @@ static __u8 dfp_rdesc_fixed[] = { | |||
| 99 | 0xC0 /* End Collection */ | 170 | 0xC0 /* End Collection */ |
| 100 | }; | 171 | }; |
| 101 | 172 | ||
| 173 | static __u8 momo_rdesc_fixed[] = { | ||
| 174 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 175 | 0x09, 0x04, /* Usage (Joystik), */ | ||
| 176 | 0xA1, 0x01, /* Collection (Application), */ | ||
| 177 | 0xA1, 0x02, /* Collection (Logical), */ | ||
| 178 | 0x95, 0x01, /* Report Count (1), */ | ||
| 179 | 0x75, 0x0A, /* Report Size (10), */ | ||
| 180 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
| 181 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
| 182 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
| 183 | 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ | ||
| 184 | 0x09, 0x30, /* Usage (X), */ | ||
| 185 | 0x81, 0x02, /* Input (Variable), */ | ||
| 186 | 0x95, 0x08, /* Report Count (8), */ | ||
| 187 | 0x75, 0x01, /* Report Size (1), */ | ||
| 188 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
| 189 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
| 190 | 0x05, 0x09, /* Usage Page (Button), */ | ||
| 191 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
| 192 | 0x29, 0x08, /* Usage Maximum (08h), */ | ||
| 193 | 0x81, 0x02, /* Input (Variable), */ | ||
| 194 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
| 195 | 0x75, 0x0E, /* Report Size (14), */ | ||
| 196 | 0x95, 0x01, /* Report Count (1), */ | ||
| 197 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
| 198 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
| 199 | 0x09, 0x00, /* Usage (00h), */ | ||
| 200 | 0x81, 0x02, /* Input (Variable), */ | ||
| 201 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 202 | 0x75, 0x08, /* Report Size (8), */ | ||
| 203 | 0x09, 0x31, /* Usage (Y), */ | ||
| 204 | 0x81, 0x02, /* Input (Variable), */ | ||
| 205 | 0x09, 0x32, /* Usage (Z), */ | ||
| 206 | 0x81, 0x02, /* Input (Variable), */ | ||
| 207 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
| 208 | 0x09, 0x01, /* Usage (01h), */ | ||
| 209 | 0x81, 0x02, /* Input (Variable), */ | ||
| 210 | 0xC0, /* End Collection, */ | ||
| 211 | 0xA1, 0x02, /* Collection (Logical), */ | ||
| 212 | 0x09, 0x02, /* Usage (02h), */ | ||
| 213 | 0x95, 0x07, /* Report Count (7), */ | ||
| 214 | 0x91, 0x02, /* Output (Variable), */ | ||
| 215 | 0xC0, /* End Collection, */ | ||
| 216 | 0xC0 /* End Collection */ | ||
| 217 | }; | ||
| 102 | 218 | ||
| 103 | /* | 219 | /* |
| 104 | * Certain Logitech keyboards send in report #3 keys which are far | 220 | * Certain Logitech keyboards send in report #3 keys which are far |
| @@ -109,6 +225,8 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 109 | unsigned int *rsize) | 225 | unsigned int *rsize) |
| 110 | { | 226 | { |
| 111 | struct lg_drv_data *drv_data = hid_get_drvdata(hdev); | 227 | struct lg_drv_data *drv_data = hid_get_drvdata(hdev); |
| 228 | struct usb_device_descriptor *udesc; | ||
| 229 | __u16 bcdDevice, rev_maj, rev_min; | ||
| 112 | 230 | ||
| 113 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | 231 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && |
| 114 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 232 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
| @@ -124,17 +242,39 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 124 | "fixing up rel/abs in Logitech report descriptor\n"); | 242 | "fixing up rel/abs in Logitech report descriptor\n"); |
| 125 | rdesc[33] = rdesc[50] = 0x02; | 243 | rdesc[33] = rdesc[50] = 0x02; |
| 126 | } | 244 | } |
| 127 | if ((drv_data->quirks & LG_FF4) && *rsize >= 101 && | ||
| 128 | rdesc[41] == 0x95 && rdesc[42] == 0x0B && | ||
| 129 | rdesc[47] == 0x05 && rdesc[48] == 0x09) { | ||
| 130 | hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n"); | ||
| 131 | rdesc[41] = 0x05; | ||
| 132 | rdesc[42] = 0x09; | ||
| 133 | rdesc[47] = 0x95; | ||
| 134 | rdesc[48] = 0x0B; | ||
| 135 | } | ||
| 136 | 245 | ||
| 137 | switch (hdev->product) { | 246 | switch (hdev->product) { |
| 247 | |||
| 248 | /* Several wheels report as this id when operating in emulation mode. */ | ||
| 249 | case USB_DEVICE_ID_LOGITECH_WHEEL: | ||
| 250 | udesc = &(hid_to_usb_dev(hdev)->descriptor); | ||
| 251 | if (!udesc) { | ||
| 252 | hid_err(hdev, "NULL USB device descriptor\n"); | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | bcdDevice = le16_to_cpu(udesc->bcdDevice); | ||
| 256 | rev_maj = bcdDevice >> 8; | ||
| 257 | rev_min = bcdDevice & 0xff; | ||
| 258 | |||
| 259 | /* Update the report descriptor for only the Driving Force wheel */ | ||
| 260 | if (rev_maj == 1 && rev_min == 2 && | ||
| 261 | *rsize == DF_RDESC_ORIG_SIZE) { | ||
| 262 | hid_info(hdev, | ||
| 263 | "fixing up Logitech Driving Force report descriptor\n"); | ||
| 264 | rdesc = df_rdesc_fixed; | ||
| 265 | *rsize = sizeof(df_rdesc_fixed); | ||
| 266 | } | ||
| 267 | break; | ||
| 268 | |||
| 269 | case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: | ||
| 270 | if (*rsize == MOMO_RDESC_ORIG_SIZE) { | ||
| 271 | hid_info(hdev, | ||
| 272 | "fixing up Logitech Momo Force (Red) report descriptor\n"); | ||
| 273 | rdesc = momo_rdesc_fixed; | ||
| 274 | *rsize = sizeof(momo_rdesc_fixed); | ||
| 275 | } | ||
| 276 | break; | ||
| 277 | |||
| 138 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: | 278 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: |
| 139 | if (*rsize == DFP_RDESC_ORIG_SIZE) { | 279 | if (*rsize == DFP_RDESC_ORIG_SIZE) { |
| 140 | hid_info(hdev, | 280 | hid_info(hdev, |
| @@ -143,6 +283,17 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 143 | *rsize = sizeof(dfp_rdesc_fixed); | 283 | *rsize = sizeof(dfp_rdesc_fixed); |
| 144 | } | 284 | } |
| 145 | break; | 285 | break; |
| 286 | |||
| 287 | case USB_DEVICE_ID_LOGITECH_WII_WHEEL: | ||
| 288 | if (*rsize >= 101 && rdesc[41] == 0x95 && rdesc[42] == 0x0B && | ||
| 289 | rdesc[47] == 0x05 && rdesc[48] == 0x09) { | ||
| 290 | hid_info(hdev, "fixing up Logitech Speed Force Wireless report descriptor\n"); | ||
| 291 | rdesc[41] = 0x05; | ||
| 292 | rdesc[42] = 0x09; | ||
| 293 | rdesc[47] = 0x95; | ||
| 294 | rdesc[48] = 0x0B; | ||
| 295 | } | ||
| 296 | break; | ||
| 146 | } | 297 | } |
| 147 | 298 | ||
| 148 | return rdesc; | 299 | return rdesc; |
| @@ -328,6 +479,26 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
| 328 | usage->type == EV_REL || usage->type == EV_ABS)) | 479 | usage->type == EV_REL || usage->type == EV_ABS)) |
| 329 | clear_bit(usage->code, *bit); | 480 | clear_bit(usage->code, *bit); |
| 330 | 481 | ||
| 482 | /* Ensure that Logitech wheels are not given a default fuzz/flat value */ | ||
| 483 | if (usage->type == EV_ABS && (usage->code == ABS_X || | ||
| 484 | usage->code == ABS_Y || usage->code == ABS_Z || | ||
| 485 | usage->code == ABS_RZ)) { | ||
| 486 | switch (hdev->product) { | ||
| 487 | case USB_DEVICE_ID_LOGITECH_WHEEL: | ||
| 488 | case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: | ||
| 489 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: | ||
| 490 | case USB_DEVICE_ID_LOGITECH_G25_WHEEL: | ||
| 491 | case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: | ||
| 492 | case USB_DEVICE_ID_LOGITECH_G27_WHEEL: | ||
| 493 | case USB_DEVICE_ID_LOGITECH_WII_WHEEL: | ||
| 494 | case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2: | ||
| 495 | field->application = HID_GD_MULTIAXIS; | ||
| 496 | break; | ||
| 497 | default: | ||
| 498 | break; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 331 | return 0; | 502 | return 0; |
| 332 | } | 503 | } |
| 333 | 504 | ||
| @@ -465,7 +636,7 @@ static const struct hid_device_id lg_devices[] = { | |||
| 465 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), | 636 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), |
| 466 | .driver_data = LG_FF }, | 637 | .driver_data = LG_FF }, |
| 467 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), | 638 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), |
| 468 | .driver_data = LG_FF4 }, | 639 | .driver_data = LG_NOGET | LG_FF4 }, |
| 469 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), | 640 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), |
| 470 | .driver_data = LG_FF4 }, | 641 | .driver_data = LG_FF4 }, |
| 471 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), | 642 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), |
| @@ -503,17 +674,6 @@ static struct hid_driver lg_driver = { | |||
| 503 | .probe = lg_probe, | 674 | .probe = lg_probe, |
| 504 | .remove = lg_remove, | 675 | .remove = lg_remove, |
| 505 | }; | 676 | }; |
| 677 | module_hid_driver(lg_driver); | ||
| 506 | 678 | ||
| 507 | static int __init lg_init(void) | ||
| 508 | { | ||
| 509 | return hid_register_driver(&lg_driver); | ||
| 510 | } | ||
| 511 | |||
| 512 | static void __exit lg_exit(void) | ||
| 513 | { | ||
| 514 | hid_unregister_driver(&lg_driver); | ||
| 515 | } | ||
| 516 | |||
| 517 | module_init(lg_init); | ||
| 518 | module_exit(lg_exit); | ||
| 519 | MODULE_LICENSE("GPL"); | 679 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index d7947c701f30..65a6ec8d3742 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
| @@ -43,11 +43,6 @@ | |||
| 43 | #define G27_REV_MAJ 0x12 | 43 | #define G27_REV_MAJ 0x12 |
| 44 | #define G27_REV_MIN 0x38 | 44 | #define G27_REV_MIN 0x38 |
| 45 | 45 | ||
| 46 | #define DFP_X_MIN 0 | ||
| 47 | #define DFP_X_MAX 16383 | ||
| 48 | #define DFP_PEDAL_MIN 0 | ||
| 49 | #define DFP_PEDAL_MAX 255 | ||
| 50 | |||
| 51 | #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) | 46 | #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) |
| 52 | 47 | ||
| 53 | static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); | 48 | static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); |
| @@ -598,18 +593,6 @@ int lg4ff_init(struct hid_device *hid) | |||
| 598 | return error; | 593 | return error; |
| 599 | dbg_hid("sysfs interface created\n"); | 594 | dbg_hid("sysfs interface created\n"); |
| 600 | 595 | ||
| 601 | /* Set default axes parameters */ | ||
| 602 | switch (lg4ff_devices[i].product_id) { | ||
| 603 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: | ||
| 604 | dbg_hid("Setting axes parameters for Driving Force Pro\n"); | ||
| 605 | input_set_abs_params(dev, ABS_X, DFP_X_MIN, DFP_X_MAX, 0, 0); | ||
| 606 | input_set_abs_params(dev, ABS_Y, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0); | ||
| 607 | input_set_abs_params(dev, ABS_RZ, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0); | ||
| 608 | break; | ||
| 609 | default: | ||
| 610 | break; | ||
| 611 | } | ||
| 612 | |||
| 613 | /* Set the maximum range to start with */ | 596 | /* Set the maximum range to start with */ |
| 614 | entry->range = entry->max_range; | 597 | entry->range = entry->max_range; |
| 615 | if (entry->set_range != NULL) | 598 | if (entry->set_range != NULL) |
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 25ddf3e3aec6..f7f113ba083e 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
| @@ -569,23 +569,6 @@ static struct hid_driver magicmouse_driver = { | |||
| 569 | .raw_event = magicmouse_raw_event, | 569 | .raw_event = magicmouse_raw_event, |
| 570 | .input_mapping = magicmouse_input_mapping, | 570 | .input_mapping = magicmouse_input_mapping, |
| 571 | }; | 571 | }; |
| 572 | module_hid_driver(magicmouse_driver); | ||
| 572 | 573 | ||
| 573 | static int __init magicmouse_init(void) | ||
| 574 | { | ||
| 575 | int ret; | ||
| 576 | |||
| 577 | ret = hid_register_driver(&magicmouse_driver); | ||
| 578 | if (ret) | ||
| 579 | pr_err("can't register magicmouse driver\n"); | ||
| 580 | |||
| 581 | return ret; | ||
| 582 | } | ||
| 583 | |||
| 584 | static void __exit magicmouse_exit(void) | ||
| 585 | { | ||
| 586 | hid_unregister_driver(&magicmouse_driver); | ||
| 587 | } | ||
| 588 | |||
| 589 | module_init(magicmouse_init); | ||
| 590 | module_exit(magicmouse_exit); | ||
| 591 | MODULE_LICENSE("GPL"); | 574 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 6fcd466d0825..29d27f65a118 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
| @@ -221,17 +221,6 @@ static struct hid_driver ms_driver = { | |||
| 221 | .event = ms_event, | 221 | .event = ms_event, |
| 222 | .probe = ms_probe, | 222 | .probe = ms_probe, |
| 223 | }; | 223 | }; |
| 224 | module_hid_driver(ms_driver); | ||
| 224 | 225 | ||
| 225 | static int __init ms_init(void) | ||
| 226 | { | ||
| 227 | return hid_register_driver(&ms_driver); | ||
| 228 | } | ||
| 229 | |||
| 230 | static void __exit ms_exit(void) | ||
| 231 | { | ||
| 232 | hid_unregister_driver(&ms_driver); | ||
| 233 | } | ||
| 234 | |||
| 235 | module_init(ms_init); | ||
| 236 | module_exit(ms_exit); | ||
| 237 | MODULE_LICENSE("GPL"); | 226 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c index cd3643e06fa6..9e14c00eb1b6 100644 --- a/drivers/hid/hid-monterey.c +++ b/drivers/hid/hid-monterey.c | |||
| @@ -63,17 +63,6 @@ static struct hid_driver mr_driver = { | |||
| 63 | .report_fixup = mr_report_fixup, | 63 | .report_fixup = mr_report_fixup, |
| 64 | .input_mapping = mr_input_mapping, | 64 | .input_mapping = mr_input_mapping, |
| 65 | }; | 65 | }; |
| 66 | module_hid_driver(mr_driver); | ||
| 66 | 67 | ||
| 67 | static int __init mr_init(void) | ||
| 68 | { | ||
| 69 | return hid_register_driver(&mr_driver); | ||
| 70 | } | ||
| 71 | |||
| 72 | static void __exit mr_exit(void) | ||
| 73 | { | ||
| 74 | hid_unregister_driver(&mr_driver); | ||
| 75 | } | ||
| 76 | |||
| 77 | module_init(mr_init); | ||
| 78 | module_exit(mr_exit); | ||
| 79 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 61543c02ea0b..7a1ebb867cf4 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -54,6 +54,7 @@ MODULE_LICENSE("GPL"); | |||
| 54 | #define MT_QUIRK_NO_AREA (1 << 9) | 54 | #define MT_QUIRK_NO_AREA (1 << 9) |
| 55 | #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) | 55 | #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) |
| 56 | #define MT_QUIRK_HOVERING (1 << 11) | 56 | #define MT_QUIRK_HOVERING (1 << 11) |
| 57 | #define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) | ||
| 57 | 58 | ||
| 58 | struct mt_slot { | 59 | struct mt_slot { |
| 59 | __s32 x, y, cx, cy, p, w, h; | 60 | __s32 x, y, cx, cy, p, w, h; |
| @@ -83,8 +84,11 @@ struct mt_device { | |||
| 83 | struct mt_class mtclass; /* our mt device class */ | 84 | struct mt_class mtclass; /* our mt device class */ |
| 84 | struct mt_fields *fields; /* temporary placeholder for storing the | 85 | struct mt_fields *fields; /* temporary placeholder for storing the |
| 85 | multitouch fields */ | 86 | multitouch fields */ |
| 87 | int cc_index; /* contact count field index in the report */ | ||
| 88 | int cc_value_index; /* contact count value index in the field */ | ||
| 86 | unsigned last_field_index; /* last field index of the report */ | 89 | unsigned last_field_index; /* last field index of the report */ |
| 87 | unsigned last_slot_field; /* the last field of a slot */ | 90 | unsigned last_slot_field; /* the last field of a slot */ |
| 91 | unsigned mt_report_id; /* the report ID of the multitouch device */ | ||
| 88 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 92 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
| 89 | __s8 inputmode_index; /* InputMode HID feature index in the report */ | 93 | __s8 inputmode_index; /* InputMode HID feature index in the report */ |
| 90 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, | 94 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, |
| @@ -111,6 +115,9 @@ struct mt_device { | |||
| 111 | #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007 | 115 | #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007 |
| 112 | #define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 | 116 | #define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 |
| 113 | #define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 | 117 | #define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 |
| 118 | #define MT_CLS_NSMU 0x000a | ||
| 119 | #define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 | ||
| 120 | #define MT_CLS_DUAL_CONTACT_ID 0x0011 | ||
| 114 | 121 | ||
| 115 | /* vendor specific classes */ | 122 | /* vendor specific classes */ |
| 116 | #define MT_CLS_3M 0x0101 | 123 | #define MT_CLS_3M 0x0101 |
| @@ -144,6 +151,9 @@ static int cypress_compute_slot(struct mt_device *td) | |||
| 144 | 151 | ||
| 145 | static struct mt_class mt_classes[] = { | 152 | static struct mt_class mt_classes[] = { |
| 146 | { .name = MT_CLS_DEFAULT, | 153 | { .name = MT_CLS_DEFAULT, |
| 154 | .quirks = MT_QUIRK_ALWAYS_VALID | | ||
| 155 | MT_QUIRK_CONTACT_CNT_ACCURATE }, | ||
| 156 | { .name = MT_CLS_NSMU, | ||
| 147 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, | 157 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, |
| 148 | { .name = MT_CLS_SERIAL, | 158 | { .name = MT_CLS_SERIAL, |
| 149 | .quirks = MT_QUIRK_ALWAYS_VALID}, | 159 | .quirks = MT_QUIRK_ALWAYS_VALID}, |
| @@ -170,6 +180,16 @@ static struct mt_class mt_classes[] = { | |||
| 170 | { .name = MT_CLS_INRANGE_CONTACTNUMBER, | 180 | { .name = MT_CLS_INRANGE_CONTACTNUMBER, |
| 171 | .quirks = MT_QUIRK_VALID_IS_INRANGE | | 181 | .quirks = MT_QUIRK_VALID_IS_INRANGE | |
| 172 | MT_QUIRK_SLOT_IS_CONTACTNUMBER }, | 182 | MT_QUIRK_SLOT_IS_CONTACTNUMBER }, |
| 183 | { .name = MT_CLS_DUAL_CONTACT_NUMBER, | ||
| 184 | .quirks = MT_QUIRK_ALWAYS_VALID | | ||
| 185 | MT_QUIRK_CONTACT_CNT_ACCURATE | | ||
| 186 | MT_QUIRK_SLOT_IS_CONTACTNUMBER, | ||
| 187 | .maxcontacts = 2 }, | ||
| 188 | { .name = MT_CLS_DUAL_CONTACT_ID, | ||
| 189 | .quirks = MT_QUIRK_ALWAYS_VALID | | ||
| 190 | MT_QUIRK_CONTACT_CNT_ACCURATE | | ||
| 191 | MT_QUIRK_SLOT_IS_CONTACTID, | ||
| 192 | .maxcontacts = 2 }, | ||
| 173 | 193 | ||
| 174 | /* | 194 | /* |
| 175 | * vendor specific classes | 195 | * vendor specific classes |
| @@ -250,6 +270,9 @@ static ssize_t mt_set_quirks(struct device *dev, | |||
| 250 | 270 | ||
| 251 | td->mtclass.quirks = val; | 271 | td->mtclass.quirks = val; |
| 252 | 272 | ||
| 273 | if (td->cc_index < 0) | ||
| 274 | td->mtclass.quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; | ||
| 275 | |||
| 253 | return count; | 276 | return count; |
| 254 | } | 277 | } |
| 255 | 278 | ||
| @@ -301,6 +324,7 @@ static void mt_feature_mapping(struct hid_device *hdev, | |||
| 301 | *quirks |= MT_QUIRK_ALWAYS_VALID; | 324 | *quirks |= MT_QUIRK_ALWAYS_VALID; |
| 302 | *quirks |= MT_QUIRK_IGNORE_DUPLICATES; | 325 | *quirks |= MT_QUIRK_IGNORE_DUPLICATES; |
| 303 | *quirks |= MT_QUIRK_HOVERING; | 326 | *quirks |= MT_QUIRK_HOVERING; |
| 327 | *quirks |= MT_QUIRK_CONTACT_CNT_ACCURATE; | ||
| 304 | *quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | 328 | *quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; |
| 305 | *quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | 329 | *quirks &= ~MT_QUIRK_VALID_IS_INRANGE; |
| 306 | *quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; | 330 | *quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; |
| @@ -428,6 +452,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 428 | mt_store_field(usage, td, hi); | 452 | mt_store_field(usage, td, hi); |
| 429 | td->last_field_index = field->index; | 453 | td->last_field_index = field->index; |
| 430 | td->touches_by_report++; | 454 | td->touches_by_report++; |
| 455 | td->mt_report_id = field->report->id; | ||
| 431 | return 1; | 456 | return 1; |
| 432 | case HID_DG_WIDTH: | 457 | case HID_DG_WIDTH: |
| 433 | hid_map_usage(hi, usage, bit, max, | 458 | hid_map_usage(hi, usage, bit, max, |
| @@ -459,6 +484,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 459 | td->last_field_index = field->index; | 484 | td->last_field_index = field->index; |
| 460 | return 1; | 485 | return 1; |
| 461 | case HID_DG_CONTACTCOUNT: | 486 | case HID_DG_CONTACTCOUNT: |
| 487 | td->cc_index = field->index; | ||
| 488 | td->cc_value_index = usage->usage_index; | ||
| 462 | td->last_field_index = field->index; | 489 | td->last_field_index = field->index; |
| 463 | return 1; | 490 | return 1; |
| 464 | case HID_DG_CONTACTMAX: | 491 | case HID_DG_CONTACTMAX: |
| @@ -523,6 +550,10 @@ static int mt_compute_slot(struct mt_device *td, struct input_dev *input) | |||
| 523 | */ | 550 | */ |
| 524 | static void mt_complete_slot(struct mt_device *td, struct input_dev *input) | 551 | static void mt_complete_slot(struct mt_device *td, struct input_dev *input) |
| 525 | { | 552 | { |
| 553 | if ((td->mtclass.quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) && | ||
| 554 | td->num_received >= td->num_expected) | ||
| 555 | return; | ||
| 556 | |||
| 526 | if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { | 557 | if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { |
| 527 | int slotnum = mt_compute_slot(td, input); | 558 | int slotnum = mt_compute_slot(td, input); |
| 528 | struct mt_slot *s = &td->curdata; | 559 | struct mt_slot *s = &td->curdata; |
| @@ -578,6 +609,16 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) | |||
| 578 | static int mt_event(struct hid_device *hid, struct hid_field *field, | 609 | static int mt_event(struct hid_device *hid, struct hid_field *field, |
| 579 | struct hid_usage *usage, __s32 value) | 610 | struct hid_usage *usage, __s32 value) |
| 580 | { | 611 | { |
| 612 | /* we will handle the hidinput part later, now remains hiddev */ | ||
| 613 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | ||
| 614 | hid->hiddev_hid_event(hid, field, usage, value); | ||
| 615 | |||
| 616 | return 1; | ||
| 617 | } | ||
| 618 | |||
| 619 | static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | ||
| 620 | struct hid_usage *usage, __s32 value) | ||
| 621 | { | ||
| 581 | struct mt_device *td = hid_get_drvdata(hid); | 622 | struct mt_device *td = hid_get_drvdata(hid); |
| 582 | __s32 quirks = td->mtclass.quirks; | 623 | __s32 quirks = td->mtclass.quirks; |
| 583 | 624 | ||
| @@ -623,20 +664,13 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
| 623 | td->curdata.h = value; | 664 | td->curdata.h = value; |
| 624 | break; | 665 | break; |
| 625 | case HID_DG_CONTACTCOUNT: | 666 | case HID_DG_CONTACTCOUNT: |
| 626 | /* | ||
| 627 | * Includes multi-packet support where subsequent | ||
| 628 | * packets are sent with zero contactcount. | ||
| 629 | */ | ||
| 630 | if (value) | ||
| 631 | td->num_expected = value; | ||
| 632 | break; | 667 | break; |
| 633 | case HID_DG_TOUCH: | 668 | case HID_DG_TOUCH: |
| 634 | /* do nothing */ | 669 | /* do nothing */ |
| 635 | break; | 670 | break; |
| 636 | 671 | ||
| 637 | default: | 672 | default: |
| 638 | /* fallback to the generic hidinput handling */ | 673 | return; |
| 639 | return 0; | ||
| 640 | } | 674 | } |
| 641 | 675 | ||
| 642 | if (usage->usage_index + 1 == field->report_count) { | 676 | if (usage->usage_index + 1 == field->report_count) { |
| @@ -650,12 +684,43 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, | |||
| 650 | } | 684 | } |
| 651 | 685 | ||
| 652 | } | 686 | } |
| 687 | } | ||
| 653 | 688 | ||
| 654 | /* we have handled the hidinput part, now remains hiddev */ | 689 | static void mt_report(struct hid_device *hid, struct hid_report *report) |
| 655 | if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) | 690 | { |
| 656 | hid->hiddev_hid_event(hid, field, usage, value); | 691 | struct mt_device *td = hid_get_drvdata(hid); |
| 692 | struct hid_field *field; | ||
| 693 | unsigned count; | ||
| 694 | int r, n; | ||
| 657 | 695 | ||
| 658 | return 1; | 696 | if (report->id != td->mt_report_id) |
| 697 | return; | ||
| 698 | |||
| 699 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
| 700 | return; | ||
| 701 | |||
| 702 | /* | ||
| 703 | * Includes multi-packet support where subsequent | ||
| 704 | * packets are sent with zero contactcount. | ||
| 705 | */ | ||
| 706 | if (td->cc_index >= 0) { | ||
| 707 | struct hid_field *field = report->field[td->cc_index]; | ||
| 708 | int value = field->value[td->cc_value_index]; | ||
| 709 | if (value) | ||
| 710 | td->num_expected = value; | ||
| 711 | } | ||
| 712 | |||
| 713 | for (r = 0; r < report->maxfield; r++) { | ||
| 714 | field = report->field[r]; | ||
| 715 | count = field->report_count; | ||
| 716 | |||
| 717 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) | ||
| 718 | continue; | ||
| 719 | |||
| 720 | for (n = 0; n < count; n++) | ||
| 721 | mt_process_mt_event(hid, field, &field->usage[n], | ||
| 722 | field->value[n]); | ||
| 723 | } | ||
| 659 | } | 724 | } |
| 660 | 725 | ||
| 661 | static void mt_set_input_mode(struct hid_device *hdev) | 726 | static void mt_set_input_mode(struct hid_device *hdev) |
| @@ -711,6 +776,7 @@ static void mt_post_parse_default_settings(struct mt_device *td) | |||
| 711 | quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; | 776 | quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; |
| 712 | quirks &= ~MT_QUIRK_VALID_IS_INRANGE; | 777 | quirks &= ~MT_QUIRK_VALID_IS_INRANGE; |
| 713 | quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; | 778 | quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; |
| 779 | quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; | ||
| 714 | } | 780 | } |
| 715 | 781 | ||
| 716 | td->mtclass.quirks = quirks; | 782 | td->mtclass.quirks = quirks; |
| @@ -719,11 +785,15 @@ static void mt_post_parse_default_settings(struct mt_device *td) | |||
| 719 | static void mt_post_parse(struct mt_device *td) | 785 | static void mt_post_parse(struct mt_device *td) |
| 720 | { | 786 | { |
| 721 | struct mt_fields *f = td->fields; | 787 | struct mt_fields *f = td->fields; |
| 788 | struct mt_class *cls = &td->mtclass; | ||
| 722 | 789 | ||
| 723 | if (td->touches_by_report > 0) { | 790 | if (td->touches_by_report > 0) { |
| 724 | int field_count_per_touch = f->length / td->touches_by_report; | 791 | int field_count_per_touch = f->length / td->touches_by_report; |
| 725 | td->last_slot_field = f->usages[field_count_per_touch - 1]; | 792 | td->last_slot_field = f->usages[field_count_per_touch - 1]; |
| 726 | } | 793 | } |
| 794 | |||
| 795 | if (td->cc_index < 0) | ||
| 796 | cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; | ||
| 727 | } | 797 | } |
| 728 | 798 | ||
| 729 | static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) | 799 | static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) |
| @@ -781,6 +851,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 781 | td->mtclass = *mtclass; | 851 | td->mtclass = *mtclass; |
| 782 | td->inputmode = -1; | 852 | td->inputmode = -1; |
| 783 | td->maxcontact_report_id = -1; | 853 | td->maxcontact_report_id = -1; |
| 854 | td->cc_index = -1; | ||
| 784 | hid_set_drvdata(hdev, td); | 855 | hid_set_drvdata(hdev, td); |
| 785 | 856 | ||
| 786 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); | 857 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); |
| @@ -875,7 +946,7 @@ static const struct hid_device_id mt_devices[] = { | |||
| 875 | USB_DEVICE_ID_3M3266) }, | 946 | USB_DEVICE_ID_3M3266) }, |
| 876 | 947 | ||
| 877 | /* ActionStar panels */ | 948 | /* ActionStar panels */ |
| 878 | { .driver_data = MT_CLS_DEFAULT, | 949 | { .driver_data = MT_CLS_NSMU, |
| 879 | MT_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, | 950 | MT_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, |
| 880 | USB_DEVICE_ID_ACTIONSTAR_1011) }, | 951 | USB_DEVICE_ID_ACTIONSTAR_1011) }, |
| 881 | 952 | ||
| @@ -888,14 +959,14 @@ static const struct hid_device_id mt_devices[] = { | |||
| 888 | USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, | 959 | USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, |
| 889 | 960 | ||
| 890 | /* Baanto multitouch devices */ | 961 | /* Baanto multitouch devices */ |
| 891 | { .driver_data = MT_CLS_DEFAULT, | 962 | { .driver_data = MT_CLS_NSMU, |
| 892 | MT_USB_DEVICE(USB_VENDOR_ID_BAANTO, | 963 | MT_USB_DEVICE(USB_VENDOR_ID_BAANTO, |
| 893 | USB_DEVICE_ID_BAANTO_MT_190W2) }, | 964 | USB_DEVICE_ID_BAANTO_MT_190W2) }, |
| 894 | /* Cando panels */ | 965 | /* Cando panels */ |
| 895 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 966 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
| 896 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, | 967 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
| 897 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 968 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
| 898 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 969 | { .driver_data = MT_CLS_DUAL_CONTACT_NUMBER, |
| 899 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, | 970 | MT_USB_DEVICE(USB_VENDOR_ID_CANDO, |
| 900 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, | 971 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, |
| 901 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, | 972 | { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, |
| @@ -906,12 +977,12 @@ static const struct hid_device_id mt_devices[] = { | |||
| 906 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | 977 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, |
| 907 | 978 | ||
| 908 | /* Chunghwa Telecom touch panels */ | 979 | /* Chunghwa Telecom touch panels */ |
| 909 | { .driver_data = MT_CLS_DEFAULT, | 980 | { .driver_data = MT_CLS_NSMU, |
| 910 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, | 981 | MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, |
| 911 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, | 982 | USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, |
| 912 | 983 | ||
| 913 | /* CVTouch panels */ | 984 | /* CVTouch panels */ |
| 914 | { .driver_data = MT_CLS_DEFAULT, | 985 | { .driver_data = MT_CLS_NSMU, |
| 915 | MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, | 986 | MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, |
| 916 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, | 987 | USB_DEVICE_ID_CVTOUCH_SCREEN) }, |
| 917 | 988 | ||
| @@ -982,7 +1053,7 @@ static const struct hid_device_id mt_devices[] = { | |||
| 982 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) }, | 1053 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) }, |
| 983 | 1054 | ||
| 984 | /* Elo TouchSystems IntelliTouch Plus panel */ | 1055 | /* Elo TouchSystems IntelliTouch Plus panel */ |
| 985 | { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, | 1056 | { .driver_data = MT_CLS_DUAL_CONTACT_ID, |
| 986 | MT_USB_DEVICE(USB_VENDOR_ID_ELO, | 1057 | MT_USB_DEVICE(USB_VENDOR_ID_ELO, |
| 987 | USB_DEVICE_ID_ELO_TS2515) }, | 1058 | USB_DEVICE_ID_ELO_TS2515) }, |
| 988 | 1059 | ||
| @@ -1000,12 +1071,12 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1000 | USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS) }, | 1071 | USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS) }, |
| 1001 | 1072 | ||
| 1002 | /* Gametel game controller */ | 1073 | /* Gametel game controller */ |
| 1003 | { .driver_data = MT_CLS_DEFAULT, | 1074 | { .driver_data = MT_CLS_NSMU, |
| 1004 | MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL, | 1075 | MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL, |
| 1005 | USB_DEVICE_ID_GAMETEL_MT_MODE) }, | 1076 | USB_DEVICE_ID_GAMETEL_MT_MODE) }, |
| 1006 | 1077 | ||
| 1007 | /* GoodTouch panels */ | 1078 | /* GoodTouch panels */ |
| 1008 | { .driver_data = MT_CLS_DEFAULT, | 1079 | { .driver_data = MT_CLS_NSMU, |
| 1009 | MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, | 1080 | MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, |
| 1010 | USB_DEVICE_ID_GOODTOUCH_000f) }, | 1081 | USB_DEVICE_ID_GOODTOUCH_000f) }, |
| 1011 | 1082 | ||
| @@ -1023,7 +1094,7 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1023 | USB_DEVICE_ID_IDEACOM_IDC6651) }, | 1094 | USB_DEVICE_ID_IDEACOM_IDC6651) }, |
| 1024 | 1095 | ||
| 1025 | /* Ilitek dual touch panel */ | 1096 | /* Ilitek dual touch panel */ |
| 1026 | { .driver_data = MT_CLS_DEFAULT, | 1097 | { .driver_data = MT_CLS_NSMU, |
| 1027 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, | 1098 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
| 1028 | USB_DEVICE_ID_ILITEK_MULTITOUCH) }, | 1099 | USB_DEVICE_ID_ILITEK_MULTITOUCH) }, |
| 1029 | 1100 | ||
| @@ -1056,6 +1127,11 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1056 | MT_USB_DEVICE(USB_VENDOR_ID_TURBOX, | 1127 | MT_USB_DEVICE(USB_VENDOR_ID_TURBOX, |
| 1057 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, | 1128 | USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, |
| 1058 | 1129 | ||
| 1130 | /* Nexio panels */ | ||
| 1131 | { .driver_data = MT_CLS_DEFAULT, | ||
| 1132 | MT_USB_DEVICE(USB_VENDOR_ID_NEXIO, | ||
| 1133 | USB_DEVICE_ID_NEXIO_MULTITOUCH_420)}, | ||
| 1134 | |||
| 1059 | /* Panasonic panels */ | 1135 | /* Panasonic panels */ |
| 1060 | { .driver_data = MT_CLS_PANASONIC, | 1136 | { .driver_data = MT_CLS_PANASONIC, |
| 1061 | MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, | 1137 | MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, |
| @@ -1065,7 +1141,7 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1065 | USB_DEVICE_ID_PANABOARD_UBT880) }, | 1141 | USB_DEVICE_ID_PANABOARD_UBT880) }, |
| 1066 | 1142 | ||
| 1067 | /* Novatek Panel */ | 1143 | /* Novatek Panel */ |
| 1068 | { .driver_data = MT_CLS_DEFAULT, | 1144 | { .driver_data = MT_CLS_NSMU, |
| 1069 | MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK, | 1145 | MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK, |
| 1070 | USB_DEVICE_ID_NOVATEK_PCT) }, | 1146 | USB_DEVICE_ID_NOVATEK_PCT) }, |
| 1071 | 1147 | ||
| @@ -1111,7 +1187,7 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1111 | { .driver_data = MT_CLS_CONFIDENCE, | 1187 | { .driver_data = MT_CLS_CONFIDENCE, |
| 1112 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, | 1188 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, |
| 1113 | USB_DEVICE_ID_MTP_STM)}, | 1189 | USB_DEVICE_ID_MTP_STM)}, |
| 1114 | { .driver_data = MT_CLS_CONFIDENCE, | 1190 | { .driver_data = MT_CLS_DEFAULT, |
| 1115 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, | 1191 | MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, |
| 1116 | USB_DEVICE_ID_MTP_SITRONIX)}, | 1192 | USB_DEVICE_ID_MTP_SITRONIX)}, |
| 1117 | 1193 | ||
| @@ -1121,48 +1197,48 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1121 | USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, | 1197 | USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, |
| 1122 | 1198 | ||
| 1123 | /* Touch International panels */ | 1199 | /* Touch International panels */ |
| 1124 | { .driver_data = MT_CLS_DEFAULT, | 1200 | { .driver_data = MT_CLS_NSMU, |
| 1125 | MT_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, | 1201 | MT_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, |
| 1126 | USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, | 1202 | USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, |
| 1127 | 1203 | ||
| 1128 | /* Unitec panels */ | 1204 | /* Unitec panels */ |
| 1129 | { .driver_data = MT_CLS_DEFAULT, | 1205 | { .driver_data = MT_CLS_NSMU, |
| 1130 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, | 1206 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, |
| 1131 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, | 1207 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, |
| 1132 | { .driver_data = MT_CLS_DEFAULT, | 1208 | { .driver_data = MT_CLS_NSMU, |
| 1133 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, | 1209 | MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, |
| 1134 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, | 1210 | USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, |
| 1135 | /* XAT */ | 1211 | /* XAT */ |
| 1136 | { .driver_data = MT_CLS_DEFAULT, | 1212 | { .driver_data = MT_CLS_NSMU, |
| 1137 | MT_USB_DEVICE(USB_VENDOR_ID_XAT, | 1213 | MT_USB_DEVICE(USB_VENDOR_ID_XAT, |
| 1138 | USB_DEVICE_ID_XAT_CSR) }, | 1214 | USB_DEVICE_ID_XAT_CSR) }, |
| 1139 | 1215 | ||
| 1140 | /* Xiroku */ | 1216 | /* Xiroku */ |
| 1141 | { .driver_data = MT_CLS_DEFAULT, | 1217 | { .driver_data = MT_CLS_NSMU, |
| 1142 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1218 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1143 | USB_DEVICE_ID_XIROKU_SPX) }, | 1219 | USB_DEVICE_ID_XIROKU_SPX) }, |
| 1144 | { .driver_data = MT_CLS_DEFAULT, | 1220 | { .driver_data = MT_CLS_NSMU, |
| 1145 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1221 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1146 | USB_DEVICE_ID_XIROKU_MPX) }, | 1222 | USB_DEVICE_ID_XIROKU_MPX) }, |
| 1147 | { .driver_data = MT_CLS_DEFAULT, | 1223 | { .driver_data = MT_CLS_NSMU, |
| 1148 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1224 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1149 | USB_DEVICE_ID_XIROKU_CSR) }, | 1225 | USB_DEVICE_ID_XIROKU_CSR) }, |
| 1150 | { .driver_data = MT_CLS_DEFAULT, | 1226 | { .driver_data = MT_CLS_NSMU, |
| 1151 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1227 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1152 | USB_DEVICE_ID_XIROKU_SPX1) }, | 1228 | USB_DEVICE_ID_XIROKU_SPX1) }, |
| 1153 | { .driver_data = MT_CLS_DEFAULT, | 1229 | { .driver_data = MT_CLS_NSMU, |
| 1154 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1230 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1155 | USB_DEVICE_ID_XIROKU_MPX1) }, | 1231 | USB_DEVICE_ID_XIROKU_MPX1) }, |
| 1156 | { .driver_data = MT_CLS_DEFAULT, | 1232 | { .driver_data = MT_CLS_NSMU, |
| 1157 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1233 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1158 | USB_DEVICE_ID_XIROKU_CSR1) }, | 1234 | USB_DEVICE_ID_XIROKU_CSR1) }, |
| 1159 | { .driver_data = MT_CLS_DEFAULT, | 1235 | { .driver_data = MT_CLS_NSMU, |
| 1160 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1236 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1161 | USB_DEVICE_ID_XIROKU_SPX2) }, | 1237 | USB_DEVICE_ID_XIROKU_SPX2) }, |
| 1162 | { .driver_data = MT_CLS_DEFAULT, | 1238 | { .driver_data = MT_CLS_NSMU, |
| 1163 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1239 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1164 | USB_DEVICE_ID_XIROKU_MPX2) }, | 1240 | USB_DEVICE_ID_XIROKU_MPX2) }, |
| 1165 | { .driver_data = MT_CLS_DEFAULT, | 1241 | { .driver_data = MT_CLS_NSMU, |
| 1166 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1242 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
| 1167 | USB_DEVICE_ID_XIROKU_CSR2) }, | 1243 | USB_DEVICE_ID_XIROKU_CSR2) }, |
| 1168 | 1244 | ||
| @@ -1193,21 +1269,10 @@ static struct hid_driver mt_driver = { | |||
| 1193 | .feature_mapping = mt_feature_mapping, | 1269 | .feature_mapping = mt_feature_mapping, |
| 1194 | .usage_table = mt_grabbed_usages, | 1270 | .usage_table = mt_grabbed_usages, |
| 1195 | .event = mt_event, | 1271 | .event = mt_event, |
| 1272 | .report = mt_report, | ||
| 1196 | #ifdef CONFIG_PM | 1273 | #ifdef CONFIG_PM |
| 1197 | .reset_resume = mt_reset_resume, | 1274 | .reset_resume = mt_reset_resume, |
| 1198 | .resume = mt_resume, | 1275 | .resume = mt_resume, |
| 1199 | #endif | 1276 | #endif |
| 1200 | }; | 1277 | }; |
| 1201 | 1278 | module_hid_driver(mt_driver); | |
| 1202 | static int __init mt_init(void) | ||
| 1203 | { | ||
| 1204 | return hid_register_driver(&mt_driver); | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | static void __exit mt_exit(void) | ||
| 1208 | { | ||
| 1209 | hid_unregister_driver(&mt_driver); | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | module_init(mt_init); | ||
| 1213 | module_exit(mt_exit); | ||
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 86a969f63292..7757e82416e7 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
| @@ -858,12 +858,43 @@ not_claimed_input: | |||
| 858 | return 1; | 858 | return 1; |
| 859 | } | 859 | } |
| 860 | 860 | ||
| 861 | static void ntrig_input_configured(struct hid_device *hid, | ||
| 862 | struct hid_input *hidinput) | ||
| 863 | |||
| 864 | { | ||
| 865 | struct input_dev *input = hidinput->input; | ||
| 866 | |||
| 867 | if (hidinput->report->maxfield < 1) | ||
| 868 | return; | ||
| 869 | |||
| 870 | switch (hidinput->report->field[0]->application) { | ||
| 871 | case HID_DG_PEN: | ||
| 872 | input->name = "N-Trig Pen"; | ||
| 873 | break; | ||
| 874 | case HID_DG_TOUCHSCREEN: | ||
| 875 | /* These keys are redundant for fingers, clear them | ||
| 876 | * to prevent incorrect identification */ | ||
| 877 | __clear_bit(BTN_TOOL_PEN, input->keybit); | ||
| 878 | __clear_bit(BTN_TOOL_FINGER, input->keybit); | ||
| 879 | __clear_bit(BTN_0, input->keybit); | ||
| 880 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | ||
| 881 | /* | ||
| 882 | * The physical touchscreen (single touch) | ||
| 883 | * input has a value for physical, whereas | ||
| 884 | * the multitouch only has logical input | ||
| 885 | * fields. | ||
| 886 | */ | ||
| 887 | input->name = (hidinput->report->field[0]->physical) ? | ||
| 888 | "N-Trig Touchscreen" : | ||
| 889 | "N-Trig MultiTouch"; | ||
| 890 | break; | ||
| 891 | } | ||
| 892 | } | ||
| 893 | |||
| 861 | static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | 894 | static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| 862 | { | 895 | { |
| 863 | int ret; | 896 | int ret; |
| 864 | struct ntrig_data *nd; | 897 | struct ntrig_data *nd; |
| 865 | struct hid_input *hidinput; | ||
| 866 | struct input_dev *input; | ||
| 867 | struct hid_report *report; | 898 | struct hid_report *report; |
| 868 | 899 | ||
| 869 | if (id->driver_data) | 900 | if (id->driver_data) |
| @@ -901,38 +932,6 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 901 | goto err_free; | 932 | goto err_free; |
| 902 | } | 933 | } |
| 903 | 934 | ||
| 904 | |||
| 905 | list_for_each_entry(hidinput, &hdev->inputs, list) { | ||
| 906 | if (hidinput->report->maxfield < 1) | ||
| 907 | continue; | ||
| 908 | |||
| 909 | input = hidinput->input; | ||
| 910 | switch (hidinput->report->field[0]->application) { | ||
| 911 | case HID_DG_PEN: | ||
| 912 | input->name = "N-Trig Pen"; | ||
| 913 | break; | ||
| 914 | case HID_DG_TOUCHSCREEN: | ||
| 915 | /* These keys are redundant for fingers, clear them | ||
| 916 | * to prevent incorrect identification */ | ||
| 917 | __clear_bit(BTN_TOOL_PEN, input->keybit); | ||
| 918 | __clear_bit(BTN_TOOL_FINGER, input->keybit); | ||
| 919 | __clear_bit(BTN_0, input->keybit); | ||
| 920 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | ||
| 921 | /* | ||
| 922 | * The physical touchscreen (single touch) | ||
| 923 | * input has a value for physical, whereas | ||
| 924 | * the multitouch only has logical input | ||
| 925 | * fields. | ||
| 926 | */ | ||
| 927 | input->name = | ||
| 928 | (hidinput->report->field[0] | ||
| 929 | ->physical) ? | ||
| 930 | "N-Trig Touchscreen" : | ||
| 931 | "N-Trig MultiTouch"; | ||
| 932 | break; | ||
| 933 | } | ||
| 934 | } | ||
| 935 | |||
| 936 | /* This is needed for devices with more recent firmware versions */ | 935 | /* This is needed for devices with more recent firmware versions */ |
| 937 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; | 936 | report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; |
| 938 | if (report) { | 937 | if (report) { |
| @@ -1023,20 +1022,10 @@ static struct hid_driver ntrig_driver = { | |||
| 1023 | .remove = ntrig_remove, | 1022 | .remove = ntrig_remove, |
| 1024 | .input_mapping = ntrig_input_mapping, | 1023 | .input_mapping = ntrig_input_mapping, |
| 1025 | .input_mapped = ntrig_input_mapped, | 1024 | .input_mapped = ntrig_input_mapped, |
| 1025 | .input_configured = ntrig_input_configured, | ||
| 1026 | .usage_table = ntrig_grabbed_usages, | 1026 | .usage_table = ntrig_grabbed_usages, |
| 1027 | .event = ntrig_event, | 1027 | .event = ntrig_event, |
| 1028 | }; | 1028 | }; |
| 1029 | module_hid_driver(ntrig_driver); | ||
| 1029 | 1030 | ||
| 1030 | static int __init ntrig_init(void) | ||
| 1031 | { | ||
| 1032 | return hid_register_driver(&ntrig_driver); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | static void __exit ntrig_exit(void) | ||
| 1036 | { | ||
| 1037 | hid_unregister_driver(&ntrig_driver); | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | module_init(ntrig_init); | ||
| 1041 | module_exit(ntrig_exit); | ||
| 1042 | MODULE_LICENSE("GPL"); | 1031 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c index 0ffa1d2d64f0..6620f15fec22 100644 --- a/drivers/hid/hid-ortek.c +++ b/drivers/hid/hid-ortek.c | |||
| @@ -50,17 +50,6 @@ static struct hid_driver ortek_driver = { | |||
| 50 | .id_table = ortek_devices, | 50 | .id_table = ortek_devices, |
| 51 | .report_fixup = ortek_report_fixup | 51 | .report_fixup = ortek_report_fixup |
| 52 | }; | 52 | }; |
| 53 | module_hid_driver(ortek_driver); | ||
| 53 | 54 | ||
| 54 | static int __init ortek_init(void) | ||
| 55 | { | ||
| 56 | return hid_register_driver(&ortek_driver); | ||
| 57 | } | ||
| 58 | |||
| 59 | static void __exit ortek_exit(void) | ||
| 60 | { | ||
| 61 | hid_unregister_driver(&ortek_driver); | ||
| 62 | } | ||
| 63 | |||
| 64 | module_init(ortek_init); | ||
| 65 | module_exit(ortek_exit); | ||
| 66 | MODULE_LICENSE("GPL"); | 55 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 4c521de4e7e6..736b2502df4f 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c | |||
| @@ -103,17 +103,6 @@ static struct hid_driver pl_driver = { | |||
| 103 | .input_mapping = pl_input_mapping, | 103 | .input_mapping = pl_input_mapping, |
| 104 | .probe = pl_probe, | 104 | .probe = pl_probe, |
| 105 | }; | 105 | }; |
| 106 | module_hid_driver(pl_driver); | ||
| 106 | 107 | ||
| 107 | static int __init pl_init(void) | ||
| 108 | { | ||
| 109 | return hid_register_driver(&pl_driver); | ||
| 110 | } | ||
| 111 | |||
| 112 | static void __exit pl_exit(void) | ||
| 113 | { | ||
| 114 | hid_unregister_driver(&pl_driver); | ||
| 115 | } | ||
| 116 | |||
| 117 | module_init(pl_init); | ||
| 118 | module_exit(pl_exit); | ||
| 119 | MODULE_LICENSE("GPL"); | 108 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c index 86df26e58aba..31cd93fc3d4b 100644 --- a/drivers/hid/hid-picolcd_core.c +++ b/drivers/hid/hid-picolcd_core.c | |||
| @@ -672,18 +672,7 @@ static struct hid_driver picolcd_driver = { | |||
| 672 | .reset_resume = picolcd_reset_resume, | 672 | .reset_resume = picolcd_reset_resume, |
| 673 | #endif | 673 | #endif |
| 674 | }; | 674 | }; |
| 675 | module_hid_driver(picolcd_driver); | ||
| 675 | 676 | ||
| 676 | static int __init picolcd_init(void) | ||
| 677 | { | ||
| 678 | return hid_register_driver(&picolcd_driver); | ||
| 679 | } | ||
| 680 | |||
| 681 | static void __exit picolcd_exit(void) | ||
| 682 | { | ||
| 683 | hid_unregister_driver(&picolcd_driver); | ||
| 684 | } | ||
| 685 | |||
| 686 | module_init(picolcd_init); | ||
| 687 | module_exit(picolcd_exit); | ||
| 688 | MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver"); | 677 | MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver"); |
| 689 | MODULE_LICENSE("GPL v2"); | 678 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index 47ed74c46b6b..b0199d27787b 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | * 0e8f:0003 "GASIA USB Gamepad" | 14 | * 0e8f:0003 "GASIA USB Gamepad" |
| 15 | * - another version of the König gamepad | 15 | * - another version of the König gamepad |
| 16 | * | 16 | * |
| 17 | * 0f30:0111 "Saitek Color Rumble Pad" | ||
| 18 | * | ||
| 17 | * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com> | 19 | * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com> |
| 18 | */ | 20 | */ |
| 19 | 21 | ||
| @@ -51,6 +53,7 @@ | |||
| 51 | 53 | ||
| 52 | struct plff_device { | 54 | struct plff_device { |
| 53 | struct hid_report *report; | 55 | struct hid_report *report; |
| 56 | s32 maxval; | ||
| 54 | s32 *strong; | 57 | s32 *strong; |
| 55 | s32 *weak; | 58 | s32 *weak; |
| 56 | }; | 59 | }; |
| @@ -66,8 +69,8 @@ static int hid_plff_play(struct input_dev *dev, void *data, | |||
| 66 | right = effect->u.rumble.weak_magnitude; | 69 | right = effect->u.rumble.weak_magnitude; |
| 67 | debug("called with 0x%04x 0x%04x", left, right); | 70 | debug("called with 0x%04x 0x%04x", left, right); |
| 68 | 71 | ||
| 69 | left = left * 0x7f / 0xffff; | 72 | left = left * plff->maxval / 0xffff; |
| 70 | right = right * 0x7f / 0xffff; | 73 | right = right * plff->maxval / 0xffff; |
| 71 | 74 | ||
| 72 | *plff->strong = left; | 75 | *plff->strong = left; |
| 73 | *plff->weak = right; | 76 | *plff->weak = right; |
| @@ -87,6 +90,7 @@ static int plff_init(struct hid_device *hid) | |||
| 87 | struct list_head *report_ptr = report_list; | 90 | struct list_head *report_ptr = report_list; |
| 88 | struct input_dev *dev; | 91 | struct input_dev *dev; |
| 89 | int error; | 92 | int error; |
| 93 | s32 maxval; | ||
| 90 | s32 *strong; | 94 | s32 *strong; |
| 91 | s32 *weak; | 95 | s32 *weak; |
| 92 | 96 | ||
| @@ -123,6 +127,7 @@ static int plff_init(struct hid_device *hid) | |||
| 123 | return -ENODEV; | 127 | return -ENODEV; |
| 124 | } | 128 | } |
| 125 | 129 | ||
| 130 | maxval = 0x7f; | ||
| 126 | if (report->field[0]->report_count >= 4) { | 131 | if (report->field[0]->report_count >= 4) { |
| 127 | report->field[0]->value[0] = 0x00; | 132 | report->field[0]->value[0] = 0x00; |
| 128 | report->field[0]->value[1] = 0x00; | 133 | report->field[0]->value[1] = 0x00; |
| @@ -135,6 +140,8 @@ static int plff_init(struct hid_device *hid) | |||
| 135 | report->field[1]->value[0] = 0x00; | 140 | report->field[1]->value[0] = 0x00; |
| 136 | strong = &report->field[2]->value[0]; | 141 | strong = &report->field[2]->value[0]; |
| 137 | weak = &report->field[3]->value[0]; | 142 | weak = &report->field[3]->value[0]; |
| 143 | if (hid->vendor == USB_VENDOR_ID_JESS2) | ||
| 144 | maxval = 0xff; | ||
| 138 | debug("detected 4-field device"); | 145 | debug("detected 4-field device"); |
| 139 | } else { | 146 | } else { |
| 140 | hid_err(hid, "not enough fields or values\n"); | 147 | hid_err(hid, "not enough fields or values\n"); |
| @@ -158,6 +165,7 @@ static int plff_init(struct hid_device *hid) | |||
| 158 | plff->report = report; | 165 | plff->report = report; |
| 159 | plff->strong = strong; | 166 | plff->strong = strong; |
| 160 | plff->weak = weak; | 167 | plff->weak = weak; |
| 168 | plff->maxval = maxval; | ||
| 161 | 169 | ||
| 162 | *strong = 0x00; | 170 | *strong = 0x00; |
| 163 | *weak = 0x00; | 171 | *weak = 0x00; |
| @@ -207,6 +215,7 @@ static const struct hid_device_id pl_devices[] = { | |||
| 207 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), | 215 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), |
| 208 | .driver_data = 1 }, /* Twin USB Joystick */ | 216 | .driver_data = 1 }, /* Twin USB Joystick */ |
| 209 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, | 217 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, |
| 218 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD), }, | ||
| 210 | { } | 219 | { } |
| 211 | }; | 220 | }; |
| 212 | MODULE_DEVICE_TABLE(hid, pl_devices); | 221 | MODULE_DEVICE_TABLE(hid, pl_devices); |
| @@ -216,17 +225,6 @@ static struct hid_driver pl_driver = { | |||
| 216 | .id_table = pl_devices, | 225 | .id_table = pl_devices, |
| 217 | .probe = pl_probe, | 226 | .probe = pl_probe, |
| 218 | }; | 227 | }; |
| 228 | module_hid_driver(pl_driver); | ||
| 219 | 229 | ||
| 220 | static int __init pl_init(void) | ||
| 221 | { | ||
| 222 | return hid_register_driver(&pl_driver); | ||
| 223 | } | ||
| 224 | |||
| 225 | static void __exit pl_exit(void) | ||
| 226 | { | ||
| 227 | hid_unregister_driver(&pl_driver); | ||
| 228 | } | ||
| 229 | |||
| 230 | module_init(pl_init); | ||
| 231 | module_exit(pl_exit); | ||
| 232 | MODULE_LICENSE("GPL"); | 230 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c index c15adb0c98a1..3a1c3c4c50dc 100644 --- a/drivers/hid/hid-primax.c +++ b/drivers/hid/hid-primax.c | |||
| @@ -75,18 +75,7 @@ static struct hid_driver px_driver = { | |||
| 75 | .id_table = px_devices, | 75 | .id_table = px_devices, |
| 76 | .raw_event = px_raw_event, | 76 | .raw_event = px_raw_event, |
| 77 | }; | 77 | }; |
| 78 | module_hid_driver(px_driver); | ||
| 78 | 79 | ||
| 79 | static int __init px_init(void) | ||
| 80 | { | ||
| 81 | return hid_register_driver(&px_driver); | ||
| 82 | } | ||
| 83 | |||
| 84 | static void __exit px_exit(void) | ||
| 85 | { | ||
| 86 | hid_unregister_driver(&px_driver); | ||
| 87 | } | ||
| 88 | |||
| 89 | module_init(px_init); | ||
| 90 | module_exit(px_exit); | ||
| 91 | MODULE_AUTHOR("Terry Lambert <tlambert@google.com>"); | 80 | MODULE_AUTHOR("Terry Lambert <tlambert@google.com>"); |
| 92 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index ec8ca3336315..4e1c4bcbdc03 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c | |||
| @@ -889,23 +889,6 @@ static struct hid_driver pk_driver = { | |||
| 889 | .probe = pk_probe, | 889 | .probe = pk_probe, |
| 890 | .remove = pk_remove, | 890 | .remove = pk_remove, |
| 891 | }; | 891 | }; |
| 892 | module_hid_driver(pk_driver); | ||
| 892 | 893 | ||
| 893 | static int pk_init(void) | ||
| 894 | { | ||
| 895 | int ret; | ||
| 896 | |||
| 897 | ret = hid_register_driver(&pk_driver); | ||
| 898 | if (ret) | ||
| 899 | pr_err("can't register prodikeys driver\n"); | ||
| 900 | |||
| 901 | return ret; | ||
| 902 | } | ||
| 903 | |||
| 904 | static void pk_exit(void) | ||
| 905 | { | ||
| 906 | hid_unregister_driver(&pk_driver); | ||
| 907 | } | ||
| 908 | |||
| 909 | module_init(pk_init); | ||
| 910 | module_exit(pk_exit); | ||
| 911 | MODULE_LICENSE("GPL"); | 894 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-ps3remote.c b/drivers/hid/hid-ps3remote.c index 03811e539d71..f1239d3c5b14 100644 --- a/drivers/hid/hid-ps3remote.c +++ b/drivers/hid/hid-ps3remote.c | |||
| @@ -198,18 +198,7 @@ static struct hid_driver ps3remote_driver = { | |||
| 198 | .report_fixup = ps3remote_fixup, | 198 | .report_fixup = ps3remote_fixup, |
| 199 | .input_mapping = ps3remote_mapping, | 199 | .input_mapping = ps3remote_mapping, |
| 200 | }; | 200 | }; |
| 201 | module_hid_driver(ps3remote_driver); | ||
| 201 | 202 | ||
| 202 | static int __init ps3remote_init(void) | ||
| 203 | { | ||
| 204 | return hid_register_driver(&ps3remote_driver); | ||
| 205 | } | ||
| 206 | |||
| 207 | static void __exit ps3remote_exit(void) | ||
| 208 | { | ||
| 209 | hid_unregister_driver(&ps3remote_driver); | ||
| 210 | } | ||
| 211 | |||
| 212 | module_init(ps3remote_init); | ||
| 213 | module_exit(ps3remote_exit); | ||
| 214 | MODULE_LICENSE("GPL"); | 203 | MODULE_LICENSE("GPL"); |
| 215 | MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>"); | 204 | MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>"); |
diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c index 5084fb4b7e91..6adc0fa08d96 100644 --- a/drivers/hid/hid-roccat-lua.c +++ b/drivers/hid/hid-roccat-lua.c | |||
| @@ -208,19 +208,7 @@ static struct hid_driver lua_driver = { | |||
| 208 | .probe = lua_probe, | 208 | .probe = lua_probe, |
| 209 | .remove = lua_remove | 209 | .remove = lua_remove |
| 210 | }; | 210 | }; |
| 211 | 211 | module_hid_driver(lua_driver); | |
| 212 | static int __init lua_init(void) | ||
| 213 | { | ||
| 214 | return hid_register_driver(&lua_driver); | ||
| 215 | } | ||
| 216 | |||
| 217 | static void __exit lua_exit(void) | ||
| 218 | { | ||
| 219 | hid_unregister_driver(&lua_driver); | ||
| 220 | } | ||
| 221 | |||
| 222 | module_init(lua_init); | ||
| 223 | module_exit(lua_exit); | ||
| 224 | 212 | ||
| 225 | MODULE_AUTHOR("Stefan Achatz"); | 213 | MODULE_AUTHOR("Stefan Achatz"); |
| 226 | MODULE_DESCRIPTION("USB Roccat Lua driver"); | 214 | MODULE_DESCRIPTION("USB Roccat Lua driver"); |
diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c index 45aea77bb611..37961c7e397d 100644 --- a/drivers/hid/hid-saitek.c +++ b/drivers/hid/hid-saitek.c | |||
| @@ -54,17 +54,6 @@ static struct hid_driver saitek_driver = { | |||
| 54 | .id_table = saitek_devices, | 54 | .id_table = saitek_devices, |
| 55 | .report_fixup = saitek_report_fixup | 55 | .report_fixup = saitek_report_fixup |
| 56 | }; | 56 | }; |
| 57 | module_hid_driver(saitek_driver); | ||
| 57 | 58 | ||
| 58 | static int __init saitek_init(void) | ||
| 59 | { | ||
| 60 | return hid_register_driver(&saitek_driver); | ||
| 61 | } | ||
| 62 | |||
| 63 | static void __exit saitek_exit(void) | ||
| 64 | { | ||
| 65 | hid_unregister_driver(&saitek_driver); | ||
| 66 | } | ||
| 67 | |||
| 68 | module_init(saitek_init); | ||
| 69 | module_exit(saitek_exit); | ||
| 70 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index a5821d317229..7cbb067d4a9e 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c | |||
| @@ -196,17 +196,6 @@ static struct hid_driver samsung_driver = { | |||
| 196 | .input_mapping = samsung_input_mapping, | 196 | .input_mapping = samsung_input_mapping, |
| 197 | .probe = samsung_probe, | 197 | .probe = samsung_probe, |
| 198 | }; | 198 | }; |
| 199 | module_hid_driver(samsung_driver); | ||
| 199 | 200 | ||
| 200 | static int __init samsung_init(void) | ||
| 201 | { | ||
| 202 | return hid_register_driver(&samsung_driver); | ||
| 203 | } | ||
| 204 | |||
| 205 | static void __exit samsung_exit(void) | ||
| 206 | { | ||
| 207 | hid_unregister_driver(&samsung_driver); | ||
| 208 | } | ||
| 209 | |||
| 210 | module_init(samsung_init); | ||
| 211 | module_exit(samsung_exit); | ||
| 212 | MODULE_LICENSE("GPL"); | 201 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 0bc58bd8d4f5..6679788bf75a 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
| @@ -605,16 +605,12 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | static const struct hid_device_id sensor_hub_devices[] = { | 607 | static const struct hid_device_id sensor_hub_devices[] = { |
| 608 | { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, | 608 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
| 609 | HID_ANY_ID) }, | ||
| 609 | { } | 610 | { } |
| 610 | }; | 611 | }; |
| 611 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); | 612 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); |
| 612 | 613 | ||
| 613 | static const struct hid_usage_id sensor_hub_grabbed_usages[] = { | ||
| 614 | { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, | ||
| 615 | { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1 } | ||
| 616 | }; | ||
| 617 | |||
| 618 | static struct hid_driver sensor_hub_driver = { | 614 | static struct hid_driver sensor_hub_driver = { |
| 619 | .name = "hid-sensor-hub", | 615 | .name = "hid-sensor-hub", |
| 620 | .id_table = sensor_hub_devices, | 616 | .id_table = sensor_hub_devices, |
| @@ -627,19 +623,7 @@ static struct hid_driver sensor_hub_driver = { | |||
| 627 | .reset_resume = sensor_hub_reset_resume, | 623 | .reset_resume = sensor_hub_reset_resume, |
| 628 | #endif | 624 | #endif |
| 629 | }; | 625 | }; |
| 630 | 626 | module_hid_driver(sensor_hub_driver); | |
| 631 | static int __init sensor_hub_init(void) | ||
| 632 | { | ||
| 633 | return hid_register_driver(&sensor_hub_driver); | ||
| 634 | } | ||
| 635 | |||
| 636 | static void __exit sensor_hub_exit(void) | ||
| 637 | { | ||
| 638 | hid_unregister_driver(&sensor_hub_driver); | ||
| 639 | } | ||
| 640 | |||
| 641 | module_init(sensor_hub_init); | ||
| 642 | module_exit(sensor_hub_exit); | ||
| 643 | 627 | ||
| 644 | MODULE_DESCRIPTION("HID Sensor Hub driver"); | 628 | MODULE_DESCRIPTION("HID Sensor Hub driver"); |
| 645 | MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); | 629 | MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); |
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index 42257acfeb73..28f774003f03 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c | |||
| @@ -177,19 +177,8 @@ static struct hid_driver sjoy_driver = { | |||
| 177 | .id_table = sjoy_devices, | 177 | .id_table = sjoy_devices, |
| 178 | .probe = sjoy_probe, | 178 | .probe = sjoy_probe, |
| 179 | }; | 179 | }; |
| 180 | module_hid_driver(sjoy_driver); | ||
| 180 | 181 | ||
| 181 | static int __init sjoy_init(void) | ||
| 182 | { | ||
| 183 | return hid_register_driver(&sjoy_driver); | ||
| 184 | } | ||
| 185 | |||
| 186 | static void __exit sjoy_exit(void) | ||
| 187 | { | ||
| 188 | hid_unregister_driver(&sjoy_driver); | ||
| 189 | } | ||
| 190 | |||
| 191 | module_init(sjoy_init); | ||
| 192 | module_exit(sjoy_exit); | ||
| 193 | MODULE_LICENSE("GPL"); | 182 | MODULE_LICENSE("GPL"); |
| 194 | MODULE_AUTHOR("Jussi Kivilinna"); | 183 | MODULE_AUTHOR("Jussi Kivilinna"); |
| 195 | 184 | ||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 7f33ebf299c2..312098e4af4f 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
| @@ -33,6 +33,28 @@ static const u8 sixaxis_rdesc_fixup[] = { | |||
| 33 | 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 | 33 | 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02 |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static const u8 sixaxis_rdesc_fixup2[] = { | ||
| 37 | 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02, | ||
| 38 | 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, | ||
| 39 | 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95, | ||
| 40 | 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45, | ||
| 41 | 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81, | ||
| 42 | 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff, | ||
| 43 | 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, | ||
| 44 | 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95, | ||
| 45 | 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30, | ||
| 46 | 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02, | ||
| 47 | 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81, | ||
| 48 | 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95, | ||
| 49 | 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09, | ||
| 50 | 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02, | ||
| 51 | 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02, | ||
| 52 | 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95, | ||
| 53 | 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02, | ||
| 54 | 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, | ||
| 55 | 0xb1, 0x02, 0xc0, 0xc0, | ||
| 56 | }; | ||
| 57 | |||
| 36 | struct sony_sc { | 58 | struct sony_sc { |
| 37 | unsigned long quirks; | 59 | unsigned long quirks; |
| 38 | }; | 60 | }; |
| @@ -43,9 +65,19 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 43 | { | 65 | { |
| 44 | struct sony_sc *sc = hid_get_drvdata(hdev); | 66 | struct sony_sc *sc = hid_get_drvdata(hdev); |
| 45 | 67 | ||
| 46 | if ((sc->quirks & VAIO_RDESC_CONSTANT) && | 68 | /* |
| 47 | *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { | 69 | * Some Sony RF receivers wrongly declare the mouse pointer as a |
| 48 | hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n"); | 70 | * a constant non-data variable. |
| 71 | */ | ||
| 72 | if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && | ||
| 73 | /* usage page: generic desktop controls */ | ||
| 74 | /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ | ||
| 75 | /* usage: mouse */ | ||
| 76 | rdesc[2] == 0x09 && rdesc[3] == 0x02 && | ||
| 77 | /* input (usage page for x,y axes): constant, variable, relative */ | ||
| 78 | rdesc[54] == 0x81 && rdesc[55] == 0x07) { | ||
| 79 | hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); | ||
| 80 | /* input: data, variable, relative */ | ||
| 49 | rdesc[55] = 0x06; | 81 | rdesc[55] = 0x06; |
| 50 | } | 82 | } |
| 51 | 83 | ||
| @@ -56,6 +88,12 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 56 | hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); | 88 | hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n"); |
| 57 | memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, | 89 | memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup, |
| 58 | sizeof(sixaxis_rdesc_fixup)); | 90 | sizeof(sixaxis_rdesc_fixup)); |
| 91 | } else if (sc->quirks & SIXAXIS_CONTROLLER_USB && | ||
| 92 | *rsize > sizeof(sixaxis_rdesc_fixup2)) { | ||
| 93 | hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n", | ||
| 94 | *rsize, (int)sizeof(sixaxis_rdesc_fixup2)); | ||
| 95 | *rsize = sizeof(sixaxis_rdesc_fixup2); | ||
| 96 | memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize); | ||
| 59 | } | 97 | } |
| 60 | return rdesc; | 98 | return rdesc; |
| 61 | } | 99 | } |
| @@ -217,6 +255,8 @@ static const struct hid_device_id sony_devices[] = { | |||
| 217 | .driver_data = SIXAXIS_CONTROLLER_BT }, | 255 | .driver_data = SIXAXIS_CONTROLLER_BT }, |
| 218 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), | 256 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), |
| 219 | .driver_data = VAIO_RDESC_CONSTANT }, | 257 | .driver_data = VAIO_RDESC_CONSTANT }, |
| 258 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), | ||
| 259 | .driver_data = VAIO_RDESC_CONSTANT }, | ||
| 220 | { } | 260 | { } |
| 221 | }; | 261 | }; |
| 222 | MODULE_DEVICE_TABLE(hid, sony_devices); | 262 | MODULE_DEVICE_TABLE(hid, sony_devices); |
| @@ -229,17 +269,6 @@ static struct hid_driver sony_driver = { | |||
| 229 | .report_fixup = sony_report_fixup, | 269 | .report_fixup = sony_report_fixup, |
| 230 | .raw_event = sony_raw_event | 270 | .raw_event = sony_raw_event |
| 231 | }; | 271 | }; |
| 272 | module_hid_driver(sony_driver); | ||
| 232 | 273 | ||
| 233 | static int __init sony_init(void) | ||
| 234 | { | ||
| 235 | return hid_register_driver(&sony_driver); | ||
| 236 | } | ||
| 237 | |||
| 238 | static void __exit sony_exit(void) | ||
| 239 | { | ||
| 240 | hid_unregister_driver(&sony_driver); | ||
| 241 | } | ||
| 242 | |||
| 243 | module_init(sony_init); | ||
| 244 | module_exit(sony_exit); | ||
| 245 | MODULE_LICENSE("GPL"); | 274 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c index 602013741718..e94371a059cb 100644 --- a/drivers/hid/hid-speedlink.c +++ b/drivers/hid/hid-speedlink.c | |||
| @@ -73,17 +73,6 @@ static struct hid_driver speedlink_driver = { | |||
| 73 | .input_mapping = speedlink_input_mapping, | 73 | .input_mapping = speedlink_input_mapping, |
| 74 | .event = speedlink_event, | 74 | .event = speedlink_event, |
| 75 | }; | 75 | }; |
| 76 | module_hid_driver(speedlink_driver); | ||
| 76 | 77 | ||
| 77 | static int __init speedlink_init(void) | ||
| 78 | { | ||
| 79 | return hid_register_driver(&speedlink_driver); | ||
| 80 | } | ||
| 81 | |||
| 82 | static void __exit speedlink_exit(void) | ||
| 83 | { | ||
| 84 | hid_unregister_driver(&speedlink_driver); | ||
| 85 | } | ||
| 86 | |||
| 87 | module_init(speedlink_init); | ||
| 88 | module_exit(speedlink_exit); | ||
| 89 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c new file mode 100644 index 000000000000..2ed995cda44a --- /dev/null +++ b/drivers/hid/hid-steelseries.c | |||
| @@ -0,0 +1,393 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for Steelseries SRW-S1 | ||
| 3 | * | ||
| 4 | * Copyright (c) 2013 Simon Wood | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/usb.h> | ||
| 16 | #include <linux/hid.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | |||
| 19 | #include "usbhid/usbhid.h" | ||
| 20 | #include "hid-ids.h" | ||
| 21 | |||
| 22 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | ||
| 23 | #define SRWS1_NUMBER_LEDS 15 | ||
| 24 | struct steelseries_srws1_data { | ||
| 25 | __u16 led_state; | ||
| 26 | /* the last element is used for setting all leds simultaneously */ | ||
| 27 | struct led_classdev *led[SRWS1_NUMBER_LEDS + 1]; | ||
| 28 | }; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* Fixed report descriptor for Steelseries SRW-S1 wheel controller | ||
| 32 | * | ||
| 33 | * The original descriptor hides the sensitivity and assists dials | ||
| 34 | * a custom vendor usage page. This inserts a patch to make them | ||
| 35 | * appear in the 'Generic Desktop' usage. | ||
| 36 | */ | ||
| 37 | |||
| 38 | static __u8 steelseries_srws1_rdesc_fixed[] = { | ||
| 39 | 0x05, 0x01, /* Usage Page (Desktop) */ | ||
| 40 | 0x09, 0x08, /* Usage (MultiAxis), Changed */ | ||
| 41 | 0xA1, 0x01, /* Collection (Application), */ | ||
| 42 | 0xA1, 0x02, /* Collection (Logical), */ | ||
| 43 | 0x95, 0x01, /* Report Count (1), */ | ||
| 44 | 0x05, 0x01, /* Changed Usage Page (Desktop), */ | ||
| 45 | 0x09, 0x30, /* Changed Usage (X), */ | ||
| 46 | 0x16, 0xF8, 0xF8, /* Logical Minimum (-1800), */ | ||
| 47 | 0x26, 0x08, 0x07, /* Logical Maximum (1800), */ | ||
| 48 | 0x65, 0x14, /* Unit (Degrees), */ | ||
| 49 | 0x55, 0x0F, /* Unit Exponent (15), */ | ||
| 50 | 0x75, 0x10, /* Report Size (16), */ | ||
| 51 | 0x81, 0x02, /* Input (Variable), */ | ||
| 52 | 0x09, 0x31, /* Changed Usage (Y), */ | ||
| 53 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
| 54 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
| 55 | 0x75, 0x0C, /* Report Size (12), */ | ||
| 56 | 0x81, 0x02, /* Input (Variable), */ | ||
| 57 | 0x09, 0x32, /* Changed Usage (Z), */ | ||
| 58 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
| 59 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
| 60 | 0x75, 0x0C, /* Report Size (12), */ | ||
| 61 | 0x81, 0x02, /* Input (Variable), */ | ||
| 62 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 63 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
| 64 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
| 65 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
| 66 | 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ | ||
| 67 | 0x65, 0x14, /* Unit (Degrees), */ | ||
| 68 | 0x75, 0x04, /* Report Size (4), */ | ||
| 69 | 0x95, 0x01, /* Report Count (1), */ | ||
| 70 | 0x81, 0x02, /* Input (Variable), */ | ||
| 71 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
| 72 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
| 73 | 0x65, 0x00, /* Unit, */ | ||
| 74 | 0x75, 0x01, /* Report Size (1), */ | ||
| 75 | 0x95, 0x03, /* Report Count (3), */ | ||
| 76 | 0x81, 0x01, /* Input (Constant), */ | ||
| 77 | 0x05, 0x09, /* Usage Page (Button), */ | ||
| 78 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
| 79 | 0x29, 0x11, /* Usage Maximum (11h), */ | ||
| 80 | 0x95, 0x11, /* Report Count (17), */ | ||
| 81 | 0x81, 0x02, /* Input (Variable), */ | ||
| 82 | /* ---- Dial patch starts here ---- */ | ||
| 83 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
| 84 | 0x09, 0x33, /* Usage (RX), */ | ||
| 85 | 0x75, 0x04, /* Report Size (4), */ | ||
| 86 | 0x95, 0x02, /* Report Count (2), */ | ||
| 87 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
| 88 | 0x25, 0x0b, /* Logical Maximum (b), */ | ||
| 89 | 0x81, 0x02, /* Input (Variable), */ | ||
| 90 | 0x09, 0x35, /* Usage (RZ), */ | ||
| 91 | 0x75, 0x04, /* Report Size (4), */ | ||
| 92 | 0x95, 0x01, /* Report Count (1), */ | ||
| 93 | 0x25, 0x03, /* Logical Maximum (3), */ | ||
| 94 | 0x81, 0x02, /* Input (Variable), */ | ||
| 95 | /* ---- Dial patch ends here ---- */ | ||
| 96 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
| 97 | 0x09, 0x01, /* Usage (01h), */ | ||
| 98 | 0x75, 0x04, /* Changed Report Size (4), */ | ||
| 99 | 0x95, 0x0D, /* Changed Report Count (13), */ | ||
| 100 | 0x81, 0x02, /* Input (Variable), */ | ||
| 101 | 0xC0, /* End Collection, */ | ||
| 102 | 0xA1, 0x02, /* Collection (Logical), */ | ||
| 103 | 0x09, 0x02, /* Usage (02h), */ | ||
| 104 | 0x75, 0x08, /* Report Size (8), */ | ||
| 105 | 0x95, 0x10, /* Report Count (16), */ | ||
| 106 | 0x91, 0x02, /* Output (Variable), */ | ||
| 107 | 0xC0, /* End Collection, */ | ||
| 108 | 0xC0 /* End Collection */ | ||
| 109 | }; | ||
| 110 | |||
| 111 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | ||
| 112 | static void steelseries_srws1_set_leds(struct hid_device *hdev, __u16 leds) | ||
| 113 | { | ||
| 114 | struct list_head *report_list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; | ||
| 115 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | ||
| 116 | __s32 *value = report->field[0]->value; | ||
| 117 | |||
| 118 | value[0] = 0x40; | ||
| 119 | value[1] = leds & 0xFF; | ||
| 120 | value[2] = leds >> 8; | ||
| 121 | value[3] = 0x00; | ||
| 122 | value[4] = 0x00; | ||
| 123 | value[5] = 0x00; | ||
| 124 | value[6] = 0x00; | ||
| 125 | value[7] = 0x00; | ||
| 126 | value[8] = 0x00; | ||
| 127 | value[9] = 0x00; | ||
| 128 | value[10] = 0x00; | ||
| 129 | value[11] = 0x00; | ||
| 130 | value[12] = 0x00; | ||
| 131 | value[13] = 0x00; | ||
| 132 | value[14] = 0x00; | ||
| 133 | value[15] = 0x00; | ||
| 134 | |||
| 135 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | ||
| 136 | |||
| 137 | /* Note: LED change does not show on device until the device is read/polled */ | ||
| 138 | } | ||
| 139 | |||
| 140 | static void steelseries_srws1_led_all_set_brightness(struct led_classdev *led_cdev, | ||
| 141 | enum led_brightness value) | ||
| 142 | { | ||
| 143 | struct device *dev = led_cdev->dev->parent; | ||
| 144 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
| 145 | struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); | ||
| 146 | |||
| 147 | if (!drv_data) { | ||
| 148 | hid_err(hid, "Device data not found."); | ||
| 149 | return; | ||
| 150 | } | ||
| 151 | |||
| 152 | if (value == LED_OFF) | ||
| 153 | drv_data->led_state = 0; | ||
| 154 | else | ||
| 155 | drv_data->led_state = (1 << (SRWS1_NUMBER_LEDS + 1)) - 1; | ||
| 156 | |||
| 157 | steelseries_srws1_set_leds(hid, drv_data->led_state); | ||
| 158 | } | ||
| 159 | |||
| 160 | static enum led_brightness steelseries_srws1_led_all_get_brightness(struct led_classdev *led_cdev) | ||
| 161 | { | ||
| 162 | struct device *dev = led_cdev->dev->parent; | ||
| 163 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
| 164 | struct steelseries_srws1_data *drv_data; | ||
| 165 | |||
| 166 | drv_data = hid_get_drvdata(hid); | ||
| 167 | |||
| 168 | if (!drv_data) { | ||
| 169 | hid_err(hid, "Device data not found."); | ||
| 170 | return LED_OFF; | ||
| 171 | } | ||
| 172 | |||
| 173 | return (drv_data->led_state >> SRWS1_NUMBER_LEDS) ? LED_FULL : LED_OFF; | ||
| 174 | } | ||
| 175 | |||
| 176 | static void steelseries_srws1_led_set_brightness(struct led_classdev *led_cdev, | ||
| 177 | enum led_brightness value) | ||
| 178 | { | ||
| 179 | struct device *dev = led_cdev->dev->parent; | ||
| 180 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
| 181 | struct steelseries_srws1_data *drv_data = hid_get_drvdata(hid); | ||
| 182 | int i, state = 0; | ||
| 183 | |||
| 184 | if (!drv_data) { | ||
| 185 | hid_err(hid, "Device data not found."); | ||
| 186 | return; | ||
| 187 | } | ||
| 188 | |||
| 189 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { | ||
| 190 | if (led_cdev != drv_data->led[i]) | ||
| 191 | continue; | ||
| 192 | |||
| 193 | state = (drv_data->led_state >> i) & 1; | ||
| 194 | if (value == LED_OFF && state) { | ||
| 195 | drv_data->led_state &= ~(1 << i); | ||
| 196 | steelseries_srws1_set_leds(hid, drv_data->led_state); | ||
| 197 | } else if (value != LED_OFF && !state) { | ||
| 198 | drv_data->led_state |= 1 << i; | ||
| 199 | steelseries_srws1_set_leds(hid, drv_data->led_state); | ||
| 200 | } | ||
| 201 | break; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | static enum led_brightness steelseries_srws1_led_get_brightness(struct led_classdev *led_cdev) | ||
| 206 | { | ||
| 207 | struct device *dev = led_cdev->dev->parent; | ||
| 208 | struct hid_device *hid = container_of(dev, struct hid_device, dev); | ||
| 209 | struct steelseries_srws1_data *drv_data; | ||
| 210 | int i, value = 0; | ||
| 211 | |||
| 212 | drv_data = hid_get_drvdata(hid); | ||
| 213 | |||
| 214 | if (!drv_data) { | ||
| 215 | hid_err(hid, "Device data not found."); | ||
| 216 | return LED_OFF; | ||
| 217 | } | ||
| 218 | |||
| 219 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) | ||
| 220 | if (led_cdev == drv_data->led[i]) { | ||
| 221 | value = (drv_data->led_state >> i) & 1; | ||
| 222 | break; | ||
| 223 | } | ||
| 224 | |||
| 225 | return value ? LED_FULL : LED_OFF; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int steelseries_srws1_probe(struct hid_device *hdev, | ||
| 229 | const struct hid_device_id *id) | ||
| 230 | { | ||
| 231 | int ret, i; | ||
| 232 | struct led_classdev *led; | ||
| 233 | size_t name_sz; | ||
| 234 | char *name; | ||
| 235 | |||
| 236 | struct steelseries_srws1_data *drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); | ||
| 237 | |||
| 238 | if (drv_data == NULL) { | ||
| 239 | hid_err(hdev, "can't alloc SRW-S1 memory\n"); | ||
| 240 | return -ENOMEM; | ||
| 241 | } | ||
| 242 | |||
| 243 | hid_set_drvdata(hdev, drv_data); | ||
| 244 | |||
| 245 | ret = hid_parse(hdev); | ||
| 246 | if (ret) { | ||
| 247 | hid_err(hdev, "parse failed\n"); | ||
| 248 | goto err_free; | ||
| 249 | } | ||
| 250 | |||
| 251 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 252 | if (ret) { | ||
| 253 | hid_err(hdev, "hw start failed\n"); | ||
| 254 | goto err_free; | ||
| 255 | } | ||
| 256 | |||
| 257 | /* register led subsystem */ | ||
| 258 | drv_data->led_state = 0; | ||
| 259 | for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) | ||
| 260 | drv_data->led[i] = NULL; | ||
| 261 | |||
| 262 | steelseries_srws1_set_leds(hdev, 0); | ||
| 263 | |||
| 264 | name_sz = strlen(hdev->uniq) + 16; | ||
| 265 | |||
| 266 | /* 'ALL', for setting all LEDs simultaneously */ | ||
| 267 | led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); | ||
| 268 | if (!led) { | ||
| 269 | hid_err(hdev, "can't allocate memory for LED ALL\n"); | ||
| 270 | goto err_led; | ||
| 271 | } | ||
| 272 | |||
| 273 | name = (void *)(&led[1]); | ||
| 274 | snprintf(name, name_sz, "SRWS1::%s::RPMALL", hdev->uniq); | ||
| 275 | led->name = name; | ||
| 276 | led->brightness = 0; | ||
| 277 | led->max_brightness = 1; | ||
| 278 | led->brightness_get = steelseries_srws1_led_all_get_brightness; | ||
| 279 | led->brightness_set = steelseries_srws1_led_all_set_brightness; | ||
| 280 | |||
| 281 | drv_data->led[SRWS1_NUMBER_LEDS] = led; | ||
| 282 | ret = led_classdev_register(&hdev->dev, led); | ||
| 283 | if (ret) | ||
| 284 | goto err_led; | ||
| 285 | |||
| 286 | /* Each individual LED */ | ||
| 287 | for (i = 0; i < SRWS1_NUMBER_LEDS; i++) { | ||
| 288 | led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL); | ||
| 289 | if (!led) { | ||
| 290 | hid_err(hdev, "can't allocate memory for LED %d\n", i); | ||
| 291 | goto err_led; | ||
| 292 | } | ||
| 293 | |||
| 294 | name = (void *)(&led[1]); | ||
| 295 | snprintf(name, name_sz, "SRWS1::%s::RPM%d", hdev->uniq, i+1); | ||
| 296 | led->name = name; | ||
| 297 | led->brightness = 0; | ||
| 298 | led->max_brightness = 1; | ||
| 299 | led->brightness_get = steelseries_srws1_led_get_brightness; | ||
| 300 | led->brightness_set = steelseries_srws1_led_set_brightness; | ||
| 301 | |||
| 302 | drv_data->led[i] = led; | ||
| 303 | ret = led_classdev_register(&hdev->dev, led); | ||
| 304 | |||
| 305 | if (ret) { | ||
| 306 | hid_err(hdev, "failed to register LED %d. Aborting.\n", i); | ||
| 307 | err_led: | ||
| 308 | /* Deregister all LEDs (if any) */ | ||
| 309 | for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) { | ||
| 310 | led = drv_data->led[i]; | ||
| 311 | drv_data->led[i] = NULL; | ||
| 312 | if (!led) | ||
| 313 | continue; | ||
| 314 | led_classdev_unregister(led); | ||
| 315 | kfree(led); | ||
| 316 | } | ||
| 317 | goto out; /* but let the driver continue without LEDs */ | ||
| 318 | } | ||
| 319 | } | ||
| 320 | out: | ||
| 321 | return 0; | ||
| 322 | err_free: | ||
| 323 | kfree(drv_data); | ||
| 324 | return ret; | ||
| 325 | } | ||
| 326 | |||
| 327 | static void steelseries_srws1_remove(struct hid_device *hdev) | ||
| 328 | { | ||
| 329 | int i; | ||
| 330 | struct led_classdev *led; | ||
| 331 | |||
| 332 | struct steelseries_srws1_data *drv_data = hid_get_drvdata(hdev); | ||
| 333 | |||
| 334 | if (drv_data) { | ||
| 335 | /* Deregister LEDs (if any) */ | ||
| 336 | for (i = 0; i < SRWS1_NUMBER_LEDS + 1; i++) { | ||
| 337 | led = drv_data->led[i]; | ||
| 338 | drv_data->led[i] = NULL; | ||
| 339 | if (!led) | ||
| 340 | continue; | ||
| 341 | led_classdev_unregister(led); | ||
| 342 | kfree(led); | ||
| 343 | } | ||
| 344 | |||
| 345 | } | ||
| 346 | |||
| 347 | hid_hw_stop(hdev); | ||
| 348 | kfree(drv_data); | ||
| 349 | return; | ||
| 350 | } | ||
| 351 | #endif | ||
| 352 | |||
| 353 | static __u8 *steelseries_srws1_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 354 | unsigned int *rsize) | ||
| 355 | { | ||
| 356 | if (*rsize >= 115 && rdesc[11] == 0x02 && rdesc[13] == 0xc8 | ||
| 357 | && rdesc[29] == 0xbb && rdesc[40] == 0xc5) { | ||
| 358 | hid_info(hdev, "Fixing up Steelseries SRW-S1 report descriptor\n"); | ||
| 359 | rdesc = steelseries_srws1_rdesc_fixed; | ||
| 360 | *rsize = sizeof(steelseries_srws1_rdesc_fixed); | ||
| 361 | } | ||
| 362 | return rdesc; | ||
| 363 | } | ||
| 364 | |||
| 365 | static const struct hid_device_id steelseries_srws1_devices[] = { | ||
| 366 | { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, | ||
| 367 | { } | ||
| 368 | }; | ||
| 369 | MODULE_DEVICE_TABLE(hid, steelseries_srws1_devices); | ||
| 370 | |||
| 371 | static struct hid_driver steelseries_srws1_driver = { | ||
| 372 | .name = "steelseries_srws1", | ||
| 373 | .id_table = steelseries_srws1_devices, | ||
| 374 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | ||
| 375 | .probe = steelseries_srws1_probe, | ||
| 376 | .remove = steelseries_srws1_remove, | ||
| 377 | #endif | ||
| 378 | .report_fixup = steelseries_srws1_report_fixup | ||
| 379 | }; | ||
| 380 | |||
| 381 | static int __init steelseries_srws1_init(void) | ||
| 382 | { | ||
| 383 | return hid_register_driver(&steelseries_srws1_driver); | ||
| 384 | } | ||
| 385 | |||
| 386 | static void __exit steelseries_srws1_exit(void) | ||
| 387 | { | ||
| 388 | hid_unregister_driver(&steelseries_srws1_driver); | ||
| 389 | } | ||
| 390 | |||
| 391 | module_init(steelseries_srws1_init); | ||
| 392 | module_exit(steelseries_srws1_exit); | ||
| 393 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c index 45b4b066a262..87fc91e1c8de 100644 --- a/drivers/hid/hid-sunplus.c +++ b/drivers/hid/hid-sunplus.c | |||
| @@ -63,17 +63,6 @@ static struct hid_driver sp_driver = { | |||
| 63 | .report_fixup = sp_report_fixup, | 63 | .report_fixup = sp_report_fixup, |
| 64 | .input_mapping = sp_input_mapping, | 64 | .input_mapping = sp_input_mapping, |
| 65 | }; | 65 | }; |
| 66 | module_hid_driver(sp_driver); | ||
| 66 | 67 | ||
| 67 | static int __init sp_init(void) | ||
| 68 | { | ||
| 69 | return hid_register_driver(&sp_driver); | ||
| 70 | } | ||
| 71 | |||
| 72 | static void __exit sp_exit(void) | ||
| 73 | { | ||
| 74 | hid_unregister_driver(&sp_driver); | ||
| 75 | } | ||
| 76 | |||
| 77 | module_init(sp_init); | ||
| 78 | module_exit(sp_exit); | ||
| 79 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c new file mode 100644 index 000000000000..2055a52e9a20 --- /dev/null +++ b/drivers/hid/hid-thingm.c | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* | ||
| 2 | * ThingM blink(1) USB RGB LED driver | ||
| 3 | * | ||
| 4 | * Copyright 2013 Savoir-faire Linux Inc. | ||
| 5 | * Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License as | ||
| 9 | * published by the Free Software Foundation, version 2. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/hid.h> | ||
| 13 | #include <linux/leds.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/usb.h> | ||
| 16 | |||
| 17 | #include "hid-ids.h" | ||
| 18 | |||
| 19 | #define BLINK1_CMD_SIZE 9 | ||
| 20 | |||
| 21 | #define blink1_rgb_to_r(rgb) ((rgb & 0xFF0000) >> 16) | ||
| 22 | #define blink1_rgb_to_g(rgb) ((rgb & 0x00FF00) >> 8) | ||
| 23 | #define blink1_rgb_to_b(rgb) ((rgb & 0x0000FF) >> 0) | ||
| 24 | |||
| 25 | /** | ||
| 26 | * struct blink1_data - blink(1) device specific data | ||
| 27 | * @hdev: HID device. | ||
| 28 | * @led_cdev: LED class instance. | ||
| 29 | * @rgb: 8-bit per channel RGB notation. | ||
| 30 | * @fade: fade time in hundredths of a second. | ||
| 31 | * @brightness: brightness coefficient. | ||
| 32 | * @play: play/pause in-memory patterns. | ||
| 33 | */ | ||
| 34 | struct blink1_data { | ||
| 35 | struct hid_device *hdev; | ||
| 36 | struct led_classdev led_cdev; | ||
| 37 | u32 rgb; | ||
| 38 | u16 fade; | ||
| 39 | u8 brightness; | ||
| 40 | bool play; | ||
| 41 | }; | ||
| 42 | |||
| 43 | static int blink1_send_command(struct blink1_data *data, | ||
| 44 | u8 buf[BLINK1_CMD_SIZE]) | ||
| 45 | { | ||
| 46 | int ret; | ||
| 47 | |||
| 48 | hid_dbg(data->hdev, "command: %d%c%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", | ||
| 49 | buf[0], buf[1], buf[2], buf[3], buf[4], | ||
| 50 | buf[5], buf[6], buf[7], buf[8]); | ||
| 51 | |||
| 52 | ret = data->hdev->hid_output_raw_report(data->hdev, buf, | ||
| 53 | BLINK1_CMD_SIZE, HID_FEATURE_REPORT); | ||
| 54 | |||
| 55 | return ret < 0 ? ret : 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int blink1_update_color(struct blink1_data *data) | ||
| 59 | { | ||
| 60 | u8 buf[BLINK1_CMD_SIZE] = { 1, 'n', 0, 0, 0, 0, 0, 0, 0 }; | ||
| 61 | |||
| 62 | if (data->brightness) { | ||
| 63 | unsigned int coef = DIV_ROUND_CLOSEST(255, data->brightness); | ||
| 64 | |||
| 65 | buf[2] = DIV_ROUND_CLOSEST(blink1_rgb_to_r(data->rgb), coef); | ||
| 66 | buf[3] = DIV_ROUND_CLOSEST(blink1_rgb_to_g(data->rgb), coef); | ||
| 67 | buf[4] = DIV_ROUND_CLOSEST(blink1_rgb_to_b(data->rgb), coef); | ||
| 68 | } | ||
| 69 | |||
| 70 | if (data->fade) { | ||
| 71 | buf[1] = 'c'; | ||
| 72 | buf[5] = (data->fade & 0xFF00) >> 8; | ||
| 73 | buf[6] = (data->fade & 0x00FF); | ||
| 74 | } | ||
| 75 | |||
| 76 | return blink1_send_command(data, buf); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void blink1_led_set(struct led_classdev *led_cdev, | ||
| 80 | enum led_brightness brightness) | ||
| 81 | { | ||
| 82 | struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent); | ||
| 83 | |||
| 84 | data->brightness = brightness; | ||
| 85 | if (blink1_update_color(data)) | ||
| 86 | hid_err(data->hdev, "failed to update color\n"); | ||
| 87 | } | ||
| 88 | |||
| 89 | static enum led_brightness blink1_led_get(struct led_classdev *led_cdev) | ||
| 90 | { | ||
| 91 | struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent); | ||
| 92 | |||
| 93 | return data->brightness; | ||
| 94 | } | ||
| 95 | |||
| 96 | static ssize_t blink1_show_rgb(struct device *dev, | ||
| 97 | struct device_attribute *attr, char *buf) | ||
| 98 | { | ||
| 99 | struct blink1_data *data = dev_get_drvdata(dev->parent); | ||
| 100 | |||
| 101 | return sprintf(buf, "%.6X\n", data->rgb); | ||
| 102 | } | ||
| 103 | |||
| 104 | static ssize_t blink1_store_rgb(struct device *dev, | ||
| 105 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 106 | { | ||
| 107 | struct blink1_data *data = dev_get_drvdata(dev->parent); | ||
| 108 | long unsigned int rgb; | ||
| 109 | int ret; | ||
| 110 | |||
| 111 | ret = kstrtoul(buf, 16, &rgb); | ||
| 112 | if (ret) | ||
| 113 | return ret; | ||
| 114 | |||
| 115 | /* RGB triplet notation is 24-bit hexadecimal */ | ||
| 116 | if (rgb > 0xFFFFFF) | ||
| 117 | return -EINVAL; | ||
| 118 | |||
| 119 | data->rgb = rgb; | ||
| 120 | ret = blink1_update_color(data); | ||
| 121 | |||
| 122 | return ret ? ret : count; | ||
| 123 | } | ||
| 124 | |||
| 125 | static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR, blink1_show_rgb, blink1_store_rgb); | ||
| 126 | |||
| 127 | static ssize_t blink1_show_fade(struct device *dev, | ||
| 128 | struct device_attribute *attr, char *buf) | ||
| 129 | { | ||
| 130 | struct blink1_data *data = dev_get_drvdata(dev->parent); | ||
| 131 | |||
| 132 | return sprintf(buf, "%d\n", data->fade * 10); | ||
| 133 | } | ||
| 134 | |||
| 135 | static ssize_t blink1_store_fade(struct device *dev, | ||
| 136 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 137 | { | ||
| 138 | struct blink1_data *data = dev_get_drvdata(dev->parent); | ||
| 139 | long unsigned int fade; | ||
| 140 | int ret; | ||
| 141 | |||
| 142 | ret = kstrtoul(buf, 10, &fade); | ||
| 143 | if (ret) | ||
| 144 | return ret; | ||
| 145 | |||
| 146 | /* blink(1) accepts 16-bit fade time, number of 10ms ticks */ | ||
| 147 | fade = DIV_ROUND_CLOSEST(fade, 10); | ||
| 148 | if (fade > 65535) | ||
| 149 | return -EINVAL; | ||
| 150 | |||
| 151 | data->fade = fade; | ||
| 152 | |||
| 153 | return count; | ||
| 154 | } | ||
| 155 | |||
| 156 | static DEVICE_ATTR(fade, S_IRUGO | S_IWUSR, | ||
| 157 | blink1_show_fade, blink1_store_fade); | ||
| 158 | |||
| 159 | static ssize_t blink1_show_play(struct device *dev, | ||
| 160 | struct device_attribute *attr, char *buf) | ||
| 161 | { | ||
| 162 | struct blink1_data *data = dev_get_drvdata(dev->parent); | ||
| 163 | |||
| 164 | return sprintf(buf, "%d\n", data->play); | ||
| 165 | } | ||
| 166 | |||
| 167 | static ssize_t blink1_store_play(struct device *dev, | ||
| 168 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 169 | { | ||
| 170 | struct blink1_data *data = dev_get_drvdata(dev->parent); | ||
| 171 | u8 cmd[BLINK1_CMD_SIZE] = { 1, 'p', 0, 0, 0, 0, 0, 0, 0 }; | ||
| 172 | long unsigned int play; | ||
| 173 | int ret; | ||
| 174 | |||
| 175 | ret = kstrtoul(buf, 10, &play); | ||
| 176 | if (ret) | ||
| 177 | return ret; | ||
| 178 | |||
| 179 | data->play = !!play; | ||
| 180 | cmd[2] = data->play; | ||
| 181 | ret = blink1_send_command(data, cmd); | ||
| 182 | |||
| 183 | return ret ? ret : count; | ||
| 184 | } | ||
| 185 | |||
| 186 | static DEVICE_ATTR(play, S_IRUGO | S_IWUSR, | ||
| 187 | blink1_show_play, blink1_store_play); | ||
| 188 | |||
| 189 | static const struct attribute_group blink1_sysfs_group = { | ||
| 190 | .attrs = (struct attribute *[]) { | ||
| 191 | &dev_attr_rgb.attr, | ||
| 192 | &dev_attr_fade.attr, | ||
| 193 | &dev_attr_play.attr, | ||
| 194 | NULL | ||
| 195 | }, | ||
| 196 | }; | ||
| 197 | |||
| 198 | static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
| 199 | { | ||
| 200 | struct blink1_data *data; | ||
| 201 | struct led_classdev *led; | ||
| 202 | char led_name[13]; | ||
| 203 | int ret; | ||
| 204 | |||
| 205 | data = devm_kzalloc(&hdev->dev, sizeof(struct blink1_data), GFP_KERNEL); | ||
| 206 | if (!data) | ||
| 207 | return -ENOMEM; | ||
| 208 | |||
| 209 | hid_set_drvdata(hdev, data); | ||
| 210 | data->hdev = hdev; | ||
| 211 | data->rgb = 0xFFFFFF; /* set a default white color */ | ||
| 212 | |||
| 213 | ret = hid_parse(hdev); | ||
| 214 | if (ret) | ||
| 215 | goto error; | ||
| 216 | |||
| 217 | ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); | ||
| 218 | if (ret) | ||
| 219 | goto error; | ||
| 220 | |||
| 221 | /* blink(1) serial numbers range is 0x1A001000 to 0x1A002FFF */ | ||
| 222 | led = &data->led_cdev; | ||
| 223 | snprintf(led_name, sizeof(led_name), "blink1::%s", hdev->uniq + 4); | ||
| 224 | led->name = led_name; | ||
| 225 | led->brightness_set = blink1_led_set; | ||
| 226 | led->brightness_get = blink1_led_get; | ||
| 227 | ret = led_classdev_register(&hdev->dev, led); | ||
| 228 | if (ret) | ||
| 229 | goto stop; | ||
| 230 | |||
| 231 | ret = sysfs_create_group(&led->dev->kobj, &blink1_sysfs_group); | ||
| 232 | if (ret) | ||
| 233 | goto remove_led; | ||
| 234 | |||
| 235 | return 0; | ||
| 236 | |||
| 237 | remove_led: | ||
| 238 | led_classdev_unregister(led); | ||
| 239 | stop: | ||
| 240 | hid_hw_stop(hdev); | ||
| 241 | error: | ||
| 242 | return ret; | ||
| 243 | } | ||
| 244 | |||
| 245 | static void thingm_remove(struct hid_device *hdev) | ||
| 246 | { | ||
| 247 | struct blink1_data *data = hid_get_drvdata(hdev); | ||
| 248 | struct led_classdev *led = &data->led_cdev; | ||
| 249 | |||
| 250 | sysfs_remove_group(&led->dev->kobj, &blink1_sysfs_group); | ||
| 251 | led_classdev_unregister(led); | ||
| 252 | hid_hw_stop(hdev); | ||
| 253 | } | ||
| 254 | |||
| 255 | static const struct hid_device_id thingm_table[] = { | ||
| 256 | { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, | ||
| 257 | { } | ||
| 258 | }; | ||
| 259 | MODULE_DEVICE_TABLE(hid, thingm_table); | ||
| 260 | |||
| 261 | static struct hid_driver thingm_driver = { | ||
| 262 | .name = "thingm", | ||
| 263 | .probe = thingm_probe, | ||
| 264 | .remove = thingm_remove, | ||
| 265 | .id_table = thingm_table, | ||
| 266 | }; | ||
| 267 | |||
| 268 | module_hid_driver(thingm_driver); | ||
| 269 | |||
| 270 | MODULE_LICENSE("GPL"); | ||
| 271 | MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>"); | ||
| 272 | MODULE_DESCRIPTION("ThingM blink(1) USB RGB LED driver"); | ||
diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c index 9f85f827607f..d790d8d71f7f 100644 --- a/drivers/hid/hid-tivo.c +++ b/drivers/hid/hid-tivo.c | |||
| @@ -73,18 +73,7 @@ static struct hid_driver tivo_driver = { | |||
| 73 | .id_table = tivo_devices, | 73 | .id_table = tivo_devices, |
| 74 | .input_mapping = tivo_input_mapping, | 74 | .input_mapping = tivo_input_mapping, |
| 75 | }; | 75 | }; |
| 76 | module_hid_driver(tivo_driver); | ||
| 76 | 77 | ||
| 77 | static int __init tivo_init(void) | ||
| 78 | { | ||
| 79 | return hid_register_driver(&tivo_driver); | ||
| 80 | } | ||
| 81 | |||
| 82 | static void __exit tivo_exit(void) | ||
| 83 | { | ||
| 84 | hid_unregister_driver(&tivo_driver); | ||
| 85 | } | ||
| 86 | |||
| 87 | module_init(tivo_init); | ||
| 88 | module_exit(tivo_exit); | ||
| 89 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
| 90 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); | 79 | MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); |
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index 83a933b9c2e9..e4fcf3f702a5 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c | |||
| @@ -261,17 +261,6 @@ static struct hid_driver tm_driver = { | |||
| 261 | .id_table = tm_devices, | 261 | .id_table = tm_devices, |
| 262 | .probe = tm_probe, | 262 | .probe = tm_probe, |
| 263 | }; | 263 | }; |
| 264 | module_hid_driver(tm_driver); | ||
| 264 | 265 | ||
| 265 | static int __init tm_init(void) | ||
| 266 | { | ||
| 267 | return hid_register_driver(&tm_driver); | ||
| 268 | } | ||
| 269 | |||
| 270 | static void __exit tm_exit(void) | ||
| 271 | { | ||
| 272 | hid_unregister_driver(&tm_driver); | ||
| 273 | } | ||
| 274 | |||
| 275 | module_init(tm_init); | ||
| 276 | module_exit(tm_exit); | ||
| 277 | MODULE_LICENSE("GPL"); | 266 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c index 613ff7b1d746..8a5b843e9dd6 100644 --- a/drivers/hid/hid-topseed.c +++ b/drivers/hid/hid-topseed.c | |||
| @@ -76,17 +76,6 @@ static struct hid_driver ts_driver = { | |||
| 76 | .id_table = ts_devices, | 76 | .id_table = ts_devices, |
| 77 | .input_mapping = ts_input_mapping, | 77 | .input_mapping = ts_input_mapping, |
| 78 | }; | 78 | }; |
| 79 | module_hid_driver(ts_driver); | ||
| 79 | 80 | ||
| 80 | static int __init ts_init(void) | ||
| 81 | { | ||
| 82 | return hid_register_driver(&ts_driver); | ||
| 83 | } | ||
| 84 | |||
| 85 | static void __exit ts_exit(void) | ||
| 86 | { | ||
| 87 | hid_unregister_driver(&ts_driver); | ||
| 88 | } | ||
| 89 | |||
| 90 | module_init(ts_init); | ||
| 91 | module_exit(ts_exit); | ||
| 92 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-twinhan.c b/drivers/hid/hid-twinhan.c index f23456b1fd4b..c08c36443f83 100644 --- a/drivers/hid/hid-twinhan.c +++ b/drivers/hid/hid-twinhan.c | |||
| @@ -131,17 +131,6 @@ static struct hid_driver twinhan_driver = { | |||
| 131 | .id_table = twinhan_devices, | 131 | .id_table = twinhan_devices, |
| 132 | .input_mapping = twinhan_input_mapping, | 132 | .input_mapping = twinhan_input_mapping, |
| 133 | }; | 133 | }; |
| 134 | module_hid_driver(twinhan_driver); | ||
| 134 | 135 | ||
| 135 | static int __init twinhan_init(void) | ||
| 136 | { | ||
| 137 | return hid_register_driver(&twinhan_driver); | ||
| 138 | } | ||
| 139 | |||
| 140 | static void __exit twinhan_exit(void) | ||
| 141 | { | ||
| 142 | hid_unregister_driver(&twinhan_driver); | ||
| 143 | } | ||
| 144 | |||
| 145 | module_init(twinhan_init); | ||
| 146 | module_exit(twinhan_exit); | ||
| 147 | MODULE_LICENSE("GPL"); | 136 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c index 2e56a1fd2375..fb8b516ff0ed 100644 --- a/drivers/hid/hid-uclogic.c +++ b/drivers/hid/hid-uclogic.c | |||
| @@ -650,17 +650,6 @@ static struct hid_driver uclogic_driver = { | |||
| 650 | .id_table = uclogic_devices, | 650 | .id_table = uclogic_devices, |
| 651 | .report_fixup = uclogic_report_fixup, | 651 | .report_fixup = uclogic_report_fixup, |
| 652 | }; | 652 | }; |
| 653 | module_hid_driver(uclogic_driver); | ||
| 653 | 654 | ||
| 654 | static int __init uclogic_init(void) | ||
| 655 | { | ||
| 656 | return hid_register_driver(&uclogic_driver); | ||
| 657 | } | ||
| 658 | |||
| 659 | static void __exit uclogic_exit(void) | ||
| 660 | { | ||
| 661 | hid_unregister_driver(&uclogic_driver); | ||
| 662 | } | ||
| 663 | |||
| 664 | module_init(uclogic_init); | ||
| 665 | module_exit(uclogic_exit); | ||
| 666 | MODULE_LICENSE("GPL"); | 655 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 2f60da9ed066..a4a8bb0da688 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c | |||
| @@ -953,23 +953,7 @@ static struct hid_driver wacom_driver = { | |||
| 953 | .raw_event = wacom_raw_event, | 953 | .raw_event = wacom_raw_event, |
| 954 | .input_mapped = wacom_input_mapped, | 954 | .input_mapped = wacom_input_mapped, |
| 955 | }; | 955 | }; |
| 956 | module_hid_driver(wacom_driver); | ||
| 956 | 957 | ||
| 957 | static int __init wacom_init(void) | ||
| 958 | { | ||
| 959 | int ret; | ||
| 960 | |||
| 961 | ret = hid_register_driver(&wacom_driver); | ||
| 962 | if (ret) | ||
| 963 | pr_err("can't register wacom driver\n"); | ||
| 964 | return ret; | ||
| 965 | } | ||
| 966 | |||
| 967 | static void __exit wacom_exit(void) | ||
| 968 | { | ||
| 969 | hid_unregister_driver(&wacom_driver); | ||
| 970 | } | ||
| 971 | |||
| 972 | module_init(wacom_init); | ||
| 973 | module_exit(wacom_exit); | ||
| 974 | MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); | 958 | MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); |
| 975 | MODULE_LICENSE("GPL"); | 959 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c index bb536ab5941e..059931d7b392 100644 --- a/drivers/hid/hid-waltop.c +++ b/drivers/hid/hid-waltop.c | |||
| @@ -779,17 +779,6 @@ static struct hid_driver waltop_driver = { | |||
| 779 | .report_fixup = waltop_report_fixup, | 779 | .report_fixup = waltop_report_fixup, |
| 780 | .raw_event = waltop_raw_event, | 780 | .raw_event = waltop_raw_event, |
| 781 | }; | 781 | }; |
| 782 | module_hid_driver(waltop_driver); | ||
| 782 | 783 | ||
| 783 | static int __init waltop_init(void) | ||
| 784 | { | ||
| 785 | return hid_register_driver(&waltop_driver); | ||
| 786 | } | ||
| 787 | |||
| 788 | static void __exit waltop_exit(void) | ||
| 789 | { | ||
| 790 | hid_unregister_driver(&waltop_driver); | ||
| 791 | } | ||
| 792 | |||
| 793 | module_init(waltop_init); | ||
| 794 | module_exit(waltop_exit); | ||
| 795 | MODULE_LICENSE("GPL"); | 784 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 84e2fbec5fbb..0fb8ab93db68 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c | |||
| @@ -1294,25 +1294,8 @@ static struct hid_driver wiimote_hid_driver = { | |||
| 1294 | .remove = wiimote_hid_remove, | 1294 | .remove = wiimote_hid_remove, |
| 1295 | .raw_event = wiimote_hid_event, | 1295 | .raw_event = wiimote_hid_event, |
| 1296 | }; | 1296 | }; |
| 1297 | module_hid_driver(wiimote_hid_driver); | ||
| 1297 | 1298 | ||
| 1298 | static int __init wiimote_init(void) | ||
| 1299 | { | ||
| 1300 | int ret; | ||
| 1301 | |||
| 1302 | ret = hid_register_driver(&wiimote_hid_driver); | ||
| 1303 | if (ret) | ||
| 1304 | pr_err("Can't register wiimote hid driver\n"); | ||
| 1305 | |||
| 1306 | return ret; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | static void __exit wiimote_exit(void) | ||
| 1310 | { | ||
| 1311 | hid_unregister_driver(&wiimote_hid_driver); | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | module_init(wiimote_init); | ||
| 1315 | module_exit(wiimote_exit); | ||
| 1316 | MODULE_LICENSE("GPL"); | 1299 | MODULE_LICENSE("GPL"); |
| 1317 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); | 1300 | MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); |
| 1318 | MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver"); | 1301 | MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver"); |
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index eec329197c16..90124ffaa2a5 100644 --- a/drivers/hid/hid-wiimote-debug.c +++ b/drivers/hid/hid-wiimote-debug.c | |||
| @@ -31,7 +31,7 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s, | |||
| 31 | unsigned long flags; | 31 | unsigned long flags; |
| 32 | ssize_t ret; | 32 | ssize_t ret; |
| 33 | char buf[16]; | 33 | char buf[16]; |
| 34 | __u16 size; | 34 | __u16 size = 0; |
| 35 | 35 | ||
| 36 | if (s == 0) | 36 | if (s == 0) |
| 37 | return -EINVAL; | 37 | return -EINVAL; |
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c index 38ae87772e96..0472191d4a72 100644 --- a/drivers/hid/hid-wiimote-ext.c +++ b/drivers/hid/hid-wiimote-ext.c | |||
| @@ -403,14 +403,14 @@ static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload) | |||
| 403 | 403 | ||
| 404 | if (ext->motionp) { | 404 | if (ext->motionp) { |
| 405 | input_report_key(ext->input, | 405 | input_report_key(ext->input, |
| 406 | wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x04)); | 406 | wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04)); |
| 407 | input_report_key(ext->input, | 407 | input_report_key(ext->input, |
| 408 | wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x08)); | 408 | wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08)); |
| 409 | } else { | 409 | } else { |
| 410 | input_report_key(ext->input, | 410 | input_report_key(ext->input, |
| 411 | wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x01)); | 411 | wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01)); |
| 412 | input_report_key(ext->input, | 412 | input_report_key(ext->input, |
| 413 | wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x02)); | 413 | wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02)); |
| 414 | } | 414 | } |
| 415 | 415 | ||
| 416 | input_sync(ext->input); | 416 | input_sync(ext->input); |
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index f6ba81df71bd..af66452592e9 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c | |||
| @@ -152,17 +152,6 @@ static struct hid_driver zp_driver = { | |||
| 152 | .id_table = zp_devices, | 152 | .id_table = zp_devices, |
| 153 | .probe = zp_probe, | 153 | .probe = zp_probe, |
| 154 | }; | 154 | }; |
| 155 | module_hid_driver(zp_driver); | ||
| 155 | 156 | ||
| 156 | static int __init zp_init(void) | ||
| 157 | { | ||
| 158 | return hid_register_driver(&zp_driver); | ||
| 159 | } | ||
| 160 | |||
| 161 | static void __exit zp_exit(void) | ||
| 162 | { | ||
| 163 | hid_unregister_driver(&zp_driver); | ||
| 164 | } | ||
| 165 | |||
| 166 | module_init(zp_init); | ||
| 167 | module_exit(zp_exit); | ||
| 168 | MODULE_LICENSE("GPL"); | 157 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c index 1ad85f2257b4..e4cddeccd6b5 100644 --- a/drivers/hid/hid-zydacron.c +++ b/drivers/hid/hid-zydacron.c | |||
| @@ -219,17 +219,6 @@ static struct hid_driver zc_driver = { | |||
| 219 | .probe = zc_probe, | 219 | .probe = zc_probe, |
| 220 | .remove = zc_remove, | 220 | .remove = zc_remove, |
| 221 | }; | 221 | }; |
| 222 | module_hid_driver(zc_driver); | ||
| 222 | 223 | ||
| 223 | static int __init zc_init(void) | ||
| 224 | { | ||
| 225 | return hid_register_driver(&zc_driver); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void __exit zc_exit(void) | ||
| 229 | { | ||
| 230 | hid_unregister_driver(&zc_driver); | ||
| 231 | } | ||
| 232 | |||
| 233 | module_init(zc_init); | ||
| 234 | module_exit(zc_exit); | ||
| 235 | MODULE_LICENSE("GPL"); | 224 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 413a73187d33..f3bbbce8353b 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -581,6 +581,7 @@ int __init hidraw_init(void) | |||
| 581 | if (result < 0) | 581 | if (result < 0) |
| 582 | goto error_class; | 582 | goto error_class; |
| 583 | 583 | ||
| 584 | printk(KERN_INFO "hidraw: raw HID events driver (C) Jiri Kosina\n"); | ||
| 584 | out: | 585 | out: |
| 585 | return result; | 586 | return result; |
| 586 | 587 | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index e766b5614ef5..ec7930217a6d 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
| 35 | #include <linux/hid.h> | 35 | #include <linux/hid.h> |
| 36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
| 37 | #include <linux/acpi.h> | ||
| 37 | 38 | ||
| 38 | #include <linux/i2c/i2c-hid.h> | 39 | #include <linux/i2c/i2c-hid.h> |
| 39 | 40 | ||
| @@ -139,6 +140,8 @@ struct i2c_hid { | |||
| 139 | unsigned long flags; /* device flags */ | 140 | unsigned long flags; /* device flags */ |
| 140 | 141 | ||
| 141 | wait_queue_head_t wait; /* For waiting the interrupt */ | 142 | wait_queue_head_t wait; /* For waiting the interrupt */ |
| 143 | |||
| 144 | struct i2c_hid_platform_data pdata; | ||
| 142 | }; | 145 | }; |
| 143 | 146 | ||
| 144 | static int __i2c_hid_command(struct i2c_client *client, | 147 | static int __i2c_hid_command(struct i2c_client *client, |
| @@ -821,6 +824,70 @@ static int i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) | |||
| 821 | return 0; | 824 | return 0; |
| 822 | } | 825 | } |
| 823 | 826 | ||
| 827 | #ifdef CONFIG_ACPI | ||
| 828 | static int i2c_hid_acpi_pdata(struct i2c_client *client, | ||
| 829 | struct i2c_hid_platform_data *pdata) | ||
| 830 | { | ||
| 831 | static u8 i2c_hid_guid[] = { | ||
| 832 | 0xF7, 0xF6, 0xDF, 0x3C, 0x67, 0x42, 0x55, 0x45, | ||
| 833 | 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE, | ||
| 834 | }; | ||
| 835 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 836 | union acpi_object params[4], *obj; | ||
| 837 | struct acpi_object_list input; | ||
| 838 | struct acpi_device *adev; | ||
| 839 | acpi_handle handle; | ||
| 840 | |||
| 841 | handle = ACPI_HANDLE(&client->dev); | ||
| 842 | if (!handle || acpi_bus_get_device(handle, &adev)) | ||
| 843 | return -ENODEV; | ||
| 844 | |||
| 845 | input.count = ARRAY_SIZE(params); | ||
| 846 | input.pointer = params; | ||
| 847 | |||
| 848 | params[0].type = ACPI_TYPE_BUFFER; | ||
| 849 | params[0].buffer.length = sizeof(i2c_hid_guid); | ||
| 850 | params[0].buffer.pointer = i2c_hid_guid; | ||
| 851 | params[1].type = ACPI_TYPE_INTEGER; | ||
| 852 | params[1].integer.value = 1; | ||
| 853 | params[2].type = ACPI_TYPE_INTEGER; | ||
| 854 | params[2].integer.value = 1; /* HID function */ | ||
| 855 | params[3].type = ACPI_TYPE_INTEGER; | ||
| 856 | params[3].integer.value = 0; | ||
| 857 | |||
| 858 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) { | ||
| 859 | dev_err(&client->dev, "device _DSM execution failed\n"); | ||
| 860 | return -ENODEV; | ||
| 861 | } | ||
| 862 | |||
| 863 | obj = (union acpi_object *)buf.pointer; | ||
| 864 | if (obj->type != ACPI_TYPE_INTEGER) { | ||
| 865 | dev_err(&client->dev, "device _DSM returned invalid type: %d\n", | ||
| 866 | obj->type); | ||
| 867 | kfree(buf.pointer); | ||
| 868 | return -EINVAL; | ||
| 869 | } | ||
| 870 | |||
| 871 | pdata->hid_descriptor_address = obj->integer.value; | ||
| 872 | |||
| 873 | kfree(buf.pointer); | ||
| 874 | return 0; | ||
| 875 | } | ||
| 876 | |||
| 877 | static const struct acpi_device_id i2c_hid_acpi_match[] = { | ||
| 878 | {"ACPI0C50", 0 }, | ||
| 879 | {"PNP0C50", 0 }, | ||
| 880 | { }, | ||
| 881 | }; | ||
| 882 | MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match); | ||
| 883 | #else | ||
| 884 | static inline int i2c_hid_acpi_pdata(struct i2c_client *client, | ||
| 885 | struct i2c_hid_platform_data *pdata) | ||
| 886 | { | ||
| 887 | return -ENODEV; | ||
| 888 | } | ||
| 889 | #endif | ||
| 890 | |||
| 824 | static int i2c_hid_probe(struct i2c_client *client, | 891 | static int i2c_hid_probe(struct i2c_client *client, |
| 825 | const struct i2c_device_id *dev_id) | 892 | const struct i2c_device_id *dev_id) |
| 826 | { | 893 | { |
| @@ -832,11 +899,6 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
| 832 | 899 | ||
| 833 | dbg_hid("HID probe called for i2c 0x%02x\n", client->addr); | 900 | dbg_hid("HID probe called for i2c 0x%02x\n", client->addr); |
| 834 | 901 | ||
| 835 | if (!platform_data) { | ||
| 836 | dev_err(&client->dev, "HID register address not provided\n"); | ||
| 837 | return -EINVAL; | ||
| 838 | } | ||
| 839 | |||
| 840 | if (!client->irq) { | 902 | if (!client->irq) { |
| 841 | dev_err(&client->dev, | 903 | dev_err(&client->dev, |
| 842 | "HID over i2c has not been provided an Int IRQ\n"); | 904 | "HID over i2c has not been provided an Int IRQ\n"); |
| @@ -847,11 +909,22 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
| 847 | if (!ihid) | 909 | if (!ihid) |
| 848 | return -ENOMEM; | 910 | return -ENOMEM; |
| 849 | 911 | ||
| 912 | if (!platform_data) { | ||
| 913 | ret = i2c_hid_acpi_pdata(client, &ihid->pdata); | ||
| 914 | if (ret) { | ||
| 915 | dev_err(&client->dev, | ||
| 916 | "HID register address not provided\n"); | ||
| 917 | goto err; | ||
| 918 | } | ||
| 919 | } else { | ||
| 920 | ihid->pdata = *platform_data; | ||
| 921 | } | ||
| 922 | |||
| 850 | i2c_set_clientdata(client, ihid); | 923 | i2c_set_clientdata(client, ihid); |
| 851 | 924 | ||
| 852 | ihid->client = client; | 925 | ihid->client = client; |
| 853 | 926 | ||
| 854 | hidRegister = platform_data->hid_descriptor_address; | 927 | hidRegister = ihid->pdata.hid_descriptor_address; |
| 855 | ihid->wHIDDescRegister = cpu_to_le16(hidRegister); | 928 | ihid->wHIDDescRegister = cpu_to_le16(hidRegister); |
| 856 | 929 | ||
| 857 | init_waitqueue_head(&ihid->wait); | 930 | init_waitqueue_head(&ihid->wait); |
| @@ -884,6 +957,7 @@ static int i2c_hid_probe(struct i2c_client *client, | |||
| 884 | hid->hid_get_raw_report = i2c_hid_get_raw_report; | 957 | hid->hid_get_raw_report = i2c_hid_get_raw_report; |
| 885 | hid->hid_output_raw_report = i2c_hid_output_raw_report; | 958 | hid->hid_output_raw_report = i2c_hid_output_raw_report; |
| 886 | hid->dev.parent = &client->dev; | 959 | hid->dev.parent = &client->dev; |
| 960 | ACPI_HANDLE_SET(&hid->dev, ACPI_HANDLE(&client->dev)); | ||
| 887 | hid->bus = BUS_I2C; | 961 | hid->bus = BUS_I2C; |
| 888 | hid->version = le16_to_cpu(ihid->hdesc.bcdVersion); | 962 | hid->version = le16_to_cpu(ihid->hdesc.bcdVersion); |
| 889 | hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); | 963 | hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); |
| @@ -975,6 +1049,7 @@ static struct i2c_driver i2c_hid_driver = { | |||
| 975 | .name = "i2c_hid", | 1049 | .name = "i2c_hid", |
| 976 | .owner = THIS_MODULE, | 1050 | .owner = THIS_MODULE, |
| 977 | .pm = &i2c_hid_pm, | 1051 | .pm = &i2c_hid_pm, |
| 1052 | .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match), | ||
| 978 | }, | 1053 | }, |
| 979 | 1054 | ||
| 980 | .probe = i2c_hid_probe, | 1055 | .probe = i2c_hid_probe, |
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 714cd8cc9579..fc307e0422af 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
| 14 | #include <linux/compat.h> | ||
| 14 | #include <linux/device.h> | 15 | #include <linux/device.h> |
| 15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
| 16 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
| @@ -276,6 +277,94 @@ static struct hid_ll_driver uhid_hid_driver = { | |||
| 276 | .parse = uhid_hid_parse, | 277 | .parse = uhid_hid_parse, |
| 277 | }; | 278 | }; |
| 278 | 279 | ||
| 280 | #ifdef CONFIG_COMPAT | ||
| 281 | |||
| 282 | /* Apparently we haven't stepped on these rakes enough times yet. */ | ||
| 283 | struct uhid_create_req_compat { | ||
| 284 | __u8 name[128]; | ||
| 285 | __u8 phys[64]; | ||
| 286 | __u8 uniq[64]; | ||
| 287 | |||
| 288 | compat_uptr_t rd_data; | ||
| 289 | __u16 rd_size; | ||
| 290 | |||
| 291 | __u16 bus; | ||
| 292 | __u32 vendor; | ||
| 293 | __u32 product; | ||
| 294 | __u32 version; | ||
| 295 | __u32 country; | ||
| 296 | } __attribute__((__packed__)); | ||
| 297 | |||
| 298 | static int uhid_event_from_user(const char __user *buffer, size_t len, | ||
| 299 | struct uhid_event *event) | ||
| 300 | { | ||
| 301 | if (is_compat_task()) { | ||
| 302 | u32 type; | ||
| 303 | |||
| 304 | if (get_user(type, buffer)) | ||
| 305 | return -EFAULT; | ||
| 306 | |||
| 307 | if (type == UHID_CREATE) { | ||
| 308 | /* | ||
| 309 | * This is our messed up request with compat pointer. | ||
| 310 | * It is largish (more than 256 bytes) so we better | ||
| 311 | * allocate it from the heap. | ||
| 312 | */ | ||
| 313 | struct uhid_create_req_compat *compat; | ||
| 314 | |||
| 315 | compat = kmalloc(sizeof(*compat), GFP_KERNEL); | ||
| 316 | if (!compat) | ||
| 317 | return -ENOMEM; | ||
| 318 | |||
| 319 | buffer += sizeof(type); | ||
| 320 | len -= sizeof(type); | ||
| 321 | if (copy_from_user(compat, buffer, | ||
| 322 | min(len, sizeof(*compat)))) { | ||
| 323 | kfree(compat); | ||
| 324 | return -EFAULT; | ||
| 325 | } | ||
| 326 | |||
| 327 | /* Shuffle the data over to proper structure */ | ||
| 328 | event->type = type; | ||
| 329 | |||
| 330 | memcpy(event->u.create.name, compat->name, | ||
| 331 | sizeof(compat->name)); | ||
| 332 | memcpy(event->u.create.phys, compat->phys, | ||
| 333 | sizeof(compat->phys)); | ||
| 334 | memcpy(event->u.create.uniq, compat->uniq, | ||
| 335 | sizeof(compat->uniq)); | ||
| 336 | |||
| 337 | event->u.create.rd_data = compat_ptr(compat->rd_data); | ||
| 338 | event->u.create.rd_size = compat->rd_size; | ||
| 339 | |||
| 340 | event->u.create.bus = compat->bus; | ||
| 341 | event->u.create.vendor = compat->vendor; | ||
| 342 | event->u.create.product = compat->product; | ||
| 343 | event->u.create.version = compat->version; | ||
| 344 | event->u.create.country = compat->country; | ||
| 345 | |||
| 346 | kfree(compat); | ||
| 347 | return 0; | ||
| 348 | } | ||
| 349 | /* All others can be copied directly */ | ||
| 350 | } | ||
| 351 | |||
| 352 | if (copy_from_user(event, buffer, min(len, sizeof(*event)))) | ||
| 353 | return -EFAULT; | ||
| 354 | |||
| 355 | return 0; | ||
| 356 | } | ||
| 357 | #else | ||
| 358 | static int uhid_event_from_user(const char __user *buffer, size_t len, | ||
| 359 | struct uhid_event *event) | ||
| 360 | { | ||
| 361 | if (copy_from_user(event, buffer, min(len, sizeof(*event)))) | ||
| 362 | return -EFAULT; | ||
| 363 | |||
| 364 | return 0; | ||
| 365 | } | ||
| 366 | #endif | ||
| 367 | |||
| 279 | static int uhid_dev_create(struct uhid_device *uhid, | 368 | static int uhid_dev_create(struct uhid_device *uhid, |
| 280 | const struct uhid_event *ev) | 369 | const struct uhid_event *ev) |
| 281 | { | 370 | { |
| @@ -498,10 +587,10 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, | |||
| 498 | 587 | ||
| 499 | memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); | 588 | memset(&uhid->input_buf, 0, sizeof(uhid->input_buf)); |
| 500 | len = min(count, sizeof(uhid->input_buf)); | 589 | len = min(count, sizeof(uhid->input_buf)); |
| 501 | if (copy_from_user(&uhid->input_buf, buffer, len)) { | 590 | |
| 502 | ret = -EFAULT; | 591 | ret = uhid_event_from_user(buffer, len, &uhid->input_buf); |
| 592 | if (ret) | ||
| 503 | goto unlock; | 593 | goto unlock; |
| 504 | } | ||
| 505 | 594 | ||
| 506 | switch (uhid->input_buf.type) { | 595 | switch (uhid->input_buf.type) { |
| 507 | case UHID_CREATE: | 596 | case UHID_CREATE: |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 7330a0fef0c0..e14b465b1146 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -589,6 +589,7 @@ struct hid_usage_id { | |||
| 589 | * @raw_event: if report in report_table, this hook is called (NULL means nop) | 589 | * @raw_event: if report in report_table, this hook is called (NULL means nop) |
| 590 | * @usage_table: on which events to call event (NULL means all) | 590 | * @usage_table: on which events to call event (NULL means all) |
| 591 | * @event: if usage in usage_table, this hook is called (NULL means nop) | 591 | * @event: if usage in usage_table, this hook is called (NULL means nop) |
| 592 | * @report: this hook is called after parsing a report (NULL means nop) | ||
| 592 | * @report_fixup: called before report descriptor parsing (NULL means nop) | 593 | * @report_fixup: called before report descriptor parsing (NULL means nop) |
| 593 | * @input_mapping: invoked on input registering before mapping an usage | 594 | * @input_mapping: invoked on input registering before mapping an usage |
| 594 | * @input_mapped: invoked on input registering after mapping an usage | 595 | * @input_mapped: invoked on input registering after mapping an usage |
| @@ -627,6 +628,7 @@ struct hid_driver { | |||
| 627 | const struct hid_usage_id *usage_table; | 628 | const struct hid_usage_id *usage_table; |
| 628 | int (*event)(struct hid_device *hdev, struct hid_field *field, | 629 | int (*event)(struct hid_device *hdev, struct hid_field *field, |
| 629 | struct hid_usage *usage, __s32 value); | 630 | struct hid_usage *usage, __s32 value); |
| 631 | void (*report)(struct hid_device *hdev, struct hid_report *report); | ||
| 630 | 632 | ||
| 631 | __u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf, | 633 | __u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf, |
| 632 | unsigned int *size); | 634 | unsigned int *size); |
| @@ -700,6 +702,18 @@ extern int __must_check __hid_register_driver(struct hid_driver *, | |||
| 700 | 702 | ||
| 701 | extern void hid_unregister_driver(struct hid_driver *); | 703 | extern void hid_unregister_driver(struct hid_driver *); |
| 702 | 704 | ||
| 705 | /** | ||
| 706 | * module_hid_driver() - Helper macro for registering a HID driver | ||
| 707 | * @__hid_driver: hid_driver struct | ||
| 708 | * | ||
| 709 | * Helper macro for HID drivers which do not do anything special in module | ||
| 710 | * init/exit. This eliminates a lot of boilerplate. Each module may only | ||
| 711 | * use this macro once, and calling it replaces module_init() and module_exit() | ||
| 712 | */ | ||
| 713 | #define module_hid_driver(__hid_driver) \ | ||
| 714 | module_driver(__hid_driver, hid_register_driver, \ | ||
| 715 | hid_unregister_driver) | ||
| 716 | |||
| 703 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | 717 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
| 704 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); | 718 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); |
| 705 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); | 719 | extern int hidinput_connect(struct hid_device *hid, unsigned int force); |
| @@ -872,9 +886,6 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) | |||
| 872 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 886 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
| 873 | int interrupt); | 887 | int interrupt); |
| 874 | 888 | ||
| 875 | extern int hid_generic_init(void); | ||
| 876 | extern void hid_generic_exit(void); | ||
| 877 | |||
| 878 | /* HID quirks API */ | 889 | /* HID quirks API */ |
| 879 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); | 890 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); |
| 880 | int usbhid_quirks_init(char **quirks_param); | 891 | int usbhid_quirks_init(char **quirks_param); |
diff --git a/include/uapi/linux/uhid.h b/include/uapi/linux/uhid.h index 9c6974f16966..e9ed951e2b09 100644 --- a/include/uapi/linux/uhid.h +++ b/include/uapi/linux/uhid.h | |||
| @@ -86,7 +86,7 @@ struct uhid_feature_answer_req { | |||
| 86 | __u16 err; | 86 | __u16 err; |
| 87 | __u16 size; | 87 | __u16 size; |
| 88 | __u8 data[UHID_DATA_MAX]; | 88 | __u8 data[UHID_DATA_MAX]; |
| 89 | }; | 89 | } __attribute__((__packed__)); |
| 90 | 90 | ||
| 91 | struct uhid_event { | 91 | struct uhid_event { |
| 92 | __u32 type; | 92 | __u32 type; |
