From 4d02c58eb1f19433cb852b2bde41c44849691614 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Dec 2012 15:26:55 -0700 Subject: HID: introduce helper for hid_driver boilerplate Introduce the module_hid_driver macro which is a convenience macro for HID driver modules similar to module_usb_driver. It is intended to be used by drivers with init/exit sections that do nothing but register/unregister the HID driver. Signed-off-by: H Hartley Sweeten Signed-off-by: Jiri Kosina --- include/linux/hid.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/hid.h b/include/linux/hid.h index 7330a0fef0c0..d6c71a674310 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -700,6 +700,18 @@ extern int __must_check __hid_register_driver(struct hid_driver *, extern void hid_unregister_driver(struct hid_driver *); +/** + * module_hid_driver() - Helper macro for registering a HID driver + * @__hid_driver: hid_driver struct + * + * Helper macro for HID drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only + * use this macro once, and calling it replaces module_init() and module_exit() + */ +#define module_hid_driver(__hid_driver) \ + module_driver(__hid_driver, hid_register_driver, \ + hid_unregister_driver) + extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *hid, unsigned int force); -- cgit v1.2.3 From d463f4719a2fa883bc0bb1fb67e6fea2307aa6df Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Dec 2012 15:27:33 -0700 Subject: HID: hid.h: remove unused hid_generic_{init,exit} prototypes These functions are not defined. Remove the extern declarations. Signed-off-by: H Hartley Sweeten Signed-off-by: Jiri Kosina --- include/linux/hid.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/hid.h b/include/linux/hid.h index d6c71a674310..828726c70503 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -884,9 +884,6 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); -extern int hid_generic_init(void); -extern void hid_generic_exit(void); - /* HID quirks API */ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); int usbhid_quirks_init(char **quirks_param); -- cgit v1.2.3 From f425458eafd51b6b5ab64f407922e1198c567cb2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 17 Dec 2012 15:28:26 -0700 Subject: HID: Use module_hid_driver macro Use the new module_hid_driver macro in all HID drivers that have a simple register/unregister init/exit. This also converts the hid drivers that test for a failure of hid_register_driver() and report the failure. Using module_hid_driver in those drivers removes the failure message. Signed-off-by: H Hartley Sweeten Signed-off-by: Jiri Kosina --- drivers/hid/hid-a4tech.c | 13 +------------ drivers/hid/hid-apple.c | 19 +------------------ drivers/hid/hid-aureal.c | 13 +------------ drivers/hid/hid-axff.c | 14 +------------- drivers/hid/hid-belkin.c | 13 +------------ drivers/hid/hid-cherry.c | 13 +------------ drivers/hid/hid-chicony.c | 13 +------------ drivers/hid/hid-cypress.c | 13 +------------ drivers/hid/hid-dr.c | 13 +------------ drivers/hid/hid-elecom.c | 13 +------------ drivers/hid/hid-emsff.c | 13 +------------ drivers/hid/hid-ezkey.c | 13 +------------ drivers/hid/hid-gaff.c | 13 +------------ drivers/hid/hid-generic.c | 14 +------------- drivers/hid/hid-gyration.c | 13 +------------ drivers/hid/hid-holtek-kbd.c | 13 +------------ drivers/hid/hid-holtekff.c | 15 +-------------- drivers/hid/hid-icade.c | 19 +------------------ drivers/hid/hid-kensington.c | 13 +------------ drivers/hid/hid-keytouch.c | 13 +------------ drivers/hid/hid-kye.c | 13 +------------ drivers/hid/hid-lcpower.c | 13 +------------ drivers/hid/hid-lenovo-tpkbd.c | 14 +------------- drivers/hid/hid-lg.c | 13 +------------ drivers/hid/hid-magicmouse.c | 19 +------------------ drivers/hid/hid-microsoft.c | 13 +------------ drivers/hid/hid-monterey.c | 13 +------------ drivers/hid/hid-multitouch.c | 14 +------------- drivers/hid/hid-ntrig.c | 13 +------------ drivers/hid/hid-ortek.c | 13 +------------ drivers/hid/hid-petalynx.c | 13 +------------ drivers/hid/hid-picolcd_core.c | 13 +------------ drivers/hid/hid-pl.c | 13 +------------ drivers/hid/hid-primax.c | 13 +------------ drivers/hid/hid-prodikeys.c | 19 +------------------ drivers/hid/hid-ps3remote.c | 13 +------------ drivers/hid/hid-roccat-lua.c | 14 +------------- drivers/hid/hid-saitek.c | 13 +------------ drivers/hid/hid-samsung.c | 13 +------------ drivers/hid/hid-sensor-hub.c | 14 +------------- drivers/hid/hid-sjoy.c | 13 +------------ drivers/hid/hid-sony.c | 13 +------------ drivers/hid/hid-speedlink.c | 13 +------------ drivers/hid/hid-sunplus.c | 13 +------------ drivers/hid/hid-tivo.c | 13 +------------ drivers/hid/hid-tmff.c | 13 +------------ drivers/hid/hid-topseed.c | 13 +------------ drivers/hid/hid-twinhan.c | 13 +------------ drivers/hid/hid-uclogic.c | 13 +------------ drivers/hid/hid-wacom.c | 18 +----------------- drivers/hid/hid-waltop.c | 13 +------------ drivers/hid/hid-wiimote-core.c | 19 +------------------ drivers/hid/hid-zpff.c | 13 +------------ drivers/hid/hid-zydacron.c | 13 +------------ 54 files changed, 54 insertions(+), 691 deletions(-) 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 = { .probe = a4_probe, .remove = a4_remove, }; +module_hid_driver(a4_driver); -static int __init a4_init(void) -{ - return hid_register_driver(&a4_driver); -} - -static void __exit a4_exit(void) -{ - hid_unregister_driver(&a4_driver); -} - -module_init(a4_init); -module_exit(a4_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index d0f7662aacca..320a958d4139 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -555,23 +555,6 @@ static struct hid_driver apple_driver = { .input_mapping = apple_input_mapping, .input_mapped = apple_input_mapped, }; +module_hid_driver(apple_driver); -static int __init apple_init(void) -{ - int ret; - - ret = hid_register_driver(&apple_driver); - if (ret) - pr_err("can't register apple driver\n"); - - return ret; -} - -static void __exit apple_exit(void) -{ - hid_unregister_driver(&apple_driver); -} - -module_init(apple_init); -module_exit(apple_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-aureal.c b/drivers/hid/hid-aureal.c index 7968187ddf7b..340ba9d394a0 100644 --- a/drivers/hid/hid-aureal.c +++ b/drivers/hid/hid-aureal.c @@ -37,17 +37,6 @@ static struct hid_driver aureal_driver = { .id_table = aureal_devices, .report_fixup = aureal_report_fixup, }; +module_hid_driver(aureal_driver); -static int __init aureal_init(void) -{ - return hid_register_driver(&aureal_driver); -} - -static void __exit aureal_exit(void) -{ - hid_unregister_driver(&aureal_driver); -} - -module_init(aureal_init); -module_exit(aureal_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index 5be858dd9a15..62f0cee032ba 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c @@ -192,19 +192,7 @@ static struct hid_driver ax_driver = { .probe = ax_probe, .remove = ax_remove, }; - -static int __init ax_init(void) -{ - return hid_register_driver(&ax_driver); -} - -static void __exit ax_exit(void) -{ - hid_unregister_driver(&ax_driver); -} - -module_init(ax_init); -module_exit(ax_exit); +module_hid_driver(ax_driver); MODULE_AUTHOR("Sergei Kolzun"); MODULE_DESCRIPTION("Force feedback support for ACRUX game controllers"); diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c index a1a5a12c3a6b..cc4cf138bef5 100644 --- a/drivers/hid/hid-belkin.c +++ b/drivers/hid/hid-belkin.c @@ -86,17 +86,6 @@ static struct hid_driver belkin_driver = { .input_mapping = belkin_input_mapping, .probe = belkin_probe, }; +module_hid_driver(belkin_driver); -static int __init belkin_init(void) -{ - return hid_register_driver(&belkin_driver); -} - -static void __exit belkin_exit(void) -{ - hid_unregister_driver(&belkin_driver); -} - -module_init(belkin_init); -module_exit(belkin_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index af034d3d9256..1bdcccc54a1d 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c @@ -69,17 +69,6 @@ static struct hid_driver ch_driver = { .report_fixup = ch_report_fixup, .input_mapping = ch_input_mapping, }; +module_hid_driver(ch_driver); -static int __init ch_init(void) -{ - return hid_register_driver(&ch_driver); -} - -static void __exit ch_exit(void) -{ - hid_unregister_driver(&ch_driver); -} - -module_init(ch_init); -module_exit(ch_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index a2abb8e15727..b613d5a79684 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -70,17 +70,6 @@ static struct hid_driver ch_driver = { .id_table = ch_devices, .input_mapping = ch_input_mapping, }; +module_hid_driver(ch_driver); -static int __init ch_init(void) -{ - return hid_register_driver(&ch_driver); -} - -static void __exit ch_exit(void) -{ - hid_unregister_driver(&ch_driver); -} - -module_init(ch_init); -module_exit(ch_exit); MODULE_LICENSE("GPL"); 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 = { .event = cp_event, .probe = cp_probe, }; +module_hid_driver(cp_driver); -static int __init cp_init(void) -{ - return hid_register_driver(&cp_driver); -} - -static void __exit cp_exit(void) -{ - hid_unregister_driver(&cp_driver); -} - -module_init(cp_init); -module_exit(cp_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index e832f44ae383..0fe8f65ef01a 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c @@ -297,17 +297,6 @@ static struct hid_driver dr_driver = { .report_fixup = dr_report_fixup, .probe = dr_probe, }; +module_hid_driver(dr_driver); -static int __init dr_init(void) -{ - return hid_register_driver(&dr_driver); -} - -static void __exit dr_exit(void) -{ - hid_unregister_driver(&dr_driver); -} - -module_init(dr_init); -module_exit(dr_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index 79d0c61e7214..d0bd13b62dc2 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c @@ -41,17 +41,6 @@ static struct hid_driver elecom_driver = { .id_table = elecom_devices, .report_fixup = elecom_report_fixup }; +module_hid_driver(elecom_driver); -static int __init elecom_init(void) -{ - return hid_register_driver(&elecom_driver); -} - -static void __exit elecom_exit(void) -{ - hid_unregister_driver(&elecom_driver); -} - -module_init(elecom_init); -module_exit(elecom_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 2630d483d262..2e093ab99b43 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c @@ -150,18 +150,7 @@ static struct hid_driver ems_driver = { .id_table = ems_devices, .probe = ems_probe, }; +module_hid_driver(ems_driver); -static int ems_init(void) -{ - return hid_register_driver(&ems_driver); -} - -static void ems_exit(void) -{ - hid_unregister_driver(&ems_driver); -} - -module_init(ems_init); -module_exit(ems_exit); MODULE_LICENSE("GPL"); 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 = { .input_mapping = ez_input_mapping, .event = ez_event, }; +module_hid_driver(ez_driver); -static int __init ez_init(void) -{ - return hid_register_driver(&ez_driver); -} - -static void __exit ez_exit(void) -{ - hid_unregister_driver(&ez_driver); -} - -module_init(ez_init); -module_exit(ez_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index f1e1bcf67427..04d2e6aca778 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c @@ -176,17 +176,6 @@ static struct hid_driver ga_driver = { .id_table = ga_devices, .probe = ga_probe, }; +module_hid_driver(ga_driver); -static int __init ga_init(void) -{ - return hid_register_driver(&ga_driver); -} - -static void __exit ga_exit(void) -{ - hid_unregister_driver(&ga_driver); -} - -module_init(ga_init); -module_exit(ga_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c index a8b3148e03a2..e288a4a06fe8 100644 --- a/drivers/hid/hid-generic.c +++ b/drivers/hid/hid-generic.c @@ -34,19 +34,7 @@ static struct hid_driver hid_generic = { .name = "hid-generic", .id_table = hid_table, }; - -static int __init hid_init(void) -{ - return hid_register_driver(&hid_generic); -} - -static void __exit hid_exit(void) -{ - hid_unregister_driver(&hid_generic); -} - -module_init(hid_init); -module_exit(hid_exit); +module_hid_driver(hid_generic); MODULE_AUTHOR("Henrik Rydberg"); MODULE_DESCRIPTION("HID generic driver"); diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c index 4442c30ef531..288d61c9748e 100644 --- a/drivers/hid/hid-gyration.c +++ b/drivers/hid/hid-gyration.c @@ -88,17 +88,6 @@ static struct hid_driver gyration_driver = { .input_mapping = gyration_input_mapping, .event = gyration_event, }; +module_hid_driver(gyration_driver); -static int __init gyration_init(void) -{ - return hid_register_driver(&gyration_driver); -} - -static void __exit gyration_exit(void) -{ - hid_unregister_driver(&gyration_driver); -} - -module_init(gyration_init); -module_exit(gyration_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c index e0a5d1739fc3..6e1a4a4fc0c1 100644 --- a/drivers/hid/hid-holtek-kbd.c +++ b/drivers/hid/hid-holtek-kbd.c @@ -167,17 +167,6 @@ static struct hid_driver holtek_kbd_driver = { .report_fixup = holtek_kbd_report_fixup, .probe = holtek_kbd_probe }; +module_hid_driver(holtek_kbd_driver); -static int __init holtek_kbd_init(void) -{ - return hid_register_driver(&holtek_kbd_driver); -} - -static void __exit holtek_kbd_exit(void) -{ - hid_unregister_driver(&holtek_kbd_driver); -} - -module_exit(holtek_kbd_exit); -module_init(holtek_kbd_init); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index ff295e60059b..f34d1186a3e1 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c @@ -224,17 +224,4 @@ static struct hid_driver holtek_driver = { .id_table = holtek_devices, .probe = holtek_probe, }; - -static int __init holtek_init(void) -{ - return hid_register_driver(&holtek_driver); -} - -static void __exit holtek_exit(void) -{ - hid_unregister_driver(&holtek_driver); -} - -module_init(holtek_init); -module_exit(holtek_exit); - +module_hid_driver(holtek_driver); 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 = { .input_mapped = icade_input_mapped, .input_mapping = icade_input_mapping, }; +module_hid_driver(icade_driver); -static int __init icade_init(void) -{ - int ret; - - ret = hid_register_driver(&icade_driver); - if (ret) - pr_err("can't register icade driver\n"); - - return ret; -} - -static void __exit icade_exit(void) -{ - hid_unregister_driver(&icade_driver); -} - -module_init(icade_init); -module_exit(icade_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bastien Nocera "); MODULE_DESCRIPTION("ION iCade input driver"); 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 = { .id_table = ks_devices, .input_mapping = ks_input_mapping, }; +module_hid_driver(ks_driver); -static int __init ks_init(void) -{ - return hid_register_driver(&ks_driver); -} - -static void __exit ks_exit(void) -{ - hid_unregister_driver(&ks_driver); -} - -module_init(ks_init); -module_exit(ks_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-keytouch.c b/drivers/hid/hid-keytouch.c index 07cd825f6f01..3074671b7d6a 100644 --- a/drivers/hid/hid-keytouch.c +++ b/drivers/hid/hid-keytouch.c @@ -49,18 +49,7 @@ static struct hid_driver keytouch_driver = { .id_table = keytouch_devices, .report_fixup = keytouch_report_fixup, }; +module_hid_driver(keytouch_driver); -static int __init keytouch_init(void) -{ - return hid_register_driver(&keytouch_driver); -} - -static void __exit keytouch_exit(void) -{ - hid_unregister_driver(&keytouch_driver); -} - -module_init(keytouch_init); -module_exit(keytouch_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jiri Kosina"); diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index b4f0d8216fd0..ef72daecfa16 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -419,17 +419,6 @@ static struct hid_driver kye_driver = { .probe = kye_probe, .report_fixup = kye_report_fixup, }; +module_hid_driver(kye_driver); -static int __init kye_init(void) -{ - return hid_register_driver(&kye_driver); -} - -static void __exit kye_exit(void) -{ - hid_unregister_driver(&kye_driver); -} - -module_init(kye_init); -module_exit(kye_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-lcpower.c b/drivers/hid/hid-lcpower.c index 22bc14abdfa3..6424cfdb7737 100644 --- a/drivers/hid/hid-lcpower.c +++ b/drivers/hid/hid-lcpower.c @@ -54,17 +54,6 @@ static struct hid_driver ts_driver = { .id_table = ts_devices, .input_mapping = ts_input_mapping, }; +module_hid_driver(ts_driver); -static int __init ts_init(void) -{ - return hid_register_driver(&ts_driver); -} - -static void __exit ts_exit(void) -{ - hid_unregister_driver(&ts_driver); -} - -module_init(ts_init); -module_exit(ts_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c index cea016e94f43..956c3b135f64 100644 --- a/drivers/hid/hid-lenovo-tpkbd.c +++ b/drivers/hid/hid-lenovo-tpkbd.c @@ -468,18 +468,6 @@ static struct hid_driver tpkbd_driver = { .probe = tpkbd_probe, .remove = tpkbd_remove, }; - -static int __init tpkbd_init(void) -{ - return hid_register_driver(&tpkbd_driver); -} - -static void __exit tpkbd_exit(void) -{ - hid_unregister_driver(&tpkbd_driver); -} - -module_init(tpkbd_init); -module_exit(tpkbd_exit); +module_hid_driver(tpkbd_driver); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a2f8e88b9fa2..e3dc73b612de 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -503,17 +503,6 @@ static struct hid_driver lg_driver = { .probe = lg_probe, .remove = lg_remove, }; +module_hid_driver(lg_driver); -static int __init lg_init(void) -{ - return hid_register_driver(&lg_driver); -} - -static void __exit lg_exit(void) -{ - hid_unregister_driver(&lg_driver); -} - -module_init(lg_init); -module_exit(lg_exit); MODULE_LICENSE("GPL"); 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 = { .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, }; +module_hid_driver(magicmouse_driver); -static int __init magicmouse_init(void) -{ - int ret; - - ret = hid_register_driver(&magicmouse_driver); - if (ret) - pr_err("can't register magicmouse driver\n"); - - return ret; -} - -static void __exit magicmouse_exit(void) -{ - hid_unregister_driver(&magicmouse_driver); -} - -module_init(magicmouse_init); -module_exit(magicmouse_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 6fcd466d0825..29d27f65a118 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -221,17 +221,6 @@ static struct hid_driver ms_driver = { .event = ms_event, .probe = ms_probe, }; +module_hid_driver(ms_driver); -static int __init ms_init(void) -{ - return hid_register_driver(&ms_driver); -} - -static void __exit ms_exit(void) -{ - hid_unregister_driver(&ms_driver); -} - -module_init(ms_init); -module_exit(ms_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c index cd3643e06fa6..9e14c00eb1b6 100644 --- a/drivers/hid/hid-monterey.c +++ b/drivers/hid/hid-monterey.c @@ -63,17 +63,6 @@ static struct hid_driver mr_driver = { .report_fixup = mr_report_fixup, .input_mapping = mr_input_mapping, }; +module_hid_driver(mr_driver); -static int __init mr_init(void) -{ - return hid_register_driver(&mr_driver); -} - -static void __exit mr_exit(void) -{ - hid_unregister_driver(&mr_driver); -} - -module_init(mr_init); -module_exit(mr_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 61543c02ea0b..46d8136daf99 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1198,16 +1198,4 @@ static struct hid_driver mt_driver = { .resume = mt_resume, #endif }; - -static int __init mt_init(void) -{ - return hid_register_driver(&mt_driver); -} - -static void __exit mt_exit(void) -{ - hid_unregister_driver(&mt_driver); -} - -module_init(mt_init); -module_exit(mt_exit); +module_hid_driver(mt_driver); diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 86a969f63292..2ffc0e3844c7 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -1026,17 +1026,6 @@ static struct hid_driver ntrig_driver = { .usage_table = ntrig_grabbed_usages, .event = ntrig_event, }; +module_hid_driver(ntrig_driver); -static int __init ntrig_init(void) -{ - return hid_register_driver(&ntrig_driver); -} - -static void __exit ntrig_exit(void) -{ - hid_unregister_driver(&ntrig_driver); -} - -module_init(ntrig_init); -module_exit(ntrig_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c index 0ffa1d2d64f0..6620f15fec22 100644 --- a/drivers/hid/hid-ortek.c +++ b/drivers/hid/hid-ortek.c @@ -50,17 +50,6 @@ static struct hid_driver ortek_driver = { .id_table = ortek_devices, .report_fixup = ortek_report_fixup }; +module_hid_driver(ortek_driver); -static int __init ortek_init(void) -{ - return hid_register_driver(&ortek_driver); -} - -static void __exit ortek_exit(void) -{ - hid_unregister_driver(&ortek_driver); -} - -module_init(ortek_init); -module_exit(ortek_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 4c521de4e7e6..736b2502df4f 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c @@ -103,17 +103,6 @@ static struct hid_driver pl_driver = { .input_mapping = pl_input_mapping, .probe = pl_probe, }; +module_hid_driver(pl_driver); -static int __init pl_init(void) -{ - return hid_register_driver(&pl_driver); -} - -static void __exit pl_exit(void) -{ - hid_unregister_driver(&pl_driver); -} - -module_init(pl_init); -module_exit(pl_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c index 86df26e58aba..31cd93fc3d4b 100644 --- a/drivers/hid/hid-picolcd_core.c +++ b/drivers/hid/hid-picolcd_core.c @@ -672,18 +672,7 @@ static struct hid_driver picolcd_driver = { .reset_resume = picolcd_reset_resume, #endif }; +module_hid_driver(picolcd_driver); -static int __init picolcd_init(void) -{ - return hid_register_driver(&picolcd_driver); -} - -static void __exit picolcd_exit(void) -{ - hid_unregister_driver(&picolcd_driver); -} - -module_init(picolcd_init); -module_exit(picolcd_exit); MODULE_DESCRIPTION("Minibox graphics PicoLCD Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index 47ed74c46b6b..123977e5aeee 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -216,17 +216,6 @@ static struct hid_driver pl_driver = { .id_table = pl_devices, .probe = pl_probe, }; +module_hid_driver(pl_driver); -static int __init pl_init(void) -{ - return hid_register_driver(&pl_driver); -} - -static void __exit pl_exit(void) -{ - hid_unregister_driver(&pl_driver); -} - -module_init(pl_init); -module_exit(pl_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c index c15adb0c98a1..3a1c3c4c50dc 100644 --- a/drivers/hid/hid-primax.c +++ b/drivers/hid/hid-primax.c @@ -75,18 +75,7 @@ static struct hid_driver px_driver = { .id_table = px_devices, .raw_event = px_raw_event, }; +module_hid_driver(px_driver); -static int __init px_init(void) -{ - return hid_register_driver(&px_driver); -} - -static void __exit px_exit(void) -{ - hid_unregister_driver(&px_driver); -} - -module_init(px_init); -module_exit(px_exit); MODULE_AUTHOR("Terry Lambert "); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index ec8ca3336315..4e1c4bcbdc03 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -889,23 +889,6 @@ static struct hid_driver pk_driver = { .probe = pk_probe, .remove = pk_remove, }; +module_hid_driver(pk_driver); -static int pk_init(void) -{ - int ret; - - ret = hid_register_driver(&pk_driver); - if (ret) - pr_err("can't register prodikeys driver\n"); - - return ret; -} - -static void pk_exit(void) -{ - hid_unregister_driver(&pk_driver); -} - -module_init(pk_init); -module_exit(pk_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-ps3remote.c b/drivers/hid/hid-ps3remote.c index 03811e539d71..f1239d3c5b14 100644 --- a/drivers/hid/hid-ps3remote.c +++ b/drivers/hid/hid-ps3remote.c @@ -198,18 +198,7 @@ static struct hid_driver ps3remote_driver = { .report_fixup = ps3remote_fixup, .input_mapping = ps3remote_mapping, }; +module_hid_driver(ps3remote_driver); -static int __init ps3remote_init(void) -{ - return hid_register_driver(&ps3remote_driver); -} - -static void __exit ps3remote_exit(void) -{ - hid_unregister_driver(&ps3remote_driver); -} - -module_init(ps3remote_init); -module_exit(ps3remote_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Dillow , Antonio Ospite "); 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 = { .probe = lua_probe, .remove = lua_remove }; - -static int __init lua_init(void) -{ - return hid_register_driver(&lua_driver); -} - -static void __exit lua_exit(void) -{ - hid_unregister_driver(&lua_driver); -} - -module_init(lua_init); -module_exit(lua_exit); +module_hid_driver(lua_driver); MODULE_AUTHOR("Stefan Achatz"); MODULE_DESCRIPTION("USB Roccat Lua driver"); diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c index 45aea77bb611..37961c7e397d 100644 --- a/drivers/hid/hid-saitek.c +++ b/drivers/hid/hid-saitek.c @@ -54,17 +54,6 @@ static struct hid_driver saitek_driver = { .id_table = saitek_devices, .report_fixup = saitek_report_fixup }; +module_hid_driver(saitek_driver); -static int __init saitek_init(void) -{ - return hid_register_driver(&saitek_driver); -} - -static void __exit saitek_exit(void) -{ - hid_unregister_driver(&saitek_driver); -} - -module_init(saitek_init); -module_exit(saitek_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index a5821d317229..7cbb067d4a9e 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -196,17 +196,6 @@ static struct hid_driver samsung_driver = { .input_mapping = samsung_input_mapping, .probe = samsung_probe, }; +module_hid_driver(samsung_driver); -static int __init samsung_init(void) -{ - return hid_register_driver(&samsung_driver); -} - -static void __exit samsung_exit(void) -{ - hid_unregister_driver(&samsung_driver); -} - -module_init(samsung_init); -module_exit(samsung_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 0bc58bd8d4f5..4179f5e91e68 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -627,19 +627,7 @@ static struct hid_driver sensor_hub_driver = { .reset_resume = sensor_hub_reset_resume, #endif }; - -static int __init sensor_hub_init(void) -{ - return hid_register_driver(&sensor_hub_driver); -} - -static void __exit sensor_hub_exit(void) -{ - hid_unregister_driver(&sensor_hub_driver); -} - -module_init(sensor_hub_init); -module_exit(sensor_hub_exit); +module_hid_driver(sensor_hub_driver); MODULE_DESCRIPTION("HID Sensor Hub driver"); MODULE_AUTHOR("Srinivas Pandruvada "); 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 = { .id_table = sjoy_devices, .probe = sjoy_probe, }; +module_hid_driver(sjoy_driver); -static int __init sjoy_init(void) -{ - return hid_register_driver(&sjoy_driver); -} - -static void __exit sjoy_exit(void) -{ - hid_unregister_driver(&sjoy_driver); -} - -module_init(sjoy_init); -module_exit(sjoy_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jussi Kivilinna"); diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 7f33ebf299c2..23fc762e8633 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -229,17 +229,6 @@ static struct hid_driver sony_driver = { .report_fixup = sony_report_fixup, .raw_event = sony_raw_event }; +module_hid_driver(sony_driver); -static int __init sony_init(void) -{ - return hid_register_driver(&sony_driver); -} - -static void __exit sony_exit(void) -{ - hid_unregister_driver(&sony_driver); -} - -module_init(sony_init); -module_exit(sony_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c index 602013741718..e94371a059cb 100644 --- a/drivers/hid/hid-speedlink.c +++ b/drivers/hid/hid-speedlink.c @@ -73,17 +73,6 @@ static struct hid_driver speedlink_driver = { .input_mapping = speedlink_input_mapping, .event = speedlink_event, }; +module_hid_driver(speedlink_driver); -static int __init speedlink_init(void) -{ - return hid_register_driver(&speedlink_driver); -} - -static void __exit speedlink_exit(void) -{ - hid_unregister_driver(&speedlink_driver); -} - -module_init(speedlink_init); -module_exit(speedlink_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c index 45b4b066a262..87fc91e1c8de 100644 --- a/drivers/hid/hid-sunplus.c +++ b/drivers/hid/hid-sunplus.c @@ -63,17 +63,6 @@ static struct hid_driver sp_driver = { .report_fixup = sp_report_fixup, .input_mapping = sp_input_mapping, }; +module_hid_driver(sp_driver); -static int __init sp_init(void) -{ - return hid_register_driver(&sp_driver); -} - -static void __exit sp_exit(void) -{ - hid_unregister_driver(&sp_driver); -} - -module_init(sp_init); -module_exit(sp_exit); MODULE_LICENSE("GPL"); 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 = { .id_table = tivo_devices, .input_mapping = tivo_input_mapping, }; +module_hid_driver(tivo_driver); -static int __init tivo_init(void) -{ - return hid_register_driver(&tivo_driver); -} - -static void __exit tivo_exit(void) -{ - hid_unregister_driver(&tivo_driver); -} - -module_init(tivo_init); -module_exit(tivo_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jarod Wilson "); 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 = { .id_table = tm_devices, .probe = tm_probe, }; +module_hid_driver(tm_driver); -static int __init tm_init(void) -{ - return hid_register_driver(&tm_driver); -} - -static void __exit tm_exit(void) -{ - hid_unregister_driver(&tm_driver); -} - -module_init(tm_init); -module_exit(tm_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c index 613ff7b1d746..8a5b843e9dd6 100644 --- a/drivers/hid/hid-topseed.c +++ b/drivers/hid/hid-topseed.c @@ -76,17 +76,6 @@ static struct hid_driver ts_driver = { .id_table = ts_devices, .input_mapping = ts_input_mapping, }; +module_hid_driver(ts_driver); -static int __init ts_init(void) -{ - return hid_register_driver(&ts_driver); -} - -static void __exit ts_exit(void) -{ - hid_unregister_driver(&ts_driver); -} - -module_init(ts_init); -module_exit(ts_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-twinhan.c b/drivers/hid/hid-twinhan.c index f23456b1fd4b..c08c36443f83 100644 --- a/drivers/hid/hid-twinhan.c +++ b/drivers/hid/hid-twinhan.c @@ -131,17 +131,6 @@ static struct hid_driver twinhan_driver = { .id_table = twinhan_devices, .input_mapping = twinhan_input_mapping, }; +module_hid_driver(twinhan_driver); -static int __init twinhan_init(void) -{ - return hid_register_driver(&twinhan_driver); -} - -static void __exit twinhan_exit(void) -{ - hid_unregister_driver(&twinhan_driver); -} - -module_init(twinhan_init); -module_exit(twinhan_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c index 2e56a1fd2375..fb8b516ff0ed 100644 --- a/drivers/hid/hid-uclogic.c +++ b/drivers/hid/hid-uclogic.c @@ -650,17 +650,6 @@ static struct hid_driver uclogic_driver = { .id_table = uclogic_devices, .report_fixup = uclogic_report_fixup, }; +module_hid_driver(uclogic_driver); -static int __init uclogic_init(void) -{ - return hid_register_driver(&uclogic_driver); -} - -static void __exit uclogic_exit(void) -{ - hid_unregister_driver(&uclogic_driver); -} - -module_init(uclogic_init); -module_exit(uclogic_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 2f60da9ed066..a4a8bb0da688 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c @@ -953,23 +953,7 @@ static struct hid_driver wacom_driver = { .raw_event = wacom_raw_event, .input_mapped = wacom_input_mapped, }; +module_hid_driver(wacom_driver); -static int __init wacom_init(void) -{ - int ret; - - ret = hid_register_driver(&wacom_driver); - if (ret) - pr_err("can't register wacom driver\n"); - return ret; -} - -static void __exit wacom_exit(void) -{ - hid_unregister_driver(&wacom_driver); -} - -module_init(wacom_init); -module_exit(wacom_exit); MODULE_DESCRIPTION("Driver for Wacom Graphire Bluetooth and Wacom Intuos4 WL"); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c index bb536ab5941e..059931d7b392 100644 --- a/drivers/hid/hid-waltop.c +++ b/drivers/hid/hid-waltop.c @@ -779,17 +779,6 @@ static struct hid_driver waltop_driver = { .report_fixup = waltop_report_fixup, .raw_event = waltop_raw_event, }; +module_hid_driver(waltop_driver); -static int __init waltop_init(void) -{ - return hid_register_driver(&waltop_driver); -} - -static void __exit waltop_exit(void) -{ - hid_unregister_driver(&waltop_driver); -} - -module_init(waltop_init); -module_exit(waltop_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 84e2fbec5fbb..0fb8ab93db68 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c @@ -1294,25 +1294,8 @@ static struct hid_driver wiimote_hid_driver = { .remove = wiimote_hid_remove, .raw_event = wiimote_hid_event, }; +module_hid_driver(wiimote_hid_driver); -static int __init wiimote_init(void) -{ - int ret; - - ret = hid_register_driver(&wiimote_hid_driver); - if (ret) - pr_err("Can't register wiimote hid driver\n"); - - return ret; -} - -static void __exit wiimote_exit(void) -{ - hid_unregister_driver(&wiimote_hid_driver); -} - -module_init(wiimote_init); -module_exit(wiimote_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Herrmann "); MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver"); 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 = { .id_table = zp_devices, .probe = zp_probe, }; +module_hid_driver(zp_driver); -static int __init zp_init(void) -{ - return hid_register_driver(&zp_driver); -} - -static void __exit zp_exit(void) -{ - hid_unregister_driver(&zp_driver); -} - -module_init(zp_init); -module_exit(zp_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c index 1ad85f2257b4..e4cddeccd6b5 100644 --- a/drivers/hid/hid-zydacron.c +++ b/drivers/hid/hid-zydacron.c @@ -219,17 +219,6 @@ static struct hid_driver zc_driver = { .probe = zc_probe, .remove = zc_remove, }; +module_hid_driver(zc_driver); -static int __init zc_init(void) -{ - return hid_register_driver(&zc_driver); -} - -static void __exit zc_exit(void) -{ - hid_unregister_driver(&zc_driver); -} - -module_init(zc_init); -module_exit(zc_exit); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From fee5dfecb0c74c9eab475a2a20d7a5ababe2f8e6 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 17 Dec 2012 13:20:43 +0100 Subject: HID: uhid: use __packed__ for uhid_feature_answer_req We use __packed__ for all API structures so we can extend them without breaking alignment rules. We do try to explicitly align the structures, but to be safe we also use __packed__. uhid_feature_answer_req is already 64bit aligned so we can add __packed__ without breaking ABI. Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- include/uapi/linux/uhid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/uhid.h b/include/uapi/linux/uhid.h index 9c6974f16966..e9ed951e2b09 100644 --- a/include/uapi/linux/uhid.h +++ b/include/uapi/linux/uhid.h @@ -86,7 +86,7 @@ struct uhid_feature_answer_req { __u16 err; __u16 size; __u8 data[UHID_DATA_MAX]; -}; +} __attribute__((__packed__)); struct uhid_event { __u32 type; -- cgit v1.2.3 From aaca9cc0165f06a037a1e07770f6b379ff496288 Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Thu, 17 Jan 2013 11:06:09 +0100 Subject: HID: Support Jess/Saitek Color Rumble Pad Add support for another gamepad to the hid-pl driver. The "color rumble pad P580" marketed using the "Saitek" brand in Germany, and using a USB Vendor ID attributed to "Jess" seems to be electronically identical to the 4-field variant of the "Green Asia" gamepad. The pad has been tested to support rumble strengths up to 255, not just 127. Signed-off-by: Michael Karcher Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-pl.c | 13 +++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index eb2ee11b6412..aad262727300 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1599,6 +1599,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 4dfa605e2d14..3a493345ded0 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -442,6 +442,9 @@ #define USB_VENDOR_ID_JESS 0x0c45 #define USB_DEVICE_ID_JESS_YUREX 0x1010 +#define USB_VENDOR_ID_JESS2 0x0f30 +#define USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD 0x0111 + #define USB_VENDOR_ID_KBGEAR 0x084e #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index 123977e5aeee..b0199d27787b 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -14,6 +14,8 @@ * 0e8f:0003 "GASIA USB Gamepad" * - another version of the König gamepad * + * 0f30:0111 "Saitek Color Rumble Pad" + * * Copyright (c) 2007, 2009 Anssi Hannula */ @@ -51,6 +53,7 @@ struct plff_device { struct hid_report *report; + s32 maxval; s32 *strong; s32 *weak; }; @@ -66,8 +69,8 @@ static int hid_plff_play(struct input_dev *dev, void *data, right = effect->u.rumble.weak_magnitude; debug("called with 0x%04x 0x%04x", left, right); - left = left * 0x7f / 0xffff; - right = right * 0x7f / 0xffff; + left = left * plff->maxval / 0xffff; + right = right * plff->maxval / 0xffff; *plff->strong = left; *plff->weak = right; @@ -87,6 +90,7 @@ static int plff_init(struct hid_device *hid) struct list_head *report_ptr = report_list; struct input_dev *dev; int error; + s32 maxval; s32 *strong; s32 *weak; @@ -123,6 +127,7 @@ static int plff_init(struct hid_device *hid) return -ENODEV; } + maxval = 0x7f; if (report->field[0]->report_count >= 4) { report->field[0]->value[0] = 0x00; report->field[0]->value[1] = 0x00; @@ -135,6 +140,8 @@ static int plff_init(struct hid_device *hid) report->field[1]->value[0] = 0x00; strong = &report->field[2]->value[0]; weak = &report->field[3]->value[0]; + if (hid->vendor == USB_VENDOR_ID_JESS2) + maxval = 0xff; debug("detected 4-field device"); } else { hid_err(hid, "not enough fields or values\n"); @@ -158,6 +165,7 @@ static int plff_init(struct hid_device *hid) plff->report = report; plff->strong = strong; plff->weak = weak; + plff->maxval = maxval; *strong = 0x00; *weak = 0x00; @@ -207,6 +215,7 @@ static const struct hid_device_id pl_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), .driver_data = 1 }, /* Twin USB Joystick */ { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, + { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD), }, { } }; MODULE_DEVICE_TABLE(hid, pl_devices); -- cgit v1.2.3 From b77a989acca3fb4d09c2d8c3749499c663f5ab9f Mon Sep 17 00:00:00 2001 From: Simon Que Date: Thu, 17 Jan 2013 13:02:52 -0800 Subject: HID: Fix uninitialized variable "size" in hid-wiimote-debug This variable is initialized conditionally, based on whether a wiimote call succeeds. However, the logic is not obvious to the compiler so it throws a warning. Eliminate the warning by initializing "size" to 0. The warning is: files/drivers/hid/hid-wiimote-debug.c:69:18: warning: 'size' may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Simon Que Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, unsigned long flags; ssize_t ret; char buf[16]; - __u16 size; + __u16 size = 0; if (s == 0) return -EINVAL; -- cgit v1.2.3 From 6d85d037d6247b06e1060b5e5ad0e4854a7d1e3b Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:23 +0100 Subject: HID: core: add "report" hook, called once the report has been parsed This callback is called when the parsing of the report has been done by hid-core (so after the calls to .event). The hid drivers can now have access to the whole report by relying on the values stored in the different fields. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 4 ++++ include/linux/hid.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index eb2ee11b6412..754098a7dd47 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1195,6 +1195,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, { struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; + struct hid_driver *hdrv; unsigned int a; int rsize, csize = size; u8 *cdata = data; @@ -1231,6 +1232,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, if (hid->claimed != HID_CLAIMED_HIDRAW) { for (a = 0; a < report->maxfield; a++) hid_input_field(hid, report->field[a], cdata, interrupt); + hdrv = hid->driver; + if (hdrv && hdrv->report) + hdrv->report(hid, report); } if (hid->claimed & HID_CLAIMED_INPUT) diff --git a/include/linux/hid.h b/include/linux/hid.h index 7330a0fef0c0..9f56e9040f66 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -589,6 +589,7 @@ struct hid_usage_id { * @raw_event: if report in report_table, this hook is called (NULL means nop) * @usage_table: on which events to call event (NULL means all) * @event: if usage in usage_table, this hook is called (NULL means nop) + * @report: this hook is called after parsing a report (NULL means nop) * @report_fixup: called before report descriptor parsing (NULL means nop) * @input_mapping: invoked on input registering before mapping an usage * @input_mapped: invoked on input registering after mapping an usage @@ -627,6 +628,7 @@ struct hid_driver { const struct hid_usage_id *usage_table; int (*event)(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value); + void (*report)(struct hid_device *hdev, struct hid_report *report); __u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf, unsigned int *size); -- cgit v1.2.3 From 55978fa9dc4c57f8249617c35d28c0599de850df Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:24 +0100 Subject: HID: multitouch: use the callback "report" instead of sequential events Nexio 42" devices requires to rely on the HID field Contact Count to compute the valid values. However, this field is most of the time at the end of the report, meaning that we need to get the all report parsed before processing it. This patch does not introduce functional changes. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 61543c02ea0b..13b94619b5d0 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -85,6 +85,7 @@ struct mt_device { multitouch fields */ unsigned last_field_index; /* last field index of the report */ unsigned last_slot_field; /* the last field of a slot */ + unsigned mt_report_id; /* the report ID of the multitouch device */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ __s8 inputmode_index; /* InputMode HID feature index in the report */ __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, @@ -428,6 +429,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, mt_store_field(usage, td, hi); td->last_field_index = field->index; td->touches_by_report++; + td->mt_report_id = field->report->id; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, @@ -577,6 +579,16 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) static int mt_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) +{ + /* we will handle the hidinput part later, now remains hiddev */ + if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) + hid->hiddev_hid_event(hid, field, usage, value); + + return 1; +} + +static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, + struct hid_usage *usage, __s32 value) { struct mt_device *td = hid_get_drvdata(hid); __s32 quirks = td->mtclass.quirks; @@ -635,8 +647,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, break; default: - /* fallback to the generic hidinput handling */ - return 0; + return; } if (usage->usage_index + 1 == field->report_count) { @@ -650,12 +661,32 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, } } +} - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); +static void mt_report(struct hid_device *hid, struct hid_report *report) +{ + struct mt_device *td = hid_get_drvdata(hid); + struct hid_field *field; + unsigned count; + int r, n; - return 1; + if (report->id != td->mt_report_id) + return; + + if (!(hid->claimed & HID_CLAIMED_INPUT)) + return; + + for (r = 0; r < report->maxfield; r++) { + field = report->field[r]; + count = field->report_count; + + if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) + continue; + + for (n = 0; n < count; n++) + mt_process_mt_event(hid, field, &field->usage[n], + field->value[n]); + } } static void mt_set_input_mode(struct hid_device *hdev) @@ -1193,6 +1224,7 @@ static struct hid_driver mt_driver = { .feature_mapping = mt_feature_mapping, .usage_table = mt_grabbed_usages, .event = mt_event, + .report = mt_report, #ifdef CONFIG_PM .reset_resume = mt_reset_resume, .resume = mt_resume, -- cgit v1.2.3 From c2517f62dac608e43b652dc6ed1e478e8447e029 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:25 +0100 Subject: HID: multitouch: add support for Nexio 42" panel This device is the worst device I saw. It keeps TipSwitch and InRange at 1 for fingers that are not touching the panel. The solution is to rely on the field ContactCount, which is accurate as the correct information are packed at the begining of the frame. Unfortunately, CountactCount is most of the time at the end of the report. The solution is to pick it when we have the whole report in raw_event. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-multitouch.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 34e25471aeaa..8311380c76f6 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -597,6 +597,9 @@ #define USB_VENDOR_ID_NEC 0x073e #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 +#define USB_VENDOR_ID_NEXIO 0x1870 +#define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d + #define USB_VENDOR_ID_NEXTWINDOW 0x1926 #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 13b94619b5d0..87690e2726ac 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -54,6 +54,7 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_NO_AREA (1 << 9) #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) #define MT_QUIRK_HOVERING (1 << 11) +#define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12) struct mt_slot { __s32 x, y, cx, cy, p, w, h; @@ -83,6 +84,7 @@ struct mt_device { struct mt_class mtclass; /* our mt device class */ struct mt_fields *fields; /* temporary placeholder for storing the multitouch fields */ + __s32 *contactcount; /* contact count value in the report */ unsigned last_field_index; /* last field index of the report */ unsigned last_slot_field; /* the last field of a slot */ unsigned mt_report_id; /* the report ID of the multitouch device */ @@ -112,6 +114,7 @@ struct mt_device { #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007 #define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 #define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 +#define MT_CLS_ALWAYS_TRUE 0x000a /* vendor specific classes */ #define MT_CLS_3M 0x0101 @@ -171,6 +174,9 @@ static struct mt_class mt_classes[] = { { .name = MT_CLS_INRANGE_CONTACTNUMBER, .quirks = MT_QUIRK_VALID_IS_INRANGE | MT_QUIRK_SLOT_IS_CONTACTNUMBER }, + { .name = MT_CLS_ALWAYS_TRUE, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_CONTACT_CNT_ACCURATE }, /* * vendor specific classes @@ -251,6 +257,9 @@ static ssize_t mt_set_quirks(struct device *dev, td->mtclass.quirks = val; + if (!td->contactcount) + td->mtclass.quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; + return count; } @@ -461,6 +470,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->last_field_index = field->index; return 1; case HID_DG_CONTACTCOUNT: + td->contactcount = field->value + usage->usage_index; td->last_field_index = field->index; return 1; case HID_DG_CONTACTMAX: @@ -525,6 +535,10 @@ static int mt_compute_slot(struct mt_device *td, struct input_dev *input) */ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) { + if ((td->mtclass.quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) && + td->num_received >= td->num_expected) + return; + if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { int slotnum = mt_compute_slot(td, input); struct mt_slot *s = &td->curdata; @@ -635,12 +649,6 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, td->curdata.h = value; break; case HID_DG_CONTACTCOUNT: - /* - * Includes multi-packet support where subsequent - * packets are sent with zero contactcount. - */ - if (value) - td->num_expected = value; break; case HID_DG_TOUCH: /* do nothing */ @@ -676,6 +684,13 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) if (!(hid->claimed & HID_CLAIMED_INPUT)) return; + /* + * Includes multi-packet support where subsequent + * packets are sent with zero contactcount. + */ + if (td->contactcount && *td->contactcount) + td->num_expected = *td->contactcount; + for (r = 0; r < report->maxfield; r++) { field = report->field[r]; count = field->report_count; @@ -750,11 +765,15 @@ static void mt_post_parse_default_settings(struct mt_device *td) static void mt_post_parse(struct mt_device *td) { struct mt_fields *f = td->fields; + struct mt_class *cls = &td->mtclass; if (td->touches_by_report > 0) { int field_count_per_touch = f->length / td->touches_by_report; td->last_slot_field = f->usages[field_count_per_touch - 1]; } + + if (!td->contactcount) + cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; } static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) @@ -1087,6 +1106,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, + /* Nexio panels */ + { .driver_data = MT_CLS_ALWAYS_TRUE, + MT_USB_DEVICE(USB_VENDOR_ID_NEXIO, + USB_DEVICE_ID_NEXIO_MULTITOUCH_420)}, + /* Panasonic panels */ { .driver_data = MT_CLS_PANASONIC, MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, -- cgit v1.2.3 From c629dd7eb3b43bb09eecb035f016bdca32dc8acf Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:26 +0100 Subject: HID: multitouch: fix Win8 protocol for Sharp like devices The Sharp LC-20FE1-W screen (04dd:9681) behaves like the Nexio 42". It may report out of ranges values that are filtered out by relying on the Contact Count HID field. Adding the quirk MT_QUIRK_CONTACT_CNT_ACCURATE makes hid-multitouch strongest against this kind of device, without breaking the current devices. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 87690e2726ac..1cf676d93049 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -311,6 +311,7 @@ static void mt_feature_mapping(struct hid_device *hdev, *quirks |= MT_QUIRK_ALWAYS_VALID; *quirks |= MT_QUIRK_IGNORE_DUPLICATES; *quirks |= MT_QUIRK_HOVERING; + *quirks |= MT_QUIRK_CONTACT_CNT_ACCURATE; *quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; *quirks &= ~MT_QUIRK_VALID_IS_INRANGE; *quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; -- cgit v1.2.3 From e0bb8f9adf1e11cea419c845220d1524a525823b Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:27 +0100 Subject: HID: multitouch: ensure that serial devices make no use of contact count The serial protocol makes contact count a redondant information, and sometimes it is not reliable (TRS-Star are in this case). Disabling the use of contact count for these devices is thus safer. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 1cf676d93049..2693059df534 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -758,6 +758,7 @@ static void mt_post_parse_default_settings(struct mt_device *td) quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; quirks &= ~MT_QUIRK_VALID_IS_INRANGE; quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; + quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; } td->mtclass.quirks = quirks; -- cgit v1.2.3 From 51377fed20461ad857c020b7109efa8207200222 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:28 +0100 Subject: HID: multitouch: fix protocol for Sitronix 1403:5001 Since the inclusion of this device in hid-multitouch, the device did not forward any events. Using the serial class makes it working again. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 2693059df534..4ea28de33d0a 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1168,7 +1168,7 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_CONFIDENCE, MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM)}, - { .driver_data = MT_CLS_CONFIDENCE, + { .driver_data = MT_CLS_ALWAYS_TRUE, MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX)}, -- cgit v1.2.3 From efc16787cf92de4906adae8e451c10c6189b4ca8 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:29 +0100 Subject: HID: multitouch: fix protocol for Cando 2087:0a02 Cando 2087:0a02 was broken, this fixes it. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 4ea28de33d0a..e2fc1211f130 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -115,6 +115,7 @@ struct mt_device { #define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 #define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 #define MT_CLS_ALWAYS_TRUE 0x000a +#define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 /* vendor specific classes */ #define MT_CLS_3M 0x0101 @@ -177,6 +178,11 @@ static struct mt_class mt_classes[] = { { .name = MT_CLS_ALWAYS_TRUE, .quirks = MT_QUIRK_ALWAYS_VALID | MT_QUIRK_CONTACT_CNT_ACCURATE }, + { .name = MT_CLS_DUAL_CONTACT_NUMBER, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_SLOT_IS_CONTACTNUMBER, + .maxcontacts = 2 }, /* * vendor specific classes @@ -947,7 +953,7 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, MT_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, - { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + { .driver_data = MT_CLS_DUAL_CONTACT_NUMBER, MT_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, -- cgit v1.2.3 From e325905c6c28331772dcd3218a690af744a1a564 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:30 +0100 Subject: HID: multitouch: fix protocol for Elo panels The previous protocol was nearly working, but when several fingers were present on the sensor, those that were not moving were not updated in the next report, introducing a lot of releases. Signed-off-by: Benjamin Tissoires Conflicts: drivers/hid/hid-multitouch.c Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e2fc1211f130..a3d4f0fbc4be 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -116,6 +116,7 @@ struct mt_device { #define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 #define MT_CLS_ALWAYS_TRUE 0x000a #define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 +#define MT_CLS_DUAL_CONTACT_ID 0x0011 /* vendor specific classes */ #define MT_CLS_3M 0x0101 @@ -183,6 +184,11 @@ static struct mt_class mt_classes[] = { MT_QUIRK_CONTACT_CNT_ACCURATE | MT_QUIRK_SLOT_IS_CONTACTNUMBER, .maxcontacts = 2 }, + { .name = MT_CLS_DUAL_CONTACT_ID, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_SLOT_IS_CONTACTID, + .maxcontacts = 2 }, /* * vendor specific classes @@ -1040,7 +1046,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) }, /* Elo TouchSystems IntelliTouch Plus panel */ - { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, + { .driver_data = MT_CLS_DUAL_CONTACT_ID, MT_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) }, -- cgit v1.2.3 From dc3e1d8052548f5b46288a1d43c93684f7d64804 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 31 Jan 2013 17:22:31 +0100 Subject: HID: multitouch: make MT_CLS_ALWAYS_TRUE the new default class By running a test on all the traces of the devices I have, I noticed that the class MT_CLS_ALWAYS_TRUE could handle all the devices I've seen so far without any other quirks. I guess this is the behavior Win 7 requires in its driver. We can change the default class then and keep the existing classes for backward compatibility and performances for some of them. Two operations have been done: * replaced MT_CLS_DEFAULT by MT_CLS_NSMU * then replaced MT_CLS_ALWAYS_TRUE by MT_CLS_DEFAULT Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index a3d4f0fbc4be..28af54fb07d9 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -114,7 +114,7 @@ struct mt_device { #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007 #define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 #define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 -#define MT_CLS_ALWAYS_TRUE 0x000a +#define MT_CLS_NSMU 0x000a #define MT_CLS_DUAL_CONTACT_NUMBER 0x0010 #define MT_CLS_DUAL_CONTACT_ID 0x0011 @@ -150,6 +150,9 @@ static int cypress_compute_slot(struct mt_device *td) static struct mt_class mt_classes[] = { { .name = MT_CLS_DEFAULT, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_CONTACT_CNT_ACCURATE }, + { .name = MT_CLS_NSMU, .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, { .name = MT_CLS_SERIAL, .quirks = MT_QUIRK_ALWAYS_VALID}, @@ -176,9 +179,6 @@ static struct mt_class mt_classes[] = { { .name = MT_CLS_INRANGE_CONTACTNUMBER, .quirks = MT_QUIRK_VALID_IS_INRANGE | MT_QUIRK_SLOT_IS_CONTACTNUMBER }, - { .name = MT_CLS_ALWAYS_TRUE, - .quirks = MT_QUIRK_ALWAYS_VALID | - MT_QUIRK_CONTACT_CNT_ACCURATE }, { .name = MT_CLS_DUAL_CONTACT_NUMBER, .quirks = MT_QUIRK_ALWAYS_VALID | MT_QUIRK_CONTACT_CNT_ACCURATE | @@ -939,7 +939,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_3M3266) }, /* ActionStar panels */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, USB_DEVICE_ID_ACTIONSTAR_1011) }, @@ -952,7 +952,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, /* Baanto multitouch devices */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_BAANTO, USB_DEVICE_ID_BAANTO_MT_190W2) }, /* Cando panels */ @@ -970,12 +970,12 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, /* Chunghwa Telecom touch panels */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, /* CVTouch panels */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, @@ -1064,12 +1064,12 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS) }, /* Gametel game controller */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL, USB_DEVICE_ID_GAMETEL_MT_MODE) }, /* GoodTouch panels */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, USB_DEVICE_ID_GOODTOUCH_000f) }, @@ -1087,7 +1087,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_IDEACOM_IDC6651) }, /* Ilitek dual touch panel */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, @@ -1121,7 +1121,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, /* Nexio panels */ - { .driver_data = MT_CLS_ALWAYS_TRUE, + { .driver_data = MT_CLS_DEFAULT, MT_USB_DEVICE(USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_420)}, @@ -1134,7 +1134,7 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_PANABOARD_UBT880) }, /* Novatek Panel */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_PCT) }, @@ -1180,7 +1180,7 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_CONFIDENCE, MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM)}, - { .driver_data = MT_CLS_ALWAYS_TRUE, + { .driver_data = MT_CLS_DEFAULT, MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX)}, @@ -1190,48 +1190,48 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, /* Touch International panels */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, /* Unitec panels */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, /* XAT */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) }, /* Xiroku */ - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX1) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX1) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR1) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX2) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX2) }, - { .driver_data = MT_CLS_DEFAULT, + { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) }, -- cgit v1.2.3 From e7e2b788614c453c72550264bd915ba8923218e8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 6 Feb 2013 17:23:55 +0100 Subject: HID: add missing GENERIC_HARDIRQ dependency HID Sensors framework support (CONFIG_HID_SENSOR_HUB) unconditionally selects MFD_CORE which however depends on GENERIC_HARDIRQS. So add this dependency to HID_SENSOR_HUB as well. Signed-off-by: Heiko Carstens Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index e7d6a13ec6a6..bf88eca3e868 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -719,7 +719,7 @@ config HID_ZYDACRON config HID_SENSOR_HUB tristate "HID Sensors framework support" - depends on USB_HID + depends on USB_HID && GENERIC_HARDIRQS select MFD_CORE default n -- help--- -- cgit v1.2.3 From 7e3cc447ff8906558619b1ecc46e4bd776a4f3a6 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 6 Feb 2013 12:10:47 +0100 Subject: HID: multitouch: do not use pointers towards hid-core The previous implementation registered a pointer towards hid-core to the value of contact count. This is not safe and may be difficult to debug if hid-core ever changes its implementation. The use of regular indexes is a better choice. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 28af54fb07d9..e22fbd33ad8c 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -84,7 +84,8 @@ struct mt_device { struct mt_class mtclass; /* our mt device class */ struct mt_fields *fields; /* temporary placeholder for storing the multitouch fields */ - __s32 *contactcount; /* contact count value in the report */ + int cc_index; /* contact count field index in the report */ + int cc_value_index; /* contact count value index in the field */ unsigned last_field_index; /* last field index of the report */ unsigned last_slot_field; /* the last field of a slot */ unsigned mt_report_id; /* the report ID of the multitouch device */ @@ -269,7 +270,7 @@ static ssize_t mt_set_quirks(struct device *dev, td->mtclass.quirks = val; - if (!td->contactcount) + if (td->cc_index < 0) td->mtclass.quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; return count; @@ -483,7 +484,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->last_field_index = field->index; return 1; case HID_DG_CONTACTCOUNT: - td->contactcount = field->value + usage->usage_index; + td->cc_index = field->index; + td->cc_value_index = usage->usage_index; td->last_field_index = field->index; return 1; case HID_DG_CONTACTMAX: @@ -701,8 +703,12 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) * Includes multi-packet support where subsequent * packets are sent with zero contactcount. */ - if (td->contactcount && *td->contactcount) - td->num_expected = *td->contactcount; + if (td->cc_index >= 0) { + struct hid_field *field = report->field[td->cc_index]; + int value = field->value[td->cc_value_index]; + if (value) + td->num_expected = value; + } for (r = 0; r < report->maxfield; r++) { field = report->field[r]; @@ -786,7 +792,7 @@ static void mt_post_parse(struct mt_device *td) td->last_slot_field = f->usages[field_count_per_touch - 1]; } - if (!td->contactcount) + if (td->cc_index < 0) cls->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE; } @@ -845,6 +851,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) td->mtclass = *mtclass; td->inputmode = -1; td->maxcontact_report_id = -1; + td->cc_index = -1; hid_set_drvdata(hdev, td); td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); -- cgit v1.2.3 From 1b474fe82d4eed3c909f02be82586284827c1705 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 8 Feb 2013 15:51:30 +0100 Subject: HID: ntrig: use input_configured() callback to set the name The use of input_configured() allows the ntrig driver to actually change the name of the input and its bitmask before it is added to the input subsystem. Thus, the logs are coherents and udev catch the real bitmask when the device is added. Signed-off-by: Benjamin Tissoires Signed-off-by: Rafi Rubin Signed-off-by: Jiri Kosina --- drivers/hid/hid-ntrig.c | 68 ++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 86a969f63292..79ab34949cb1 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -858,12 +858,43 @@ not_claimed_input: return 1; } +static void ntrig_input_configured(struct hid_device *hid, + struct hid_input *hidinput) + +{ + struct input_dev *input = hidinput->input; + + if (hidinput->report->maxfield < 1) + return; + + switch (hidinput->report->field[0]->application) { + case HID_DG_PEN: + input->name = "N-Trig Pen"; + break; + case HID_DG_TOUCHSCREEN: + /* These keys are redundant for fingers, clear them + * to prevent incorrect identification */ + __clear_bit(BTN_TOOL_PEN, input->keybit); + __clear_bit(BTN_TOOL_FINGER, input->keybit); + __clear_bit(BTN_0, input->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); + /* + * The physical touchscreen (single touch) + * input has a value for physical, whereas + * the multitouch only has logical input + * fields. + */ + input->name = (hidinput->report->field[0]->physical) ? + "N-Trig Touchscreen" : + "N-Trig MultiTouch"; + break; + } +} + static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; struct ntrig_data *nd; - struct hid_input *hidinput; - struct input_dev *input; struct hid_report *report; if (id->driver_data) @@ -901,38 +932,6 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } - - list_for_each_entry(hidinput, &hdev->inputs, list) { - if (hidinput->report->maxfield < 1) - continue; - - input = hidinput->input; - switch (hidinput->report->field[0]->application) { - case HID_DG_PEN: - input->name = "N-Trig Pen"; - break; - case HID_DG_TOUCHSCREEN: - /* These keys are redundant for fingers, clear them - * to prevent incorrect identification */ - __clear_bit(BTN_TOOL_PEN, input->keybit); - __clear_bit(BTN_TOOL_FINGER, input->keybit); - __clear_bit(BTN_0, input->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); - /* - * The physical touchscreen (single touch) - * input has a value for physical, whereas - * the multitouch only has logical input - * fields. - */ - input->name = - (hidinput->report->field[0] - ->physical) ? - "N-Trig Touchscreen" : - "N-Trig MultiTouch"; - break; - } - } - /* This is needed for devices with more recent firmware versions */ report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; if (report) { @@ -1023,6 +1022,7 @@ static struct hid_driver ntrig_driver = { .remove = ntrig_remove, .input_mapping = ntrig_input_mapping, .input_mapped = ntrig_input_mapped, + .input_configured = ntrig_input_configured, .usage_table = ntrig_grabbed_usages, .event = ntrig_event, }; -- cgit v1.2.3 From 30b6b7d8d340f41d11eb75e5238d33dbc438fde4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 13 Feb 2013 13:22:45 +0000 Subject: HID: blacklist Velleman data acquisition boards These are simple data acquistion boards, not HID devices and are handled by the vmk80xx comedi driver. At least one of them (10cf:5500) misidentifies itself as a HID in its USB interface descriptor. Ignore all these devices. Signed-off-by: Ian Abbott Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 8 ++++++++ drivers/hid/hid-ids.h | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index aad262727300..bf44af35439b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2229,6 +2229,14 @@ bool hid_ignore(struct hid_device *hdev) hdev->type != HID_TYPE_USBMOUSE) return true; break; + case USB_VENDOR_ID_VELLEMAN: + /* These are not HID devices. They are handled by comedi. */ + if ((hdev->product >= USB_DEVICE_ID_VELLEMAN_K8055_FIRST && + hdev->product <= USB_DEVICE_ID_VELLEMAN_K8055_LAST) || + (hdev->product >= USB_DEVICE_ID_VELLEMAN_K8061_FIRST && + hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST)) + return true; + break; } if (hdev->type == HID_TYPE_USBMOUSE && diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3a493345ded0..104105208596 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -794,6 +794,12 @@ #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19 +#define USB_VENDOR_ID_VELLEMAN 0x10cf +#define USB_DEVICE_ID_VELLEMAN_K8055_FIRST 0x5500 +#define USB_DEVICE_ID_VELLEMAN_K8055_LAST 0x5503 +#define USB_DEVICE_ID_VELLEMAN_K8061_FIRST 0x8061 +#define USB_DEVICE_ID_VELLEMAN_K8061_LAST 0x8068 + #define USB_VENDOR_ID_VERNIER 0x08f7 #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -- cgit v1.2.3 From 89bdd0c6f38ccf0de43d5a36ede384a730f3394e Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 18 Feb 2013 01:47:15 +0100 Subject: HID: wiimote: fix nunchuck button parser The buttons of the Wii Remote Nunchuck extension are actually active low. Fix the parser to forward the inverted values. The comment in the function always said "0 == pressed" but the implementation was wrong from the beginning. Cc: stable@vger.kernel.org Reported-by: Victor Quicksilver Signed-off-by: David Herrmann Signed-off-by: Jiri Kosina --- drivers/hid/hid-wiimote-ext.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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) if (ext->motionp) { input_report_key(ext->input, - wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x04)); + wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04)); input_report_key(ext->input, - wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x08)); + wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08)); } else { input_report_key(ext->input, - wiiext_keymap[WIIEXT_KEY_Z], !!(payload[5] & 0x01)); + wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01)); input_report_key(ext->input, - wiiext_keymap[WIIEXT_KEY_C], !!(payload[5] & 0x02)); + wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02)); } input_sync(ext->input); -- cgit v1.2.3 From 30ba2fbde1840db440915491cdde235b72a11384 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Tue, 22 Jan 2013 12:01:21 -0500 Subject: HID: add ThingM blink(1) USB RGB LED support The ThingM blink(1) is an open source hardware USB RGB LED. It contains an internal EEPROM, allowing to configure up to 12 light patterns. A light pattern is a RGB color plus a fade time. This driver registers a LED class instance with additional sysfs attributes to support basic functions such as setting RGB colors, fade and playing. Other functions are still accessible through the hidraw interface. At this time, the only documentation for the device is the firmware source code from ThingM, plus a few schematics. They are available at: https://github.com/todbot/blink1 This patch is version 3. It updates the name of the source file, the driver and the led sysfs entry, according to comments from Jiri Kosina and Simon Wood. Signed-off-by: Vivien Didelot Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-driver-hid-thingm | 23 ++ MAINTAINERS | 5 + drivers/hid/Kconfig | 10 + drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 3 + drivers/hid/hid-thingm.c | 272 ++++++++++++++++++++++ 7 files changed, 315 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-thingm create mode 100644 drivers/hid/hid-thingm.c diff --git a/Documentation/ABI/testing/sysfs-driver-hid-thingm b/Documentation/ABI/testing/sysfs-driver-hid-thingm new file mode 100644 index 000000000000..abcffeedd20a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-thingm @@ -0,0 +1,23 @@ +What: /sys/class/leds/blink1::/rgb +Date: January 2013 +Contact: Vivien Didelot +Description: The ThingM blink1 is an USB RGB LED. The color notation is + 3-byte hexadecimal. Read this attribute to get the last set + color. Write the 24-bit hexadecimal color to change the current + LED color. The default color is full white (0xFFFFFF). + For instance, set the color to green with: echo 00FF00 > rgb + +What: /sys/class/leds/blink1::/fade +Date: January 2013 +Contact: Vivien Didelot +Description: This attribute allows to set a fade time in milliseconds for + the next color change. Read the attribute to know the current + fade time. The default value is set to 0 (no fade time). For + instance, set a fade time of 2 seconds with: echo 2000 > fade + +What: /sys/class/leds/blink1::/play +Date: January 2013 +Contact: Vivien Didelot +Description: This attribute is used to play/pause the light patterns. Write 1 + to start playing, 0 to stop. Reading this attribute returns the + current playing status. diff --git a/MAINTAINERS b/MAINTAINERS index b0b880da6e5c..10a4a36dd534 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7306,6 +7306,11 @@ S: Supported F: drivers/thermal/ F: include/linux/thermal.h +THINGM BLINK(1) USB RGB LED DRIVER +M: Vivien Didelot +S: Maintained +F: drivers/hid/hid-thingm.c + THINKPAD ACPI EXTRAS DRIVER M: Henrique de Moraes Holschuh L: ibm-acpi-devel@lists.sourceforge.net diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index bf88eca3e868..3d5294531ba5 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -655,6 +655,16 @@ config HID_TOPSEED Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic CLLRCMCE remote control. +config HID_THINGM + tristate "ThingM blink(1) USB RGB LED" + depends on USB_HID + depends on LEDS_CLASS + ---help--- + Support for the ThingM blink(1) USB RGB LED. This driver registers a + Linux LED class instance, plus additional sysfs attributes to control + RGB colors, fade time and playing. The device is exposed through hidraw + to access other functions. + config HID_THRUSTMASTER tristate "ThrustMaster devices support" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index b62215716b2f..93017043f6f8 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -103,6 +103,7 @@ obj-$(CONFIG_HID_SONY) += hid-sony.o obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o +obj-$(CONFIG_HID_THINGM) += hid-thingm.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o obj-$(CONFIG_HID_TIVO) += hid-tivo.o obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bf44af35439b..5f7115eb9412 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1699,6 +1699,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 104105208596..eebbbf6f0a9a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -747,6 +747,9 @@ #define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 #define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 +#define USB_VENDOR_ID_THINGM 0x27b8 +#define USB_DEVICE_ID_BLINK1 0x01ed + #define USB_VENDOR_ID_THRUSTMASTER 0x044f #define USB_VENDOR_ID_TIVO 0x150a 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 @@ +/* + * ThingM blink(1) USB RGB LED driver + * + * Copyright 2013 Savoir-faire Linux Inc. + * Vivien Didelot + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + */ + +#include +#include +#include +#include + +#include "hid-ids.h" + +#define BLINK1_CMD_SIZE 9 + +#define blink1_rgb_to_r(rgb) ((rgb & 0xFF0000) >> 16) +#define blink1_rgb_to_g(rgb) ((rgb & 0x00FF00) >> 8) +#define blink1_rgb_to_b(rgb) ((rgb & 0x0000FF) >> 0) + +/** + * struct blink1_data - blink(1) device specific data + * @hdev: HID device. + * @led_cdev: LED class instance. + * @rgb: 8-bit per channel RGB notation. + * @fade: fade time in hundredths of a second. + * @brightness: brightness coefficient. + * @play: play/pause in-memory patterns. + */ +struct blink1_data { + struct hid_device *hdev; + struct led_classdev led_cdev; + u32 rgb; + u16 fade; + u8 brightness; + bool play; +}; + +static int blink1_send_command(struct blink1_data *data, + u8 buf[BLINK1_CMD_SIZE]) +{ + int ret; + + hid_dbg(data->hdev, "command: %d%c%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], + buf[5], buf[6], buf[7], buf[8]); + + ret = data->hdev->hid_output_raw_report(data->hdev, buf, + BLINK1_CMD_SIZE, HID_FEATURE_REPORT); + + return ret < 0 ? ret : 0; +} + +static int blink1_update_color(struct blink1_data *data) +{ + u8 buf[BLINK1_CMD_SIZE] = { 1, 'n', 0, 0, 0, 0, 0, 0, 0 }; + + if (data->brightness) { + unsigned int coef = DIV_ROUND_CLOSEST(255, data->brightness); + + buf[2] = DIV_ROUND_CLOSEST(blink1_rgb_to_r(data->rgb), coef); + buf[3] = DIV_ROUND_CLOSEST(blink1_rgb_to_g(data->rgb), coef); + buf[4] = DIV_ROUND_CLOSEST(blink1_rgb_to_b(data->rgb), coef); + } + + if (data->fade) { + buf[1] = 'c'; + buf[5] = (data->fade & 0xFF00) >> 8; + buf[6] = (data->fade & 0x00FF); + } + + return blink1_send_command(data, buf); +} + +static void blink1_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent); + + data->brightness = brightness; + if (blink1_update_color(data)) + hid_err(data->hdev, "failed to update color\n"); +} + +static enum led_brightness blink1_led_get(struct led_classdev *led_cdev) +{ + struct blink1_data *data = dev_get_drvdata(led_cdev->dev->parent); + + return data->brightness; +} + +static ssize_t blink1_show_rgb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct blink1_data *data = dev_get_drvdata(dev->parent); + + return sprintf(buf, "%.6X\n", data->rgb); +} + +static ssize_t blink1_store_rgb(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct blink1_data *data = dev_get_drvdata(dev->parent); + long unsigned int rgb; + int ret; + + ret = kstrtoul(buf, 16, &rgb); + if (ret) + return ret; + + /* RGB triplet notation is 24-bit hexadecimal */ + if (rgb > 0xFFFFFF) + return -EINVAL; + + data->rgb = rgb; + ret = blink1_update_color(data); + + return ret ? ret : count; +} + +static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR, blink1_show_rgb, blink1_store_rgb); + +static ssize_t blink1_show_fade(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct blink1_data *data = dev_get_drvdata(dev->parent); + + return sprintf(buf, "%d\n", data->fade * 10); +} + +static ssize_t blink1_store_fade(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct blink1_data *data = dev_get_drvdata(dev->parent); + long unsigned int fade; + int ret; + + ret = kstrtoul(buf, 10, &fade); + if (ret) + return ret; + + /* blink(1) accepts 16-bit fade time, number of 10ms ticks */ + fade = DIV_ROUND_CLOSEST(fade, 10); + if (fade > 65535) + return -EINVAL; + + data->fade = fade; + + return count; +} + +static DEVICE_ATTR(fade, S_IRUGO | S_IWUSR, + blink1_show_fade, blink1_store_fade); + +static ssize_t blink1_show_play(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct blink1_data *data = dev_get_drvdata(dev->parent); + + return sprintf(buf, "%d\n", data->play); +} + +static ssize_t blink1_store_play(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct blink1_data *data = dev_get_drvdata(dev->parent); + u8 cmd[BLINK1_CMD_SIZE] = { 1, 'p', 0, 0, 0, 0, 0, 0, 0 }; + long unsigned int play; + int ret; + + ret = kstrtoul(buf, 10, &play); + if (ret) + return ret; + + data->play = !!play; + cmd[2] = data->play; + ret = blink1_send_command(data, cmd); + + return ret ? ret : count; +} + +static DEVICE_ATTR(play, S_IRUGO | S_IWUSR, + blink1_show_play, blink1_store_play); + +static const struct attribute_group blink1_sysfs_group = { + .attrs = (struct attribute *[]) { + &dev_attr_rgb.attr, + &dev_attr_fade.attr, + &dev_attr_play.attr, + NULL + }, +}; + +static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct blink1_data *data; + struct led_classdev *led; + char led_name[13]; + int ret; + + data = devm_kzalloc(&hdev->dev, sizeof(struct blink1_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + hid_set_drvdata(hdev, data); + data->hdev = hdev; + data->rgb = 0xFFFFFF; /* set a default white color */ + + ret = hid_parse(hdev); + if (ret) + goto error; + + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); + if (ret) + goto error; + + /* blink(1) serial numbers range is 0x1A001000 to 0x1A002FFF */ + led = &data->led_cdev; + snprintf(led_name, sizeof(led_name), "blink1::%s", hdev->uniq + 4); + led->name = led_name; + led->brightness_set = blink1_led_set; + led->brightness_get = blink1_led_get; + ret = led_classdev_register(&hdev->dev, led); + if (ret) + goto stop; + + ret = sysfs_create_group(&led->dev->kobj, &blink1_sysfs_group); + if (ret) + goto remove_led; + + return 0; + +remove_led: + led_classdev_unregister(led); +stop: + hid_hw_stop(hdev); +error: + return ret; +} + +static void thingm_remove(struct hid_device *hdev) +{ + struct blink1_data *data = hid_get_drvdata(hdev); + struct led_classdev *led = &data->led_cdev; + + sysfs_remove_group(&led->dev->kobj, &blink1_sysfs_group); + led_classdev_unregister(led); + hid_hw_stop(hdev); +} + +static const struct hid_device_id thingm_table[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, + { } +}; +MODULE_DEVICE_TABLE(hid, thingm_table); + +static struct hid_driver thingm_driver = { + .name = "thingm", + .probe = thingm_probe, + .remove = thingm_remove, + .id_table = thingm_table, +}; + +module_hid_driver(thingm_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vivien Didelot "); +MODULE_DESCRIPTION("ThingM blink(1) USB RGB LED driver"); -- cgit v1.2.3 From 54bfe3f0dab2b2f0ac629690f187537d95adeb4f Mon Sep 17 00:00:00 2001 From: Paul Sbarra Date: Sun, 17 Feb 2013 11:53:13 -0600 Subject: HID: logitech: add report descriptor for Driving Force wheel This is the original report descriptor as reported by lsusb -vd 046d:c294. Signed-off-by: Paul Sbarra Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a2f8e88b9fa2..6daa1927bf69 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -21,8 +21,10 @@ #include #include #include +#include #include +#include "usbhid/usbhid.h" #include "hid-ids.h" #include "hid-lg.h" @@ -40,17 +42,83 @@ #define LG_FF3 0x1000 #define LG_FF4 0x2000 -/* Size of the original descriptor of the Driving Force Pro wheel */ +/* Size of the original descriptors of the Driving Force (and Pro) wheels */ +#define DF_RDESC_ORIG_SIZE 130 #define DFP_RDESC_ORIG_SIZE 97 -/* Fixed report descriptor for Logitech Driving Force Pro wheel controller +/* Fixed report descriptors for Logitech Driving Force (and Pro) + * wheel controllers * - * The original descriptor hides the separate throttle and brake axes in + * The original descriptors hide the separate throttle and brake axes in * a custom vendor usage page, providing only a combined value as * GenericDesktop.Y. - * This descriptor removes the combined Y axis and instead reports + * These descriptors remove the combined Y axis and instead report * separate throttle (Y) and brake (RZ). */ +static __u8 df_rdesc_fixed[] = { +0x05, 0x01, /* Usage Page (Desktop), */ +0x09, 0x04, /* Usage (Joystik), */ +0xA1, 0x01, /* Collection (Application), */ +0xA1, 0x02, /* Collection (Logical), */ +0x95, 0x01, /* Report Count (1), */ +0x75, 0x0A, /* Report Size (10), */ +0x14, /* Logical Minimum (0), */ +0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ +0x34, /* Physical Minimum (0), */ +0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ +0x09, 0x30, /* Usage (X), */ +0x81, 0x02, /* Input (Variable), */ +0x95, 0x0C, /* Report Count (12), */ +0x75, 0x01, /* Report Size (1), */ +0x25, 0x01, /* Logical Maximum (1), */ +0x45, 0x01, /* Physical Maximum (1), */ +0x05, 0x09, /* Usage (Buttons), */ +0x19, 0x01, /* Usage Minimum (1), */ +0x29, 0x0c, /* Usage Maximum (12), */ +0x81, 0x02, /* Input (Variable), */ +0x95, 0x02, /* Report Count (2), */ +0x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */ +0x09, 0x01, /* Usage (?: 1), */ +0x81, 0x02, /* Input (Variable), */ +0x05, 0x01, /* Usage Page (Desktop), */ +0x09, 0x31, /* Usage (Y), */ +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ +0x95, 0x01, /* Report Count (1), */ +0x75, 0x08, /* Report Size (8), */ +0x81, 0x02, /* Input (Variable), */ +0x25, 0x07, /* Logical Maximum (7), */ +0x46, 0x3B, 0x01, /* Physical Maximum (315), */ +0x75, 0x04, /* Report Size (4), */ +0x65, 0x14, /* Unit (Degrees), */ +0x09, 0x39, /* Usage (Hat Switch), */ +0x81, 0x42, /* Input (Variable, Null State), */ +0x75, 0x01, /* Report Size (1), */ +0x95, 0x04, /* Report Count (4), */ +0x65, 0x00, /* Unit (none), */ +0x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */ +0x09, 0x01, /* Usage (?: 1), */ +0x25, 0x01, /* Logical Maximum (1), */ +0x45, 0x01, /* Physical Maximum (1), */ +0x81, 0x02, /* Input (Variable), */ +0x95, 0x02, /* Report Count (2), */ +0x75, 0x08, /* Report Size (8), */ +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ +0x09, 0x02, /* Usage (?: 2), */ +0x81, 0x02, /* Input (Variable), */ +0xC0, /* End Collection, */ +0xA1, 0x02, /* Collection (Logical), */ +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ +0x95, 0x07, /* Report Count (7), */ +0x75, 0x08, /* Report Size (8), */ +0x09, 0x03, /* Usage (?: 3), */ +0x91, 0x02, /* Output (Variable), */ +0xC0, /* End Collection, */ +0xC0 /* End Collection */ +}; + static __u8 dfp_rdesc_fixed[] = { 0x05, 0x01, /* Usage Page (Desktop), */ 0x09, 0x04, /* Usage (Joystik), */ @@ -99,7 +167,6 @@ static __u8 dfp_rdesc_fixed[] = { 0xC0 /* End Collection */ }; - /* * Certain Logitech keyboards send in report #3 keys which are far * above the logical maximum described in descriptor. This extends @@ -109,6 +176,8 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { struct lg_drv_data *drv_data = hid_get_drvdata(hdev); + struct usb_device_descriptor *udesc; + __u16 bcdDevice, rev_maj, rev_min; if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && rdesc[84] == 0x8c && rdesc[85] == 0x02) { @@ -135,6 +204,28 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, } switch (hdev->product) { + + /* Several wheels report as this id when operating in emulation mode. */ + case USB_DEVICE_ID_LOGITECH_WHEEL: + udesc = &(hid_to_usb_dev(hdev)->descriptor); + if (!udesc) { + hid_err(hdev, "NULL USB device descriptor\n"); + break; + } + bcdDevice = le16_to_cpu(udesc->bcdDevice); + rev_maj = bcdDevice >> 8; + rev_min = bcdDevice & 0xff; + + /* Update the report descriptor for only the Driving Force wheel */ + if (rev_maj == 1 && rev_min == 2 && + *rsize == DF_RDESC_ORIG_SIZE) { + hid_info(hdev, + "fixing up Logitech Driving Force report descriptor\n"); + rdesc = df_rdesc_fixed; + *rsize = sizeof(df_rdesc_fixed); + } + break; + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: if (*rsize == DFP_RDESC_ORIG_SIZE) { hid_info(hdev, -- cgit v1.2.3 From 5a9b571bacafffaff75f4f523c4479c85e83cb15 Mon Sep 17 00:00:00 2001 From: Paul Sbarra Date: Sun, 17 Feb 2013 11:53:14 -0600 Subject: HID: logitech: split accel, brake for Driving Force wheel Signed-off-by: Paul Sbarra Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 6daa1927bf69..6bb7f059941a 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -81,7 +81,6 @@ static __u8 df_rdesc_fixed[] = { 0x09, 0x01, /* Usage (?: 1), */ 0x81, 0x02, /* Input (Variable), */ 0x05, 0x01, /* Usage Page (Desktop), */ -0x09, 0x31, /* Usage (Y), */ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 0x95, 0x01, /* Report Count (1), */ @@ -101,11 +100,14 @@ static __u8 df_rdesc_fixed[] = { 0x25, 0x01, /* Logical Maximum (1), */ 0x45, 0x01, /* Physical Maximum (1), */ 0x81, 0x02, /* Input (Variable), */ -0x95, 0x02, /* Report Count (2), */ +0x05, 0x01, /* Usage Page (Desktop), */ +0x95, 0x01, /* Report Count (1), */ 0x75, 0x08, /* Report Size (8), */ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ -0x09, 0x02, /* Usage (?: 2), */ +0x09, 0x31, /* Usage (Y), */ +0x81, 0x02, /* Input (Variable), */ +0x09, 0x35, /* Usage (Rz), */ 0x81, 0x02, /* Input (Variable), */ 0xC0, /* End Collection, */ 0xA1, 0x02, /* Collection (Logical), */ -- cgit v1.2.3 From 270baef1fafab50410e0e395ec26834de2dcc390 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Tue, 19 Feb 2013 20:25:10 -0700 Subject: HID: LG: Add support for Logitech Momo Force (Red) Wheel This patch provides a modified report descriptor to split accelerator and brake, and adds the 'NO_GET' flag to prevent it hanging on connection. Note: for convience this patch is against the follow patch which was applied earlier this week. https://patchwork.kernel.org/patch/2153471/ Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 6bb7f059941a..160c48919081 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -45,6 +45,7 @@ /* Size of the original descriptors of the Driving Force (and Pro) wheels */ #define DF_RDESC_ORIG_SIZE 130 #define DFP_RDESC_ORIG_SIZE 97 +#define MOMO_RDESC_ORIG_SIZE 87 /* Fixed report descriptors for Logitech Driving Force (and Pro) * wheel controllers @@ -169,6 +170,52 @@ static __u8 dfp_rdesc_fixed[] = { 0xC0 /* End Collection */ }; +static __u8 momo_rdesc_fixed[] = { +0x05, 0x01, /* Usage Page (Desktop), */ +0x09, 0x04, /* Usage (Joystik), */ +0xA1, 0x01, /* Collection (Application), */ +0xA1, 0x02, /* Collection (Logical), */ +0x95, 0x01, /* Report Count (1), */ +0x75, 0x0A, /* Report Size (10), */ +0x15, 0x00, /* Logical Minimum (0), */ +0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ +0x35, 0x00, /* Physical Minimum (0), */ +0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ +0x09, 0x30, /* Usage (X), */ +0x81, 0x02, /* Input (Variable), */ +0x95, 0x08, /* Report Count (8), */ +0x75, 0x01, /* Report Size (1), */ +0x25, 0x01, /* Logical Maximum (1), */ +0x45, 0x01, /* Physical Maximum (1), */ +0x05, 0x09, /* Usage Page (Button), */ +0x19, 0x01, /* Usage Minimum (01h), */ +0x29, 0x08, /* Usage Maximum (08h), */ +0x81, 0x02, /* Input (Variable), */ +0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ +0x75, 0x0E, /* Report Size (14), */ +0x95, 0x01, /* Report Count (1), */ +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ +0x09, 0x00, /* Usage (00h), */ +0x81, 0x02, /* Input (Variable), */ +0x05, 0x01, /* Usage Page (Desktop), */ +0x75, 0x08, /* Report Size (8), */ +0x09, 0x31, /* Usage (Y), */ +0x81, 0x02, /* Input (Variable), */ +0x09, 0x32, /* Usage (Z), */ +0x81, 0x02, /* Input (Variable), */ +0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ +0x09, 0x01, /* Usage (01h), */ +0x81, 0x02, /* Input (Variable), */ +0xC0, /* End Collection, */ +0xA1, 0x02, /* Collection (Logical), */ +0x09, 0x02, /* Usage (02h), */ +0x95, 0x07, /* Report Count (7), */ +0x91, 0x02, /* Output (Variable), */ +0xC0, /* End Collection, */ +0xC0 /* End Collection */ +}; + /* * Certain Logitech keyboards send in report #3 keys which are far * above the logical maximum described in descriptor. This extends @@ -228,6 +275,15 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, } break; + case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: + if (*rsize == MOMO_RDESC_ORIG_SIZE) { + hid_info(hdev, + "fixing up Logitech Momo Force (Red) report descriptor\n"); + rdesc = momo_rdesc_fixed; + *rsize = sizeof(momo_rdesc_fixed); + } + break; + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: if (*rsize == DFP_RDESC_ORIG_SIZE) { hid_info(hdev, @@ -558,7 +614,7 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), - .driver_data = LG_FF4 }, + .driver_data = LG_NOGET | LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), -- cgit v1.2.3 From b5836246c127ce1f0afe9790537b94c71efd2d2a Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Tue, 19 Feb 2013 20:25:11 -0700 Subject: HID: LG: Fix detection of Logitech Speed Force Wireless (WiiWheel) Previously 'LG4FF' was only used for the WiiWheel, however it is now used for all the Logitech Wheels. This patch corrects the detection mechanism for the patching the report descriptor to ensure only the WiiWheel will be patched. Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 160c48919081..c06559803fd8 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -242,15 +242,6 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, "fixing up rel/abs in Logitech report descriptor\n"); rdesc[33] = rdesc[50] = 0x02; } - if ((drv_data->quirks & LG_FF4) && *rsize >= 101 && - rdesc[41] == 0x95 && rdesc[42] == 0x0B && - rdesc[47] == 0x05 && rdesc[48] == 0x09) { - hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n"); - rdesc[41] = 0x05; - rdesc[42] = 0x09; - rdesc[47] = 0x95; - rdesc[48] = 0x0B; - } switch (hdev->product) { @@ -292,6 +283,17 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, *rsize = sizeof(dfp_rdesc_fixed); } break; + + case USB_DEVICE_ID_LOGITECH_WII_WHEEL: + if (*rsize >= 101 && rdesc[41] == 0x95 && rdesc[42] == 0x0B && + rdesc[47] == 0x05 && rdesc[48] == 0x09) { + hid_info(hdev, "fixing up Logitech Speed Force Wireless report descriptor\n"); + rdesc[41] = 0x05; + rdesc[42] = 0x09; + rdesc[47] = 0x95; + rdesc[48] = 0x0B; + } + break; } return rdesc; -- cgit v1.2.3 From 94b3f712fe2cd5c33d57ca0ab9604d2402bc72cd Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Tue, 19 Feb 2013 20:25:12 -0700 Subject: HID: LG: Prevent the Logitech Gaming Wheels deadzone This patch ensures that the Logitech wheels are not initialised with default fuzz/flat values, by marking them as multiaxis devices (rather than joysticks). Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index c06559803fd8..5d3c861e2c5b 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -479,6 +479,26 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, usage->type == EV_REL || usage->type == EV_ABS)) clear_bit(usage->code, *bit); + /* Ensure that Logitech wheels are not given a default fuzz/flat value */ + if (usage->type == EV_ABS && (usage->code == ABS_X || + usage->code == ABS_Y || usage->code == ABS_Z || + usage->code == ABS_RZ)) { + switch (hdev->product) { + case USB_DEVICE_ID_LOGITECH_WHEEL: + case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: + case USB_DEVICE_ID_LOGITECH_G25_WHEEL: + case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: + case USB_DEVICE_ID_LOGITECH_G27_WHEEL: + case USB_DEVICE_ID_LOGITECH_WII_WHEEL: + case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2: + field->application = HID_GD_MULTIAXIS; + break; + default: + break; + } + } + return 0; } -- cgit v1.2.3 From d50bbd008ac3ead5eb8990fac1908c4a53e7a164 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Tue, 19 Feb 2013 20:25:13 -0700 Subject: HID: LG4FF: Remove unnecessary deadzone code This patch removes code which is now unnecessary for setting the fuzz/flat characterics for the logitech DFP wheel. This is now done in the previous patch by marking the wheel as a multi-axis device. Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-lg4ff.c | 17 ----------------- 1 file changed, 17 deletions(-) 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 @@ #define G27_REV_MAJ 0x12 #define G27_REV_MIN 0x38 -#define DFP_X_MIN 0 -#define DFP_X_MAX 16383 -#define DFP_PEDAL_MIN 0 -#define DFP_PEDAL_MAX 255 - #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); @@ -598,18 +593,6 @@ int lg4ff_init(struct hid_device *hid) return error; dbg_hid("sysfs interface created\n"); - /* Set default axes parameters */ - switch (lg4ff_devices[i].product_id) { - case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: - dbg_hid("Setting axes parameters for Driving Force Pro\n"); - input_set_abs_params(dev, ABS_X, DFP_X_MIN, DFP_X_MAX, 0, 0); - input_set_abs_params(dev, ABS_Y, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0); - input_set_abs_params(dev, ABS_RZ, DFP_PEDAL_MIN, DFP_PEDAL_MAX, 0, 0); - break; - default: - break; - } - /* Set the maximum range to start with */ entry->range = entry->max_range; if (entry->set_range != NULL) -- cgit v1.2.3 From 483f86a54c6d89f16da2e53f2b7b6205b34756df Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Tue, 19 Feb 2013 20:25:14 -0700 Subject: HID: Correct Logitech order in hid-ids.h Reorders a couple of device IDs (Logitech controllers) to ensure that they are in hexidecimal order. Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 34e25471aeaa..865492c8b0e0 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -525,8 +525,8 @@ #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 -#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 +#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 -- cgit v1.2.3