blob: cbd8cc42e75ab38d203697f1752cbeabd09ad2c7 [file] [log] [blame]
Stefan Achatz14bf62c2010-03-18 16:19:43 +01001/*
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 *
Stefan Achatz14bf62c2010-03-18 16:19:43 +010025 * 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>
Tejun Heoed28f042010-03-30 02:52:41 +090033#include <linux/slab.h>
Stefan Achatz14bf62c2010-03-18 16:19:43 +010034#include "hid-ids.h"
Stefan Achatz206f5f22010-05-19 18:55:16 +020035#include "hid-roccat.h"
Stefan Achatz14bf62c2010-03-18 16:19:43 +010036#include "hid-roccat-kone.h"
37
Stefan Achatz14a057f2010-11-26 19:57:38 +000038static uint profile_numbers[5] = {0, 1, 2, 3, 4};
39
Stefan Achatz5012aad2010-11-26 19:57:33 +000040/* kone_class is used for creating sysfs attributes via roccat char device */
41static struct class *kone_class;
42
Stefan Achatz14bf62c2010-03-18 16:19:43 +010043static void kone_set_settings_checksum(struct kone_settings *settings)
44{
45 uint16_t checksum = 0;
46 unsigned char *address = (unsigned char *)settings;
47 int i;
48
49 for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address)
50 checksum += *address;
51 settings->checksum = cpu_to_le16(checksum);
52}
53
54/*
55 * Checks success after writing data to mouse
56 * On success returns 0
57 * On failure returns errno
58 */
59static int kone_check_write(struct usb_device *usb_dev)
60{
61 int len;
62 unsigned char *data;
63
64 data = kmalloc(1, GFP_KERNEL);
65 if (!data)
66 return -ENOMEM;
67
68 do {
69 /*
70 * Mouse needs 50 msecs until it says ok, but there are
71 * 30 more msecs needed for next write to work.
72 */
73 msleep(80);
74
75 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
76 USB_REQ_CLEAR_FEATURE,
77 USB_TYPE_CLASS | USB_RECIP_INTERFACE |
78 USB_DIR_IN,
79 kone_command_confirm_write, 0, data, 1,
80 USB_CTRL_SET_TIMEOUT);
81
82 if (len != 1) {
83 kfree(data);
84 return -EIO;
85 }
86
87 /*
88 * value of 3 seems to mean something like
89 * "not finished yet, but it looks good"
90 * So check again after a moment.
91 */
92 } while (*data == 3);
93
94 if (*data == 1) { /* everything alright */
95 kfree(data);
96 return 0;
97 } else { /* unknown answer */
Joe Perches4291ee32010-12-09 19:29:03 -080098 hid_err(usb_dev, "got retval %d when checking write\n", *data);
Stefan Achatz14bf62c2010-03-18 16:19:43 +010099 kfree(data);
100 return -EIO;
101 }
102}
103
104/*
105 * Reads settings from mouse and stores it in @buf
106 * @buf has to be alloced with GFP_KERNEL
107 * On success returns 0
108 * On failure returns errno
109 */
110static int kone_get_settings(struct usb_device *usb_dev,
111 struct kone_settings *buf)
112{
113 int len;
114
115 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
116 USB_REQ_CLEAR_FEATURE,
117 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
118 kone_command_settings, 0, buf,
119 sizeof(struct kone_settings), USB_CTRL_SET_TIMEOUT);
120
121 if (len != sizeof(struct kone_settings))
122 return -EIO;
123
124 return 0;
125}
126
127/*
128 * Writes settings from @buf to mouse
129 * On success returns 0
130 * On failure returns errno
131 */
132static int kone_set_settings(struct usb_device *usb_dev,
133 struct kone_settings const *settings)
134{
135 int len;
136
137 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
138 USB_REQ_SET_CONFIGURATION,
139 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
140 kone_command_settings, 0, (char *)settings,
141 sizeof(struct kone_settings),
142 USB_CTRL_SET_TIMEOUT);
143
144 if (len != sizeof(struct kone_settings))
145 return -EIO;
146
147 if (kone_check_write(usb_dev))
148 return -EIO;
149
150 return 0;
151}
152
153/*
154 * Reads profile data from mouse and stores it in @buf
155 * @number: profile number to read
156 * On success returns 0
157 * On failure returns errno
158 */
159static int kone_get_profile(struct usb_device *usb_dev,
160 struct kone_profile *buf, int number)
161{
162 int len;
163
164 if (number < 1 || number > 5)
165 return -EINVAL;
166
167 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
168 USB_REQ_CLEAR_FEATURE,
169 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
170 kone_command_profile, number, buf,
171 sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT);
172
173 if (len != sizeof(struct kone_profile))
174 return -EIO;
175
176 return 0;
177}
178
179/*
180 * Writes profile data to mouse.
181 * @number: profile number to write
182 * On success returns 0
183 * On failure returns errno
184 */
185static int kone_set_profile(struct usb_device *usb_dev,
186 struct kone_profile const *profile, int number)
187{
188 int len;
189
190 if (number < 1 || number > 5)
191 return -EINVAL;
192
193 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
194 USB_REQ_SET_CONFIGURATION,
195 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
196 kone_command_profile, number, (char *)profile,
197 sizeof(struct kone_profile),
198 USB_CTRL_SET_TIMEOUT);
199
200 if (len != sizeof(struct kone_profile))
201 return len;
202
203 if (kone_check_write(usb_dev))
204 return -EIO;
205
206 return 0;
207}
208
209/*
210 * Reads value of "fast-clip-weight" and stores it in @result
211 * On success returns 0
212 * On failure returns errno
213 */
214static int kone_get_weight(struct usb_device *usb_dev, int *result)
215{
216 int len;
217 uint8_t *data;
218
219 data = kmalloc(1, GFP_KERNEL);
220 if (!data)
221 return -ENOMEM;
222
223 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
224 USB_REQ_CLEAR_FEATURE,
225 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
226 kone_command_weight, 0, data, 1, USB_CTRL_SET_TIMEOUT);
227
228 if (len != 1) {
229 kfree(data);
230 return -EIO;
231 }
232 *result = (int)*data;
233 kfree(data);
234 return 0;
235}
236
237/*
238 * Reads firmware_version of mouse and stores it in @result
239 * On success returns 0
240 * On failure returns errno
241 */
242static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
243{
244 int len;
245 unsigned char *data;
246
247 data = kmalloc(2, GFP_KERNEL);
248 if (!data)
249 return -ENOMEM;
250
251 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
252 USB_REQ_CLEAR_FEATURE,
253 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
254 kone_command_firmware_version, 0, data, 2,
255 USB_CTRL_SET_TIMEOUT);
256
257 if (len != 2) {
258 kfree(data);
259 return -EIO;
260 }
261 *result = le16_to_cpu(*data);
262 kfree(data);
263 return 0;
264}
265
Stephen Rothwell5f277622010-05-21 16:15:32 +1000266static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100267 struct bin_attribute *attr, char *buf,
268 loff_t off, size_t count) {
Stefan Achatz5012aad2010-11-26 19:57:33 +0000269 struct device *dev =
270 container_of(kobj, struct device, kobj)->parent->parent;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100271 struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
272
273 if (off >= sizeof(struct kone_settings))
274 return 0;
275
276 if (off + count > sizeof(struct kone_settings))
277 count = sizeof(struct kone_settings) - off;
278
279 mutex_lock(&kone->kone_lock);
Stefan Achatzcab6b162010-06-20 19:19:06 +0200280 memcpy(buf, ((char const *)&kone->settings) + off, count);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100281 mutex_unlock(&kone->kone_lock);
282
283 return count;
284}
285
286/*
287 * Writing settings automatically activates startup_profile.
288 * This function keeps values in kone_device up to date and assumes that in
289 * case of error the old data is still valid
290 */
Stephen Rothwell5f277622010-05-21 16:15:32 +1000291static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100292 struct bin_attribute *attr, char *buf,
293 loff_t off, size_t count) {
Stefan Achatz5012aad2010-11-26 19:57:33 +0000294 struct device *dev =
295 container_of(kobj, struct device, kobj)->parent->parent;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100296 struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
297 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
298 int retval = 0, difference;
299
300 /* I need to get my data in one piece */
301 if (off != 0 || count != sizeof(struct kone_settings))
302 return -EINVAL;
303
304 mutex_lock(&kone->kone_lock);
305 difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings));
306 if (difference) {
307 retval = kone_set_settings(usb_dev,
308 (struct kone_settings const *)buf);
309 if (!retval)
310 memcpy(&kone->settings, buf,
311 sizeof(struct kone_settings));
312 }
313 mutex_unlock(&kone->kone_lock);
314
315 if (retval)
316 return retval;
317
318 /*
319 * If we get here, treat settings as okay and update actual values
320 * according to startup_profile
321 */
322 kone->actual_profile = kone->settings.startup_profile;
323 kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi;
324
325 return sizeof(struct kone_settings);
326}
327
Stefan Achatz14a057f2010-11-26 19:57:38 +0000328static 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) {
Stefan Achatz5012aad2010-11-26 19:57:33 +0000331 struct device *dev =
332 container_of(kobj, struct device, kobj)->parent->parent;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100333 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);
Stefan Achatz14a057f2010-11-26 19:57:38 +0000342 memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100343 mutex_unlock(&kone->kone_lock);
344
345 return count;
346}
347
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100348/* Writes data only if different to stored data */
Stefan Achatz14a057f2010-11-26 19:57:38 +0000349static 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) {
Stefan Achatz5012aad2010-11-26 19:57:33 +0000352 struct device *dev =
353 container_of(kobj, struct device, kobj)->parent->parent;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100354 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
Stefan Achatz14a057f2010-11-26 19:57:38 +0000363 profile = &kone->profiles[*(uint *)(attr->private)];
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100364
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,
Stefan Achatz14a057f2010-11-26 19:57:38 +0000369 (struct kone_profile const *)buf,
370 *(uint *)(attr->private) + 1);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100371 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
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100382static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
383 struct device_attribute *attr, char *buf)
384{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000385 struct kone_device *kone =
386 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100387 return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
388}
389
390static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
391 struct device_attribute *attr, char *buf)
392{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000393 struct kone_device *kone =
394 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100395 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 */
399static ssize_t kone_sysfs_show_weight(struct device *dev,
400 struct device_attribute *attr, char *buf)
401{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000402 struct kone_device *kone;
403 struct usb_device *usb_dev;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100404 int weight = 0;
405 int retval;
406
Stefan Achatz5012aad2010-11-26 19:57:33 +0000407 dev = dev->parent->parent;
408 kone = hid_get_drvdata(dev_get_drvdata(dev));
409 usb_dev = interface_to_usbdev(to_usb_interface(dev));
410
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100411 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
420static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
421 struct device_attribute *attr, char *buf)
422{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000423 struct kone_device *kone =
424 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100425 return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
426}
427
428static ssize_t kone_sysfs_show_tcu(struct device *dev,
429 struct device_attribute *attr, char *buf)
430{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000431 struct kone_device *kone =
432 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100433 return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
434}
435
436static int kone_tcu_command(struct usb_device *usb_dev, int number)
437{
438 int len;
439 char *value;
440
441 value = kmalloc(1, GFP_KERNEL);
442 if (!value)
443 return -ENOMEM;
444
445 *value = number;
446
447 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
448 USB_REQ_SET_CONFIGURATION,
449 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
450 kone_command_calibrate, 0, value, 1,
451 USB_CTRL_SET_TIMEOUT);
452
453 kfree(value);
454 return ((len != 1) ? -EIO : 0);
455}
456
457/*
458 * Calibrating the tcu is the only action that changes settings data inside the
459 * mouse, so this data needs to be reread
460 */
461static ssize_t kone_sysfs_set_tcu(struct device *dev,
462 struct device_attribute *attr, char const *buf, size_t size)
463{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000464 struct kone_device *kone;
465 struct usb_device *usb_dev;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100466 int retval;
467 unsigned long state;
468
Stefan Achatz5012aad2010-11-26 19:57:33 +0000469 dev = dev->parent->parent;
470 kone = hid_get_drvdata(dev_get_drvdata(dev));
471 usb_dev = interface_to_usbdev(to_usb_interface(dev));
472
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100473 retval = strict_strtoul(buf, 10, &state);
474 if (retval)
475 return retval;
476
477 if (state != 0 && state != 1)
478 return -EINVAL;
479
480 mutex_lock(&kone->kone_lock);
481
482 if (state == 1) { /* state activate */
483 retval = kone_tcu_command(usb_dev, 1);
484 if (retval)
485 goto exit_unlock;
486 retval = kone_tcu_command(usb_dev, 2);
487 if (retval)
488 goto exit_unlock;
489 ssleep(5); /* tcu needs this time for calibration */
490 retval = kone_tcu_command(usb_dev, 3);
491 if (retval)
492 goto exit_unlock;
493 retval = kone_tcu_command(usb_dev, 0);
494 if (retval)
495 goto exit_unlock;
496 retval = kone_tcu_command(usb_dev, 4);
497 if (retval)
498 goto exit_unlock;
499 /*
500 * Kone needs this time to settle things.
501 * Reading settings too early will result in invalid data.
502 * Roccat's driver waits 1 sec, maybe this time could be
503 * shortened.
504 */
505 ssleep(1);
506 }
507
508 /* calibration changes values in settings, so reread */
509 retval = kone_get_settings(usb_dev, &kone->settings);
510 if (retval)
511 goto exit_no_settings;
512
513 /* only write settings back if activation state is different */
514 if (kone->settings.tcu != state) {
515 kone->settings.tcu = state;
516 kone_set_settings_checksum(&kone->settings);
517
518 retval = kone_set_settings(usb_dev, &kone->settings);
519 if (retval) {
Joe Perches4291ee32010-12-09 19:29:03 -0800520 hid_err(usb_dev, "couldn't set tcu state\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100521 /*
522 * try to reread valid settings into buffer overwriting
523 * first error code
524 */
525 retval = kone_get_settings(usb_dev, &kone->settings);
526 if (retval)
527 goto exit_no_settings;
528 goto exit_unlock;
529 }
530 }
531
532 retval = size;
533exit_no_settings:
Joe Perches4291ee32010-12-09 19:29:03 -0800534 hid_err(usb_dev, "couldn't read settings\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100535exit_unlock:
536 mutex_unlock(&kone->kone_lock);
537 return retval;
538}
539
540static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
541 struct device_attribute *attr, char *buf)
542{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000543 struct kone_device *kone =
544 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100545 return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
546}
547
548static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
549 struct device_attribute *attr, char const *buf, size_t size)
550{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000551 struct kone_device *kone;
552 struct usb_device *usb_dev;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100553 int retval;
554 unsigned long new_startup_profile;
555
Stefan Achatz5012aad2010-11-26 19:57:33 +0000556 dev = dev->parent->parent;
557 kone = hid_get_drvdata(dev_get_drvdata(dev));
558 usb_dev = interface_to_usbdev(to_usb_interface(dev));
559
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100560 retval = strict_strtoul(buf, 10, &new_startup_profile);
561 if (retval)
562 return retval;
563
564 if (new_startup_profile < 1 || new_startup_profile > 5)
565 return -EINVAL;
566
567 mutex_lock(&kone->kone_lock);
568
569 kone->settings.startup_profile = new_startup_profile;
570 kone_set_settings_checksum(&kone->settings);
571
572 retval = kone_set_settings(usb_dev, &kone->settings);
573
574 mutex_unlock(&kone->kone_lock);
575
576 if (retval)
577 return retval;
578
579 /* changing the startup profile immediately activates this profile */
580 kone->actual_profile = new_startup_profile;
581 kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi;
582
583 return size;
584}
585
Stefan Achatz5012aad2010-11-26 19:57:33 +0000586static struct device_attribute kone_attributes[] = {
587 /*
588 * Read actual dpi settings.
589 * Returns raw value for further processing. Refer to enum
590 * kone_polling_rates to get real value.
591 */
592 __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL),
593 __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL),
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100594
Stefan Achatz5012aad2010-11-26 19:57:33 +0000595 /*
596 * The mouse can be equipped with one of four supplied weights from 5
597 * to 20 grams which are recognized and its value can be read out.
598 * This returns the raw value reported by the mouse for easy evaluation
599 * by software. Refer to enum kone_weights to get corresponding real
600 * weight.
601 */
602 __ATTR(weight, 0440, kone_sysfs_show_weight, NULL),
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100603
Stefan Achatz5012aad2010-11-26 19:57:33 +0000604 /*
605 * Prints firmware version stored in mouse as integer.
606 * The raw value reported by the mouse is returned for easy evaluation,
607 * to get the real version number the decimal point has to be shifted 2
608 * positions to the left. E.g. a value of 138 means 1.38.
609 */
610 __ATTR(firmware_version, 0440,
611 kone_sysfs_show_firmware_version, NULL),
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100612
Stefan Achatz5012aad2010-11-26 19:57:33 +0000613 /*
614 * Prints state of Tracking Control Unit as number where 0 = off and
615 * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
616 * activates the tcu
617 */
618 __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu),
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100619
Stefan Achatz5012aad2010-11-26 19:57:33 +0000620 /* Prints and takes the number of the profile the mouse starts with */
621 __ATTR(startup_profile, 0660,
622 kone_sysfs_show_startup_profile,
623 kone_sysfs_set_startup_profile),
624 __ATTR_NULL
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100625};
626
Stefan Achatz5012aad2010-11-26 19:57:33 +0000627static struct bin_attribute kone_bin_attributes[] = {
628 {
629 .attr = { .name = "settings", .mode = 0660 },
630 .size = sizeof(struct kone_settings),
631 .read = kone_sysfs_read_settings,
632 .write = kone_sysfs_write_settings
633 },
634 {
635 .attr = { .name = "profile1", .mode = 0660 },
636 .size = sizeof(struct kone_profile),
Stefan Achatz14a057f2010-11-26 19:57:38 +0000637 .read = kone_sysfs_read_profilex,
638 .write = kone_sysfs_write_profilex,
639 .private = &profile_numbers[0]
Stefan Achatz5012aad2010-11-26 19:57:33 +0000640 },
641 {
642 .attr = { .name = "profile2", .mode = 0660 },
643 .size = sizeof(struct kone_profile),
Stefan Achatz14a057f2010-11-26 19:57:38 +0000644 .read = kone_sysfs_read_profilex,
645 .write = kone_sysfs_write_profilex,
646 .private = &profile_numbers[1]
Stefan Achatz5012aad2010-11-26 19:57:33 +0000647 },
648 {
649 .attr = { .name = "profile3", .mode = 0660 },
650 .size = sizeof(struct kone_profile),
Stefan Achatz14a057f2010-11-26 19:57:38 +0000651 .read = kone_sysfs_read_profilex,
652 .write = kone_sysfs_write_profilex,
653 .private = &profile_numbers[2]
Stefan Achatz5012aad2010-11-26 19:57:33 +0000654 },
655 {
656 .attr = { .name = "profile4", .mode = 0660 },
657 .size = sizeof(struct kone_profile),
Stefan Achatz14a057f2010-11-26 19:57:38 +0000658 .read = kone_sysfs_read_profilex,
659 .write = kone_sysfs_write_profilex,
660 .private = &profile_numbers[3]
Stefan Achatz5012aad2010-11-26 19:57:33 +0000661 },
662 {
663 .attr = { .name = "profile5", .mode = 0660 },
664 .size = sizeof(struct kone_profile),
Stefan Achatz14a057f2010-11-26 19:57:38 +0000665 .read = kone_sysfs_read_profilex,
666 .write = kone_sysfs_write_profilex,
667 .private = &profile_numbers[4]
Stefan Achatz5012aad2010-11-26 19:57:33 +0000668 },
669 __ATTR_NULL
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100670};
671
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100672static int kone_init_kone_device_struct(struct usb_device *usb_dev,
673 struct kone_device *kone)
674{
675 uint i;
676 int retval;
677
678 mutex_init(&kone->kone_lock);
679
680 for (i = 0; i < 5; ++i) {
681 retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
682 if (retval)
683 return retval;
684 }
685
686 retval = kone_get_settings(usb_dev, &kone->settings);
687 if (retval)
688 return retval;
689
690 retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
691 if (retval)
692 return retval;
693
694 kone->actual_profile = kone->settings.startup_profile;
695 kone->actual_dpi = kone->profiles[kone->actual_profile].startup_dpi;
696
697 return 0;
698}
699
700/*
701 * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
702 * mousepart if usb_hid is compiled into the kernel and kone is compiled as
703 * module.
704 * Secial behaviour is bound only to mousepart since only mouseevents contain
705 * additional notifications.
706 */
707static int kone_init_specials(struct hid_device *hdev)
708{
709 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
710 struct usb_device *usb_dev = interface_to_usbdev(intf);
711 struct kone_device *kone;
712 int retval;
713
714 if (intf->cur_altsetting->desc.bInterfaceProtocol
715 == USB_INTERFACE_PROTOCOL_MOUSE) {
716
717 kone = kzalloc(sizeof(*kone), GFP_KERNEL);
718 if (!kone) {
Joe Perches4291ee32010-12-09 19:29:03 -0800719 hid_err(hdev, "can't alloc device descriptor\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100720 return -ENOMEM;
721 }
722 hid_set_drvdata(hdev, kone);
723
724 retval = kone_init_kone_device_struct(usb_dev, kone);
725 if (retval) {
Joe Perches4291ee32010-12-09 19:29:03 -0800726 hid_err(hdev, "couldn't init struct kone_device\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100727 goto exit_free;
728 }
Stefan Achatz206f5f22010-05-19 18:55:16 +0200729
Stefan Achatz5012aad2010-11-26 19:57:33 +0000730 retval = roccat_connect(kone_class, hdev);
Stefan Achatz206f5f22010-05-19 18:55:16 +0200731 if (retval < 0) {
Joe Perches4291ee32010-12-09 19:29:03 -0800732 hid_err(hdev, "couldn't init char dev\n");
Stefan Achatz206f5f22010-05-19 18:55:16 +0200733 /* be tolerant about not getting chrdev */
734 } else {
735 kone->roccat_claimed = 1;
736 kone->chrdev_minor = retval;
737 }
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100738 } else {
739 hid_set_drvdata(hdev, NULL);
740 }
741
742 return 0;
743exit_free:
744 kfree(kone);
745 return retval;
746}
747
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100748static void kone_remove_specials(struct hid_device *hdev)
749{
750 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
Stefan Achatz206f5f22010-05-19 18:55:16 +0200751 struct kone_device *kone;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100752
753 if (intf->cur_altsetting->desc.bInterfaceProtocol
754 == USB_INTERFACE_PROTOCOL_MOUSE) {
Stefan Achatz206f5f22010-05-19 18:55:16 +0200755 kone = hid_get_drvdata(hdev);
756 if (kone->roccat_claimed)
757 roccat_disconnect(kone->chrdev_minor);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100758 kfree(hid_get_drvdata(hdev));
759 }
760}
761
762static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
763{
764 int retval;
765
766 retval = hid_parse(hdev);
767 if (retval) {
Joe Perches4291ee32010-12-09 19:29:03 -0800768 hid_err(hdev, "parse failed\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100769 goto exit;
770 }
771
772 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
773 if (retval) {
Joe Perches4291ee32010-12-09 19:29:03 -0800774 hid_err(hdev, "hw start failed\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100775 goto exit;
776 }
777
778 retval = kone_init_specials(hdev);
779 if (retval) {
Joe Perches4291ee32010-12-09 19:29:03 -0800780 hid_err(hdev, "couldn't install mouse\n");
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100781 goto exit_stop;
782 }
783
784 return 0;
785
786exit_stop:
787 hid_hw_stop(hdev);
788exit:
789 return retval;
790}
791
792static void kone_remove(struct hid_device *hdev)
793{
794 kone_remove_specials(hdev);
795 hid_hw_stop(hdev);
796}
797
Stefan Achatz48e70802010-05-18 18:31:04 +0200798/* handle special events and keep actual profile and dpi values up to date */
799static void kone_keep_values_up_to_date(struct kone_device *kone,
800 struct kone_mouse_event const *event)
801{
802 switch (event->event) {
803 case kone_mouse_event_switch_profile:
804 case kone_mouse_event_osd_profile:
805 kone->actual_profile = event->value;
806 kone->actual_dpi = kone->profiles[kone->actual_profile - 1].
807 startup_dpi;
808 break;
809 case kone_mouse_event_switch_dpi:
810 case kone_mouse_event_osd_dpi:
811 kone->actual_dpi = event->value;
812 break;
813 }
814}
815
Stefan Achatz206f5f22010-05-19 18:55:16 +0200816static void kone_report_to_chrdev(struct kone_device const *kone,
817 struct kone_mouse_event const *event)
818{
819 struct kone_roccat_report roccat_report;
820
821 switch (event->event) {
822 case kone_mouse_event_switch_profile:
823 case kone_mouse_event_switch_dpi:
824 case kone_mouse_event_osd_profile:
825 case kone_mouse_event_osd_dpi:
826 roccat_report.event = event->event;
827 roccat_report.value = event->value;
828 roccat_report.key = 0;
829 roccat_report_event(kone->chrdev_minor,
830 (uint8_t *)&roccat_report,
831 sizeof(struct kone_roccat_report));
832 break;
833 case kone_mouse_event_call_overlong_macro:
834 if (event->value == kone_keystroke_action_press) {
835 roccat_report.event = kone_mouse_event_call_overlong_macro;
836 roccat_report.value = kone->actual_profile;
837 roccat_report.key = event->macro_key;
838 roccat_report_event(kone->chrdev_minor,
839 (uint8_t *)&roccat_report,
840 sizeof(struct kone_roccat_report));
841 }
842 break;
843 }
844
845}
846
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100847/*
848 * Is called for keyboard- and mousepart.
849 * Only mousepart gets informations about special events in its extended event
850 * structure.
851 */
852static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
853 u8 *data, int size)
854{
855 struct kone_device *kone = hid_get_drvdata(hdev);
856 struct kone_mouse_event *event = (struct kone_mouse_event *)data;
857
858 /* keyboard events are always processed by default handler */
859 if (size != sizeof(struct kone_mouse_event))
860 return 0;
861
862 /*
Stefan Achatz73b35772010-05-19 13:53:22 +0200863 * Firmware 1.38 introduced new behaviour for tilt and special buttons.
864 * Pressed button is reported in each movement event.
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100865 * Workaround sends only one event per press.
866 */
Stefan Achatz73b35772010-05-19 13:53:22 +0200867 if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
868 memcpy(&kone->last_mouse_event, event,
869 sizeof(struct kone_mouse_event));
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100870 else
Stefan Achatz73b35772010-05-19 13:53:22 +0200871 memset(&event->tilt, 0, 5);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100872
Stefan Achatz48e70802010-05-18 18:31:04 +0200873 kone_keep_values_up_to_date(kone, event);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100874
Stefan Achatz206f5f22010-05-19 18:55:16 +0200875 if (kone->roccat_claimed)
876 kone_report_to_chrdev(kone, event);
877
Stefan Achatz48e70802010-05-18 18:31:04 +0200878 return 0; /* always do further processing */
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100879}
880
881static const struct hid_device_id kone_devices[] = {
882 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
883 { }
884};
885
886MODULE_DEVICE_TABLE(hid, kone_devices);
887
888static struct hid_driver kone_driver = {
889 .name = "kone",
890 .id_table = kone_devices,
891 .probe = kone_probe,
892 .remove = kone_remove,
893 .raw_event = kone_raw_event
894};
895
Stefan Achatz00237bc2010-05-08 17:20:38 +0200896static int __init kone_init(void)
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100897{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000898 int retval;
899
900 /* class name has to be same as driver name */
901 kone_class = class_create(THIS_MODULE, "kone");
902 if (IS_ERR(kone_class))
903 return PTR_ERR(kone_class);
904 kone_class->dev_attrs = kone_attributes;
905 kone_class->dev_bin_attrs = kone_bin_attributes;
906
907 retval = hid_register_driver(&kone_driver);
908 if (retval)
909 class_destroy(kone_class);
910 return retval;
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100911}
912
Stefan Achatz00237bc2010-05-08 17:20:38 +0200913static void __exit kone_exit(void)
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100914{
Stefan Achatz5012aad2010-11-26 19:57:33 +0000915 class_destroy(kone_class);
Stefan Achatz14bf62c2010-03-18 16:19:43 +0100916 hid_unregister_driver(&kone_driver);
917}
918
919module_init(kone_init);
920module_exit(kone_exit);
921
Stefan Achatz1f749d82010-05-12 17:43:34 +0200922MODULE_AUTHOR("Stefan Achatz");
923MODULE_DESCRIPTION("USB Roccat Kone driver");
924MODULE_LICENSE("GPL v2");