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