1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Roccat Arvo driver for Linux
5 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
12 * Roccat Arvo is a gamer keyboard with 5 macro keys that can be configured in
16 #include <linux/device.h>
17 #include <linux/input.h>
18 #include <linux/hid.h>
19 #include <linux/module.h>
20 #include <linux/slab.h>
21 #include <linux/hid-roccat.h>
23 #include "hid-roccat-common.h"
24 #include "hid-roccat-arvo.h"
26 static struct class *arvo_class
;
28 static ssize_t
arvo_sysfs_show_mode_key(struct device
*dev
,
29 struct device_attribute
*attr
, char *buf
)
31 struct arvo_device
*arvo
=
32 hid_get_drvdata(dev_get_drvdata(dev
->parent
->parent
));
33 struct usb_device
*usb_dev
=
34 interface_to_usbdev(to_usb_interface(dev
->parent
->parent
));
35 struct arvo_mode_key temp_buf
;
38 mutex_lock(&arvo
->arvo_lock
);
39 retval
= roccat_common2_receive(usb_dev
, ARVO_COMMAND_MODE_KEY
,
40 &temp_buf
, sizeof(struct arvo_mode_key
));
41 mutex_unlock(&arvo
->arvo_lock
);
45 return snprintf(buf
, PAGE_SIZE
, "%d\n", temp_buf
.state
);
48 static ssize_t
arvo_sysfs_set_mode_key(struct device
*dev
,
49 struct device_attribute
*attr
, char const *buf
, size_t size
)
51 struct arvo_device
*arvo
=
52 hid_get_drvdata(dev_get_drvdata(dev
->parent
->parent
));
53 struct usb_device
*usb_dev
=
54 interface_to_usbdev(to_usb_interface(dev
->parent
->parent
));
55 struct arvo_mode_key temp_buf
;
59 retval
= kstrtoul(buf
, 10, &state
);
63 temp_buf
.command
= ARVO_COMMAND_MODE_KEY
;
64 temp_buf
.state
= state
;
66 mutex_lock(&arvo
->arvo_lock
);
67 retval
= roccat_common2_send(usb_dev
, ARVO_COMMAND_MODE_KEY
,
68 &temp_buf
, sizeof(struct arvo_mode_key
));
69 mutex_unlock(&arvo
->arvo_lock
);
75 static DEVICE_ATTR(mode_key
, 0660,
76 arvo_sysfs_show_mode_key
, arvo_sysfs_set_mode_key
);
78 static ssize_t
arvo_sysfs_show_key_mask(struct device
*dev
,
79 struct device_attribute
*attr
, char *buf
)
81 struct arvo_device
*arvo
=
82 hid_get_drvdata(dev_get_drvdata(dev
->parent
->parent
));
83 struct usb_device
*usb_dev
=
84 interface_to_usbdev(to_usb_interface(dev
->parent
->parent
));
85 struct arvo_key_mask temp_buf
;
88 mutex_lock(&arvo
->arvo_lock
);
89 retval
= roccat_common2_receive(usb_dev
, ARVO_COMMAND_KEY_MASK
,
90 &temp_buf
, sizeof(struct arvo_key_mask
));
91 mutex_unlock(&arvo
->arvo_lock
);
95 return snprintf(buf
, PAGE_SIZE
, "%d\n", temp_buf
.key_mask
);
98 static ssize_t
arvo_sysfs_set_key_mask(struct device
*dev
,
99 struct device_attribute
*attr
, char const *buf
, size_t size
)
101 struct arvo_device
*arvo
=
102 hid_get_drvdata(dev_get_drvdata(dev
->parent
->parent
));
103 struct usb_device
*usb_dev
=
104 interface_to_usbdev(to_usb_interface(dev
->parent
->parent
));
105 struct arvo_key_mask temp_buf
;
106 unsigned long key_mask
;
109 retval
= kstrtoul(buf
, 10, &key_mask
);
113 temp_buf
.command
= ARVO_COMMAND_KEY_MASK
;
114 temp_buf
.key_mask
= key_mask
;
116 mutex_lock(&arvo
->arvo_lock
);
117 retval
= roccat_common2_send(usb_dev
, ARVO_COMMAND_KEY_MASK
,
118 &temp_buf
, sizeof(struct arvo_key_mask
));
119 mutex_unlock(&arvo
->arvo_lock
);
125 static DEVICE_ATTR(key_mask
, 0660,
126 arvo_sysfs_show_key_mask
, arvo_sysfs_set_key_mask
);
128 /* retval is 1-5 on success, < 0 on error */
129 static int arvo_get_actual_profile(struct usb_device
*usb_dev
)
131 struct arvo_actual_profile temp_buf
;
134 retval
= roccat_common2_receive(usb_dev
, ARVO_COMMAND_ACTUAL_PROFILE
,
135 &temp_buf
, sizeof(struct arvo_actual_profile
));
140 return temp_buf
.actual_profile
;
143 static ssize_t
arvo_sysfs_show_actual_profile(struct device
*dev
,
144 struct device_attribute
*attr
, char *buf
)
146 struct arvo_device
*arvo
=
147 hid_get_drvdata(dev_get_drvdata(dev
->parent
->parent
));
149 return snprintf(buf
, PAGE_SIZE
, "%d\n", arvo
->actual_profile
);
152 static ssize_t
arvo_sysfs_set_actual_profile(struct device
*dev
,
153 struct device_attribute
*attr
, char const *buf
, size_t size
)
155 struct arvo_device
*arvo
=
156 hid_get_drvdata(dev_get_drvdata(dev
->parent
->parent
));
157 struct usb_device
*usb_dev
=
158 interface_to_usbdev(to_usb_interface(dev
->parent
->parent
));
159 struct arvo_actual_profile temp_buf
;
160 unsigned long profile
;
163 retval
= kstrtoul(buf
, 10, &profile
);
167 if (profile
< 1 || profile
> 5)
170 temp_buf
.command
= ARVO_COMMAND_ACTUAL_PROFILE
;
171 temp_buf
.actual_profile
= profile
;
173 mutex_lock(&arvo
->arvo_lock
);
174 retval
= roccat_common2_send(usb_dev
, ARVO_COMMAND_ACTUAL_PROFILE
,
175 &temp_buf
, sizeof(struct arvo_actual_profile
));
177 arvo
->actual_profile
= profile
;
180 mutex_unlock(&arvo
->arvo_lock
);
183 static DEVICE_ATTR(actual_profile
, 0660,
184 arvo_sysfs_show_actual_profile
,
185 arvo_sysfs_set_actual_profile
);
187 static ssize_t
arvo_sysfs_write(struct file
*fp
,
188 struct kobject
*kobj
, void const *buf
,
189 loff_t off
, size_t count
, size_t real_size
, uint command
)
191 struct device
*dev
= kobj_to_dev(kobj
)->parent
->parent
;
192 struct arvo_device
*arvo
= hid_get_drvdata(dev_get_drvdata(dev
));
193 struct usb_device
*usb_dev
= interface_to_usbdev(to_usb_interface(dev
));
196 if (off
!= 0 || count
!= real_size
)
199 mutex_lock(&arvo
->arvo_lock
);
200 retval
= roccat_common2_send(usb_dev
, command
, buf
, real_size
);
201 mutex_unlock(&arvo
->arvo_lock
);
203 return (retval
? retval
: real_size
);
206 static ssize_t
arvo_sysfs_read(struct file
*fp
,
207 struct kobject
*kobj
, void *buf
, loff_t off
,
208 size_t count
, size_t real_size
, uint command
)
210 struct device
*dev
= kobj_to_dev(kobj
)->parent
->parent
;
211 struct arvo_device
*arvo
= hid_get_drvdata(dev_get_drvdata(dev
));
212 struct usb_device
*usb_dev
= interface_to_usbdev(to_usb_interface(dev
));
215 if (off
>= real_size
)
218 if (off
!= 0 || count
!= real_size
)
221 mutex_lock(&arvo
->arvo_lock
);
222 retval
= roccat_common2_receive(usb_dev
, command
, buf
, real_size
);
223 mutex_unlock(&arvo
->arvo_lock
);
225 return (retval
? retval
: real_size
);
228 static ssize_t
arvo_sysfs_write_button(struct file
*fp
,
229 struct kobject
*kobj
, struct bin_attribute
*attr
, char *buf
,
230 loff_t off
, size_t count
)
232 return arvo_sysfs_write(fp
, kobj
, buf
, off
, count
,
233 sizeof(struct arvo_button
), ARVO_COMMAND_BUTTON
);
235 static BIN_ATTR(button
, 0220, NULL
, arvo_sysfs_write_button
,
236 sizeof(struct arvo_button
));
238 static ssize_t
arvo_sysfs_read_info(struct file
*fp
,
239 struct kobject
*kobj
, struct bin_attribute
*attr
, char *buf
,
240 loff_t off
, size_t count
)
242 return arvo_sysfs_read(fp
, kobj
, buf
, off
, count
,
243 sizeof(struct arvo_info
), ARVO_COMMAND_INFO
);
245 static BIN_ATTR(info
, 0440, arvo_sysfs_read_info
, NULL
,
246 sizeof(struct arvo_info
));
248 static struct attribute
*arvo_attrs
[] = {
249 &dev_attr_mode_key
.attr
,
250 &dev_attr_key_mask
.attr
,
251 &dev_attr_actual_profile
.attr
,
255 static struct bin_attribute
*arvo_bin_attributes
[] = {
261 static const struct attribute_group arvo_group
= {
263 .bin_attrs
= arvo_bin_attributes
,
266 static const struct attribute_group
*arvo_groups
[] = {
271 static int arvo_init_arvo_device_struct(struct usb_device
*usb_dev
,
272 struct arvo_device
*arvo
)
276 mutex_init(&arvo
->arvo_lock
);
278 retval
= arvo_get_actual_profile(usb_dev
);
281 arvo
->actual_profile
= retval
;
286 static int arvo_init_specials(struct hid_device
*hdev
)
288 struct usb_interface
*intf
= to_usb_interface(hdev
->dev
.parent
);
289 struct usb_device
*usb_dev
= interface_to_usbdev(intf
);
290 struct arvo_device
*arvo
;
293 if (intf
->cur_altsetting
->desc
.bInterfaceProtocol
294 == USB_INTERFACE_PROTOCOL_KEYBOARD
) {
295 hid_set_drvdata(hdev
, NULL
);
299 arvo
= kzalloc(sizeof(*arvo
), GFP_KERNEL
);
301 hid_err(hdev
, "can't alloc device descriptor\n");
304 hid_set_drvdata(hdev
, arvo
);
306 retval
= arvo_init_arvo_device_struct(usb_dev
, arvo
);
308 hid_err(hdev
, "couldn't init struct arvo_device\n");
312 retval
= roccat_connect(arvo_class
, hdev
,
313 sizeof(struct arvo_roccat_report
));
315 hid_err(hdev
, "couldn't init char dev\n");
317 arvo
->chrdev_minor
= retval
;
318 arvo
->roccat_claimed
= 1;
327 static void arvo_remove_specials(struct hid_device
*hdev
)
329 struct usb_interface
*intf
= to_usb_interface(hdev
->dev
.parent
);
330 struct arvo_device
*arvo
;
332 if (intf
->cur_altsetting
->desc
.bInterfaceProtocol
333 == USB_INTERFACE_PROTOCOL_KEYBOARD
)
336 arvo
= hid_get_drvdata(hdev
);
337 if (arvo
->roccat_claimed
)
338 roccat_disconnect(arvo
->chrdev_minor
);
342 static int arvo_probe(struct hid_device
*hdev
,
343 const struct hid_device_id
*id
)
347 retval
= hid_parse(hdev
);
349 hid_err(hdev
, "parse failed\n");
353 retval
= hid_hw_start(hdev
, HID_CONNECT_DEFAULT
);
355 hid_err(hdev
, "hw start failed\n");
359 retval
= arvo_init_specials(hdev
);
361 hid_err(hdev
, "couldn't install keyboard\n");
373 static void arvo_remove(struct hid_device
*hdev
)
375 arvo_remove_specials(hdev
);
379 static void arvo_report_to_chrdev(struct arvo_device
const *arvo
,
382 struct arvo_special_report
const *special_report
;
383 struct arvo_roccat_report roccat_report
;
385 special_report
= (struct arvo_special_report
const *)data
;
387 roccat_report
.profile
= arvo
->actual_profile
;
388 roccat_report
.button
= special_report
->event
&
389 ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON
;
390 if ((special_report
->event
& ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION
) ==
391 ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS
)
392 roccat_report
.action
= ARVO_ROCCAT_REPORT_ACTION_PRESS
;
394 roccat_report
.action
= ARVO_ROCCAT_REPORT_ACTION_RELEASE
;
396 roccat_report_event(arvo
->chrdev_minor
,
397 (uint8_t const *)&roccat_report
);
400 static int arvo_raw_event(struct hid_device
*hdev
,
401 struct hid_report
*report
, u8
*data
, int size
)
403 struct arvo_device
*arvo
= hid_get_drvdata(hdev
);
408 if (arvo
&& arvo
->roccat_claimed
)
409 arvo_report_to_chrdev(arvo
, data
);
414 static const struct hid_device_id arvo_devices
[] = {
415 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT
, USB_DEVICE_ID_ROCCAT_ARVO
) },
419 MODULE_DEVICE_TABLE(hid
, arvo_devices
);
421 static struct hid_driver arvo_driver
= {
423 .id_table
= arvo_devices
,
425 .remove
= arvo_remove
,
426 .raw_event
= arvo_raw_event
429 static int __init
arvo_init(void)
433 arvo_class
= class_create(THIS_MODULE
, "arvo");
434 if (IS_ERR(arvo_class
))
435 return PTR_ERR(arvo_class
);
436 arvo_class
->dev_groups
= arvo_groups
;
438 retval
= hid_register_driver(&arvo_driver
);
440 class_destroy(arvo_class
);
444 static void __exit
arvo_exit(void)
446 hid_unregister_driver(&arvo_driver
);
447 class_destroy(arvo_class
);
450 module_init(arvo_init
);
451 module_exit(arvo_exit
);
453 MODULE_AUTHOR("Stefan Achatz");
454 MODULE_DESCRIPTION("USB Roccat Arvo driver");
455 MODULE_LICENSE("GPL v2");