HID: add driver for Roccat Kone gaming mouse
This Patch adds support for Kone gaming mouse from Roccat. It provides access to profiles, settings, firmware, weight, actual settings etc. through sysfs attributes. Event handling of this mouse differs from standard hid behaviour in that tilt button press is reported in each move event which results in strange behaviour if not handled by the driver. This is a heavily reworked version of the previously introduced driver. The changes include most of the previously raised concerns, memory leak and other fixes, code cleanups, adoption of additional achieved knowlege about the hardware and is (IMHO) a much better version than before even when I exchanged reduced USB-IO with a bigger memory consumption. I refused to implement one mentioned point: Removing the 'just-because-we-can' attributes. Motivation: Reading the clipped in weight: I'm no gamer and can't determine the usefulness of this feature but if the manufacturer implements such a feature it might make sense to someone and I would unwillingly limit the functionality besides its such a small feature. Reading the actual profile and dpi settings: Here I can testify that one can get lost of the actual settings when switching back and forth. The manufacturers windows driver has the ability for on-screen-display of the values and there is a mouse in the market that has an lcd on the underside of it to show these values. So I think this feature makes sense not only for me and shouldn't be removed. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
3971047930
commit
14bf62cde7
7 changed files with 1343 additions and 0 deletions
111
Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
Normal file
111
Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
Normal file
|
@ -0,0 +1,111 @@
|
|||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_dpi
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: It is possible to switch the dpi setting of the mouse with the
|
||||
press of a button.
|
||||
When read, this file returns the raw number of the actual dpi
|
||||
setting reported by the mouse. This number has to be further
|
||||
processed to receive the real dpi value.
|
||||
|
||||
VALUE DPI
|
||||
1 800
|
||||
2 1200
|
||||
3 1600
|
||||
4 2000
|
||||
5 2400
|
||||
6 3200
|
||||
|
||||
This file is readonly.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/actual_profile
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: When read, this file returns the number of the actual profile.
|
||||
This file is readonly.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/firmware_version
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: When read, this file returns the raw integer version number of the
|
||||
firmware reported by the mouse. Using the integer value eases
|
||||
further usage in other programs. To receive the real version
|
||||
number the decimal point has to be shifted 2 positions to the
|
||||
left. E.g. a returned value of 138 means 1.38
|
||||
This file is readonly.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/kone_driver_version
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: When read, this file returns the driver version.
|
||||
The format of the string is "v<major>.<minor>.<patchlevel>".
|
||||
This attribute is used by the userland tools to find the sysfs-
|
||||
paths of installed kone-mice and determine the capabilites of
|
||||
the driver. Versions of this driver for old kernels replace
|
||||
usbhid instead of generic-usb. The way to scan for this file
|
||||
has been chosen to provide a consistent way for all supported
|
||||
kernel versions.
|
||||
This file is readonly.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: The mouse can store 5 profiles which can be switched by the
|
||||
press of a button. A profile holds informations like button
|
||||
mappings, sensitivity, the colors of the 5 leds and light
|
||||
effects.
|
||||
When read, these files return the respective profile. The
|
||||
returned data is 975 bytes in size.
|
||||
When written, this file lets one write the respective profile
|
||||
data back to the mouse. The data has to be 975 bytes long.
|
||||
The mouse will reject invalid data, whereas the profile number
|
||||
stored in the profile doesn't need to fit the number of the
|
||||
store.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/settings
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: When read, this file returns the settings stored in the mouse.
|
||||
The size of the data is 36 bytes and holds information like the
|
||||
startup_profile, tcu state and calibration_data.
|
||||
When written, this file lets write settings back to the mouse.
|
||||
The data has to be 36 bytes long. The mouse will reject invalid
|
||||
data.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/startup_profile
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: The integer value of this attribute ranges from 1 to 5.
|
||||
When read, this attribute returns the number of the profile
|
||||
that's active when the mouse is powered on.
|
||||
When written, this file sets the number of the startup profile
|
||||
and the mouse activates this profile immediately.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/tcu
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: The mouse has a "Tracking Control Unit" which lets the user
|
||||
calibrate the laser power to fit the mousepad surface.
|
||||
When read, this file returns the current state of the TCU,
|
||||
where 0 means off and 1 means on.
|
||||
Writing 0 in this file will switch the TCU off.
|
||||
Writing 1 in this file will start the calibration which takes
|
||||
around 6 seconds to complete and activates the TCU.
|
||||
|
||||
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/weight
|
||||
Date: March 2010
|
||||
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
Description: The mouse can be equipped with one of four supplied weights
|
||||
ranging from 5 to 20 grams which are recognized by the mouse
|
||||
and its value can be read out. When read, this file returns the
|
||||
raw value returned by the mouse which eases further processing
|
||||
in other software.
|
||||
The values map to the weights as follows:
|
||||
|
||||
VALUE WEIGHT
|
||||
0 none
|
||||
1 5g
|
||||
2 10g
|
||||
3 15g
|
||||
4 20g
|
||||
|
||||
This file is readonly.
|
|
@ -268,6 +268,13 @@ config HID_QUANTA
|
|||
---help---
|
||||
Support for Quanta Optical Touch dual-touch panels.
|
||||
|
||||
config HID_ROCCAT_KONE
|
||||
tristate "Roccat Kone" if EMBEDDED
|
||||
depends on USB_HID
|
||||
default !EMBEDDED
|
||||
---help---
|
||||
Support for Roccat Kone mouse.
|
||||
|
||||
config HID_SAMSUNG
|
||||
tristate "Samsung" if EMBEDDED
|
||||
depends on USB_HID
|
||||
|
|
|
@ -44,6 +44,7 @@ obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
|
|||
obj-$(CONFIG_HID_QUANTA) += hid-quanta.o
|
||||
obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
|
||||
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
|
||||
obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
|
||||
obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
|
||||
obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
|
||||
obj-$(CONFIG_HID_SONY) += hid-sony.o
|
||||
|
|
|
@ -1346,6 +1346,7 @@ static const struct hid_device_id hid_blacklist[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
|
||||
|
|
|
@ -399,6 +399,9 @@
|
|||
#define USB_VENDOR_ID_PRODIGE 0x05af
|
||||
#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
|
||||
|
||||
#define USB_VENDOR_ID_ROCCAT 0x1e7d
|
||||
#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
|
||||
|
||||
#define USB_VENDOR_ID_SAITEK 0x06a3
|
||||
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
|
||||
|
||||
|
|
1006
drivers/hid/hid-roccat-kone.c
Normal file
1006
drivers/hid/hid-roccat-kone.c
Normal file
File diff suppressed because it is too large
Load diff
214
drivers/hid/hid-roccat-kone.h
Normal file
214
drivers/hid/hid-roccat-kone.h
Normal file
|
@ -0,0 +1,214 @@
|
|||
#ifndef __HID_ROCCAT_KONE_H
|
||||
#define __HID_ROCCAT_KONE_H
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <linux/types.h>
|
||||
|
||||
#define DRIVER_VERSION "v0.3.0"
|
||||
#define DRIVER_AUTHOR "Stefan Achatz"
|
||||
#define DRIVER_DESC "USB Roccat Kone driver"
|
||||
#define DRIVER_LICENSE "GPL v2"
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct kone_keystroke {
|
||||
uint8_t key;
|
||||
uint8_t action;
|
||||
uint16_t period; /* in milliseconds */
|
||||
};
|
||||
|
||||
enum kone_keystroke_buttons {
|
||||
kone_keystroke_button_1 = 0xf0, /* left mouse button */
|
||||
kone_keystroke_button_2 = 0xf1, /* right mouse button */
|
||||
kone_keystroke_button_3 = 0xf2, /* wheel */
|
||||
kone_keystroke_button_9 = 0xf3, /* side button up */
|
||||
kone_keystroke_button_8 = 0xf4 /* side button down */
|
||||
};
|
||||
|
||||
enum kone_keystroke_actions {
|
||||
kone_keystroke_action_press = 0,
|
||||
kone_keystroke_action_release = 1
|
||||
};
|
||||
|
||||
struct kone_button_info {
|
||||
uint8_t number; /* range 1-8 */
|
||||
uint8_t type;
|
||||
uint8_t macro_type; /* 0 = short, 1 = overlong */
|
||||
uint8_t macro_set_name[16]; /* can be max 15 chars long */
|
||||
uint8_t macro_name[16]; /* can be max 15 chars long */
|
||||
uint8_t count;
|
||||
struct kone_keystroke keystrokes[20];
|
||||
};
|
||||
|
||||
enum kone_button_info_types {
|
||||
/* valid button types until firmware 1.32 */
|
||||
kone_button_info_type_button_1 = 0x1, /* click (left mouse button) */
|
||||
kone_button_info_type_button_2 = 0x2, /* menu (right mouse button)*/
|
||||
kone_button_info_type_button_3 = 0x3, /* scroll (wheel) */
|
||||
kone_button_info_type_double_click = 0x4,
|
||||
kone_button_info_type_key = 0x5,
|
||||
kone_button_info_type_macro = 0x6,
|
||||
kone_button_info_type_off = 0x7,
|
||||
/* TODO clarify function and rename */
|
||||
kone_button_info_type_osd_xy_prescaling = 0x8,
|
||||
kone_button_info_type_osd_dpi = 0x9,
|
||||
kone_button_info_type_osd_profile = 0xa,
|
||||
kone_button_info_type_button_9 = 0xb, /* ie forward */
|
||||
kone_button_info_type_button_8 = 0xc, /* ie backward */
|
||||
kone_button_info_type_dpi_up = 0xd, /* internal */
|
||||
kone_button_info_type_dpi_down = 0xe, /* internal */
|
||||
kone_button_info_type_button_7 = 0xf, /* tilt left */
|
||||
kone_button_info_type_button_6 = 0x10, /* tilt right */
|
||||
kone_button_info_type_profile_up = 0x11, /* internal */
|
||||
kone_button_info_type_profile_down = 0x12, /* internal */
|
||||
/* additional valid button types since firmware 1.38 */
|
||||
kone_button_info_type_multimedia_open_player = 0x20,
|
||||
kone_button_info_type_multimedia_next_track = 0x21,
|
||||
kone_button_info_type_multimedia_prev_track = 0x22,
|
||||
kone_button_info_type_multimedia_play_pause = 0x23,
|
||||
kone_button_info_type_multimedia_stop = 0x24,
|
||||
kone_button_info_type_multimedia_mute = 0x25,
|
||||
kone_button_info_type_multimedia_volume_up = 0x26,
|
||||
kone_button_info_type_multimedia_volume_down = 0x27
|
||||
};
|
||||
|
||||
struct kone_light_info {
|
||||
uint8_t number; /* number of light 1-5 */
|
||||
uint8_t mod; /* 1 = on, 2 = off */
|
||||
uint8_t red; /* range 0x00-0xff */
|
||||
uint8_t green; /* range 0x00-0xff */
|
||||
uint8_t blue; /* range 0x00-0xff */
|
||||
};
|
||||
|
||||
struct kone_profile {
|
||||
uint16_t size; /* always 975 */
|
||||
uint16_t unused; /* always 0 */
|
||||
|
||||
/*
|
||||
* range 1-5
|
||||
* This number does not need to correspond with location where profile
|
||||
* saved
|
||||
*/
|
||||
uint8_t profile; /* range 1-5 */
|
||||
|
||||
uint16_t main_sensitivity; /* range 100-1000 */
|
||||
uint8_t xy_sensitivity_enabled; /* 1 = on, 2 = off */
|
||||
uint16_t x_sensitivity; /* range 100-1000 */
|
||||
uint16_t y_sensitivity; /* range 100-1000 */
|
||||
uint8_t dpi_rate; /* bit 1 = 800, ... */
|
||||
uint8_t startup_dpi; /* range 1-6 */
|
||||
uint8_t polling_rate; /* 1 = 125Hz, 2 = 500Hz, 3 = 1000Hz */
|
||||
/* kone has no dcu
|
||||
* value is always 2 in firmwares <= 1.32 and
|
||||
* 1 in firmwares > 1.32
|
||||
*/
|
||||
uint8_t dcu_flag;
|
||||
uint8_t light_effect_1; /* range 1-3 */
|
||||
uint8_t light_effect_2; /* range 1-5 */
|
||||
uint8_t light_effect_3; /* range 1-4 */
|
||||
uint8_t light_effect_speed; /* range 0-255 */
|
||||
|
||||
struct kone_light_info light_infos[5];
|
||||
struct kone_button_info button_infos[8];
|
||||
|
||||
uint16_t checksum; /* \brief holds checksum of struct */
|
||||
};
|
||||
|
||||
enum kone_polling_rates {
|
||||
kone_polling_rate_125 = 1,
|
||||
kone_polling_rate_500 = 2,
|
||||
kone_polling_rate_1000 = 3
|
||||
};
|
||||
|
||||
struct kone_settings {
|
||||
uint16_t size; /* always 36 */
|
||||
uint8_t startup_profile; /* 1-5 */
|
||||
uint8_t unknown1;
|
||||
uint8_t tcu; /* 0 = off, 1 = on */
|
||||
uint8_t unknown2[23];
|
||||
uint8_t calibration_data[4];
|
||||
uint8_t unknown3[2];
|
||||
uint16_t checksum;
|
||||
};
|
||||
|
||||
/*
|
||||
* 12 byte mouse event read by interrupt_read
|
||||
*/
|
||||
struct kone_mouse_event {
|
||||
uint8_t report_number; /* always 1 */
|
||||
uint8_t button;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint8_t wheel; /* up = 1, down = -1 */
|
||||
uint8_t tilt; /* right = 1, left = -1 */
|
||||
uint8_t unknown;
|
||||
uint8_t event;
|
||||
uint8_t value; /* press = 0, release = 1 */
|
||||
uint8_t macro_key; /* 0 to 8 */
|
||||
};
|
||||
|
||||
enum kone_mouse_events {
|
||||
/* osd events are thought to be display on screen */
|
||||
kone_mouse_event_osd_dpi = 0xa0,
|
||||
kone_mouse_event_osd_profile = 0xb0,
|
||||
/* TODO clarify meaning and occurence of kone_mouse_event_calibration */
|
||||
kone_mouse_event_calibration = 0xc0,
|
||||
kone_mouse_event_call_overlong_macro = 0xe0,
|
||||
/* switch events notify if user changed values wiht mousebutton click */
|
||||
kone_mouse_event_switch_dpi = 0xf0,
|
||||
kone_mouse_event_switch_profile = 0xf1
|
||||
};
|
||||
|
||||
enum kone_commands {
|
||||
kone_command_profile = 0x5a,
|
||||
kone_command_settings = 0x15a,
|
||||
kone_command_firmware_version = 0x25a,
|
||||
kone_command_weight = 0x45a,
|
||||
kone_command_calibrate = 0x55a,
|
||||
kone_command_confirm_write = 0x65a,
|
||||
kone_command_firmware = 0xe5a
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct kone_device {
|
||||
/*
|
||||
* Storing actual values when we get informed about changes since there
|
||||
* is no way of getting this information from the device on demand
|
||||
*/
|
||||
int actual_profile, actual_dpi;
|
||||
/* Used for neutralizing abnormal tilt button behaviour */
|
||||
int last_tilt_state;
|
||||
/*
|
||||
* It's unlikely that multiple sysfs attributes are accessed at a time,
|
||||
* so only one mutex is used to secure hardware access and profiles and
|
||||
* settings of this struct.
|
||||
*/
|
||||
struct mutex kone_lock;
|
||||
|
||||
/*
|
||||
* Storing the data here reduces IO and ensures that data is available
|
||||
* when its needed (E.g. interrupt handler).
|
||||
*/
|
||||
struct kone_profile profiles[5];
|
||||
struct kone_settings settings;
|
||||
|
||||
/*
|
||||
* firmware doesn't change unless firmware update is implemented,
|
||||
* so it's read only once
|
||||
*/
|
||||
int firmware_version;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue