[PATCH 2/2] HID: corsair: Add K40 support

2016-03-23 Thread =?UTF-8?q?Cl=C3=A9ment=20Vuchener?=
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

2016-03-23 Thread =?UTF-8?q?Cl=C3=A9ment=20Vuchener?=
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

2016-03-23 Thread =?UTF-8?q?Cl=C3=A9ment=20Vuchener?=
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

2016-02-16 Thread =?UTF-8?q?Cl=C3=A9ment=20Vuchener?=
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

2015-09-17 Thread =?UTF-8?q?Cl=C3=A9ment=20Vuchener?=
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

2015-09-17 Thread =?UTF-8?q?Cl=C3=A9ment=20Vuchener?=
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/