Blame view
drivers/hid/hid-roccat-pyra.c
19 KB
cb7cf3da0 HID: roccat: add ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/* * Roccat Pyra driver for Linux * * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> */ /* * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. */ /* * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless * variant. Wireless variant is not tested. * Userland tools can be found at http://sourceforge.net/projects/roccat */ #include <linux/device.h> #include <linux/input.h> #include <linux/hid.h> |
cb7cf3da0 HID: roccat: add ... |
23 24 |
#include <linux/module.h> #include <linux/slab.h> |
5dc0c9835 HID: roccat: Rena... |
25 |
#include <linux/hid-roccat.h> |
cb7cf3da0 HID: roccat: add ... |
26 |
#include "hid-ids.h" |
5772f6361 HID: roccat: Intr... |
27 |
#include "hid-roccat-common.h" |
cb7cf3da0 HID: roccat: add ... |
28 |
#include "hid-roccat-pyra.h" |
14a057f80 HID: roccat: redu... |
29 |
static uint profile_numbers[5] = {0, 1, 2, 3, 4}; |
5012aada5 HID: roccat: use ... |
30 31 |
/* pyra_class is used for creating sysfs attributes via roccat char device */ static struct class *pyra_class; |
cb7cf3da0 HID: roccat: add ... |
32 33 34 35 36 37 38 39 40 41 |
static void profile_activated(struct pyra_device *pyra, unsigned int new_profile) { pyra->actual_profile = new_profile; pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; } static int pyra_send_control(struct usb_device *usb_dev, int value, enum pyra_control_requests request) { |
cb7cf3da0 HID: roccat: add ... |
42 43 44 45 46 47 48 49 50 51 |
struct pyra_control control; if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && (value < 0 || value > 4)) return -EINVAL; control.command = PYRA_COMMAND_CONTROL; control.value = value; control.request = request; |
1edd5b42a HID: roccat: corr... |
52 |
return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL, |
5772f6361 HID: roccat: Intr... |
53 |
&control, sizeof(struct pyra_control)); |
cb7cf3da0 HID: roccat: add ... |
54 55 56 57 |
} static int pyra_receive_control_status(struct usb_device *usb_dev) { |
5772f6361 HID: roccat: Intr... |
58 |
int retval; |
cb7cf3da0 HID: roccat: add ... |
59 60 61 62 |
struct pyra_control control; do { msleep(10); |
1edd5b42a HID: roccat: corr... |
63 |
retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL, |
5772f6361 HID: roccat: Intr... |
64 |
&control, sizeof(struct pyra_control)); |
cb7cf3da0 HID: roccat: add ... |
65 66 |
/* requested too early, try again */ |
5772f6361 HID: roccat: Intr... |
67 |
} while (retval == -EPROTO); |
cb7cf3da0 HID: roccat: add ... |
68 |
|
5772f6361 HID: roccat: Intr... |
69 |
if (!retval && control.command == PYRA_COMMAND_CONTROL && |
cb7cf3da0 HID: roccat: add ... |
70 71 |
control.request == PYRA_CONTROL_REQUEST_STATUS && control.value == 1) |
5772f6361 HID: roccat: Intr... |
72 |
return 0; |
cb7cf3da0 HID: roccat: add ... |
73 |
else { |
4291ee305 HID: Add and use ... |
74 75 76 |
hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x ", control.request, control.value); |
5772f6361 HID: roccat: Intr... |
77 |
return retval ? retval : -EINVAL; |
cb7cf3da0 HID: roccat: add ... |
78 79 80 81 82 83 84 |
} } static int pyra_get_profile_settings(struct usb_device *usb_dev, struct pyra_profile_settings *buf, int number) { int retval; |
cb7cf3da0 HID: roccat: add ... |
85 86 |
retval = pyra_send_control(usb_dev, number, PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); |
cb7cf3da0 HID: roccat: add ... |
87 88 |
if (retval) return retval; |
1edd5b42a HID: roccat: corr... |
89 |
return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, |
5772f6361 HID: roccat: Intr... |
90 |
buf, sizeof(struct pyra_profile_settings)); |
cb7cf3da0 HID: roccat: add ... |
91 92 93 94 95 96 |
} static int pyra_get_profile_buttons(struct usb_device *usb_dev, struct pyra_profile_buttons *buf, int number) { int retval; |
cb7cf3da0 HID: roccat: add ... |
97 98 |
retval = pyra_send_control(usb_dev, number, PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); |
cb7cf3da0 HID: roccat: add ... |
99 100 |
if (retval) return retval; |
1edd5b42a HID: roccat: corr... |
101 |
return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, |
5772f6361 HID: roccat: Intr... |
102 |
buf, sizeof(struct pyra_profile_buttons)); |
cb7cf3da0 HID: roccat: add ... |
103 104 105 106 107 |
} static int pyra_get_settings(struct usb_device *usb_dev, struct pyra_settings *buf) { |
1edd5b42a HID: roccat: corr... |
108 |
return roccat_common_receive(usb_dev, PYRA_COMMAND_SETTINGS, |
5772f6361 HID: roccat: Intr... |
109 |
buf, sizeof(struct pyra_settings)); |
cb7cf3da0 HID: roccat: add ... |
110 111 112 113 |
} static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) { |
1edd5b42a HID: roccat: corr... |
114 |
return roccat_common_receive(usb_dev, PYRA_COMMAND_INFO, |
5772f6361 HID: roccat: Intr... |
115 116 117 118 119 120 121 122 123 124 125 |
buf, sizeof(struct pyra_info)); } static int pyra_send(struct usb_device *usb_dev, uint command, void const *buf, uint size) { int retval; retval = roccat_common_send(usb_dev, command, buf, size); if (retval) return retval; return pyra_receive_control_status(usb_dev); |
cb7cf3da0 HID: roccat: add ... |
126 127 128 129 130 |
} static int pyra_set_profile_settings(struct usb_device *usb_dev, struct pyra_profile_settings const *settings) { |
1edd5b42a HID: roccat: corr... |
131 |
return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings, |
5772f6361 HID: roccat: Intr... |
132 |
sizeof(struct pyra_profile_settings)); |
cb7cf3da0 HID: roccat: add ... |
133 134 135 136 137 |
} static int pyra_set_profile_buttons(struct usb_device *usb_dev, struct pyra_profile_buttons const *buttons) { |
1edd5b42a HID: roccat: corr... |
138 |
return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons, |
5772f6361 HID: roccat: Intr... |
139 |
sizeof(struct pyra_profile_buttons)); |
cb7cf3da0 HID: roccat: add ... |
140 141 142 143 144 |
} static int pyra_set_settings(struct usb_device *usb_dev, struct pyra_settings const *settings) { |
1edd5b42a HID: roccat: corr... |
145 |
return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings, |
5772f6361 HID: roccat: Intr... |
146 |
sizeof(struct pyra_settings)); |
cb7cf3da0 HID: roccat: add ... |
147 148 149 150 |
} static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, |
14a057f80 HID: roccat: redu... |
151 |
loff_t off, size_t count) |
cb7cf3da0 HID: roccat: add ... |
152 |
{ |
5012aada5 HID: roccat: use ... |
153 154 |
struct device *dev = container_of(kobj, struct device, kobj)->parent->parent; |
cb7cf3da0 HID: roccat: add ... |
155 156 157 158 159 160 161 162 163 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct pyra_profile_settings)) return 0; if (off + count > sizeof(struct pyra_profile_settings)) count = sizeof(struct pyra_profile_settings) - off; mutex_lock(&pyra->pyra_lock); |
14a057f80 HID: roccat: redu... |
164 |
memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off, |
cb7cf3da0 HID: roccat: add ... |
165 166 167 168 169 |
count); mutex_unlock(&pyra->pyra_lock); return count; } |
cb7cf3da0 HID: roccat: add ... |
170 171 |
static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, |
14a057f80 HID: roccat: redu... |
172 |
loff_t off, size_t count) |
cb7cf3da0 HID: roccat: add ... |
173 |
{ |
5012aada5 HID: roccat: use ... |
174 175 |
struct device *dev = container_of(kobj, struct device, kobj)->parent->parent; |
cb7cf3da0 HID: roccat: add ... |
176 177 178 179 180 181 182 183 184 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct pyra_profile_buttons)) return 0; if (off + count > sizeof(struct pyra_profile_buttons)) count = sizeof(struct pyra_profile_buttons) - off; mutex_lock(&pyra->pyra_lock); |
14a057f80 HID: roccat: redu... |
185 |
memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off, |
cb7cf3da0 HID: roccat: add ... |
186 187 188 189 190 |
count); mutex_unlock(&pyra->pyra_lock); return count; } |
cb7cf3da0 HID: roccat: add ... |
191 192 193 194 |
static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { |
5012aada5 HID: roccat: use ... |
195 196 |
struct device *dev = container_of(kobj, struct device, kobj)->parent->parent; |
cb7cf3da0 HID: roccat: add ... |
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; int difference; int profile_number; struct pyra_profile_settings *profile_settings; if (off != 0 || count != sizeof(struct pyra_profile_settings)) return -EINVAL; profile_number = ((struct pyra_profile_settings const *)buf)->number; profile_settings = &pyra->profile_settings[profile_number]; mutex_lock(&pyra->pyra_lock); difference = memcmp(buf, profile_settings, sizeof(struct pyra_profile_settings)); if (difference) { retval = pyra_set_profile_settings(usb_dev, (struct pyra_profile_settings const *)buf); if (!retval) memcpy(profile_settings, buf, sizeof(struct pyra_profile_settings)); } mutex_unlock(&pyra->pyra_lock); if (retval) return retval; return sizeof(struct pyra_profile_settings); } static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { |
5012aada5 HID: roccat: use ... |
232 233 |
struct device *dev = container_of(kobj, struct device, kobj)->parent->parent; |
cb7cf3da0 HID: roccat: add ... |
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; int difference; int profile_number; struct pyra_profile_buttons *profile_buttons; if (off != 0 || count != sizeof(struct pyra_profile_buttons)) return -EINVAL; profile_number = ((struct pyra_profile_buttons const *)buf)->number; profile_buttons = &pyra->profile_buttons[profile_number]; mutex_lock(&pyra->pyra_lock); difference = memcmp(buf, profile_buttons, sizeof(struct pyra_profile_buttons)); if (difference) { retval = pyra_set_profile_buttons(usb_dev, (struct pyra_profile_buttons const *)buf); if (!retval) memcpy(profile_buttons, buf, sizeof(struct pyra_profile_buttons)); } mutex_unlock(&pyra->pyra_lock); if (retval) return retval; return sizeof(struct pyra_profile_buttons); } static ssize_t pyra_sysfs_read_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { |
5012aada5 HID: roccat: use ... |
269 270 |
struct device *dev = container_of(kobj, struct device, kobj)->parent->parent; |
cb7cf3da0 HID: roccat: add ... |
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); if (off >= sizeof(struct pyra_settings)) return 0; if (off + count > sizeof(struct pyra_settings)) count = sizeof(struct pyra_settings) - off; mutex_lock(&pyra->pyra_lock); memcpy(buf, ((char const *)&pyra->settings) + off, count); mutex_unlock(&pyra->pyra_lock); return count; } static ssize_t pyra_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { |
5012aada5 HID: roccat: use ... |
290 291 |
struct device *dev = container_of(kobj, struct device, kobj)->parent->parent; |
cb7cf3da0 HID: roccat: add ... |
292 293 294 295 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0; int difference; |
dc186b661 HID: roccat: Pyra... |
296 |
struct pyra_roccat_report roccat_report; |
cb7cf3da0 HID: roccat: add ... |
297 298 299 300 301 302 303 304 305 |
if (off != 0 || count != sizeof(struct pyra_settings)) return -EINVAL; mutex_lock(&pyra->pyra_lock); difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings)); if (difference) { retval = pyra_set_settings(usb_dev, (struct pyra_settings const *)buf); |
dc186b661 HID: roccat: Pyra... |
306 307 308 309 |
if (retval) { mutex_unlock(&pyra->pyra_lock); return retval; } |
cb7cf3da0 HID: roccat: add ... |
310 |
|
dc186b661 HID: roccat: Pyra... |
311 312 |
memcpy(&pyra->settings, buf, sizeof(struct pyra_settings)); |
cb7cf3da0 HID: roccat: add ... |
313 |
|
dc186b661 HID: roccat: Pyra... |
314 |
profile_activated(pyra, pyra->settings.startup_profile); |
cb7cf3da0 HID: roccat: add ... |
315 |
|
dc186b661 HID: roccat: Pyra... |
316 317 318 319 320 321 322 |
roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2; roccat_report.value = pyra->settings.startup_profile + 1; roccat_report.key = 0; roccat_report_event(pyra->chrdev_minor, (uint8_t const *)&roccat_report); } mutex_unlock(&pyra->pyra_lock); |
cb7cf3da0 HID: roccat: add ... |
323 324 325 326 327 328 329 |
return sizeof(struct pyra_settings); } static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, struct device_attribute *attr, char *buf) { |
5012aada5 HID: roccat: use ... |
330 331 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
cb7cf3da0 HID: roccat: add ... |
332 333 334 335 336 337 338 |
return snprintf(buf, PAGE_SIZE, "%d ", pyra->actual_cpi); } static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, struct device_attribute *attr, char *buf) { |
5012aada5 HID: roccat: use ... |
339 340 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
cb7cf3da0 HID: roccat: add ... |
341 342 343 344 345 346 347 |
return snprintf(buf, PAGE_SIZE, "%d ", pyra->actual_profile); } static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, struct device_attribute *attr, char *buf) { |
5012aada5 HID: roccat: use ... |
348 349 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
cb7cf3da0 HID: roccat: add ... |
350 351 352 353 354 355 356 |
return snprintf(buf, PAGE_SIZE, "%d ", pyra->firmware_version); } static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, struct device_attribute *attr, char *buf) { |
5012aada5 HID: roccat: use ... |
357 358 |
struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
cb7cf3da0 HID: roccat: add ... |
359 360 361 |
return snprintf(buf, PAGE_SIZE, "%d ", pyra->settings.startup_profile); } |
5012aada5 HID: roccat: use ... |
362 363 364 365 366 367 368 369 |
static struct device_attribute pyra_attributes[] = { __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL), __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL), __ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version, NULL), __ATTR(startup_profile, 0440, pyra_sysfs_show_startup_profile, NULL), __ATTR_NULL |
cb7cf3da0 HID: roccat: add ... |
370 |
}; |
5012aada5 HID: roccat: use ... |
371 372 |
static struct bin_attribute pyra_bin_attributes[] = { { |
cb7cf3da0 HID: roccat: add ... |
373 374 375 |
.attr = { .name = "profile_settings", .mode = 0220 }, .size = sizeof(struct pyra_profile_settings), .write = pyra_sysfs_write_profile_settings |
5012aada5 HID: roccat: use ... |
376 377 |
}, { |
cb7cf3da0 HID: roccat: add ... |
378 379 |
.attr = { .name = "profile1_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), |
14a057f80 HID: roccat: redu... |
380 381 |
.read = pyra_sysfs_read_profilex_settings, .private = &profile_numbers[0] |
5012aada5 HID: roccat: use ... |
382 383 |
}, { |
cb7cf3da0 HID: roccat: add ... |
384 385 |
.attr = { .name = "profile2_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), |
14a057f80 HID: roccat: redu... |
386 387 |
.read = pyra_sysfs_read_profilex_settings, .private = &profile_numbers[1] |
5012aada5 HID: roccat: use ... |
388 389 |
}, { |
cb7cf3da0 HID: roccat: add ... |
390 391 |
.attr = { .name = "profile3_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), |
14a057f80 HID: roccat: redu... |
392 393 |
.read = pyra_sysfs_read_profilex_settings, .private = &profile_numbers[2] |
5012aada5 HID: roccat: use ... |
394 395 |
}, { |
cb7cf3da0 HID: roccat: add ... |
396 397 |
.attr = { .name = "profile4_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), |
14a057f80 HID: roccat: redu... |
398 399 |
.read = pyra_sysfs_read_profilex_settings, .private = &profile_numbers[3] |
5012aada5 HID: roccat: use ... |
400 401 |
}, { |
cb7cf3da0 HID: roccat: add ... |
402 403 |
.attr = { .name = "profile5_settings", .mode = 0440 }, .size = sizeof(struct pyra_profile_settings), |
14a057f80 HID: roccat: redu... |
404 405 |
.read = pyra_sysfs_read_profilex_settings, .private = &profile_numbers[4] |
5012aada5 HID: roccat: use ... |
406 407 |
}, { |
cb7cf3da0 HID: roccat: add ... |
408 409 410 |
.attr = { .name = "profile_buttons", .mode = 0220 }, .size = sizeof(struct pyra_profile_buttons), .write = pyra_sysfs_write_profile_buttons |
5012aada5 HID: roccat: use ... |
411 412 |
}, { |
cb7cf3da0 HID: roccat: add ... |
413 414 |
.attr = { .name = "profile1_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), |
14a057f80 HID: roccat: redu... |
415 416 |
.read = pyra_sysfs_read_profilex_buttons, .private = &profile_numbers[0] |
5012aada5 HID: roccat: use ... |
417 418 |
}, { |
cb7cf3da0 HID: roccat: add ... |
419 420 |
.attr = { .name = "profile2_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), |
14a057f80 HID: roccat: redu... |
421 422 |
.read = pyra_sysfs_read_profilex_buttons, .private = &profile_numbers[1] |
5012aada5 HID: roccat: use ... |
423 424 |
}, { |
cb7cf3da0 HID: roccat: add ... |
425 426 |
.attr = { .name = "profile3_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), |
14a057f80 HID: roccat: redu... |
427 428 |
.read = pyra_sysfs_read_profilex_buttons, .private = &profile_numbers[2] |
5012aada5 HID: roccat: use ... |
429 430 |
}, { |
cb7cf3da0 HID: roccat: add ... |
431 432 |
.attr = { .name = "profile4_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), |
14a057f80 HID: roccat: redu... |
433 434 |
.read = pyra_sysfs_read_profilex_buttons, .private = &profile_numbers[3] |
5012aada5 HID: roccat: use ... |
435 436 |
}, { |
cb7cf3da0 HID: roccat: add ... |
437 438 |
.attr = { .name = "profile5_buttons", .mode = 0440 }, .size = sizeof(struct pyra_profile_buttons), |
14a057f80 HID: roccat: redu... |
439 440 |
.read = pyra_sysfs_read_profilex_buttons, .private = &profile_numbers[4] |
5012aada5 HID: roccat: use ... |
441 442 |
}, { |
cb7cf3da0 HID: roccat: add ... |
443 444 445 446 |
.attr = { .name = "settings", .mode = 0660 }, .size = sizeof(struct pyra_settings), .read = pyra_sysfs_read_settings, .write = pyra_sysfs_write_settings |
5012aada5 HID: roccat: use ... |
447 448 |
}, __ATTR_NULL |
cb7cf3da0 HID: roccat: add ... |
449 |
}; |
cb7cf3da0 HID: roccat: add ... |
450 451 452 |
static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, struct pyra_device *pyra) { |
5772f6361 HID: roccat: Intr... |
453 |
struct pyra_info info; |
cb7cf3da0 HID: roccat: add ... |
454 455 456 |
int retval, i; mutex_init(&pyra->pyra_lock); |
5772f6361 HID: roccat: Intr... |
457 458 |
retval = pyra_get_info(usb_dev, &info); if (retval) |
cb7cf3da0 HID: roccat: add ... |
459 |
return retval; |
5772f6361 HID: roccat: Intr... |
460 461 |
pyra->firmware_version = info.firmware_version; |
cb7cf3da0 HID: roccat: add ... |
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
retval = pyra_get_settings(usb_dev, &pyra->settings); if (retval) return retval; for (i = 0; i < 5; ++i) { retval = pyra_get_profile_settings(usb_dev, &pyra->profile_settings[i], i); if (retval) return retval; retval = pyra_get_profile_buttons(usb_dev, &pyra->profile_buttons[i], i); if (retval) return retval; } profile_activated(pyra, pyra->settings.startup_profile); return 0; } static int pyra_init_specials(struct hid_device *hdev) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_device *usb_dev = interface_to_usbdev(intf); struct pyra_device *pyra; int retval; if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); if (!pyra) { |
4291ee305 HID: Add and use ... |
496 497 |
hid_err(hdev, "can't alloc device descriptor "); |
cb7cf3da0 HID: roccat: add ... |
498 499 500 501 502 503 |
return -ENOMEM; } hid_set_drvdata(hdev, pyra); retval = pyra_init_pyra_device_struct(usb_dev, pyra); if (retval) { |
4291ee305 HID: Add and use ... |
504 505 |
hid_err(hdev, "couldn't init struct pyra_device "); |
cb7cf3da0 HID: roccat: add ... |
506 507 |
goto exit_free; } |
8211e4600 HID: roccat: Add ... |
508 509 |
retval = roccat_connect(pyra_class, hdev, sizeof(struct pyra_roccat_report)); |
cb7cf3da0 HID: roccat: add ... |
510 |
if (retval < 0) { |
4291ee305 HID: Add and use ... |
511 512 |
hid_err(hdev, "couldn't init char dev "); |
cb7cf3da0 HID: roccat: add ... |
513 514 515 516 |
} else { pyra->chrdev_minor = retval; pyra->roccat_claimed = 1; } |
cb7cf3da0 HID: roccat: add ... |
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
} else { hid_set_drvdata(hdev, NULL); } return 0; exit_free: kfree(pyra); return retval; } static void pyra_remove_specials(struct hid_device *hdev) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct pyra_device *pyra; if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { |
cb7cf3da0 HID: roccat: add ... |
534 535 536 537 538 539 540 541 542 543 544 545 546 |
pyra = hid_get_drvdata(hdev); if (pyra->roccat_claimed) roccat_disconnect(pyra->chrdev_minor); kfree(hid_get_drvdata(hdev)); } } static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; retval = hid_parse(hdev); if (retval) { |
4291ee305 HID: Add and use ... |
547 548 |
hid_err(hdev, "parse failed "); |
cb7cf3da0 HID: roccat: add ... |
549 550 551 552 553 |
goto exit; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { |
4291ee305 HID: Add and use ... |
554 555 |
hid_err(hdev, "hw start failed "); |
cb7cf3da0 HID: roccat: add ... |
556 557 558 559 560 |
goto exit; } retval = pyra_init_specials(hdev); if (retval) { |
4291ee305 HID: Add and use ... |
561 562 |
hid_err(hdev, "couldn't install mouse "); |
cb7cf3da0 HID: roccat: add ... |
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
goto exit_stop; } return 0; exit_stop: hid_hw_stop(hdev); exit: return retval; } static void pyra_remove(struct hid_device *hdev) { pyra_remove_specials(hdev); hid_hw_stop(hdev); } static void pyra_keep_values_up_to_date(struct pyra_device *pyra, u8 const *data) { struct pyra_mouse_event_button const *button_event; switch (data[0]) { case PYRA_MOUSE_REPORT_NUMBER_BUTTON: button_event = (struct pyra_mouse_event_button const *)data; switch (button_event->type) { case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: profile_activated(pyra, button_event->data1 - 1); break; case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: pyra->actual_cpi = button_event->data1; break; } break; } } static void pyra_report_to_chrdev(struct pyra_device const *pyra, u8 const *data) { struct pyra_roccat_report roccat_report; struct pyra_mouse_event_button const *button_event; if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON) return; button_event = (struct pyra_mouse_event_button const *)data; switch (button_event->type) { case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: roccat_report.type = button_event->type; roccat_report.value = button_event->data1; roccat_report.key = 0; roccat_report_event(pyra->chrdev_minor, |
8211e4600 HID: roccat: Add ... |
617 |
(uint8_t const *)&roccat_report); |
cb7cf3da0 HID: roccat: add ... |
618 619 620 621 622 623 624 |
break; case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO: case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT: case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH: if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) { roccat_report.type = button_event->type; roccat_report.key = button_event->data1; |
d2b570a5d HID: roccat: Norm... |
625 626 627 628 629 |
/* * pyra reports profile numbers with range 1-5. * Keeping this behaviour. */ roccat_report.value = pyra->actual_profile + 1; |
cb7cf3da0 HID: roccat: add ... |
630 |
roccat_report_event(pyra->chrdev_minor, |
8211e4600 HID: roccat: Add ... |
631 |
(uint8_t const *)&roccat_report); |
cb7cf3da0 HID: roccat: add ... |
632 633 634 635 636 637 638 639 640 641 642 643 644 645 |
} break; } } static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct pyra_device *pyra = hid_get_drvdata(hdev); if (intf->cur_altsetting->desc.bInterfaceProtocol != USB_INTERFACE_PROTOCOL_MOUSE) return 0; |
901e64dbd HID: roccat: fix ... |
646 647 |
if (pyra == NULL) return 0; |
cb7cf3da0 HID: roccat: add ... |
648 649 650 651 652 653 654 655 656 657 658 |
pyra_keep_values_up_to_date(pyra, data); if (pyra->roccat_claimed) pyra_report_to_chrdev(pyra, data); return 0; } static const struct hid_device_id pyra_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, |
3fce22460 HID: roccat: Add ... |
659 660 |
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, |
cb7cf3da0 HID: roccat: add ... |
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
{ } }; MODULE_DEVICE_TABLE(hid, pyra_devices); static struct hid_driver pyra_driver = { .name = "pyra", .id_table = pyra_devices, .probe = pyra_probe, .remove = pyra_remove, .raw_event = pyra_raw_event }; static int __init pyra_init(void) { |
5012aada5 HID: roccat: use ... |
676 677 678 679 680 681 682 683 684 685 686 687 688 |
int retval; /* class name has to be same as driver name */ pyra_class = class_create(THIS_MODULE, "pyra"); if (IS_ERR(pyra_class)) return PTR_ERR(pyra_class); pyra_class->dev_attrs = pyra_attributes; pyra_class->dev_bin_attrs = pyra_bin_attributes; retval = hid_register_driver(&pyra_driver); if (retval) class_destroy(pyra_class); return retval; |
cb7cf3da0 HID: roccat: add ... |
689 690 691 692 693 |
} static void __exit pyra_exit(void) { hid_unregister_driver(&pyra_driver); |
74b643dac HID: roccat: Fix ... |
694 |
class_destroy(pyra_class); |
cb7cf3da0 HID: roccat: add ... |
695 696 697 698 699 700 701 702 |
} module_init(pyra_init); module_exit(pyra_exit); MODULE_AUTHOR("Stefan Achatz"); MODULE_DESCRIPTION("USB Roccat Pyra driver"); MODULE_LICENSE("GPL v2"); |