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