diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/Kconfig | 7 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-cherry.c | 87 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-dummy.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-input-quirks.c | 21 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 19 |
7 files changed, 99 insertions, 40 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 01456b1d383..85aabb5d971 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -103,6 +103,13 @@ config HID_APPLE If unsure, say M. +config HID_CHERRY + tristate "Cherry" + default m + depends on USB_HID + ---help--- + Support for Cherry Cymotion. + config HID_CYPRESS tristate "Cypress" default m diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index ceede11eed7..cd6bd024767 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -14,6 +14,7 @@ endif obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_APPLE) += hid-apple.o +obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c new file mode 100644 index 00000000000..b833b9769ab --- /dev/null +++ b/drivers/hid/hid-cherry.c @@ -0,0 +1,87 @@ +/* + * HID driver for some cherry "special" devices + * + * Copyright (c) 1999 Andreas Gal + * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> + * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc + * Copyright (c) 2006-2007 Jiri Kosina + * Copyright (c) 2007 Paul Walmsley + * Copyright (c) 2008 Jiri Slaby + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <linux/device.h> +#include <linux/hid.h> +#include <linux/module.h> + +#include "hid-ids.h" + +/* + * Cherry Cymotion keyboard have an invalid HID report descriptor, + * that needs fixing before we can parse it. + */ +static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int rsize) +{ + if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { + dev_info(&hdev->dev, "fixing up Cherry Cymotion report " + "descriptor\n"); + rdesc[11] = rdesc[16] = 0xff; + rdesc[12] = rdesc[17] = 0x03; + } +} + +#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ + EV_KEY, (c)) +static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x301: ch_map_key_clear(KEY_PROG1); break; + case 0x302: ch_map_key_clear(KEY_PROG2); break; + case 0x303: ch_map_key_clear(KEY_PROG3); break; + default: + return 0; + } + + return 1; +} + +static const struct hid_device_id ch_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, + { } +}; +MODULE_DEVICE_TABLE(hid, ch_devices); + +static struct hid_driver ch_driver = { + .name = "cherry", + .id_table = ch_devices, + .report_fixup = ch_report_fixup, + .input_mapping = ch_input_mapping, +}; + +static int ch_init(void) +{ + return hid_register_driver(&ch_driver); +} + +static void ch_exit(void) +{ + hid_unregister_driver(&ch_driver); +} + +module_init(ch_init); +module_exit(ch_exit); +MODULE_LICENSE("GPL"); + +HID_COMPAT_LOAD_DRIVER(cherry); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index be582976db2..5acdc374285 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1164,6 +1164,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c index 123f1c71cdf..178344ea651 100644 --- a/drivers/hid/hid-dummy.c +++ b/drivers/hid/hid-dummy.c @@ -10,6 +10,9 @@ static int __init hid_dummy_init(void) #ifdef CONFIG_HID_APPLE_MODULE HID_COMPAT_CALL_DRIVER(apple); #endif +#ifdef CONFIG_HID_CHERRY_MODULE + HID_COMPAT_CALL_DRIVER(cherry); +#endif #ifdef CONFIG_HID_CYPRESS_MODULE HID_COMPAT_CALL_DRIVER(cypress); #endif diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c index 5bacf181a8c..97ee75064a0 100644 --- a/drivers/hid/hid-input-quirks.c +++ b/drivers/hid/hid-input-quirks.c @@ -38,22 +38,6 @@ static int quirk_belkin_wkbd(struct hid_usage *usage, return 1; } -static int quirk_cherry_cymotion(struct hid_usage *usage, - struct hid_input *hidinput, unsigned long **bit, int *max) -{ - if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) - return 0; - - switch (usage->hid & HID_USAGE) { - 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: - return 0; - } - return 1; -} - static int quirk_gyration_remote(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { @@ -173,9 +157,6 @@ static int quirk_btc_8193(struct hid_usage *usage, struct hid_input *hidinput, #define VENDOR_ID_BELKIN 0x1020 #define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006 -#define VENDOR_ID_CHERRY 0x046a -#define DEVICE_ID_CHERRY_CYMOTION 0x0023 - #define VENDOR_ID_CHICONY 0x04f2 #define DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 @@ -199,8 +180,6 @@ static const struct hid_input_blacklist { } hid_input_blacklist[] = { { VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd }, - { VENDOR_ID_CHERRY, DEVICE_ID_CHERRY_CYMOTION, quirk_cherry_cymotion }, - { VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad }, { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 1d12fb24829..0cc6e4223cd 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -79,9 +79,6 @@ static const struct hid_rdesc_blacklist { __u16 idProduct; __u32 quirks; } hid_rdesc_blacklist[] = { - - { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION }, - { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, @@ -320,19 +317,6 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); /* - * Cherry Cymotion keyboard have an invalid HID report descriptor, - * that needs fixing before we can parse it. - */ -static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize) -{ - if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n"); - rdesc[11] = rdesc[16] = 0xff; - rdesc[12] = rdesc[17] = 0x03; - } -} - -/* * Samsung IrDA remote controller (reports as Cypress USB Mouse). * * Vendor specific report #4 has a size of 48 bit, @@ -385,9 +369,6 @@ static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rs static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) { - if ((quirks & HID_QUIRK_RDESC_CYMOTION)) - usbhid_fixup_cymotion_descriptor(rdesc, rsize); - if (quirks & HID_QUIRK_RDESC_PETALYNX) usbhid_fixup_petalynx_descriptor(rdesc, rsize); |