aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 20:41:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 20:41:38 -0500
commit48a732dfaa77a4dfec803aa8f248373998704f76 (patch)
treeb8ea89d3f48bc82fcc1b14d8cd356241e7ef2d37 /drivers/hid
parent9afa3195b96da7d2320ec44d19fbfbded7a15571 (diff)
parent0d69a3c731e120b05b7da9fb976830475a3fbc01 (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 ...
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig18
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-a4tech.c13
-rw-r--r--drivers/hid/hid-apple.c19
-rw-r--r--drivers/hid/hid-aureal.c13
-rw-r--r--drivers/hid/hid-axff.c14
-rw-r--r--drivers/hid/hid-belkin.c13
-rw-r--r--drivers/hid/hid-cherry.c13
-rw-r--r--drivers/hid/hid-chicony.c13
-rw-r--r--drivers/hid/hid-core.c17
-rw-r--r--drivers/hid/hid-cypress.c13
-rw-r--r--drivers/hid/hid-dr.c13
-rw-r--r--drivers/hid/hid-elecom.c13
-rw-r--r--drivers/hid/hid-emsff.c13
-rw-r--r--drivers/hid/hid-ezkey.c13
-rw-r--r--drivers/hid/hid-gaff.c13
-rw-r--r--drivers/hid/hid-generic.c14
-rw-r--r--drivers/hid/hid-gyration.c13
-rw-r--r--drivers/hid/hid-holtek-kbd.c13
-rw-r--r--drivers/hid/hid-holtekff.c15
-rw-r--r--drivers/hid/hid-icade.c19
-rw-r--r--drivers/hid/hid-ids.h21
-rw-r--r--drivers/hid/hid-kensington.c13
-rw-r--r--drivers/hid/hid-keytouch.c13
-rw-r--r--drivers/hid/hid-kye.c13
-rw-r--r--drivers/hid/hid-lcpower.c13
-rw-r--r--drivers/hid/hid-lenovo-tpkbd.c14
-rw-r--r--drivers/hid/hid-lg.c212
-rw-r--r--drivers/hid/hid-lg4ff.c17
-rw-r--r--drivers/hid/hid-magicmouse.c19
-rw-r--r--drivers/hid/hid-microsoft.c13
-rw-r--r--drivers/hid/hid-monterey.c13
-rw-r--r--drivers/hid/hid-multitouch.c163
-rw-r--r--drivers/hid/hid-ntrig.c81
-rw-r--r--drivers/hid/hid-ortek.c13
-rw-r--r--drivers/hid/hid-petalynx.c13
-rw-r--r--drivers/hid/hid-picolcd_core.c13
-rw-r--r--drivers/hid/hid-pl.c26
-rw-r--r--drivers/hid/hid-primax.c13
-rw-r--r--drivers/hid/hid-prodikeys.c19
-rw-r--r--drivers/hid/hid-ps3remote.c13
-rw-r--r--drivers/hid/hid-roccat-lua.c14
-rw-r--r--drivers/hid/hid-saitek.c13
-rw-r--r--drivers/hid/hid-samsung.c13
-rw-r--r--drivers/hid/hid-sensor-hub.c22
-rw-r--r--drivers/hid/hid-sjoy.c13
-rw-r--r--drivers/hid/hid-sony.c59
-rw-r--r--drivers/hid/hid-speedlink.c13
-rw-r--r--drivers/hid/hid-steelseries.c393
-rw-r--r--drivers/hid/hid-sunplus.c13
-rw-r--r--drivers/hid/hid-thingm.c272
-rw-r--r--drivers/hid/hid-tivo.c13
-rw-r--r--drivers/hid/hid-tmff.c13
-rw-r--r--drivers/hid/hid-topseed.c13
-rw-r--r--drivers/hid/hid-twinhan.c13
-rw-r--r--drivers/hid/hid-uclogic.c13
-rw-r--r--drivers/hid/hid-wacom.c18
-rw-r--r--drivers/hid/hid-waltop.c13
-rw-r--r--drivers/hid/hid-wiimote-core.c19
-rw-r--r--drivers/hid/hid-wiimote-debug.c2
-rw-r--r--drivers/hid/hid-wiimote-ext.c8
-rw-r--r--drivers/hid/hid-zpff.c13
-rw-r--r--drivers/hid/hid-zydacron.c13
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c87
-rw-r--r--drivers/hid/uhid.c95
66 files changed, 1341 insertions, 820 deletions
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
599config 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
599config HID_SUNPLUS 605config 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
664config 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
658config HID_THRUSTMASTER 674config 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
720config HID_SENSOR_HUB 736config 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
101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
102obj-$(CONFIG_HID_SONY) += hid-sony.o 102obj-$(CONFIG_HID_SONY) += hid-sony.o
103obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o 103obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
104obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o
104obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o 105obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
105obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o 106obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
107obj-$(CONFIG_HID_THINGM) += hid-thingm.o
106obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o 108obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
107obj-$(CONFIG_HID_TIVO) += hid-tivo.o 109obj-$(CONFIG_HID_TIVO) += hid-tivo.o
108obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o 110obj-$(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};
149module_hid_driver(a4_driver);
149 150
150static int __init a4_init(void)
151{
152 return hid_register_driver(&a4_driver);
153}
154
155static void __exit a4_exit(void)
156{
157 hid_unregister_driver(&a4_driver);
158}
159
160module_init(a4_init);
161module_exit(a4_exit);
162MODULE_LICENSE("GPL"); 151MODULE_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};
558module_hid_driver(apple_driver);
558 559
559static 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
570static void __exit apple_exit(void)
571{
572 hid_unregister_driver(&apple_driver);
573}
574
575module_init(apple_init);
576module_exit(apple_exit);
577MODULE_LICENSE("GPL"); 560MODULE_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};
40module_hid_driver(aureal_driver);
40 41
41static int __init aureal_init(void)
42{
43 return hid_register_driver(&aureal_driver);
44}
45
46static void __exit aureal_exit(void)
47{
48 hid_unregister_driver(&aureal_driver);
49}
50
51module_init(aureal_init);
52module_exit(aureal_exit);
53MODULE_LICENSE("GPL"); 42MODULE_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 195module_hid_driver(ax_driver);
196static int __init ax_init(void)
197{
198 return hid_register_driver(&ax_driver);
199}
200
201static void __exit ax_exit(void)
202{
203 hid_unregister_driver(&ax_driver);
204}
205
206module_init(ax_init);
207module_exit(ax_exit);
208 196
209MODULE_AUTHOR("Sergei Kolzun"); 197MODULE_AUTHOR("Sergei Kolzun");
210MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers"); 198MODULE_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};
89module_hid_driver(belkin_driver);
89 90
90static int __init belkin_init(void)
91{
92 return hid_register_driver(&belkin_driver);
93}
94
95static void __exit belkin_exit(void)
96{
97 hid_unregister_driver(&belkin_driver);
98}
99
100module_init(belkin_init);
101module_exit(belkin_exit);
102MODULE_LICENSE("GPL"); 91MODULE_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};
72module_hid_driver(ch_driver);
72 73
73static int __init ch_init(void)
74{
75 return hid_register_driver(&ch_driver);
76}
77
78static void __exit ch_exit(void)
79{
80 hid_unregister_driver(&ch_driver);
81}
82
83module_init(ch_init);
84module_exit(ch_exit);
85MODULE_LICENSE("GPL"); 74MODULE_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};
73module_hid_driver(ch_driver);
73 74
74static int __init ch_init(void)
75{
76 return hid_register_driver(&ch_driver);
77}
78
79static void __exit ch_exit(void)
80{
81 hid_unregister_driver(&ch_driver);
82}
83
84module_init(ch_init);
85module_exit(ch_exit);
86MODULE_LICENSE("GPL"); 75MODULE_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};
147module_hid_driver(cp_driver);
147 148
148static int __init cp_init(void)
149{
150 return hid_register_driver(&cp_driver);
151}
152
153static void __exit cp_exit(void)
154{
155 hid_unregister_driver(&cp_driver);
156}
157
158module_init(cp_init);
159module_exit(cp_exit);
160MODULE_LICENSE("GPL"); 149MODULE_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};
300module_hid_driver(dr_driver);
300 301
301static int __init dr_init(void)
302{
303 return hid_register_driver(&dr_driver);
304}
305
306static void __exit dr_exit(void)
307{
308 hid_unregister_driver(&dr_driver);
309}
310
311module_init(dr_init);
312module_exit(dr_exit);
313MODULE_LICENSE("GPL"); 302MODULE_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};
44module_hid_driver(elecom_driver);
44 45
45static int __init elecom_init(void)
46{
47 return hid_register_driver(&elecom_driver);
48}
49
50static void __exit elecom_exit(void)
51{
52 hid_unregister_driver(&elecom_driver);
53}
54
55module_init(elecom_init);
56module_exit(elecom_exit);
57MODULE_LICENSE("GPL"); 46MODULE_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};
153module_hid_driver(ems_driver);
153 154
154static int ems_init(void)
155{
156 return hid_register_driver(&ems_driver);
157}
158
159static void ems_exit(void)
160{
161 hid_unregister_driver(&ems_driver);
162}
163
164module_init(ems_init);
165module_exit(ems_exit);
166MODULE_LICENSE("GPL"); 155MODULE_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};
79module_hid_driver(ez_driver);
79 80
80static int __init ez_init(void)
81{
82 return hid_register_driver(&ez_driver);
83}
84
85static void __exit ez_exit(void)
86{
87 hid_unregister_driver(&ez_driver);
88}
89
90module_init(ez_init);
91module_exit(ez_exit);
92MODULE_LICENSE("GPL"); 81MODULE_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};
179module_hid_driver(ga_driver);
179 180
180static int __init ga_init(void)
181{
182 return hid_register_driver(&ga_driver);
183}
184
185static void __exit ga_exit(void)
186{
187 hid_unregister_driver(&ga_driver);
188}
189
190module_init(ga_init);
191module_exit(ga_exit);
192MODULE_LICENSE("GPL"); 181MODULE_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 37module_hid_driver(hid_generic);
38static int __init hid_init(void)
39{
40 return hid_register_driver(&hid_generic);
41}
42
43static void __exit hid_exit(void)
44{
45 hid_unregister_driver(&hid_generic);
46}
47
48module_init(hid_init);
49module_exit(hid_exit);
50 38
51MODULE_AUTHOR("Henrik Rydberg"); 39MODULE_AUTHOR("Henrik Rydberg");
52MODULE_DESCRIPTION("HID generic driver"); 40MODULE_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};
91module_hid_driver(gyration_driver);
91 92
92static int __init gyration_init(void)
93{
94 return hid_register_driver(&gyration_driver);
95}
96
97static void __exit gyration_exit(void)
98{
99 hid_unregister_driver(&gyration_driver);
100}
101
102module_init(gyration_init);
103module_exit(gyration_exit);
104MODULE_LICENSE("GPL"); 93MODULE_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};
170module_hid_driver(holtek_kbd_driver);
170 171
171static int __init holtek_kbd_init(void)
172{
173 return hid_register_driver(&holtek_kbd_driver);
174}
175
176static void __exit holtek_kbd_exit(void)
177{
178 hid_unregister_driver(&holtek_kbd_driver);
179}
180
181module_exit(holtek_kbd_exit);
182module_init(holtek_kbd_init);
183MODULE_LICENSE("GPL"); 172MODULE_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 227module_hid_driver(holtek_driver);
228static int __init holtek_init(void)
229{
230 return hid_register_driver(&holtek_driver);
231}
232
233static void __exit holtek_exit(void)
234{
235 hid_unregister_driver(&holtek_driver);
236}
237
238module_init(holtek_init);
239module_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};
238module_hid_driver(icade_driver);
238 239
239static 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
250static void __exit icade_exit(void)
251{
252 hid_unregister_driver(&icade_driver);
253}
254
255module_init(icade_init);
256module_exit(icade_exit);
257MODULE_LICENSE("GPL"); 240MODULE_LICENSE("GPL");
258MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); 241MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
259MODULE_DESCRIPTION("ION iCade input driver"); 242MODULE_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};
50module_hid_driver(ks_driver);
50 51
51static int __init ks_init(void)
52{
53 return hid_register_driver(&ks_driver);
54}
55
56static void __exit ks_exit(void)
57{
58 hid_unregister_driver(&ks_driver);
59}
60
61module_init(ks_init);
62module_exit(ks_exit);
63MODULE_LICENSE("GPL"); 52MODULE_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};
52module_hid_driver(keytouch_driver);
52 53
53static int __init keytouch_init(void)
54{
55 return hid_register_driver(&keytouch_driver);
56}
57
58static void __exit keytouch_exit(void)
59{
60 hid_unregister_driver(&keytouch_driver);
61}
62
63module_init(keytouch_init);
64module_exit(keytouch_exit);
65MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
66MODULE_AUTHOR("Jiri Kosina"); 55MODULE_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};
422module_hid_driver(kye_driver);
422 423
423static int __init kye_init(void)
424{
425 return hid_register_driver(&kye_driver);
426}
427
428static void __exit kye_exit(void)
429{
430 hid_unregister_driver(&kye_driver);
431}
432
433module_init(kye_init);
434module_exit(kye_exit);
435MODULE_LICENSE("GPL"); 424MODULE_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};
57module_hid_driver(ts_driver);
57 58
58static int __init ts_init(void)
59{
60 return hid_register_driver(&ts_driver);
61}
62
63static void __exit ts_exit(void)
64{
65 hid_unregister_driver(&ts_driver);
66}
67
68module_init(ts_init);
69module_exit(ts_exit);
70MODULE_LICENSE("GPL"); 59MODULE_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 471module_hid_driver(tpkbd_driver);
472static int __init tpkbd_init(void)
473{
474 return hid_register_driver(&tpkbd_driver);
475}
476
477static void __exit tpkbd_exit(void)
478{
479 hid_unregister_driver(&tpkbd_driver);
480}
481
482module_init(tpkbd_init);
483module_exit(tpkbd_exit);
484 472
485MODULE_LICENSE("GPL"); 473MODULE_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 */
59static __u8 df_rdesc_fixed[] = {
600x05, 0x01, /* Usage Page (Desktop), */
610x09, 0x04, /* Usage (Joystik), */
620xA1, 0x01, /* Collection (Application), */
630xA1, 0x02, /* Collection (Logical), */
640x95, 0x01, /* Report Count (1), */
650x75, 0x0A, /* Report Size (10), */
660x14, /* Logical Minimum (0), */
670x26, 0xFF, 0x03, /* Logical Maximum (1023), */
680x34, /* Physical Minimum (0), */
690x46, 0xFF, 0x03, /* Physical Maximum (1023), */
700x09, 0x30, /* Usage (X), */
710x81, 0x02, /* Input (Variable), */
720x95, 0x0C, /* Report Count (12), */
730x75, 0x01, /* Report Size (1), */
740x25, 0x01, /* Logical Maximum (1), */
750x45, 0x01, /* Physical Maximum (1), */
760x05, 0x09, /* Usage (Buttons), */
770x19, 0x01, /* Usage Minimum (1), */
780x29, 0x0c, /* Usage Maximum (12), */
790x81, 0x02, /* Input (Variable), */
800x95, 0x02, /* Report Count (2), */
810x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */
820x09, 0x01, /* Usage (?: 1), */
830x81, 0x02, /* Input (Variable), */
840x05, 0x01, /* Usage Page (Desktop), */
850x26, 0xFF, 0x00, /* Logical Maximum (255), */
860x46, 0xFF, 0x00, /* Physical Maximum (255), */
870x95, 0x01, /* Report Count (1), */
880x75, 0x08, /* Report Size (8), */
890x81, 0x02, /* Input (Variable), */
900x25, 0x07, /* Logical Maximum (7), */
910x46, 0x3B, 0x01, /* Physical Maximum (315), */
920x75, 0x04, /* Report Size (4), */
930x65, 0x14, /* Unit (Degrees), */
940x09, 0x39, /* Usage (Hat Switch), */
950x81, 0x42, /* Input (Variable, Null State), */
960x75, 0x01, /* Report Size (1), */
970x95, 0x04, /* Report Count (4), */
980x65, 0x00, /* Unit (none), */
990x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */
1000x09, 0x01, /* Usage (?: 1), */
1010x25, 0x01, /* Logical Maximum (1), */
1020x45, 0x01, /* Physical Maximum (1), */
1030x81, 0x02, /* Input (Variable), */
1040x05, 0x01, /* Usage Page (Desktop), */
1050x95, 0x01, /* Report Count (1), */
1060x75, 0x08, /* Report Size (8), */
1070x26, 0xFF, 0x00, /* Logical Maximum (255), */
1080x46, 0xFF, 0x00, /* Physical Maximum (255), */
1090x09, 0x31, /* Usage (Y), */
1100x81, 0x02, /* Input (Variable), */
1110x09, 0x35, /* Usage (Rz), */
1120x81, 0x02, /* Input (Variable), */
1130xC0, /* End Collection, */
1140xA1, 0x02, /* Collection (Logical), */
1150x26, 0xFF, 0x00, /* Logical Maximum (255), */
1160x46, 0xFF, 0x00, /* Physical Maximum (255), */
1170x95, 0x07, /* Report Count (7), */
1180x75, 0x08, /* Report Size (8), */
1190x09, 0x03, /* Usage (?: 3), */
1200x91, 0x02, /* Output (Variable), */
1210xC0, /* End Collection, */
1220xC0 /* End Collection */
123};
124
54static __u8 dfp_rdesc_fixed[] = { 125static __u8 dfp_rdesc_fixed[] = {
550x05, 0x01, /* Usage Page (Desktop), */ 1260x05, 0x01, /* Usage Page (Desktop), */
560x09, 0x04, /* Usage (Joystik), */ 1270x09, 0x04, /* Usage (Joystik), */
@@ -99,6 +170,51 @@ static __u8 dfp_rdesc_fixed[] = {
990xC0 /* End Collection */ 1700xC0 /* End Collection */
100}; 171};
101 172
173static __u8 momo_rdesc_fixed[] = {
1740x05, 0x01, /* Usage Page (Desktop), */
1750x09, 0x04, /* Usage (Joystik), */
1760xA1, 0x01, /* Collection (Application), */
1770xA1, 0x02, /* Collection (Logical), */
1780x95, 0x01, /* Report Count (1), */
1790x75, 0x0A, /* Report Size (10), */
1800x15, 0x00, /* Logical Minimum (0), */
1810x26, 0xFF, 0x03, /* Logical Maximum (1023), */
1820x35, 0x00, /* Physical Minimum (0), */
1830x46, 0xFF, 0x03, /* Physical Maximum (1023), */
1840x09, 0x30, /* Usage (X), */
1850x81, 0x02, /* Input (Variable), */
1860x95, 0x08, /* Report Count (8), */
1870x75, 0x01, /* Report Size (1), */
1880x25, 0x01, /* Logical Maximum (1), */
1890x45, 0x01, /* Physical Maximum (1), */
1900x05, 0x09, /* Usage Page (Button), */
1910x19, 0x01, /* Usage Minimum (01h), */
1920x29, 0x08, /* Usage Maximum (08h), */
1930x81, 0x02, /* Input (Variable), */
1940x06, 0x00, 0xFF, /* Usage Page (FF00h), */
1950x75, 0x0E, /* Report Size (14), */
1960x95, 0x01, /* Report Count (1), */
1970x26, 0xFF, 0x00, /* Logical Maximum (255), */
1980x46, 0xFF, 0x00, /* Physical Maximum (255), */
1990x09, 0x00, /* Usage (00h), */
2000x81, 0x02, /* Input (Variable), */
2010x05, 0x01, /* Usage Page (Desktop), */
2020x75, 0x08, /* Report Size (8), */
2030x09, 0x31, /* Usage (Y), */
2040x81, 0x02, /* Input (Variable), */
2050x09, 0x32, /* Usage (Z), */
2060x81, 0x02, /* Input (Variable), */
2070x06, 0x00, 0xFF, /* Usage Page (FF00h), */
2080x09, 0x01, /* Usage (01h), */
2090x81, 0x02, /* Input (Variable), */
2100xC0, /* End Collection, */
2110xA1, 0x02, /* Collection (Logical), */
2120x09, 0x02, /* Usage (02h), */
2130x95, 0x07, /* Report Count (7), */
2140x91, 0x02, /* Output (Variable), */
2150xC0, /* End Collection, */
2160xC0 /* 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};
677module_hid_driver(lg_driver);
506 678
507static int __init lg_init(void)
508{
509 return hid_register_driver(&lg_driver);
510}
511
512static void __exit lg_exit(void)
513{
514 hid_unregister_driver(&lg_driver);
515}
516
517module_init(lg_init);
518module_exit(lg_exit);
519MODULE_LICENSE("GPL"); 679MODULE_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
53static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); 48static 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};
572module_hid_driver(magicmouse_driver);
572 573
573static 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
584static void __exit magicmouse_exit(void)
585{
586 hid_unregister_driver(&magicmouse_driver);
587}
588
589module_init(magicmouse_init);
590module_exit(magicmouse_exit);
591MODULE_LICENSE("GPL"); 574MODULE_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};
224module_hid_driver(ms_driver);
224 225
225static int __init ms_init(void)
226{
227 return hid_register_driver(&ms_driver);
228}
229
230static void __exit ms_exit(void)
231{
232 hid_unregister_driver(&ms_driver);
233}
234
235module_init(ms_init);
236module_exit(ms_exit);
237MODULE_LICENSE("GPL"); 226MODULE_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};
66module_hid_driver(mr_driver);
66 67
67static int __init mr_init(void)
68{
69 return hid_register_driver(&mr_driver);
70}
71
72static void __exit mr_exit(void)
73{
74 hid_unregister_driver(&mr_driver);
75}
76
77module_init(mr_init);
78module_exit(mr_exit);
79MODULE_LICENSE("GPL"); 68MODULE_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
58struct mt_slot { 59struct mt_slot {
59 __s32 x, y, cx, cy, p, w, h; 60 __s32 x, y, cx, cy, p, w, h;
@@ -83,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
145static struct mt_class mt_classes[] = { 152static 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 */
524static void mt_complete_slot(struct mt_device *td, struct input_dev *input) 551static 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)
578static int mt_event(struct hid_device *hid, struct hid_field *field, 609static 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
619static 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 */ 689static 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
661static void mt_set_input_mode(struct hid_device *hdev) 726static 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)
719static void mt_post_parse(struct mt_device *td) 785static 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
729static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) 799static 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 1278module_hid_driver(mt_driver);
1202static int __init mt_init(void)
1203{
1204 return hid_register_driver(&mt_driver);
1205}
1206
1207static void __exit mt_exit(void)
1208{
1209 hid_unregister_driver(&mt_driver);
1210}
1211
1212module_init(mt_init);
1213module_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
861static 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
861static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) 894static 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};
1029module_hid_driver(ntrig_driver);
1029 1030
1030static int __init ntrig_init(void)
1031{
1032 return hid_register_driver(&ntrig_driver);
1033}
1034
1035static void __exit ntrig_exit(void)
1036{
1037 hid_unregister_driver(&ntrig_driver);
1038}
1039
1040module_init(ntrig_init);
1041module_exit(ntrig_exit);
1042MODULE_LICENSE("GPL"); 1031MODULE_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};
53module_hid_driver(ortek_driver);
53 54
54static int __init ortek_init(void)
55{
56 return hid_register_driver(&ortek_driver);
57}
58
59static void __exit ortek_exit(void)
60{
61 hid_unregister_driver(&ortek_driver);
62}
63
64module_init(ortek_init);
65module_exit(ortek_exit);
66MODULE_LICENSE("GPL"); 55MODULE_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};
106module_hid_driver(pl_driver);
106 107
107static int __init pl_init(void)
108{
109 return hid_register_driver(&pl_driver);
110}
111
112static void __exit pl_exit(void)
113{
114 hid_unregister_driver(&pl_driver);
115}
116
117module_init(pl_init);
118module_exit(pl_exit);
119MODULE_LICENSE("GPL"); 108MODULE_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};
675module_hid_driver(picolcd_driver);
675 676
676static int __init picolcd_init(void)
677{
678 return hid_register_driver(&picolcd_driver);
679}
680
681static void __exit picolcd_exit(void)
682{
683 hid_unregister_driver(&picolcd_driver);
684}
685
686module_init(picolcd_init);
687module_exit(picolcd_exit);
688MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver"); 677MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver");
689MODULE_LICENSE("GPL v2"); 678MODULE_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
52struct plff_device { 54struct 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};
212MODULE_DEVICE_TABLE(hid, pl_devices); 221MODULE_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};
228module_hid_driver(pl_driver);
219 229
220static int __init pl_init(void)
221{
222 return hid_register_driver(&pl_driver);
223}
224
225static void __exit pl_exit(void)
226{
227 hid_unregister_driver(&pl_driver);
228}
229
230module_init(pl_init);
231module_exit(pl_exit);
232MODULE_LICENSE("GPL"); 230MODULE_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};
78module_hid_driver(px_driver);
78 79
79static int __init px_init(void)
80{
81 return hid_register_driver(&px_driver);
82}
83
84static void __exit px_exit(void)
85{
86 hid_unregister_driver(&px_driver);
87}
88
89module_init(px_init);
90module_exit(px_exit);
91MODULE_AUTHOR("Terry Lambert <tlambert@google.com>"); 80MODULE_AUTHOR("Terry Lambert <tlambert@google.com>");
92MODULE_LICENSE("GPL"); 81MODULE_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};
892module_hid_driver(pk_driver);
892 893
893static 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
904static void pk_exit(void)
905{
906 hid_unregister_driver(&pk_driver);
907}
908
909module_init(pk_init);
910module_exit(pk_exit);
911MODULE_LICENSE("GPL"); 894MODULE_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};
201module_hid_driver(ps3remote_driver);
201 202
202static int __init ps3remote_init(void)
203{
204 return hid_register_driver(&ps3remote_driver);
205}
206
207static void __exit ps3remote_exit(void)
208{
209 hid_unregister_driver(&ps3remote_driver);
210}
211
212module_init(ps3remote_init);
213module_exit(ps3remote_exit);
214MODULE_LICENSE("GPL"); 203MODULE_LICENSE("GPL");
215MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>"); 204MODULE_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 211module_hid_driver(lua_driver);
212static int __init lua_init(void)
213{
214 return hid_register_driver(&lua_driver);
215}
216
217static void __exit lua_exit(void)
218{
219 hid_unregister_driver(&lua_driver);
220}
221
222module_init(lua_init);
223module_exit(lua_exit);
224 212
225MODULE_AUTHOR("Stefan Achatz"); 213MODULE_AUTHOR("Stefan Achatz");
226MODULE_DESCRIPTION("USB Roccat Lua driver"); 214MODULE_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};
57module_hid_driver(saitek_driver);
57 58
58static int __init saitek_init(void)
59{
60 return hid_register_driver(&saitek_driver);
61}
62
63static void __exit saitek_exit(void)
64{
65 hid_unregister_driver(&saitek_driver);
66}
67
68module_init(saitek_init);
69module_exit(saitek_exit);
70MODULE_LICENSE("GPL"); 59MODULE_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};
199module_hid_driver(samsung_driver);
199 200
200static int __init samsung_init(void)
201{
202 return hid_register_driver(&samsung_driver);
203}
204
205static void __exit samsung_exit(void)
206{
207 hid_unregister_driver(&samsung_driver);
208}
209
210module_init(samsung_init);
211module_exit(samsung_exit);
212MODULE_LICENSE("GPL"); 201MODULE_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
607static const struct hid_device_id sensor_hub_devices[] = { 607static 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};
611MODULE_DEVICE_TABLE(hid, sensor_hub_devices); 612MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
612 613
613static 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
618static struct hid_driver sensor_hub_driver = { 614static 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 626module_hid_driver(sensor_hub_driver);
631static int __init sensor_hub_init(void)
632{
633 return hid_register_driver(&sensor_hub_driver);
634}
635
636static void __exit sensor_hub_exit(void)
637{
638 hid_unregister_driver(&sensor_hub_driver);
639}
640
641module_init(sensor_hub_init);
642module_exit(sensor_hub_exit);
643 627
644MODULE_DESCRIPTION("HID Sensor Hub driver"); 628MODULE_DESCRIPTION("HID Sensor Hub driver");
645MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); 629MODULE_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};
180module_hid_driver(sjoy_driver);
180 181
181static int __init sjoy_init(void)
182{
183 return hid_register_driver(&sjoy_driver);
184}
185
186static void __exit sjoy_exit(void)
187{
188 hid_unregister_driver(&sjoy_driver);
189}
190
191module_init(sjoy_init);
192module_exit(sjoy_exit);
193MODULE_LICENSE("GPL"); 182MODULE_LICENSE("GPL");
194MODULE_AUTHOR("Jussi Kivilinna"); 183MODULE_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
36static 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
36struct sony_sc { 58struct 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};
222MODULE_DEVICE_TABLE(hid, sony_devices); 262MODULE_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};
272module_hid_driver(sony_driver);
232 273
233static int __init sony_init(void)
234{
235 return hid_register_driver(&sony_driver);
236}
237
238static void __exit sony_exit(void)
239{
240 hid_unregister_driver(&sony_driver);
241}
242
243module_init(sony_init);
244module_exit(sony_exit);
245MODULE_LICENSE("GPL"); 274MODULE_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};
76module_hid_driver(speedlink_driver);
76 77
77static int __init speedlink_init(void)
78{
79 return hid_register_driver(&speedlink_driver);
80}
81
82static void __exit speedlink_exit(void)
83{
84 hid_unregister_driver(&speedlink_driver);
85}
86
87module_init(speedlink_init);
88module_exit(speedlink_exit);
89MODULE_LICENSE("GPL"); 78MODULE_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
24struct 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
38static __u8 steelseries_srws1_rdesc_fixed[] = {
390x05, 0x01, /* Usage Page (Desktop) */
400x09, 0x08, /* Usage (MultiAxis), Changed */
410xA1, 0x01, /* Collection (Application), */
420xA1, 0x02, /* Collection (Logical), */
430x95, 0x01, /* Report Count (1), */
440x05, 0x01, /* Changed Usage Page (Desktop), */
450x09, 0x30, /* Changed Usage (X), */
460x16, 0xF8, 0xF8, /* Logical Minimum (-1800), */
470x26, 0x08, 0x07, /* Logical Maximum (1800), */
480x65, 0x14, /* Unit (Degrees), */
490x55, 0x0F, /* Unit Exponent (15), */
500x75, 0x10, /* Report Size (16), */
510x81, 0x02, /* Input (Variable), */
520x09, 0x31, /* Changed Usage (Y), */
530x15, 0x00, /* Logical Minimum (0), */
540x26, 0xFF, 0x03, /* Logical Maximum (1023), */
550x75, 0x0C, /* Report Size (12), */
560x81, 0x02, /* Input (Variable), */
570x09, 0x32, /* Changed Usage (Z), */
580x15, 0x00, /* Logical Minimum (0), */
590x26, 0xFF, 0x03, /* Logical Maximum (1023), */
600x75, 0x0C, /* Report Size (12), */
610x81, 0x02, /* Input (Variable), */
620x05, 0x01, /* Usage Page (Desktop), */
630x09, 0x39, /* Usage (Hat Switch), */
640x25, 0x07, /* Logical Maximum (7), */
650x35, 0x00, /* Physical Minimum (0), */
660x46, 0x3B, 0x01, /* Physical Maximum (315), */
670x65, 0x14, /* Unit (Degrees), */
680x75, 0x04, /* Report Size (4), */
690x95, 0x01, /* Report Count (1), */
700x81, 0x02, /* Input (Variable), */
710x25, 0x01, /* Logical Maximum (1), */
720x45, 0x01, /* Physical Maximum (1), */
730x65, 0x00, /* Unit, */
740x75, 0x01, /* Report Size (1), */
750x95, 0x03, /* Report Count (3), */
760x81, 0x01, /* Input (Constant), */
770x05, 0x09, /* Usage Page (Button), */
780x19, 0x01, /* Usage Minimum (01h), */
790x29, 0x11, /* Usage Maximum (11h), */
800x95, 0x11, /* Report Count (17), */
810x81, 0x02, /* Input (Variable), */
82 /* ---- Dial patch starts here ---- */
830x05, 0x01, /* Usage Page (Desktop), */
840x09, 0x33, /* Usage (RX), */
850x75, 0x04, /* Report Size (4), */
860x95, 0x02, /* Report Count (2), */
870x15, 0x00, /* Logical Minimum (0), */
880x25, 0x0b, /* Logical Maximum (b), */
890x81, 0x02, /* Input (Variable), */
900x09, 0x35, /* Usage (RZ), */
910x75, 0x04, /* Report Size (4), */
920x95, 0x01, /* Report Count (1), */
930x25, 0x03, /* Logical Maximum (3), */
940x81, 0x02, /* Input (Variable), */
95 /* ---- Dial patch ends here ---- */
960x06, 0x00, 0xFF, /* Usage Page (FF00h), */
970x09, 0x01, /* Usage (01h), */
980x75, 0x04, /* Changed Report Size (4), */
990x95, 0x0D, /* Changed Report Count (13), */
1000x81, 0x02, /* Input (Variable), */
1010xC0, /* End Collection, */
1020xA1, 0x02, /* Collection (Logical), */
1030x09, 0x02, /* Usage (02h), */
1040x75, 0x08, /* Report Size (8), */
1050x95, 0x10, /* Report Count (16), */
1060x91, 0x02, /* Output (Variable), */
1070xC0, /* End Collection, */
1080xC0 /* End Collection */
109};
110
111#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
112static 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
140static 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
160static 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
176static 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
205static 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
228static 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);
307err_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 }
320out:
321 return 0;
322err_free:
323 kfree(drv_data);
324 return ret;
325}
326
327static 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
353static __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
365static const struct hid_device_id steelseries_srws1_devices[] = {
366 { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
367 { }
368};
369MODULE_DEVICE_TABLE(hid, steelseries_srws1_devices);
370
371static 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
381static int __init steelseries_srws1_init(void)
382{
383 return hid_register_driver(&steelseries_srws1_driver);
384}
385
386static void __exit steelseries_srws1_exit(void)
387{
388 hid_unregister_driver(&steelseries_srws1_driver);
389}
390
391module_init(steelseries_srws1_init);
392module_exit(steelseries_srws1_exit);
393MODULE_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};
66module_hid_driver(sp_driver);
66 67
67static int __init sp_init(void)
68{
69 return hid_register_driver(&sp_driver);
70}
71
72static void __exit sp_exit(void)
73{
74 hid_unregister_driver(&sp_driver);
75}
76
77module_init(sp_init);
78module_exit(sp_exit);
79MODULE_LICENSE("GPL"); 68MODULE_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 */
34struct 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
43static 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
58static 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
79static 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
89static 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
96static 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
104static 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
125static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR, blink1_show_rgb, blink1_store_rgb);
126
127static 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
135static 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
156static DEVICE_ATTR(fade, S_IRUGO | S_IWUSR,
157 blink1_show_fade, blink1_store_fade);
158
159static 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
167static 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
186static DEVICE_ATTR(play, S_IRUGO | S_IWUSR,
187 blink1_show_play, blink1_store_play);
188
189static 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
198static 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
237remove_led:
238 led_classdev_unregister(led);
239stop:
240 hid_hw_stop(hdev);
241error:
242 return ret;
243}
244
245static 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
255static const struct hid_device_id thingm_table[] = {
256 { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) },
257 { }
258};
259MODULE_DEVICE_TABLE(hid, thingm_table);
260
261static struct hid_driver thingm_driver = {
262 .name = "thingm",
263 .probe = thingm_probe,
264 .remove = thingm_remove,
265 .id_table = thingm_table,
266};
267
268module_hid_driver(thingm_driver);
269
270MODULE_LICENSE("GPL");
271MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>");
272MODULE_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};
76module_hid_driver(tivo_driver);
76 77
77static int __init tivo_init(void)
78{
79 return hid_register_driver(&tivo_driver);
80}
81
82static void __exit tivo_exit(void)
83{
84 hid_unregister_driver(&tivo_driver);
85}
86
87module_init(tivo_init);
88module_exit(tivo_exit);
89MODULE_LICENSE("GPL"); 78MODULE_LICENSE("GPL");
90MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>"); 79MODULE_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};
264module_hid_driver(tm_driver);
264 265
265static int __init tm_init(void)
266{
267 return hid_register_driver(&tm_driver);
268}
269
270static void __exit tm_exit(void)
271{
272 hid_unregister_driver(&tm_driver);
273}
274
275module_init(tm_init);
276module_exit(tm_exit);
277MODULE_LICENSE("GPL"); 266MODULE_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};
79module_hid_driver(ts_driver);
79 80
80static int __init ts_init(void)
81{
82 return hid_register_driver(&ts_driver);
83}
84
85static void __exit ts_exit(void)
86{
87 hid_unregister_driver(&ts_driver);
88}
89
90module_init(ts_init);
91module_exit(ts_exit);
92MODULE_LICENSE("GPL"); 81MODULE_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};
134module_hid_driver(twinhan_driver);
134 135
135static int __init twinhan_init(void)
136{
137 return hid_register_driver(&twinhan_driver);
138}
139
140static void __exit twinhan_exit(void)
141{
142 hid_unregister_driver(&twinhan_driver);
143}
144
145module_init(twinhan_init);
146module_exit(twinhan_exit);
147MODULE_LICENSE("GPL"); 136MODULE_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};
653module_hid_driver(uclogic_driver);
653 654
654static int __init uclogic_init(void)
655{
656 return hid_register_driver(&uclogic_driver);
657}
658
659static void __exit uclogic_exit(void)
660{
661 hid_unregister_driver(&uclogic_driver);
662}
663
664module_init(uclogic_init);
665module_exit(uclogic_exit);
666MODULE_LICENSE("GPL"); 655MODULE_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};
956module_hid_driver(wacom_driver);
956 957
957static 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
967static void __exit wacom_exit(void)
968{
969 hid_unregister_driver(&wacom_driver);
970}
971
972module_init(wacom_init);
973module_exit(wacom_exit);
974MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); 958MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL");
975MODULE_LICENSE("GPL"); 959MODULE_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};
782module_hid_driver(waltop_driver);
782 783
783static int __init waltop_init(void)
784{
785 return hid_register_driver(&waltop_driver);
786}
787
788static void __exit waltop_exit(void)
789{
790 hid_unregister_driver(&waltop_driver);
791}
792
793module_init(waltop_init);
794module_exit(waltop_exit);
795MODULE_LICENSE("GPL"); 784MODULE_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};
1297module_hid_driver(wiimote_hid_driver);
1297 1298
1298static 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
1309static void __exit wiimote_exit(void)
1310{
1311 hid_unregister_driver(&wiimote_hid_driver);
1312}
1313
1314module_init(wiimote_init);
1315module_exit(wiimote_exit);
1316MODULE_LICENSE("GPL"); 1299MODULE_LICENSE("GPL");
1317MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>"); 1300MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
1318MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver"); 1301MODULE_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};
155module_hid_driver(zp_driver);
155 156
156static int __init zp_init(void)
157{
158 return hid_register_driver(&zp_driver);
159}
160
161static void __exit zp_exit(void)
162{
163 hid_unregister_driver(&zp_driver);
164}
165
166module_init(zp_init);
167module_exit(zp_exit);
168MODULE_LICENSE("GPL"); 157MODULE_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};
222module_hid_driver(zc_driver);
222 223
223static int __init zc_init(void)
224{
225 return hid_register_driver(&zc_driver);
226}
227
228static void __exit zc_exit(void)
229{
230 hid_unregister_driver(&zc_driver);
231}
232
233module_init(zc_init);
234module_exit(zc_exit);
235MODULE_LICENSE("GPL"); 224MODULE_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");
584out: 585out:
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
144static int __i2c_hid_command(struct i2c_client *client, 147static 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
828static 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
877static const struct acpi_device_id i2c_hid_acpi_match[] = {
878 {"ACPI0C50", 0 },
879 {"PNP0C50", 0 },
880 { },
881};
882MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
883#else
884static 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
824static int i2c_hid_probe(struct i2c_client *client, 891static 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. */
283struct 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
298static 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
358static 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
279static int uhid_dev_create(struct uhid_device *uhid, 368static 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: