HID: Sunplus Wireless Desktop needs report descriptor fixup
Jiri Kosina [Fri, 14 Mar 2008 15:53:07 +0000 (16:53 +0100)]
This device has reports lower logical maximum compared to the real
usages for Zoom+ and Zoom- it emits.

This patch bumps the values in the report descriptor up, and also
adjusts HID_MAX_USAGE accordingly.

Reported-by: Khelben Blackstaff <eye.of.the.8eholder@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

drivers/hid/hid-input-quirks.c
drivers/hid/usbhid/hid-quirks.c
include/linux/hid.h

index dceadd0..845d31d 100644 (file)
@@ -276,6 +276,21 @@ static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
        return 1;
 }
 
+static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *input,
+                             unsigned long **bit, int *max)
+{
+       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
+               return 0;
+
+       switch (usage->hid & HID_USAGE) {
+               case 0x2003: map_key_clear(KEY_ZOOMIN);         break;
+               case 0x2103: map_key_clear(KEY_ZOOMOUT);        break;
+               default:
+                       return 0;
+       }
+       return 1;
+}
+
 #define VENDOR_ID_BELKIN                       0x1020
 #define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD     0x0006
 
@@ -306,6 +321,9 @@ static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
 #define VENDOR_ID_PETALYNX                     0x18b1
 #define DEVICE_ID_PETALYNX_MAXTER_REMOTE       0x0037
 
+#define VENDOR_ID_SUNPLUS                      0x04fc
+#define DEVICE_ID_SUNPLUS_WDESKTOP             0x05d8
+
 static const struct hid_input_blacklist {
        __u16 idVendor;
        __u16 idProduct;
@@ -332,7 +350,9 @@ static const struct hid_input_blacklist {
        { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e },
 
        { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote },
-       
+
+       { VENDOR_ID_SUNPLUS, DEVICE_ID_SUNPLUS_WDESKTOP, quirk_sunplus_wdesktop },
+
        { 0, 0, 0 }
 };
 
index 81dc5e3..f063565 100644 (file)
 #define USB_VENDOR_ID_SUN              0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE       0xcdab
 
+#define USB_VENDOR_ID_SUNPLUS          0x04fc
+#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
+
 #define USB_VENDOR_ID_TOPMAX           0x0663
 #define USB_DEVICE_ID_TOPMAX_COBRAPAD  0x0103
 
@@ -735,6 +738,8 @@ static const struct hid_rdesc_blacklist {
 
        { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE },
 
+       { USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP, HID_QUIRK_RDESC_SUNPLUS_WDESKTOP },
+
        { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
        { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
 
@@ -1009,6 +1014,17 @@ static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
        }
 }
 
+static void usbhid_fixup_sunplus_wdesktop(unsigned char *rdesc, int rsize)
+{
+       if (rsize >= 107 && rdesc[104] == 0x26
+                        && rdesc[105] == 0x80
+                        && rdesc[106] == 0x03) {
+               printk(KERN_INFO "Fixing up Sunplus Wireless Desktop report descriptor\n");
+               rdesc[105] = rdesc[110] = 0x03;
+               rdesc[106] = rdesc[111] = 0x21;
+       }
+}
+
 /*
  * Samsung IrDA remote controller (reports as Cypress USB Mouse).
  *
@@ -1182,4 +1198,7 @@ void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct,
                        __usbhid_fixup_report_descriptor(quirks, rdesc, rsize);
        }
 
+       if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP)
+               usbhid_fixup_sunplus_wdesktop(rdesc, rsize);
+
 }
index e9701f2..5bf6282 100644 (file)
@@ -298,6 +298,7 @@ struct hid_item {
 #define HID_QUIRK_RDESC_BUTTON_CONSUMER                0x00000020
 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE         0x00000040
 #define HID_QUIRK_RDESC_MICROSOFT_RECV_1028    0x00000080
+#define HID_QUIRK_RDESC_SUNPLUS_WDESKTOP       0x00000100
 
 /*
  * This is the global environment of the parser. This information is
@@ -322,7 +323,7 @@ struct hid_global {
  * This is the local environment. It is persistent up the next main-item.
  */
 
-#define HID_MAX_USAGES                 8192
+#define HID_MAX_USAGES                 12288
 #define HID_DEFAULT_NUM_COLLECTIONS    16
 
 struct hid_local {