|
@@ -1450,6 +1450,9 @@ void hid_init_reports(struct hid_device *hid)
|
|
|
#define USB_VENDOR_ID_APPLE 0x05ac
|
|
|
#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304
|
|
|
|
|
|
+#define USB_VENDOR_ID_CHERRY 0x046a
|
|
|
+#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
|
|
|
+
|
|
|
/*
|
|
|
* Alphabetically sorted blacklist by quirk type.
|
|
|
*/
|
|
@@ -1580,6 +1583,8 @@ static const struct hid_blacklist {
|
|
|
{ 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_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
|
|
|
+
|
|
|
{ 0, 0 }
|
|
|
};
|
|
|
|
|
@@ -1626,6 +1631,20 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
|
|
|
usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Cherry Cymotion keyboard have an invalid HID report descriptor,
|
|
|
+ * that needs fixing before we can parse it.
|
|
|
+ */
|
|
|
+
|
|
|
+static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
|
|
|
+{
|
|
|
+ if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
|
|
|
+ info("Fixing up Cherry Cymotion report descriptor");
|
|
|
+ rdesc[11] = rdesc[16] = 0xff;
|
|
|
+ rdesc[12] = rdesc[17] = 0x03;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static struct hid_device *usb_hid_configure(struct usb_interface *intf)
|
|
|
{
|
|
|
struct usb_host_interface *interface = intf->cur_altsetting;
|
|
@@ -1673,6 +1692,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ if ((quirks & HID_QUIRK_CYMOTION))
|
|
|
+ hid_fixup_cymotion_descriptor(rdesc, rsize);
|
|
|
+
|
|
|
#ifdef DEBUG_DATA
|
|
|
printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
|
|
|
for (n = 0; n < rsize; n++)
|