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