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