Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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