Input: HID - add support for Cherry Cymotion keyboard
authorVojtech Pavlik <vojtech@suse.cz>
Sat, 14 Jan 2006 05:25:39 +0000 (00:25 -0500)
committerDmitry Torokhov <dtor_core@ameritech.net>
Sat, 14 Jan 2006 05:25:39 +0000 (00:25 -0500)
The Cherry Cymotion is a special Linux keyboard made by Cherry, with
only one little problem: it doesn't work with Linux. This patch
(originally by hexten.net, cleaned up by me) makes it work including
all the special keys.

Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
drivers/usb/input/hid-core.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid.h

index 5f52979..1a2d203 100644 (file)
@@ -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++)
index 192a03b..9e5a80b 100644 (file)
@@ -289,11 +289,19 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x226: map_key_clear(KEY_STOP);            break;
                                case 0x227: map_key_clear(KEY_REFRESH);         break;
                                case 0x22a: map_key_clear(KEY_BOOKMARKS);       break;
+                               case 0x233: map_key_clear(KEY_SCROLLUP);        break;
+                               case 0x234: map_key_clear(KEY_SCROLLDOWN);      break;
                                case 0x238: map_rel(REL_HWHEEL);                break;
                                case 0x279: map_key_clear(KEY_REDO);            break;
                                case 0x289: map_key_clear(KEY_REPLY);           break;
                                case 0x28b: map_key_clear(KEY_FORWARDMAIL);     break;
                                case 0x28c: map_key_clear(KEY_SEND);            break;
+
+                               /* Reported on a Cherry Cymotion keyboard */
+                               case 0x301: map_key_clear(KEY_PROG1);           break;
+                               case 0x302: map_key_clear(KEY_PROG2);           break;
+                               case 0x303: map_key_clear(KEY_PROG3);           break;
+
                                default:    goto ignore;
                        }
                        break;
index ee48a22..335316c 100644 (file)
@@ -246,6 +246,7 @@ struct hid_item {
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5          0x100
 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON         0x200
 #define HID_QUIRK_2WHEEL_POWERMOUSE            0x400
+#define HID_QUIRK_CYMOTION                     0x800
 
 /*
  * This is the global environment of the parser. This information is