aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Achatz <erazor_de@users.sourceforge.net>2013-10-28 13:52:07 -0400
committerJiri Kosina <jkosina@suse.cz>2013-10-30 09:17:31 -0400
commit6f3a19360545bf8c646a4d079a8c023ae06838de (patch)
tree6589253ca7700eaf74c2b032b679cd9dbe88c145
parent71304f5a269abc25b9277744dfd6925f3e29e26a (diff)
HID: roccat: add support for Ryos MK keyboards
Added support for 3 keyboards with increasing illumination capabilities Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos178
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-core.c3
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/hid/hid-roccat-ryos.c241
5 files changed, 426 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos b/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos
new file mode 100644
index 000000000000..1d6a8cf9dc0a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos
@@ -0,0 +1,178 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/control
2Date: October 2013
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: When written, this file lets one select which data from which
5 profile will be read next. The data has to be 3 bytes long.
6 This file is writeonly.
7Users: http://roccat.sourceforge.net
8
9What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/profile
10Date: October 2013
11Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
12Description: The mouse can store 5 profiles which can be switched by the
13 press of a button. profile holds index of actual profile.
14 This value is persistent, so its value determines the profile
15 that's active when the device is powered on next time.
16 When written, the device activates the set profile immediately.
17 The data has to be 3 bytes long.
18 The device will reject invalid data.
19Users: http://roccat.sourceforge.net
20
21What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_primary
22Date: October 2013
23Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
24Description: When written, this file lets one set the default of all keys for
25 a specific profile. Profile index is included in written data.
26 The data has to be 125 bytes long.
27 Before reading this file, control has to be written to select
28 which profile to read.
29Users: http://roccat.sourceforge.net
30
31What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_function
32Date: October 2013
33Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
34Description: When written, this file lets one set the function of the
35 function keys for a specific profile. Profile index is included
36 in written data. The data has to be 95 bytes long.
37 Before reading this file, control has to be written to select
38 which profile to read.
39Users: http://roccat.sourceforge.net
40
41What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_macro
42Date: October 2013
43Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
44Description: When written, this file lets one set the function of the macro
45 keys for a specific profile. Profile index is included in
46 written data. The data has to be 35 bytes long.
47 Before reading this file, control has to be written to select
48 which profile to read.
49Users: http://roccat.sourceforge.net
50
51What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_thumbster
52Date: October 2013
53Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
54Description: When written, this file lets one set the function of the
55 thumbster keys for a specific profile. Profile index is included
56 in written data. The data has to be 23 bytes long.
57 Before reading this file, control has to be written to select
58 which profile to read.
59Users: http://roccat.sourceforge.net
60
61What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_extra
62Date: October 2013
63Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
64Description: When written, this file lets one set the function of the
65 capslock and function keys for a specific profile. Profile index
66 is included in written data. The data has to be 8 bytes long.
67 Before reading this file, control has to be written to select
68 which profile to read.
69Users: http://roccat.sourceforge.net
70
71What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_easyzone
72Date: October 2013
73Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
74Description: When written, this file lets one set the function of the
75 easyzone keys for a specific profile. Profile index is included
76 in written data. The data has to be 294 bytes long.
77 Before reading this file, control has to be written to select
78 which profile to read.
79Users: http://roccat.sourceforge.net
80
81What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/key_mask
82Date: October 2013
83Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
84Description: When written, this file lets one deactivate certain keys like
85 windows and application keys, to prevent accidental presses.
86 Profile index for which this settings occur is included in
87 written data. The data has to be 6 bytes long.
88 Before reading this file, control has to be written to select
89 which profile to read.
90Users: http://roccat.sourceforge.net
91
92What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light
93Date: October 2013
94Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
95Description: When written, this file lets one set the backlight intensity for
96 a specific profile. Profile index is included in written data.
97 This attribute is only valid for the glow and pro variant.
98 The data has to be 16 bytes long.
99 Before reading this file, control has to be written to select
100 which profile to read.
101Users: http://roccat.sourceforge.net
102
103What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/macro
104Date: October 2013
105Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
106Description: When written, this file lets one store macros with max 480
107 keystrokes for a specific button for a specific profile.
108 Button and profile indexes are included in written data.
109 The data has to be 2002 bytes long.
110 Before reading this file, control has to be written to select
111 which profile and key to read.
112Users: http://roccat.sourceforge.net
113
114What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/info
115Date: October 2013
116Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
117Description: When read, this file returns general data like firmware version.
118 The data is 8 bytes long.
119 This file is readonly.
120Users: http://roccat.sourceforge.net
121
122What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/reset
123Date: October 2013
124Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
125Description: When written, this file lets one reset the device.
126 The data has to be 3 bytes long.
127 This file is writeonly.
128Users: http://roccat.sourceforge.net
129
130What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/talk
131Date: October 2013
132Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
133Description: When written, this file lets one trigger easyshift functionality
134 from the host.
135 The data has to be 16 bytes long.
136 This file is writeonly.
137Users: http://roccat.sourceforge.net
138
139What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light_control
140Date: October 2013
141Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
142Description: When written, this file lets one switch between stored and custom
143 light settings.
144 This attribute is only valid for the pro variant.
145 The data has to be 8 bytes long.
146 This file is writeonly.
147Users: http://roccat.sourceforge.net
148
149What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/stored_lights
150Date: October 2013
151Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
152Description: When written, this file lets one set per-key lighting for different
153 layers.
154 This attribute is only valid for the pro variant.
155 The data has to be 1382 bytes long.
156 Before reading this file, control has to be written to select
157 which profile to read.
158Users: http://roccat.sourceforge.net
159
160What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/custom_lights
161Date: October 2013
162Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
163Description: When written, this file lets one set the actual per-key lighting.
164 This attribute is only valid for the pro variant.
165 The data has to be 20 bytes long.
166 This file is writeonly.
167Users: http://roccat.sourceforge.net
168
169What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light_macro
170Date: October 2013
171Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
172Description: When written, this file lets one set a light macro that is looped
173 whenever the device gets in dimness mode.
174 This attribute is only valid for the pro variant.
175 The data has to be 2002 bytes long.
176 Before reading this file, control has to be written to select
177 which profile to read.
178Users: http://roccat.sourceforge.net
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a959f4aecaf5..30e44318f87f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -95,7 +95,7 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
95obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 95obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
96 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ 96 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
97 hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ 97 hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
98 hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-savu.o 98 hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-ryos.o hid-roccat-savu.o
99obj-$(CONFIG_HID_SAITEK) += hid-saitek.o 99obj-$(CONFIG_HID_SAITEK) += hid-saitek.o
100obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 100obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index e80da62363bc..00794229a2cf 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1811,6 +1811,9 @@ static const struct hid_device_id hid_have_special_driver[] = {
1811 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, 1811 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
1812 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, 1812 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1813 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, 1813 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
1814 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK) },
1815 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW) },
1816 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
1814 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, 1817 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
1815#endif 1818#endif
1816 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, 1819 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index f0296a50be5f..768fafc42c87 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -726,6 +726,9 @@
726#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e 726#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e
727#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 727#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
728#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 728#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
729#define USB_DEVICE_ID_ROCCAT_RYOS_MK 0x3138
730#define USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW 0x31ce
731#define USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO 0x3232
729#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a 732#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a
730 733
731#define USB_VENDOR_ID_SAITEK 0x06a3 734#define USB_VENDOR_ID_SAITEK 0x06a3
diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c
new file mode 100644
index 000000000000..47cc8f30ff6d
--- /dev/null
+++ b/drivers/hid/hid-roccat-ryos.c
@@ -0,0 +1,241 @@
1/*
2 * Roccat Ryos driver for Linux
3 *
4 * Copyright (c) 2013 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/types.h>
15#include <linux/device.h>
16#include <linux/input.h>
17#include <linux/hid.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/hid-roccat.h>
21#include "hid-ids.h"
22#include "hid-roccat-common.h"
23
24enum {
25 RYOS_REPORT_NUMBER_SPECIAL = 3,
26 RYOS_USB_INTERFACE_PROTOCOL = 0,
27};
28
29struct ryos_report_special {
30 uint8_t number; /* RYOS_REPORT_NUMBER_SPECIAL */
31 uint8_t data[4];
32} __packed;
33
34static struct class *ryos_class;
35
36ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x04, 0x03);
37ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x05, 0x03);
38ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_primary, 0x06, 0x7d);
39ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_function, 0x07, 0x5f);
40ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_macro, 0x08, 0x23);
41ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_thumbster, 0x09, 0x17);
42ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_extra, 0x0a, 0x08);
43ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_easyzone, 0x0b, 0x126);
44ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(key_mask, 0x0c, 0x06);
45ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(light, 0x0d, 0x10);
46ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x0e, 0x7d2);
47ROCCAT_COMMON2_BIN_ATTRIBUTE_R(info, 0x0f, 0x08);
48ROCCAT_COMMON2_BIN_ATTRIBUTE_W(reset, 0x11, 0x03);
49ROCCAT_COMMON2_BIN_ATTRIBUTE_W(light_control, 0x13, 0x08);
50ROCCAT_COMMON2_BIN_ATTRIBUTE_W(talk, 0x16, 0x10);
51ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(stored_lights, 0x17, 0x0566);
52ROCCAT_COMMON2_BIN_ATTRIBUTE_W(custom_lights, 0x18, 0x14);
53ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(light_macro, 0x19, 0x07d2);
54
55static struct bin_attribute *ryos_bin_attrs[] = {
56 &bin_attr_control,
57 &bin_attr_profile,
58 &bin_attr_keys_primary,
59 &bin_attr_keys_function,
60 &bin_attr_keys_macro,
61 &bin_attr_keys_thumbster,
62 &bin_attr_keys_extra,
63 &bin_attr_keys_easyzone,
64 &bin_attr_key_mask,
65 &bin_attr_light,
66 &bin_attr_macro,
67 &bin_attr_info,
68 &bin_attr_reset,
69 &bin_attr_light_control,
70 &bin_attr_talk,
71 &bin_attr_stored_lights,
72 &bin_attr_custom_lights,
73 &bin_attr_light_macro,
74 NULL,
75};
76
77static const struct attribute_group ryos_group = {
78 .bin_attrs = ryos_bin_attrs,
79};
80
81static const struct attribute_group *ryos_groups[] = {
82 &ryos_group,
83 NULL,
84};
85
86static int ryos_init_specials(struct hid_device *hdev)
87{
88 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
89 struct usb_device *usb_dev = interface_to_usbdev(intf);
90 struct roccat_common2_device *ryos;
91 int retval;
92
93 if (intf->cur_altsetting->desc.bInterfaceProtocol
94 != RYOS_USB_INTERFACE_PROTOCOL) {
95 hid_set_drvdata(hdev, NULL);
96 return 0;
97 }
98
99 ryos = kzalloc(sizeof(*ryos), GFP_KERNEL);
100 if (!ryos) {
101 hid_err(hdev, "can't alloc device descriptor\n");
102 return -ENOMEM;
103 }
104 hid_set_drvdata(hdev, ryos);
105
106 retval = roccat_common2_device_init_struct(usb_dev, ryos);
107 if (retval) {
108 hid_err(hdev, "couldn't init Ryos device\n");
109 goto exit_free;
110 }
111
112 retval = roccat_connect(ryos_class, hdev,
113 sizeof(struct ryos_report_special));
114 if (retval < 0) {
115 hid_err(hdev, "couldn't init char dev\n");
116 } else {
117 ryos->chrdev_minor = retval;
118 ryos->roccat_claimed = 1;
119 }
120
121 return 0;
122exit_free:
123 kfree(ryos);
124 return retval;
125}
126
127static void ryos_remove_specials(struct hid_device *hdev)
128{
129 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
130 struct roccat_common2_device *ryos;
131
132 if (intf->cur_altsetting->desc.bInterfaceProtocol
133 != RYOS_USB_INTERFACE_PROTOCOL)
134 return;
135
136 ryos = hid_get_drvdata(hdev);
137 if (ryos->roccat_claimed)
138 roccat_disconnect(ryos->chrdev_minor);
139 kfree(ryos);
140}
141
142static int ryos_probe(struct hid_device *hdev,
143 const struct hid_device_id *id)
144{
145 int retval;
146
147 retval = hid_parse(hdev);
148 if (retval) {
149 hid_err(hdev, "parse failed\n");
150 goto exit;
151 }
152
153 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
154 if (retval) {
155 hid_err(hdev, "hw start failed\n");
156 goto exit;
157 }
158
159 retval = ryos_init_specials(hdev);
160 if (retval) {
161 hid_err(hdev, "couldn't install mouse\n");
162 goto exit_stop;
163 }
164
165 return 0;
166
167exit_stop:
168 hid_hw_stop(hdev);
169exit:
170 return retval;
171}
172
173static void ryos_remove(struct hid_device *hdev)
174{
175 ryos_remove_specials(hdev);
176 hid_hw_stop(hdev);
177}
178
179static int ryos_raw_event(struct hid_device *hdev,
180 struct hid_report *report, u8 *data, int size)
181{
182 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
183 struct roccat_common2_device *ryos = hid_get_drvdata(hdev);
184
185 if (intf->cur_altsetting->desc.bInterfaceProtocol
186 != RYOS_USB_INTERFACE_PROTOCOL)
187 return 0;
188
189 if (data[0] != RYOS_REPORT_NUMBER_SPECIAL)
190 return 0;
191
192 if (ryos != NULL && ryos->roccat_claimed)
193 roccat_report_event(ryos->chrdev_minor, data);
194
195 return 0;
196}
197
198static const struct hid_device_id ryos_devices[] = {
199 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK) },
200 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW) },
201 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
202 { }
203};
204
205MODULE_DEVICE_TABLE(hid, ryos_devices);
206
207static struct hid_driver ryos_driver = {
208 .name = "ryos",
209 .id_table = ryos_devices,
210 .probe = ryos_probe,
211 .remove = ryos_remove,
212 .raw_event = ryos_raw_event
213};
214
215static int __init ryos_init(void)
216{
217 int retval;
218
219 ryos_class = class_create(THIS_MODULE, "ryos");
220 if (IS_ERR(ryos_class))
221 return PTR_ERR(ryos_class);
222 ryos_class->dev_groups = ryos_groups;
223
224 retval = hid_register_driver(&ryos_driver);
225 if (retval)
226 class_destroy(ryos_class);
227 return retval;
228}
229
230static void __exit ryos_exit(void)
231{
232 hid_unregister_driver(&ryos_driver);
233 class_destroy(ryos_class);
234}
235
236module_init(ryos_init);
237module_exit(ryos_exit);
238
239MODULE_AUTHOR("Stefan Achatz");
240MODULE_DESCRIPTION("USB Roccat Ryos MK/Glow/Pro driver");
241MODULE_LICENSE("GPL v2");