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