Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Roccat Pyra driver for Linux
0004  *
0005  * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
0006  */
0007 
0008 /*
0009  */
0010 
0011 /*
0012  * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless
0013  * variant. Wireless variant is not tested.
0014  * Userland tools can be found at http://sourceforge.net/projects/roccat
0015  */
0016 
0017 #include <linux/device.h>
0018 #include <linux/input.h>
0019 #include <linux/hid.h>
0020 #include <linux/module.h>
0021 #include <linux/slab.h>
0022 #include <linux/hid-roccat.h>
0023 #include "hid-ids.h"
0024 #include "hid-roccat-common.h"
0025 #include "hid-roccat-pyra.h"
0026 
0027 static uint profile_numbers[5] = {0, 1, 2, 3, 4};
0028 
0029 /* pyra_class is used for creating sysfs attributes via roccat char device */
0030 static struct class *pyra_class;
0031 
0032 static void profile_activated(struct pyra_device *pyra,
0033         unsigned int new_profile)
0034 {
0035     if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
0036         return;
0037     pyra->actual_profile = new_profile;
0038     pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
0039 }
0040 
0041 static int pyra_send_control(struct usb_device *usb_dev, int value,
0042         enum pyra_control_requests request)
0043 {
0044     struct roccat_common2_control control;
0045 
0046     if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
0047             request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
0048             (value < 0 || value > 4))
0049         return -EINVAL;
0050 
0051     control.command = ROCCAT_COMMON_COMMAND_CONTROL;
0052     control.value = value;
0053     control.request = request;
0054 
0055     return roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
0056             &control, sizeof(struct roccat_common2_control));
0057 }
0058 
0059 static int pyra_get_profile_settings(struct usb_device *usb_dev,
0060         struct pyra_profile_settings *buf, int number)
0061 {
0062     int retval;
0063     retval = pyra_send_control(usb_dev, number,
0064             PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
0065     if (retval)
0066         return retval;
0067     return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
0068             buf, PYRA_SIZE_PROFILE_SETTINGS);
0069 }
0070 
0071 static int pyra_get_settings(struct usb_device *usb_dev,
0072         struct pyra_settings *buf)
0073 {
0074     return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
0075             buf, PYRA_SIZE_SETTINGS);
0076 }
0077 
0078 static int pyra_set_settings(struct usb_device *usb_dev,
0079         struct pyra_settings const *settings)
0080 {
0081     return roccat_common2_send_with_status(usb_dev,
0082             PYRA_COMMAND_SETTINGS, settings,
0083             PYRA_SIZE_SETTINGS);
0084 }
0085 
0086 static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj,
0087         char *buf, loff_t off, size_t count,
0088         size_t real_size, uint command)
0089 {
0090     struct device *dev = kobj_to_dev(kobj)->parent->parent;
0091     struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
0092     struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
0093     int retval;
0094 
0095     if (off >= real_size)
0096         return 0;
0097 
0098     if (off != 0 || count != real_size)
0099         return -EINVAL;
0100 
0101     mutex_lock(&pyra->pyra_lock);
0102     retval = roccat_common2_receive(usb_dev, command, buf, real_size);
0103     mutex_unlock(&pyra->pyra_lock);
0104 
0105     if (retval)
0106         return retval;
0107 
0108     return real_size;
0109 }
0110 
0111 static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj,
0112         void const *buf, loff_t off, size_t count,
0113         size_t real_size, uint command)
0114 {
0115     struct device *dev = kobj_to_dev(kobj)->parent->parent;
0116     struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
0117     struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
0118     int retval;
0119 
0120     if (off != 0 || count != real_size)
0121         return -EINVAL;
0122 
0123     mutex_lock(&pyra->pyra_lock);
0124     retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size);
0125     mutex_unlock(&pyra->pyra_lock);
0126 
0127     if (retval)
0128         return retval;
0129 
0130     return real_size;
0131 }
0132 
0133 #define PYRA_SYSFS_W(thingy, THINGY) \
0134 static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \
0135         struct kobject *kobj, struct bin_attribute *attr, char *buf, \
0136         loff_t off, size_t count) \
0137 { \
0138     return pyra_sysfs_write(fp, kobj, buf, off, count, \
0139             PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
0140 }
0141 
0142 #define PYRA_SYSFS_R(thingy, THINGY) \
0143 static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \
0144         struct kobject *kobj, struct bin_attribute *attr, char *buf, \
0145         loff_t off, size_t count) \
0146 { \
0147     return pyra_sysfs_read(fp, kobj, buf, off, count, \
0148             PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
0149 }
0150 
0151 #define PYRA_SYSFS_RW(thingy, THINGY) \
0152 PYRA_SYSFS_W(thingy, THINGY) \
0153 PYRA_SYSFS_R(thingy, THINGY)
0154 
0155 #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
0156 PYRA_SYSFS_RW(thingy, THINGY); \
0157 static struct bin_attribute bin_attr_##thingy = { \
0158     .attr = { .name = #thingy, .mode = 0660 }, \
0159     .size = PYRA_SIZE_ ## THINGY, \
0160     .read = pyra_sysfs_read_ ## thingy, \
0161     .write = pyra_sysfs_write_ ## thingy \
0162 }
0163 
0164 #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
0165 PYRA_SYSFS_R(thingy, THINGY); \
0166 static struct bin_attribute bin_attr_##thingy = { \
0167     .attr = { .name = #thingy, .mode = 0440 }, \
0168     .size = PYRA_SIZE_ ## THINGY, \
0169     .read = pyra_sysfs_read_ ## thingy, \
0170 }
0171 
0172 #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
0173 PYRA_SYSFS_W(thingy, THINGY); \
0174 static struct bin_attribute bin_attr_##thingy = { \
0175     .attr = { .name = #thingy, .mode = 0220 }, \
0176     .size = PYRA_SIZE_ ## THINGY, \
0177     .write = pyra_sysfs_write_ ## thingy \
0178 }
0179 
0180 PYRA_BIN_ATTRIBUTE_W(control, CONTROL);
0181 PYRA_BIN_ATTRIBUTE_RW(info, INFO);
0182 PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
0183 PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
0184 
0185 static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
0186         struct kobject *kobj, struct bin_attribute *attr, char *buf,
0187         loff_t off, size_t count)
0188 {
0189     struct device *dev = kobj_to_dev(kobj)->parent->parent;
0190     struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
0191     ssize_t retval;
0192 
0193     retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
0194             PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
0195     if (retval)
0196         return retval;
0197 
0198     return pyra_sysfs_read(fp, kobj, buf, off, count,
0199             PYRA_SIZE_PROFILE_SETTINGS,
0200             PYRA_COMMAND_PROFILE_SETTINGS);
0201 }
0202 
0203 static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
0204         struct kobject *kobj, struct bin_attribute *attr, char *buf,
0205         loff_t off, size_t count)
0206 {
0207     struct device *dev = kobj_to_dev(kobj)->parent->parent;
0208     struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
0209     ssize_t retval;
0210 
0211     retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
0212             PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
0213     if (retval)
0214         return retval;
0215 
0216     return pyra_sysfs_read(fp, kobj, buf, off, count,
0217             PYRA_SIZE_PROFILE_BUTTONS,
0218             PYRA_COMMAND_PROFILE_BUTTONS);
0219 }
0220 
0221 #define PROFILE_ATTR(number)                        \
0222 static struct bin_attribute bin_attr_profile##number##_settings = { \
0223     .attr = { .name = "profile" #number "_settings", .mode = 0440 },    \
0224     .size = PYRA_SIZE_PROFILE_SETTINGS,             \
0225     .read = pyra_sysfs_read_profilex_settings,          \
0226     .private = &profile_numbers[number-1],              \
0227 };                                  \
0228 static struct bin_attribute bin_attr_profile##number##_buttons = {  \
0229     .attr = { .name = "profile" #number "_buttons", .mode = 0440 }, \
0230     .size = PYRA_SIZE_PROFILE_BUTTONS,              \
0231     .read = pyra_sysfs_read_profilex_buttons,           \
0232     .private = &profile_numbers[number-1],              \
0233 };
0234 PROFILE_ATTR(1);
0235 PROFILE_ATTR(2);
0236 PROFILE_ATTR(3);
0237 PROFILE_ATTR(4);
0238 PROFILE_ATTR(5);
0239 
0240 static ssize_t pyra_sysfs_write_settings(struct file *fp,
0241         struct kobject *kobj, struct bin_attribute *attr, char *buf,
0242         loff_t off, size_t count)
0243 {
0244     struct device *dev = kobj_to_dev(kobj)->parent->parent;
0245     struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
0246     struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
0247     int retval = 0;
0248     struct pyra_roccat_report roccat_report;
0249     struct pyra_settings const *settings;
0250 
0251     if (off != 0 || count != PYRA_SIZE_SETTINGS)
0252         return -EINVAL;
0253 
0254     settings = (struct pyra_settings const *)buf;
0255     if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
0256         return -EINVAL;
0257 
0258     mutex_lock(&pyra->pyra_lock);
0259 
0260     retval = pyra_set_settings(usb_dev, settings);
0261     if (retval) {
0262         mutex_unlock(&pyra->pyra_lock);
0263         return retval;
0264     }
0265 
0266     profile_activated(pyra, settings->startup_profile);
0267 
0268     roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
0269     roccat_report.value = settings->startup_profile + 1;
0270     roccat_report.key = 0;
0271     roccat_report_event(pyra->chrdev_minor,
0272             (uint8_t const *)&roccat_report);
0273 
0274     mutex_unlock(&pyra->pyra_lock);
0275     return PYRA_SIZE_SETTINGS;
0276 }
0277 
0278 PYRA_SYSFS_R(settings, SETTINGS);
0279 static struct bin_attribute bin_attr_settings =
0280     __BIN_ATTR(settings, (S_IWUSR | S_IRUGO),
0281            pyra_sysfs_read_settings, pyra_sysfs_write_settings,
0282            PYRA_SIZE_SETTINGS);
0283 
0284 static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
0285         struct device_attribute *attr, char *buf)
0286 {
0287     struct pyra_device *pyra =
0288             hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
0289     return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
0290 }
0291 static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
0292 
0293 static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
0294         struct device_attribute *attr, char *buf)
0295 {
0296     struct pyra_device *pyra =
0297             hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
0298     struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
0299     struct pyra_settings settings;
0300 
0301     mutex_lock(&pyra->pyra_lock);
0302     roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
0303             &settings, PYRA_SIZE_SETTINGS);
0304     mutex_unlock(&pyra->pyra_lock);
0305 
0306     return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile);
0307 }
0308 static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
0309 static DEVICE_ATTR(startup_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
0310 
0311 static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
0312         struct device_attribute *attr, char *buf)
0313 {
0314     struct pyra_device *pyra;
0315     struct usb_device *usb_dev;
0316     struct pyra_info info;
0317 
0318     dev = dev->parent->parent;
0319     pyra = hid_get_drvdata(dev_get_drvdata(dev));
0320     usb_dev = interface_to_usbdev(to_usb_interface(dev));
0321 
0322     mutex_lock(&pyra->pyra_lock);
0323     roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
0324             &info, PYRA_SIZE_INFO);
0325     mutex_unlock(&pyra->pyra_lock);
0326 
0327     return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
0328 }
0329 static DEVICE_ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version,
0330            NULL);
0331 
0332 static struct attribute *pyra_attrs[] = {
0333     &dev_attr_actual_cpi.attr,
0334     &dev_attr_actual_profile.attr,
0335     &dev_attr_firmware_version.attr,
0336     &dev_attr_startup_profile.attr,
0337     NULL,
0338 };
0339 
0340 static struct bin_attribute *pyra_bin_attributes[] = {
0341     &bin_attr_control,
0342     &bin_attr_info,
0343     &bin_attr_profile_settings,
0344     &bin_attr_profile_buttons,
0345     &bin_attr_settings,
0346     &bin_attr_profile1_settings,
0347     &bin_attr_profile2_settings,
0348     &bin_attr_profile3_settings,
0349     &bin_attr_profile4_settings,
0350     &bin_attr_profile5_settings,
0351     &bin_attr_profile1_buttons,
0352     &bin_attr_profile2_buttons,
0353     &bin_attr_profile3_buttons,
0354     &bin_attr_profile4_buttons,
0355     &bin_attr_profile5_buttons,
0356     NULL,
0357 };
0358 
0359 static const struct attribute_group pyra_group = {
0360     .attrs = pyra_attrs,
0361     .bin_attrs = pyra_bin_attributes,
0362 };
0363 
0364 static const struct attribute_group *pyra_groups[] = {
0365     &pyra_group,
0366     NULL,
0367 };
0368 
0369 static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
0370         struct pyra_device *pyra)
0371 {
0372     struct pyra_settings settings;
0373     int retval, i;
0374 
0375     mutex_init(&pyra->pyra_lock);
0376 
0377     retval = pyra_get_settings(usb_dev, &settings);
0378     if (retval)
0379         return retval;
0380 
0381     for (i = 0; i < 5; ++i) {
0382         retval = pyra_get_profile_settings(usb_dev,
0383                 &pyra->profile_settings[i], i);
0384         if (retval)
0385             return retval;
0386     }
0387 
0388     profile_activated(pyra, settings.startup_profile);
0389 
0390     return 0;
0391 }
0392 
0393 static int pyra_init_specials(struct hid_device *hdev)
0394 {
0395     struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
0396     struct usb_device *usb_dev = interface_to_usbdev(intf);
0397     struct pyra_device *pyra;
0398     int retval;
0399 
0400     if (intf->cur_altsetting->desc.bInterfaceProtocol
0401             == USB_INTERFACE_PROTOCOL_MOUSE) {
0402 
0403         pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
0404         if (!pyra) {
0405             hid_err(hdev, "can't alloc device descriptor\n");
0406             return -ENOMEM;
0407         }
0408         hid_set_drvdata(hdev, pyra);
0409 
0410         retval = pyra_init_pyra_device_struct(usb_dev, pyra);
0411         if (retval) {
0412             hid_err(hdev, "couldn't init struct pyra_device\n");
0413             goto exit_free;
0414         }
0415 
0416         retval = roccat_connect(pyra_class, hdev,
0417                 sizeof(struct pyra_roccat_report));
0418         if (retval < 0) {
0419             hid_err(hdev, "couldn't init char dev\n");
0420         } else {
0421             pyra->chrdev_minor = retval;
0422             pyra->roccat_claimed = 1;
0423         }
0424     } else {
0425         hid_set_drvdata(hdev, NULL);
0426     }
0427 
0428     return 0;
0429 exit_free:
0430     kfree(pyra);
0431     return retval;
0432 }
0433 
0434 static void pyra_remove_specials(struct hid_device *hdev)
0435 {
0436     struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
0437     struct pyra_device *pyra;
0438 
0439     if (intf->cur_altsetting->desc.bInterfaceProtocol
0440             == USB_INTERFACE_PROTOCOL_MOUSE) {
0441         pyra = hid_get_drvdata(hdev);
0442         if (pyra->roccat_claimed)
0443             roccat_disconnect(pyra->chrdev_minor);
0444         kfree(hid_get_drvdata(hdev));
0445     }
0446 }
0447 
0448 static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
0449 {
0450     int retval;
0451 
0452     if (!hid_is_usb(hdev))
0453         return -EINVAL;
0454 
0455     retval = hid_parse(hdev);
0456     if (retval) {
0457         hid_err(hdev, "parse failed\n");
0458         goto exit;
0459     }
0460 
0461     retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
0462     if (retval) {
0463         hid_err(hdev, "hw start failed\n");
0464         goto exit;
0465     }
0466 
0467     retval = pyra_init_specials(hdev);
0468     if (retval) {
0469         hid_err(hdev, "couldn't install mouse\n");
0470         goto exit_stop;
0471     }
0472     return 0;
0473 
0474 exit_stop:
0475     hid_hw_stop(hdev);
0476 exit:
0477     return retval;
0478 }
0479 
0480 static void pyra_remove(struct hid_device *hdev)
0481 {
0482     pyra_remove_specials(hdev);
0483     hid_hw_stop(hdev);
0484 }
0485 
0486 static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
0487         u8 const *data)
0488 {
0489     struct pyra_mouse_event_button const *button_event;
0490 
0491     switch (data[0]) {
0492     case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
0493         button_event = (struct pyra_mouse_event_button const *)data;
0494         switch (button_event->type) {
0495         case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
0496             profile_activated(pyra, button_event->data1 - 1);
0497             break;
0498         case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
0499             pyra->actual_cpi = button_event->data1;
0500             break;
0501         }
0502         break;
0503     }
0504 }
0505 
0506 static void pyra_report_to_chrdev(struct pyra_device const *pyra,
0507         u8 const *data)
0508 {
0509     struct pyra_roccat_report roccat_report;
0510     struct pyra_mouse_event_button const *button_event;
0511 
0512     if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
0513         return;
0514 
0515     button_event = (struct pyra_mouse_event_button const *)data;
0516 
0517     switch (button_event->type) {
0518     case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
0519     case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
0520         roccat_report.type = button_event->type;
0521         roccat_report.value = button_event->data1;
0522         roccat_report.key = 0;
0523         roccat_report_event(pyra->chrdev_minor,
0524                 (uint8_t const *)&roccat_report);
0525         break;
0526     case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
0527     case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
0528     case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
0529         if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
0530             roccat_report.type = button_event->type;
0531             roccat_report.key = button_event->data1;
0532             /*
0533              * pyra reports profile numbers with range 1-5.
0534              * Keeping this behaviour.
0535              */
0536             roccat_report.value = pyra->actual_profile + 1;
0537             roccat_report_event(pyra->chrdev_minor,
0538                     (uint8_t const *)&roccat_report);
0539         }
0540         break;
0541     }
0542 }
0543 
0544 static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
0545         u8 *data, int size)
0546 {
0547     struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
0548     struct pyra_device *pyra = hid_get_drvdata(hdev);
0549 
0550     if (intf->cur_altsetting->desc.bInterfaceProtocol
0551             != USB_INTERFACE_PROTOCOL_MOUSE)
0552         return 0;
0553 
0554     if (pyra == NULL)
0555         return 0;
0556 
0557     pyra_keep_values_up_to_date(pyra, data);
0558 
0559     if (pyra->roccat_claimed)
0560         pyra_report_to_chrdev(pyra, data);
0561 
0562     return 0;
0563 }
0564 
0565 static const struct hid_device_id pyra_devices[] = {
0566     { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
0567             USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
0568     { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
0569             USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
0570     { }
0571 };
0572 
0573 MODULE_DEVICE_TABLE(hid, pyra_devices);
0574 
0575 static struct hid_driver pyra_driver = {
0576         .name = "pyra",
0577         .id_table = pyra_devices,
0578         .probe = pyra_probe,
0579         .remove = pyra_remove,
0580         .raw_event = pyra_raw_event
0581 };
0582 
0583 static int __init pyra_init(void)
0584 {
0585     int retval;
0586 
0587     /* class name has to be same as driver name */
0588     pyra_class = class_create(THIS_MODULE, "pyra");
0589     if (IS_ERR(pyra_class))
0590         return PTR_ERR(pyra_class);
0591     pyra_class->dev_groups = pyra_groups;
0592 
0593     retval = hid_register_driver(&pyra_driver);
0594     if (retval)
0595         class_destroy(pyra_class);
0596     return retval;
0597 }
0598 
0599 static void __exit pyra_exit(void)
0600 {
0601     hid_unregister_driver(&pyra_driver);
0602     class_destroy(pyra_class);
0603 }
0604 
0605 module_init(pyra_init);
0606 module_exit(pyra_exit);
0607 
0608 MODULE_AUTHOR("Stefan Achatz");
0609 MODULE_DESCRIPTION("USB Roccat Pyra driver");
0610 MODULE_LICENSE("GPL v2");