Merge tag 'perf_urgent_for_v5.13_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / hid / hid-lg-g15.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  HID driver for gaming keys on Logitech gaming keyboards (such as the G15)
4  *
5  *  Copyright (c) 2019 Hans de Goede <hdegoede@redhat.com>
6  */
7
8 #include <linux/device.h>
9 #include <linux/hid.h>
10 #include <linux/module.h>
11 #include <linux/random.h>
12 #include <linux/sched.h>
13 #include <linux/usb.h>
14 #include <linux/wait.h>
15
16 #include "hid-ids.h"
17
18 #define LG_G15_TRANSFER_BUF_SIZE        20
19
20 #define LG_G15_FEATURE_REPORT           0x02
21
22 #define LG_G510_FEATURE_M_KEYS_LEDS     0x04
23 #define LG_G510_FEATURE_BACKLIGHT_RGB   0x05
24 #define LG_G510_FEATURE_POWER_ON_RGB    0x06
25
26 enum lg_g15_model {
27         LG_G15,
28         LG_G15_V2,
29         LG_G510,
30         LG_G510_USB_AUDIO,
31 };
32
33 enum lg_g15_led_type {
34         LG_G15_KBD_BRIGHTNESS,
35         LG_G15_LCD_BRIGHTNESS,
36         LG_G15_BRIGHTNESS_MAX,
37         LG_G15_MACRO_PRESET1 = 2,
38         LG_G15_MACRO_PRESET2,
39         LG_G15_MACRO_PRESET3,
40         LG_G15_MACRO_RECORD,
41         LG_G15_LED_MAX
42 };
43
44 struct lg_g15_led {
45         struct led_classdev cdev;
46         enum led_brightness brightness;
47         enum lg_g15_led_type led;
48         u8 red, green, blue;
49 };
50
51 struct lg_g15_data {
52         /* Must be first for proper dma alignment */
53         u8 transfer_buf[LG_G15_TRANSFER_BUF_SIZE];
54         /* Protects the transfer_buf and led brightness */
55         struct mutex mutex;
56         struct work_struct work;
57         struct input_dev *input;
58         struct hid_device *hdev;
59         enum lg_g15_model model;
60         struct lg_g15_led leds[LG_G15_LED_MAX];
61         bool game_mode_enabled;
62 };
63
64 /******** G15 and G15 v2 LED functions ********/
65
66 static int lg_g15_update_led_brightness(struct lg_g15_data *g15)
67 {
68         int ret;
69
70         ret = hid_hw_raw_request(g15->hdev, LG_G15_FEATURE_REPORT,
71                                  g15->transfer_buf, 4,
72                                  HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
73         if (ret != 4) {
74                 hid_err(g15->hdev, "Error getting LED brightness: %d\n", ret);
75                 return (ret < 0) ? ret : -EIO;
76         }
77
78         g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = g15->transfer_buf[1];
79         g15->leds[LG_G15_LCD_BRIGHTNESS].brightness = g15->transfer_buf[2];
80
81         g15->leds[LG_G15_MACRO_PRESET1].brightness =
82                 !(g15->transfer_buf[3] & 0x01);
83         g15->leds[LG_G15_MACRO_PRESET2].brightness =
84                 !(g15->transfer_buf[3] & 0x02);
85         g15->leds[LG_G15_MACRO_PRESET3].brightness =
86                 !(g15->transfer_buf[3] & 0x04);
87         g15->leds[LG_G15_MACRO_RECORD].brightness =
88                 !(g15->transfer_buf[3] & 0x08);
89
90         return 0;
91 }
92
93 static enum led_brightness lg_g15_led_get(struct led_classdev *led_cdev)
94 {
95         struct lg_g15_led *g15_led =
96                 container_of(led_cdev, struct lg_g15_led, cdev);
97         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
98         enum led_brightness brightness;
99
100         mutex_lock(&g15->mutex);
101         lg_g15_update_led_brightness(g15);
102         brightness = g15->leds[g15_led->led].brightness;
103         mutex_unlock(&g15->mutex);
104
105         return brightness;
106 }
107
108 static int lg_g15_led_set(struct led_classdev *led_cdev,
109                           enum led_brightness brightness)
110 {
111         struct lg_g15_led *g15_led =
112                 container_of(led_cdev, struct lg_g15_led, cdev);
113         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
114         u8 val, mask = 0;
115         int i, ret;
116
117         /* Ignore LED off on unregister / keyboard unplug */
118         if (led_cdev->flags & LED_UNREGISTERING)
119                 return 0;
120
121         mutex_lock(&g15->mutex);
122
123         g15->transfer_buf[0] = LG_G15_FEATURE_REPORT;
124         g15->transfer_buf[3] = 0;
125
126         if (g15_led->led < LG_G15_BRIGHTNESS_MAX) {
127                 g15->transfer_buf[1] = g15_led->led + 1;
128                 g15->transfer_buf[2] = brightness << (g15_led->led * 4);
129         } else {
130                 for (i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; i++) {
131                         if (i == g15_led->led)
132                                 val = brightness;
133                         else
134                                 val = g15->leds[i].brightness;
135
136                         if (val)
137                                 mask |= 1 << (i - LG_G15_MACRO_PRESET1);
138                 }
139
140                 g15->transfer_buf[1] = 0x04;
141                 g15->transfer_buf[2] = ~mask;
142         }
143
144         ret = hid_hw_raw_request(g15->hdev, LG_G15_FEATURE_REPORT,
145                                  g15->transfer_buf, 4,
146                                  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
147         if (ret == 4) {
148                 /* Success */
149                 g15_led->brightness = brightness;
150                 ret = 0;
151         } else {
152                 hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret);
153                 ret = (ret < 0) ? ret : -EIO;
154         }
155
156         mutex_unlock(&g15->mutex);
157
158         return ret;
159 }
160
161 static void lg_g15_leds_changed_work(struct work_struct *work)
162 {
163         struct lg_g15_data *g15 = container_of(work, struct lg_g15_data, work);
164         enum led_brightness old_brightness[LG_G15_BRIGHTNESS_MAX];
165         enum led_brightness brightness[LG_G15_BRIGHTNESS_MAX];
166         int i, ret;
167
168         mutex_lock(&g15->mutex);
169         for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++)
170                 old_brightness[i] = g15->leds[i].brightness;
171
172         ret = lg_g15_update_led_brightness(g15);
173
174         for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++)
175                 brightness[i] = g15->leds[i].brightness;
176         mutex_unlock(&g15->mutex);
177
178         if (ret)
179                 return;
180
181         for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++) {
182                 if (brightness[i] == old_brightness[i])
183                         continue;
184
185                 led_classdev_notify_brightness_hw_changed(&g15->leds[i].cdev,
186                                                           brightness[i]);
187         }
188 }
189
190 /******** G510 LED functions ********/
191
192 static int lg_g510_get_initial_led_brightness(struct lg_g15_data *g15, int i)
193 {
194         int ret, high;
195
196         ret = hid_hw_raw_request(g15->hdev, LG_G510_FEATURE_BACKLIGHT_RGB + i,
197                                  g15->transfer_buf, 4,
198                                  HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
199         if (ret != 4) {
200                 hid_err(g15->hdev, "Error getting LED brightness: %d\n", ret);
201                 return (ret < 0) ? ret : -EIO;
202         }
203
204         high = max3(g15->transfer_buf[1], g15->transfer_buf[2],
205                     g15->transfer_buf[3]);
206
207         if (high) {
208                 g15->leds[i].red =
209                         DIV_ROUND_CLOSEST(g15->transfer_buf[1] * 255, high);
210                 g15->leds[i].green =
211                         DIV_ROUND_CLOSEST(g15->transfer_buf[2] * 255, high);
212                 g15->leds[i].blue =
213                         DIV_ROUND_CLOSEST(g15->transfer_buf[3] * 255, high);
214                 g15->leds[i].brightness = high;
215         } else {
216                 g15->leds[i].red   = 255;
217                 g15->leds[i].green = 255;
218                 g15->leds[i].blue  = 255;
219                 g15->leds[i].brightness = 0;
220         }
221
222         return 0;
223 }
224
225 /* Must be called with g15->mutex locked */
226 static int lg_g510_kbd_led_write(struct lg_g15_data *g15,
227                                  struct lg_g15_led *g15_led,
228                                  enum led_brightness brightness)
229 {
230         int ret;
231
232         g15->transfer_buf[0] = 5 + g15_led->led;
233         g15->transfer_buf[1] =
234                 DIV_ROUND_CLOSEST(g15_led->red * brightness, 255);
235         g15->transfer_buf[2] =
236                 DIV_ROUND_CLOSEST(g15_led->green * brightness, 255);
237         g15->transfer_buf[3] =
238                 DIV_ROUND_CLOSEST(g15_led->blue * brightness, 255);
239
240         ret = hid_hw_raw_request(g15->hdev,
241                                  LG_G510_FEATURE_BACKLIGHT_RGB + g15_led->led,
242                                  g15->transfer_buf, 4,
243                                  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
244         if (ret == 4) {
245                 /* Success */
246                 g15_led->brightness = brightness;
247                 ret = 0;
248         } else {
249                 hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret);
250                 ret = (ret < 0) ? ret : -EIO;
251         }
252
253         return ret;
254 }
255
256 static int lg_g510_kbd_led_set(struct led_classdev *led_cdev,
257                                enum led_brightness brightness)
258 {
259         struct lg_g15_led *g15_led =
260                 container_of(led_cdev, struct lg_g15_led, cdev);
261         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
262         int ret;
263
264         /* Ignore LED off on unregister / keyboard unplug */
265         if (led_cdev->flags & LED_UNREGISTERING)
266                 return 0;
267
268         mutex_lock(&g15->mutex);
269         ret = lg_g510_kbd_led_write(g15, g15_led, brightness);
270         mutex_unlock(&g15->mutex);
271
272         return ret;
273 }
274
275 static enum led_brightness lg_g510_kbd_led_get(struct led_classdev *led_cdev)
276 {
277         struct lg_g15_led *g15_led =
278                 container_of(led_cdev, struct lg_g15_led, cdev);
279
280         return g15_led->brightness;
281 }
282
283 static ssize_t color_store(struct device *dev, struct device_attribute *attr,
284                            const char *buf, size_t count)
285 {
286         struct led_classdev *led_cdev = dev_get_drvdata(dev);
287         struct lg_g15_led *g15_led =
288                 container_of(led_cdev, struct lg_g15_led, cdev);
289         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
290         unsigned long value;
291         int ret;
292
293         if (count < 7 || (count == 8 && buf[7] != '\n') || count > 8)
294                 return -EINVAL;
295
296         if (buf[0] != '#')
297                 return -EINVAL;
298
299         ret = kstrtoul(buf + 1, 16, &value);
300         if (ret)
301                 return ret;
302
303         mutex_lock(&g15->mutex);
304         g15_led->red   = (value & 0xff0000) >> 16;
305         g15_led->green = (value & 0x00ff00) >> 8;
306         g15_led->blue  = (value & 0x0000ff);
307         ret = lg_g510_kbd_led_write(g15, g15_led, g15_led->brightness);
308         mutex_unlock(&g15->mutex);
309
310         return (ret < 0) ? ret : count;
311 }
312
313 static ssize_t color_show(struct device *dev, struct device_attribute *attr,
314                           char *buf)
315 {
316         struct led_classdev *led_cdev = dev_get_drvdata(dev);
317         struct lg_g15_led *g15_led =
318                 container_of(led_cdev, struct lg_g15_led, cdev);
319         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
320         ssize_t ret;
321
322         mutex_lock(&g15->mutex);
323         ret = sprintf(buf, "#%02x%02x%02x\n",
324                       g15_led->red, g15_led->green, g15_led->blue);
325         mutex_unlock(&g15->mutex);
326
327         return ret;
328 }
329
330 static DEVICE_ATTR_RW(color);
331
332 static struct attribute *lg_g510_kbd_led_attrs[] = {
333         &dev_attr_color.attr,
334         NULL,
335 };
336
337 static const struct attribute_group lg_g510_kbd_led_group = {
338         .attrs = lg_g510_kbd_led_attrs,
339 };
340
341 static const struct attribute_group *lg_g510_kbd_led_groups[] = {
342         &lg_g510_kbd_led_group,
343         NULL,
344 };
345
346 static void lg_g510_leds_sync_work(struct work_struct *work)
347 {
348         struct lg_g15_data *g15 = container_of(work, struct lg_g15_data, work);
349
350         mutex_lock(&g15->mutex);
351         lg_g510_kbd_led_write(g15, &g15->leds[LG_G15_KBD_BRIGHTNESS],
352                               g15->leds[LG_G15_KBD_BRIGHTNESS].brightness);
353         mutex_unlock(&g15->mutex);
354 }
355
356 static int lg_g510_update_mkey_led_brightness(struct lg_g15_data *g15)
357 {
358         int ret;
359
360         ret = hid_hw_raw_request(g15->hdev, LG_G510_FEATURE_M_KEYS_LEDS,
361                                  g15->transfer_buf, 2,
362                                  HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
363         if (ret != 2) {
364                 hid_err(g15->hdev, "Error getting LED brightness: %d\n", ret);
365                 ret = (ret < 0) ? ret : -EIO;
366         }
367
368         g15->leds[LG_G15_MACRO_PRESET1].brightness =
369                 !!(g15->transfer_buf[1] & 0x80);
370         g15->leds[LG_G15_MACRO_PRESET2].brightness =
371                 !!(g15->transfer_buf[1] & 0x40);
372         g15->leds[LG_G15_MACRO_PRESET3].brightness =
373                 !!(g15->transfer_buf[1] & 0x20);
374         g15->leds[LG_G15_MACRO_RECORD].brightness =
375                 !!(g15->transfer_buf[1] & 0x10);
376
377         return 0;
378 }
379
380 static enum led_brightness lg_g510_mkey_led_get(struct led_classdev *led_cdev)
381 {
382         struct lg_g15_led *g15_led =
383                 container_of(led_cdev, struct lg_g15_led, cdev);
384         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
385         enum led_brightness brightness;
386
387         mutex_lock(&g15->mutex);
388         lg_g510_update_mkey_led_brightness(g15);
389         brightness = g15->leds[g15_led->led].brightness;
390         mutex_unlock(&g15->mutex);
391
392         return brightness;
393 }
394
395 static int lg_g510_mkey_led_set(struct led_classdev *led_cdev,
396                                 enum led_brightness brightness)
397 {
398         struct lg_g15_led *g15_led =
399                 container_of(led_cdev, struct lg_g15_led, cdev);
400         struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
401         u8 val, mask = 0;
402         int i, ret;
403
404         /* Ignore LED off on unregister / keyboard unplug */
405         if (led_cdev->flags & LED_UNREGISTERING)
406                 return 0;
407
408         mutex_lock(&g15->mutex);
409
410         for (i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; i++) {
411                 if (i == g15_led->led)
412                         val = brightness;
413                 else
414                         val = g15->leds[i].brightness;
415
416                 if (val)
417                         mask |= 0x80 >> (i - LG_G15_MACRO_PRESET1);
418         }
419
420         g15->transfer_buf[0] = LG_G510_FEATURE_M_KEYS_LEDS;
421         g15->transfer_buf[1] = mask;
422
423         ret = hid_hw_raw_request(g15->hdev, LG_G510_FEATURE_M_KEYS_LEDS,
424                                  g15->transfer_buf, 2,
425                                  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
426         if (ret == 2) {
427                 /* Success */
428                 g15_led->brightness = brightness;
429                 ret = 0;
430         } else {
431                 hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret);
432                 ret = (ret < 0) ? ret : -EIO;
433         }
434
435         mutex_unlock(&g15->mutex);
436
437         return ret;
438 }
439
440 /******** Generic LED functions ********/
441 static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15)
442 {
443         int ret;
444
445         switch (g15->model) {
446         case LG_G15:
447         case LG_G15_V2:
448                 return lg_g15_update_led_brightness(g15);
449         case LG_G510:
450         case LG_G510_USB_AUDIO:
451                 ret = lg_g510_get_initial_led_brightness(g15, 0);
452                 if (ret)
453                         return ret;
454
455                 ret = lg_g510_get_initial_led_brightness(g15, 1);
456                 if (ret)
457                         return ret;
458
459                 return lg_g510_update_mkey_led_brightness(g15);
460         }
461         return -EINVAL; /* Never reached */
462 }
463
464 /******** Input functions ********/
465
466 /* On the G15 Mark I Logitech has been quite creative with which bit is what */
467 static int lg_g15_event(struct lg_g15_data *g15, u8 *data, int size)
468 {
469         int i, val;
470
471         /* G1 - G6 */
472         for (i = 0; i < 6; i++) {
473                 val = data[i + 1] & (1 << i);
474                 input_report_key(g15->input, KEY_MACRO1 + i, val);
475         }
476         /* G7 - G12 */
477         for (i = 0; i < 6; i++) {
478                 val = data[i + 2] & (1 << i);
479                 input_report_key(g15->input, KEY_MACRO7 + i, val);
480         }
481         /* G13 - G17 */
482         for (i = 0; i < 5; i++) {
483                 val = data[i + 1] & (4 << i);
484                 input_report_key(g15->input, KEY_MACRO13 + i, val);
485         }
486         /* G18 */
487         input_report_key(g15->input, KEY_MACRO18, data[8] & 0x40);
488
489         /* M1 - M3 */
490         for (i = 0; i < 3; i++) {
491                 val = data[i + 6] & (1 << i);
492                 input_report_key(g15->input, KEY_MACRO_PRESET1 + i, val);
493         }
494         /* MR */
495         input_report_key(g15->input, KEY_MACRO_RECORD_START, data[7] & 0x40);
496
497         /* Most left (round) button below the LCD */
498         input_report_key(g15->input, KEY_KBD_LCD_MENU1, data[8] & 0x80);
499         /* 4 other buttons below the LCD */
500         for (i = 0; i < 4; i++) {
501                 val = data[i + 2] & 0x80;
502                 input_report_key(g15->input, KEY_KBD_LCD_MENU2 + i, val);
503         }
504
505         /* Backlight cycle button pressed? */
506         if (data[1] & 0x80)
507                 schedule_work(&g15->work);
508
509         input_sync(g15->input);
510         return 0;
511 }
512
513 static int lg_g15_v2_event(struct lg_g15_data *g15, u8 *data, int size)
514 {
515         int i, val;
516
517         /* G1 - G6 */
518         for (i = 0; i < 6; i++) {
519                 val = data[1] & (1 << i);
520                 input_report_key(g15->input, KEY_MACRO1 + i, val);
521         }
522
523         /* M1 - M3 + MR */
524         input_report_key(g15->input, KEY_MACRO_PRESET1, data[1] & 0x40);
525         input_report_key(g15->input, KEY_MACRO_PRESET2, data[1] & 0x80);
526         input_report_key(g15->input, KEY_MACRO_PRESET3, data[2] & 0x20);
527         input_report_key(g15->input, KEY_MACRO_RECORD_START, data[2] & 0x40);
528
529         /* Round button to the left of the LCD */
530         input_report_key(g15->input, KEY_KBD_LCD_MENU1, data[2] & 0x80);
531         /* 4 buttons below the LCD */
532         for (i = 0; i < 4; i++) {
533                 val = data[2] & (2 << i);
534                 input_report_key(g15->input, KEY_KBD_LCD_MENU2 + i, val);
535         }
536
537         /* Backlight cycle button pressed? */
538         if (data[2] & 0x01)
539                 schedule_work(&g15->work);
540
541         input_sync(g15->input);
542         return 0;
543 }
544
545 static int lg_g510_event(struct lg_g15_data *g15, u8 *data, int size)
546 {
547         bool game_mode_enabled;
548         int i, val;
549
550         /* G1 - G18 */
551         for (i = 0; i < 18; i++) {
552                 val = data[i / 8 + 1] & (1 << (i % 8));
553                 input_report_key(g15->input, KEY_MACRO1 + i, val);
554         }
555
556         /* Game mode on/off slider */
557         game_mode_enabled = data[3] & 0x04;
558         if (game_mode_enabled != g15->game_mode_enabled) {
559                 if (game_mode_enabled)
560                         hid_info(g15->hdev, "Game Mode enabled, Windows (super) key is disabled\n");
561                 else
562                         hid_info(g15->hdev, "Game Mode disabled\n");
563                 g15->game_mode_enabled = game_mode_enabled;
564         }
565
566         /* M1 - M3 */
567         for (i = 0; i < 3; i++) {
568                 val = data[3] & (0x10 << i);
569                 input_report_key(g15->input, KEY_MACRO_PRESET1 + i, val);
570         }
571         /* MR */
572         input_report_key(g15->input, KEY_MACRO_RECORD_START, data[3] & 0x80);
573
574         /* LCD menu keys */
575         for (i = 0; i < 5; i++) {
576                 val = data[4] & (1 << i);
577                 input_report_key(g15->input, KEY_KBD_LCD_MENU1 + i, val);
578         }
579
580         /* Headphone Mute */
581         input_report_key(g15->input, KEY_MUTE, data[4] & 0x20);
582         /* Microphone Mute */
583         input_report_key(g15->input, KEY_F20, data[4] & 0x40);
584
585         input_sync(g15->input);
586         return 0;
587 }
588
589 static int lg_g510_leds_event(struct lg_g15_data *g15, u8 *data, int size)
590 {
591         bool backlight_disabled;
592
593         /*
594          * The G510 ignores backlight updates when the backlight is turned off
595          * through the light toggle button on the keyboard, to work around this
596          * we queue a workitem to sync values when the backlight is turned on.
597          */
598         backlight_disabled = data[1] & 0x04;
599         if (!backlight_disabled)
600                 schedule_work(&g15->work);
601
602         return 0;
603 }
604
605 static int lg_g15_raw_event(struct hid_device *hdev, struct hid_report *report,
606                             u8 *data, int size)
607 {
608         struct lg_g15_data *g15 = hid_get_drvdata(hdev);
609
610         if (!g15)
611                 return 0;
612
613         switch (g15->model) {
614         case LG_G15:
615                 if (data[0] == 0x02 && size == 9)
616                         return lg_g15_event(g15, data, size);
617                 break;
618         case LG_G15_V2:
619                 if (data[0] == 0x02 && size == 5)
620                         return lg_g15_v2_event(g15, data, size);
621                 break;
622         case LG_G510:
623         case LG_G510_USB_AUDIO:
624                 if (data[0] == 0x03 && size == 5)
625                         return lg_g510_event(g15, data, size);
626                 if (data[0] == 0x04 && size == 2)
627                         return lg_g510_leds_event(g15, data, size);
628                 break;
629         }
630
631         return 0;
632 }
633
634 static int lg_g15_input_open(struct input_dev *dev)
635 {
636         struct hid_device *hdev = input_get_drvdata(dev);
637
638         return hid_hw_open(hdev);
639 }
640
641 static void lg_g15_input_close(struct input_dev *dev)
642 {
643         struct hid_device *hdev = input_get_drvdata(dev);
644
645         hid_hw_close(hdev);
646 }
647
648 static int lg_g15_register_led(struct lg_g15_data *g15, int i)
649 {
650         static const char * const led_names[] = {
651                 "g15::kbd_backlight",
652                 "g15::lcd_backlight",
653                 "g15::macro_preset1",
654                 "g15::macro_preset2",
655                 "g15::macro_preset3",
656                 "g15::macro_record",
657         };
658
659         g15->leds[i].led = i;
660         g15->leds[i].cdev.name = led_names[i];
661
662         switch (g15->model) {
663         case LG_G15:
664         case LG_G15_V2:
665                 g15->leds[i].cdev.brightness_set_blocking = lg_g15_led_set;
666                 g15->leds[i].cdev.brightness_get = lg_g15_led_get;
667                 if (i < LG_G15_BRIGHTNESS_MAX) {
668                         g15->leds[i].cdev.flags = LED_BRIGHT_HW_CHANGED;
669                         g15->leds[i].cdev.max_brightness = 2;
670                 } else {
671                         g15->leds[i].cdev.max_brightness = 1;
672                 }
673                 break;
674         case LG_G510:
675         case LG_G510_USB_AUDIO:
676                 switch (i) {
677                 case LG_G15_LCD_BRIGHTNESS:
678                         /*
679                          * The G510 does not have a separate LCD brightness,
680                          * but it does have a separate power-on (reset) value.
681                          */
682                         g15->leds[i].cdev.name = "g15::power_on_backlight_val";
683                         fallthrough;
684                 case LG_G15_KBD_BRIGHTNESS:
685                         g15->leds[i].cdev.brightness_set_blocking =
686                                 lg_g510_kbd_led_set;
687                         g15->leds[i].cdev.brightness_get =
688                                 lg_g510_kbd_led_get;
689                         g15->leds[i].cdev.max_brightness = 255;
690                         g15->leds[i].cdev.groups = lg_g510_kbd_led_groups;
691                         break;
692                 default:
693                         g15->leds[i].cdev.brightness_set_blocking =
694                                 lg_g510_mkey_led_set;
695                         g15->leds[i].cdev.brightness_get =
696                                 lg_g510_mkey_led_get;
697                         g15->leds[i].cdev.max_brightness = 1;
698                 }
699                 break;
700         }
701
702         return devm_led_classdev_register(&g15->hdev->dev, &g15->leds[i].cdev);
703 }
704
705 static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
706 {
707         u8 gkeys_settings_output_report = 0;
708         u8 gkeys_settings_feature_report = 0;
709         struct hid_report_enum *rep_enum;
710         unsigned int connect_mask = 0;
711         bool has_ff000000 = false;
712         struct lg_g15_data *g15;
713         struct input_dev *input;
714         struct hid_report *rep;
715         int ret, i, gkeys = 0;
716
717         hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
718
719         ret = hid_parse(hdev);
720         if (ret)
721                 return ret;
722
723         /*
724          * Some models have multiple interfaces, we want the interface with
725          * with the f000.0000 application input report.
726          */
727         rep_enum = &hdev->report_enum[HID_INPUT_REPORT];
728         list_for_each_entry(rep, &rep_enum->report_list, list) {
729                 if (rep->application == 0xff000000)
730                         has_ff000000 = true;
731         }
732         if (!has_ff000000)
733                 return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
734
735         g15 = devm_kzalloc(&hdev->dev, sizeof(*g15), GFP_KERNEL);
736         if (!g15)
737                 return -ENOMEM;
738
739         mutex_init(&g15->mutex);
740
741         input = devm_input_allocate_device(&hdev->dev);
742         if (!input)
743                 return -ENOMEM;
744
745         g15->hdev = hdev;
746         g15->model = id->driver_data;
747         hid_set_drvdata(hdev, (void *)g15);
748
749         switch (g15->model) {
750         case LG_G15:
751                 INIT_WORK(&g15->work, lg_g15_leds_changed_work);
752                 /*
753                  * The G15 and G15 v2 use a separate usb-device (on a builtin
754                  * hub) which emulates a keyboard for the F1 - F12 emulation
755                  * on the G-keys, which we disable, rendering the emulated kbd
756                  * non-functional, so we do not let hid-input connect.
757                  */
758                 connect_mask = HID_CONNECT_HIDRAW;
759                 gkeys_settings_output_report = 0x02;
760                 gkeys = 18;
761                 break;
762         case LG_G15_V2:
763                 INIT_WORK(&g15->work, lg_g15_leds_changed_work);
764                 connect_mask = HID_CONNECT_HIDRAW;
765                 gkeys_settings_output_report = 0x02;
766                 gkeys = 6;
767                 break;
768         case LG_G510:
769         case LG_G510_USB_AUDIO:
770                 INIT_WORK(&g15->work, lg_g510_leds_sync_work);
771                 connect_mask = HID_CONNECT_HIDINPUT | HID_CONNECT_HIDRAW;
772                 gkeys_settings_feature_report = 0x01;
773                 gkeys = 18;
774                 break;
775         }
776
777         ret = hid_hw_start(hdev, connect_mask);
778         if (ret)
779                 return ret;
780
781         /* Tell the keyboard to stop sending F1-F12 + 1-6 for G1 - G18 */
782         if (gkeys_settings_output_report) {
783                 g15->transfer_buf[0] = gkeys_settings_output_report;
784                 memset(g15->transfer_buf + 1, 0, gkeys);
785                 /*
786                  * The kbd ignores our output report if we do not queue
787                  * an URB on the USB input endpoint first...
788                  */
789                 ret = hid_hw_open(hdev);
790                 if (ret)
791                         goto error_hw_stop;
792                 ret = hid_hw_output_report(hdev, g15->transfer_buf, gkeys + 1);
793                 hid_hw_close(hdev);
794         }
795
796         if (gkeys_settings_feature_report) {
797                 g15->transfer_buf[0] = gkeys_settings_feature_report;
798                 memset(g15->transfer_buf + 1, 0, gkeys);
799                 ret = hid_hw_raw_request(g15->hdev,
800                                 gkeys_settings_feature_report,
801                                 g15->transfer_buf, gkeys + 1,
802                                 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
803         }
804
805         if (ret < 0) {
806                 hid_err(hdev, "Error %d disabling keyboard emulation for the G-keys, falling back to generic hid-input driver\n",
807                         ret);
808                 hid_set_drvdata(hdev, NULL);
809                 return 0;
810         }
811
812         /* Get initial brightness levels */
813         ret = lg_g15_get_initial_led_brightness(g15);
814         if (ret)
815                 goto error_hw_stop;
816
817         /* Setup and register input device */
818         input->name = "Logitech Gaming Keyboard Gaming Keys";
819         input->phys = hdev->phys;
820         input->uniq = hdev->uniq;
821         input->id.bustype = hdev->bus;
822         input->id.vendor  = hdev->vendor;
823         input->id.product = hdev->product;
824         input->id.version = hdev->version;
825         input->dev.parent = &hdev->dev;
826         input->open = lg_g15_input_open;
827         input->close = lg_g15_input_close;
828
829         /* G-keys */
830         for (i = 0; i < gkeys; i++)
831                 input_set_capability(input, EV_KEY, KEY_MACRO1 + i);
832
833         /* M1 - M3 and MR keys */
834         for (i = 0; i < 3; i++)
835                 input_set_capability(input, EV_KEY, KEY_MACRO_PRESET1 + i);
836         input_set_capability(input, EV_KEY, KEY_MACRO_RECORD_START);
837
838         /* Keys below the LCD, intended for controlling a menu on the LCD */
839         for (i = 0; i < 5; i++)
840                 input_set_capability(input, EV_KEY, KEY_KBD_LCD_MENU1 + i);
841
842         /*
843          * On the G510 only report headphone and mic mute keys when *not* using
844          * the builtin USB audio device. When the builtin audio is used these
845          * keys directly toggle mute (and the LEDs) on/off.
846          */
847         if (g15->model == LG_G510) {
848                 input_set_capability(input, EV_KEY, KEY_MUTE);
849                 /* Userspace expects F20 for micmute */
850                 input_set_capability(input, EV_KEY, KEY_F20);
851         }
852
853         g15->input = input;
854         input_set_drvdata(input, hdev);
855
856         ret = input_register_device(input);
857         if (ret)
858                 goto error_hw_stop;
859
860         /* Register LED devices */
861         for (i = 0; i < LG_G15_LED_MAX; i++) {
862                 ret = lg_g15_register_led(g15, i);
863                 if (ret)
864                         goto error_hw_stop;
865         }
866
867         return 0;
868
869 error_hw_stop:
870         hid_hw_stop(hdev);
871         return ret;
872 }
873
874 static const struct hid_device_id lg_g15_devices[] = {
875         /* The G11 is a G15 without the LCD, treat it as a G15 */
876         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
877                 USB_DEVICE_ID_LOGITECH_G11),
878                 .driver_data = LG_G15 },
879         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
880                          USB_DEVICE_ID_LOGITECH_G15_LCD),
881                 .driver_data = LG_G15 },
882         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
883                          USB_DEVICE_ID_LOGITECH_G15_V2_LCD),
884                 .driver_data = LG_G15_V2 },
885         /* G510 without a headset plugged in */
886         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
887                          USB_DEVICE_ID_LOGITECH_G510),
888                 .driver_data = LG_G510 },
889         /* G510 with headset plugged in / with extra USB audio interface */
890         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
891                          USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO),
892                 .driver_data = LG_G510_USB_AUDIO },
893         { }
894 };
895 MODULE_DEVICE_TABLE(hid, lg_g15_devices);
896
897 static struct hid_driver lg_g15_driver = {
898         .name                   = "lg-g15",
899         .id_table               = lg_g15_devices,
900         .raw_event              = lg_g15_raw_event,
901         .probe                  = lg_g15_probe,
902 };
903 module_hid_driver(lg_g15_driver);
904
905 MODULE_LICENSE("GPL");