md/bitmap: disable bitmap_resize for file-backed bitmaps.
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / hid / hid-roccat-pyra.c
CommitLineData
cb7cf3da
SA
1/*
2 * Roccat Pyra 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 Pyra is a mobile gamer mouse which comes in wired and wireless
16 * variant. Wireless variant is not tested.
17 * Userland tools can be found at http://sourceforge.net/projects/roccat
18 */
19
20#include <linux/device.h>
21#include <linux/input.h>
22#include <linux/hid.h>
cb7cf3da
SA
23#include <linux/module.h>
24#include <linux/slab.h>
5dc0c983 25#include <linux/hid-roccat.h>
cb7cf3da 26#include "hid-ids.h"
5772f636 27#include "hid-roccat-common.h"
cb7cf3da
SA
28#include "hid-roccat-pyra.h"
29
14a057f8
SA
30static uint profile_numbers[5] = {0, 1, 2, 3, 4};
31
5012aada
SA
32/* pyra_class is used for creating sysfs attributes via roccat char device */
33static struct class *pyra_class;
34
cb7cf3da
SA
35static void profile_activated(struct pyra_device *pyra,
36 unsigned int new_profile)
37{
94bb429e
DC
38 if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
39 return;
cb7cf3da
SA
40 pyra->actual_profile = new_profile;
41 pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
42}
43
44static int pyra_send_control(struct usb_device *usb_dev, int value,
45 enum pyra_control_requests request)
46{
7392d73b 47 struct roccat_common2_control control;
cb7cf3da
SA
48
49 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
50 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
51 (value < 0 || value > 4))
52 return -EINVAL;
53
4728f2dc 54 control.command = ROCCAT_COMMON_COMMAND_CONTROL;
cb7cf3da
SA
55 control.value = value;
56 control.request = request;
57
7392d73b
SA
58 return roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
59 &control, sizeof(struct roccat_common2_control));
cb7cf3da
SA
60}
61
62static int pyra_get_profile_settings(struct usb_device *usb_dev,
63 struct pyra_profile_settings *buf, int number)
64{
65 int retval;
cb7cf3da
SA
66 retval = pyra_send_control(usb_dev, number,
67 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
cb7cf3da
SA
68 if (retval)
69 return retval;
7392d73b 70 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
be34380e 71 buf, PYRA_SIZE_PROFILE_SETTINGS);
cb7cf3da
SA
72}
73
74static int pyra_get_settings(struct usb_device *usb_dev,
75 struct pyra_settings *buf)
76{
7392d73b 77 return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
be34380e 78 buf, PYRA_SIZE_SETTINGS);
cb7cf3da
SA
79}
80
81static int pyra_set_settings(struct usb_device *usb_dev,
82 struct pyra_settings const *settings)
83{
7392d73b 84 return roccat_common2_send_with_status(usb_dev,
4728f2dc 85 PYRA_COMMAND_SETTINGS, settings,
be34380e 86 PYRA_SIZE_SETTINGS);
cb7cf3da
SA
87}
88
be34380e
SA
89static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj,
90 char *buf, loff_t off, size_t count,
91 size_t real_size, uint command)
cb7cf3da 92{
5012aada
SA
93 struct device *dev =
94 container_of(kobj, struct device, kobj)->parent->parent;
cb7cf3da 95 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
be34380e
SA
96 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
97 int retval;
cb7cf3da 98
be34380e 99 if (off >= real_size)
cb7cf3da
SA
100 return 0;
101
be34380e
SA
102 if (off != 0 || count != real_size)
103 return -EINVAL;
cb7cf3da
SA
104
105 mutex_lock(&pyra->pyra_lock);
be34380e 106 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
cb7cf3da
SA
107 mutex_unlock(&pyra->pyra_lock);
108
be34380e
SA
109 if (retval)
110 return retval;
111
112 return real_size;
cb7cf3da
SA
113}
114
be34380e
SA
115static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj,
116 void const *buf, loff_t off, size_t count,
117 size_t real_size, uint command)
cb7cf3da 118{
5012aada
SA
119 struct device *dev =
120 container_of(kobj, struct device, kobj)->parent->parent;
cb7cf3da 121 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
be34380e
SA
122 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
123 int retval;
cb7cf3da 124
be34380e
SA
125 if (off != 0 || count != real_size)
126 return -EINVAL;
cb7cf3da
SA
127
128 mutex_lock(&pyra->pyra_lock);
be34380e 129 retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size);
cb7cf3da
SA
130 mutex_unlock(&pyra->pyra_lock);
131
be34380e
SA
132 if (retval)
133 return retval;
134
135 return real_size;
cb7cf3da
SA
136}
137
be34380e
SA
138#define PYRA_SYSFS_W(thingy, THINGY) \
139static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \
140 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
141 loff_t off, size_t count) \
142{ \
143 return pyra_sysfs_write(fp, kobj, buf, off, count, \
144 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
145}
cb7cf3da 146
be34380e
SA
147#define PYRA_SYSFS_R(thingy, THINGY) \
148static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \
149 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
150 loff_t off, size_t count) \
151{ \
152 return pyra_sysfs_read(fp, kobj, buf, off, count, \
153 PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
154}
cb7cf3da 155
be34380e
SA
156#define PYRA_SYSFS_RW(thingy, THINGY) \
157PYRA_SYSFS_W(thingy, THINGY) \
158PYRA_SYSFS_R(thingy, THINGY)
cb7cf3da 159
be34380e
SA
160#define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
161{ \
162 .attr = { .name = #thingy, .mode = 0660 }, \
163 .size = PYRA_SIZE_ ## THINGY, \
164 .read = pyra_sysfs_read_ ## thingy, \
165 .write = pyra_sysfs_write_ ## thingy \
166}
cb7cf3da 167
be34380e
SA
168#define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
169{ \
170 .attr = { .name = #thingy, .mode = 0440 }, \
171 .size = PYRA_SIZE_ ## THINGY, \
172 .read = pyra_sysfs_read_ ## thingy, \
173}
cb7cf3da 174
be34380e
SA
175#define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
176{ \
177 .attr = { .name = #thingy, .mode = 0220 }, \
178 .size = PYRA_SIZE_ ## THINGY, \
179 .write = pyra_sysfs_write_ ## thingy \
cb7cf3da
SA
180}
181
ecbfe7aa 182PYRA_SYSFS_W(control, CONTROL)
be34380e 183PYRA_SYSFS_RW(info, INFO)
ecbfe7aa
SA
184PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
185PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
be34380e
SA
186PYRA_SYSFS_R(settings, SETTINGS)
187
188static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
cb7cf3da
SA
189 struct kobject *kobj, struct bin_attribute *attr, char *buf,
190 loff_t off, size_t count)
191{
5012aada
SA
192 struct device *dev =
193 container_of(kobj, struct device, kobj)->parent->parent;
cb7cf3da 194 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
be34380e 195 ssize_t retval;
cb7cf3da 196
be34380e
SA
197 retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
198 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
cb7cf3da
SA
199 if (retval)
200 return retval;
201
be34380e
SA
202 return pyra_sysfs_read(fp, kobj, buf, off, count,
203 PYRA_SIZE_PROFILE_SETTINGS,
204 PYRA_COMMAND_PROFILE_SETTINGS);
cb7cf3da
SA
205}
206
be34380e 207static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
cb7cf3da
SA
208 struct kobject *kobj, struct bin_attribute *attr, char *buf,
209 loff_t off, size_t count)
210{
5012aada
SA
211 struct device *dev =
212 container_of(kobj, struct device, kobj)->parent->parent;
be34380e
SA
213 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
214 ssize_t retval;
cb7cf3da 215
be34380e
SA
216 retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
217 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
218 if (retval)
219 return retval;
cb7cf3da 220
be34380e
SA
221 return pyra_sysfs_read(fp, kobj, buf, off, count,
222 PYRA_SIZE_PROFILE_BUTTONS,
223 PYRA_COMMAND_PROFILE_BUTTONS);
cb7cf3da
SA
224}
225
226static ssize_t pyra_sysfs_write_settings(struct file *fp,
227 struct kobject *kobj, struct bin_attribute *attr, char *buf,
228 loff_t off, size_t count)
229{
5012aada
SA
230 struct device *dev =
231 container_of(kobj, struct device, kobj)->parent->parent;
cb7cf3da
SA
232 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
233 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
234 int retval = 0;
dc186b66 235 struct pyra_roccat_report roccat_report;
be34380e 236 struct pyra_settings const *settings;
cb7cf3da 237
be34380e 238 if (off != 0 || count != PYRA_SIZE_SETTINGS)
cb7cf3da
SA
239 return -EINVAL;
240
be34380e 241 settings = (struct pyra_settings const *)buf;
94bb429e
DC
242 if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
243 return -EINVAL;
244
245 mutex_lock(&pyra->pyra_lock);
cb7cf3da 246
be34380e
SA
247 retval = pyra_set_settings(usb_dev, settings);
248 if (retval) {
249 mutex_unlock(&pyra->pyra_lock);
250 return retval;
dc186b66 251 }
be34380e
SA
252
253 profile_activated(pyra, settings->startup_profile);
254
255 roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
256 roccat_report.value = settings->startup_profile + 1;
257 roccat_report.key = 0;
258 roccat_report_event(pyra->chrdev_minor,
259 (uint8_t const *)&roccat_report);
260
dc186b66 261 mutex_unlock(&pyra->pyra_lock);
be34380e 262 return PYRA_SIZE_SETTINGS;
cb7cf3da
SA
263}
264
265
266static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
267 struct device_attribute *attr, char *buf)
268{
5012aada
SA
269 struct pyra_device *pyra =
270 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
cb7cf3da
SA
271 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
272}
273
274static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
275 struct device_attribute *attr, char *buf)
276{
5012aada
SA
277 struct pyra_device *pyra =
278 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
be34380e
SA
279 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
280 struct pyra_settings settings;
281
282 mutex_lock(&pyra->pyra_lock);
283 roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
284 &settings, PYRA_SIZE_SETTINGS);
285 mutex_unlock(&pyra->pyra_lock);
286
287 return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile);
cb7cf3da
SA
288}
289
290static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
291 struct device_attribute *attr, char *buf)
292{
be34380e
SA
293 struct pyra_device *pyra;
294 struct usb_device *usb_dev;
295 struct pyra_info info;
cb7cf3da 296
be34380e
SA
297 dev = dev->parent->parent;
298 pyra = hid_get_drvdata(dev_get_drvdata(dev));
299 usb_dev = interface_to_usbdev(to_usb_interface(dev));
300
301 mutex_lock(&pyra->pyra_lock);
302 roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
303 &info, PYRA_SIZE_INFO);
304 mutex_unlock(&pyra->pyra_lock);
305
306 return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
cb7cf3da
SA
307}
308
5012aada
SA
309static struct device_attribute pyra_attributes[] = {
310 __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL),
311 __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL),
312 __ATTR(firmware_version, 0440,
313 pyra_sysfs_show_firmware_version, NULL),
314 __ATTR(startup_profile, 0440,
be34380e 315 pyra_sysfs_show_actual_profile, NULL),
5012aada 316 __ATTR_NULL
cb7cf3da
SA
317};
318
5012aada 319static struct bin_attribute pyra_bin_attributes[] = {
ecbfe7aa 320 PYRA_BIN_ATTRIBUTE_W(control, CONTROL),
be34380e 321 PYRA_BIN_ATTRIBUTE_RW(info, INFO),
ecbfe7aa
SA
322 PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
323 PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
be34380e 324 PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS),
5012aada 325 {
cb7cf3da 326 .attr = { .name = "profile1_settings", .mode = 0440 },
be34380e 327 .size = PYRA_SIZE_PROFILE_SETTINGS,
14a057f8
SA
328 .read = pyra_sysfs_read_profilex_settings,
329 .private = &profile_numbers[0]
5012aada
SA
330 },
331 {
cb7cf3da 332 .attr = { .name = "profile2_settings", .mode = 0440 },
be34380e 333 .size = PYRA_SIZE_PROFILE_SETTINGS,
14a057f8
SA
334 .read = pyra_sysfs_read_profilex_settings,
335 .private = &profile_numbers[1]
5012aada
SA
336 },
337 {
cb7cf3da 338 .attr = { .name = "profile3_settings", .mode = 0440 },
be34380e 339 .size = PYRA_SIZE_PROFILE_SETTINGS,
14a057f8
SA
340 .read = pyra_sysfs_read_profilex_settings,
341 .private = &profile_numbers[2]
5012aada
SA
342 },
343 {
cb7cf3da 344 .attr = { .name = "profile4_settings", .mode = 0440 },
be34380e 345 .size = PYRA_SIZE_PROFILE_SETTINGS,
14a057f8
SA
346 .read = pyra_sysfs_read_profilex_settings,
347 .private = &profile_numbers[3]
5012aada
SA
348 },
349 {
cb7cf3da 350 .attr = { .name = "profile5_settings", .mode = 0440 },
be34380e 351 .size = PYRA_SIZE_PROFILE_SETTINGS,
14a057f8
SA
352 .read = pyra_sysfs_read_profilex_settings,
353 .private = &profile_numbers[4]
5012aada 354 },
5012aada 355 {
cb7cf3da 356 .attr = { .name = "profile1_buttons", .mode = 0440 },
be34380e 357 .size = PYRA_SIZE_PROFILE_BUTTONS,
14a057f8
SA
358 .read = pyra_sysfs_read_profilex_buttons,
359 .private = &profile_numbers[0]
5012aada
SA
360 },
361 {
cb7cf3da 362 .attr = { .name = "profile2_buttons", .mode = 0440 },
be34380e 363 .size = PYRA_SIZE_PROFILE_BUTTONS,
14a057f8
SA
364 .read = pyra_sysfs_read_profilex_buttons,
365 .private = &profile_numbers[1]
5012aada
SA
366 },
367 {
cb7cf3da 368 .attr = { .name = "profile3_buttons", .mode = 0440 },
be34380e 369 .size = PYRA_SIZE_PROFILE_BUTTONS,
14a057f8
SA
370 .read = pyra_sysfs_read_profilex_buttons,
371 .private = &profile_numbers[2]
5012aada
SA
372 },
373 {
cb7cf3da 374 .attr = { .name = "profile4_buttons", .mode = 0440 },
be34380e 375 .size = PYRA_SIZE_PROFILE_BUTTONS,
14a057f8
SA
376 .read = pyra_sysfs_read_profilex_buttons,
377 .private = &profile_numbers[3]
5012aada
SA
378 },
379 {
cb7cf3da 380 .attr = { .name = "profile5_buttons", .mode = 0440 },
be34380e 381 .size = PYRA_SIZE_PROFILE_BUTTONS,
14a057f8
SA
382 .read = pyra_sysfs_read_profilex_buttons,
383 .private = &profile_numbers[4]
5012aada 384 },
5012aada 385 __ATTR_NULL
cb7cf3da
SA
386};
387
cb7cf3da
SA
388static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
389 struct pyra_device *pyra)
390{
be34380e 391 struct pyra_settings settings;
cb7cf3da
SA
392 int retval, i;
393
394 mutex_init(&pyra->pyra_lock);
395
be34380e 396 retval = pyra_get_settings(usb_dev, &settings);
cb7cf3da
SA
397 if (retval)
398 return retval;
399
400 for (i = 0; i < 5; ++i) {
401 retval = pyra_get_profile_settings(usb_dev,
402 &pyra->profile_settings[i], i);
403 if (retval)
404 return retval;
cb7cf3da
SA
405 }
406
be34380e 407 profile_activated(pyra, settings.startup_profile);
cb7cf3da
SA
408
409 return 0;
410}
411
412static int pyra_init_specials(struct hid_device *hdev)
413{
414 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
415 struct usb_device *usb_dev = interface_to_usbdev(intf);
416 struct pyra_device *pyra;
417 int retval;
418
419 if (intf->cur_altsetting->desc.bInterfaceProtocol
420 == USB_INTERFACE_PROTOCOL_MOUSE) {
421
422 pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
423 if (!pyra) {
4291ee30 424 hid_err(hdev, "can't alloc device descriptor\n");
cb7cf3da
SA
425 return -ENOMEM;
426 }
427 hid_set_drvdata(hdev, pyra);
428
429 retval = pyra_init_pyra_device_struct(usb_dev, pyra);
430 if (retval) {
4291ee30 431 hid_err(hdev, "couldn't init struct pyra_device\n");
cb7cf3da
SA
432 goto exit_free;
433 }
434
8211e460
SA
435 retval = roccat_connect(pyra_class, hdev,
436 sizeof(struct pyra_roccat_report));
cb7cf3da 437 if (retval < 0) {
4291ee30 438 hid_err(hdev, "couldn't init char dev\n");
cb7cf3da
SA
439 } else {
440 pyra->chrdev_minor = retval;
441 pyra->roccat_claimed = 1;
442 }
cb7cf3da
SA
443 } else {
444 hid_set_drvdata(hdev, NULL);
445 }
446
447 return 0;
448exit_free:
449 kfree(pyra);
450 return retval;
451}
452
453static void pyra_remove_specials(struct hid_device *hdev)
454{
455 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
456 struct pyra_device *pyra;
457
458 if (intf->cur_altsetting->desc.bInterfaceProtocol
459 == USB_INTERFACE_PROTOCOL_MOUSE) {
cb7cf3da
SA
460 pyra = hid_get_drvdata(hdev);
461 if (pyra->roccat_claimed)
462 roccat_disconnect(pyra->chrdev_minor);
463 kfree(hid_get_drvdata(hdev));
464 }
465}
466
467static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
468{
469 int retval;
470
471 retval = hid_parse(hdev);
472 if (retval) {
4291ee30 473 hid_err(hdev, "parse failed\n");
cb7cf3da
SA
474 goto exit;
475 }
476
477 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
478 if (retval) {
4291ee30 479 hid_err(hdev, "hw start failed\n");
cb7cf3da
SA
480 goto exit;
481 }
482
483 retval = pyra_init_specials(hdev);
484 if (retval) {
4291ee30 485 hid_err(hdev, "couldn't install mouse\n");
cb7cf3da
SA
486 goto exit_stop;
487 }
488 return 0;
489
490exit_stop:
491 hid_hw_stop(hdev);
492exit:
493 return retval;
494}
495
496static void pyra_remove(struct hid_device *hdev)
497{
498 pyra_remove_specials(hdev);
499 hid_hw_stop(hdev);
500}
501
502static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
503 u8 const *data)
504{
505 struct pyra_mouse_event_button const *button_event;
506
507 switch (data[0]) {
508 case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
509 button_event = (struct pyra_mouse_event_button const *)data;
510 switch (button_event->type) {
511 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
512 profile_activated(pyra, button_event->data1 - 1);
513 break;
514 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
515 pyra->actual_cpi = button_event->data1;
516 break;
517 }
518 break;
519 }
520}
521
522static void pyra_report_to_chrdev(struct pyra_device const *pyra,
523 u8 const *data)
524{
525 struct pyra_roccat_report roccat_report;
526 struct pyra_mouse_event_button const *button_event;
527
528 if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
529 return;
530
531 button_event = (struct pyra_mouse_event_button const *)data;
532
533 switch (button_event->type) {
534 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
535 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
536 roccat_report.type = button_event->type;
537 roccat_report.value = button_event->data1;
538 roccat_report.key = 0;
539 roccat_report_event(pyra->chrdev_minor,
8211e460 540 (uint8_t const *)&roccat_report);
cb7cf3da
SA
541 break;
542 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
543 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
544 case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
545 if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
546 roccat_report.type = button_event->type;
547 roccat_report.key = button_event->data1;
d2b570a5
SA
548 /*
549 * pyra reports profile numbers with range 1-5.
550 * Keeping this behaviour.
551 */
552 roccat_report.value = pyra->actual_profile + 1;
cb7cf3da 553 roccat_report_event(pyra->chrdev_minor,
8211e460 554 (uint8_t const *)&roccat_report);
cb7cf3da
SA
555 }
556 break;
557 }
558}
559
560static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
561 u8 *data, int size)
562{
563 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
564 struct pyra_device *pyra = hid_get_drvdata(hdev);
565
566 if (intf->cur_altsetting->desc.bInterfaceProtocol
567 != USB_INTERFACE_PROTOCOL_MOUSE)
568 return 0;
569
901e64db
SA
570 if (pyra == NULL)
571 return 0;
572
cb7cf3da
SA
573 pyra_keep_values_up_to_date(pyra, data);
574
575 if (pyra->roccat_claimed)
576 pyra_report_to_chrdev(pyra, data);
577
578 return 0;
579}
580
581static const struct hid_device_id pyra_devices[] = {
582 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
583 USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
3fce2246
SA
584 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
585 USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
cb7cf3da
SA
586 { }
587};
588
589MODULE_DEVICE_TABLE(hid, pyra_devices);
590
591static struct hid_driver pyra_driver = {
592 .name = "pyra",
593 .id_table = pyra_devices,
594 .probe = pyra_probe,
595 .remove = pyra_remove,
596 .raw_event = pyra_raw_event
597};
598
599static int __init pyra_init(void)
600{
5012aada
SA
601 int retval;
602
603 /* class name has to be same as driver name */
604 pyra_class = class_create(THIS_MODULE, "pyra");
605 if (IS_ERR(pyra_class))
606 return PTR_ERR(pyra_class);
607 pyra_class->dev_attrs = pyra_attributes;
608 pyra_class->dev_bin_attrs = pyra_bin_attributes;
609
610 retval = hid_register_driver(&pyra_driver);
611 if (retval)
612 class_destroy(pyra_class);
613 return retval;
cb7cf3da
SA
614}
615
616static void __exit pyra_exit(void)
617{
618 hid_unregister_driver(&pyra_driver);
74b643da 619 class_destroy(pyra_class);
cb7cf3da
SA
620}
621
622module_init(pyra_init);
623module_exit(pyra_exit);
624
625MODULE_AUTHOR("Stefan Achatz");
626MODULE_DESCRIPTION("USB Roccat Pyra driver");
627MODULE_LICENSE("GPL v2");