diff options
-rw-r--r-- | drivers/hid/Kconfig | 7 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-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 | 33 | ||||
-rw-r--r-- | drivers/hid/hid-petalynx.c | 122 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 21 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
8 files changed, 134 insertions, 55 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b093f3c83e36..04f646a90d32 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -154,6 +154,13 @@ config HID_MICROSOFT Support for some Microsoft devices which breaks less or more HID specification. +config HID_PETALYNX + tristate "Petalynx" + default m + depends on USB_HID + ---help--- + Support for Petalynx Maxter remote. + config HID_SUNPLUS tristate "Sunplus" default m diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index ffb58f8001b7..359a5bae4082 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o +obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_USB_HID) += usbhid/ diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 81e7d70260a4..2b7a08fe1718 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1191,6 +1191,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c index b95476c47449..c28422c9d2b5 100644 --- a/drivers/hid/hid-dummy.c +++ b/drivers/hid/hid-dummy.c @@ -31,6 +31,9 @@ static int __init hid_dummy_init(void) #ifdef CONFIG_HID_MICROSOFT_MODULE HID_COMPAT_CALL_DRIVER(microsoft); #endif +#ifdef CONFIG_HID_PETALYNX_MODULE + HID_COMPAT_CALL_DRIVER(petalynx); +#endif #ifdef CONFIG_HID_SUNPLUS_MODULE HID_COMPAT_CALL_DRIVER(sunplus); #endif diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c index d10f47765553..903162a63c4f 100644 --- a/drivers/hid/hid-input-quirks.c +++ b/drivers/hid/hid-input-quirks.c @@ -42,34 +42,6 @@ static int quirk_gyration_remote(struct hid_usage *usage, return 1; } -static int quirk_petalynx_remote(struct hid_usage *usage, - struct hid_input *hidinput, unsigned long **bit, int *max) -{ - if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) && - ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)) - return 0; - - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) - switch(usage->hid & HID_USAGE) { - case 0x05a: map_key_clear(KEY_TEXT); break; - case 0x05b: map_key_clear(KEY_RED); break; - case 0x05c: map_key_clear(KEY_GREEN); break; - case 0x05d: map_key_clear(KEY_YELLOW); break; - case 0x05e: map_key_clear(KEY_BLUE); break; - default: - return 0; - } - - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) - switch(usage->hid & HID_USAGE) { - case 0x0f6: map_key_clear(KEY_NEXT); break; - case 0x0fa: map_key_clear(KEY_BACK); break; - default: - return 0; - } - return 1; -} - static int quirk_cherry_genius_29e(struct hid_usage *usage, struct hid_input *hidinput, unsigned long **bit, int *max) { @@ -94,9 +66,6 @@ static int quirk_cherry_genius_29e(struct hid_usage *usage, #define VENDOR_ID_MONTEREY 0x0566 #define DEVICE_ID_GENIUS_KB29E 0x3004 -#define VENDOR_ID_PETALYNX 0x18b1 -#define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 - static const struct hid_input_blacklist { __u16 idVendor; __u16 idProduct; @@ -107,8 +76,6 @@ 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 }, - { 0, 0, NULL } }; diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c new file mode 100644 index 000000000000..4109244f1d72 --- /dev/null +++ b/drivers/hid/hid-petalynx.c @@ -0,0 +1,122 @@ +/* + * HID driver for some petalynx "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" + +/* Petalynx Maxter Remote has maximum for consumer page set too low */ +static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int rsize) +{ + if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && + rdesc[41] == 0x00 && rdesc[59] == 0x26 && + rdesc[60] == 0xf9 && rdesc[61] == 0x00) { + dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " + "descriptor\n"); + rdesc[60] = 0xfa; + rdesc[40] = 0xfa; + } +} + +#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ + EV_KEY, (c)) +static int pl_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_LOGIVENDOR) { + switch (usage->hid & HID_USAGE) { + case 0x05a: pl_map_key_clear(KEY_TEXT); break; + case 0x05b: pl_map_key_clear(KEY_RED); break; + case 0x05c: pl_map_key_clear(KEY_GREEN); break; + case 0x05d: pl_map_key_clear(KEY_YELLOW); break; + case 0x05e: pl_map_key_clear(KEY_BLUE); break; + default: + return 0; + } + return 1; + } + + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) { + switch (usage->hid & HID_USAGE) { + case 0x0f6: pl_map_key_clear(KEY_NEXT); break; + case 0x0fa: pl_map_key_clear(KEY_BACK); break; + default: + return 0; + } + return 1; + } + + return 0; +} + +static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + + hdev->quirks |= HID_QUIRK_NOGET; + + ret = hid_parse(hdev); + if (ret) { + dev_err(&hdev->dev, "parse failed\n"); + goto err_free; + } + + ret = hid_hw_start(hdev); + if (ret) { + dev_err(&hdev->dev, "hw start failed\n"); + goto err_free; + } + + return 0; +err_free: + return ret; +} + +static const struct hid_device_id pl_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { } +}; +MODULE_DEVICE_TABLE(hid, pl_devices); + +static struct hid_driver pl_driver = { + .name = "petalynx", + .id_table = pl_devices, + .report_fixup = pl_report_fixup, + .input_mapping = pl_input_mapping, + .probe = pl_probe, +}; + +static int pl_init(void) +{ + return hid_register_driver(&pl_driver); +} + +static void pl_exit(void) +{ + hid_unregister_driver(&pl_driver); +} + +module_init(pl_init); +module_exit(pl_exit); +MODULE_LICENSE("GPL"); + +HID_COMPAT_LOAD_DRIVER(petalynx); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index c344ec2fad5d..3f977abb62b1 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -57,7 +57,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, @@ -78,8 +77,6 @@ static const struct hid_rdesc_blacklist { } hid_rdesc_blacklist[] = { { 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 }, - { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, { 0, 0 } @@ -340,21 +337,6 @@ static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc, } } -/* Petalynx Maxter Remote has maximum for consumer page set too low */ -static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) -{ - if (rsize >= 60 && rdesc[39] == 0x2a - && rdesc[40] == 0xf5 - && rdesc[41] == 0x00 - && rdesc[59] == 0x26 - && rdesc[60] == 0xf9 - && rdesc[61] == 0x00) { - printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n"); - rdesc[60] = 0xfa; - rdesc[40] = 0xfa; - } -} - static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize) { if (rsize >= 30 && rdesc[29] == 0x05 @@ -366,9 +348,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_PETALYNX) - usbhid_fixup_petalynx_descriptor(rdesc, rsize); - if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER) usbhid_fixup_button_consumer_descriptor(rdesc, rsize); diff --git a/include/linux/hid.h b/include/linux/hid.h index 298cbcce3a2d..7f4c94ffa617 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -272,7 +272,6 @@ struct hid_item { * Separate quirks for runtime report descriptor fixup */ -#define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 |