Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: HID: Steelseries SRW-S1 Add support for dials

This patch to the SRW-S1 driver re-writes the HID descriptor
to insert a section for the 3 dials on the device, previously
these were contained within a 'Manufacturer Specific' usage
page.

Signed-off-by: Simon Wood <simon@mungewell.org>
Tested-by: John Murphy <rosegardener@freeode.co.uk>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Simon Wood and committed by
Jiri Kosina
5492606d 75dbb953

+82 -4
+82 -4
drivers/hid/hid-steelseries-srws1.c
··· 17 17 18 18 #include "hid-ids.h" 19 19 20 + /* Fixed report descriptor for Steelseries SRW-S1 wheel controller 21 + * 22 + * The original descriptor hides the sensitivity and assists dials 23 + * a custom vendor usage page. This inserts a patch to make them 24 + * appear in the 'Generic Desktop' usage. 25 + */ 26 + 27 + static __u8 steelseries_srws1_rdesc_fixed[] = { 28 + 0x05, 0x01, /* Usage Page (Desktop) */ 29 + 0x09, 0x08, /* Usage (MultiAxis), Changed */ 30 + 0xA1, 0x01, /* Collection (Application), */ 31 + 0xA1, 0x02, /* Collection (Logical), */ 32 + 0x95, 0x01, /* Report Count (1), */ 33 + 0x05, 0x01, /* Changed Usage Page (Desktop), */ 34 + 0x09, 0x30, /* Changed Usage (X), */ 35 + 0x16, 0xF8, 0xF8, /* Logical Minimum (-1800), */ 36 + 0x26, 0x08, 0x07, /* Logical Maximum (1800), */ 37 + 0x65, 0x14, /* Unit (Degrees), */ 38 + 0x55, 0x0F, /* Unit Exponent (15), */ 39 + 0x75, 0x10, /* Report Size (16), */ 40 + 0x81, 0x02, /* Input (Variable), */ 41 + 0x09, 0x31, /* Changed Usage (Y), */ 42 + 0x15, 0x00, /* Logical Minimum (0), */ 43 + 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 44 + 0x75, 0x0C, /* Report Size (12), */ 45 + 0x81, 0x02, /* Input (Variable), */ 46 + 0x09, 0x32, /* Changed Usage (Z), */ 47 + 0x15, 0x00, /* Logical Minimum (0), */ 48 + 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 49 + 0x75, 0x0C, /* Report Size (12), */ 50 + 0x81, 0x02, /* Input (Variable), */ 51 + 0x05, 0x01, /* Usage Page (Desktop), */ 52 + 0x09, 0x39, /* Usage (Hat Switch), */ 53 + 0x25, 0x07, /* Logical Maximum (7), */ 54 + 0x35, 0x00, /* Physical Minimum (0), */ 55 + 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ 56 + 0x65, 0x14, /* Unit (Degrees), */ 57 + 0x75, 0x04, /* Report Size (4), */ 58 + 0x95, 0x01, /* Report Count (1), */ 59 + 0x81, 0x02, /* Input (Variable), */ 60 + 0x25, 0x01, /* Logical Maximum (1), */ 61 + 0x45, 0x01, /* Physical Maximum (1), */ 62 + 0x65, 0x00, /* Unit, */ 63 + 0x75, 0x01, /* Report Size (1), */ 64 + 0x95, 0x03, /* Report Count (3), */ 65 + 0x81, 0x01, /* Input (Constant), */ 66 + 0x05, 0x09, /* Usage Page (Button), */ 67 + 0x19, 0x01, /* Usage Minimum (01h), */ 68 + 0x29, 0x11, /* Usage Maximum (11h), */ 69 + 0x95, 0x11, /* Report Count (17), */ 70 + 0x81, 0x02, /* Input (Variable), */ 71 + /* ---- Dial patch starts here ---- */ 72 + 0x05, 0x01, /* Usage Page (Desktop), */ 73 + 0x09, 0x33, /* Usage (RX), */ 74 + 0x75, 0x04, /* Report Size (4), */ 75 + 0x95, 0x02, /* Report Count (2), */ 76 + 0x15, 0x00, /* Logical Minimum (0), */ 77 + 0x25, 0x0b, /* Logical Maximum (b), */ 78 + 0x81, 0x02, /* Input (Variable), */ 79 + 0x09, 0x35, /* Usage (RZ), */ 80 + 0x75, 0x04, /* Report Size (4), */ 81 + 0x95, 0x01, /* Report Count (1), */ 82 + 0x25, 0x03, /* Logical Maximum (3), */ 83 + 0x81, 0x02, /* Input (Variable), */ 84 + /* ---- Dial patch ends here ---- */ 85 + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 86 + 0x09, 0x01, /* Usage (01h), */ 87 + 0x75, 0x04, /* Changed Report Size (4), */ 88 + 0x95, 0x0D, /* Changed Report Count (13), */ 89 + 0x81, 0x02, /* Input (Variable), */ 90 + 0xC0, /* End Collection, */ 91 + 0xA1, 0x02, /* Collection (Logical), */ 92 + 0x09, 0x02, /* Usage (02h), */ 93 + 0x75, 0x08, /* Report Size (8), */ 94 + 0x95, 0x10, /* Report Count (16), */ 95 + 0x91, 0x02, /* Output (Variable), */ 96 + 0xC0, /* End Collection, */ 97 + 0xC0 /* End Collection */ 98 + }; 99 + 20 100 static __u8 *steelseries_srws1_report_fixup(struct hid_device *hdev, __u8 *rdesc, 21 101 unsigned int *rsize) 22 102 { 23 103 if (*rsize >= 115 && rdesc[11] == 0x02 && rdesc[13] == 0xc8 24 104 && rdesc[29] == 0xbb && rdesc[40] == 0xc5) { 25 105 hid_info(hdev, "Fixing up Steelseries SRW-S1 report descriptor\n"); 26 - rdesc[11] = 0x01; 27 - rdesc[13] = 0x30; 28 - rdesc[29] = 0x31; 29 - rdesc[40] = 0x32; 106 + rdesc = steelseries_srws1_rdesc_fixed; 107 + *rsize = sizeof(steelseries_srws1_rdesc_fixed); 30 108 } 31 109 return rdesc; 32 110 }