From 41de326eafa6eff71c6ca00ae27c6be235c65a6d Mon Sep 17 00:00:00 2001 From: Christian Ohm Date: Tue, 21 May 2013 01:31:08 +0200 Subject: HID: Add driver for Holtek gaming mouse 04d9:a067 This mouse is sold as Sharkoon Drakonia and Perixx MX-2000 and reports a too high usage maximum and logical maximum. This driver fixes the report descriptor so those values don't exceed HID_MAX_USAGES. Signed-off-by: Christian Ohm Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/hid/Kconfig') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index fb52f3f6de8..a0e19dc69da 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -231,6 +231,7 @@ config HID_HOLTEK Support for Holtek based devices: - Holtek On Line Grip based game controller - Trust GXT 18 Gaming Keyboard + - Sharkoon Drakonia / Perixx MX-2000 gaming mice config HOLTEK_FF bool "Holtek On Line Grip force feedback support" -- cgit v1.2.3-70-g09d2 From d4f5189052c68f5bae3aac62b357577ecb862fee Mon Sep 17 00:00:00 2001 From: Christian Ohm Date: Tue, 21 May 2013 01:31:09 +0200 Subject: HID: Add support for Holtek gaming mouse 04d9:a04a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This mouse is sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 and Zalman ZM-GM1, and reports too high usage maximum and logical maximum (like 04d9:a067, but its report descriptor is different). This patch adds its USB ID and fixes the report descriptor in the same way. Note: I don't actually have such a mouse to test, I took the report descriptor posted at https://bugzilla.novell.com/show_bug.cgi?id=774676, compared it to the one from 04d9:a067 and changed the offsets accordingly (all numbers minus 9, since it is 9 bytes shorter, and the difference is before the values that need changing). That Surely Works™. Signed-off-by: Christian Ohm Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 2 ++ drivers/hid/hid-holtek-mouse.c | 28 ++++++++++++++++++++++------ drivers/hid/hid-ids.h | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) (limited to 'drivers/hid/Kconfig') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a0e19dc69da..79e02682b2d 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -232,6 +232,8 @@ config HID_HOLTEK - Holtek On Line Grip based game controller - Trust GXT 18 Gaming Keyboard - Sharkoon Drakonia / Perixx MX-2000 gaming mice + - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 / + Zalman ZM-GM1 config HOLTEK_FF bool "Holtek On Line Grip force feedback support" diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c index f32e29aea11..6a23ee67813 100644 --- a/drivers/hid/hid-holtek-mouse.c +++ b/drivers/hid/hid-holtek-mouse.c @@ -23,8 +23,10 @@ * excessively large number of consumer usages (2^15), which is more than * HID_MAX_USAGES. This prevents proper parsing of the report descriptor. * - * This driver fixes the report descriptor for USB ID 04d9:a067, sold as - * Sharkoon Drakonia and Perixx MX-2000. + * This driver fixes the report descriptor for: + * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000 + * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 + * and Zalman ZM-GM1 */ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, @@ -35,11 +37,23 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { /* Change usage maximum and logical maximum from 0x7fff to * 0x2fff, so they don't exceed HID_MAX_USAGES */ - if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f - && rdesc[120] == 0xff && rdesc[121] == 0x7f) { - hid_info(hdev, "Fixing up report descriptor\n"); - rdesc[116] = rdesc[121] = 0x2f; + switch (hdev->product) { + case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067: + if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f + && rdesc[120] == 0xff && rdesc[121] == 0x7f) { + hid_info(hdev, "Fixing up report descriptor\n"); + rdesc[116] = rdesc[121] = 0x2f; + } + break; + case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A: + if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f + && rdesc[111] == 0xff && rdesc[112] == 0x7f) { + hid_info(hdev, "Fixing up report descriptor\n"); + rdesc[107] = rdesc[112] = 0x2f; + } + break; } + } return rdesc; } @@ -47,6 +61,8 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, static const struct hid_device_id holtek_mouse_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, + USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, { } }; MODULE_DEVICE_TABLE(hid, holtek_mouse_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 59766dfdf76..a9fcb9ea6c1 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -441,6 +441,7 @@ #define USB_VENDOR_ID_HOLTEK_ALT 0x04d9 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067 +#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a #define USB_VENDOR_ID_IMATION 0x0718 #define USB_DEVICE_ID_DISC_STAKKA 0xd000 -- cgit v1.2.3-70-g09d2 From d23efc19478ac7fb517038922b920a6979cbd958 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 7 May 2013 11:40:58 +0200 Subject: HID: add driver for ELO 4000/4500 This is a driver for ELO 4000/4500 devices which report themselves as HID devices, but do not really send HID events on touch. So we introduce a new HID 'quirk' driver with a raw_event handler where we take care of those events. What we need additionally is an input_configured hook, because the device does not mention anything about PRESSURE and TOUCH in its report descriptor, but it actually generate those. So we set the bits in the corresponding input_dev in that hook. Thanks to Petr Ostadal who was willing to test the driver. The rest of Cc's listed below had something to do with that driver over the years in our enterprise tree. Signed-off-by: Jiri Slaby Tested-by: Petr Ostadal Cc: Oliver Neukum Cc: Vojtech Pavlik Cc: Egbert Eich Cc: Libor Pechacek Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 7 +++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 2 + drivers/hid/hid-elo.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 drivers/hid/hid-elo.c (limited to 'drivers/hid/Kconfig') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index fb52f3f6de8..dd4fdb67c97 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -217,6 +217,13 @@ config HID_ELECOM ---help--- Support for the ELECOM BM084 (bluetooth mouse). +config HID_ELO + tristate "ELO USB 4000/4500 touchscreen" + depends on USB_HID + ---help--- + Support for the ELO USB 4000/4500 touchscreens. Note that this is for + different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO. + config HID_EZKEY tristate "Ezkey BTC 8193 keyboard" if EXPERT depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 2065694f57a..d1841ce0a30 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o obj-$(CONFIG_HID_ELECOM) += hid-elecom.o +obj-$(CONFIG_HID_ELO) += hid-elo.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o obj-$(CONFIG_HID_GYRATION) += hid-gyration.o obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 264f5509994..b06bac2f04e 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1573,6 +1573,8 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c new file mode 100644 index 00000000000..56143e011f2 --- /dev/null +++ b/drivers/hid/hid-elo.c @@ -0,0 +1,131 @@ +/* + * HID driver for ELO usb touchscreen 4000/4500 + * + * Copyright (c) 2013 Jiri Slaby + * + * Data parsing taken from elousb driver by Vojtech Pavlik. + * + * This driver is licensed under the terms of GPLv2. + */ + +#include +#include +#include + +#include "hid-ids.h" + +static void elo_input_configured(struct hid_device *hdev, + struct hid_input *hidinput) +{ + struct input_dev *input = hidinput->input; + + set_bit(BTN_TOUCH, input->keybit); + set_bit(ABS_PRESSURE, input->absbit); + input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0); +} + +static void elo_process_data(struct input_dev *input, const u8 *data, int size) +{ + int press; + + input_report_abs(input, ABS_X, (data[3] << 8) | data[2]); + input_report_abs(input, ABS_Y, (data[5] << 8) | data[4]); + + press = 0; + if (data[1] & 0x80) + press = (data[7] << 8) | data[6]; + input_report_abs(input, ABS_PRESSURE, press); + + if (data[1] & 0x03) { + input_report_key(input, BTN_TOUCH, 1); + input_sync(input); + } + + if (data[1] & 0x04) + input_report_key(input, BTN_TOUCH, 0); + + input_sync(input); +} + +static int elo_raw_event(struct hid_device *hdev, struct hid_report *report, + u8 *data, int size) +{ + struct hid_input *hidinput; + + if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs)) + return 0; + + hidinput = list_first_entry(&hdev->inputs, struct hid_input, list); + + switch (report->id) { + case 0: + if (data[0] == 'T') { /* Mandatory ELO packet marker */ + elo_process_data(hidinput->input, data, size); + return 1; + } + break; + default: /* unknown report */ + /* Unknown report type; pass upstream */ + hid_info(hdev, "unknown report type %d\n", report->id); + break; + } + + return 0; +} + +static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + goto err_free; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto err_free; + } + + return 0; +err_free: + return ret; +} + +static void elo_remove(struct hid_device *hdev) +{ + hid_hw_stop(hdev); +} + +static const struct hid_device_id elo_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), }, + { } +}; +MODULE_DEVICE_TABLE(hid, elo_devices); + +static struct hid_driver elo_driver = { + .name = "elo", + .id_table = elo_devices, + .probe = elo_probe, + .remove = elo_remove, + .raw_event = elo_raw_event, + .input_configured = elo_input_configured, +}; + +static int __init elo_driver_init(void) +{ + return hid_register_driver(&elo_driver); +} +module_init(elo_driver_init); + +static void __exit elo_driver_exit(void) +{ + hid_unregister_driver(&elo_driver); +} +module_exit(elo_driver_exit); + +MODULE_AUTHOR("Jiri Slaby "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2