From 1989dada7ce07848196991c9ebf25ff9c5f14d4e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 13 Sep 2016 11:52:37 +0200 Subject: HID: input: ignore System Control application usages if not System Controls Microsoft is reusing its report descriptor again and again, and part of it looks like this: 0x05, 0x01, // Usage Page (Generic Desktop) 299 0x09, 0x80, // Usage (System Control) 301 0xa1, 0x01, // Collection (Application) 303 0x85, 0x03, // Report ID (3) 305 0x19, 0x00, // Usage Minimum (0) 307 0x29, 0xff, // Usage Maximum (255) 309 0x15, 0x00, // Logical Minimum (0) 311 0x26, 0xff, 0x00, // Logical Maximum (255) 313 0x81, 0x00, // Input (Data,Arr,Abs) 316 0xc0, // End Collection 318 While there is nothing wrong in term of processing, we do however blindly map the full usage range (it's an array) from 0x00 to 0xff, which creates some interesting axis, like ABS_X|Y, and a bunch of ABS_MISC + n. While libinput and other stacks don't care that much (we can detect them), joydev is very happy and attaches itself to the mouse or keyboard. The problem is that joydev now handles the device as a joystick, but given that we have a HID array, it sets all the ABS_* values to 0. And in its world, 0 means -32767 (minimum value), which sends spurious events to games (think Steam). It looks like hid-microsoft tries to tackle the very same problem with its .report_fixup callback. But fixing the report descriptor is an endless task and is quite obfuscated. So take the hammer, and decide that if the application is meant to be System Control, any other usage not in the System Control range should be ignored. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1325354 Link: https://bugzilla.kernel.org/show_bug.cgi?id=28912 Link: https://github.com/ValveSoftware/steam-for-linux/issues/3384 Link: https://bugzilla.redhat.com/show_bug.cgi?id=1325354 Link: https://bugzilla.kernel.org/show_bug.cgi?id=37982 Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/hid') diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index bcfaf32d9e5e..058919d5b2bb 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -604,6 +604,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; } + /* + * Some lazy vendors declare 255 usages for System Control, + * leading to the creation of ABS_X|Y axis and too many others. + * It wouldn't be a problem if joydev doesn't consider the + * device as a joystick then. + */ + if (field->application == HID_GD_SYSTEM_CONTROL) + goto ignore; + if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ switch (usage->hid) { case HID_GD_UP: usage->hat_dir = 1; break; -- cgit v1.2.3