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