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