RFC: HID: razer: Add a driver for Razer Keyboards

The Razer gaming accessories are a pretty popular keyboard
brand. The keyboards as such work pretty well with the standard
HID interface driver, but will miss out on a bunch of extra
functionality.

The extra functions have been supported for years by an
out-of-tree project, OpenRazer. However out-of-tree code
annoys me because special keys and features don't "just
work" out of the box with the mainline kernel.

So what about we start to bring this support into the kernel
properly.

This is a first shot that only support the keyboards, so as
to limit the scope a bit.

It is tested on the Razer Ornata Chroma and Razer BlackWidow
Elite, because that's all I have.

The driver registers an additional input device to funnel the
special keys (these report themselves as "game controller"
events) and register LEDs with the LED subsystem for the
backlight and special LEDs on the Razer keyboards.

The "game" LED goes on/off in response to pushing the
special "game" key (sometimes prefixed with the Fn key).
This on some keyboards also has the side effect of inhibiting
the "super" key (Windows) while active. Apparently gamers
often accidentally push the super key. The HID USB device
reports two individual keyboard interfaces: one for common
mode and one for game mode. Some developer noted it is
a bit over the top to have a separate HID device for a
game mode that only inhibits a single key, but that is
how it works.

The "macro" LED goes to on when pressed, the macro is
then supposed to be recorded, second time it is pressed
the LED starts flashing meaning it is time to store the
macro, and after pressing a key where the macro is
stored, the LED goes off. ESC can abort macro recording.
The LED is all handled in the driver, and each time we press
the macro key the standard Linux key KEY_MACRO is reported
to userspace, that should take care of the actual macro
recording.

The special keys to increase/decrease backlight on the
keyboard itself are handled directly in the driver.
The input subsystem only supports KEY_LIGHTS_TOGGLE, but
I guess if people prefer we could add KEY_LIGHTS_UP
and KEY_LIGHTS_DOWN and handle this in userspace,
looping back to the backlight. I am uncertain about that.

The special matrix effects are fun but (IMHO) pointless to
abstract further than a plain selection item. They are
controlled by a sysfs file named "matrix_effect" in the
class device for the "backlight" LED like this:

 > cd /sys/class/leds/razer:rgb:backlight
 > cat matrix_effect
 > [none] static spectrum wave reactive breathing starlight ripple fire
 > echo wave > matrix_effect

TODO:
- No support for non-keyboard devices. People can send
  patches.
- There is no RGB LED color control for the backlight or
  anything else. Just leave it for now.
- There is no individual LED control: each key on the
  keyboard can be assigned a custom color, but we do
  not support this yet.
- I imagine RGB LED control need some work in the LED
  subsystem or alternatively custom sysfs files.
- I kept some sysfs files from openrazer giving the product
  name, firmware version and serial number, albeit the usage
  is dubious. Should I just drop them?
- Userspace that does something reasonable with KEY_MACRO
- Userspace that plays with matrix_effects so users don't
  have to use sysfs.
- Left some debug code in etc. Well it is an RFC patch
  after all.

Cc: Terry Cain <terry@terrys-home.co.uk>
Cc: Luca Weiss <luca@z3ntu.xyz>
Cc: Tim Theede <pez2001@voyagerproject.de>
Cc: Adam Honse <calcprogrammer1@gmail.com>
Cc: Steve Kondik <shade@chemlab.org>
Cc: Ian Kumlien <ian.kumlien@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
4 files changed