[PATCH 2/2] HID: corsair: Add K40 support
The Corsair K40 uses the same usage codes as the K90 for its special keys (although it has only 6 G-keys). Signed-off-by: Clément Vuchener --- drivers/hid/hid-core.c| 1 + drivers/hid/hid-corsair.c | 1 + drivers/hid/hid-ids.h | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bdb8cc8..73860b9 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1871,6 +1871,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K40) }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) }, diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 98f40aa..85b5168 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -151,6 +151,7 @@ static int corsair_input_mapping(struct hid_device *dev, } static const struct hid_device_id corsair_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K40) }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) }, {} }; diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5c0e43e..ea9fef9 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -256,6 +256,7 @@ #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff #define USB_VENDOR_ID_CORSAIR 0x1b1c +#define USB_DEVICE_ID_CORSAIR_K40 0x1b0e #define USB_DEVICE_ID_CORSAIR_K90 0x1b02 #define USB_VENDOR_ID_CREATIVELABS 0x041e -- 2.5.5
[PATCH 1/2] HID: corsair: Remove all features using the USB protocol
Remove every use of USB control requests since it can be more easily done in user space. This removes the dependency on USB and LED subsystems. The simplyfied driver now only remaps Corsair usage codes. Signed-off-by: Clément Vuchener --- Documentation/ABI/testing/sysfs-driver-hid-corsair | 15 - drivers/hid/Kconfig| 2 +- drivers/hid/hid-corsair.c | 497 + 3 files changed, 2 insertions(+), 512 deletions(-) delete mode 100644 Documentation/ABI/testing/sysfs-driver-hid-corsair diff --git a/Documentation/ABI/testing/sysfs-driver-hid-corsair b/Documentation/ABI/testing/sysfs-driver-hid-corsair deleted file mode 100644 index b8827f0..000 --- a/Documentation/ABI/testing/sysfs-driver-hid-corsair +++ /dev/null @@ -1,15 +0,0 @@ -What: /sys/bus/drivers/corsair//macro_mode -Date: August 2015 -KernelVersion: 4.2 -Contact: Clement Vuchener -Description: Get/set the current playback mode. "SW" for software mode - where G-keys triggers their regular key codes. "HW" for - hardware playback mode where the G-keys play their macro - from the on-board memory. - - -What: /sys/bus/drivers/corsair//current_profile -Date: August 2015 -KernelVersion: 4.2 -Contact: Clement Vuchener -Description: Get/set the current selected profile. Values are from 1 to 3. diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 4117225..43b018f 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -173,7 +173,7 @@ config HID_CHICONY config HID_CORSAIR tristate "Corsair devices" - depends on HID && USB && LEDS_CLASS + depends on HID ---help--- Support for Corsair devices that are not fully compliant with the HID standard. diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 717704e..98f40aa 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -16,31 +16,9 @@ #include #include -#include -#include #include "hid-ids.h" -#define CORSAIR_USE_K90_MACRO (1<<0) -#define CORSAIR_USE_K90_BACKLIGHT (1<<1) - -struct k90_led { - struct led_classdev cdev; - int brightness; - struct work_struct work; - bool removed; -}; - -struct k90_drvdata { - struct k90_led record_led; -}; - -struct corsair_drvdata { - unsigned long quirks; - struct k90_drvdata *k90; - struct k90_led *backlight; -}; - #define K90_GKEY_COUNT 18 static int corsair_usage_to_gkey(unsigned int usage) @@ -119,474 +97,6 @@ MODULE_PARM_DESC(profilekey_codes, "Key codes for the profile buttons"); #define CORSAIR_USAGE_LIGHT_BRIGHT 0xfd #define CORSAIR_USAGE_LIGHT_MAX 0xfd -/* USB control protocol */ - -#define K90_REQUEST_BRIGHTNESS 49 -#define K90_REQUEST_MACRO_MODE 2 -#define K90_REQUEST_STATUS 4 -#define K90_REQUEST_GET_MODE 5 -#define K90_REQUEST_PROFILE 20 - -#define K90_MACRO_MODE_SW 0x0030 -#define K90_MACRO_MODE_HW 0x0001 - -#define K90_MACRO_LED_ON 0x0020 -#define K90_MACRO_LED_OFF 0x0040 - -/* - * LED class devices - */ - -#define K90_BACKLIGHT_LED_SUFFIX "::backlight" -#define K90_RECORD_LED_SUFFIX "::record" - -static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) -{ - int ret; - struct k90_led *led = container_of(led_cdev, struct k90_led, cdev); - struct device *dev = led->cdev.dev->parent; - struct usb_interface *usbif = to_usb_interface(dev->parent); - struct usb_device *usbdev = interface_to_usbdev(usbif); - int brightness; - char data[8]; - - ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), - K90_REQUEST_STATUS, - USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, 0, 0, data, 8, - USB_CTRL_SET_TIMEOUT); - if (ret < 0) { - dev_warn(dev, "Failed to get K90 initial state (error %d).\n", -ret); - return -EIO; - } - brightness = data[4]; - if (brightness < 0 || brightness > 3) { - dev_warn(dev, -"Read invalid backlight brightness: %02hhx.\n", -data[4]); - return -EIO; - } - return brightness; -} - -static enum led_brightness k90_record_led_get(struct led_classdev *led_cdev) -{ - struct k90_led *led = container_of(led_cdev, struct k90_led, cdev); - - return led->brightness; -} - -static void k90_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct k90_led *led = container_of(led_cdev, struct k90_led, cdev); - - led->brightness = brightness; - schedule_work(&led->work); -} - -static void k90_backlight_work(struct work_struct *work) -{ - int ret; - struct k90_led *led = containe
[PATCH 0/2] hid: corsair: Driver simplification and new supported device
I tried to add support for the K40 some time ago, but the vendor specific USB protocol became over-complicated because of a lot of small differences between the K90 and the K40. Also, since I wrote the first version of this driver, I learned that USB control transfers could be done from user-space without the need to detach the kernel driver (please tell me if I am wrong). So, I decided to move all USB related features in user-space (as far as I know, I was the only user, but if someone is looking for a replacement, I wrote a small tool available here: https://github.com/cvuchener/corsair-usb-config). This simplification only leaves the usage code remapping part and the driver no longer depends on USB and LED subsystems. This should make the driver easier to maintain or to add new supported devices. After the removal of USB related functions in first patch, the addition of K40 support in the second patch is simply a matter of adding the device in the id list. Clément Vuchener (2): HID: corsair: Remove all features using the USB protocol HID: corsair: Add K40 support Documentation/ABI/testing/sysfs-driver-hid-corsair | 15 - drivers/hid/Kconfig| 2 +- drivers/hid/hid-core.c | 1 + drivers/hid/hid-corsair.c | 498 + drivers/hid/hid-ids.h | 1 + 5 files changed, 5 insertions(+), 512 deletions(-) delete mode 100644 Documentation/ABI/testing/sysfs-driver-hid-corsair -- 2.5.5
[PATCH] HID: corsair: fix mapping of non-keyboard usages
This fixes a bug where the Volume Up key was ignored because it uses the same usage code as G18. Special Corsair usage codes are in the keyboard page, other pages should be left to the generic driver. Signed-off-by: Clément Vuchener --- drivers/hid/hid-corsair.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 5855196..717704e 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -595,6 +595,9 @@ static int corsair_input_mapping(struct hid_device *dev, { int gkey; + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD) + return 0; + gkey = corsair_usage_to_gkey(usage->hid & HID_USAGE); if (gkey != 0) { hid_map_usage_clear(input, usage, bit, max, EV_KEY, -- 2.5.0
[PATCH v3 1/1] Add Corsair Vengeance K90 driver
This patch implements a HID driver for the Corsair Vengeance K90 keyboard. It fixes the behaviour of the keys using incorrect HID usage codes and exposes the macro playback mode and current profile to the user space through sysfs attributes. It also adds two LED class devices controlling the "record" LED and the backlight. Signed-off-by: Clément Vuchener --- Documentation/ABI/testing/sysfs-driver-hid-corsair | 15 + drivers/hid/Kconfig| 10 + drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-corsair.c | 673 + drivers/hid/hid-ids.h | 3 + 6 files changed, 703 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-corsair create mode 100644 drivers/hid/hid-corsair.c diff --git a/Documentation/ABI/testing/sysfs-driver-hid-corsair b/Documentation/ABI/testing/sysfs-driver-hid-corsair new file mode 100644 index 000..b8827f0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-corsair @@ -0,0 +1,15 @@ +What: /sys/bus/drivers/corsair//macro_mode +Date: August 2015 +KernelVersion: 4.2 +Contact: Clement Vuchener +Description: Get/set the current playback mode. "SW" for software mode + where G-keys triggers their regular key codes. "HW" for + hardware playback mode where the G-keys play their macro + from the on-board memory. + + +What: /sys/bus/drivers/corsair//current_profile +Date: August 2015 +KernelVersion: 4.2 +Contact: Clement Vuchener +Description: Get/set the current selected profile. Values are from 1 to 3. diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 6ab51ae..3fe9678 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -171,6 +171,16 @@ config HID_CHICONY ---help--- Support for Chicony Tactical pad. +config HID_CORSAIR + tristate "Corsair devices" + depends on HID && USB && LEDS_CLASS + ---help--- + Support for Corsair devices that are not fully compliant with the + HID standard. + + Supported devices: + - Vengeance K90 + config HID_PRODIKEYS tristate "Prodikeys PC-MIDI Keyboard support" depends on HID && SND diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index e6441bc..edaa0f2 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CHICONY) += hid-chicony.o +obj-$(CONFIG_HID_CORSAIR) += hid-corsair.o obj-$(CONFIG_HID_CP2112) += hid-cp2112.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 70a11ac..0e3baae 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1828,6 +1828,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c new file mode 100644 index 000..cd3429e --- /dev/null +++ b/drivers/hid/hid-corsair.c @@ -0,0 +1,673 @@ +/* + * HID driver for Corsair devices + * + * Supported devices: + * - Vengeance K90 Keyboard + * + * Copyright (c) 2015 Clement Vuchener + */ + +/* + * 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 + +#include "hid-ids.h" + +#define CORSAIR_USE_K90_MACRO (1<<0) +#define CORSAIR_USE_K90_BACKLIGHT (1<<1) + +struct k90_led { + struct led_classdev cdev; + int brightness; + struct work_struct work; + int removed; +}; + +struct k90_drvdata { + struct k90_led record_led; +}; + +struct corsair_drvdata { + unsigned long quirks; + struct k90_drvdata *k90; + struct k90_led *backlight; +}; + +#define K90_GKEY_COUNT 18 + +static int corsair_usage_to_gkey(unsigned int usage) +{ + /* G1 (0xd0) to G16 (0xdf) */ + if (usage >= 0xd0 && usage <= 0xdf) +
[PATCH v3 0/1] Corsair Vengeance K90 driver
I have split the special functions between backlight and macro functions. This should make it easier to test new devices. I think the macro functions will only be reused with the K95. While backlight is more common feature, though I have no idea it is done with other Corsair hardware. I have changed most sysfs attributes and LEDs so that the current value is queried from the hardware instead of tracking events. I started this way when I did not know how to read the value, but I think it is better done this way when I can. I don't know how to read the state of the record LED, so this one still use events to update the state. I removed the color from the LEDs name. I understand it is only necessary when having LEDs with several colors. This way the names will stay the same across different hardware with different backlight color. I don't think it is an useful information here. I also added event for the MR (macro record) button and profile switch buttons. I think that userspace program may want to know about these events. For example for using profile keys to start some configuration program. changes in v3: - query the hardware instead of tracking the value with events when possible (except record_led) - added quirks for activating special functions (macro functions and backlight) - allocation of led name use kzalloc instead of devm_kzalloc (free mem when initialization failed) - renamed led devices (without colors) - added key codes for record and profile keys Clément Vuchener (1): Add Corsair Vengeance K90 driver Documentation/ABI/testing/sysfs-driver-hid-corsair | 15 + drivers/hid/Kconfig| 10 + drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-corsair.c | 673 + drivers/hid/hid-ids.h | 3 + 6 files changed, 703 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-corsair create mode 100644 drivers/hid/hid-corsair.c -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/