Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID updates from Jiri Kosina:

- Support for Logitech G15 (Hans de Goede)

- HID parser improvements, improving support for some devices; e.g.
Windows Precision Touchpad, products from Primax, etc. (Blaž
Hrastnik, Candle Sun)

- robustification of tablet mode support in google-whiskers driver
(Dmitry Torokhov)

- assorted small fixes, device-specific quirks and device ID additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (23 commits)
HID: rmi: Check that the RMI_STARTED bit is set before unregistering the RMI transport device
HID: quirks: remove hid-led devices from hid_have_special_driver
HID: Improve Windows Precision Touchpad detection.
HID: i2c-hid: Reset ALPS touchpads on resume
HID: i2c-hid: fix no irq after reset on raydium 3118
HID: logitech-hidpp: Silence intermittent get_battery_capacity errors
HID: i2c-hid: remove orphaned member sleep_delay
HID: quirks: Add quirk for HP MSU1465 PIXART OEM mouse
HID: core: check whether Usage Page item is after Usage ID items
HID: intel-ish-hid: Spelling s/diconnect/disconnect/
HID: google: Detect base folded usage instead of hard-coding whiskers
HID: logitech: Add depends on LEDS_CLASS to Logitech Kconfig entry
HID: lg-g15: Add support for the G510's M1-M3 and MR LEDs
HID: lg-g15: Add support for controlling the G510's RGB backlight
HID: lg-g15: Add support for the G510 keyboards' gaming keys
HID: lg-g15: Add support for the M1-M3 and MR LEDs
HID: lg-g15: Add keyboard and LCD backlight control
HID: Add driver for Logitech gaming keyboards (G15, G15 v2)
Input: Add event-codes for macro keys found on various keyboards
HID: hidraw: replace printk() with corresponding pr_xx() variant
...

+1166 -66
+7
MAINTAINERS
··· 9709 9709 F: Documentation/admin-guide/ldm.rst 9710 9710 F: block/partitions/ldm.* 9711 9711 9712 + LOGITECH HID GAMING KEYBOARDS 9713 + M: Hans de Goede <hdegoede@redhat.com> 9714 + L: linux-input@vger.kernel.org 9715 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git 9716 + S: Maintained 9717 + F: drivers/hid/hid-lg-g15.c 9718 + 9712 9719 LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) 9713 9720 M: Sathya Prakash <sathya.prakash@broadcom.com> 9714 9721 M: Chaitra P B <chaitra.basappa@broadcom.com>
+1
drivers/hid/Kconfig
··· 525 525 config HID_LOGITECH 526 526 tristate "Logitech devices" 527 527 depends on HID 528 + depends on LEDS_CLASS 528 529 default !EXPERT 529 530 ---help--- 530 531 Support for Logitech devices that are not fully compliant with HID standard.
+1
drivers/hid/Makefile
··· 64 64 obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o 65 65 obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o 66 66 obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 67 + obj-$(CONFIG_HID_LOGITECH) += hid-lg-g15.o 67 68 obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o 68 69 obj-$(CONFIG_HID_LOGITECH_HIDPP) += hid-logitech-hidpp.o 69 70 obj-$(CONFIG_HID_MACALLY) += hid-macally.o
+49 -6
drivers/hid/hid-core.c
··· 212 212 } 213 213 214 214 /* 215 + * Concatenate usage which defines 16 bits or less with the 216 + * currently defined usage page to form a 32 bit usage 217 + */ 218 + 219 + static void complete_usage(struct hid_parser *parser, unsigned int index) 220 + { 221 + parser->local.usage[index] &= 0xFFFF; 222 + parser->local.usage[index] |= 223 + (parser->global.usage_page & 0xFFFF) << 16; 224 + } 225 + 226 + /* 215 227 * Add a usage to the temporary parser table. 216 228 */ 217 229 ··· 234 222 return -1; 235 223 } 236 224 parser->local.usage[parser->local.usage_index] = usage; 225 + 226 + /* 227 + * If Usage item only includes usage id, concatenate it with 228 + * currently defined usage page 229 + */ 230 + if (size <= 2) 231 + complete_usage(parser, parser->local.usage_index); 232 + 237 233 parser->local.usage_size[parser->local.usage_index] = size; 238 234 parser->local.collection_index[parser->local.usage_index] = 239 235 parser->collection_stack_ptr ? ··· 563 543 * usage value." 564 544 */ 565 545 566 - static void hid_concatenate_usage_page(struct hid_parser *parser) 546 + static void hid_concatenate_last_usage_page(struct hid_parser *parser) 567 547 { 568 548 int i; 549 + unsigned int usage_page; 550 + unsigned int current_page; 569 551 570 - for (i = 0; i < parser->local.usage_index; i++) 571 - if (parser->local.usage_size[i] <= 2) 572 - parser->local.usage[i] += parser->global.usage_page << 16; 552 + if (!parser->local.usage_index) 553 + return; 554 + 555 + usage_page = parser->global.usage_page; 556 + 557 + /* 558 + * Concatenate usage page again only if last declared Usage Page 559 + * has not been already used in previous usages concatenation 560 + */ 561 + for (i = parser->local.usage_index - 1; i >= 0; i--) { 562 + if (parser->local.usage_size[i] > 2) 563 + /* Ignore extended usages */ 564 + continue; 565 + 566 + current_page = parser->local.usage[i] >> 16; 567 + if (current_page == usage_page) 568 + break; 569 + 570 + complete_usage(parser, i); 571 + } 573 572 } 574 573 575 574 /* ··· 600 561 __u32 data; 601 562 int ret; 602 563 603 - hid_concatenate_usage_page(parser); 564 + hid_concatenate_last_usage_page(parser); 604 565 605 566 data = item_udata(item); 606 567 ··· 781 742 if (usage == 0xff0000c5 && parser->global.report_count == 256 && 782 743 parser->global.report_size == 8) 783 744 parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; 745 + 746 + if (usage == 0xff0000c6 && parser->global.report_count == 1 && 747 + parser->global.report_size == 8) 748 + parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; 784 749 } 785 750 786 751 static void hid_scan_collection(struct hid_parser *parser, unsigned type) ··· 815 772 __u32 data; 816 773 int i; 817 774 818 - hid_concatenate_usage_page(parser); 775 + hid_concatenate_last_usage_page(parser); 819 776 820 777 data = item_udata(item); 821 778
+103 -43
drivers/hid/hid-google-hammer.c
··· 35 35 struct device *dev; /* The platform device (EC) */ 36 36 struct input_dev *input; 37 37 bool base_present; 38 + bool base_folded; 38 39 struct notifier_block notifier; 39 40 }; 40 41 ··· 209 208 return error; 210 209 } 211 210 212 - input_report_switch(input, SW_TABLET_MODE, !cbas_ec.base_present); 211 + if (!cbas_ec.base_present) 212 + cbas_ec.base_folded = false; 213 + 214 + dev_dbg(&pdev->dev, "%s: base: %d, folded: %d\n", __func__, 215 + cbas_ec.base_present, cbas_ec.base_folded); 216 + 217 + input_report_switch(input, SW_TABLET_MODE, 218 + !cbas_ec.base_present || cbas_ec.base_folded); 213 219 214 220 cbas_ec_set_input(input); 215 221 ··· 330 322 static int hammer_register_leds(struct hid_device *hdev) 331 323 { 332 324 struct hammer_kbd_leds *kbd_backlight; 325 + int error; 333 326 334 - kbd_backlight = devm_kzalloc(&hdev->dev, 335 - sizeof(*kbd_backlight), 336 - GFP_KERNEL); 327 + kbd_backlight = kzalloc(sizeof(*kbd_backlight), GFP_KERNEL); 337 328 if (!kbd_backlight) 338 329 return -ENOMEM; 339 330 ··· 346 339 /* Set backlight to 0% initially. */ 347 340 hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0); 348 341 349 - return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev); 342 + error = led_classdev_register(&hdev->dev, &kbd_backlight->cdev); 343 + if (error) 344 + goto err_free_mem; 345 + 346 + hid_set_drvdata(hdev, kbd_backlight); 347 + return 0; 348 + 349 + err_free_mem: 350 + kfree(kbd_backlight); 351 + return error; 352 + } 353 + 354 + static void hammer_unregister_leds(struct hid_device *hdev) 355 + { 356 + struct hammer_kbd_leds *kbd_backlight = hid_get_drvdata(hdev); 357 + 358 + if (kbd_backlight) { 359 + led_classdev_unregister(&kbd_backlight->cdev); 360 + kfree(kbd_backlight); 361 + } 350 362 } 351 363 352 364 #define HID_UP_GOOGLEVENDOR 0xffd10000 353 365 #define HID_VD_KBD_FOLDED 0x00000019 354 - #define WHISKERS_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED) 366 + #define HID_USAGE_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED) 355 367 356 368 /* HID usage for keyboard backlight (Alphanumeric display brightness) */ 357 369 #define HID_AD_BRIGHTNESS 0x00140046 ··· 380 354 struct hid_usage *usage, 381 355 unsigned long **bit, int *max) 382 356 { 383 - if (hdev->product == USB_DEVICE_ID_GOOGLE_WHISKERS && 384 - usage->hid == WHISKERS_KBD_FOLDED) { 357 + if (usage->hid == HID_USAGE_KBD_FOLDED) { 385 358 /* 386 359 * We do not want to have this usage mapped as it will get 387 360 * mixed in with "base attached" signal and delivered over ··· 397 372 { 398 373 unsigned long flags; 399 374 400 - if (hid->product == USB_DEVICE_ID_GOOGLE_WHISKERS && 401 - usage->hid == WHISKERS_KBD_FOLDED) { 375 + if (usage->hid == HID_USAGE_KBD_FOLDED) { 402 376 spin_lock_irqsave(&cbas_ec_lock, flags); 403 377 404 - hid_dbg(hid, "%s: base: %d, folded: %d\n", __func__, 405 - cbas_ec.base_present, value); 406 - 407 378 /* 408 - * We should not get event if base is detached, but in case 409 - * we happen to service HID and EC notifications out of order 410 - * let's still check the "base present" flag. 379 + * If we are getting events from Whiskers that means that it 380 + * is attached to the lid. 411 381 */ 412 - if (cbas_ec.input && cbas_ec.base_present) { 382 + cbas_ec.base_present = true; 383 + cbas_ec.base_folded = value; 384 + hid_dbg(hid, "%s: base: %d, folded: %d\n", __func__, 385 + cbas_ec.base_present, cbas_ec.base_folded); 386 + 387 + if (cbas_ec.input) { 413 388 input_report_switch(cbas_ec.input, 414 389 SW_TABLET_MODE, value); 415 390 input_sync(cbas_ec.input); ··· 422 397 return 0; 423 398 } 424 399 425 - static bool hammer_is_keyboard_interface(struct hid_device *hdev) 400 + static bool hammer_has_usage(struct hid_device *hdev, unsigned int report_type, 401 + unsigned application, unsigned usage) 426 402 { 427 - struct hid_report_enum *re = &hdev->report_enum[HID_INPUT_REPORT]; 428 - struct hid_report *report; 429 - 430 - list_for_each_entry(report, &re->report_list, list) 431 - if (report->application == HID_GD_KEYBOARD) 432 - return true; 433 - 434 - return false; 435 - } 436 - 437 - static bool hammer_has_backlight_control(struct hid_device *hdev) 438 - { 439 - struct hid_report_enum *re = &hdev->report_enum[HID_OUTPUT_REPORT]; 403 + struct hid_report_enum *re = &hdev->report_enum[report_type]; 440 404 struct hid_report *report; 441 405 int i, j; 442 406 443 407 list_for_each_entry(report, &re->report_list, list) { 444 - if (report->application != HID_GD_KEYBOARD) 408 + if (report->application != application) 445 409 continue; 446 410 447 411 for (i = 0; i < report->maxfield; i++) { 448 412 struct hid_field *field = report->field[i]; 449 413 450 414 for (j = 0; j < field->maxusage; j++) 451 - if (field->usage[j].hid == HID_AD_BRIGHTNESS) 415 + if (field->usage[j].hid == usage) 452 416 return true; 453 417 } 454 418 } ··· 445 431 return false; 446 432 } 447 433 434 + static bool hammer_has_folded_event(struct hid_device *hdev) 435 + { 436 + return hammer_has_usage(hdev, HID_INPUT_REPORT, 437 + HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED); 438 + } 439 + 440 + static bool hammer_has_backlight_control(struct hid_device *hdev) 441 + { 442 + return hammer_has_usage(hdev, HID_OUTPUT_REPORT, 443 + HID_GD_KEYBOARD, HID_AD_BRIGHTNESS); 444 + } 445 + 448 446 static int hammer_probe(struct hid_device *hdev, 449 447 const struct hid_device_id *id) 450 448 { 451 449 int error; 452 - 453 - /* 454 - * We always want to poll for, and handle tablet mode events from 455 - * Whiskers, even when nobody has opened the input device. This also 456 - * prevents the hid core from dropping early tablet mode events from 457 - * the device. 458 - */ 459 - if (hdev->product == USB_DEVICE_ID_GOOGLE_WHISKERS && 460 - hammer_is_keyboard_interface(hdev)) 461 - hdev->quirks |= HID_QUIRK_ALWAYS_POLL; 462 450 463 451 error = hid_parse(hdev); 464 452 if (error) ··· 469 453 error = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 470 454 if (error) 471 455 return error; 456 + 457 + /* 458 + * We always want to poll for, and handle tablet mode events from 459 + * devices that have folded usage, even when nobody has opened the input 460 + * device. This also prevents the hid core from dropping early tablet 461 + * mode events from the device. 462 + */ 463 + if (hammer_has_folded_event(hdev)) { 464 + hdev->quirks |= HID_QUIRK_ALWAYS_POLL; 465 + error = hid_hw_open(hdev); 466 + if (error) 467 + return error; 468 + } 472 469 473 470 if (hammer_has_backlight_control(hdev)) { 474 471 error = hammer_register_leds(hdev); ··· 494 465 return 0; 495 466 } 496 467 468 + static void hammer_remove(struct hid_device *hdev) 469 + { 470 + unsigned long flags; 471 + 472 + if (hammer_has_folded_event(hdev)) { 473 + hid_hw_close(hdev); 474 + 475 + /* 476 + * If we are disconnecting then most likely Whiskers is 477 + * being removed. Even if it is not removed, without proper 478 + * keyboard we should not stay in clamshell mode. 479 + * 480 + * The reason for doing it here and not waiting for signal 481 + * from EC, is that on some devices there are high leakage 482 + * on Whiskers pins and we do not detect disconnect reliably, 483 + * resulting in devices being stuck in clamshell mode. 484 + */ 485 + spin_lock_irqsave(&cbas_ec_lock, flags); 486 + if (cbas_ec.input && cbas_ec.base_present) { 487 + input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1); 488 + input_sync(cbas_ec.input); 489 + } 490 + cbas_ec.base_present = false; 491 + spin_unlock_irqrestore(&cbas_ec_lock, flags); 492 + } 493 + 494 + hammer_unregister_leds(hdev); 495 + 496 + hid_hw_stop(hdev); 497 + } 497 498 498 499 static const struct hid_device_id hammer_devices[] = { 499 500 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, ··· 546 487 .name = "hammer", 547 488 .id_table = hammer_devices, 548 489 .probe = hammer_probe, 490 + .remove = hammer_remove, 549 491 .input_mapping = hammer_input_mapping, 550 492 .event = hammer_event, 551 493 };
+6
drivers/hid/hid-ids.h
··· 573 573 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a 574 574 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941 0x0941 575 575 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641 576 + #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a 0x1f4a 576 577 577 578 #define USB_VENDOR_ID_HUION 0x256c 578 579 #define USB_DEVICE_ID_HUION_TABLET 0x006e ··· 750 749 #define USB_DEVICE_ID_LOGITECH_DUAL_ACTION 0xc216 751 750 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 752 751 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 752 + #define USB_DEVICE_ID_LOGITECH_G15_LCD 0xc222 753 + #define USB_DEVICE_ID_LOGITECH_G15_V2_LCD 0xc227 754 + #define USB_DEVICE_ID_LOGITECH_G510 0xc22d 755 + #define USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO 0xc22e 753 756 #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f 754 757 #define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262 755 758 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 ··· 964 959 965 960 #define I2C_VENDOR_ID_RAYDIUM 0x2386 966 961 #define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33 962 + #define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118 967 963 968 964 #define USB_VENDOR_ID_RAZER 0x1532 969 965 #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
+899
drivers/hid/hid-lg-g15.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * HID driver for gaming keys on Logitech gaming keyboards (such as the G15) 4 + * 5 + * Copyright (c) 2019 Hans de Goede <hdegoede@redhat.com> 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/hid.h> 10 + #include <linux/module.h> 11 + #include <linux/random.h> 12 + #include <linux/sched.h> 13 + #include <linux/usb.h> 14 + #include <linux/wait.h> 15 + 16 + #include "hid-ids.h" 17 + 18 + #define LG_G15_TRANSFER_BUF_SIZE 20 19 + 20 + #define LG_G15_FEATURE_REPORT 0x02 21 + 22 + #define LG_G510_FEATURE_M_KEYS_LEDS 0x04 23 + #define LG_G510_FEATURE_BACKLIGHT_RGB 0x05 24 + #define LG_G510_FEATURE_POWER_ON_RGB 0x06 25 + 26 + enum lg_g15_model { 27 + LG_G15, 28 + LG_G15_V2, 29 + LG_G510, 30 + LG_G510_USB_AUDIO, 31 + }; 32 + 33 + enum lg_g15_led_type { 34 + LG_G15_KBD_BRIGHTNESS, 35 + LG_G15_LCD_BRIGHTNESS, 36 + LG_G15_BRIGHTNESS_MAX, 37 + LG_G15_MACRO_PRESET1 = 2, 38 + LG_G15_MACRO_PRESET2, 39 + LG_G15_MACRO_PRESET3, 40 + LG_G15_MACRO_RECORD, 41 + LG_G15_LED_MAX 42 + }; 43 + 44 + struct lg_g15_led { 45 + struct led_classdev cdev; 46 + enum led_brightness brightness; 47 + enum lg_g15_led_type led; 48 + u8 red, green, blue; 49 + }; 50 + 51 + struct lg_g15_data { 52 + /* Must be first for proper dma alignment */ 53 + u8 transfer_buf[LG_G15_TRANSFER_BUF_SIZE]; 54 + /* Protects the transfer_buf and led brightness */ 55 + struct mutex mutex; 56 + struct work_struct work; 57 + struct input_dev *input; 58 + struct hid_device *hdev; 59 + enum lg_g15_model model; 60 + struct lg_g15_led leds[LG_G15_LED_MAX]; 61 + bool game_mode_enabled; 62 + }; 63 + 64 + /******** G15 and G15 v2 LED functions ********/ 65 + 66 + static int lg_g15_update_led_brightness(struct lg_g15_data *g15) 67 + { 68 + int ret; 69 + 70 + ret = hid_hw_raw_request(g15->hdev, LG_G15_FEATURE_REPORT, 71 + g15->transfer_buf, 4, 72 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 73 + if (ret != 4) { 74 + hid_err(g15->hdev, "Error getting LED brightness: %d\n", ret); 75 + return (ret < 0) ? ret : -EIO; 76 + } 77 + 78 + g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = g15->transfer_buf[1]; 79 + g15->leds[LG_G15_LCD_BRIGHTNESS].brightness = g15->transfer_buf[2]; 80 + 81 + g15->leds[LG_G15_MACRO_PRESET1].brightness = 82 + !(g15->transfer_buf[3] & 0x01); 83 + g15->leds[LG_G15_MACRO_PRESET2].brightness = 84 + !(g15->transfer_buf[3] & 0x02); 85 + g15->leds[LG_G15_MACRO_PRESET3].brightness = 86 + !(g15->transfer_buf[3] & 0x04); 87 + g15->leds[LG_G15_MACRO_RECORD].brightness = 88 + !(g15->transfer_buf[3] & 0x08); 89 + 90 + return 0; 91 + } 92 + 93 + static enum led_brightness lg_g15_led_get(struct led_classdev *led_cdev) 94 + { 95 + struct lg_g15_led *g15_led = 96 + container_of(led_cdev, struct lg_g15_led, cdev); 97 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 98 + enum led_brightness brightness; 99 + 100 + mutex_lock(&g15->mutex); 101 + lg_g15_update_led_brightness(g15); 102 + brightness = g15->leds[g15_led->led].brightness; 103 + mutex_unlock(&g15->mutex); 104 + 105 + return brightness; 106 + } 107 + 108 + static int lg_g15_led_set(struct led_classdev *led_cdev, 109 + enum led_brightness brightness) 110 + { 111 + struct lg_g15_led *g15_led = 112 + container_of(led_cdev, struct lg_g15_led, cdev); 113 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 114 + u8 val, mask = 0; 115 + int i, ret; 116 + 117 + /* Ignore LED off on unregister / keyboard unplug */ 118 + if (led_cdev->flags & LED_UNREGISTERING) 119 + return 0; 120 + 121 + mutex_lock(&g15->mutex); 122 + 123 + g15->transfer_buf[0] = LG_G15_FEATURE_REPORT; 124 + g15->transfer_buf[3] = 0; 125 + 126 + if (g15_led->led < LG_G15_BRIGHTNESS_MAX) { 127 + g15->transfer_buf[1] = g15_led->led + 1; 128 + g15->transfer_buf[2] = brightness << (g15_led->led * 4); 129 + } else { 130 + for (i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; i++) { 131 + if (i == g15_led->led) 132 + val = brightness; 133 + else 134 + val = g15->leds[i].brightness; 135 + 136 + if (val) 137 + mask |= 1 << (i - LG_G15_MACRO_PRESET1); 138 + } 139 + 140 + g15->transfer_buf[1] = 0x04; 141 + g15->transfer_buf[2] = ~mask; 142 + } 143 + 144 + ret = hid_hw_raw_request(g15->hdev, LG_G15_FEATURE_REPORT, 145 + g15->transfer_buf, 4, 146 + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 147 + if (ret == 4) { 148 + /* Success */ 149 + g15_led->brightness = brightness; 150 + ret = 0; 151 + } else { 152 + hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret); 153 + ret = (ret < 0) ? ret : -EIO; 154 + } 155 + 156 + mutex_unlock(&g15->mutex); 157 + 158 + return ret; 159 + } 160 + 161 + static void lg_g15_leds_changed_work(struct work_struct *work) 162 + { 163 + struct lg_g15_data *g15 = container_of(work, struct lg_g15_data, work); 164 + enum led_brightness old_brightness[LG_G15_BRIGHTNESS_MAX]; 165 + enum led_brightness brightness[LG_G15_BRIGHTNESS_MAX]; 166 + int i, ret; 167 + 168 + mutex_lock(&g15->mutex); 169 + for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++) 170 + old_brightness[i] = g15->leds[i].brightness; 171 + 172 + ret = lg_g15_update_led_brightness(g15); 173 + 174 + for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++) 175 + brightness[i] = g15->leds[i].brightness; 176 + mutex_unlock(&g15->mutex); 177 + 178 + if (ret) 179 + return; 180 + 181 + for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++) { 182 + if (brightness[i] == old_brightness[i]) 183 + continue; 184 + 185 + led_classdev_notify_brightness_hw_changed(&g15->leds[i].cdev, 186 + brightness[i]); 187 + } 188 + } 189 + 190 + /******** G510 LED functions ********/ 191 + 192 + static int lg_g510_get_initial_led_brightness(struct lg_g15_data *g15, int i) 193 + { 194 + int ret, high; 195 + 196 + ret = hid_hw_raw_request(g15->hdev, LG_G510_FEATURE_BACKLIGHT_RGB + i, 197 + g15->transfer_buf, 4, 198 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 199 + if (ret != 4) { 200 + hid_err(g15->hdev, "Error getting LED brightness: %d\n", ret); 201 + return (ret < 0) ? ret : -EIO; 202 + } 203 + 204 + high = max3(g15->transfer_buf[1], g15->transfer_buf[2], 205 + g15->transfer_buf[3]); 206 + 207 + if (high) { 208 + g15->leds[i].red = 209 + DIV_ROUND_CLOSEST(g15->transfer_buf[1] * 255, high); 210 + g15->leds[i].green = 211 + DIV_ROUND_CLOSEST(g15->transfer_buf[2] * 255, high); 212 + g15->leds[i].blue = 213 + DIV_ROUND_CLOSEST(g15->transfer_buf[3] * 255, high); 214 + g15->leds[i].brightness = high; 215 + } else { 216 + g15->leds[i].red = 255; 217 + g15->leds[i].green = 255; 218 + g15->leds[i].blue = 255; 219 + g15->leds[i].brightness = 0; 220 + } 221 + 222 + return 0; 223 + } 224 + 225 + /* Must be called with g15->mutex locked */ 226 + static int lg_g510_kbd_led_write(struct lg_g15_data *g15, 227 + struct lg_g15_led *g15_led, 228 + enum led_brightness brightness) 229 + { 230 + int ret; 231 + 232 + g15->transfer_buf[0] = 5 + g15_led->led; 233 + g15->transfer_buf[1] = 234 + DIV_ROUND_CLOSEST(g15_led->red * brightness, 255); 235 + g15->transfer_buf[2] = 236 + DIV_ROUND_CLOSEST(g15_led->green * brightness, 255); 237 + g15->transfer_buf[3] = 238 + DIV_ROUND_CLOSEST(g15_led->blue * brightness, 255); 239 + 240 + ret = hid_hw_raw_request(g15->hdev, 241 + LG_G510_FEATURE_BACKLIGHT_RGB + g15_led->led, 242 + g15->transfer_buf, 4, 243 + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 244 + if (ret == 4) { 245 + /* Success */ 246 + g15_led->brightness = brightness; 247 + ret = 0; 248 + } else { 249 + hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret); 250 + ret = (ret < 0) ? ret : -EIO; 251 + } 252 + 253 + return ret; 254 + } 255 + 256 + static int lg_g510_kbd_led_set(struct led_classdev *led_cdev, 257 + enum led_brightness brightness) 258 + { 259 + struct lg_g15_led *g15_led = 260 + container_of(led_cdev, struct lg_g15_led, cdev); 261 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 262 + int ret; 263 + 264 + /* Ignore LED off on unregister / keyboard unplug */ 265 + if (led_cdev->flags & LED_UNREGISTERING) 266 + return 0; 267 + 268 + mutex_lock(&g15->mutex); 269 + ret = lg_g510_kbd_led_write(g15, g15_led, brightness); 270 + mutex_unlock(&g15->mutex); 271 + 272 + return ret; 273 + } 274 + 275 + static enum led_brightness lg_g510_kbd_led_get(struct led_classdev *led_cdev) 276 + { 277 + struct lg_g15_led *g15_led = 278 + container_of(led_cdev, struct lg_g15_led, cdev); 279 + 280 + return g15_led->brightness; 281 + } 282 + 283 + static ssize_t color_store(struct device *dev, struct device_attribute *attr, 284 + const char *buf, size_t count) 285 + { 286 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 287 + struct lg_g15_led *g15_led = 288 + container_of(led_cdev, struct lg_g15_led, cdev); 289 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 290 + unsigned long value; 291 + int ret; 292 + 293 + if (count < 7 || (count == 8 && buf[7] != '\n') || count > 8) 294 + return -EINVAL; 295 + 296 + if (buf[0] != '#') 297 + return -EINVAL; 298 + 299 + ret = kstrtoul(buf + 1, 16, &value); 300 + if (ret) 301 + return ret; 302 + 303 + mutex_lock(&g15->mutex); 304 + g15_led->red = (value & 0xff0000) >> 16; 305 + g15_led->green = (value & 0x00ff00) >> 8; 306 + g15_led->blue = (value & 0x0000ff); 307 + ret = lg_g510_kbd_led_write(g15, g15_led, g15_led->brightness); 308 + mutex_unlock(&g15->mutex); 309 + 310 + return (ret < 0) ? ret : count; 311 + } 312 + 313 + static ssize_t color_show(struct device *dev, struct device_attribute *attr, 314 + char *buf) 315 + { 316 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 317 + struct lg_g15_led *g15_led = 318 + container_of(led_cdev, struct lg_g15_led, cdev); 319 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 320 + ssize_t ret; 321 + 322 + mutex_lock(&g15->mutex); 323 + ret = sprintf(buf, "#%02x%02x%02x\n", 324 + g15_led->red, g15_led->green, g15_led->blue); 325 + mutex_unlock(&g15->mutex); 326 + 327 + return ret; 328 + } 329 + 330 + static DEVICE_ATTR_RW(color); 331 + 332 + static struct attribute *lg_g510_kbd_led_attrs[] = { 333 + &dev_attr_color.attr, 334 + NULL, 335 + }; 336 + 337 + static const struct attribute_group lg_g510_kbd_led_group = { 338 + .attrs = lg_g510_kbd_led_attrs, 339 + }; 340 + 341 + static const struct attribute_group *lg_g510_kbd_led_groups[] = { 342 + &lg_g510_kbd_led_group, 343 + NULL, 344 + }; 345 + 346 + static void lg_g510_leds_sync_work(struct work_struct *work) 347 + { 348 + struct lg_g15_data *g15 = container_of(work, struct lg_g15_data, work); 349 + 350 + mutex_lock(&g15->mutex); 351 + lg_g510_kbd_led_write(g15, &g15->leds[LG_G15_KBD_BRIGHTNESS], 352 + g15->leds[LG_G15_KBD_BRIGHTNESS].brightness); 353 + mutex_unlock(&g15->mutex); 354 + } 355 + 356 + static int lg_g510_update_mkey_led_brightness(struct lg_g15_data *g15) 357 + { 358 + int ret; 359 + 360 + ret = hid_hw_raw_request(g15->hdev, LG_G510_FEATURE_M_KEYS_LEDS, 361 + g15->transfer_buf, 2, 362 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 363 + if (ret != 2) { 364 + hid_err(g15->hdev, "Error getting LED brightness: %d\n", ret); 365 + ret = (ret < 0) ? ret : -EIO; 366 + } 367 + 368 + g15->leds[LG_G15_MACRO_PRESET1].brightness = 369 + !!(g15->transfer_buf[1] & 0x80); 370 + g15->leds[LG_G15_MACRO_PRESET2].brightness = 371 + !!(g15->transfer_buf[1] & 0x40); 372 + g15->leds[LG_G15_MACRO_PRESET3].brightness = 373 + !!(g15->transfer_buf[1] & 0x20); 374 + g15->leds[LG_G15_MACRO_RECORD].brightness = 375 + !!(g15->transfer_buf[1] & 0x10); 376 + 377 + return 0; 378 + } 379 + 380 + static enum led_brightness lg_g510_mkey_led_get(struct led_classdev *led_cdev) 381 + { 382 + struct lg_g15_led *g15_led = 383 + container_of(led_cdev, struct lg_g15_led, cdev); 384 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 385 + enum led_brightness brightness; 386 + 387 + mutex_lock(&g15->mutex); 388 + lg_g510_update_mkey_led_brightness(g15); 389 + brightness = g15->leds[g15_led->led].brightness; 390 + mutex_unlock(&g15->mutex); 391 + 392 + return brightness; 393 + } 394 + 395 + static int lg_g510_mkey_led_set(struct led_classdev *led_cdev, 396 + enum led_brightness brightness) 397 + { 398 + struct lg_g15_led *g15_led = 399 + container_of(led_cdev, struct lg_g15_led, cdev); 400 + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); 401 + u8 val, mask = 0; 402 + int i, ret; 403 + 404 + /* Ignore LED off on unregister / keyboard unplug */ 405 + if (led_cdev->flags & LED_UNREGISTERING) 406 + return 0; 407 + 408 + mutex_lock(&g15->mutex); 409 + 410 + for (i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; i++) { 411 + if (i == g15_led->led) 412 + val = brightness; 413 + else 414 + val = g15->leds[i].brightness; 415 + 416 + if (val) 417 + mask |= 0x80 >> (i - LG_G15_MACRO_PRESET1); 418 + } 419 + 420 + g15->transfer_buf[0] = LG_G510_FEATURE_M_KEYS_LEDS; 421 + g15->transfer_buf[1] = mask; 422 + 423 + ret = hid_hw_raw_request(g15->hdev, LG_G510_FEATURE_M_KEYS_LEDS, 424 + g15->transfer_buf, 2, 425 + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 426 + if (ret == 2) { 427 + /* Success */ 428 + g15_led->brightness = brightness; 429 + ret = 0; 430 + } else { 431 + hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret); 432 + ret = (ret < 0) ? ret : -EIO; 433 + } 434 + 435 + mutex_unlock(&g15->mutex); 436 + 437 + return ret; 438 + } 439 + 440 + /******** Generic LED functions ********/ 441 + static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15) 442 + { 443 + int ret; 444 + 445 + switch (g15->model) { 446 + case LG_G15: 447 + case LG_G15_V2: 448 + return lg_g15_update_led_brightness(g15); 449 + case LG_G510: 450 + case LG_G510_USB_AUDIO: 451 + ret = lg_g510_get_initial_led_brightness(g15, 0); 452 + if (ret) 453 + return ret; 454 + 455 + ret = lg_g510_get_initial_led_brightness(g15, 1); 456 + if (ret) 457 + return ret; 458 + 459 + return lg_g510_update_mkey_led_brightness(g15); 460 + } 461 + return -EINVAL; /* Never reached */ 462 + } 463 + 464 + /******** Input functions ********/ 465 + 466 + /* On the G15 Mark I Logitech has been quite creative with which bit is what */ 467 + static int lg_g15_event(struct lg_g15_data *g15, u8 *data, int size) 468 + { 469 + int i, val; 470 + 471 + /* G1 - G6 */ 472 + for (i = 0; i < 6; i++) { 473 + val = data[i + 1] & (1 << i); 474 + input_report_key(g15->input, KEY_MACRO1 + i, val); 475 + } 476 + /* G7 - G12 */ 477 + for (i = 0; i < 6; i++) { 478 + val = data[i + 2] & (1 << i); 479 + input_report_key(g15->input, KEY_MACRO7 + i, val); 480 + } 481 + /* G13 - G17 */ 482 + for (i = 0; i < 5; i++) { 483 + val = data[i + 1] & (4 << i); 484 + input_report_key(g15->input, KEY_MACRO13 + i, val); 485 + } 486 + /* G18 */ 487 + input_report_key(g15->input, KEY_MACRO18, data[8] & 0x40); 488 + 489 + /* M1 - M3 */ 490 + for (i = 0; i < 3; i++) { 491 + val = data[i + 6] & (1 << i); 492 + input_report_key(g15->input, KEY_MACRO_PRESET1 + i, val); 493 + } 494 + /* MR */ 495 + input_report_key(g15->input, KEY_MACRO_RECORD_START, data[7] & 0x40); 496 + 497 + /* Most left (round) button below the LCD */ 498 + input_report_key(g15->input, KEY_KBD_LCD_MENU1, data[8] & 0x80); 499 + /* 4 other buttons below the LCD */ 500 + for (i = 0; i < 4; i++) { 501 + val = data[i + 2] & 0x80; 502 + input_report_key(g15->input, KEY_KBD_LCD_MENU2 + i, val); 503 + } 504 + 505 + /* Backlight cycle button pressed? */ 506 + if (data[1] & 0x80) 507 + schedule_work(&g15->work); 508 + 509 + input_sync(g15->input); 510 + return 0; 511 + } 512 + 513 + static int lg_g15_v2_event(struct lg_g15_data *g15, u8 *data, int size) 514 + { 515 + int i, val; 516 + 517 + /* G1 - G6 */ 518 + for (i = 0; i < 6; i++) { 519 + val = data[1] & (1 << i); 520 + input_report_key(g15->input, KEY_MACRO1 + i, val); 521 + } 522 + 523 + /* M1 - M3 + MR */ 524 + input_report_key(g15->input, KEY_MACRO_PRESET1, data[1] & 0x40); 525 + input_report_key(g15->input, KEY_MACRO_PRESET2, data[1] & 0x80); 526 + input_report_key(g15->input, KEY_MACRO_PRESET3, data[2] & 0x20); 527 + input_report_key(g15->input, KEY_MACRO_RECORD_START, data[2] & 0x40); 528 + 529 + /* Round button to the left of the LCD */ 530 + input_report_key(g15->input, KEY_KBD_LCD_MENU1, data[2] & 0x80); 531 + /* 4 buttons below the LCD */ 532 + for (i = 0; i < 4; i++) { 533 + val = data[2] & (2 << i); 534 + input_report_key(g15->input, KEY_KBD_LCD_MENU2 + i, val); 535 + } 536 + 537 + /* Backlight cycle button pressed? */ 538 + if (data[2] & 0x01) 539 + schedule_work(&g15->work); 540 + 541 + input_sync(g15->input); 542 + return 0; 543 + } 544 + 545 + static int lg_g510_event(struct lg_g15_data *g15, u8 *data, int size) 546 + { 547 + bool game_mode_enabled; 548 + int i, val; 549 + 550 + /* G1 - G18 */ 551 + for (i = 0; i < 18; i++) { 552 + val = data[i / 8 + 1] & (1 << (i % 8)); 553 + input_report_key(g15->input, KEY_MACRO1 + i, val); 554 + } 555 + 556 + /* Game mode on/off slider */ 557 + game_mode_enabled = data[3] & 0x04; 558 + if (game_mode_enabled != g15->game_mode_enabled) { 559 + if (game_mode_enabled) 560 + hid_info(g15->hdev, "Game Mode enabled, Windows (super) key is disabled\n"); 561 + else 562 + hid_info(g15->hdev, "Game Mode disabled\n"); 563 + g15->game_mode_enabled = game_mode_enabled; 564 + } 565 + 566 + /* M1 - M3 */ 567 + for (i = 0; i < 3; i++) { 568 + val = data[3] & (0x10 << i); 569 + input_report_key(g15->input, KEY_MACRO_PRESET1 + i, val); 570 + } 571 + /* MR */ 572 + input_report_key(g15->input, KEY_MACRO_RECORD_START, data[3] & 0x80); 573 + 574 + /* LCD menu keys */ 575 + for (i = 0; i < 5; i++) { 576 + val = data[4] & (1 << i); 577 + input_report_key(g15->input, KEY_KBD_LCD_MENU1 + i, val); 578 + } 579 + 580 + /* Headphone Mute */ 581 + input_report_key(g15->input, KEY_MUTE, data[4] & 0x20); 582 + /* Microphone Mute */ 583 + input_report_key(g15->input, KEY_F20, data[4] & 0x40); 584 + 585 + input_sync(g15->input); 586 + return 0; 587 + } 588 + 589 + static int lg_g510_leds_event(struct lg_g15_data *g15, u8 *data, int size) 590 + { 591 + bool backlight_disabled; 592 + 593 + /* 594 + * The G510 ignores backlight updates when the backlight is turned off 595 + * through the light toggle button on the keyboard, to work around this 596 + * we queue a workitem to sync values when the backlight is turned on. 597 + */ 598 + backlight_disabled = data[1] & 0x04; 599 + if (!backlight_disabled) 600 + schedule_work(&g15->work); 601 + 602 + return 0; 603 + } 604 + 605 + static int lg_g15_raw_event(struct hid_device *hdev, struct hid_report *report, 606 + u8 *data, int size) 607 + { 608 + struct lg_g15_data *g15 = hid_get_drvdata(hdev); 609 + 610 + if (!g15) 611 + return 0; 612 + 613 + switch (g15->model) { 614 + case LG_G15: 615 + if (data[0] == 0x02 && size == 9) 616 + return lg_g15_event(g15, data, size); 617 + break; 618 + case LG_G15_V2: 619 + if (data[0] == 0x02 && size == 5) 620 + return lg_g15_v2_event(g15, data, size); 621 + break; 622 + case LG_G510: 623 + case LG_G510_USB_AUDIO: 624 + if (data[0] == 0x03 && size == 5) 625 + return lg_g510_event(g15, data, size); 626 + if (data[0] == 0x04 && size == 2) 627 + return lg_g510_leds_event(g15, data, size); 628 + break; 629 + } 630 + 631 + return 0; 632 + } 633 + 634 + static int lg_g15_input_open(struct input_dev *dev) 635 + { 636 + struct hid_device *hdev = input_get_drvdata(dev); 637 + 638 + return hid_hw_open(hdev); 639 + } 640 + 641 + static void lg_g15_input_close(struct input_dev *dev) 642 + { 643 + struct hid_device *hdev = input_get_drvdata(dev); 644 + 645 + hid_hw_close(hdev); 646 + } 647 + 648 + static int lg_g15_register_led(struct lg_g15_data *g15, int i) 649 + { 650 + const char * const led_names[] = { 651 + "g15::kbd_backlight", 652 + "g15::lcd_backlight", 653 + "g15::macro_preset1", 654 + "g15::macro_preset2", 655 + "g15::macro_preset3", 656 + "g15::macro_record", 657 + }; 658 + 659 + g15->leds[i].led = i; 660 + g15->leds[i].cdev.name = led_names[i]; 661 + 662 + switch (g15->model) { 663 + case LG_G15: 664 + case LG_G15_V2: 665 + g15->leds[i].cdev.brightness_set_blocking = lg_g15_led_set; 666 + g15->leds[i].cdev.brightness_get = lg_g15_led_get; 667 + if (i < LG_G15_BRIGHTNESS_MAX) { 668 + g15->leds[i].cdev.flags = LED_BRIGHT_HW_CHANGED; 669 + g15->leds[i].cdev.max_brightness = 2; 670 + } else { 671 + g15->leds[i].cdev.max_brightness = 1; 672 + } 673 + break; 674 + case LG_G510: 675 + case LG_G510_USB_AUDIO: 676 + switch (i) { 677 + case LG_G15_LCD_BRIGHTNESS: 678 + /* 679 + * The G510 does not have a separate LCD brightness, 680 + * but it does have a separate power-on (reset) value. 681 + */ 682 + g15->leds[i].cdev.name = "g15::power_on_backlight_val"; 683 + /* fall through */ 684 + case LG_G15_KBD_BRIGHTNESS: 685 + g15->leds[i].cdev.brightness_set_blocking = 686 + lg_g510_kbd_led_set; 687 + g15->leds[i].cdev.brightness_get = 688 + lg_g510_kbd_led_get; 689 + g15->leds[i].cdev.max_brightness = 255; 690 + g15->leds[i].cdev.groups = lg_g510_kbd_led_groups; 691 + break; 692 + default: 693 + g15->leds[i].cdev.brightness_set_blocking = 694 + lg_g510_mkey_led_set; 695 + g15->leds[i].cdev.brightness_get = 696 + lg_g510_mkey_led_get; 697 + g15->leds[i].cdev.max_brightness = 1; 698 + } 699 + break; 700 + } 701 + 702 + return devm_led_classdev_register(&g15->hdev->dev, &g15->leds[i].cdev); 703 + } 704 + 705 + static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) 706 + { 707 + u8 gkeys_settings_output_report = 0; 708 + u8 gkeys_settings_feature_report = 0; 709 + struct hid_report_enum *rep_enum; 710 + unsigned int connect_mask = 0; 711 + bool has_ff000000 = false; 712 + struct lg_g15_data *g15; 713 + struct input_dev *input; 714 + struct hid_report *rep; 715 + int ret, i, gkeys = 0; 716 + 717 + hdev->quirks |= HID_QUIRK_INPUT_PER_APP; 718 + 719 + ret = hid_parse(hdev); 720 + if (ret) 721 + return ret; 722 + 723 + /* 724 + * Some models have multiple interfaces, we want the interface with 725 + * with the f000.0000 application input report. 726 + */ 727 + rep_enum = &hdev->report_enum[HID_INPUT_REPORT]; 728 + list_for_each_entry(rep, &rep_enum->report_list, list) { 729 + if (rep->application == 0xff000000) 730 + has_ff000000 = true; 731 + } 732 + if (!has_ff000000) 733 + return hid_hw_start(hdev, HID_CONNECT_DEFAULT); 734 + 735 + g15 = devm_kzalloc(&hdev->dev, sizeof(*g15), GFP_KERNEL); 736 + if (!g15) 737 + return -ENOMEM; 738 + 739 + mutex_init(&g15->mutex); 740 + 741 + input = devm_input_allocate_device(&hdev->dev); 742 + if (!input) 743 + return -ENOMEM; 744 + 745 + g15->hdev = hdev; 746 + g15->model = id->driver_data; 747 + hid_set_drvdata(hdev, (void *)g15); 748 + 749 + switch (g15->model) { 750 + case LG_G15: 751 + INIT_WORK(&g15->work, lg_g15_leds_changed_work); 752 + /* 753 + * The G15 and G15 v2 use a separate usb-device (on a builtin 754 + * hub) which emulates a keyboard for the F1 - F12 emulation 755 + * on the G-keys, which we disable, rendering the emulated kbd 756 + * non-functional, so we do not let hid-input connect. 757 + */ 758 + connect_mask = HID_CONNECT_HIDRAW; 759 + gkeys_settings_output_report = 0x02; 760 + gkeys = 18; 761 + break; 762 + case LG_G15_V2: 763 + INIT_WORK(&g15->work, lg_g15_leds_changed_work); 764 + connect_mask = HID_CONNECT_HIDRAW; 765 + gkeys_settings_output_report = 0x02; 766 + gkeys = 6; 767 + break; 768 + case LG_G510: 769 + case LG_G510_USB_AUDIO: 770 + INIT_WORK(&g15->work, lg_g510_leds_sync_work); 771 + connect_mask = HID_CONNECT_HIDINPUT | HID_CONNECT_HIDRAW; 772 + gkeys_settings_feature_report = 0x01; 773 + gkeys = 18; 774 + break; 775 + } 776 + 777 + ret = hid_hw_start(hdev, connect_mask); 778 + if (ret) 779 + return ret; 780 + 781 + /* Tell the keyboard to stop sending F1-F12 + 1-6 for G1 - G18 */ 782 + if (gkeys_settings_output_report) { 783 + g15->transfer_buf[0] = gkeys_settings_output_report; 784 + memset(g15->transfer_buf + 1, 0, gkeys); 785 + /* 786 + * The kbd ignores our output report if we do not queue 787 + * an URB on the USB input endpoint first... 788 + */ 789 + ret = hid_hw_open(hdev); 790 + if (ret) 791 + goto error_hw_stop; 792 + ret = hid_hw_output_report(hdev, g15->transfer_buf, gkeys + 1); 793 + hid_hw_close(hdev); 794 + } 795 + 796 + if (gkeys_settings_feature_report) { 797 + g15->transfer_buf[0] = gkeys_settings_feature_report; 798 + memset(g15->transfer_buf + 1, 0, gkeys); 799 + ret = hid_hw_raw_request(g15->hdev, 800 + gkeys_settings_feature_report, 801 + g15->transfer_buf, gkeys + 1, 802 + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 803 + } 804 + 805 + if (ret < 0) { 806 + hid_err(hdev, "Error disabling keyboard emulation for the G-keys\n"); 807 + goto error_hw_stop; 808 + } 809 + 810 + /* Get initial brightness levels */ 811 + ret = lg_g15_get_initial_led_brightness(g15); 812 + if (ret) 813 + goto error_hw_stop; 814 + 815 + /* Setup and register input device */ 816 + input->name = "Logitech Gaming Keyboard Gaming Keys"; 817 + input->phys = hdev->phys; 818 + input->uniq = hdev->uniq; 819 + input->id.bustype = hdev->bus; 820 + input->id.vendor = hdev->vendor; 821 + input->id.product = hdev->product; 822 + input->id.version = hdev->version; 823 + input->dev.parent = &hdev->dev; 824 + input->open = lg_g15_input_open; 825 + input->close = lg_g15_input_close; 826 + 827 + /* G-keys */ 828 + for (i = 0; i < gkeys; i++) 829 + input_set_capability(input, EV_KEY, KEY_MACRO1 + i); 830 + 831 + /* M1 - M3 and MR keys */ 832 + for (i = 0; i < 3; i++) 833 + input_set_capability(input, EV_KEY, KEY_MACRO_PRESET1 + i); 834 + input_set_capability(input, EV_KEY, KEY_MACRO_RECORD_START); 835 + 836 + /* Keys below the LCD, intended for controlling a menu on the LCD */ 837 + for (i = 0; i < 5; i++) 838 + input_set_capability(input, EV_KEY, KEY_KBD_LCD_MENU1 + i); 839 + 840 + /* 841 + * On the G510 only report headphone and mic mute keys when *not* using 842 + * the builtin USB audio device. When the builtin audio is used these 843 + * keys directly toggle mute (and the LEDs) on/off. 844 + */ 845 + if (g15->model == LG_G510) { 846 + input_set_capability(input, EV_KEY, KEY_MUTE); 847 + /* Userspace expects F20 for micmute */ 848 + input_set_capability(input, EV_KEY, KEY_F20); 849 + } 850 + 851 + g15->input = input; 852 + input_set_drvdata(input, hdev); 853 + 854 + ret = input_register_device(input); 855 + if (ret) 856 + goto error_hw_stop; 857 + 858 + /* Register LED devices */ 859 + for (i = 0; i < LG_G15_LED_MAX; i++) { 860 + ret = lg_g15_register_led(g15, i); 861 + if (ret) 862 + goto error_hw_stop; 863 + } 864 + 865 + return 0; 866 + 867 + error_hw_stop: 868 + hid_hw_stop(hdev); 869 + return ret; 870 + } 871 + 872 + static const struct hid_device_id lg_g15_devices[] = { 873 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 874 + USB_DEVICE_ID_LOGITECH_G15_LCD), 875 + .driver_data = LG_G15 }, 876 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 877 + USB_DEVICE_ID_LOGITECH_G15_V2_LCD), 878 + .driver_data = LG_G15_V2 }, 879 + /* G510 without a headset plugged in */ 880 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 881 + USB_DEVICE_ID_LOGITECH_G510), 882 + .driver_data = LG_G510 }, 883 + /* G510 with headset plugged in / with extra USB audio interface */ 884 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 885 + USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO), 886 + .driver_data = LG_G510_USB_AUDIO }, 887 + { } 888 + }; 889 + MODULE_DEVICE_TABLE(hid, lg_g15_devices); 890 + 891 + static struct hid_driver lg_g15_driver = { 892 + .name = "lg-g15", 893 + .id_table = lg_g15_devices, 894 + .raw_event = lg_g15_raw_event, 895 + .probe = lg_g15_probe, 896 + }; 897 + module_hid_driver(lg_g15_driver); 898 + 899 + MODULE_LICENSE("GPL");
+3
drivers/hid/hid-logitech-hidpp.c
··· 1102 1102 ret = hidpp_send_fap_command_sync(hidpp, feature_index, 1103 1103 CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS, 1104 1104 NULL, 0, &response); 1105 + /* Ignore these intermittent errors */ 1106 + if (ret == HIDPP_ERROR_RESOURCE_ERROR) 1107 + return -EIO; 1105 1108 if (ret > 0) { 1106 1109 hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", 1107 1110 __func__, ret);
+1 -7
drivers/hid/hid-quirks.c
··· 94 94 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL }, 95 95 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL }, 96 96 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL }, 97 + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL }, 97 98 { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT }, 98 99 { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT }, 99 100 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT }, ··· 419 418 #endif 420 419 #if IS_ENABLED(CONFIG_HID_LCPOWER) 421 420 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000) }, 422 - #endif 423 - #if IS_ENABLED(CONFIG_HID_LED) 424 - { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, 425 - { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) }, 426 - { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_LUXAFOR) }, 427 - { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) }, 428 - { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, 429 421 #endif 430 422 #if IS_ENABLED(CONFIG_HID_LENOVO) 431 423 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
+2 -1
drivers/hid/hid-rmi.c
··· 744 744 { 745 745 struct rmi_data *hdata = hid_get_drvdata(hdev); 746 746 747 - if (hdata->device_flags & RMI_DEVICE) { 747 + if ((hdata->device_flags & RMI_DEVICE) 748 + && test_bit(RMI_STARTED, &hdata->flags)) { 748 749 clear_bit(RMI_STARTED, &hdata->flags); 749 750 cancel_work_sync(&hdata->reset_work); 750 751 rmi_unregister_transport_device(&hdata->xport);
+5 -5
drivers/hid/hidraw.c
··· 197 197 } 198 198 199 199 if (count > HID_MAX_BUFFER_SIZE) { 200 - printk(KERN_WARNING "hidraw: pid %d passed too large report\n", 201 - task_pid_nr(current)); 200 + hid_warn(dev, "pid %d passed too large report\n", 201 + task_pid_nr(current)); 202 202 ret = -EINVAL; 203 203 goto out; 204 204 } 205 205 206 206 if (count < 2) { 207 - printk(KERN_WARNING "hidraw: pid %d passed too short report\n", 208 - task_pid_nr(current)); 207 + hid_warn(dev, "pid %d passed too short report\n", 208 + task_pid_nr(current)); 209 209 ret = -EINVAL; 210 210 goto out; 211 211 } ··· 595 595 if (result < 0) 596 596 goto error_class; 597 597 598 - printk(KERN_INFO "hidraw: raw HID events driver (C) Jiri Kosina\n"); 598 + pr_info("raw HID events driver (C) Jiri Kosina\n"); 599 599 out: 600 600 return result; 601 601
+13 -3
drivers/hid/i2c-hid/i2c-hid-core.c
··· 48 48 #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) 49 49 #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) 50 50 #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) 51 + #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) 51 52 52 53 /* flags */ 53 54 #define I2C_HID_STARTED 0 ··· 158 157 159 158 bool irq_wake_enabled; 160 159 struct mutex reset_lock; 161 - 162 - unsigned long sleep_delay; 163 160 }; 164 161 165 162 static const struct i2c_hid_quirks { ··· 169 170 I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, 170 171 { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, 171 172 I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, 173 + { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, 174 + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, 172 175 { USB_VENDOR_ID_ELAN, HID_ANY_ID, 173 176 I2C_HID_QUIRK_BOGUS_IRQ }, 177 + { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, 178 + I2C_HID_QUIRK_RESET_ON_RESUME }, 174 179 { 0, 0 } 175 180 }; 176 181 ··· 1215 1212 * solves "incomplete reports" on Raydium devices 2386:3118 and 1216 1213 * 2386:4B33 and fixes various SIS touchscreens no longer sending 1217 1214 * data after a suspend/resume. 1215 + * 1216 + * However some ALPS touchpads generate IRQ storm without reset, so 1217 + * let's still reset them here. 1218 1218 */ 1219 - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); 1219 + if (ihid->quirks & I2C_HID_QUIRK_RESET_ON_RESUME) 1220 + ret = i2c_hid_hwreset(client); 1221 + else 1222 + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); 1223 + 1220 1224 if (ret) 1221 1225 return ret; 1222 1226
+1 -1
drivers/hid/intel-ish-hid/ishtp/hbm.c
··· 402 402 * @dev: ISHTP device instance 403 403 * @disconnect_req: disconnect request structure 404 404 * 405 - * Disconnect request bus message from the fw. Send diconnect response. 405 + * Disconnect request bus message from the fw. Send disconnect response. 406 406 */ 407 407 static void ishtp_hbm_fw_disconnect_req(struct ishtp_device *dev, 408 408 struct hbm_client_connect_request *disconnect_req)
+75
include/uapi/linux/input-event-codes.h
··· 650 650 #define KEY_DATA 0x277 651 651 #define KEY_ONSCREEN_KEYBOARD 0x278 652 652 653 + /* 654 + * Some keyboards have keys which do not have a defined meaning, these keys 655 + * are intended to be programmed / bound to macros by the user. For most 656 + * keyboards with these macro-keys the key-sequence to inject, or action to 657 + * take, is all handled by software on the host side. So from the kernel's 658 + * point of view these are just normal keys. 659 + * 660 + * The KEY_MACRO# codes below are intended for such keys, which may be labeled 661 + * e.g. G1-G18, or S1 - S30. The KEY_MACRO# codes MUST NOT be used for keys 662 + * where the marking on the key does indicate a defined meaning / purpose. 663 + * 664 + * The KEY_MACRO# codes MUST also NOT be used as fallback for when no existing 665 + * KEY_FOO define matches the marking / purpose. In this case a new KEY_FOO 666 + * define MUST be added. 667 + */ 668 + #define KEY_MACRO1 0x290 669 + #define KEY_MACRO2 0x291 670 + #define KEY_MACRO3 0x292 671 + #define KEY_MACRO4 0x293 672 + #define KEY_MACRO5 0x294 673 + #define KEY_MACRO6 0x295 674 + #define KEY_MACRO7 0x296 675 + #define KEY_MACRO8 0x297 676 + #define KEY_MACRO9 0x298 677 + #define KEY_MACRO10 0x299 678 + #define KEY_MACRO11 0x29a 679 + #define KEY_MACRO12 0x29b 680 + #define KEY_MACRO13 0x29c 681 + #define KEY_MACRO14 0x29d 682 + #define KEY_MACRO15 0x29e 683 + #define KEY_MACRO16 0x29f 684 + #define KEY_MACRO17 0x2a0 685 + #define KEY_MACRO18 0x2a1 686 + #define KEY_MACRO19 0x2a2 687 + #define KEY_MACRO20 0x2a3 688 + #define KEY_MACRO21 0x2a4 689 + #define KEY_MACRO22 0x2a5 690 + #define KEY_MACRO23 0x2a6 691 + #define KEY_MACRO24 0x2a7 692 + #define KEY_MACRO25 0x2a8 693 + #define KEY_MACRO26 0x2a9 694 + #define KEY_MACRO27 0x2aa 695 + #define KEY_MACRO28 0x2ab 696 + #define KEY_MACRO29 0x2ac 697 + #define KEY_MACRO30 0x2ad 698 + 699 + /* 700 + * Some keyboards with the macro-keys described above have some extra keys 701 + * for controlling the host-side software responsible for the macro handling: 702 + * -A macro recording start/stop key. Note that not all keyboards which emit 703 + * KEY_MACRO_RECORD_START will also emit KEY_MACRO_RECORD_STOP if 704 + * KEY_MACRO_RECORD_STOP is not advertised, then KEY_MACRO_RECORD_START 705 + * should be interpreted as a recording start/stop toggle; 706 + * -Keys for switching between different macro (pre)sets, either a key for 707 + * cycling through the configured presets or keys to directly select a preset. 708 + */ 709 + #define KEY_MACRO_RECORD_START 0x2b0 710 + #define KEY_MACRO_RECORD_STOP 0x2b1 711 + #define KEY_MACRO_PRESET_CYCLE 0x2b2 712 + #define KEY_MACRO_PRESET1 0x2b3 713 + #define KEY_MACRO_PRESET2 0x2b4 714 + #define KEY_MACRO_PRESET3 0x2b5 715 + 716 + /* 717 + * Some keyboards have a buildin LCD panel where the contents are controlled 718 + * by the host. Often these have a number of keys directly below the LCD 719 + * intended for controlling a menu shown on the LCD. These keys often don't 720 + * have any labeling so we just name them KEY_KBD_LCD_MENU# 721 + */ 722 + #define KEY_KBD_LCD_MENU1 0x2b8 723 + #define KEY_KBD_LCD_MENU2 0x2b9 724 + #define KEY_KBD_LCD_MENU3 0x2ba 725 + #define KEY_KBD_LCD_MENU4 0x2bb 726 + #define KEY_KBD_LCD_MENU5 0x2bc 727 + 653 728 #define BTN_TRIGGER_HAPPY 0x2c0 654 729 #define BTN_TRIGGER_HAPPY1 0x2c0 655 730 #define BTN_TRIGGER_HAPPY2 0x2c1