1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Roccat Kone driver for Linux
4 *
5 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 */
10
11/*
12 * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard
13 * part. The keyboard part enables the mouse to execute stored macros with mixed
14 * key- and button-events.
15 *
16 * TODO implement on-the-fly polling-rate change
17 *      The windows driver has the ability to change the polling rate of the
18 *      device on the press of a mousebutton.
19 *      Is it possible to remove and reinstall the urb in raw-event- or any
20 *      other handler, or to defer this action to be executed somewhere else?
21 *
22 * TODO is it possible to overwrite group for sysfs attributes via udev?
23 */
24
25#include <linux/device.h>
26#include <linux/input.h>
27#include <linux/hid.h>
28#include <linux/module.h>
29#include <linux/slab.h>
30#include <linux/hid-roccat.h>
31#include "hid-ids.h"
32#include "hid-roccat-common.h"
33#include "hid-roccat-kone.h"
34
35static uint profile_numbers[5] = {0, 1, 2, 3, 4};
36
37static void kone_profile_activated(struct kone_device *kone, uint new_profile)
38{
39	kone->actual_profile = new_profile;
40	kone->actual_dpi = kone->profiles[new_profile - 1].startup_dpi;
41}
42
43static void kone_profile_report(struct kone_device *kone, uint new_profile)
44{
45	struct kone_roccat_report roccat_report;
46
47	roccat_report.event = kone_mouse_event_switch_profile;
48	roccat_report.value = new_profile;
49	roccat_report.key = 0;
50	roccat_report_event(kone->chrdev_minor, (uint8_t *)&roccat_report);
51}
52
53static int kone_receive(struct usb_device *usb_dev, uint usb_command,
54		void *data, uint size)
55{
56	char *buf;
57	int len;
58
59	buf = kmalloc(size, GFP_KERNEL);
60	if (buf == NULL)
61		return -ENOMEM;
62
63	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
64			HID_REQ_GET_REPORT,
65			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
66			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
67
68	memcpy(data, buf, size);
69	kfree(buf);
70	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
71}
72
73static int kone_send(struct usb_device *usb_dev, uint usb_command,
74		void const *data, uint size)
75{
76	char *buf;
77	int len;
78
79	buf = kmemdup(data, size, GFP_KERNEL);
80	if (buf == NULL)
81		return -ENOMEM;
82
83	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
84			HID_REQ_SET_REPORT,
85			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
86			usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
87
88	kfree(buf);
89	return ((len < 0) ? len : ((len != size) ? -EIO : 0));
90}
91
92static void kone_set_settings_checksum(struct kone_settings *settings)
93{
94	uint16_t checksum = 0;
95	unsigned char *address = (unsigned char *)settings;
96	int i;
97
98	for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address)
99		checksum += *address;
100	settings->checksum = cpu_to_le16(checksum);
101}
102
103/*
104 * Checks success after writing data to mouse
105 * On success returns 0
106 * On failure returns errno
107 */
108static int kone_check_write(struct usb_device *usb_dev)
109{
110	int retval;
111	uint8_t data;
112
113	do {
114		/*
115		 * Mouse needs 50 msecs until it says ok, but there are
116		 * 30 more msecs needed for next write to work.
117		 */
118		msleep(80);
119
120		retval = kone_receive(usb_dev,
121				kone_command_confirm_write, &data, 1);
122		if (retval)
123			return retval;
124
125		/*
126		 * value of 3 seems to mean something like
127		 * "not finished yet, but it looks good"
128		 * So check again after a moment.
129		 */
130	} while (data == 3);
131
132	if (data == 1) /* everything alright */
133		return 0;
134
135	/* unknown answer */
136	dev_err(&usb_dev->dev, "got retval %d when checking write\n", data);
137	return -EIO;
138}
139
140/*
141 * Reads settings from mouse and stores it in @buf
142 * On success returns 0
143 * On failure returns errno
144 */
145static int kone_get_settings(struct usb_device *usb_dev,
146		struct kone_settings *buf)
147{
148	return kone_receive(usb_dev, kone_command_settings, buf,
149			sizeof(struct kone_settings));
150}
151
152/*
153 * Writes settings from @buf to mouse
154 * On success returns 0
155 * On failure returns errno
156 */
157static int kone_set_settings(struct usb_device *usb_dev,
158		struct kone_settings const *settings)
159{
160	int retval;
161
162	retval = kone_send(usb_dev, kone_command_settings,
163			settings, sizeof(struct kone_settings));
164	if (retval)
165		return retval;
166	return kone_check_write(usb_dev);
167}
168
169/*
170 * Reads profile data from mouse and stores it in @buf
171 * @number: profile number to read
172 * On success returns 0
173 * On failure returns errno
174 */
175static int kone_get_profile(struct usb_device *usb_dev,
176		struct kone_profile *buf, int number)
177{
178	int len;
179
180	if (number < 1 || number > 5)
181		return -EINVAL;
182
183	len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
184			USB_REQ_CLEAR_FEATURE,
185			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
186			kone_command_profile, number, buf,
187			sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT);
188
189	if (len != sizeof(struct kone_profile))
190		return -EIO;
191
192	return 0;
193}
194
195/*
196 * Writes profile data to mouse.
197 * @number: profile number to write
198 * On success returns 0
199 * On failure returns errno
200 */
201static int kone_set_profile(struct usb_device *usb_dev,
202		struct kone_profile const *profile, int number)
203{
204	int len;
205
206	if (number < 1 || number > 5)
207		return -EINVAL;
208
209	len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
210			USB_REQ_SET_CONFIGURATION,
211			USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
212			kone_command_profile, number, (void *)profile,
213			sizeof(struct kone_profile),
214			USB_CTRL_SET_TIMEOUT);
215
216	if (len != sizeof(struct kone_profile))
217		return len;
218
219	if (kone_check_write(usb_dev))
220		return -EIO;
221
222	return 0;
223}
224
225/*
226 * Reads value of "fast-clip-weight" and stores it in @result
227 * On success returns 0
228 * On failure returns errno
229 */
230static int kone_get_weight(struct usb_device *usb_dev, int *result)
231{
232	int retval;
233	uint8_t data;
234
235	retval = kone_receive(usb_dev, kone_command_weight, &data, 1);
236
237	if (retval)
238		return retval;
239
240	*result = (int)data;
241	return 0;
242}
243
244/*
245 * Reads firmware_version of mouse and stores it in @result
246 * On success returns 0
247 * On failure returns errno
248 */
249static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
250{
251	int retval;
252	uint16_t data;
253
254	retval = kone_receive(usb_dev, kone_command_firmware_version,
255			&data, 2);
256	if (retval)
257		return retval;
258
259	*result = le16_to_cpu(data);
260	return 0;
261}
262
263static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
264		struct bin_attribute *attr, char *buf,
265		loff_t off, size_t count) {
266	struct device *dev = kobj_to_dev(kobj)->parent->parent;
267	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
268
269	if (off >= sizeof(struct kone_settings))
270		return 0;
271
272	if (off + count > sizeof(struct kone_settings))
273		count = sizeof(struct kone_settings) - off;
274
275	mutex_lock(&kone->kone_lock);
276	memcpy(buf, ((char const *)&kone->settings) + off, count);
277	mutex_unlock(&kone->kone_lock);
278
279	return count;
280}
281
282/*
283 * Writing settings automatically activates startup_profile.
284 * This function keeps values in kone_device up to date and assumes that in
285 * case of error the old data is still valid
286 */
287static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
288		struct bin_attribute *attr, char *buf,
289		loff_t off, size_t count) {
290	struct device *dev = kobj_to_dev(kobj)->parent->parent;
291	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
292	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
293	int retval = 0, difference, old_profile;
294	struct kone_settings *settings = (struct kone_settings *)buf;
295
296	/* I need to get my data in one piece */
297	if (off != 0 || count != sizeof(struct kone_settings))
298		return -EINVAL;
299
300	mutex_lock(&kone->kone_lock);
301	difference = memcmp(settings, &kone->settings,
302			    sizeof(struct kone_settings));
303	if (difference) {
304		if (settings->startup_profile < 1 ||
305		    settings->startup_profile > 5) {
306			retval = -EINVAL;
307			goto unlock;
308		}
309
310		retval = kone_set_settings(usb_dev, settings);
311		if (retval)
312			goto unlock;
313
314		old_profile = kone->settings.startup_profile;
315		memcpy(&kone->settings, settings, sizeof(struct kone_settings));
316
317		kone_profile_activated(kone, kone->settings.startup_profile);
318
319		if (kone->settings.startup_profile != old_profile)
320			kone_profile_report(kone, kone->settings.startup_profile);
321	}
322unlock:
323	mutex_unlock(&kone->kone_lock);
324
325	if (retval)
326		return retval;
327
328	return sizeof(struct kone_settings);
329}
330static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
331		kone_sysfs_write_settings, sizeof(struct kone_settings));
332
333static ssize_t kone_sysfs_read_profilex(struct file *fp,
334		struct kobject *kobj, struct bin_attribute *attr,
335		char *buf, loff_t off, size_t count) {
336	struct device *dev = kobj_to_dev(kobj)->parent->parent;
337	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
338
339	if (off >= sizeof(struct kone_profile))
340		return 0;
341
342	if (off + count > sizeof(struct kone_profile))
343		count = sizeof(struct kone_profile) - off;
344
345	mutex_lock(&kone->kone_lock);
346	memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
347	mutex_unlock(&kone->kone_lock);
348
349	return count;
350}
351
352/* Writes data only if different to stored data */
353static ssize_t kone_sysfs_write_profilex(struct file *fp,
354		struct kobject *kobj, struct bin_attribute *attr,
355		char *buf, loff_t off, size_t count) {
356	struct device *dev = kobj_to_dev(kobj)->parent->parent;
357	struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
358	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
359	struct kone_profile *profile;
360	int retval = 0, difference;
361
362	/* I need to get my data in one piece */
363	if (off != 0 || count != sizeof(struct kone_profile))
364		return -EINVAL;
365
366	profile = &kone->profiles[*(uint *)(attr->private)];
367
368	mutex_lock(&kone->kone_lock);
369	difference = memcmp(buf, profile, sizeof(struct kone_profile));
370	if (difference) {
371		retval = kone_set_profile(usb_dev,
372				(struct kone_profile const *)buf,
373				*(uint *)(attr->private) + 1);
374		if (!retval)
375			memcpy(profile, buf, sizeof(struct kone_profile));
376	}
377	mutex_unlock(&kone->kone_lock);
378
379	if (retval)
380		return retval;
381
382	return sizeof(struct kone_profile);
383}
384#define PROFILE_ATTR(number)					\
385static struct bin_attribute bin_attr_profile##number = {	\
386	.attr = { .name = "profile" #number, .mode = 0660 },	\
387	.size = sizeof(struct kone_profile),			\
388	.read = kone_sysfs_read_profilex,			\
389	.write = kone_sysfs_write_profilex,			\
390	.private = &profile_numbers[number-1],			\
391}
392PROFILE_ATTR(1);
393PROFILE_ATTR(2);
394PROFILE_ATTR(3);
395PROFILE_ATTR(4);
396PROFILE_ATTR(5);
397
398static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
399		struct device_attribute *attr, char *buf)
400{
401	struct kone_device *kone =
402			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
403	return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
404}
405static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
406
407static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
408		struct device_attribute *attr, char *buf)
409{
410	struct kone_device *kone =
411			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
412	return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
413}
414static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
415
416/* weight is read each time, since we don't get informed when it's changed */
417static ssize_t kone_sysfs_show_weight(struct device *dev,
418		struct device_attribute *attr, char *buf)
419{
420	struct kone_device *kone;
421	struct usb_device *usb_dev;
422	int weight = 0;
423	int retval;
424
425	dev = dev->parent->parent;
426	kone = hid_get_drvdata(dev_get_drvdata(dev));
427	usb_dev = interface_to_usbdev(to_usb_interface(dev));
428
429	mutex_lock(&kone->kone_lock);
430	retval = kone_get_weight(usb_dev, &weight);
431	mutex_unlock(&kone->kone_lock);
432
433	if (retval)
434		return retval;
435	return snprintf(buf, PAGE_SIZE, "%d\n", weight);
436}
437static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
438
439static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
440		struct device_attribute *attr, char *buf)
441{
442	struct kone_device *kone =
443			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
444	return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
445}
446static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
447		   NULL);
448
449static ssize_t kone_sysfs_show_tcu(struct device *dev,
450		struct device_attribute *attr, char *buf)
451{
452	struct kone_device *kone =
453			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
454	return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
455}
456
457static int kone_tcu_command(struct usb_device *usb_dev, int number)
458{
459	unsigned char value;
460
461	value = number;
462	return kone_send(usb_dev, kone_command_calibrate, &value, 1);
463}
464
465/*
466 * Calibrating the tcu is the only action that changes settings data inside the
467 * mouse, so this data needs to be reread
468 */
469static ssize_t kone_sysfs_set_tcu(struct device *dev,
470		struct device_attribute *attr, char const *buf, size_t size)
471{
472	struct kone_device *kone;
473	struct usb_device *usb_dev;
474	int retval;
475	unsigned long state;
476
477	dev = dev->parent->parent;
478	kone = hid_get_drvdata(dev_get_drvdata(dev));
479	usb_dev = interface_to_usbdev(to_usb_interface(dev));
480
481	retval = kstrtoul(buf, 10, &state);
482	if (retval)
483		return retval;
484
485	if (state != 0 && state != 1)
486		return -EINVAL;
487
488	mutex_lock(&kone->kone_lock);
489
490	if (state == 1) { /* state activate */
491		retval = kone_tcu_command(usb_dev, 1);
492		if (retval)
493			goto exit_unlock;
494		retval = kone_tcu_command(usb_dev, 2);
495		if (retval)
496			goto exit_unlock;
497		ssleep(5); /* tcu needs this time for calibration */
498		retval = kone_tcu_command(usb_dev, 3);
499		if (retval)
500			goto exit_unlock;
501		retval = kone_tcu_command(usb_dev, 0);
502		if (retval)
503			goto exit_unlock;
504		retval = kone_tcu_command(usb_dev, 4);
505		if (retval)
506			goto exit_unlock;
507		/*
508		 * Kone needs this time to settle things.
509		 * Reading settings too early will result in invalid data.
510		 * Roccat's driver waits 1 sec, maybe this time could be
511		 * shortened.
512		 */
513		ssleep(1);
514	}
515
516	/* calibration changes values in settings, so reread */
517	retval = kone_get_settings(usb_dev, &kone->settings);
518	if (retval)
519		goto exit_no_settings;
520
521	/* only write settings back if activation state is different */
522	if (kone->settings.tcu != state) {
523		kone->settings.tcu = state;
524		kone_set_settings_checksum(&kone->settings);
525
526		retval = kone_set_settings(usb_dev, &kone->settings);
527		if (retval) {
528			dev_err(&usb_dev->dev, "couldn't set tcu state\n");
529			/*
530			 * try to reread valid settings into buffer overwriting
531			 * first error code
532			 */
533			retval = kone_get_settings(usb_dev, &kone->settings);
534			if (retval)
535				goto exit_no_settings;
536			goto exit_unlock;
537		}
538		/* calibration resets profile */
539		kone_profile_activated(kone, kone->settings.startup_profile);
540	}
541
542	retval = size;
543exit_no_settings:
544	dev_err(&usb_dev->dev, "couldn't read settings\n");
545exit_unlock:
546	mutex_unlock(&kone->kone_lock);
547	return retval;
548}
549static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
550
551static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
552		struct device_attribute *attr, char *buf)
553{
554	struct kone_device *kone =
555			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
556	return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
557}
558
559static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
560		struct device_attribute *attr, char const *buf, size_t size)
561{
562	struct kone_device *kone;
563	struct usb_device *usb_dev;
564	int retval;
565	unsigned long new_startup_profile;
566
567	dev = dev->parent->parent;
568	kone = hid_get_drvdata(dev_get_drvdata(dev));
569	usb_dev = interface_to_usbdev(to_usb_interface(dev));
570
571	retval = kstrtoul(buf, 10, &new_startup_profile);
572	if (retval)
573		return retval;
574
575	if (new_startup_profile  < 1 || new_startup_profile > 5)
576		return -EINVAL;
577
578	mutex_lock(&kone->kone_lock);
579
580	kone->settings.startup_profile = new_startup_profile;
581	kone_set_settings_checksum(&kone->settings);
582
583	retval = kone_set_settings(usb_dev, &kone->settings);
584	if (retval) {
585		mutex_unlock(&kone->kone_lock);
586		return retval;
587	}
588
589	/* changing the startup profile immediately activates this profile */
590	kone_profile_activated(kone, new_startup_profile);
591	kone_profile_report(kone, new_startup_profile);
592
593	mutex_unlock(&kone->kone_lock);
594	return size;
595}
596static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
597		   kone_sysfs_set_startup_profile);
598
599static struct attribute *kone_attrs[] = {
600	/*
601	 * Read actual dpi settings.
602	 * Returns raw value for further processing. Refer to enum
603	 * kone_polling_rates to get real value.
604	 */
605	&dev_attr_actual_dpi.attr,
606	&dev_attr_actual_profile.attr,
607
608	/*
609	 * The mouse can be equipped with one of four supplied weights from 5
610	 * to 20 grams which are recognized and its value can be read out.
611	 * This returns the raw value reported by the mouse for easy evaluation
612	 * by software. Refer to enum kone_weights to get corresponding real
613	 * weight.
614	 */
615	&dev_attr_weight.attr,
616
617	/*
618	 * Prints firmware version stored in mouse as integer.
619	 * The raw value reported by the mouse is returned for easy evaluation,
620	 * to get the real version number the decimal point has to be shifted 2
621	 * positions to the left. E.g. a value of 138 means 1.38.
622	 */
623	&dev_attr_firmware_version.attr,
624
625	/*
626	 * Prints state of Tracking Control Unit as number where 0 = off and
627	 * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
628	 * activates the tcu
629	 */
630	&dev_attr_tcu.attr,
631
632	/* Prints and takes the number of the profile the mouse starts with */
633	&dev_attr_startup_profile.attr,
634	NULL,
635};
636
637static struct bin_attribute *kone_bin_attributes[] = {
638	&bin_attr_settings,
639	&bin_attr_profile1,
640	&bin_attr_profile2,
641	&bin_attr_profile3,
642	&bin_attr_profile4,
643	&bin_attr_profile5,
644	NULL,
645};
646
647static const struct attribute_group kone_group = {
648	.attrs = kone_attrs,
649	.bin_attrs = kone_bin_attributes,
650};
651
652static const struct attribute_group *kone_groups[] = {
653	&kone_group,
654	NULL,
655};
656
657/* kone_class is used for creating sysfs attributes via roccat char device */
658static const struct class kone_class = {
659	.name = "kone",
660	.dev_groups = kone_groups,
661};
662
663static int kone_init_kone_device_struct(struct usb_device *usb_dev,
664		struct kone_device *kone)
665{
666	uint i;
667	int retval;
668
669	mutex_init(&kone->kone_lock);
670
671	for (i = 0; i < 5; ++i) {
672		retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
673		if (retval)
674			return retval;
675	}
676
677	retval = kone_get_settings(usb_dev, &kone->settings);
678	if (retval)
679		return retval;
680
681	retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
682	if (retval)
683		return retval;
684
685	kone_profile_activated(kone, kone->settings.startup_profile);
686
687	return 0;
688}
689
690/*
691 * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
692 * mousepart if usb_hid is compiled into the kernel and kone is compiled as
693 * module.
694 * Secial behaviour is bound only to mousepart since only mouseevents contain
695 * additional notifications.
696 */
697static int kone_init_specials(struct hid_device *hdev)
698{
699	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
700	struct usb_device *usb_dev = interface_to_usbdev(intf);
701	struct kone_device *kone;
702	int retval;
703
704	if (intf->cur_altsetting->desc.bInterfaceProtocol
705			== USB_INTERFACE_PROTOCOL_MOUSE) {
706
707		kone = kzalloc(sizeof(*kone), GFP_KERNEL);
708		if (!kone)
709			return -ENOMEM;
710		hid_set_drvdata(hdev, kone);
711
712		retval = kone_init_kone_device_struct(usb_dev, kone);
713		if (retval) {
714			hid_err(hdev, "couldn't init struct kone_device\n");
715			goto exit_free;
716		}
717
718		retval = roccat_connect(&kone_class, hdev,
719					sizeof(struct kone_roccat_report));
720		if (retval < 0) {
721			hid_err(hdev, "couldn't init char dev\n");
722			/* be tolerant about not getting chrdev */
723		} else {
724			kone->roccat_claimed = 1;
725			kone->chrdev_minor = retval;
726		}
727	} else {
728		hid_set_drvdata(hdev, NULL);
729	}
730
731	return 0;
732exit_free:
733	kfree(kone);
734	return retval;
735}
736
737static void kone_remove_specials(struct hid_device *hdev)
738{
739	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
740	struct kone_device *kone;
741
742	if (intf->cur_altsetting->desc.bInterfaceProtocol
743			== USB_INTERFACE_PROTOCOL_MOUSE) {
744		kone = hid_get_drvdata(hdev);
745		if (kone->roccat_claimed)
746			roccat_disconnect(kone->chrdev_minor);
747		kfree(hid_get_drvdata(hdev));
748	}
749}
750
751static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
752{
753	int retval;
754
755	if (!hid_is_usb(hdev))
756		return -EINVAL;
757
758	retval = hid_parse(hdev);
759	if (retval) {
760		hid_err(hdev, "parse failed\n");
761		goto exit;
762	}
763
764	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
765	if (retval) {
766		hid_err(hdev, "hw start failed\n");
767		goto exit;
768	}
769
770	retval = kone_init_specials(hdev);
771	if (retval) {
772		hid_err(hdev, "couldn't install mouse\n");
773		goto exit_stop;
774	}
775
776	return 0;
777
778exit_stop:
779	hid_hw_stop(hdev);
780exit:
781	return retval;
782}
783
784static void kone_remove(struct hid_device *hdev)
785{
786	kone_remove_specials(hdev);
787	hid_hw_stop(hdev);
788}
789
790/* handle special events and keep actual profile and dpi values up to date */
791static void kone_keep_values_up_to_date(struct kone_device *kone,
792		struct kone_mouse_event const *event)
793{
794	switch (event->event) {
795	case kone_mouse_event_switch_profile:
796		kone->actual_dpi = kone->profiles[event->value - 1].
797				startup_dpi;
798		fallthrough;
799	case kone_mouse_event_osd_profile:
800		kone->actual_profile = event->value;
801		break;
802	case kone_mouse_event_switch_dpi:
803	case kone_mouse_event_osd_dpi:
804		kone->actual_dpi = event->value;
805		break;
806	}
807}
808
809static void kone_report_to_chrdev(struct kone_device const *kone,
810		struct kone_mouse_event const *event)
811{
812	struct kone_roccat_report roccat_report;
813
814	switch (event->event) {
815	case kone_mouse_event_switch_profile:
816	case kone_mouse_event_switch_dpi:
817	case kone_mouse_event_osd_profile:
818	case kone_mouse_event_osd_dpi:
819		roccat_report.event = event->event;
820		roccat_report.value = event->value;
821		roccat_report.key = 0;
822		roccat_report_event(kone->chrdev_minor,
823				(uint8_t *)&roccat_report);
824		break;
825	case kone_mouse_event_call_overlong_macro:
826	case kone_mouse_event_multimedia:
827		if (event->value == kone_keystroke_action_press) {
828			roccat_report.event = event->event;
829			roccat_report.value = kone->actual_profile;
830			roccat_report.key = event->macro_key;
831			roccat_report_event(kone->chrdev_minor,
832					(uint8_t *)&roccat_report);
833		}
834		break;
835	}
836
837}
838
839/*
840 * Is called for keyboard- and mousepart.
841 * Only mousepart gets informations about special events in its extended event
842 * structure.
843 */
844static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
845		u8 *data, int size)
846{
847	struct kone_device *kone = hid_get_drvdata(hdev);
848	struct kone_mouse_event *event = (struct kone_mouse_event *)data;
849
850	/* keyboard events are always processed by default handler */
851	if (size != sizeof(struct kone_mouse_event))
852		return 0;
853
854	if (kone == NULL)
855		return 0;
856
857	/*
858	 * Firmware 1.38 introduced new behaviour for tilt and special buttons.
859	 * Pressed button is reported in each movement event.
860	 * Workaround sends only one event per press.
861	 */
862	if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
863		memcpy(&kone->last_mouse_event, event,
864				sizeof(struct kone_mouse_event));
865	else
866		memset(&event->wipe, 0, sizeof(event->wipe));
867
868	kone_keep_values_up_to_date(kone, event);
869
870	if (kone->roccat_claimed)
871		kone_report_to_chrdev(kone, event);
872
873	return 0; /* always do further processing */
874}
875
876static const struct hid_device_id kone_devices[] = {
877	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
878	{ }
879};
880
881MODULE_DEVICE_TABLE(hid, kone_devices);
882
883static struct hid_driver kone_driver = {
884		.name = "kone",
885		.id_table = kone_devices,
886		.probe = kone_probe,
887		.remove = kone_remove,
888		.raw_event = kone_raw_event
889};
890
891static int __init kone_init(void)
892{
893	int retval;
894
895	/* class name has to be same as driver name */
896	retval = class_register(&kone_class);
897	if (retval)
898		return retval;
899
900	retval = hid_register_driver(&kone_driver);
901	if (retval)
902		class_unregister(&kone_class);
903	return retval;
904}
905
906static void __exit kone_exit(void)
907{
908	hid_unregister_driver(&kone_driver);
909	class_unregister(&kone_class);
910}
911
912module_init(kone_init);
913module_exit(kone_exit);
914
915MODULE_AUTHOR("Stefan Achatz");
916MODULE_DESCRIPTION("USB Roccat Kone driver");
917MODULE_LICENSE("GPL v2");
918