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