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