From 8f507c8b0fa5d679e2957aad0e5ecd47675fca9a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 16 Mar 2016 16:59:38 -0700 Subject: HID: hidraw: switch to using memdup_user Instead of open-coding memory allocation and copying form user memory sequence let's use memdup_user(). Signed-off-by: Dmitry Torokhov Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 9c2d7c2..b9a76e3 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -123,7 +124,6 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, dev = hidraw_table[minor]->hid; - if (count > HID_MAX_BUFFER_SIZE) { hid_warn(dev, "pid %d passed too large report\n", task_pid_nr(current)); @@ -138,17 +138,12 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, goto out; } - buf = kmalloc(count * sizeof(__u8), GFP_KERNEL); - if (!buf) { - ret = -ENOMEM; + buf = memdup_user(buffer, count); + if (IS_ERR(buf)) { + ret = PTR_ERR(buf); goto out; } - if (copy_from_user(buf, buffer, count)) { - ret = -EFAULT; - goto out_free; - } - if ((report_type == HID_OUTPUT_REPORT) && !(dev->quirks & HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP)) { ret = hid_hw_output_report(dev, buf, count); -- cgit v0.10.2 From eeb01a57921a5e373302733d7cdf1ca87da5375a Mon Sep 17 00:00:00 2001 From: Yusuke Fujimaki Date: Mon, 21 Mar 2016 16:18:42 +0900 Subject: HID: Asus X205TA keyboard driver Asus X205TA built-in keyboard contains wrong logical maximum value in report descriptor. 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x06, // Usage (Keyboard) 0xa1, 0x01, // Collection (Application) 0x85, 0x01, // Report ID (1) 0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x19, 0xe0, // Usage Minimum (224) 0x29, 0xe7, // Usage Maximum (231) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data,Array,Abs) 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0x81, 0x03, // Input (Const,Var,Abs) 0x95, 0x05, // Report Count (5) 0x75, 0x01, // Report Size (1) 0x05, 0x08, // Usage (LED) 0x19, 0x01, // Usage Minimum (1) 0x29, 0x05, // Usage Maximum (5) 0x91, 0x02, // Output (Data,Var,Abs) 0x95, 0x01, // Report Count (1) 0x75, 0x03, // Report Size (3) 0x91, 0x03, // Output (Const,Var,Abs) 0x95, 0x06, // Report Count (6) 0x75, 0x08, // Report Size (8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x65, // Logical Maximum (101) * too small * 0x05, 0x07, // Usage Page (Keyboard/Keypad) 0x19, 0x00, // Usage Minimum (0) 0x29, 0xdd, // Usage Maximum (221) 0x81, 0x00, // Input(Data,Array,Abs) In Asus X205TA japanese keyboard model,there are language specific keys over usage id 101. This patch correct wrong logical maximum in report descriptor. Signed-off-by: Yusuke Fujimaki Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 4117225..513c93e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -134,6 +134,12 @@ config HID_APPLEIR Say Y here if you want support for Apple infrared remote control. +config HID_ASUS + tristate "Asus" + depends on I2C_HID + ---help--- + Support for Asus X205TA built-in keyboard via i2c. + config HID_AUREAL tristate "Aureal" depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index be56ab6..a2fb562 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o +obj-$(CONFIG_HID_ASUS) += hid-asus.o obj-$(CONFIG_HID_AUREAL) += hid-aureal.o obj-$(CONFIG_HID_BELKIN) += hid-belkin.o obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c new file mode 100644 index 0000000..1734e11 --- /dev/null +++ b/drivers/hid/hid-asus.c @@ -0,0 +1,48 @@ +/* + * HID driver for Asus X205TA built-in keyboard. + * Fixes small logical maximum to match usage maximum. + * + * Copyright (c) 2016 Yusuke Fujimaki + * + * This module based on hid-ortek by + * Copyright (c) 2010 Johnathon Harris + * Copyright (c) 2011 Jiri Kosina + */ + +/* + * 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 +#include +#include + +#include "hid-ids.h" + +static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + if (*rsize >= 180 && rdesc[54] == 0x25 && rdesc[55] == 0x65) { + hid_info(hdev, "Fixing up Asus X205TA report descriptor\n"); + rdesc[55] = 0xdd; + } + return rdesc; +} + +static const struct hid_device_id asus_devices[] = { + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_X205TA_KEYBOARD) }, + { } +}; +MODULE_DEVICE_TABLE(hid, asus_devices); + +static struct hid_driver asus_driver = { + .name = "asus", + .id_table = asus_devices, + .report_fixup = asus_report_fixup +}; +module_hid_driver(asus_driver); + +MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bdb8cc8..7426b5a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1856,6 +1856,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_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_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_X205TA_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5c0e43e..f83e7fd 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -163,6 +163,7 @@ #define USB_VENDOR_ID_ASUSTEK 0x0b05 #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b +#define USB_DEVICE_ID_ASUSTEK_X205TA_KEYBOARD 0x8585 #define USB_VENDOR_ID_ATEN 0x0557 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -- cgit v0.10.2 From 85d08340c3de1126467db4e69140fe483d91c114 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 2 Apr 2016 07:44:32 +0300 Subject: HID: roccat: silence an uninitialized variable warning My static checker complains because we use "dev_id" before we check for errors so it could be uninitialized. Fix this by moving the error handling forward a couple lines. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index 65c4ccfc..76d06cf 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -421,14 +421,13 @@ static int __init roccat_init(void) retval = alloc_chrdev_region(&dev_id, ROCCAT_FIRST_MINOR, ROCCAT_MAX_DEVICES, "roccat"); - - roccat_major = MAJOR(dev_id); - if (retval < 0) { pr_warn("can't get major number\n"); goto error; } + roccat_major = MAJOR(dev_id); + cdev_init(&roccat_cdev, &roccat_ops); retval = cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); -- cgit v0.10.2 From 6edac6fde59e231bd297ebcbc3d1bd395006cd1d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 2 Apr 2016 07:45:01 +0300 Subject: HID: hidraw: silence an uninitialized variable warning My static checker complains that "devid" can be uninitialized if alloc_chrdev_region() fails. Fix this by moving the error hanling forward a couple lines. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 9c2d7c2..4b981fd 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -587,14 +587,13 @@ int __init hidraw_init(void) result = alloc_chrdev_region(&dev_id, HIDRAW_FIRST_MINOR, HIDRAW_MAX_DEVICES, "hidraw"); - - hidraw_major = MAJOR(dev_id); - if (result < 0) { pr_warn("can't get major number\n"); goto out; } + hidraw_major = MAJOR(dev_id); + hidraw_class = class_create(THIS_MODULE, "hidraw"); if (IS_ERR(hidraw_class)) { result = PTR_ERR(hidraw_class); -- cgit v0.10.2 From b94f7d5ddf1b114e66d9bcc07d0ead080470383b Mon Sep 17 00:00:00 2001 From: Yusuke Fujimaki Date: Sun, 3 Apr 2016 23:15:16 +0900 Subject: HID: asus: add support for VivoBook E200HA Asus X205TA and E200HA built-in keyboard contain wrong logical maximum value in report descriptor. This patch correct wrong logical maximum in report descriptor. Signed-off-by: Yusuke Fujimaki Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 513c93e..5646ca4 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -138,7 +138,11 @@ config HID_ASUS tristate "Asus" depends on I2C_HID ---help--- - Support for Asus X205TA built-in keyboard via i2c. + Support for Asus notebook built-in keyboard via i2c. + + Supported devices: + - EeeBook X205TA + - VivoBook E200HA config HID_AUREAL tristate "Aureal" diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 1734e11..7a811ec 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -1,7 +1,11 @@ /* - * HID driver for Asus X205TA built-in keyboard. + * HID driver for Asus notebook built-in keyboard. * Fixes small logical maximum to match usage maximum. * + * Currently supported devices are: + * EeeBook X205TA + * VivoBook E200HA + * * Copyright (c) 2016 Yusuke Fujimaki * * This module based on hid-ortek by @@ -25,15 +29,15 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - if (*rsize >= 180 && rdesc[54] == 0x25 && rdesc[55] == 0x65) { - hid_info(hdev, "Fixing up Asus X205TA report descriptor\n"); + if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x65) { + hid_info(hdev, "Fixing up Asus notebook report descriptor\n"); rdesc[55] = 0xdd; } return rdesc; } static const struct hid_device_id asus_devices[] = { - { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_X205TA_KEYBOARD) }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, { } }; MODULE_DEVICE_TABLE(hid, asus_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7426b5a..7f8105b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1856,7 +1856,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_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_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_X205TA_KEYBOARD) }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f83e7fd..1219e59 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -163,7 +163,7 @@ #define USB_VENDOR_ID_ASUSTEK 0x0b05 #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b -#define USB_DEVICE_ID_ASUSTEK_X205TA_KEYBOARD 0x8585 +#define USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD 0x8585 #define USB_VENDOR_ID_ATEN 0x0557 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 -- cgit v0.10.2 From 95d1c8951e5bd50bb89654a99a7012b1e75646bd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Apr 2016 10:19:58 -0700 Subject: HID: simplify implement() a bit The 'size' variable is not really needed, and we can also shift constant in the loop body when masking off existing bits. Also we do not have to use 64 bit calculations if we take an extra branch. [jkosina@suse.cz: fix a small error in changelog] Suggested-by: Doug Anderson Signed-off-by: Dmitry Torokhov Reviewed-by: Douglas Anderson Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bdb8cc8..9985c0a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1129,49 +1129,46 @@ EXPORT_SYMBOL_GPL(hid_field_extract); static void __implement(u8 *report, unsigned offset, int n, u32 value) { unsigned int idx = offset / 8; - unsigned int size = offset + n; unsigned int bit_shift = offset % 8; int bits_to_set = 8 - bit_shift; - u8 bit_mask = 0xff << bit_shift; while (n - bits_to_set >= 0) { - report[idx] &= ~bit_mask; + report[idx] &= ~(0xff << bit_shift); report[idx] |= value << bit_shift; value >>= bits_to_set; n -= bits_to_set; bits_to_set = 8; - bit_mask = 0xff; bit_shift = 0; idx++; } /* last nibble */ if (n) { - if (size % 8) - bit_mask &= (1U << (size % 8)) - 1; - report[idx] &= ~bit_mask; - report[idx] |= (value << bit_shift) & bit_mask; + u8 bit_mask = ((1U << n) - 1); + report[idx] &= ~(bit_mask << bit_shift); + report[idx] |= value << bit_shift; } } static void implement(const struct hid_device *hid, u8 *report, unsigned offset, unsigned n, u32 value) { - u64 m; - - if (n > 32) { + if (unlikely(n > 32)) { hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n", __func__, n, current->comm); n = 32; + } else if (n < 32) { + u32 m = (1U << n) - 1; + + if (unlikely(value > m)) { + hid_warn(hid, + "%s() called with too large value %d (n: %d)! (%s)\n", + __func__, value, n, current->comm); + WARN_ON(1); + value &= m; + } } - m = (1ULL << n) - 1; - if (value > m) - hid_warn(hid, "%s() called with too large value %d! (%s)\n", - __func__, value, current->comm); - WARN_ON(value > m); - value &= m; - __implement(report, offset, n, value); } -- cgit v0.10.2 From 91540ccc9c4554c8bbb8b8a1be0b255a378b6475 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sun, 17 Apr 2016 22:46:59 +0200 Subject: HID: thingm: factor out duplicated code to thingm_init_led Simplify thingm_init_rgb by factoring out duplicated code to thingm_init_led. Signed-off-by: Heiner Kallweit Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 847a497..a90463e 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -157,48 +157,35 @@ static int thingm_led_set(struct led_classdev *ldev, return ret; } +static int thingm_init_led(struct thingm_led *led, const char *color_name, + struct thingm_rgb *rgb, int minor) +{ + snprintf(led->name, sizeof(led->name), "thingm%d:%s:led%d", + minor, color_name, rgb->num); + led->ldev.name = led->name; + led->ldev.max_brightness = 255; + led->ldev.brightness_set_blocking = thingm_led_set; + led->rgb = rgb; + return devm_led_classdev_register(&rgb->tdev->hdev->dev, &led->ldev); +} + static int thingm_init_rgb(struct thingm_rgb *rgb) { const int minor = ((struct hidraw *) rgb->tdev->hdev->hidraw)->minor; int err; /* Register the red diode */ - snprintf(rgb->red.name, sizeof(rgb->red.name), - "thingm%d:red:led%d", minor, rgb->num); - rgb->red.ldev.name = rgb->red.name; - rgb->red.ldev.max_brightness = 255; - rgb->red.ldev.brightness_set_blocking = thingm_led_set; - rgb->red.rgb = rgb; - - err = devm_led_classdev_register(&rgb->tdev->hdev->dev, - &rgb->red.ldev); + err = thingm_init_led(&rgb->red, "red", rgb, minor); if (err) return err; /* Register the green diode */ - snprintf(rgb->green.name, sizeof(rgb->green.name), - "thingm%d:green:led%d", minor, rgb->num); - rgb->green.ldev.name = rgb->green.name; - rgb->green.ldev.max_brightness = 255; - rgb->green.ldev.brightness_set_blocking = thingm_led_set; - rgb->green.rgb = rgb; - - err = devm_led_classdev_register(&rgb->tdev->hdev->dev, - &rgb->green.ldev); + err = thingm_init_led(&rgb->green, "green", rgb, minor); if (err) return err; /* Register the blue diode */ - snprintf(rgb->blue.name, sizeof(rgb->blue.name), - "thingm%d:blue:led%d", minor, rgb->num); - rgb->blue.ldev.name = rgb->blue.name; - rgb->blue.ldev.max_brightness = 255; - rgb->blue.ldev.brightness_set_blocking = thingm_led_set; - rgb->blue.rgb = rgb; - - err = devm_led_classdev_register(&rgb->tdev->hdev->dev, - &rgb->blue.ldev); - return err; + return thingm_init_led(&rgb->blue, "blue", rgb, minor); } static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) -- cgit v0.10.2 From a4362fd6da7ab8b08028734004df486847ea593e Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sun, 17 Apr 2016 22:51:46 +0200 Subject: HID: thingm: set new flag LED_HW_PLUGGABLE Use recently introduced flag LED_HW_PLUGGABLE to avoid warnings when the device is unplugged. Signed-off-by: Heiner Kallweit Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index a90463e..2507bbe 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -165,6 +165,7 @@ static int thingm_init_led(struct thingm_led *led, const char *color_name, led->ldev.name = led->name; led->ldev.max_brightness = 255; led->ldev.brightness_set_blocking = thingm_led_set; + led->ldev.flags = LED_HW_PLUGGABLE; led->rgb = rgb; return devm_led_classdev_register(&rgb->tdev->hdev->dev, &led->ldev); } -- cgit v0.10.2 From bbf4ac9cfa9b681e3b657699f39fc855408904b8 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 20 Apr 2016 20:33:05 +0200 Subject: HID: thingm: remove not needed error message LED core takes care of handling failed calls to thingm_let_set. - print error message in set_brightness_delayed or - pass error to caller in led_set_brightness_sync Also the error message here doesn't provide any hint what actually went wrong. Therefore remove it. Signed-off-by: Heiner Kallweit Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 2507bbe..9ad9c6e 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -148,13 +148,8 @@ static int thingm_led_set(struct led_classdev *ldev, enum led_brightness brightness) { struct thingm_led *led = container_of(ldev, struct thingm_led, ldev); - int ret; - - ret = thingm_write_color(led->rgb); - if (ret) - hid_err(led->rgb->tdev->hdev, "failed to write color\n"); - return ret; + return thingm_write_color(led->rgb); } static int thingm_init_led(struct thingm_led *led, const char *color_name, -- cgit v0.10.2 From 282bf1fe6dca4b768d6bedc14aea1b82c36241c1 Mon Sep 17 00:00:00 2001 From: Trent Lloyd Date: Thu, 9 Jul 2015 13:38:50 +0800 Subject: HID: usbhid: quirks for Corsair RGB keyboard & mice (K70R, K95RGB, M65RGB, K70RGB, K65RGB) These devices feature multiple interfaces/endpoints: a legacy BIOS/boot interface (endpoint 0x81), as well as 2 corsair-specific keyboard interfaces (endpoint 0x82, 0x83 IN/0x03 OUT) and an RGB LED control interface (endpoint 0x84 IN/0x04 OUT) Because the extra 3 interfaces are not of subclass USB_INTERFACE_SUBCLASS_BOOT, HID_QUIRK_NOGET is not automatically set on them and a 10s timeout per-endpoint (30s per device) occurs initialising reports on boot. We configure HID_QUIRK_NO_INIT_REPORTS for these devices. Additionally the left-side G1-G18 macro keys on the K95RGB generate output on the un-opened 0x82/0x83 endpoints which causes the keyboard to stop responding waiting for this event to be collected. We enable HID_QUIRK_ALWAYS_POLL to prevent this situation from occurring. Signed-off-by: Trent Lloyd Tested-by: SUGNIAUX Wilfried Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5c0e43e..fa5b128 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -258,6 +258,13 @@ #define USB_VENDOR_ID_CORSAIR 0x1b1c #define USB_DEVICE_ID_CORSAIR_K90 0x1b02 +#define USB_VENDOR_ID_CORSAIR 0x1b1c +#define USB_DEVICE_ID_CORSAIR_K70R 0x1b09 +#define USB_DEVICE_ID_CORSAIR_K95RGB 0x1b11 +#define USB_DEVICE_ID_CORSAIR_M65RGB 0x1b12 +#define USB_DEVICE_ID_CORSAIR_K70RGB 0x1b13 +#define USB_DEVICE_ID_CORSAIR_K65RGB 0x1b17 + #define USB_VENDOR_ID_CREATIVELABS 0x041e #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index ed2f68e..0ffcaf9 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -71,6 +71,11 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70R, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_M65RGB, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K95RGB, HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, -- cgit v0.10.2 From bef7e200065086e2ceef091f6853f3b053ad2ba9 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Fri, 22 Apr 2016 14:30:53 -0700 Subject: HID: wacom: Add fuzz factor to distance and tilt axes The fuzz present on the distance and tilt axes is noticable when a puck is present, and userspace (specifically libinput) would like the ability to filter out the noise. To facilitate this, we assign a fuzz value of '1' for the distance and tilt axes. This is large enough to cover most of the natural variation in distance value as the puck is moved around, and enough to cover the jitter in rotation (reported through tilt axes) when the puck is left alone. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index ccf1883..499cc82 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -493,7 +493,8 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, features->x_fuzz = 4; features->y_fuzz = 4; features->pressure_fuzz = 0; - features->distance_fuzz = 0; + features->distance_fuzz = 1; + features->tilt_fuzz = 1; /* * The wireless device HID is basic and layout conflicts with diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 02c4efe..ea949cb 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2343,12 +2343,13 @@ static void wacom_setup_basic_pro_pen(struct wacom_wac *wacom_wac) __set_bit(BTN_STYLUS2, input_dev->keybit); input_set_abs_params(input_dev, ABS_DISTANCE, - 0, wacom_wac->features.distance_max, 0, 0); + 0, wacom_wac->features.distance_max, wacom_wac->features.distance_fuzz, 0); } static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) { struct input_dev *input_dev = wacom_wac->pen_input; + struct wacom_features *features = &wacom_wac->features; wacom_setup_basic_pro_pen(wacom_wac); @@ -2358,9 +2359,9 @@ static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, features->tilt_fuzz, 0); input_abs_set_res(input_dev, ABS_TILT_X, 57); - input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, 0, 0); + input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, features->tilt_fuzz, 0); input_abs_set_res(input_dev, ABS_TILT_Y, 57); } @@ -2506,7 +2507,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, case WACOM_G4: input_set_abs_params(input_dev, ABS_DISTANCE, 0, features->distance_max, - 0, 0); + features->distance_fuzz, 0); /* fall through */ case GRAPHIRE: @@ -2568,7 +2569,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_DISTANCE, 0, features->distance_max, - 0, 0); + features->distance_fuzz, 0); input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_abs_set_res(input_dev, ABS_Z, 287); @@ -2627,7 +2628,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, __set_bit(BTN_STYLUS2, input_dev->keybit); input_set_abs_params(input_dev, ABS_DISTANCE, 0, features->distance_max, - 0, 0); + features->distance_fuzz, 0); } break; case BAMBOO_PAD: diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index e2084d9..53d1653 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -177,6 +177,7 @@ struct wacom_features { int y_fuzz; int pressure_fuzz; int distance_fuzz; + int tilt_fuzz; unsigned quirks; unsigned touch_max; int oVid; -- cgit v0.10.2