linux/drivers/hid/hid-roccat-kone.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Roccat Kone driver for Linux
   4 *
   5 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
   6 */
   7
   8/*
   9 */
  10
  11/*
  12 * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard
  13 * part. The keyboard part enables the mouse to execute stored macros with mixed
  14 * key- and button-events.
  15 *
  16 * TODO implement on-the-fly polling-rate change
  17 *      The windows driver has the ability to change the polling rate of the
  18 *      device on the press of a mousebutton.
  19 *      Is it possible to remove and reinstall the urb in raw-event- or any
  20 *      other handler, or to defer this action to be executed somewhere else?
  21 *
  22 * TODO is it possible to overwrite group for sysfs attributes via udev?
  23 */
  24
  25#include <linux/device.h>
  26#include <linux/input.h>
  27#include <linux/hid.h>
  28#include <linux/module.h>
  29#include <linux/slab.h>
  30#include <linux/hid-roccat.h>
  31#include "hid-ids.h"
  32#include "hid-roccat-common.h"
  33#include "hid-roccat-kone.h"
  34
  35static uint profile_numbers[5] = {0, 1, 2, 3, 4};
  36
  37static void kone_profile_activated(struct kone_device *kone, uint new_profile)
  38{
  39        kone->actual_profile = new_profile;
  40        kone->actual_dpi = kone->profiles[new_profile - 1].startup_dpi;
  41}
  42
  43static void kone_profile_report(struct kone_device *kone, uint new_profile)
  44{
  45        struct kone_roccat_report roccat_report;
  46
  47        roccat_report.event = kone_mouse_event_switch_profile;
  48        roccat_report.value = new_profile;
  49        roccat_report.key = 0;
  50        roccat_report_event(kone->chrdev_minor, (uint8_t *)&roccat_report);
  51}
  52
  53static int kone_receive(struct usb_device *usb_dev, uint usb_command,
  54                void *data, uint size)
  55{
  56        char *buf;
  57        int len;
  58
  59        buf = kmalloc(size, GFP_KERNEL);
  60        if (buf == NULL)
  61                return -ENOMEM;
  62
  63        len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
  64                        HID_REQ_GET_REPORT,
  65                        USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
  66                        usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
  67
  68        memcpy(data, buf, size);
  69        kfree(buf);
  70        return ((len < 0) ? len : ((len != size) ? -EIO : 0));
  71}
  72
  73static int kone_send(struct usb_device *usb_dev, uint usb_command,
  74                void const *data, uint size)
  75{
  76        char *buf;
  77        int len;
  78
  79        buf = kmemdup(data, size, GFP_KERNEL);
  80        if (buf == NULL)
  81                return -ENOMEM;
  82
  83        len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
  84                        HID_REQ_SET_REPORT,
  85                        USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
  86                        usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
  87
  88        kfree(buf);
  89        return ((len < 0) ? len : ((len != size) ? -EIO : 0));
  90}
  91
  92/* kone_class is used for creating sysfs attributes via roccat char device */
  93static struct class *kone_class;
  94
  95static void kone_set_settings_checksum(struct kone_settings *settings)
  96{
  97        uint16_t checksum = 0;
  98        unsigned char *address = (unsigned char *)settings;
  99        int i;
 100
 101        for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address)
 102                checksum += *address;
 103        settings->checksum = cpu_to_le16(checksum);
 104}
 105
 106/*
 107 * Checks success after writing data to mouse
 108 * On success returns 0
 109 * On failure returns errno
 110 */
 111static int kone_check_write(struct usb_device *usb_dev)
 112{
 113        int retval;
 114        uint8_t data;
 115
 116        do {
 117                /*
 118                 * Mouse needs 50 msecs until it says ok, but there are
 119                 * 30 more msecs needed for next write to work.
 120                 */
 121                msleep(80);
 122
 123                retval = kone_receive(usb_dev,
 124                                kone_command_confirm_write, &data, 1);
 125                if (retval)
 126                        return retval;
 127
 128                /*
 129                 * value of 3 seems to mean something like
 130                 * "not finished yet, but it looks good"
 131                 * So check again after a moment.
 132                 */
 133        } while (data == 3);
 134
 135        if (data == 1) /* everything alright */
 136                return 0;
 137
 138        /* unknown answer */
 139        dev_err(&usb_dev->dev, "got retval %d when checking write\n", data);
 140        return -EIO;
 141}
 142
 143/*
 144 * Reads settings from mouse and stores it in @buf
 145 * On success returns 0
 146 * On failure returns errno
 147 */
 148static int kone_get_settings(struct usb_device *usb_dev,
 149                struct kone_settings *buf)
 150{
 151        return kone_receive(usb_dev, kone_command_settings, buf,
 152                        sizeof(struct kone_settings));
 153}
 154
 155/*
 156 * Writes settings from @buf to mouse
 157 * On success returns 0
 158 * On failure returns errno
 159 */
 160static int kone_set_settings(struct usb_device *usb_dev,
 161                struct kone_settings const *settings)
 162{
 163        int retval;
 164
 165        retval = kone_send(usb_dev, kone_command_settings,
 166                        settings, sizeof(struct kone_settings));
 167        if (retval)
 168                return retval;
 169        return kone_check_write(usb_dev);
 170}
 171
 172/*
 173 * Reads profile data from mouse and stores it in @buf
 174 * @number: profile number to read
 175 * On success returns 0
 176 * On failure returns errno
 177 */
 178static int kone_get_profile(struct usb_device *usb_dev,
 179                struct kone_profile *buf, int number)
 180{
 181        int len;
 182
 183        if (number < 1 || number > 5)
 184                return -EINVAL;
 185
 186        len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
 187                        USB_REQ_CLEAR_FEATURE,
 188                        USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 189                        kone_command_profile, number, buf,
 190                        sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT);
 191
 192        if (len != sizeof(struct kone_profile))
 193                return -EIO;
 194
 195        return 0;
 196}
 197
 198/*
 199 * Writes profile data to mouse.
 200 * @number: profile number to write
 201 * On success returns 0
 202 * On failure returns errno
 203 */
 204static int kone_set_profile(struct usb_device *usb_dev,
 205                struct kone_profile const *profile, int number)
 206{
 207        int len;
 208
 209        if (number < 1 || number > 5)
 210                return -EINVAL;
 211
 212        len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
 213                        USB_REQ_SET_CONFIGURATION,
 214                        USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
 215                        kone_command_profile, number, (void *)profile,
 216                        sizeof(struct kone_profile),
 217                        USB_CTRL_SET_TIMEOUT);
 218
 219        if (len != sizeof(struct kone_profile))
 220                return len;
 221
 222        if (kone_check_write(usb_dev))
 223                return -EIO;
 224
 225        return 0;
 226}
 227
 228/*
 229 * Reads value of "fast-clip-weight" and stores it in @result
 230 * On success returns 0
 231 * On failure returns errno
 232 */
 233static int kone_get_weight(struct usb_device *usb_dev, int *result)
 234{
 235        int retval;
 236        uint8_t data;
 237
 238        retval = kone_receive(usb_dev, kone_command_weight, &data, 1);
 239
 240        if (retval)
 241                return retval;
 242
 243        *result = (int)data;
 244        return 0;
 245}
 246
 247/*
 248 * Reads firmware_version of mouse and stores it in @result
 249 * On success returns 0
 250 * On failure returns errno
 251 */
 252static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
 253{
 254        int retval;
 255        uint16_t data;
 256
 257        retval = kone_receive(usb_dev, kone_command_firmware_version,
 258                        &data, 2);
 259        if (retval)
 260                return retval;
 261
 262        *result = le16_to_cpu(data);
 263        return 0;
 264}
 265
 266static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
 267                struct bin_attribute *attr, char *buf,
 268                loff_t off, size_t count) {
 269        struct device *dev = kobj_to_dev(kobj)->parent->parent;
 270        struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
 271
 272        if (off >= sizeof(struct kone_settings))
 273                return 0;
 274
 275        if (off + count > sizeof(struct kone_settings))
 276                count = sizeof(struct kone_settings) - off;
 277
 278        mutex_lock(&kone->kone_lock);
 279        memcpy(buf, ((char const *)&kone->settings) + off, count);
 280        mutex_unlock(&kone->kone_lock);
 281
 282        return count;
 283}
 284
 285/*
 286 * Writing settings automatically activates startup_profile.
 287 * This function keeps values in kone_device up to date and assumes that in
 288 * case of error the old data is still valid
 289 */
 290static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
 291                struct bin_attribute *attr, char *buf,
 292                loff_t off, size_t count) {
 293        struct device *dev = kobj_to_dev(kobj)->parent->parent;
 294        struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
 295        struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
 296        int retval = 0, difference, old_profile;
 297        struct kone_settings *settings = (struct kone_settings *)buf;
 298
 299        /* I need to get my data in one piece */
 300        if (off != 0 || count != sizeof(struct kone_settings))
 301                return -EINVAL;
 302
 303        mutex_lock(&kone->kone_lock);
 304        difference = memcmp(settings, &kone->settings,
 305                            sizeof(struct kone_settings));
 306        if (difference) {
 307                if (settings->startup_profile < 1 ||
 308                    settings->startup_profile > 5) {
 309                        retval = -EINVAL;
 310                        goto unlock;
 311                }
 312
 313                retval = kone_set_settings(usb_dev, settings);
 314                if (retval)
 315                        goto unlock;
 316
 317                old_profile = kone->settings.startup_profile;
 318                memcpy(&kone->settings, settings, sizeof(struct kone_settings));
 319
 320                kone_profile_activated(kone, kone->settings.startup_profile);
 321
 322                if (kone->settings.startup_profile != old_profile)
 323                        kone_profile_report(kone, kone->settings.startup_profile);
 324        }
 325unlock:
 326        mutex_unlock(&kone->kone_lock);
 327
 328        if (retval)
 329                return retval;
 330
 331        return sizeof(struct kone_settings);
 332}
 333static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
 334                kone_sysfs_write_settings, sizeof(struct kone_settings));
 335
 336static ssize_t kone_sysfs_read_profilex(struct file *fp,
 337                struct kobject *kobj, struct bin_attribute *attr,
 338                char *buf, loff_t off, size_t count) {
 339        struct device *dev = kobj_to_dev(kobj)->parent->parent;
 340        struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
 341
 342        if (off >= sizeof(struct kone_profile))
 343                return 0;
 344
 345        if (off + count > sizeof(struct kone_profile))
 346                count = sizeof(struct kone_profile) - off;
 347
 348        mutex_lock(&kone->kone_lock);
 349        memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
 350        mutex_unlock(&kone->kone_lock);
 351
 352        return count;
 353}
 354
 355/* Writes data only if different to stored data */
 356static ssize_t kone_sysfs_write_profilex(struct file *fp,
 357                struct kobject *kobj, struct bin_attribute *attr,
 358                char *buf, loff_t off, size_t count) {
 359        struct device *dev = kobj_to_dev(kobj)->parent->parent;
 360        struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
 361        struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
 362        struct kone_profile *profile;
 363        int retval = 0, difference;
 364
 365        /* I need to get my data in one piece */
 366        if (off != 0 || count != sizeof(struct kone_profile))
 367                return -EINVAL;
 368
 369        profile = &kone->profiles[*(uint *)(attr->private)];
 370
 371        mutex_lock(&kone->kone_lock);
 372        difference = memcmp(buf, profile, sizeof(struct kone_profile));
 373        if (difference) {
 374                retval = kone_set_profile(usb_dev,
 375                                (struct kone_profile const *)buf,
 376                                *(uint *)(attr->private) + 1);
 377                if (!retval)
 378                        memcpy(profile, buf, sizeof(struct kone_profile));
 379        }
 380        mutex_unlock(&kone->kone_lock);
 381
 382        if (retval)
 383                return retval;
 384
 385        return sizeof(struct kone_profile);
 386}
 387#define PROFILE_ATTR(number)                                    \
 388static struct bin_attribute bin_attr_profile##number = {        \
 389        .attr = { .name = "profile" #number, .mode = 0660 },    \
 390        .size = sizeof(struct kone_profile),                    \
 391        .read = kone_sysfs_read_profilex,                       \
 392        .write = kone_sysfs_write_profilex,                     \
 393        .private = &profile_numbers[number-1],                  \
 394}
 395PROFILE_ATTR(1);
 396PROFILE_ATTR(2);
 397PROFILE_ATTR(3);
 398PROFILE_ATTR(4);
 399PROFILE_ATTR(5);
 400
 401static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
 402                struct device_attribute *attr, char *buf)
 403{
 404        struct kone_device *kone =
 405                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 406        return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
 407}
 408static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
 409
 410static ssize_t kone_sysfs_show_actual_dpi(struct device *dev,
 411                struct device_attribute *attr, char *buf)
 412{
 413        struct kone_device *kone =
 414                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 415        return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi);
 416}
 417static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
 418
 419/* weight is read each time, since we don't get informed when it's changed */
 420static ssize_t kone_sysfs_show_weight(struct device *dev,
 421                struct device_attribute *attr, char *buf)
 422{
 423        struct kone_device *kone;
 424        struct usb_device *usb_dev;
 425        int weight = 0;
 426        int retval;
 427
 428        dev = dev->parent->parent;
 429        kone = hid_get_drvdata(dev_get_drvdata(dev));
 430        usb_dev = interface_to_usbdev(to_usb_interface(dev));
 431
 432        mutex_lock(&kone->kone_lock);
 433        retval = kone_get_weight(usb_dev, &weight);
 434        mutex_unlock(&kone->kone_lock);
 435
 436        if (retval)
 437                return retval;
 438        return snprintf(buf, PAGE_SIZE, "%d\n", weight);
 439}
 440static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
 441
 442static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
 443                struct device_attribute *attr, char *buf)
 444{
 445        struct kone_device *kone =
 446                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 447        return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
 448}
 449static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
 450                   NULL);
 451
 452static ssize_t kone_sysfs_show_tcu(struct device *dev,
 453                struct device_attribute *attr, char *buf)
 454{
 455        struct kone_device *kone =
 456                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 457        return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
 458}
 459
 460static int kone_tcu_command(struct usb_device *usb_dev, int number)
 461{
 462        unsigned char value;
 463
 464        value = number;
 465        return kone_send(usb_dev, kone_command_calibrate, &value, 1);
 466}
 467
 468/*
 469 * Calibrating the tcu is the only action that changes settings data inside the
 470 * mouse, so this data needs to be reread
 471 */
 472static ssize_t kone_sysfs_set_tcu(struct device *dev,
 473                struct device_attribute *attr, char const *buf, size_t size)
 474{
 475        struct kone_device *kone;
 476        struct usb_device *usb_dev;
 477        int retval;
 478        unsigned long state;
 479
 480        dev = dev->parent->parent;
 481        kone = hid_get_drvdata(dev_get_drvdata(dev));
 482        usb_dev = interface_to_usbdev(to_usb_interface(dev));
 483
 484        retval = kstrtoul(buf, 10, &state);
 485        if (retval)
 486                return retval;
 487
 488        if (state != 0 && state != 1)
 489                return -EINVAL;
 490
 491        mutex_lock(&kone->kone_lock);
 492
 493        if (state == 1) { /* state activate */
 494                retval = kone_tcu_command(usb_dev, 1);
 495                if (retval)
 496                        goto exit_unlock;
 497                retval = kone_tcu_command(usb_dev, 2);
 498                if (retval)
 499                        goto exit_unlock;
 500                ssleep(5); /* tcu needs this time for calibration */
 501                retval = kone_tcu_command(usb_dev, 3);
 502                if (retval)
 503                        goto exit_unlock;
 504                retval = kone_tcu_command(usb_dev, 0);
 505                if (retval)
 506                        goto exit_unlock;
 507                retval = kone_tcu_command(usb_dev, 4);
 508                if (retval)
 509                        goto exit_unlock;
 510                /*
 511                 * Kone needs this time to settle things.
 512                 * Reading settings too early will result in invalid data.
 513                 * Roccat's driver waits 1 sec, maybe this time could be
 514                 * shortened.
 515                 */
 516                ssleep(1);
 517        }
 518
 519        /* calibration changes values in settings, so reread */
 520        retval = kone_get_settings(usb_dev, &kone->settings);
 521        if (retval)
 522                goto exit_no_settings;
 523
 524        /* only write settings back if activation state is different */
 525        if (kone->settings.tcu != state) {
 526                kone->settings.tcu = state;
 527                kone_set_settings_checksum(&kone->settings);
 528
 529                retval = kone_set_settings(usb_dev, &kone->settings);
 530                if (retval) {
 531                        dev_err(&usb_dev->dev, "couldn't set tcu state\n");
 532                        /*
 533                         * try to reread valid settings into buffer overwriting
 534                         * first error code
 535                         */
 536                        retval = kone_get_settings(usb_dev, &kone->settings);
 537                        if (retval)
 538                                goto exit_no_settings;
 539                        goto exit_unlock;
 540                }
 541                /* calibration resets profile */
 542                kone_profile_activated(kone, kone->settings.startup_profile);
 543        }
 544
 545        retval = size;
 546exit_no_settings:
 547        dev_err(&usb_dev->dev, "couldn't read settings\n");
 548exit_unlock:
 549        mutex_unlock(&kone->kone_lock);
 550        return retval;
 551}
 552static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
 553
 554static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
 555                struct device_attribute *attr, char *buf)
 556{
 557        struct kone_device *kone =
 558                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 559        return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
 560}
 561
 562static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
 563                struct device_attribute *attr, char const *buf, size_t size)
 564{
 565        struct kone_device *kone;
 566        struct usb_device *usb_dev;
 567        int retval;
 568        unsigned long new_startup_profile;
 569
 570        dev = dev->parent->parent;
 571        kone = hid_get_drvdata(dev_get_drvdata(dev));
 572        usb_dev = interface_to_usbdev(to_usb_interface(dev));
 573
 574        retval = kstrtoul(buf, 10, &new_startup_profile);
 575        if (retval)
 576                return retval;
 577
 578        if (new_startup_profile  < 1 || new_startup_profile > 5)
 579                return -EINVAL;
 580
 581        mutex_lock(&kone->kone_lock);
 582
 583        kone->settings.startup_profile = new_startup_profile;
 584        kone_set_settings_checksum(&kone->settings);
 585
 586        retval = kone_set_settings(usb_dev, &kone->settings);
 587        if (retval) {
 588                mutex_unlock(&kone->kone_lock);
 589                return retval;
 590        }
 591
 592        /* changing the startup profile immediately activates this profile */
 593        kone_profile_activated(kone, new_startup_profile);
 594        kone_profile_report(kone, new_startup_profile);
 595
 596        mutex_unlock(&kone->kone_lock);
 597        return size;
 598}
 599static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
 600                   kone_sysfs_set_startup_profile);
 601
 602static struct attribute *kone_attrs[] = {
 603        /*
 604         * Read actual dpi settings.
 605         * Returns raw value for further processing. Refer to enum
 606         * kone_polling_rates to get real value.
 607         */
 608        &dev_attr_actual_dpi.attr,
 609        &dev_attr_actual_profile.attr,
 610
 611        /*
 612         * The mouse can be equipped with one of four supplied weights from 5
 613         * to 20 grams which are recognized and its value can be read out.
 614         * This returns the raw value reported by the mouse for easy evaluation
 615         * by software. Refer to enum kone_weights to get corresponding real
 616         * weight.
 617         */
 618        &dev_attr_weight.attr,
 619
 620        /*
 621         * Prints firmware version stored in mouse as integer.
 622         * The raw value reported by the mouse is returned for easy evaluation,
 623         * to get the real version number the decimal point has to be shifted 2
 624         * positions to the left. E.g. a value of 138 means 1.38.
 625         */
 626        &dev_attr_firmware_version.attr,
 627
 628        /*
 629         * Prints state of Tracking Control Unit as number where 0 = off and
 630         * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
 631         * activates the tcu
 632         */
 633        &dev_attr_tcu.attr,
 634
 635        /* Prints and takes the number of the profile the mouse starts with */
 636        &dev_attr_startup_profile.attr,
 637        NULL,
 638};
 639
 640static struct bin_attribute *kone_bin_attributes[] = {
 641        &bin_attr_settings,
 642        &bin_attr_profile1,
 643        &bin_attr_profile2,
 644        &bin_attr_profile3,
 645        &bin_attr_profile4,
 646        &bin_attr_profile5,
 647        NULL,
 648};
 649
 650static const struct attribute_group kone_group = {
 651        .attrs = kone_attrs,
 652        .bin_attrs = kone_bin_attributes,
 653};
 654
 655static const struct attribute_group *kone_groups[] = {
 656        &kone_group,
 657        NULL,
 658};
 659
 660static int kone_init_kone_device_struct(struct usb_device *usb_dev,
 661                struct kone_device *kone)
 662{
 663        uint i;
 664        int retval;
 665
 666        mutex_init(&kone->kone_lock);
 667
 668        for (i = 0; i < 5; ++i) {
 669                retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
 670                if (retval)
 671                        return retval;
 672        }
 673
 674        retval = kone_get_settings(usb_dev, &kone->settings);
 675        if (retval)
 676                return retval;
 677
 678        retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
 679        if (retval)
 680                return retval;
 681
 682        kone_profile_activated(kone, kone->settings.startup_profile);
 683
 684        return 0;
 685}
 686
 687/*
 688 * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
 689 * mousepart if usb_hid is compiled into the kernel and kone is compiled as
 690 * module.
 691 * Secial behaviour is bound only to mousepart since only mouseevents contain
 692 * additional notifications.
 693 */
 694static int kone_init_specials(struct hid_device *hdev)
 695{
 696        struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 697        struct usb_device *usb_dev = interface_to_usbdev(intf);
 698        struct kone_device *kone;
 699        int retval;
 700
 701        if (intf->cur_altsetting->desc.bInterfaceProtocol
 702                        == USB_INTERFACE_PROTOCOL_MOUSE) {
 703
 704                kone = kzalloc(sizeof(*kone), GFP_KERNEL);
 705                if (!kone)
 706                        return -ENOMEM;
 707                hid_set_drvdata(hdev, kone);
 708
 709                retval = kone_init_kone_device_struct(usb_dev, kone);
 710                if (retval) {
 711                        hid_err(hdev, "couldn't init struct kone_device\n");
 712                        goto exit_free;
 713                }
 714
 715                retval = roccat_connect(kone_class, hdev,
 716                                sizeof(struct kone_roccat_report));
 717                if (retval < 0) {
 718                        hid_err(hdev, "couldn't init char dev\n");
 719                        /* be tolerant about not getting chrdev */
 720                } else {
 721                        kone->roccat_claimed = 1;
 722                        kone->chrdev_minor = retval;
 723                }
 724        } else {
 725                hid_set_drvdata(hdev, NULL);
 726        }
 727
 728        return 0;
 729exit_free:
 730        kfree(kone);
 731        return retval;
 732}
 733
 734static void kone_remove_specials(struct hid_device *hdev)
 735{
 736        struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 737        struct kone_device *kone;
 738
 739        if (intf->cur_altsetting->desc.bInterfaceProtocol
 740                        == USB_INTERFACE_PROTOCOL_MOUSE) {
 741                kone = hid_get_drvdata(hdev);
 742                if (kone->roccat_claimed)
 743                        roccat_disconnect(kone->chrdev_minor);
 744                kfree(hid_get_drvdata(hdev));
 745        }
 746}
 747
 748static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
 749{
 750        int retval;
 751
 752        retval = hid_parse(hdev);
 753        if (retval) {
 754                hid_err(hdev, "parse failed\n");
 755                goto exit;
 756        }
 757
 758        retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 759        if (retval) {
 760                hid_err(hdev, "hw start failed\n");
 761                goto exit;
 762        }
 763
 764        retval = kone_init_specials(hdev);
 765        if (retval) {
 766                hid_err(hdev, "couldn't install mouse\n");
 767                goto exit_stop;
 768        }
 769
 770        return 0;
 771
 772exit_stop:
 773        hid_hw_stop(hdev);
 774exit:
 775        return retval;
 776}
 777
 778static void kone_remove(struct hid_device *hdev)
 779{
 780        kone_remove_specials(hdev);
 781        hid_hw_stop(hdev);
 782}
 783
 784/* handle special events and keep actual profile and dpi values up to date */
 785static void kone_keep_values_up_to_date(struct kone_device *kone,
 786                struct kone_mouse_event const *event)
 787{
 788        switch (event->event) {
 789        case kone_mouse_event_switch_profile:
 790                kone->actual_dpi = kone->profiles[event->value - 1].
 791                                startup_dpi;
 792                fallthrough;
 793        case kone_mouse_event_osd_profile:
 794                kone->actual_profile = event->value;
 795                break;
 796        case kone_mouse_event_switch_dpi:
 797        case kone_mouse_event_osd_dpi:
 798                kone->actual_dpi = event->value;
 799                break;
 800        }
 801}
 802
 803static void kone_report_to_chrdev(struct kone_device const *kone,
 804                struct kone_mouse_event const *event)
 805{
 806        struct kone_roccat_report roccat_report;
 807
 808        switch (event->event) {
 809        case kone_mouse_event_switch_profile:
 810        case kone_mouse_event_switch_dpi:
 811        case kone_mouse_event_osd_profile:
 812        case kone_mouse_event_osd_dpi:
 813                roccat_report.event = event->event;
 814                roccat_report.value = event->value;
 815                roccat_report.key = 0;
 816                roccat_report_event(kone->chrdev_minor,
 817                                (uint8_t *)&roccat_report);
 818                break;
 819        case kone_mouse_event_call_overlong_macro:
 820        case kone_mouse_event_multimedia:
 821                if (event->value == kone_keystroke_action_press) {
 822                        roccat_report.event = event->event;
 823                        roccat_report.value = kone->actual_profile;
 824                        roccat_report.key = event->macro_key;
 825                        roccat_report_event(kone->chrdev_minor,
 826                                        (uint8_t *)&roccat_report);
 827                }
 828                break;
 829        }
 830
 831}
 832
 833/*
 834 * Is called for keyboard- and mousepart.
 835 * Only mousepart gets informations about special events in its extended event
 836 * structure.
 837 */
 838static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
 839                u8 *data, int size)
 840{
 841        struct kone_device *kone = hid_get_drvdata(hdev);
 842        struct kone_mouse_event *event = (struct kone_mouse_event *)data;
 843
 844        /* keyboard events are always processed by default handler */
 845        if (size != sizeof(struct kone_mouse_event))
 846                return 0;
 847
 848        if (kone == NULL)
 849                return 0;
 850
 851        /*
 852         * Firmware 1.38 introduced new behaviour for tilt and special buttons.
 853         * Pressed button is reported in each movement event.
 854         * Workaround sends only one event per press.
 855         */
 856        if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
 857                memcpy(&kone->last_mouse_event, event,
 858                                sizeof(struct kone_mouse_event));
 859        else
 860                memset(&event->tilt, 0, 5);
 861
 862        kone_keep_values_up_to_date(kone, event);
 863
 864        if (kone->roccat_claimed)
 865                kone_report_to_chrdev(kone, event);
 866
 867        return 0; /* always do further processing */
 868}
 869
 870static const struct hid_device_id kone_devices[] = {
 871        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
 872        { }
 873};
 874
 875MODULE_DEVICE_TABLE(hid, kone_devices);
 876
 877static struct hid_driver kone_driver = {
 878                .name = "kone",
 879                .id_table = kone_devices,
 880                .probe = kone_probe,
 881                .remove = kone_remove,
 882                .raw_event = kone_raw_event
 883};
 884
 885static int __init kone_init(void)
 886{
 887        int retval;
 888
 889        /* class name has to be same as driver name */
 890        kone_class = class_create(THIS_MODULE, "kone");
 891        if (IS_ERR(kone_class))
 892                return PTR_ERR(kone_class);
 893        kone_class->dev_groups = kone_groups;
 894
 895        retval = hid_register_driver(&kone_driver);
 896        if (retval)
 897                class_destroy(kone_class);
 898        return retval;
 899}
 900
 901static void __exit kone_exit(void)
 902{
 903        hid_unregister_driver(&kone_driver);
 904        class_destroy(kone_class);
 905}
 906
 907module_init(kone_init);
 908module_exit(kone_exit);
 909
 910MODULE_AUTHOR("Stefan Achatz");
 911MODULE_DESCRIPTION("USB Roccat Kone driver");
 912MODULE_LICENSE("GPL v2");
 913