aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVojtech Pavlik <vojtech@suse.cz>2006-01-14 00:25:39 -0500
committerDmitry Torokhov <dtor_core@ameritech.net>2006-01-14 00:25:39 -0500
commit940824b0ac6661ff4f3b36e7bce17f681d0cbc23 (patch)
treec06af81c1983956a2beaee7c6f273a6edebef709 /drivers
parent3dd01a831133e3260b9c77a09c234b012e9507da (diff)
Input: HID - add support for Cherry Cymotion keyboard
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/input/hid-core.c22
-rw-r--r--drivers/usb/input/hid-input.c8
-rw-r--r--drivers/usb/input/hid.h1
3 files changed, 31 insertions, 0 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 5f52979af1c7..1a2d20303ed8 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1450,6 +1450,9 @@ void hid_init_reports(struct hid_device *hid)
1450#define USB_VENDOR_ID_APPLE 0x05ac 1450#define USB_VENDOR_ID_APPLE 0x05ac
1451#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 1451#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304
1452 1452
1453#define USB_VENDOR_ID_CHERRY 0x046a
1454#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
1455
1453/* 1456/*
1454 * Alphabetically sorted blacklist by quirk type. 1457 * Alphabetically sorted blacklist by quirk type.
1455 */ 1458 */
@@ -1580,6 +1583,8 @@ static const struct hid_blacklist {
1580 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, 1583 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
1581 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, 1584 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
1582 1585
1586 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
1587
1583 { 0, 0 } 1588 { 0, 0 }
1584}; 1589};
1585 1590
@@ -1626,6 +1631,20 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
1626 usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); 1631 usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
1627} 1632}
1628 1633
1634/*
1635 * Cherry Cymotion keyboard have an invalid HID report descriptor,
1636 * that needs fixing before we can parse it.
1637 */
1638
1639static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize)
1640{
1641 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
1642 info("Fixing up Cherry Cymotion report descriptor");
1643 rdesc[11] = rdesc[16] = 0xff;
1644 rdesc[12] = rdesc[17] = 0x03;
1645 }
1646}
1647
1629static struct hid_device *usb_hid_configure(struct usb_interface *intf) 1648static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1630{ 1649{
1631 struct usb_host_interface *interface = intf->cur_altsetting; 1650 struct usb_host_interface *interface = intf->cur_altsetting;
@@ -1673,6 +1692,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1673 return NULL; 1692 return NULL;
1674 } 1693 }
1675 1694
1695 if ((quirks & HID_QUIRK_CYMOTION))
1696 hid_fixup_cymotion_descriptor(rdesc, rsize);
1697
1676#ifdef DEBUG_DATA 1698#ifdef DEBUG_DATA
1677 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); 1699 printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
1678 for (n = 0; n < rsize; n++) 1700 for (n = 0; n < rsize; n++)
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 192a03b28971..9e5a80bbd16f 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -289,11 +289,19 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
289 case 0x226: map_key_clear(KEY_STOP); break; 289 case 0x226: map_key_clear(KEY_STOP); break;
290 case 0x227: map_key_clear(KEY_REFRESH); break; 290 case 0x227: map_key_clear(KEY_REFRESH); break;
291 case 0x22a: map_key_clear(KEY_BOOKMARKS); break; 291 case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
292 case 0x233: map_key_clear(KEY_SCROLLUP); break;
293 case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
292 case 0x238: map_rel(REL_HWHEEL); break; 294 case 0x238: map_rel(REL_HWHEEL); break;
293 case 0x279: map_key_clear(KEY_REDO); break; 295 case 0x279: map_key_clear(KEY_REDO); break;
294 case 0x289: map_key_clear(KEY_REPLY); break; 296 case 0x289: map_key_clear(KEY_REPLY); break;
295 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; 297 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
296 case 0x28c: map_key_clear(KEY_SEND); break; 298 case 0x28c: map_key_clear(KEY_SEND); break;
299
300 /* Reported on a Cherry Cymotion keyboard */
301 case 0x301: map_key_clear(KEY_PROG1); break;
302 case 0x302: map_key_clear(KEY_PROG2); break;
303 case 0x303: map_key_clear(KEY_PROG3); break;
304
297 default: goto ignore; 305 default: goto ignore;
298 } 306 }
299 break; 307 break;
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index ee48a2276104..335316c7233b 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -246,6 +246,7 @@ struct hid_item {
246#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 246#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
247#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 247#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
248#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400 248#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400
249#define HID_QUIRK_CYMOTION 0x800
249 250
250/* 251/*
251 * This is the global environment of the parser. This information is 252 * This is the global environment of the parser. This information is