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 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 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 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 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 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 */ 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 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 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 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 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 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 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 ********/ 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 */ 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 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 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 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 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 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 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 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 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 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 */ 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 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