root/drivers/hid/hid-roccat-kone.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kone_profile_activated
  2. kone_profile_report
  3. kone_receive
  4. kone_send
  5. kone_set_settings_checksum
  6. kone_check_write
  7. kone_get_settings
  8. kone_set_settings
  9. kone_get_profile
  10. kone_set_profile
  11. kone_get_weight
  12. kone_get_firmware_version
  13. kone_sysfs_read_settings
  14. kone_sysfs_write_settings
  15. kone_sysfs_read_profilex
  16. kone_sysfs_write_profilex
  17. kone_sysfs_show_actual_profile
  18. kone_sysfs_show_actual_dpi
  19. kone_sysfs_show_weight
  20. kone_sysfs_show_firmware_version
  21. kone_sysfs_show_tcu
  22. kone_tcu_command
  23. kone_sysfs_set_tcu
  24. kone_sysfs_show_startup_profile
  25. kone_sysfs_set_startup_profile
  26. kone_init_kone_device_struct
  27. kone_init_specials
  28. kone_remove_specials
  29. kone_probe
  30. kone_remove
  31. kone_keep_values_up_to_date
  32. kone_report_to_chrdev
  33. kone_raw_event
  34. kone_init
  35. kone_exit

   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 
  35 static uint profile_numbers[5] = {0, 1, 2, 3, 4};
  36 
  37 static 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 
  43 static 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 
  53 static 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 
  73 static 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 */
  93 static struct class *kone_class;
  94 
  95 static 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  */
 111 static 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  */
 148 static 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  */
 160 static 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  */
 178 static 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  */
 204 static 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  */
 233 static 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  */
 252 static 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 
 266 static 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  */
 290 static 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 }
 324 static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
 325                 kone_sysfs_write_settings, sizeof(struct kone_settings));
 326 
 327 static 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 */
 347 static 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)                                    \
 379 static 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 }
 386 PROFILE_ATTR(1);
 387 PROFILE_ATTR(2);
 388 PROFILE_ATTR(3);
 389 PROFILE_ATTR(4);
 390 PROFILE_ATTR(5);
 391 
 392 static 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 }
 399 static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL);
 400 
 401 static 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 }
 408 static 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 */
 411 static 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 }
 431 static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL);
 432 
 433 static 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 }
 440 static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version,
 441                    NULL);
 442 
 443 static 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 
 451 static 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  */
 463 static 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;
 537 exit_no_settings:
 538         dev_err(&usb_dev->dev, "couldn't read settings\n");
 539 exit_unlock:
 540         mutex_unlock(&kone->kone_lock);
 541         return retval;
 542 }
 543 static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu);
 544 
 545 static 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 
 553 static 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 }
 590 static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile,
 591                    kone_sysfs_set_startup_profile);
 592 
 593 static 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 
 631 static 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 
 641 static const struct attribute_group kone_group = {
 642         .attrs = kone_attrs,
 643         .bin_attrs = kone_bin_attributes,
 644 };
 645 
 646 static const struct attribute_group *kone_groups[] = {
 647         &kone_group,
 648         NULL,
 649 };
 650 
 651 static 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  */
 685 static 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;
 720 exit_free:
 721         kfree(kone);
 722         return retval;
 723 }
 724 
 725 static 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 
 739 static 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 
 763 exit_stop:
 764         hid_hw_stop(hdev);
 765 exit:
 766         return retval;
 767 }
 768 
 769 static 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 */
 776 static 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 
 794 static 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  */
 829 static 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 
 861 static const struct hid_device_id kone_devices[] = {
 862         { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
 863         { }
 864 };
 865 
 866 MODULE_DEVICE_TABLE(hid, kone_devices);
 867 
 868 static 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 
 876 static 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 
 892 static void __exit kone_exit(void)
 893 {
 894         hid_unregister_driver(&kone_driver);
 895         class_destroy(kone_class);
 896 }
 897 
 898 module_init(kone_init);
 899 module_exit(kone_exit);
 900 
 901 MODULE_AUTHOR("Stefan Achatz");
 902 MODULE_DESCRIPTION("USB Roccat Kone driver");
 903 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */