diff options
author | Jim Duchek <jim.duchek@gmail.com> | 2008-03-14 10:53:49 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-04-22 05:34:57 -0400 |
commit | 974faac46455076c709a745f546b348017ad18dc (patch) | |
tree | 8c1297b5025b3af54308176870adfe561ea2f422 | |
parent | f345c37c37641beceb0e52f61bb4cbc72904ee09 (diff) |
HID: quirk for MS Wireless Desktop Receiver (model 1028)
Microsoft's wireless desktop receiver (Model 1028) has a bug in the report
descriptor -- namely, in four seperate places it uses USAGE_MIN and _MAX when
it quite obviously doesn't intend to.
In other words, it reports that it has pretty much _everything_ in 'consumer'
and 'generic desktop'. And then the X evdev driver believes I have a mouse
with 36 absolute axes and a huge pile of keys and buttons, when I in fact,
should have zero. 255/256 in three of the cases, and 0-1024 in another.
This patch fixes the report descriptor of this device before it enters the HID
parser.
Signed-off-by: Jim Duchek <jim.duchek@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 26 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
2 files changed, 27 insertions, 0 deletions
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 54b8f8311f94..81dc5e353dd8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -335,6 +335,7 @@ | |||
335 | #define USB_VENDOR_ID_MICROSOFT 0x045e | 335 | #define USB_VENDOR_ID_MICROSOFT 0x045e |
336 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 336 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
337 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | 337 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d |
338 | #define USB_DEVICE_ID_DESKTOP_RECV_1028 0x00f9 | ||
338 | #define USB_DEVICE_ID_MS_NE4K 0x00db | 339 | #define USB_DEVICE_ID_MS_NE4K 0x00db |
339 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | 340 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 |
340 | 341 | ||
@@ -724,6 +725,7 @@ static const struct hid_rdesc_blacklist { | |||
724 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, | 725 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, |
725 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, | 726 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, |
726 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, | 727 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, |
728 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_DESKTOP_RECV_1028, HID_QUIRK_RDESC_MICROSOFT_RECV_1028 }, | ||
727 | 729 | ||
728 | { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, | 730 | { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, |
729 | 731 | ||
@@ -1094,6 +1096,28 @@ static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rs | |||
1094 | } | 1096 | } |
1095 | } | 1097 | } |
1096 | 1098 | ||
1099 | /* | ||
1100 | * Microsoft Wireless Desktop Receiver (Model 1028) has several | ||
1101 | * 'Usage Min/Max' where it ought to have 'Physical Min/Max' | ||
1102 | */ | ||
1103 | static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize) | ||
1104 | { | ||
1105 | if (rsize == 571 && rdesc[284] == 0x19 | ||
1106 | && rdesc[286] == 0x2a | ||
1107 | && rdesc[304] == 0x19 | ||
1108 | && rdesc[306] == 0x29 | ||
1109 | && rdesc[352] == 0x1a | ||
1110 | && rdesc[355] == 0x2a | ||
1111 | && rdesc[557] == 0x19 | ||
1112 | && rdesc[559] == 0x29) { | ||
1113 | printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); | ||
1114 | rdesc[284] = rdesc[304] = rdesc[558] = 0x35; | ||
1115 | rdesc[352] = 0x36; | ||
1116 | rdesc[286] = rdesc[355] = 0x46; | ||
1117 | rdesc[306] = rdesc[559] = 0x45; | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1097 | static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) | 1121 | static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) |
1098 | { | 1122 | { |
1099 | if ((quirks & HID_QUIRK_RDESC_CYMOTION)) | 1123 | if ((quirks & HID_QUIRK_RDESC_CYMOTION)) |
@@ -1117,6 +1141,8 @@ static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned | |||
1117 | if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) | 1141 | if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) |
1118 | usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); | 1142 | usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); |
1119 | 1143 | ||
1144 | if (quirks & HID_QUIRK_RDESC_MICROSOFT_RECV_1028) | ||
1145 | usbhid_fixup_microsoft_descriptor(rdesc, rsize); | ||
1120 | } | 1146 | } |
1121 | 1147 | ||
1122 | /** | 1148 | /** |
diff --git a/include/linux/hid.h b/include/linux/hid.h index af1f7e57a12d..e9701f22d423 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -297,6 +297,7 @@ struct hid_item { | |||
297 | #define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 | 297 | #define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 |
298 | #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 | 298 | #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 |
299 | #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 | 299 | #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 |
300 | #define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080 | ||
300 | 301 | ||
301 | /* | 302 | /* |
302 | * This is the global environment of the parser. This information is | 303 | * This is the global environment of the parser. This information is |