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