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
 298        /* I need to get my data in one piece */
 299        if (off != 0 || count != sizeof(struct kone_settings))
 300                return -EINVAL;
 301
 302        mutex_lock(&kone->kone_lock);
 303        difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings));
 304        if (difference) {
 305                retval = kone_set_settings(usb_dev,
 306                                (struct kone_settings const *)buf);
 307                if (retval) {
 308                        mutex_unlock(&kone->kone_lock);
 309                        return retval;
 310                }
 311
 312                old_profile = kone->settings.startup_profile;
 313                memcpy(&kone->settings, buf, sizeof(struct kone_settings));
 314
 315                kone_profile_activated(kone, kone->settings.startup_profile);
 316
 317                if (kone->settings.startup_profile != old_profile)
 318                        kone_profile_report(kone, kone->settings.startup_profile);
 319        }
 320        mutex_unlock(&kone->kone_lock);
 321
 322        return sizeof(struct kone_settings);
 323}
 324static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
 325                kone_sysfs_write_settings, sizeof(struct kone_settings));
 326
 327static ssize_t kone_sysfs_read_profilex(struct file *fp,
 328                struct kobject *kobj, struct bin_attribute *attr,
 329                char *buf, loff_t off, size_t count) {
 330        struct device *dev = kobj_to_dev(kobj)->parent->parent;
 331        struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
 332
 333        if (off >= sizeof(struct kone_profile))
 334                return 0;
 335
 336        if (off + count > sizeof(struct kone_profile))
 337                count = sizeof(struct kone_profile) - off;
 338
 339        mutex_lock(&kone->kone_lock);
 340        memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count);
 341        mutex_unlock(&kone->kone_lock);
 342
 343        return count;
 344}
 345
 346/* Writes data only if different to stored data */
 347static ssize_t kone_sysfs_write_profilex(struct file *fp,
 348                struct kobject *kobj, struct bin_attribute *attr,
 349                char *buf, loff_t off, size_t count) {
 350        struct device *dev = kobj_to_dev(kobj)->parent->parent;
 351        struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
 352        struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
 353        struct kone_profile *profile;
 354        int retval = 0, difference;
 355
 356        /* I need to get my data in one piece */
 357        if (off != 0 || count != sizeof(struct kone_profile))
 358                return -EINVAL;
 359
 360        profile = &kone->profiles[*(uint *)(attr->private)];
 361
 362        mutex_lock(&kone->kone_lock);
 363        difference = memcmp(buf, profile, sizeof(struct kone_profile));
 364        if (difference) {
 365                retval = kone_set_profile(usb_dev,
 366                                (struct kone_profile const *)buf,
 367                                *(uint *)(attr->private) + 1);
 368                if (!retval)
 369                        memcpy(profile, buf, sizeof(struct kone_profile));
 370        }
 371        mutex_unlock(&kone->kone_lock);
 372
 373        if (retval)
 374                return retval;
 375
 376        return sizeof(struct kone_profile);
 377}
 378#define PROFILE_ATTR(number)                                    \
 379static struct bin_attribute bin_attr_profile##number = {        \
 380        .attr = { .name = "profile" #number, .mode = 0660 },    \
 381        .size = sizeof(struct kone_profile),                    \
 382        .read = kone_sysfs_read_profilex,                       \
 383        .write = kone_sysfs_write_profilex,                     \
 384        .private = &profile_numbers[number-1],                  \
 385}
 386PROFILE_ATTR(1);
 387PROFILE_ATTR(2);
 388PROFILE_ATTR(3);
 389PROFILE_ATTR(4);
 390PROFILE_ATTR(5);
 391
 392static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
 393                struct device_attribute *attr, char *buf)
 394{
 395        struct kone_device *kone =
 396                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 397        return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile);
 398}
 399static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
 400
 401static ssize_t kone_sysfs_show_actual_dpi(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_dpi);
 407}
 408static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL);
 409
 410/* weight is read each time, since we don't get informed when it's changed */
 411static ssize_t kone_sysfs_show_weight(struct device *dev,
 412                struct device_attribute *attr, char *buf)
 413{
 414        struct kone_device *kone;
 415        struct usb_device *usb_dev;
 416        int weight = 0;
 417        int retval;
 418
 419        dev = dev->parent->parent;
 420        kone = hid_get_drvdata(dev_get_drvdata(dev));
 421        usb_dev = interface_to_usbdev(to_usb_interface(dev));
 422
 423        mutex_lock(&kone->kone_lock);
 424        retval = kone_get_weight(usb_dev, &weight);
 425        mutex_unlock(&kone->kone_lock);
 426
 427        if (retval)
 428                return retval;
 429        return snprintf(buf, PAGE_SIZE, "%d\n", weight);
 430}
 431static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
 432
 433static ssize_t kone_sysfs_show_firmware_version(struct device *dev,
 434                struct device_attribute *attr, char *buf)
 435{
 436        struct kone_device *kone =
 437                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 438        return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version);
 439}
 440static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
 441                   NULL);
 442
 443static ssize_t kone_sysfs_show_tcu(struct device *dev,
 444                struct device_attribute *attr, char *buf)
 445{
 446        struct kone_device *kone =
 447                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 448        return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu);
 449}
 450
 451static int kone_tcu_command(struct usb_device *usb_dev, int number)
 452{
 453        unsigned char value;
 454
 455        value = number;
 456        return kone_send(usb_dev, kone_command_calibrate, &value, 1);
 457}
 458
 459/*
 460 * Calibrating the tcu is the only action that changes settings data inside the
 461 * mouse, so this data needs to be reread
 462 */
 463static ssize_t kone_sysfs_set_tcu(struct device *dev,
 464                struct device_attribute *attr, char const *buf, size_t size)
 465{
 466        struct kone_device *kone;
 467        struct usb_device *usb_dev;
 468        int retval;
 469        unsigned long state;
 470
 471        dev = dev->parent->parent;
 472        kone = hid_get_drvdata(dev_get_drvdata(dev));
 473        usb_dev = interface_to_usbdev(to_usb_interface(dev));
 474
 475        retval = kstrtoul(buf, 10, &state);
 476        if (retval)
 477                return retval;
 478
 479        if (state != 0 && state != 1)
 480                return -EINVAL;
 481
 482        mutex_lock(&kone->kone_lock);
 483
 484        if (state == 1) { /* state activate */
 485                retval = kone_tcu_command(usb_dev, 1);
 486                if (retval)
 487                        goto exit_unlock;
 488                retval = kone_tcu_command(usb_dev, 2);
 489                if (retval)
 490                        goto exit_unlock;
 491                ssleep(5); /* tcu needs this time for calibration */
 492                retval = kone_tcu_command(usb_dev, 3);
 493                if (retval)
 494                        goto exit_unlock;
 495                retval = kone_tcu_command(usb_dev, 0);
 496                if (retval)
 497                        goto exit_unlock;
 498                retval = kone_tcu_command(usb_dev, 4);
 499                if (retval)
 500                        goto exit_unlock;
 501                /*
 502                 * Kone needs this time to settle things.
 503                 * Reading settings too early will result in invalid data.
 504                 * Roccat's driver waits 1 sec, maybe this time could be
 505                 * shortened.
 506                 */
 507                ssleep(1);
 508        }
 509
 510        /* calibration changes values in settings, so reread */
 511        retval = kone_get_settings(usb_dev, &kone->settings);
 512        if (retval)
 513                goto exit_no_settings;
 514
 515        /* only write settings back if activation state is different */
 516        if (kone->settings.tcu != state) {
 517                kone->settings.tcu = state;
 518                kone_set_settings_checksum(&kone->settings);
 519
 520                retval = kone_set_settings(usb_dev, &kone->settings);
 521                if (retval) {
 522                        dev_err(&usb_dev->dev, "couldn't set tcu state\n");
 523                        /*
 524                         * try to reread valid settings into buffer overwriting
 525                         * first error code
 526                         */
 527                        retval = kone_get_settings(usb_dev, &kone->settings);
 528                        if (retval)
 529                                goto exit_no_settings;
 530                        goto exit_unlock;
 531                }
 532                /* calibration resets profile */
 533                kone_profile_activated(kone, kone->settings.startup_profile);
 534        }
 535
 536        retval = size;
 537exit_no_settings:
 538        dev_err(&usb_dev->dev, "couldn't read settings\n");
 539exit_unlock:
 540        mutex_unlock(&kone->kone_lock);
 541        return retval;
 542}
 543static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
 544
 545static ssize_t kone_sysfs_show_startup_profile(struct device *dev,
 546                struct device_attribute *attr, char *buf)
 547{
 548        struct kone_device *kone =
 549                        hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
 550        return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile);
 551}
 552
 553static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
 554                struct device_attribute *attr, char const *buf, size_t size)
 555{
 556        struct kone_device *kone;
 557        struct usb_device *usb_dev;
 558        int retval;
 559        unsigned long new_startup_profile;
 560
 561        dev = dev->parent->parent;
 562        kone = hid_get_drvdata(dev_get_drvdata(dev));
 563        usb_dev = interface_to_usbdev(to_usb_interface(dev));
 564
 565        retval = kstrtoul(buf, 10, &new_startup_profile);
 566        if (retval)
 567                return retval;
 568
 569        if (new_startup_profile  < 1 || new_startup_profile > 5)
 570                return -EINVAL;
 571
 572        mutex_lock(&kone->kone_lock);
 573
 574        kone->settings.startup_profile = new_startup_profile;
 575        kone_set_settings_checksum(&kone->settings);
 576
 577        retval = kone_set_settings(usb_dev, &kone->settings);
 578        if (retval) {
 579                mutex_unlock(&kone->kone_lock);
 580                return retval;
 581        }
 582
 583        /* changing the startup profile immediately activates this profile */
 584        kone_profile_activated(kone, new_startup_profile);
 585        kone_profile_report(kone, new_startup_profile);
 586
 587        mutex_unlock(&kone->kone_lock);
 588        return size;
 589}
 590static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
 591                   kone_sysfs_set_startup_profile);
 592
 593static struct attribute *kone_attrs[] = {
 594        /*
 595         * Read actual dpi settings.
 596         * Returns raw value for further processing. Refer to enum
 597         * kone_polling_rates to get real value.
 598         */
 599        &dev_attr_actual_dpi.attr,
 600        &dev_attr_actual_profile.attr,
 601
 602        /*
 603         * The mouse can be equipped with one of four supplied weights from 5
 604         * to 20 grams which are recognized and its value can be read out.
 605         * This returns the raw value reported by the mouse for easy evaluation
 606         * by software. Refer to enum kone_weights to get corresponding real
 607         * weight.
 608         */
 609        &dev_attr_weight.attr,
 610
 611        /*
 612         * Prints firmware version stored in mouse as integer.
 613         * The raw value reported by the mouse is returned for easy evaluation,
 614         * to get the real version number the decimal point has to be shifted 2
 615         * positions to the left. E.g. a value of 138 means 1.38.
 616         */
 617        &dev_attr_firmware_version.attr,
 618
 619        /*
 620         * Prints state of Tracking Control Unit as number where 0 = off and
 621         * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and
 622         * activates the tcu
 623         */
 624        &dev_attr_tcu.attr,
 625
 626        /* Prints and takes the number of the profile the mouse starts with */
 627        &dev_attr_startup_profile.attr,
 628        NULL,
 629};
 630
 631static struct bin_attribute *kone_bin_attributes[] = {
 632        &bin_attr_settings,
 633        &bin_attr_profile1,
 634        &bin_attr_profile2,
 635        &bin_attr_profile3,
 636        &bin_attr_profile4,
 637        &bin_attr_profile5,
 638        NULL,
 639};
 640
 641static const struct attribute_group kone_group = {
 642        .attrs = kone_attrs,
 643        .bin_attrs = kone_bin_attributes,
 644};
 645
 646static const struct attribute_group *kone_groups[] = {
 647        &kone_group,
 648        NULL,
 649};
 650
 651static int kone_init_kone_device_struct(struct usb_device *usb_dev,
 652                struct kone_device *kone)
 653{
 654        uint i;
 655        int retval;
 656
 657        mutex_init(&kone->kone_lock);
 658
 659        for (i = 0; i < 5; ++i) {
 660                retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1);
 661                if (retval)
 662                        return retval;
 663        }
 664
 665        retval = kone_get_settings(usb_dev, &kone->settings);
 666        if (retval)
 667                return retval;
 668
 669        retval = kone_get_firmware_version(usb_dev, &kone->firmware_version);
 670        if (retval)
 671                return retval;
 672
 673        kone_profile_activated(kone, kone->settings.startup_profile);
 674
 675        return 0;
 676}
 677
 678/*
 679 * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to
 680 * mousepart if usb_hid is compiled into the kernel and kone is compiled as
 681 * module.
 682 * Secial behaviour is bound only to mousepart since only mouseevents contain
 683 * additional notifications.
 684 */
 685static int kone_init_specials(struct hid_device *hdev)
 686{
 687        struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 688        struct usb_device *usb_dev = interface_to_usbdev(intf);
 689        struct kone_device *kone;
 690        int retval;
 691
 692        if (intf->cur_altsetting->desc.bInterfaceProtocol
 693                        == USB_INTERFACE_PROTOCOL_MOUSE) {
 694
 695                kone = kzalloc(sizeof(*kone), GFP_KERNEL);
 696                if (!kone)
 697                        return -ENOMEM;
 698                hid_set_drvdata(hdev, kone);
 699
 700                retval = kone_init_kone_device_struct(usb_dev, kone);
 701                if (retval) {
 702                        hid_err(hdev, "couldn't init struct kone_device\n");
 703                        goto exit_free;
 704                }
 705
 706                retval = roccat_connect(kone_class, hdev,
 707                                sizeof(struct kone_roccat_report));
 708                if (retval < 0) {
 709                        hid_err(hdev, "couldn't init char dev\n");
 710                        /* be tolerant about not getting chrdev */
 711                } else {
 712                        kone->roccat_claimed = 1;
 713                        kone->chrdev_minor = retval;
 714                }
 715        } else {
 716                hid_set_drvdata(hdev, NULL);
 717        }
 718
 719        return 0;
 720exit_free:
 721        kfree(kone);
 722        return retval;
 723}
 724
 725static void kone_remove_specials(struct hid_device *hdev)
 726{
 727        struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 728        struct kone_device *kone;
 729
 730        if (intf->cur_altsetting->desc.bInterfaceProtocol
 731                        == USB_INTERFACE_PROTOCOL_MOUSE) {
 732                kone = hid_get_drvdata(hdev);
 733                if (kone->roccat_claimed)
 734                        roccat_disconnect(kone->chrdev_minor);
 735                kfree(hid_get_drvdata(hdev));
 736        }
 737}
 738
 739static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id)
 740{
 741        int retval;
 742
 743        retval = hid_parse(hdev);
 744        if (retval) {
 745                hid_err(hdev, "parse failed\n");
 746                goto exit;
 747        }
 748
 749        retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 750        if (retval) {
 751                hid_err(hdev, "hw start failed\n");
 752                goto exit;
 753        }
 754
 755        retval = kone_init_specials(hdev);
 756        if (retval) {
 757                hid_err(hdev, "couldn't install mouse\n");
 758                goto exit_stop;
 759        }
 760
 761        return 0;
 762
 763exit_stop:
 764        hid_hw_stop(hdev);
 765exit:
 766        return retval;
 767}
 768
 769static void kone_remove(struct hid_device *hdev)
 770{
 771        kone_remove_specials(hdev);
 772        hid_hw_stop(hdev);
 773}
 774
 775/* handle special events and keep actual profile and dpi values up to date */
 776static void kone_keep_values_up_to_date(struct kone_device *kone,
 777                struct kone_mouse_event const *event)
 778{
 779        switch (event->event) {
 780        case kone_mouse_event_switch_profile:
 781                kone->actual_dpi = kone->profiles[event->value - 1].
 782                                startup_dpi;
 783                /* fall through */
 784        case kone_mouse_event_osd_profile:
 785                kone->actual_profile = event->value;
 786                break;
 787        case kone_mouse_event_switch_dpi:
 788        case kone_mouse_event_osd_dpi:
 789                kone->actual_dpi = event->value;
 790                break;
 791        }
 792}
 793
 794static void kone_report_to_chrdev(struct kone_device const *kone,
 795                struct kone_mouse_event const *event)
 796{
 797        struct kone_roccat_report roccat_report;
 798
 799        switch (event->event) {
 800        case kone_mouse_event_switch_profile:
 801        case kone_mouse_event_switch_dpi:
 802        case kone_mouse_event_osd_profile:
 803        case kone_mouse_event_osd_dpi:
 804                roccat_report.event = event->event;
 805                roccat_report.value = event->value;
 806                roccat_report.key = 0;
 807                roccat_report_event(kone->chrdev_minor,
 808                                (uint8_t *)&roccat_report);
 809                break;
 810        case kone_mouse_event_call_overlong_macro:
 811        case kone_mouse_event_multimedia:
 812                if (event->value == kone_keystroke_action_press) {
 813                        roccat_report.event = event->event;
 814                        roccat_report.value = kone->actual_profile;
 815                        roccat_report.key = event->macro_key;
 816                        roccat_report_event(kone->chrdev_minor,
 817                                        (uint8_t *)&roccat_report);
 818                }
 819                break;
 820        }
 821
 822}
 823
 824/*
 825 * Is called for keyboard- and mousepart.
 826 * Only mousepart gets informations about special events in its extended event
 827 * structure.
 828 */
 829static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
 830                u8 *data, int size)
 831{
 832        struct kone_device *kone = hid_get_drvdata(hdev);
 833        struct kone_mouse_event *event = (struct kone_mouse_event *)data;
 834
 835        /* keyboard events are always processed by default handler */
 836        if (size != sizeof(struct kone_mouse_event))
 837                return 0;
 838
 839        if (kone == NULL)
 840                return 0;
 841
 842        /*
 843         * Firmware 1.38 introduced new behaviour for tilt and special buttons.
 844         * Pressed button is reported in each movement event.
 845         * Workaround sends only one event per press.
 846         */
 847        if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5))
 848                memcpy(&kone->last_mouse_event, event,
 849                                sizeof(struct kone_mouse_event));
 850        else
 851                memset(&event->tilt, 0, 5);
 852
 853        kone_keep_values_up_to_date(kone, event);
 854
 855        if (kone->roccat_claimed)
 856                kone_report_to_chrdev(kone, event);
 857
 858        return 0; /* always do further processing */
 859}
 860
 861static const struct hid_device_id kone_devices[] = {
 862        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
 863        { }
 864};
 865
 866MODULE_DEVICE_TABLE(hid, kone_devices);
 867
 868static struct hid_driver kone_driver = {
 869                .name = "kone",
 870                .id_table = kone_devices,
 871                .probe = kone_probe,
 872                .remove = kone_remove,
 873                .raw_event = kone_raw_event
 874};
 875
 876static int __init kone_init(void)
 877{
 878        int retval;
 879
 880        /* class name has to be same as driver name */
 881        kone_class = class_create(THIS_MODULE, "kone");
 882        if (IS_ERR(kone_class))
 883                return PTR_ERR(kone_class);
 884        kone_class->dev_groups = kone_groups;
 885
 886        retval = hid_register_driver(&kone_driver);
 887        if (retval)
 888                class_destroy(kone_class);
 889        return retval;
 890}
 891
 892static void __exit kone_exit(void)
 893{
 894        hid_unregister_driver(&kone_driver);
 895        class_destroy(kone_class);
 896}
 897
 898module_init(kone_init);
 899module_exit(kone_exit);
 900
 901MODULE_AUTHOR("Stefan Achatz");
 902MODULE_DESCRIPTION("USB Roccat Kone driver");
 903MODULE_LICENSE("GPL v2");
 904