root/drivers/hid/hid-corsair.c

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

DEFINITIONS

This source file includes following definitions.
  1. corsair_usage_to_gkey
  2. k90_backlight_get
  3. k90_record_led_get
  4. k90_brightness_set
  5. k90_backlight_work
  6. k90_record_led_work
  7. k90_show_macro_mode
  8. k90_store_macro_mode
  9. k90_show_current_profile
  10. k90_store_current_profile
  11. k90_init_backlight
  12. k90_init_macro_functions
  13. k90_cleanup_backlight
  14. k90_cleanup_macro_functions
  15. corsair_probe
  16. corsair_remove
  17. corsair_event
  18. corsair_input_mapping
  19. corsair_mouse_report_fixup

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * HID driver for Corsair devices
   4  *
   5  * Supported devices:
   6  *  - Vengeance K70 Keyboard
   7  *  - K70 RAPIDFIRE Keyboard
   8  *  - Vengeance K90 Keyboard
   9  *  - Scimitar PRO RGB Gaming Mouse
  10  *
  11  * Copyright (c) 2015 Clement Vuchener
  12  * Copyright (c) 2017 Oscar Campos
  13  * Copyright (c) 2017 Aaron Bottegal
  14  */
  15 
  16 /*
  17  */
  18 
  19 #include <linux/hid.h>
  20 #include <linux/module.h>
  21 #include <linux/usb.h>
  22 #include <linux/leds.h>
  23 
  24 #include "hid-ids.h"
  25 
  26 #define CORSAIR_USE_K90_MACRO   (1<<0)
  27 #define CORSAIR_USE_K90_BACKLIGHT       (1<<1)
  28 
  29 struct k90_led {
  30         struct led_classdev cdev;
  31         int brightness;
  32         struct work_struct work;
  33         bool removed;
  34 };
  35 
  36 struct k90_drvdata {
  37         struct k90_led record_led;
  38 };
  39 
  40 struct corsair_drvdata {
  41         unsigned long quirks;
  42         struct k90_drvdata *k90;
  43         struct k90_led *backlight;
  44 };
  45 
  46 #define K90_GKEY_COUNT  18
  47 
  48 static int corsair_usage_to_gkey(unsigned int usage)
  49 {
  50         /* G1 (0xd0) to G16 (0xdf) */
  51         if (usage >= 0xd0 && usage <= 0xdf)
  52                 return usage - 0xd0 + 1;
  53         /* G17 (0xe8) to G18 (0xe9) */
  54         if (usage >= 0xe8 && usage <= 0xe9)
  55                 return usage - 0xe8 + 17;
  56         return 0;
  57 }
  58 
  59 static unsigned short corsair_gkey_map[K90_GKEY_COUNT] = {
  60         BTN_TRIGGER_HAPPY1,
  61         BTN_TRIGGER_HAPPY2,
  62         BTN_TRIGGER_HAPPY3,
  63         BTN_TRIGGER_HAPPY4,
  64         BTN_TRIGGER_HAPPY5,
  65         BTN_TRIGGER_HAPPY6,
  66         BTN_TRIGGER_HAPPY7,
  67         BTN_TRIGGER_HAPPY8,
  68         BTN_TRIGGER_HAPPY9,
  69         BTN_TRIGGER_HAPPY10,
  70         BTN_TRIGGER_HAPPY11,
  71         BTN_TRIGGER_HAPPY12,
  72         BTN_TRIGGER_HAPPY13,
  73         BTN_TRIGGER_HAPPY14,
  74         BTN_TRIGGER_HAPPY15,
  75         BTN_TRIGGER_HAPPY16,
  76         BTN_TRIGGER_HAPPY17,
  77         BTN_TRIGGER_HAPPY18,
  78 };
  79 
  80 module_param_array_named(gkey_codes, corsair_gkey_map, ushort, NULL, S_IRUGO);
  81 MODULE_PARM_DESC(gkey_codes, "Key codes for the G-keys");
  82 
  83 static unsigned short corsair_record_keycodes[2] = {
  84         BTN_TRIGGER_HAPPY19,
  85         BTN_TRIGGER_HAPPY20
  86 };
  87 
  88 module_param_array_named(recordkey_codes, corsair_record_keycodes, ushort,
  89                          NULL, S_IRUGO);
  90 MODULE_PARM_DESC(recordkey_codes, "Key codes for the MR (start and stop record) button");
  91 
  92 static unsigned short corsair_profile_keycodes[3] = {
  93         BTN_TRIGGER_HAPPY21,
  94         BTN_TRIGGER_HAPPY22,
  95         BTN_TRIGGER_HAPPY23
  96 };
  97 
  98 module_param_array_named(profilekey_codes, corsair_profile_keycodes, ushort,
  99                          NULL, S_IRUGO);
 100 MODULE_PARM_DESC(profilekey_codes, "Key codes for the profile buttons");
 101 
 102 #define CORSAIR_USAGE_SPECIAL_MIN 0xf0
 103 #define CORSAIR_USAGE_SPECIAL_MAX 0xff
 104 
 105 #define CORSAIR_USAGE_MACRO_RECORD_START 0xf6
 106 #define CORSAIR_USAGE_MACRO_RECORD_STOP 0xf7
 107 
 108 #define CORSAIR_USAGE_PROFILE 0xf1
 109 #define CORSAIR_USAGE_M1 0xf1
 110 #define CORSAIR_USAGE_M2 0xf2
 111 #define CORSAIR_USAGE_M3 0xf3
 112 #define CORSAIR_USAGE_PROFILE_MAX 0xf3
 113 
 114 #define CORSAIR_USAGE_META_OFF 0xf4
 115 #define CORSAIR_USAGE_META_ON  0xf5
 116 
 117 #define CORSAIR_USAGE_LIGHT 0xfa
 118 #define CORSAIR_USAGE_LIGHT_OFF 0xfa
 119 #define CORSAIR_USAGE_LIGHT_DIM 0xfb
 120 #define CORSAIR_USAGE_LIGHT_MEDIUM 0xfc
 121 #define CORSAIR_USAGE_LIGHT_BRIGHT 0xfd
 122 #define CORSAIR_USAGE_LIGHT_MAX 0xfd
 123 
 124 /* USB control protocol */
 125 
 126 #define K90_REQUEST_BRIGHTNESS 49
 127 #define K90_REQUEST_MACRO_MODE 2
 128 #define K90_REQUEST_STATUS 4
 129 #define K90_REQUEST_GET_MODE 5
 130 #define K90_REQUEST_PROFILE 20
 131 
 132 #define K90_MACRO_MODE_SW 0x0030
 133 #define K90_MACRO_MODE_HW 0x0001
 134 
 135 #define K90_MACRO_LED_ON  0x0020
 136 #define K90_MACRO_LED_OFF 0x0040
 137 
 138 /*
 139  * LED class devices
 140  */
 141 
 142 #define K90_BACKLIGHT_LED_SUFFIX "::backlight"
 143 #define K90_RECORD_LED_SUFFIX "::record"
 144 
 145 static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev)
 146 {
 147         int ret;
 148         struct k90_led *led = container_of(led_cdev, struct k90_led, cdev);
 149         struct device *dev = led->cdev.dev->parent;
 150         struct usb_interface *usbif = to_usb_interface(dev->parent);
 151         struct usb_device *usbdev = interface_to_usbdev(usbif);
 152         int brightness;
 153         char *data;
 154 
 155         data = kmalloc(8, GFP_KERNEL);
 156         if (!data)
 157                 return -ENOMEM;
 158 
 159         ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
 160                               K90_REQUEST_STATUS,
 161                               USB_DIR_IN | USB_TYPE_VENDOR |
 162                               USB_RECIP_DEVICE, 0, 0, data, 8,
 163                               USB_CTRL_SET_TIMEOUT);
 164         if (ret < 5) {
 165                 dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
 166                          ret);
 167                 ret = -EIO;
 168                 goto out;
 169         }
 170         brightness = data[4];
 171         if (brightness < 0 || brightness > 3) {
 172                 dev_warn(dev,
 173                          "Read invalid backlight brightness: %02hhx.\n",
 174                          data[4]);
 175                 ret = -EIO;
 176                 goto out;
 177         }
 178         ret = brightness;
 179 out:
 180         kfree(data);
 181 
 182         return ret;
 183 }
 184 
 185 static enum led_brightness k90_record_led_get(struct led_classdev *led_cdev)
 186 {
 187         struct k90_led *led = container_of(led_cdev, struct k90_led, cdev);
 188 
 189         return led->brightness;
 190 }
 191 
 192 static void k90_brightness_set(struct led_classdev *led_cdev,
 193                                enum led_brightness brightness)
 194 {
 195         struct k90_led *led = container_of(led_cdev, struct k90_led, cdev);
 196 
 197         led->brightness = brightness;
 198         schedule_work(&led->work);
 199 }
 200 
 201 static void k90_backlight_work(struct work_struct *work)
 202 {
 203         int ret;
 204         struct k90_led *led = container_of(work, struct k90_led, work);
 205         struct device *dev;
 206         struct usb_interface *usbif;
 207         struct usb_device *usbdev;
 208 
 209         if (led->removed)
 210                 return;
 211 
 212         dev = led->cdev.dev->parent;
 213         usbif = to_usb_interface(dev->parent);
 214         usbdev = interface_to_usbdev(usbif);
 215 
 216         ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
 217                               K90_REQUEST_BRIGHTNESS,
 218                               USB_DIR_OUT | USB_TYPE_VENDOR |
 219                               USB_RECIP_DEVICE, led->brightness, 0,
 220                               NULL, 0, USB_CTRL_SET_TIMEOUT);
 221         if (ret != 0)
 222                 dev_warn(dev, "Failed to set backlight brightness (error: %d).\n",
 223                          ret);
 224 }
 225 
 226 static void k90_record_led_work(struct work_struct *work)
 227 {
 228         int ret;
 229         struct k90_led *led = container_of(work, struct k90_led, work);
 230         struct device *dev;
 231         struct usb_interface *usbif;
 232         struct usb_device *usbdev;
 233         int value;
 234 
 235         if (led->removed)
 236                 return;
 237 
 238         dev = led->cdev.dev->parent;
 239         usbif = to_usb_interface(dev->parent);
 240         usbdev = interface_to_usbdev(usbif);
 241 
 242         if (led->brightness > 0)
 243                 value = K90_MACRO_LED_ON;
 244         else
 245                 value = K90_MACRO_LED_OFF;
 246 
 247         ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
 248                               K90_REQUEST_MACRO_MODE,
 249                               USB_DIR_OUT | USB_TYPE_VENDOR |
 250                               USB_RECIP_DEVICE, value, 0, NULL, 0,
 251                               USB_CTRL_SET_TIMEOUT);
 252         if (ret != 0)
 253                 dev_warn(dev, "Failed to set record LED state (error: %d).\n",
 254                          ret);
 255 }
 256 
 257 /*
 258  * Keyboard attributes
 259  */
 260 
 261 static ssize_t k90_show_macro_mode(struct device *dev,
 262                                    struct device_attribute *attr, char *buf)
 263 {
 264         int ret;
 265         struct usb_interface *usbif = to_usb_interface(dev->parent);
 266         struct usb_device *usbdev = interface_to_usbdev(usbif);
 267         const char *macro_mode;
 268         char *data;
 269 
 270         data = kmalloc(2, GFP_KERNEL);
 271         if (!data)
 272                 return -ENOMEM;
 273 
 274         ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
 275                               K90_REQUEST_GET_MODE,
 276                               USB_DIR_IN | USB_TYPE_VENDOR |
 277                               USB_RECIP_DEVICE, 0, 0, data, 2,
 278                               USB_CTRL_SET_TIMEOUT);
 279         if (ret < 1) {
 280                 dev_warn(dev, "Failed to get K90 initial mode (error %d).\n",
 281                          ret);
 282                 ret = -EIO;
 283                 goto out;
 284         }
 285 
 286         switch (data[0]) {
 287         case K90_MACRO_MODE_HW:
 288                 macro_mode = "HW";
 289                 break;
 290 
 291         case K90_MACRO_MODE_SW:
 292                 macro_mode = "SW";
 293                 break;
 294         default:
 295                 dev_warn(dev, "K90 in unknown mode: %02hhx.\n",
 296                          data[0]);
 297                 ret = -EIO;
 298                 goto out;
 299         }
 300 
 301         ret = snprintf(buf, PAGE_SIZE, "%s\n", macro_mode);
 302 out:
 303         kfree(data);
 304 
 305         return ret;
 306 }
 307 
 308 static ssize_t k90_store_macro_mode(struct device *dev,
 309                                     struct device_attribute *attr,
 310                                     const char *buf, size_t count)
 311 {
 312         int ret;
 313         struct usb_interface *usbif = to_usb_interface(dev->parent);
 314         struct usb_device *usbdev = interface_to_usbdev(usbif);
 315         __u16 value;
 316 
 317         if (strncmp(buf, "SW", 2) == 0)
 318                 value = K90_MACRO_MODE_SW;
 319         else if (strncmp(buf, "HW", 2) == 0)
 320                 value = K90_MACRO_MODE_HW;
 321         else
 322                 return -EINVAL;
 323 
 324         ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
 325                               K90_REQUEST_MACRO_MODE,
 326                               USB_DIR_OUT | USB_TYPE_VENDOR |
 327                               USB_RECIP_DEVICE, value, 0, NULL, 0,
 328                               USB_CTRL_SET_TIMEOUT);
 329         if (ret != 0) {
 330                 dev_warn(dev, "Failed to set macro mode.\n");
 331                 return ret;
 332         }
 333 
 334         return count;
 335 }
 336 
 337 static ssize_t k90_show_current_profile(struct device *dev,
 338                                         struct device_attribute *attr,
 339                                         char *buf)
 340 {
 341         int ret;
 342         struct usb_interface *usbif = to_usb_interface(dev->parent);
 343         struct usb_device *usbdev = interface_to_usbdev(usbif);
 344         int current_profile;
 345         char *data;
 346 
 347         data = kmalloc(8, GFP_KERNEL);
 348         if (!data)
 349                 return -ENOMEM;
 350 
 351         ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
 352                               K90_REQUEST_STATUS,
 353                               USB_DIR_IN | USB_TYPE_VENDOR |
 354                               USB_RECIP_DEVICE, 0, 0, data, 8,
 355                               USB_CTRL_SET_TIMEOUT);
 356         if (ret < 8) {
 357                 dev_warn(dev, "Failed to get K90 initial state (error %d).\n",
 358                          ret);
 359                 ret = -EIO;
 360                 goto out;
 361         }
 362         current_profile = data[7];
 363         if (current_profile < 1 || current_profile > 3) {
 364                 dev_warn(dev, "Read invalid current profile: %02hhx.\n",
 365                          data[7]);
 366                 ret = -EIO;
 367                 goto out;
 368         }
 369 
 370         ret = snprintf(buf, PAGE_SIZE, "%d\n", current_profile);
 371 out:
 372         kfree(data);
 373 
 374         return ret;
 375 }
 376 
 377 static ssize_t k90_store_current_profile(struct device *dev,
 378                                          struct device_attribute *attr,
 379                                          const char *buf, size_t count)
 380 {
 381         int ret;
 382         struct usb_interface *usbif = to_usb_interface(dev->parent);
 383         struct usb_device *usbdev = interface_to_usbdev(usbif);
 384         int profile;
 385 
 386         if (kstrtoint(buf, 10, &profile))
 387                 return -EINVAL;
 388         if (profile < 1 || profile > 3)
 389                 return -EINVAL;
 390 
 391         ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0),
 392                               K90_REQUEST_PROFILE,
 393                               USB_DIR_OUT | USB_TYPE_VENDOR |
 394                               USB_RECIP_DEVICE, profile, 0, NULL, 0,
 395                               USB_CTRL_SET_TIMEOUT);
 396         if (ret != 0) {
 397                 dev_warn(dev, "Failed to change current profile (error %d).\n",
 398                          ret);
 399                 return ret;
 400         }
 401 
 402         return count;
 403 }
 404 
 405 static DEVICE_ATTR(macro_mode, 0644, k90_show_macro_mode, k90_store_macro_mode);
 406 static DEVICE_ATTR(current_profile, 0644, k90_show_current_profile,
 407                    k90_store_current_profile);
 408 
 409 static struct attribute *k90_attrs[] = {
 410         &dev_attr_macro_mode.attr,
 411         &dev_attr_current_profile.attr,
 412         NULL
 413 };
 414 
 415 static const struct attribute_group k90_attr_group = {
 416         .attrs = k90_attrs,
 417 };
 418 
 419 /*
 420  * Driver functions
 421  */
 422 
 423 static int k90_init_backlight(struct hid_device *dev)
 424 {
 425         int ret;
 426         struct corsair_drvdata *drvdata = hid_get_drvdata(dev);
 427         size_t name_sz;
 428         char *name;
 429 
 430         drvdata->backlight = kzalloc(sizeof(struct k90_led), GFP_KERNEL);
 431         if (!drvdata->backlight) {
 432                 ret = -ENOMEM;
 433                 goto fail_backlight_alloc;
 434         }
 435 
 436         name_sz =
 437             strlen(dev_name(&dev->dev)) + sizeof(K90_BACKLIGHT_LED_SUFFIX);
 438         name = kzalloc(name_sz, GFP_KERNEL);
 439         if (!name) {
 440                 ret = -ENOMEM;
 441                 goto fail_name_alloc;
 442         }
 443         snprintf(name, name_sz, "%s" K90_BACKLIGHT_LED_SUFFIX,
 444                  dev_name(&dev->dev));
 445         drvdata->backlight->removed = false;
 446         drvdata->backlight->cdev.name = name;
 447         drvdata->backlight->cdev.max_brightness = 3;
 448         drvdata->backlight->cdev.brightness_set = k90_brightness_set;
 449         drvdata->backlight->cdev.brightness_get = k90_backlight_get;
 450         INIT_WORK(&drvdata->backlight->work, k90_backlight_work);
 451         ret = led_classdev_register(&dev->dev, &drvdata->backlight->cdev);
 452         if (ret != 0)
 453                 goto fail_register_cdev;
 454 
 455         return 0;
 456 
 457 fail_register_cdev:
 458         kfree(drvdata->backlight->cdev.name);
 459 fail_name_alloc:
 460         kfree(drvdata->backlight);
 461         drvdata->backlight = NULL;
 462 fail_backlight_alloc:
 463         return ret;
 464 }
 465 
 466 static int k90_init_macro_functions(struct hid_device *dev)
 467 {
 468         int ret;
 469         struct corsair_drvdata *drvdata = hid_get_drvdata(dev);
 470         struct k90_drvdata *k90;
 471         size_t name_sz;
 472         char *name;
 473 
 474         k90 = kzalloc(sizeof(struct k90_drvdata), GFP_KERNEL);
 475         if (!k90) {
 476                 ret = -ENOMEM;
 477                 goto fail_drvdata;
 478         }
 479         drvdata->k90 = k90;
 480 
 481         /* Init LED device for record LED */
 482         name_sz = strlen(dev_name(&dev->dev)) + sizeof(K90_RECORD_LED_SUFFIX);
 483         name = kzalloc(name_sz, GFP_KERNEL);
 484         if (!name) {
 485                 ret = -ENOMEM;
 486                 goto fail_record_led_alloc;
 487         }
 488         snprintf(name, name_sz, "%s" K90_RECORD_LED_SUFFIX,
 489                  dev_name(&dev->dev));
 490         k90->record_led.removed = false;
 491         k90->record_led.cdev.name = name;
 492         k90->record_led.cdev.max_brightness = 1;
 493         k90->record_led.cdev.brightness_set = k90_brightness_set;
 494         k90->record_led.cdev.brightness_get = k90_record_led_get;
 495         INIT_WORK(&k90->record_led.work, k90_record_led_work);
 496         k90->record_led.brightness = 0;
 497         ret = led_classdev_register(&dev->dev, &k90->record_led.cdev);
 498         if (ret != 0)
 499                 goto fail_record_led;
 500 
 501         /* Init attributes */
 502         ret = sysfs_create_group(&dev->dev.kobj, &k90_attr_group);
 503         if (ret != 0)
 504                 goto fail_sysfs;
 505 
 506         return 0;
 507 
 508 fail_sysfs:
 509         k90->record_led.removed = true;
 510         led_classdev_unregister(&k90->record_led.cdev);
 511         cancel_work_sync(&k90->record_led.work);
 512 fail_record_led:
 513         kfree(k90->record_led.cdev.name);
 514 fail_record_led_alloc:
 515         kfree(k90);
 516 fail_drvdata:
 517         drvdata->k90 = NULL;
 518         return ret;
 519 }
 520 
 521 static void k90_cleanup_backlight(struct hid_device *dev)
 522 {
 523         struct corsair_drvdata *drvdata = hid_get_drvdata(dev);
 524 
 525         if (drvdata->backlight) {
 526                 drvdata->backlight->removed = true;
 527                 led_classdev_unregister(&drvdata->backlight->cdev);
 528                 cancel_work_sync(&drvdata->backlight->work);
 529                 kfree(drvdata->backlight->cdev.name);
 530                 kfree(drvdata->backlight);
 531         }
 532 }
 533 
 534 static void k90_cleanup_macro_functions(struct hid_device *dev)
 535 {
 536         struct corsair_drvdata *drvdata = hid_get_drvdata(dev);
 537         struct k90_drvdata *k90 = drvdata->k90;
 538 
 539         if (k90) {
 540                 sysfs_remove_group(&dev->dev.kobj, &k90_attr_group);
 541 
 542                 k90->record_led.removed = true;
 543                 led_classdev_unregister(&k90->record_led.cdev);
 544                 cancel_work_sync(&k90->record_led.work);
 545                 kfree(k90->record_led.cdev.name);
 546 
 547                 kfree(k90);
 548         }
 549 }
 550 
 551 static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id)
 552 {
 553         int ret;
 554         unsigned long quirks = id->driver_data;
 555         struct corsair_drvdata *drvdata;
 556         struct usb_interface *usbif = to_usb_interface(dev->dev.parent);
 557 
 558         drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
 559                                GFP_KERNEL);
 560         if (drvdata == NULL)
 561                 return -ENOMEM;
 562         drvdata->quirks = quirks;
 563         hid_set_drvdata(dev, drvdata);
 564 
 565         ret = hid_parse(dev);
 566         if (ret != 0) {
 567                 hid_err(dev, "parse failed\n");
 568                 return ret;
 569         }
 570         ret = hid_hw_start(dev, HID_CONNECT_DEFAULT);
 571         if (ret != 0) {
 572                 hid_err(dev, "hw start failed\n");
 573                 return ret;
 574         }
 575 
 576         if (usbif->cur_altsetting->desc.bInterfaceNumber == 0) {
 577                 if (quirks & CORSAIR_USE_K90_MACRO) {
 578                         ret = k90_init_macro_functions(dev);
 579                         if (ret != 0)
 580                                 hid_warn(dev, "Failed to initialize K90 macro functions.\n");
 581                 }
 582                 if (quirks & CORSAIR_USE_K90_BACKLIGHT) {
 583                         ret = k90_init_backlight(dev);
 584                         if (ret != 0)
 585                                 hid_warn(dev, "Failed to initialize K90 backlight.\n");
 586                 }
 587         }
 588 
 589         return 0;
 590 }
 591 
 592 static void corsair_remove(struct hid_device *dev)
 593 {
 594         k90_cleanup_macro_functions(dev);
 595         k90_cleanup_backlight(dev);
 596 
 597         hid_hw_stop(dev);
 598 }
 599 
 600 static int corsair_event(struct hid_device *dev, struct hid_field *field,
 601                          struct hid_usage *usage, __s32 value)
 602 {
 603         struct corsair_drvdata *drvdata = hid_get_drvdata(dev);
 604 
 605         if (!drvdata->k90)
 606                 return 0;
 607 
 608         switch (usage->hid & HID_USAGE) {
 609         case CORSAIR_USAGE_MACRO_RECORD_START:
 610                 drvdata->k90->record_led.brightness = 1;
 611                 break;
 612         case CORSAIR_USAGE_MACRO_RECORD_STOP:
 613                 drvdata->k90->record_led.brightness = 0;
 614                 break;
 615         default:
 616                 break;
 617         }
 618 
 619         return 0;
 620 }
 621 
 622 static int corsair_input_mapping(struct hid_device *dev,
 623                                  struct hid_input *input,
 624                                  struct hid_field *field,
 625                                  struct hid_usage *usage, unsigned long **bit,
 626                                  int *max)
 627 {
 628         int gkey;
 629 
 630         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD)
 631                 return 0;
 632 
 633         gkey = corsair_usage_to_gkey(usage->hid & HID_USAGE);
 634         if (gkey != 0) {
 635                 hid_map_usage_clear(input, usage, bit, max, EV_KEY,
 636                                     corsair_gkey_map[gkey - 1]);
 637                 return 1;
 638         }
 639         if ((usage->hid & HID_USAGE) >= CORSAIR_USAGE_SPECIAL_MIN &&
 640             (usage->hid & HID_USAGE) <= CORSAIR_USAGE_SPECIAL_MAX) {
 641                 switch (usage->hid & HID_USAGE) {
 642                 case CORSAIR_USAGE_MACRO_RECORD_START:
 643                         hid_map_usage_clear(input, usage, bit, max, EV_KEY,
 644                                             corsair_record_keycodes[0]);
 645                         return 1;
 646 
 647                 case CORSAIR_USAGE_MACRO_RECORD_STOP:
 648                         hid_map_usage_clear(input, usage, bit, max, EV_KEY,
 649                                             corsair_record_keycodes[1]);
 650                         return 1;
 651 
 652                 case CORSAIR_USAGE_M1:
 653                         hid_map_usage_clear(input, usage, bit, max, EV_KEY,
 654                                             corsair_profile_keycodes[0]);
 655                         return 1;
 656 
 657                 case CORSAIR_USAGE_M2:
 658                         hid_map_usage_clear(input, usage, bit, max, EV_KEY,
 659                                             corsair_profile_keycodes[1]);
 660                         return 1;
 661 
 662                 case CORSAIR_USAGE_M3:
 663                         hid_map_usage_clear(input, usage, bit, max, EV_KEY,
 664                                             corsair_profile_keycodes[2]);
 665                         return 1;
 666 
 667                 default:
 668                         return -1;
 669                 }
 670         }
 671 
 672         return 0;
 673 }
 674 
 675 /*
 676  * The report descriptor of some of the Corsair gaming mice is
 677  * non parseable as they define two consecutive Logical Minimum for
 678  * the Usage Page (Consumer) in rdescs bytes 75 and 77 being 77 0x16
 679  * that should be obviousy 0x26 for Logical Magimum of 16 bits. This
 680  * prevents poper parsing of the report descriptor due Logical
 681  * Minimum being larger than Logical Maximum.
 682  *
 683  * This driver fixes the report descriptor for:
 684  * - USB ID 1b1c:1b34, sold as GLAIVE RGB Gaming mouse
 685  * - USB ID 1b1c:1b3e, sold as Scimitar RGB Pro Gaming mouse
 686  */
 687 
 688 static __u8 *corsair_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 689         unsigned int *rsize)
 690 {
 691         struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
 692 
 693         if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
 694                 /*
 695                  * Corsair GLAIVE RGB and Scimitar RGB Pro report descriptor is
 696                  * broken and defines two different Logical Minimum for the
 697                  * Consumer Application. The byte 77 should be a 0x26 defining
 698                  * a 16 bits integer for the Logical Maximum but it is a 0x16
 699                  * instead (Logical Minimum)
 700                  */
 701                 switch (hdev->product) {
 702                 case USB_DEVICE_ID_CORSAIR_GLAIVE_RGB:
 703                 case USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB:
 704                         if (*rsize >= 172 && rdesc[75] == 0x15 && rdesc[77] == 0x16
 705                         && rdesc[78] == 0xff && rdesc[79] == 0x0f) {
 706                                 hid_info(hdev, "Fixing up report descriptor\n");
 707                                 rdesc[77] = 0x26;
 708                         }
 709                         break;
 710                 }
 711 
 712         }
 713         return rdesc;
 714 }
 715 
 716 static const struct hid_device_id corsair_devices[] = {
 717         { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90),
 718                 .driver_data = CORSAIR_USE_K90_MACRO |
 719                                CORSAIR_USE_K90_BACKLIGHT },
 720         { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
 721             USB_DEVICE_ID_CORSAIR_GLAIVE_RGB) },
 722         { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
 723             USB_DEVICE_ID_CORSAIR_SCIMITAR_PRO_RGB) },
 724         /*
 725          * Vengeance K70 and K70 RAPIDFIRE share product IDs.
 726          */
 727         { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR,
 728             USB_DEVICE_ID_CORSAIR_K70R) },
 729         {}
 730 };
 731 
 732 MODULE_DEVICE_TABLE(hid, corsair_devices);
 733 
 734 static struct hid_driver corsair_driver = {
 735         .name = "corsair",
 736         .id_table = corsair_devices,
 737         .probe = corsair_probe,
 738         .event = corsair_event,
 739         .remove = corsair_remove,
 740         .input_mapping = corsair_input_mapping,
 741         .report_fixup = corsair_mouse_report_fixup,
 742 };
 743 
 744 module_hid_driver(corsair_driver);
 745 
 746 MODULE_LICENSE("GPL");
 747 /* Original K90 driver author */
 748 MODULE_AUTHOR("Clement Vuchener");
 749 /* Scimitar PRO RGB driver author */
 750 MODULE_AUTHOR("Oscar Campos");
 751 MODULE_DESCRIPTION("HID driver for Corsair devices");

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