Skip to contentSkip to conversation

Get Shuttle PN31 remote controls to work

PATCH New Bernhard Rosenkraenzer 1 participant 1 message May 30, 2005 USB

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Get Shuttle PN31 remote controls to work

Shuttle PN31 remote controls are supposed to act as a USB keyboard and mouse -- this worked fine for older revisions of the remote control, started becoming harder with some interim revisions, and in the latest revision, the protocol the device speaks is diverging really far from the standard.

As usual, they didn't even change the USB ID or revision number when introducing more breakages -- the current revision needs 5 quirks, 2 of which are unique to this device so far (it sets a superfluous extra bit on the GenericDesktop keycodes, and the mouse flags are wrong (_Constant_, Variable, Relative).

The attached patch makes it work.

LLaP
bero

drivers/usb/input/hid-core.c renamed from drivers/usb/input/hid-core.c.pn31~ +5 -0
@@ -1423,6 +1423,9 @@
  * Alphabetically sorted blacklist by quirk type.
  */
 
+#define USB_VENDOR_ID_SHUTTLE_REMOTE	0x4572
+#define USB_DEVICE_ID_SHUTTLE_PN31	0x4572
+
 static struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
@@ -1516,6 +1519,8 @@
 	{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
 
+	{ USB_VENDOR_ID_SHUTTLE_REMOTE, USB_DEVICE_ID_SHUTTLE_PN31, HID_QUIRK_BAD_LOGICAL_RANGE | HID_QUIRK_HIDDEV | HID_QUIRK_MULTI_INPUT | HID_QUIRK_WRONG_CONSTANT | HID_QUIRK_GENDESK_EXTRA_BIT },
+
 	{ 0, 0 }
 };
 
drivers/usb/input/hid-input.c renamed from drivers/usb/input/hid-input.c.pn31~ +15 -4
@@ -88,7 +88,7 @@
 	printk(" ---> ");
 #endif
 
-	if (field->flags & HID_MAIN_ITEM_CONSTANT)
+	if ((field->flags & HID_MAIN_ITEM_CONSTANT) && !(device->quirks & HID_QUIRK_WRONG_CONSTANT))
 		goto ignore;
 
 	switch (usage->hid & HID_USAGE_PAGE) {
@@ -158,16 +158,21 @@
 				break;
 			}
 
-			switch (usage->hid) {
+			if (device->quirks & HID_QUIRK_GENDESK_EXTRA_BIT)
+				code = usage->hid & 0xfff9ffff;
+			else
+				code = usage->hid;
+
+			switch (code) {
 
 				/* These usage IDs map directly to the usage codes. */
 				case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
 				case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
 				case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
 					if (field->flags & HID_MAIN_ITEM_RELATIVE)
-						map_rel(usage->hid & 0xf);
+						map_rel(code & 0xf);
 					else
-						map_abs(usage->hid & 0xf);
+						map_abs(code & 0xf);
 					break;
 
 				case HID_GD_HATSWITCH:
@@ -342,6 +347,12 @@
 
 	set_bit(usage->type, input->evbit);
 
+	if ((usage->type == EV_REL) &&
+		(device->quirks & HID_QUIRK_BAD_LOGICAL_RANGE) && (field->logical_minimum == field->logical_maximum)) {
+		field->logical_minimum = -127;
+		field->logical_maximum = 127;
+	}
+
 	while (usage->code <= max && test_and_set_bit(usage->code, bit))
 		usage->code = find_next_zero_bit(bit, max + 1, usage->code);
 
drivers/usb/input/hid.h renamed from drivers/usb/input/hid.h.pn31~ +13 -10
@@ -232,16 +232,19 @@
  * HID device quirks.
  */
 
-#define HID_QUIRK_INVERT			0x001
-#define HID_QUIRK_NOTOUCH			0x002
-#define HID_QUIRK_IGNORE			0x004
-#define HID_QUIRK_NOGET				0x008
-#define HID_QUIRK_HIDDEV			0x010
-#define HID_QUIRK_BADPAD			0x020
-#define HID_QUIRK_MULTI_INPUT			0x040
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_7		0x080
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_5		0x100
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON		0x200
+#define HID_QUIRK_INVERT			0x0001
+#define HID_QUIRK_NOTOUCH			0x0002
+#define HID_QUIRK_IGNORE			0x0004
+#define HID_QUIRK_NOGET				0x0008
+#define HID_QUIRK_HIDDEV			0x0010
+#define HID_QUIRK_BADPAD			0x0020
+#define HID_QUIRK_MULTI_INPUT			0x0040
+#define HID_QUIRK_2WHEEL_MOUSE_HACK_7		0x0080
+#define HID_QUIRK_2WHEEL_MOUSE_HACK_5		0x0100
+#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON		0x0200
+#define HID_QUIRK_BAD_LOGICAL_RANGE		0x0400
+#define HID_QUIRK_WRONG_CONSTANT		0x0800
+#define HID_QUIRK_GENDESK_EXTRA_BIT		0x1000
 
 /*
  * This is the global environment of the parser. This information is