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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'platform-drivers-x86-v4.1-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86

Pull x86 platform driver updates from Darren Hart:
"This series includes significant updates to the toshiba_acpi driver
and the reintroduction of the dell-laptop keyboard backlight additions
I had to revert previously. Also included are various fixes for
typos, warnings, correctness, and minor bugs.

Specifics:

dell-laptop:
- add support for keyboard backlight.

toshiba_acpi:
- adaptive keyboard, hotkey, USB sleep and charge, and backlight
updates. Update sysfs documentation.

toshiba_bluetooth:
- fix enabling/disabling loop on recent devices

apple-gmux:
- lock iGP IO to protect from vgaarb changes

other:
- Fix typos, clear gcc warnings, clarify pr_* messages, correct
return types, update MAINTAINERS"

* tag 'platform-drivers-x86-v4.1-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: (25 commits)
toshiba_acpi: Do not register vendor backlight when acpi_video bl is available
MAINTAINERS: Add me on list of Dell laptop drivers
platform: x86: dell-laptop: Add support for keyboard backlight
Documentation/ABI: Update sysfs-driver-toshiba_acpi entry
toshiba_acpi: Fix pr_* messages from USB Sleep Functions
toshiba_acpi: Update and fix USB Sleep and Charge modes
wmi: Use bool function return values of true/false not 1/0
toshiba_bluetooth: Fix enabling/disabling loop on recent devices
toshiba_bluetooth: Clean up *_add function and disable BT device at removal
toshiba_bluetooth: Add three new functions to the driver
toshiba_acpi: Fix the enabling of the Special Functions
toshiba_acpi: Use the Hotkey Event Type function for keymap choosing
toshiba_acpi: Add Hotkey Event Type function and definitions
x86/wmi: delete unused wmi_data_lock mutex causing gcc warning
apple-gmux: lock iGP IO to protect from vgaarb changes
MAINTAINERS: Add missing Toshiba devices and add myself as maintainer
toshiba_acpi: Update events in toshiba_acpi_notify
intel-oaktrail: Fix trivial typo in comment
thinkpad_acpi: off by one in adaptive_keyboard_hotkey_notify_hotkey()
thinkpad_acpi: signedness bugs getting current_mode
...

+1839 -219
+80 -13
Documentation/ABI/testing/sysfs-driver-toshiba_acpi
··· 8 8 * 0x2 -> AUTO (also called TIMER) 9 9 * 0x8 -> ON 10 10 * 0x10 -> OFF 11 - Note that the kernel 3.16 onwards this file accepts all listed 11 + Note that from kernel 3.16 onwards this file accepts all listed 12 12 parameters, kernel 3.15 only accepts the first two (FN-Z and 13 13 AUTO). 14 + Also note that toggling this value on type 1 devices, requires 15 + a reboot for changes to take effect. 14 16 Users: KToshiba 15 17 16 18 What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_backlight_timeout ··· 69 67 * 2 -> Type 2, supporting modes TIMER, ON and OFF 70 68 Users: KToshiba 71 69 70 + What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/usb_sleep_charge 71 + Date: January 23, 2015 72 + KernelVersion: 4.0 73 + Contact: Azael Avalos <coproscefalo@gmail.com> 74 + Description: This file controls the USB Sleep & Charge charging mode, which 75 + can be: 76 + * 0 -> Disabled (0x00) 77 + * 1 -> Alternate (0x09) 78 + * 2 -> Auto (0x21) 79 + * 3 -> Typical (0x11) 80 + Note that from kernel 4.1 onwards this file accepts all listed 81 + values, kernel 4.0 only supports the first three. 82 + Note that this feature only works when connected to power, if 83 + you want to use it under battery, see the entry named 84 + "sleep_functions_on_battery" 85 + Users: KToshiba 86 + 87 + What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/sleep_functions_on_battery 88 + Date: January 23, 2015 89 + KernelVersion: 4.0 90 + Contact: Azael Avalos <coproscefalo@gmail.com> 91 + Description: This file controls the USB Sleep Functions under battery, and 92 + set the level at which point they will be disabled, accepted 93 + values can be: 94 + * 0 -> Disabled 95 + * 1-100 -> Battery level to disable sleep functions 96 + Currently it prints two values, the first one indicates if the 97 + feature is enabled or disabled, while the second one shows the 98 + current battery level set. 99 + Note that when the value is set to disabled, the sleep function 100 + will only work when connected to power. 101 + Users: KToshiba 102 + 103 + What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/usb_rapid_charge 104 + Date: January 23, 2015 105 + KernelVersion: 4.0 106 + Contact: Azael Avalos <coproscefalo@gmail.com> 107 + Description: This file controls the USB Rapid Charge state, which can be: 108 + * 0 -> Disabled 109 + * 1 -> Enabled 110 + Note that toggling this value requires a reboot for changes to 111 + take effect. 112 + Users: KToshiba 113 + 114 + What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/usb_sleep_music 115 + Date: January 23, 2015 116 + KernelVersion: 4.0 117 + Contact: Azael Avalos <coproscefalo@gmail.com> 118 + Description: This file controls the Sleep & Music state, which values can be: 119 + * 0 -> Disabled 120 + * 1 -> Enabled 121 + Note that this feature only works when connected to power, if 122 + you want to use it under battery, see the entry named 123 + "sleep_functions_on_battery" 124 + Users: KToshiba 125 + 72 126 What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/version 73 - Date: February, 2015 74 - KernelVersion: 3.20 127 + Date: February 12, 2015 128 + KernelVersion: 4.0 75 129 Contact: Azael Avalos <coproscefalo@gmail.com> 76 130 Description: This file shows the current version of the driver 131 + Users: KToshiba 77 132 78 133 What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/fan 79 - Date: February, 2015 80 - KernelVersion: 3.20 134 + Date: February 12, 2015 135 + KernelVersion: 4.0 81 136 Contact: Azael Avalos <coproscefalo@gmail.com> 82 137 Description: This file controls the state of the internal fan, valid 83 138 values are: ··· 142 83 * 1 -> ON 143 84 144 85 What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/kbd_function_keys 145 - Date: February, 2015 146 - KernelVersion: 3.20 86 + Date: February 12, 2015 87 + KernelVersion: 4.0 147 88 Contact: Azael Avalos <coproscefalo@gmail.com> 148 89 Description: This file controls the Special Functions (hotkeys) operation 149 90 mode, valid values are: ··· 153 94 and the hotkeys are accessed via FN-F{1-12}. 154 95 In the "Special Functions" mode, the F{1-12} keys trigger the 155 96 hotkey and the F{1-12} keys are accessed via FN-F{1-12}. 97 + Note that toggling this value requires a reboot for changes to 98 + take effect. 99 + Users: KToshiba 156 100 157 101 What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/panel_power_on 158 - Date: February, 2015 159 - KernelVersion: 3.20 102 + Date: February 12, 2015 103 + KernelVersion: 4.0 160 104 Contact: Azael Avalos <coproscefalo@gmail.com> 161 105 Description: This file controls whether the laptop should turn ON whenever 162 106 the LID is opened, valid values are: 163 107 * 0 -> Disabled 164 108 * 1 -> Enabled 109 + Note that toggling this value requires a reboot for changes to 110 + take effect. 111 + Users: KToshiba 165 112 166 113 What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/usb_three 167 - Date: February, 2015 168 - KernelVersion: 3.20 114 + Date: February 12, 2015 115 + KernelVersion: 4.0 169 116 Contact: Azael Avalos <coproscefalo@gmail.com> 170 - Description: This file controls whether the USB 3 functionality, valid 171 - values are: 117 + Description: This file controls the USB 3 functionality, valid values are: 172 118 * 0 -> Disabled (Acts as a regular USB 2) 173 119 * 1 -> Enabled (Full USB 3 functionality) 120 + Note that toggling this value requires a reboot for changes to 121 + take effect. 122 + Users: KToshiba
+69
Documentation/ABI/testing/sysfs-platform-dell-laptop
··· 1 + What: /sys/class/leds/dell::kbd_backlight/als_enabled 2 + Date: December 2014 3 + KernelVersion: 3.19 4 + Contact: Gabriele Mazzotta <gabriele.mzt@gmail.com>, 5 + Pali Rohár <pali.rohar@gmail.com> 6 + Description: 7 + This file allows to control the automatic keyboard 8 + illumination mode on some systems that have an ambient 9 + light sensor. Write 1 to this file to enable the auto 10 + mode, 0 to disable it. 11 + 12 + What: /sys/class/leds/dell::kbd_backlight/als_setting 13 + Date: December 2014 14 + KernelVersion: 3.19 15 + Contact: Gabriele Mazzotta <gabriele.mzt@gmail.com>, 16 + Pali Rohár <pali.rohar@gmail.com> 17 + Description: 18 + This file allows to specifiy the on/off threshold value, 19 + as reported by the ambient light sensor. 20 + 21 + What: /sys/class/leds/dell::kbd_backlight/start_triggers 22 + Date: December 2014 23 + KernelVersion: 3.19 24 + Contact: Gabriele Mazzotta <gabriele.mzt@gmail.com>, 25 + Pali Rohár <pali.rohar@gmail.com> 26 + Description: 27 + This file allows to control the input triggers that 28 + turn on the keyboard backlight illumination that is 29 + disabled because of inactivity. 30 + Read the file to see the triggers available. The ones 31 + enabled are preceded by '+', those disabled by '-'. 32 + 33 + To enable a trigger, write its name preceded by '+' to 34 + this file. To disable a trigger, write its name preceded 35 + by '-' instead. 36 + 37 + For example, to enable the keyboard as trigger run: 38 + echo +keyboard > /sys/class/leds/dell::kbd_backlight/start_triggers 39 + To disable it: 40 + echo -keyboard > /sys/class/leds/dell::kbd_backlight/start_triggers 41 + 42 + Note that not all the available triggers can be configured. 43 + 44 + What: /sys/class/leds/dell::kbd_backlight/stop_timeout 45 + Date: December 2014 46 + KernelVersion: 3.19 47 + Contact: Gabriele Mazzotta <gabriele.mzt@gmail.com>, 48 + Pali Rohár <pali.rohar@gmail.com> 49 + Description: 50 + This file allows to specify the interval after which the 51 + keyboard illumination is disabled because of inactivity. 52 + The timeouts are expressed in seconds, minutes, hours and 53 + days, for which the symbols are 's', 'm', 'h' and 'd' 54 + respectively. 55 + 56 + To configure the timeout, write to this file a value along 57 + with any the above units. If no unit is specified, the value 58 + is assumed to be expressed in seconds. 59 + 60 + For example, to set the timeout to 10 minutes run: 61 + echo 10m > /sys/class/leds/dell::kbd_backlight/stop_timeout 62 + 63 + Note that when this file is read, the returned value might be 64 + expressed in a different unit than the one used when the timeout 65 + was set. 66 + 67 + Also note that only some timeouts are supported and that 68 + some systems might fall back to a specific timeout in case 69 + an invalid timeout is written to this file.
+18
Documentation/laptops/thinkpad-acpi.txt
··· 1355 1355 rfkill controller switch "tpacpi_uwb_sw": refer to 1356 1356 Documentation/rfkill.txt for details. 1357 1357 1358 + Adaptive keyboard 1359 + ----------------- 1360 + 1361 + sysfs device attribute: adaptive_kbd_mode 1362 + 1363 + This sysfs attribute controls the keyboard "face" that will be shown on the 1364 + Lenovo X1 Carbon 2nd gen (2014)'s adaptive keyboard. The value can be read 1365 + and set. 1366 + 1367 + 1 = Home mode 1368 + 2 = Web-browser mode 1369 + 3 = Web-conference mode 1370 + 4 = Function mode 1371 + 5 = Layflat mode 1372 + 1373 + For more details about which buttons will appear depending on the mode, please 1374 + review the laptop's user guide: 1375 + http://www.lenovo.com/shop/americas/content/user_guides/x1carbon_2_ug_en.pdf 1358 1376 1359 1377 Multiple Commands, Module Parameters 1360 1378 ------------------------------------
+21 -1
MAINTAINERS
··· 3066 3066 3067 3067 DELL LAPTOP DRIVER 3068 3068 M: Matthew Garrett <mjg59@srcf.ucam.org> 3069 + M: Pali Rohár <pali.rohar@gmail.com> 3069 3070 L: platform-driver-x86@vger.kernel.org 3070 3071 S: Maintained 3071 3072 F: drivers/platform/x86/dell-laptop.c 3073 + 3074 + DELL LAPTOP FREEFALL DRIVER 3075 + M: Pali Rohár <pali.rohar@gmail.com> 3076 + S: Maintained 3077 + F: drivers/platform/x86/dell-smo8800.c 3072 3078 3073 3079 DELL LAPTOP SMM DRIVER 3074 3080 M: Guenter Roeck <linux@roeck-us.net> ··· 3090 3084 3091 3085 DELL WMI EXTRAS DRIVER 3092 3086 M: Matthew Garrett <mjg59@srcf.ucam.org> 3087 + M: Pali Rohár <pali.rohar@gmail.com> 3093 3088 S: Maintained 3094 3089 F: drivers/platform/x86/dell-wmi.c 3095 3090 ··· 9956 9949 F: drivers/platform/x86/topstar-laptop.c 9957 9950 9958 9951 TOSHIBA ACPI EXTRAS DRIVER 9952 + M: Azael Avalos <coproscefalo@gmail.com> 9959 9953 L: platform-driver-x86@vger.kernel.org 9960 - S: Orphan 9954 + S: Maintained 9961 9955 F: drivers/platform/x86/toshiba_acpi.c 9956 + 9957 + TOSHIBA BLUETOOTH DRIVER 9958 + M: Azael Avalos <coproscefalo@gmail.com> 9959 + L: platform-driver-x86@vger.kernel.org 9960 + S: Maintained 9961 + F: drivers/platform/x86/toshiba_bluetooth.c 9962 + 9963 + TOSHIBA HDD ACTIVE PROTECTION SENSOR DRIVER 9964 + M: Azael Avalos <coproscefalo@gmail.com> 9965 + L: platform-driver-x86@vger.kernel.org 9966 + S: Maintained 9967 + F: drivers/platform/x86/toshiba_haps.c 9962 9968 9963 9969 TOSHIBA SMM DRIVER 9964 9970 M: Jonathan Buzzard <jonathan@buzzard.org.uk>
+1
drivers/platform/x86/Kconfig
··· 614 614 depends on INPUT 615 615 depends on RFKILL || RFKILL = n 616 616 depends on SERIO_I8042 || SERIO_I8042 = n 617 + depends on ACPI_VIDEO || ACPI_VIDEO = n 617 618 select INPUT_POLLDEV 618 619 select INPUT_SPARSEKMAP 619 620 ---help---
+47 -1
drivers/platform/x86/apple-gmux.c
··· 22 22 #include <linux/delay.h> 23 23 #include <linux/pci.h> 24 24 #include <linux/vga_switcheroo.h> 25 + #include <linux/vgaarb.h> 25 26 #include <acpi/video.h> 26 27 #include <asm/io.h> 27 28 ··· 32 31 bool indexed; 33 32 struct mutex index_lock; 34 33 34 + struct pci_dev *pdev; 35 35 struct backlight_device *bdev; 36 36 37 37 /* switcheroo data */ ··· 417 415 return 0; 418 416 } 419 417 418 + static struct pci_dev *gmux_get_io_pdev(void) 419 + { 420 + struct pci_dev *pdev = NULL; 421 + 422 + while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev))) { 423 + u16 cmd; 424 + 425 + pci_read_config_word(pdev, PCI_COMMAND, &cmd); 426 + if (!(cmd & PCI_COMMAND_IO)) 427 + continue; 428 + 429 + return pdev; 430 + } 431 + 432 + return NULL; 433 + } 434 + 420 435 static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) 421 436 { 422 437 struct apple_gmux_data *gmux_data; ··· 444 425 int ret = -ENXIO; 445 426 acpi_status status; 446 427 unsigned long long gpe; 428 + struct pci_dev *pdev = NULL; 447 429 448 430 if (apple_gmux_data) 449 431 return -EBUSY; ··· 495 475 ver_minor = (version >> 16) & 0xff; 496 476 ver_release = (version >> 8) & 0xff; 497 477 } else { 498 - pr_info("gmux device not present\n"); 478 + pr_info("gmux device not present or IO disabled\n"); 499 479 ret = -ENODEV; 500 480 goto err_release; 501 481 } 502 482 } 503 483 pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, 504 484 ver_release, (gmux_data->indexed ? "indexed" : "classic")); 485 + 486 + /* 487 + * Apple systems with gmux are EFI based and normally don't use 488 + * VGA. In addition changing IO+MEM ownership between IGP and dGPU 489 + * disables IO/MEM used for backlight control on some systems. 490 + * Lock IO+MEM to GPU with active IO to prevent switch. 491 + */ 492 + pdev = gmux_get_io_pdev(); 493 + if (pdev && vga_tryget(pdev, 494 + VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM)) { 495 + pr_err("IO+MEM vgaarb-locking for PCI:%s failed\n", 496 + pci_name(pdev)); 497 + ret = -EBUSY; 498 + goto err_release; 499 + } else if (pdev) 500 + pr_info("locked IO for PCI:%s\n", pci_name(pdev)); 501 + gmux_data->pdev = pdev; 505 502 506 503 memset(&props, 0, sizeof(props)); 507 504 props.type = BACKLIGHT_PLATFORM; ··· 611 574 err_notify: 612 575 backlight_device_unregister(bdev); 613 576 err_release: 577 + if (gmux_data->pdev) 578 + vga_put(gmux_data->pdev, 579 + VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM); 580 + pci_dev_put(pdev); 614 581 release_region(gmux_data->iostart, gmux_data->iolen); 615 582 err_free: 616 583 kfree(gmux_data); ··· 634 593 &gmux_notify_handler); 635 594 } 636 595 596 + if (gmux_data->pdev) { 597 + vga_put(gmux_data->pdev, 598 + VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM); 599 + pci_dev_put(gmux_data->pdev); 600 + } 637 601 backlight_device_unregister(gmux_data->bdev); 638 602 639 603 release_region(gmux_data->iostart, gmux_data->iolen);
+1083 -6
drivers/platform/x86/dell-laptop.c
··· 2 2 * Driver for Dell laptop extras 3 3 * 4 4 * Copyright (c) Red Hat <mjg@redhat.com> 5 + * Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com> 6 + * Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com> 5 7 * 6 - * Based on documentation in the libsmbios package, Copyright (C) 2005 Dell 7 - * Inc. 8 + * Based on documentation in the libsmbios package: 9 + * Copyright (C) 2005-2014 Dell Inc. 8 10 * 9 11 * This program is free software; you can redistribute it and/or modify 10 12 * it under the terms of the GNU General Public License version 2 as ··· 34 32 #include "../../firmware/dcdbas.h" 35 33 36 34 #define BRIGHTNESS_TOKEN 0x7d 35 + #define KBD_LED_OFF_TOKEN 0x01E1 36 + #define KBD_LED_ON_TOKEN 0x01E2 37 + #define KBD_LED_AUTO_TOKEN 0x01E3 38 + #define KBD_LED_AUTO_25_TOKEN 0x02EA 39 + #define KBD_LED_AUTO_50_TOKEN 0x02EB 40 + #define KBD_LED_AUTO_75_TOKEN 0x02EC 41 + #define KBD_LED_AUTO_100_TOKEN 0x02F6 37 42 38 43 /* This structure will be modified by the firmware when we enter 39 44 * system management mode, hence the volatiles */ ··· 71 62 72 63 struct quirk_entry { 73 64 u8 touchpad_led; 65 + 66 + int needs_kbd_timeouts; 67 + /* 68 + * Ordered list of timeouts expressed in seconds. 69 + * The list must end with -1 70 + */ 71 + int kbd_timeouts[]; 74 72 }; 75 73 76 74 static struct quirk_entry *quirks; ··· 91 75 quirks = dmi->driver_data; 92 76 return 1; 93 77 } 78 + 79 + /* 80 + * These values come from Windows utility provided by Dell. If any other value 81 + * is used then BIOS silently set timeout to 0 without any error message. 82 + */ 83 + static struct quirk_entry quirk_dell_xps13_9333 = { 84 + .needs_kbd_timeouts = 1, 85 + .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 }, 86 + }; 94 87 95 88 static int da_command_address; 96 89 static int da_command_code; ··· 292 267 }, 293 268 .driver_data = &quirk_dell_vostro_v130, 294 269 }, 270 + { 271 + .callback = dmi_matched, 272 + .ident = "Dell XPS13 9333", 273 + .matches = { 274 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 275 + DMI_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"), 276 + }, 277 + .driver_data = &quirk_dell_xps13_9333, 278 + }, 295 279 { } 296 280 }; 297 281 ··· 365 331 } 366 332 } 367 333 368 - static int find_token_location(int tokenid) 334 + static int find_token_id(int tokenid) 369 335 { 370 336 int i; 337 + 371 338 for (i = 0; i < da_num_tokens; i++) { 372 339 if (da_tokens[i].tokenID == tokenid) 373 - return da_tokens[i].location; 340 + return i; 374 341 } 375 342 376 343 return -1; 344 + } 345 + 346 + static int find_token_location(int tokenid) 347 + { 348 + int id; 349 + 350 + id = find_token_id(tokenid); 351 + if (id == -1) 352 + return -1; 353 + 354 + return da_tokens[id].location; 377 355 } 378 356 379 357 static struct calling_interface_buffer * ··· 406 360 dcdbas_smi_request(&command); 407 361 408 362 return buffer; 363 + } 364 + 365 + static inline int dell_smi_error(int value) 366 + { 367 + switch (value) { 368 + case 0: /* Completed successfully */ 369 + return 0; 370 + case -1: /* Completed with error */ 371 + return -EIO; 372 + case -2: /* Function not supported */ 373 + return -ENXIO; 374 + default: /* Unknown error */ 375 + return -EINVAL; 376 + } 409 377 } 410 378 411 379 /* Derived from information in DellWirelessCtl.cpp: ··· 776 716 else 777 717 dell_send_request(buffer, 1, 1); 778 718 779 - out: 719 + out: 780 720 release_buffer(); 781 721 return ret; 782 722 } ··· 800 740 801 741 ret = buffer->output[1]; 802 742 803 - out: 743 + out: 804 744 release_buffer(); 805 745 return ret; 806 746 } ··· 847 787 static void touchpad_led_exit(void) 848 788 { 849 789 led_classdev_unregister(&touchpad_led); 790 + } 791 + 792 + /* 793 + * Derived from information in smbios-keyboard-ctl: 794 + * 795 + * cbClass 4 796 + * cbSelect 11 797 + * Keyboard illumination 798 + * cbArg1 determines the function to be performed 799 + * 800 + * cbArg1 0x0 = Get Feature Information 801 + * cbRES1 Standard return codes (0, -1, -2) 802 + * cbRES2, word0 Bitmap of user-selectable modes 803 + * bit 0 Always off (All systems) 804 + * bit 1 Always on (Travis ATG, Siberia) 805 + * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) 806 + * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off 807 + * bit 4 Auto: Input-activity-based On; input-activity based Off 808 + * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off 809 + * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off 810 + * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off 811 + * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off 812 + * bits 9-15 Reserved for future use 813 + * cbRES2, byte2 Reserved for future use 814 + * cbRES2, byte3 Keyboard illumination type 815 + * 0 Reserved 816 + * 1 Tasklight 817 + * 2 Backlight 818 + * 3-255 Reserved for future use 819 + * cbRES3, byte0 Supported auto keyboard illumination trigger bitmap. 820 + * bit 0 Any keystroke 821 + * bit 1 Touchpad activity 822 + * bit 2 Pointing stick 823 + * bit 3 Any mouse 824 + * bits 4-7 Reserved for future use 825 + * cbRES3, byte1 Supported timeout unit bitmap 826 + * bit 0 Seconds 827 + * bit 1 Minutes 828 + * bit 2 Hours 829 + * bit 3 Days 830 + * bits 4-7 Reserved for future use 831 + * cbRES3, byte2 Number of keyboard light brightness levels 832 + * cbRES4, byte0 Maximum acceptable seconds value (0 if seconds not supported). 833 + * cbRES4, byte1 Maximum acceptable minutes value (0 if minutes not supported). 834 + * cbRES4, byte2 Maximum acceptable hours value (0 if hours not supported). 835 + * cbRES4, byte3 Maximum acceptable days value (0 if days not supported) 836 + * 837 + * cbArg1 0x1 = Get Current State 838 + * cbRES1 Standard return codes (0, -1, -2) 839 + * cbRES2, word0 Bitmap of current mode state 840 + * bit 0 Always off (All systems) 841 + * bit 1 Always on (Travis ATG, Siberia) 842 + * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) 843 + * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off 844 + * bit 4 Auto: Input-activity-based On; input-activity based Off 845 + * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off 846 + * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off 847 + * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off 848 + * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off 849 + * bits 9-15 Reserved for future use 850 + * Note: Only One bit can be set 851 + * cbRES2, byte2 Currently active auto keyboard illumination triggers. 852 + * bit 0 Any keystroke 853 + * bit 1 Touchpad activity 854 + * bit 2 Pointing stick 855 + * bit 3 Any mouse 856 + * bits 4-7 Reserved for future use 857 + * cbRES2, byte3 Current Timeout 858 + * bits 7:6 Timeout units indicator: 859 + * 00b Seconds 860 + * 01b Minutes 861 + * 10b Hours 862 + * 11b Days 863 + * bits 5:0 Timeout value (0-63) in sec/min/hr/day 864 + * NOTE: A value of 0 means always on (no timeout) if any bits of RES3 byte 865 + * are set upon return from the [Get feature information] call. 866 + * cbRES3, byte0 Current setting of ALS value that turns the light on or off. 867 + * cbRES3, byte1 Current ALS reading 868 + * cbRES3, byte2 Current keyboard light level. 869 + * 870 + * cbArg1 0x2 = Set New State 871 + * cbRES1 Standard return codes (0, -1, -2) 872 + * cbArg2, word0 Bitmap of current mode state 873 + * bit 0 Always off (All systems) 874 + * bit 1 Always on (Travis ATG, Siberia) 875 + * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) 876 + * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off 877 + * bit 4 Auto: Input-activity-based On; input-activity based Off 878 + * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off 879 + * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off 880 + * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off 881 + * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off 882 + * bits 9-15 Reserved for future use 883 + * Note: Only One bit can be set 884 + * cbArg2, byte2 Desired auto keyboard illumination triggers. Must remain inactive to allow 885 + * keyboard to turn off automatically. 886 + * bit 0 Any keystroke 887 + * bit 1 Touchpad activity 888 + * bit 2 Pointing stick 889 + * bit 3 Any mouse 890 + * bits 4-7 Reserved for future use 891 + * cbArg2, byte3 Desired Timeout 892 + * bits 7:6 Timeout units indicator: 893 + * 00b Seconds 894 + * 01b Minutes 895 + * 10b Hours 896 + * 11b Days 897 + * bits 5:0 Timeout value (0-63) in sec/min/hr/day 898 + * cbArg3, byte0 Desired setting of ALS value that turns the light on or off. 899 + * cbArg3, byte2 Desired keyboard light level. 900 + */ 901 + 902 + 903 + enum kbd_timeout_unit { 904 + KBD_TIMEOUT_SECONDS = 0, 905 + KBD_TIMEOUT_MINUTES, 906 + KBD_TIMEOUT_HOURS, 907 + KBD_TIMEOUT_DAYS, 908 + }; 909 + 910 + enum kbd_mode_bit { 911 + KBD_MODE_BIT_OFF = 0, 912 + KBD_MODE_BIT_ON, 913 + KBD_MODE_BIT_ALS, 914 + KBD_MODE_BIT_TRIGGER_ALS, 915 + KBD_MODE_BIT_TRIGGER, 916 + KBD_MODE_BIT_TRIGGER_25, 917 + KBD_MODE_BIT_TRIGGER_50, 918 + KBD_MODE_BIT_TRIGGER_75, 919 + KBD_MODE_BIT_TRIGGER_100, 920 + }; 921 + 922 + #define kbd_is_als_mode_bit(bit) \ 923 + ((bit) == KBD_MODE_BIT_ALS || (bit) == KBD_MODE_BIT_TRIGGER_ALS) 924 + #define kbd_is_trigger_mode_bit(bit) \ 925 + ((bit) >= KBD_MODE_BIT_TRIGGER_ALS && (bit) <= KBD_MODE_BIT_TRIGGER_100) 926 + #define kbd_is_level_mode_bit(bit) \ 927 + ((bit) >= KBD_MODE_BIT_TRIGGER_25 && (bit) <= KBD_MODE_BIT_TRIGGER_100) 928 + 929 + struct kbd_info { 930 + u16 modes; 931 + u8 type; 932 + u8 triggers; 933 + u8 levels; 934 + u8 seconds; 935 + u8 minutes; 936 + u8 hours; 937 + u8 days; 938 + }; 939 + 940 + struct kbd_state { 941 + u8 mode_bit; 942 + u8 triggers; 943 + u8 timeout_value; 944 + u8 timeout_unit; 945 + u8 als_setting; 946 + u8 als_value; 947 + u8 level; 948 + }; 949 + 950 + static const int kbd_tokens[] = { 951 + KBD_LED_OFF_TOKEN, 952 + KBD_LED_AUTO_25_TOKEN, 953 + KBD_LED_AUTO_50_TOKEN, 954 + KBD_LED_AUTO_75_TOKEN, 955 + KBD_LED_AUTO_100_TOKEN, 956 + KBD_LED_ON_TOKEN, 957 + }; 958 + 959 + static u16 kbd_token_bits; 960 + 961 + static struct kbd_info kbd_info; 962 + static bool kbd_als_supported; 963 + static bool kbd_triggers_supported; 964 + 965 + static u8 kbd_mode_levels[16]; 966 + static int kbd_mode_levels_count; 967 + 968 + static u8 kbd_previous_level; 969 + static u8 kbd_previous_mode_bit; 970 + 971 + static bool kbd_led_present; 972 + 973 + /* 974 + * NOTE: there are three ways to set the keyboard backlight level. 975 + * First, via kbd_state.mode_bit (assigning KBD_MODE_BIT_TRIGGER_* value). 976 + * Second, via kbd_state.level (assigning numerical value <= kbd_info.levels). 977 + * Third, via SMBIOS tokens (KBD_LED_* in kbd_tokens) 978 + * 979 + * There are laptops which support only one of these methods. If we want to 980 + * support as many machines as possible we need to implement all three methods. 981 + * The first two methods use the kbd_state structure. The third uses SMBIOS 982 + * tokens. If kbd_info.levels == 0, the machine does not support setting the 983 + * keyboard backlight level via kbd_state.level. 984 + */ 985 + 986 + static int kbd_get_info(struct kbd_info *info) 987 + { 988 + u8 units; 989 + int ret; 990 + 991 + get_buffer(); 992 + 993 + buffer->input[0] = 0x0; 994 + dell_send_request(buffer, 4, 11); 995 + ret = buffer->output[0]; 996 + 997 + if (ret) { 998 + ret = dell_smi_error(ret); 999 + goto out; 1000 + } 1001 + 1002 + info->modes = buffer->output[1] & 0xFFFF; 1003 + info->type = (buffer->output[1] >> 24) & 0xFF; 1004 + info->triggers = buffer->output[2] & 0xFF; 1005 + units = (buffer->output[2] >> 8) & 0xFF; 1006 + info->levels = (buffer->output[2] >> 16) & 0xFF; 1007 + 1008 + if (units & BIT(0)) 1009 + info->seconds = (buffer->output[3] >> 0) & 0xFF; 1010 + if (units & BIT(1)) 1011 + info->minutes = (buffer->output[3] >> 8) & 0xFF; 1012 + if (units & BIT(2)) 1013 + info->hours = (buffer->output[3] >> 16) & 0xFF; 1014 + if (units & BIT(3)) 1015 + info->days = (buffer->output[3] >> 24) & 0xFF; 1016 + 1017 + out: 1018 + release_buffer(); 1019 + return ret; 1020 + } 1021 + 1022 + static unsigned int kbd_get_max_level(void) 1023 + { 1024 + if (kbd_info.levels != 0) 1025 + return kbd_info.levels; 1026 + if (kbd_mode_levels_count > 0) 1027 + return kbd_mode_levels_count - 1; 1028 + return 0; 1029 + } 1030 + 1031 + static int kbd_get_level(struct kbd_state *state) 1032 + { 1033 + int i; 1034 + 1035 + if (kbd_info.levels != 0) 1036 + return state->level; 1037 + 1038 + if (kbd_mode_levels_count > 0) { 1039 + for (i = 0; i < kbd_mode_levels_count; ++i) 1040 + if (kbd_mode_levels[i] == state->mode_bit) 1041 + return i; 1042 + return 0; 1043 + } 1044 + 1045 + return -EINVAL; 1046 + } 1047 + 1048 + static int kbd_set_level(struct kbd_state *state, u8 level) 1049 + { 1050 + if (kbd_info.levels != 0) { 1051 + if (level != 0) 1052 + kbd_previous_level = level; 1053 + if (state->level == level) 1054 + return 0; 1055 + state->level = level; 1056 + if (level != 0 && state->mode_bit == KBD_MODE_BIT_OFF) 1057 + state->mode_bit = kbd_previous_mode_bit; 1058 + else if (level == 0 && state->mode_bit != KBD_MODE_BIT_OFF) { 1059 + kbd_previous_mode_bit = state->mode_bit; 1060 + state->mode_bit = KBD_MODE_BIT_OFF; 1061 + } 1062 + return 0; 1063 + } 1064 + 1065 + if (kbd_mode_levels_count > 0 && level < kbd_mode_levels_count) { 1066 + if (level != 0) 1067 + kbd_previous_level = level; 1068 + state->mode_bit = kbd_mode_levels[level]; 1069 + return 0; 1070 + } 1071 + 1072 + return -EINVAL; 1073 + } 1074 + 1075 + static int kbd_get_state(struct kbd_state *state) 1076 + { 1077 + int ret; 1078 + 1079 + get_buffer(); 1080 + 1081 + buffer->input[0] = 0x1; 1082 + dell_send_request(buffer, 4, 11); 1083 + ret = buffer->output[0]; 1084 + 1085 + if (ret) { 1086 + ret = dell_smi_error(ret); 1087 + goto out; 1088 + } 1089 + 1090 + state->mode_bit = ffs(buffer->output[1] & 0xFFFF); 1091 + if (state->mode_bit != 0) 1092 + state->mode_bit--; 1093 + 1094 + state->triggers = (buffer->output[1] >> 16) & 0xFF; 1095 + state->timeout_value = (buffer->output[1] >> 24) & 0x3F; 1096 + state->timeout_unit = (buffer->output[1] >> 30) & 0x3; 1097 + state->als_setting = buffer->output[2] & 0xFF; 1098 + state->als_value = (buffer->output[2] >> 8) & 0xFF; 1099 + state->level = (buffer->output[2] >> 16) & 0xFF; 1100 + 1101 + out: 1102 + release_buffer(); 1103 + return ret; 1104 + } 1105 + 1106 + static int kbd_set_state(struct kbd_state *state) 1107 + { 1108 + int ret; 1109 + 1110 + get_buffer(); 1111 + buffer->input[0] = 0x2; 1112 + buffer->input[1] = BIT(state->mode_bit) & 0xFFFF; 1113 + buffer->input[1] |= (state->triggers & 0xFF) << 16; 1114 + buffer->input[1] |= (state->timeout_value & 0x3F) << 24; 1115 + buffer->input[1] |= (state->timeout_unit & 0x3) << 30; 1116 + buffer->input[2] = state->als_setting & 0xFF; 1117 + buffer->input[2] |= (state->level & 0xFF) << 16; 1118 + dell_send_request(buffer, 4, 11); 1119 + ret = buffer->output[0]; 1120 + release_buffer(); 1121 + 1122 + return dell_smi_error(ret); 1123 + } 1124 + 1125 + static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old) 1126 + { 1127 + int ret; 1128 + 1129 + ret = kbd_set_state(state); 1130 + if (ret == 0) 1131 + return 0; 1132 + 1133 + /* 1134 + * When setting the new state fails,try to restore the previous one. 1135 + * This is needed on some machines where BIOS sets a default state when 1136 + * setting a new state fails. This default state could be all off. 1137 + */ 1138 + 1139 + if (kbd_set_state(old)) 1140 + pr_err("Setting old previous keyboard state failed\n"); 1141 + 1142 + return ret; 1143 + } 1144 + 1145 + static int kbd_set_token_bit(u8 bit) 1146 + { 1147 + int id; 1148 + int ret; 1149 + 1150 + if (bit >= ARRAY_SIZE(kbd_tokens)) 1151 + return -EINVAL; 1152 + 1153 + id = find_token_id(kbd_tokens[bit]); 1154 + if (id == -1) 1155 + return -EINVAL; 1156 + 1157 + get_buffer(); 1158 + buffer->input[0] = da_tokens[id].location; 1159 + buffer->input[1] = da_tokens[id].value; 1160 + dell_send_request(buffer, 1, 0); 1161 + ret = buffer->output[0]; 1162 + release_buffer(); 1163 + 1164 + return dell_smi_error(ret); 1165 + } 1166 + 1167 + static int kbd_get_token_bit(u8 bit) 1168 + { 1169 + int id; 1170 + int ret; 1171 + int val; 1172 + 1173 + if (bit >= ARRAY_SIZE(kbd_tokens)) 1174 + return -EINVAL; 1175 + 1176 + id = find_token_id(kbd_tokens[bit]); 1177 + if (id == -1) 1178 + return -EINVAL; 1179 + 1180 + get_buffer(); 1181 + buffer->input[0] = da_tokens[id].location; 1182 + dell_send_request(buffer, 0, 0); 1183 + ret = buffer->output[0]; 1184 + val = buffer->output[1]; 1185 + release_buffer(); 1186 + 1187 + if (ret) 1188 + return dell_smi_error(ret); 1189 + 1190 + return (val == da_tokens[id].value); 1191 + } 1192 + 1193 + static int kbd_get_first_active_token_bit(void) 1194 + { 1195 + int i; 1196 + int ret; 1197 + 1198 + for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) { 1199 + ret = kbd_get_token_bit(i); 1200 + if (ret == 1) 1201 + return i; 1202 + } 1203 + 1204 + return ret; 1205 + } 1206 + 1207 + static int kbd_get_valid_token_counts(void) 1208 + { 1209 + return hweight16(kbd_token_bits); 1210 + } 1211 + 1212 + static inline int kbd_init_info(void) 1213 + { 1214 + struct kbd_state state; 1215 + int ret; 1216 + int i; 1217 + 1218 + ret = kbd_get_info(&kbd_info); 1219 + if (ret) 1220 + return ret; 1221 + 1222 + kbd_get_state(&state); 1223 + 1224 + /* NOTE: timeout value is stored in 6 bits so max value is 63 */ 1225 + if (kbd_info.seconds > 63) 1226 + kbd_info.seconds = 63; 1227 + if (kbd_info.minutes > 63) 1228 + kbd_info.minutes = 63; 1229 + if (kbd_info.hours > 63) 1230 + kbd_info.hours = 63; 1231 + if (kbd_info.days > 63) 1232 + kbd_info.days = 63; 1233 + 1234 + /* NOTE: On tested machines ON mode did not work and caused 1235 + * problems (turned backlight off) so do not use it 1236 + */ 1237 + kbd_info.modes &= ~BIT(KBD_MODE_BIT_ON); 1238 + 1239 + kbd_previous_level = kbd_get_level(&state); 1240 + kbd_previous_mode_bit = state.mode_bit; 1241 + 1242 + if (kbd_previous_level == 0 && kbd_get_max_level() != 0) 1243 + kbd_previous_level = 1; 1244 + 1245 + if (kbd_previous_mode_bit == KBD_MODE_BIT_OFF) { 1246 + kbd_previous_mode_bit = 1247 + ffs(kbd_info.modes & ~BIT(KBD_MODE_BIT_OFF)); 1248 + if (kbd_previous_mode_bit != 0) 1249 + kbd_previous_mode_bit--; 1250 + } 1251 + 1252 + if (kbd_info.modes & (BIT(KBD_MODE_BIT_ALS) | 1253 + BIT(KBD_MODE_BIT_TRIGGER_ALS))) 1254 + kbd_als_supported = true; 1255 + 1256 + if (kbd_info.modes & ( 1257 + BIT(KBD_MODE_BIT_TRIGGER_ALS) | BIT(KBD_MODE_BIT_TRIGGER) | 1258 + BIT(KBD_MODE_BIT_TRIGGER_25) | BIT(KBD_MODE_BIT_TRIGGER_50) | 1259 + BIT(KBD_MODE_BIT_TRIGGER_75) | BIT(KBD_MODE_BIT_TRIGGER_100) 1260 + )) 1261 + kbd_triggers_supported = true; 1262 + 1263 + /* kbd_mode_levels[0] is reserved, see below */ 1264 + for (i = 0; i < 16; ++i) 1265 + if (kbd_is_level_mode_bit(i) && (BIT(i) & kbd_info.modes)) 1266 + kbd_mode_levels[1 + kbd_mode_levels_count++] = i; 1267 + 1268 + /* 1269 + * Find the first supported mode and assign to kbd_mode_levels[0]. 1270 + * This should be 0 (off), but we cannot depend on the BIOS to 1271 + * support 0. 1272 + */ 1273 + if (kbd_mode_levels_count > 0) { 1274 + for (i = 0; i < 16; ++i) { 1275 + if (BIT(i) & kbd_info.modes) { 1276 + kbd_mode_levels[0] = i; 1277 + break; 1278 + } 1279 + } 1280 + kbd_mode_levels_count++; 1281 + } 1282 + 1283 + return 0; 1284 + 1285 + } 1286 + 1287 + static inline void kbd_init_tokens(void) 1288 + { 1289 + int i; 1290 + 1291 + for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) 1292 + if (find_token_id(kbd_tokens[i]) != -1) 1293 + kbd_token_bits |= BIT(i); 1294 + } 1295 + 1296 + static void kbd_init(void) 1297 + { 1298 + int ret; 1299 + 1300 + ret = kbd_init_info(); 1301 + kbd_init_tokens(); 1302 + 1303 + if (kbd_token_bits != 0 || ret == 0) 1304 + kbd_led_present = true; 1305 + } 1306 + 1307 + static ssize_t kbd_led_timeout_store(struct device *dev, 1308 + struct device_attribute *attr, 1309 + const char *buf, size_t count) 1310 + { 1311 + struct kbd_state new_state; 1312 + struct kbd_state state; 1313 + bool convert; 1314 + int value; 1315 + int ret; 1316 + char ch; 1317 + u8 unit; 1318 + int i; 1319 + 1320 + ret = sscanf(buf, "%d %c", &value, &ch); 1321 + if (ret < 1) 1322 + return -EINVAL; 1323 + else if (ret == 1) 1324 + ch = 's'; 1325 + 1326 + if (value < 0) 1327 + return -EINVAL; 1328 + 1329 + convert = false; 1330 + 1331 + switch (ch) { 1332 + case 's': 1333 + if (value > kbd_info.seconds) 1334 + convert = true; 1335 + unit = KBD_TIMEOUT_SECONDS; 1336 + break; 1337 + case 'm': 1338 + if (value > kbd_info.minutes) 1339 + convert = true; 1340 + unit = KBD_TIMEOUT_MINUTES; 1341 + break; 1342 + case 'h': 1343 + if (value > kbd_info.hours) 1344 + convert = true; 1345 + unit = KBD_TIMEOUT_HOURS; 1346 + break; 1347 + case 'd': 1348 + if (value > kbd_info.days) 1349 + convert = true; 1350 + unit = KBD_TIMEOUT_DAYS; 1351 + break; 1352 + default: 1353 + return -EINVAL; 1354 + } 1355 + 1356 + if (quirks && quirks->needs_kbd_timeouts) 1357 + convert = true; 1358 + 1359 + if (convert) { 1360 + /* Convert value from current units to seconds */ 1361 + switch (unit) { 1362 + case KBD_TIMEOUT_DAYS: 1363 + value *= 24; 1364 + case KBD_TIMEOUT_HOURS: 1365 + value *= 60; 1366 + case KBD_TIMEOUT_MINUTES: 1367 + value *= 60; 1368 + unit = KBD_TIMEOUT_SECONDS; 1369 + } 1370 + 1371 + if (quirks && quirks->needs_kbd_timeouts) { 1372 + for (i = 0; quirks->kbd_timeouts[i] != -1; i++) { 1373 + if (value <= quirks->kbd_timeouts[i]) { 1374 + value = quirks->kbd_timeouts[i]; 1375 + break; 1376 + } 1377 + } 1378 + } 1379 + 1380 + if (value <= kbd_info.seconds && kbd_info.seconds) { 1381 + unit = KBD_TIMEOUT_SECONDS; 1382 + } else if (value / 60 <= kbd_info.minutes && kbd_info.minutes) { 1383 + value /= 60; 1384 + unit = KBD_TIMEOUT_MINUTES; 1385 + } else if (value / (60 * 60) <= kbd_info.hours && kbd_info.hours) { 1386 + value /= (60 * 60); 1387 + unit = KBD_TIMEOUT_HOURS; 1388 + } else if (value / (60 * 60 * 24) <= kbd_info.days && kbd_info.days) { 1389 + value /= (60 * 60 * 24); 1390 + unit = KBD_TIMEOUT_DAYS; 1391 + } else { 1392 + return -EINVAL; 1393 + } 1394 + } 1395 + 1396 + ret = kbd_get_state(&state); 1397 + if (ret) 1398 + return ret; 1399 + 1400 + new_state = state; 1401 + new_state.timeout_value = value; 1402 + new_state.timeout_unit = unit; 1403 + 1404 + ret = kbd_set_state_safe(&new_state, &state); 1405 + if (ret) 1406 + return ret; 1407 + 1408 + return count; 1409 + } 1410 + 1411 + static ssize_t kbd_led_timeout_show(struct device *dev, 1412 + struct device_attribute *attr, char *buf) 1413 + { 1414 + struct kbd_state state; 1415 + int ret; 1416 + int len; 1417 + 1418 + ret = kbd_get_state(&state); 1419 + if (ret) 1420 + return ret; 1421 + 1422 + len = sprintf(buf, "%d", state.timeout_value); 1423 + 1424 + switch (state.timeout_unit) { 1425 + case KBD_TIMEOUT_SECONDS: 1426 + return len + sprintf(buf+len, "s\n"); 1427 + case KBD_TIMEOUT_MINUTES: 1428 + return len + sprintf(buf+len, "m\n"); 1429 + case KBD_TIMEOUT_HOURS: 1430 + return len + sprintf(buf+len, "h\n"); 1431 + case KBD_TIMEOUT_DAYS: 1432 + return len + sprintf(buf+len, "d\n"); 1433 + default: 1434 + return -EINVAL; 1435 + } 1436 + 1437 + return len; 1438 + } 1439 + 1440 + static DEVICE_ATTR(stop_timeout, S_IRUGO | S_IWUSR, 1441 + kbd_led_timeout_show, kbd_led_timeout_store); 1442 + 1443 + static const char * const kbd_led_triggers[] = { 1444 + "keyboard", 1445 + "touchpad", 1446 + /*"trackstick"*/ NULL, /* NOTE: trackstick is just alias for touchpad */ 1447 + "mouse", 1448 + }; 1449 + 1450 + static ssize_t kbd_led_triggers_store(struct device *dev, 1451 + struct device_attribute *attr, 1452 + const char *buf, size_t count) 1453 + { 1454 + struct kbd_state new_state; 1455 + struct kbd_state state; 1456 + bool triggers_enabled = false; 1457 + int trigger_bit = -1; 1458 + char trigger[21]; 1459 + int i, ret; 1460 + 1461 + ret = sscanf(buf, "%20s", trigger); 1462 + if (ret != 1) 1463 + return -EINVAL; 1464 + 1465 + if (trigger[0] != '+' && trigger[0] != '-') 1466 + return -EINVAL; 1467 + 1468 + ret = kbd_get_state(&state); 1469 + if (ret) 1470 + return ret; 1471 + 1472 + if (kbd_triggers_supported) 1473 + triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); 1474 + 1475 + if (kbd_triggers_supported) { 1476 + for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) { 1477 + if (!(kbd_info.triggers & BIT(i))) 1478 + continue; 1479 + if (!kbd_led_triggers[i]) 1480 + continue; 1481 + if (strcmp(trigger+1, kbd_led_triggers[i]) != 0) 1482 + continue; 1483 + if (trigger[0] == '+' && 1484 + triggers_enabled && (state.triggers & BIT(i))) 1485 + return count; 1486 + if (trigger[0] == '-' && 1487 + (!triggers_enabled || !(state.triggers & BIT(i)))) 1488 + return count; 1489 + trigger_bit = i; 1490 + break; 1491 + } 1492 + } 1493 + 1494 + if (trigger_bit != -1) { 1495 + new_state = state; 1496 + if (trigger[0] == '+') 1497 + new_state.triggers |= BIT(trigger_bit); 1498 + else { 1499 + new_state.triggers &= ~BIT(trigger_bit); 1500 + /* NOTE: trackstick bit (2) must be disabled when 1501 + * disabling touchpad bit (1), otherwise touchpad 1502 + * bit (1) will not be disabled */ 1503 + if (trigger_bit == 1) 1504 + new_state.triggers &= ~BIT(2); 1505 + } 1506 + if ((kbd_info.triggers & new_state.triggers) != 1507 + new_state.triggers) 1508 + return -EINVAL; 1509 + if (new_state.triggers && !triggers_enabled) { 1510 + new_state.mode_bit = KBD_MODE_BIT_TRIGGER; 1511 + kbd_set_level(&new_state, kbd_previous_level); 1512 + } else if (new_state.triggers == 0) { 1513 + kbd_set_level(&new_state, 0); 1514 + } 1515 + if (!(kbd_info.modes & BIT(new_state.mode_bit))) 1516 + return -EINVAL; 1517 + ret = kbd_set_state_safe(&new_state, &state); 1518 + if (ret) 1519 + return ret; 1520 + if (new_state.mode_bit != KBD_MODE_BIT_OFF) 1521 + kbd_previous_mode_bit = new_state.mode_bit; 1522 + return count; 1523 + } 1524 + 1525 + return -EINVAL; 1526 + } 1527 + 1528 + static ssize_t kbd_led_triggers_show(struct device *dev, 1529 + struct device_attribute *attr, char *buf) 1530 + { 1531 + struct kbd_state state; 1532 + bool triggers_enabled; 1533 + int level, i, ret; 1534 + int len = 0; 1535 + 1536 + ret = kbd_get_state(&state); 1537 + if (ret) 1538 + return ret; 1539 + 1540 + len = 0; 1541 + 1542 + if (kbd_triggers_supported) { 1543 + triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); 1544 + level = kbd_get_level(&state); 1545 + for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) { 1546 + if (!(kbd_info.triggers & BIT(i))) 1547 + continue; 1548 + if (!kbd_led_triggers[i]) 1549 + continue; 1550 + if ((triggers_enabled || level <= 0) && 1551 + (state.triggers & BIT(i))) 1552 + buf[len++] = '+'; 1553 + else 1554 + buf[len++] = '-'; 1555 + len += sprintf(buf+len, "%s ", kbd_led_triggers[i]); 1556 + } 1557 + } 1558 + 1559 + if (len) 1560 + buf[len - 1] = '\n'; 1561 + 1562 + return len; 1563 + } 1564 + 1565 + static DEVICE_ATTR(start_triggers, S_IRUGO | S_IWUSR, 1566 + kbd_led_triggers_show, kbd_led_triggers_store); 1567 + 1568 + static ssize_t kbd_led_als_enabled_store(struct device *dev, 1569 + struct device_attribute *attr, 1570 + const char *buf, size_t count) 1571 + { 1572 + struct kbd_state new_state; 1573 + struct kbd_state state; 1574 + bool triggers_enabled = false; 1575 + int enable; 1576 + int ret; 1577 + 1578 + ret = kstrtoint(buf, 0, &enable); 1579 + if (ret) 1580 + return ret; 1581 + 1582 + ret = kbd_get_state(&state); 1583 + if (ret) 1584 + return ret; 1585 + 1586 + if (enable == kbd_is_als_mode_bit(state.mode_bit)) 1587 + return count; 1588 + 1589 + new_state = state; 1590 + 1591 + if (kbd_triggers_supported) 1592 + triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); 1593 + 1594 + if (enable) { 1595 + if (triggers_enabled) 1596 + new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS; 1597 + else 1598 + new_state.mode_bit = KBD_MODE_BIT_ALS; 1599 + } else { 1600 + if (triggers_enabled) { 1601 + new_state.mode_bit = KBD_MODE_BIT_TRIGGER; 1602 + kbd_set_level(&new_state, kbd_previous_level); 1603 + } else { 1604 + new_state.mode_bit = KBD_MODE_BIT_ON; 1605 + } 1606 + } 1607 + if (!(kbd_info.modes & BIT(new_state.mode_bit))) 1608 + return -EINVAL; 1609 + 1610 + ret = kbd_set_state_safe(&new_state, &state); 1611 + if (ret) 1612 + return ret; 1613 + kbd_previous_mode_bit = new_state.mode_bit; 1614 + 1615 + return count; 1616 + } 1617 + 1618 + static ssize_t kbd_led_als_enabled_show(struct device *dev, 1619 + struct device_attribute *attr, 1620 + char *buf) 1621 + { 1622 + struct kbd_state state; 1623 + bool enabled = false; 1624 + int ret; 1625 + 1626 + ret = kbd_get_state(&state); 1627 + if (ret) 1628 + return ret; 1629 + enabled = kbd_is_als_mode_bit(state.mode_bit); 1630 + 1631 + return sprintf(buf, "%d\n", enabled ? 1 : 0); 1632 + } 1633 + 1634 + static DEVICE_ATTR(als_enabled, S_IRUGO | S_IWUSR, 1635 + kbd_led_als_enabled_show, kbd_led_als_enabled_store); 1636 + 1637 + static ssize_t kbd_led_als_setting_store(struct device *dev, 1638 + struct device_attribute *attr, 1639 + const char *buf, size_t count) 1640 + { 1641 + struct kbd_state state; 1642 + struct kbd_state new_state; 1643 + u8 setting; 1644 + int ret; 1645 + 1646 + ret = kstrtou8(buf, 10, &setting); 1647 + if (ret) 1648 + return ret; 1649 + 1650 + ret = kbd_get_state(&state); 1651 + if (ret) 1652 + return ret; 1653 + 1654 + new_state = state; 1655 + new_state.als_setting = setting; 1656 + 1657 + ret = kbd_set_state_safe(&new_state, &state); 1658 + if (ret) 1659 + return ret; 1660 + 1661 + return count; 1662 + } 1663 + 1664 + static ssize_t kbd_led_als_setting_show(struct device *dev, 1665 + struct device_attribute *attr, 1666 + char *buf) 1667 + { 1668 + struct kbd_state state; 1669 + int ret; 1670 + 1671 + ret = kbd_get_state(&state); 1672 + if (ret) 1673 + return ret; 1674 + 1675 + return sprintf(buf, "%d\n", state.als_setting); 1676 + } 1677 + 1678 + static DEVICE_ATTR(als_setting, S_IRUGO | S_IWUSR, 1679 + kbd_led_als_setting_show, kbd_led_als_setting_store); 1680 + 1681 + static struct attribute *kbd_led_attrs[] = { 1682 + &dev_attr_stop_timeout.attr, 1683 + &dev_attr_start_triggers.attr, 1684 + NULL, 1685 + }; 1686 + 1687 + static const struct attribute_group kbd_led_group = { 1688 + .attrs = kbd_led_attrs, 1689 + }; 1690 + 1691 + static struct attribute *kbd_led_als_attrs[] = { 1692 + &dev_attr_als_enabled.attr, 1693 + &dev_attr_als_setting.attr, 1694 + NULL, 1695 + }; 1696 + 1697 + static const struct attribute_group kbd_led_als_group = { 1698 + .attrs = kbd_led_als_attrs, 1699 + }; 1700 + 1701 + static const struct attribute_group *kbd_led_groups[] = { 1702 + &kbd_led_group, 1703 + &kbd_led_als_group, 1704 + NULL, 1705 + }; 1706 + 1707 + static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev) 1708 + { 1709 + int ret; 1710 + u16 num; 1711 + struct kbd_state state; 1712 + 1713 + if (kbd_get_max_level()) { 1714 + ret = kbd_get_state(&state); 1715 + if (ret) 1716 + return 0; 1717 + ret = kbd_get_level(&state); 1718 + if (ret < 0) 1719 + return 0; 1720 + return ret; 1721 + } 1722 + 1723 + if (kbd_get_valid_token_counts()) { 1724 + ret = kbd_get_first_active_token_bit(); 1725 + if (ret < 0) 1726 + return 0; 1727 + for (num = kbd_token_bits; num != 0 && ret > 0; --ret) 1728 + num &= num - 1; /* clear the first bit set */ 1729 + if (num == 0) 1730 + return 0; 1731 + return ffs(num) - 1; 1732 + } 1733 + 1734 + pr_warn("Keyboard brightness level control not supported\n"); 1735 + return 0; 1736 + } 1737 + 1738 + static void kbd_led_level_set(struct led_classdev *led_cdev, 1739 + enum led_brightness value) 1740 + { 1741 + struct kbd_state state; 1742 + struct kbd_state new_state; 1743 + u16 num; 1744 + 1745 + if (kbd_get_max_level()) { 1746 + if (kbd_get_state(&state)) 1747 + return; 1748 + new_state = state; 1749 + if (kbd_set_level(&new_state, value)) 1750 + return; 1751 + kbd_set_state_safe(&new_state, &state); 1752 + return; 1753 + } 1754 + 1755 + if (kbd_get_valid_token_counts()) { 1756 + for (num = kbd_token_bits; num != 0 && value > 0; --value) 1757 + num &= num - 1; /* clear the first bit set */ 1758 + if (num == 0) 1759 + return; 1760 + kbd_set_token_bit(ffs(num) - 1); 1761 + return; 1762 + } 1763 + 1764 + pr_warn("Keyboard brightness level control not supported\n"); 1765 + } 1766 + 1767 + static struct led_classdev kbd_led = { 1768 + .name = "dell::kbd_backlight", 1769 + .brightness_set = kbd_led_level_set, 1770 + .brightness_get = kbd_led_level_get, 1771 + .groups = kbd_led_groups, 1772 + }; 1773 + 1774 + static int __init kbd_led_init(struct device *dev) 1775 + { 1776 + kbd_init(); 1777 + if (!kbd_led_present) 1778 + return -ENODEV; 1779 + if (!kbd_als_supported) 1780 + kbd_led_groups[1] = NULL; 1781 + kbd_led.max_brightness = kbd_get_max_level(); 1782 + if (!kbd_led.max_brightness) { 1783 + kbd_led.max_brightness = kbd_get_valid_token_counts(); 1784 + if (kbd_led.max_brightness) 1785 + kbd_led.max_brightness--; 1786 + } 1787 + return led_classdev_register(dev, &kbd_led); 1788 + } 1789 + 1790 + static void brightness_set_exit(struct led_classdev *led_cdev, 1791 + enum led_brightness value) 1792 + { 1793 + /* Don't change backlight level on exit */ 1794 + }; 1795 + 1796 + static void kbd_led_exit(void) 1797 + { 1798 + if (!kbd_led_present) 1799 + return; 1800 + kbd_led.brightness_set = brightness_set_exit; 1801 + led_classdev_unregister(&kbd_led); 850 1802 } 851 1803 852 1804 static int __init dell_init(void) ··· 1912 840 1913 841 if (quirks && quirks->touchpad_led) 1914 842 touchpad_led_init(&platform_device->dev); 843 + 844 + kbd_led_init(&platform_device->dev); 1915 845 1916 846 dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); 1917 847 if (dell_laptop_dir != NULL) ··· 1982 908 debugfs_remove_recursive(dell_laptop_dir); 1983 909 if (quirks && quirks->touchpad_led) 1984 910 touchpad_led_exit(); 911 + kbd_led_exit(); 1985 912 i8042_remove_filter(dell_laptop_i8042_filter); 1986 913 cancel_delayed_work_sync(&dell_rfkill_work); 1987 914 backlight_device_unregister(dell_backlight_device); ··· 1999 924 module_exit(dell_exit); 2000 925 2001 926 MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); 927 + MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); 928 + MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); 2002 929 MODULE_DESCRIPTION("Dell laptop driver"); 2003 930 MODULE_LICENSE("GPL");
+1 -1
drivers/platform/x86/intel_oaktrail.c
··· 62 62 * (1 << 1): Bluetooth enable/disable, RW. 63 63 * (1 << 2): GPS enable/disable, RW. 64 64 * (1 << 3): WiFi enable/disable, RW. 65 - * (1 << 4): WWAN (3G) enable/disalbe, RW. 65 + * (1 << 4): WWAN (3G) enable/disable, RW. 66 66 * (1 << 5): Touchscreen enable/disable, Read Only. 67 67 */ 68 68 #define OT_EC_DEVICE_STATE_ADDRESS 0xD6
+216 -104
drivers/platform/x86/thinkpad_acpi.c
··· 319 319 u32 sensors_pdrv_attrs_registered:1; 320 320 u32 sensors_pdev_attrs_registered:1; 321 321 u32 hotkey_poll_active:1; 322 + u32 has_adaptive_kbd:1; 322 323 } tp_features; 323 324 324 325 static struct { ··· 1912 1911 TP_ACPI_HOTKEYSCAN_UNK7, 1913 1912 TP_ACPI_HOTKEYSCAN_UNK8, 1914 1913 1914 + TP_ACPI_HOTKEYSCAN_MUTE2, 1915 + TP_ACPI_HOTKEYSCAN_BRIGHTNESS_ZERO, 1916 + TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL, 1917 + TP_ACPI_HOTKEYSCAN_CLOUD, 1918 + TP_ACPI_HOTKEYSCAN_UNK9, 1919 + TP_ACPI_HOTKEYSCAN_VOICE, 1920 + TP_ACPI_HOTKEYSCAN_UNK10, 1921 + TP_ACPI_HOTKEYSCAN_GESTURES, 1922 + TP_ACPI_HOTKEYSCAN_UNK11, 1923 + TP_ACPI_HOTKEYSCAN_UNK12, 1924 + TP_ACPI_HOTKEYSCAN_UNK13, 1925 + TP_ACPI_HOTKEYSCAN_CONFIG, 1926 + TP_ACPI_HOTKEYSCAN_NEW_TAB, 1927 + TP_ACPI_HOTKEYSCAN_RELOAD, 1928 + TP_ACPI_HOTKEYSCAN_BACK, 1929 + TP_ACPI_HOTKEYSCAN_MIC_DOWN, 1930 + TP_ACPI_HOTKEYSCAN_MIC_UP, 1931 + TP_ACPI_HOTKEYSCAN_MIC_CANCELLATION, 1932 + TP_ACPI_HOTKEYSCAN_CAMERA_MODE, 1933 + TP_ACPI_HOTKEYSCAN_ROTATE_DISPLAY, 1934 + 1915 1935 /* Hotkey keymap size */ 1916 1936 TPACPI_HOTKEY_MAP_LEN 1917 1937 }; ··· 2669 2647 return count; 2670 2648 } 2671 2649 2672 - static struct device_attribute dev_attr_hotkey_enable = 2673 - __ATTR(hotkey_enable, S_IWUSR | S_IRUGO, 2674 - hotkey_enable_show, hotkey_enable_store); 2650 + static DEVICE_ATTR_RW(hotkey_enable); 2675 2651 2676 2652 /* sysfs hotkey mask --------------------------------------------------- */ 2677 2653 static ssize_t hotkey_mask_show(struct device *dev, ··· 2705 2685 return (res) ? res : count; 2706 2686 } 2707 2687 2708 - static struct device_attribute dev_attr_hotkey_mask = 2709 - __ATTR(hotkey_mask, S_IWUSR | S_IRUGO, 2710 - hotkey_mask_show, hotkey_mask_store); 2688 + static DEVICE_ATTR_RW(hotkey_mask); 2711 2689 2712 2690 /* sysfs hotkey bios_enabled ------------------------------------------- */ 2713 2691 static ssize_t hotkey_bios_enabled_show(struct device *dev, ··· 2715 2697 return sprintf(buf, "0\n"); 2716 2698 } 2717 2699 2718 - static struct device_attribute dev_attr_hotkey_bios_enabled = 2719 - __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); 2700 + static DEVICE_ATTR_RO(hotkey_bios_enabled); 2720 2701 2721 2702 /* sysfs hotkey bios_mask ---------------------------------------------- */ 2722 2703 static ssize_t hotkey_bios_mask_show(struct device *dev, ··· 2727 2710 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); 2728 2711 } 2729 2712 2730 - static struct device_attribute dev_attr_hotkey_bios_mask = 2731 - __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); 2713 + static DEVICE_ATTR_RO(hotkey_bios_mask); 2732 2714 2733 2715 /* sysfs hotkey all_mask ----------------------------------------------- */ 2734 2716 static ssize_t hotkey_all_mask_show(struct device *dev, ··· 2738 2722 hotkey_all_mask | hotkey_source_mask); 2739 2723 } 2740 2724 2741 - static struct device_attribute dev_attr_hotkey_all_mask = 2742 - __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); 2725 + static DEVICE_ATTR_RO(hotkey_all_mask); 2743 2726 2744 2727 /* sysfs hotkey recommended_mask --------------------------------------- */ 2745 2728 static ssize_t hotkey_recommended_mask_show(struct device *dev, ··· 2750 2735 & ~hotkey_reserved_mask); 2751 2736 } 2752 2737 2753 - static struct device_attribute dev_attr_hotkey_recommended_mask = 2754 - __ATTR(hotkey_recommended_mask, S_IRUGO, 2755 - hotkey_recommended_mask_show, NULL); 2738 + static DEVICE_ATTR_RO(hotkey_recommended_mask); 2756 2739 2757 2740 #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2758 2741 ··· 2805 2792 return (rc < 0) ? rc : count; 2806 2793 } 2807 2794 2808 - static struct device_attribute dev_attr_hotkey_source_mask = 2809 - __ATTR(hotkey_source_mask, S_IWUSR | S_IRUGO, 2810 - hotkey_source_mask_show, hotkey_source_mask_store); 2795 + static DEVICE_ATTR_RW(hotkey_source_mask); 2811 2796 2812 2797 /* sysfs hotkey hotkey_poll_freq --------------------------------------- */ 2813 2798 static ssize_t hotkey_poll_freq_show(struct device *dev, ··· 2837 2826 return count; 2838 2827 } 2839 2828 2840 - static struct device_attribute dev_attr_hotkey_poll_freq = 2841 - __ATTR(hotkey_poll_freq, S_IWUSR | S_IRUGO, 2842 - hotkey_poll_freq_show, hotkey_poll_freq_store); 2829 + static DEVICE_ATTR_RW(hotkey_poll_freq); 2843 2830 2844 2831 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2845 2832 ··· 2858 2849 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1); 2859 2850 } 2860 2851 2861 - static struct device_attribute dev_attr_hotkey_radio_sw = 2862 - __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 2852 + static DEVICE_ATTR_RO(hotkey_radio_sw); 2863 2853 2864 2854 static void hotkey_radio_sw_notify_change(void) 2865 2855 { ··· 2880 2872 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 2881 2873 } 2882 2874 2883 - static struct device_attribute dev_attr_hotkey_tablet_mode = 2884 - __ATTR(hotkey_tablet_mode, S_IRUGO, hotkey_tablet_mode_show, NULL); 2875 + static DEVICE_ATTR_RO(hotkey_tablet_mode); 2885 2876 2886 2877 static void hotkey_tablet_mode_notify_change(void) 2887 2878 { ··· 2897 2890 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_wakeup_reason); 2898 2891 } 2899 2892 2900 - static struct device_attribute dev_attr_hotkey_wakeup_reason = 2901 - __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL); 2893 + static DEVICE_ATTR_RO(hotkey_wakeup_reason); 2902 2894 2903 2895 static void hotkey_wakeup_reason_notify_change(void) 2904 2896 { ··· 2913 2907 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_autosleep_ack); 2914 2908 } 2915 2909 2916 - static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete = 2917 - __ATTR(wakeup_hotunplug_complete, S_IRUGO, 2918 - hotkey_wakeup_hotunplug_complete_show, NULL); 2910 + static DEVICE_ATTR_RO(hotkey_wakeup_hotunplug_complete); 2919 2911 2920 2912 static void hotkey_wakeup_hotunplug_complete_notify_change(void) 2921 2913 { 2922 2914 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2923 2915 "wakeup_hotunplug_complete"); 2924 2916 } 2917 + 2918 + /* sysfs adaptive kbd mode --------------------------------------------- */ 2919 + 2920 + static int adaptive_keyboard_get_mode(void); 2921 + static int adaptive_keyboard_set_mode(int new_mode); 2922 + 2923 + enum ADAPTIVE_KEY_MODE { 2924 + HOME_MODE, 2925 + WEB_BROWSER_MODE, 2926 + WEB_CONFERENCE_MODE, 2927 + FUNCTION_MODE, 2928 + LAYFLAT_MODE 2929 + }; 2930 + 2931 + static ssize_t adaptive_kbd_mode_show(struct device *dev, 2932 + struct device_attribute *attr, 2933 + char *buf) 2934 + { 2935 + int current_mode; 2936 + 2937 + current_mode = adaptive_keyboard_get_mode(); 2938 + if (current_mode < 0) 2939 + return current_mode; 2940 + 2941 + return snprintf(buf, PAGE_SIZE, "%d\n", current_mode); 2942 + } 2943 + 2944 + static ssize_t adaptive_kbd_mode_store(struct device *dev, 2945 + struct device_attribute *attr, 2946 + const char *buf, size_t count) 2947 + { 2948 + unsigned long t; 2949 + int res; 2950 + 2951 + if (parse_strtoul(buf, LAYFLAT_MODE, &t)) 2952 + return -EINVAL; 2953 + 2954 + res = adaptive_keyboard_set_mode(t); 2955 + return (res < 0) ? res : count; 2956 + } 2957 + 2958 + static DEVICE_ATTR_RW(adaptive_kbd_mode); 2959 + 2960 + static struct attribute *adaptive_kbd_attributes[] = { 2961 + &dev_attr_adaptive_kbd_mode.attr, 2962 + NULL 2963 + }; 2964 + 2965 + static const struct attribute_group adaptive_kbd_attr_group = { 2966 + .attrs = adaptive_kbd_attributes, 2967 + }; 2925 2968 2926 2969 /* --------------------------------------------------------------------- */ 2927 2970 ··· 3173 3118 /* (assignments unknown, please report if found) */ 3174 3119 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3175 3120 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3121 + 3122 + /* No assignments, only used for Adaptive keyboards. */ 3123 + KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3124 + KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3125 + KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3126 + KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3127 + KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3176 3128 }, 3177 3129 3178 3130 /* Generic keymap for Lenovo ThinkPads */ ··· 3236 3174 3237 3175 /* Extra keys in use since the X240 / T440 / T540 */ 3238 3176 KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_FILE, 3177 + 3178 + /* 3179 + * These are the adaptive keyboard keycodes for Carbon X1 2014. 3180 + * The first item in this list is the Mute button which is 3181 + * emitted with 0x103 through 3182 + * adaptive_keyboard_hotkey_notify_hotkey() when the sound 3183 + * symbol is held. 3184 + * We'll need to offset those by 0x20. 3185 + */ 3186 + KEY_RESERVED, /* Mute held, 0x103 */ 3187 + KEY_BRIGHTNESS_MIN, /* Backlight off */ 3188 + KEY_RESERVED, /* Clipping tool */ 3189 + KEY_RESERVED, /* Cloud */ 3190 + KEY_RESERVED, 3191 + KEY_VOICECOMMAND, /* Voice */ 3192 + KEY_RESERVED, 3193 + KEY_RESERVED, /* Gestures */ 3194 + KEY_RESERVED, 3195 + KEY_RESERVED, 3196 + KEY_RESERVED, 3197 + KEY_CONFIG, /* Settings */ 3198 + KEY_RESERVED, /* New tab */ 3199 + KEY_REFRESH, /* Reload */ 3200 + KEY_BACK, /* Back */ 3201 + KEY_RESERVED, /* Microphone down */ 3202 + KEY_RESERVED, /* Microphone up */ 3203 + KEY_RESERVED, /* Microphone cancellation */ 3204 + KEY_RESERVED, /* Camera mode */ 3205 + KEY_RESERVED, /* Rotate display, 0x116 */ 3239 3206 }, 3240 3207 }; 3241 3208 ··· 3317 3226 3318 3227 if (!tp_features.hotkey) 3319 3228 return 1; 3229 + 3230 + /* 3231 + * Check if we have an adaptive keyboard, like on the 3232 + * Lenovo Carbon X1 2014 (2nd Gen). 3233 + */ 3234 + if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 3235 + if ((hkeyv >> 8) == 2) { 3236 + tp_features.has_adaptive_kbd = true; 3237 + res = sysfs_create_group(&tpacpi_pdev->dev.kobj, 3238 + &adaptive_kbd_attr_group); 3239 + if (res) 3240 + goto err_exit; 3241 + } 3242 + } 3320 3243 3321 3244 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, 3322 3245 ARRAY_SIZE(tpacpi_hotkey_qtable)); ··· 3542 3437 3543 3438 err_exit: 3544 3439 delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); 3440 + sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3441 + &adaptive_kbd_attr_group); 3442 + 3545 3443 hotkey_dev_attributes = NULL; 3546 3444 3547 3445 return (res < 0) ? res : 1; ··· 3557 3449 * Will consider support rest of modes in future. 3558 3450 * 3559 3451 */ 3560 - enum ADAPTIVE_KEY_MODE { 3561 - HOME_MODE, 3562 - WEB_BROWSER_MODE, 3563 - WEB_CONFERENCE_MODE, 3564 - FUNCTION_MODE, 3565 - LAYFLAT_MODE 3566 - }; 3567 - 3568 3452 static const int adaptive_keyboard_modes[] = { 3569 3453 HOME_MODE, 3570 3454 /* WEB_BROWSER_MODE = 2, ··· 3566 3466 3567 3467 #define DFR_CHANGE_ROW 0x101 3568 3468 #define DFR_SHOW_QUICKVIEW_ROW 0x102 3469 + #define FIRST_ADAPTIVE_KEY 0x103 3470 + #define ADAPTIVE_KEY_OFFSET 0x020 3569 3471 3570 3472 /* press Fn key a while second, it will switch to Function Mode. Then 3571 3473 * release Fn key, previous mode be restored. 3572 3474 */ 3573 3475 static bool adaptive_keyboard_mode_is_saved; 3574 3476 static int adaptive_keyboard_prev_mode; 3477 + 3478 + static int adaptive_keyboard_get_mode(void) 3479 + { 3480 + int mode = 0; 3481 + 3482 + if (!acpi_evalf(hkey_handle, &mode, "GTRW", "dd", 0)) { 3483 + pr_err("Cannot read adaptive keyboard mode\n"); 3484 + return -EIO; 3485 + } 3486 + 3487 + return mode; 3488 + } 3489 + 3490 + static int adaptive_keyboard_set_mode(int new_mode) 3491 + { 3492 + if (new_mode < 0 || 3493 + new_mode > LAYFLAT_MODE) 3494 + return -EINVAL; 3495 + 3496 + if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", new_mode)) { 3497 + pr_err("Cannot set adaptive keyboard mode\n"); 3498 + return -EIO; 3499 + } 3500 + 3501 + return 0; 3502 + } 3575 3503 3576 3504 static int adaptive_keyboard_get_next_mode(int mode) 3577 3505 { ··· 3621 3493 3622 3494 static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode) 3623 3495 { 3624 - u32 current_mode = 0; 3496 + int current_mode = 0; 3625 3497 int new_mode = 0; 3498 + int keycode; 3626 3499 3627 3500 switch (scancode) { 3628 3501 case DFR_CHANGE_ROW: ··· 3631 3502 new_mode = adaptive_keyboard_prev_mode; 3632 3503 adaptive_keyboard_mode_is_saved = false; 3633 3504 } else { 3634 - if (!acpi_evalf( 3635 - hkey_handle, &current_mode, 3636 - "GTRW", "dd", 0)) { 3637 - pr_err("Cannot read adaptive keyboard mode\n"); 3505 + current_mode = adaptive_keyboard_get_mode(); 3506 + if (current_mode < 0) 3638 3507 return false; 3639 - } else { 3640 - new_mode = adaptive_keyboard_get_next_mode( 3641 - current_mode); 3642 - } 3508 + new_mode = adaptive_keyboard_get_next_mode( 3509 + current_mode); 3643 3510 } 3644 3511 3645 - if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", new_mode)) { 3646 - pr_err("Cannot set adaptive keyboard mode\n"); 3512 + if (adaptive_keyboard_set_mode(new_mode) < 0) 3647 3513 return false; 3648 - } 3649 3514 3650 3515 return true; 3651 3516 3652 3517 case DFR_SHOW_QUICKVIEW_ROW: 3653 - if (!acpi_evalf(hkey_handle, 3654 - &adaptive_keyboard_prev_mode, 3655 - "GTRW", "dd", 0)) { 3656 - pr_err("Cannot read adaptive keyboard mode\n"); 3518 + current_mode = adaptive_keyboard_get_mode(); 3519 + if (current_mode < 0) 3657 3520 return false; 3658 - } else { 3659 - adaptive_keyboard_mode_is_saved = true; 3660 3521 3661 - if (!acpi_evalf(hkey_handle, 3662 - NULL, "STRW", "vd", FUNCTION_MODE)) { 3663 - pr_err("Cannot set adaptive keyboard mode\n"); 3664 - return false; 3665 - } 3666 - } 3522 + adaptive_keyboard_prev_mode = current_mode; 3523 + adaptive_keyboard_mode_is_saved = true; 3524 + 3525 + if (adaptive_keyboard_set_mode (FUNCTION_MODE) < 0) 3526 + return false; 3667 3527 return true; 3668 3528 3669 3529 default: 3670 - return false; 3530 + if (scancode < FIRST_ADAPTIVE_KEY || 3531 + scancode >= FIRST_ADAPTIVE_KEY + TPACPI_HOTKEY_MAP_LEN - 3532 + ADAPTIVE_KEY_OFFSET) { 3533 + pr_info("Unhandled adaptive keyboard key: 0x%x\n", 3534 + scancode); 3535 + return false; 3536 + } 3537 + keycode = hotkey_keycode_map[scancode - FIRST_ADAPTIVE_KEY + ADAPTIVE_KEY_OFFSET]; 3538 + if (keycode != KEY_RESERVED) { 3539 + mutex_lock(&tpacpi_inputdev_send_mutex); 3540 + 3541 + input_report_key(tpacpi_inputdev, keycode, 1); 3542 + input_sync(tpacpi_inputdev); 3543 + 3544 + input_report_key(tpacpi_inputdev, keycode, 0); 3545 + input_sync(tpacpi_inputdev); 3546 + 3547 + mutex_unlock(&tpacpi_inputdev_send_mutex); 3548 + } 3549 + return true; 3671 3550 } 3672 3551 } 3673 3552 ··· 3973 3836 3974 3837 static void hotkey_suspend(void) 3975 3838 { 3976 - int hkeyv; 3977 - 3978 3839 /* Do these on suspend, we get the events on early resume! */ 3979 3840 hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE; 3980 3841 hotkey_autosleep_ack = 0; 3981 3842 3982 3843 /* save previous mode of adaptive keyboard of X1 Carbon */ 3983 - if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 3984 - if ((hkeyv >> 8) == 2) { 3985 - if (!acpi_evalf(hkey_handle, 3986 - &adaptive_keyboard_prev_mode, 3987 - "GTRW", "dd", 0)) { 3988 - pr_err("Cannot read adaptive keyboard mode.\n"); 3989 - } 3844 + if (tp_features.has_adaptive_kbd) { 3845 + if (!acpi_evalf(hkey_handle, &adaptive_keyboard_prev_mode, 3846 + "GTRW", "dd", 0)) { 3847 + pr_err("Cannot read adaptive keyboard mode.\n"); 3990 3848 } 3991 3849 } 3992 3850 } 3993 3851 3994 3852 static void hotkey_resume(void) 3995 3853 { 3996 - int hkeyv; 3997 - 3998 3854 tpacpi_disable_brightness_delay(); 3999 3855 4000 3856 if (hotkey_status_set(true) < 0 || ··· 4002 3872 hotkey_poll_setup_safe(false); 4003 3873 4004 3874 /* restore previous mode of adapive keyboard of X1 Carbon */ 4005 - if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 4006 - if ((hkeyv >> 8) == 2) { 4007 - if (!acpi_evalf(hkey_handle, 4008 - NULL, 4009 - "STRW", "vd", 4010 - adaptive_keyboard_prev_mode)) { 4011 - pr_err("Cannot set adaptive keyboard mode.\n"); 4012 - } 3875 + if (tp_features.has_adaptive_kbd) { 3876 + if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", 3877 + adaptive_keyboard_prev_mode)) { 3878 + pr_err("Cannot set adaptive keyboard mode.\n"); 4013 3879 } 4014 3880 } 4015 3881 } ··· 4205 4079 attr, buf, count); 4206 4080 } 4207 4081 4208 - static struct device_attribute dev_attr_bluetooth_enable = 4209 - __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO, 4210 - bluetooth_enable_show, bluetooth_enable_store); 4082 + static DEVICE_ATTR_RW(bluetooth_enable); 4211 4083 4212 4084 /* --------------------------------------------------------------------- */ 4213 4085 ··· 4393 4269 attr, buf, count); 4394 4270 } 4395 4271 4396 - static struct device_attribute dev_attr_wan_enable = 4397 - __ATTR(wwan_enable, S_IWUSR | S_IRUGO, 4398 - wan_enable_show, wan_enable_store); 4272 + static DEVICE_ATTR_RW(wan_enable); 4399 4273 4400 4274 /* --------------------------------------------------------------------- */ 4401 4275 ··· 5170 5048 return (res) ? res : count; 5171 5049 } 5172 5050 5173 - static struct device_attribute dev_attr_cmos_command = 5174 - __ATTR(cmos_command, S_IWUSR, NULL, cmos_command_store); 5051 + static DEVICE_ATTR_WO(cmos_command); 5175 5052 5176 5053 /* --------------------------------------------------------------------- */ 5177 5054 ··· 8138 8017 return count; 8139 8018 } 8140 8019 8141 - static struct device_attribute dev_attr_fan_pwm1_enable = 8142 - __ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 8143 - fan_pwm1_enable_show, fan_pwm1_enable_store); 8020 + static DEVICE_ATTR_RW(fan_pwm1_enable); 8144 8021 8145 8022 /* sysfs fan pwm1 ------------------------------------------------------ */ 8146 8023 static ssize_t fan_pwm1_show(struct device *dev, ··· 8198 8079 return (rc) ? rc : count; 8199 8080 } 8200 8081 8201 - static struct device_attribute dev_attr_fan_pwm1 = 8202 - __ATTR(pwm1, S_IWUSR | S_IRUGO, 8203 - fan_pwm1_show, fan_pwm1_store); 8082 + static DEVICE_ATTR_RW(fan_pwm1); 8204 8083 8205 8084 /* sysfs fan fan1_input ------------------------------------------------ */ 8206 8085 static ssize_t fan_fan1_input_show(struct device *dev, ··· 8215 8098 return snprintf(buf, PAGE_SIZE, "%u\n", speed); 8216 8099 } 8217 8100 8218 - static struct device_attribute dev_attr_fan_fan1_input = 8219 - __ATTR(fan1_input, S_IRUGO, 8220 - fan_fan1_input_show, NULL); 8101 + static DEVICE_ATTR_RO(fan_fan1_input); 8221 8102 8222 8103 /* sysfs fan fan2_input ------------------------------------------------ */ 8223 8104 static ssize_t fan_fan2_input_show(struct device *dev, ··· 8232 8117 return snprintf(buf, PAGE_SIZE, "%u\n", speed); 8233 8118 } 8234 8119 8235 - static struct device_attribute dev_attr_fan_fan2_input = 8236 - __ATTR(fan2_input, S_IRUGO, 8237 - fan_fan2_input_show, NULL); 8120 + static DEVICE_ATTR_RO(fan_fan2_input); 8238 8121 8239 8122 /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ 8240 8123 static ssize_t fan_fan_watchdog_show(struct device_driver *drv, ··· 8848 8735 return snprintf(buf, PAGE_SIZE, "%s\n", TPACPI_NAME); 8849 8736 } 8850 8737 8851 - static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = 8852 - __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); 8738 + static DEVICE_ATTR_RO(thinkpad_acpi_pdev_name); 8853 8739 8854 8740 /* --------------------------------------------------------------------- */ 8855 8741
+197 -61
drivers/platform/x86/toshiba_acpi.c
··· 51 51 #include <linux/acpi.h> 52 52 #include <linux/dmi.h> 53 53 #include <linux/uaccess.h> 54 + #include <acpi/video.h> 54 55 55 56 MODULE_AUTHOR("John Belmonte"); 56 57 MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); ··· 117 116 #define HCI_KBD_ILLUMINATION 0x0095 118 117 #define HCI_ECO_MODE 0x0097 119 118 #define HCI_ACCELEROMETER2 0x00a6 119 + #define HCI_SYSTEM_INFO 0xc000 120 120 #define SCI_PANEL_POWER_ON 0x010d 121 121 #define SCI_ILLUMINATION 0x014e 122 122 #define SCI_USB_SLEEP_CHARGE 0x0150 ··· 131 129 #define HCI_ACCEL_MASK 0x7fff 132 130 #define HCI_HOTKEY_DISABLE 0x0b 133 131 #define HCI_HOTKEY_ENABLE 0x09 132 + #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 134 133 #define HCI_LCD_BRIGHTNESS_BITS 3 135 134 #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) 136 135 #define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) 137 136 #define HCI_MISC_SHIFT 0x10 137 + #define HCI_SYSTEM_TYPE1 0x10 138 + #define HCI_SYSTEM_TYPE2 0x11 138 139 #define HCI_VIDEO_OUT_LCD 0x1 139 140 #define HCI_VIDEO_OUT_CRT 0x2 140 141 #define HCI_VIDEO_OUT_TV 0x4 ··· 152 147 #define SCI_KBD_MODE_OFF 0x10 153 148 #define SCI_KBD_TIME_MAX 0x3c001a 154 149 #define SCI_USB_CHARGE_MODE_MASK 0xff 155 - #define SCI_USB_CHARGE_DISABLED 0x30000 156 - #define SCI_USB_CHARGE_ALTERNATE 0x30009 157 - #define SCI_USB_CHARGE_AUTO 0x30021 150 + #define SCI_USB_CHARGE_DISABLED 0x00 151 + #define SCI_USB_CHARGE_ALTERNATE 0x09 152 + #define SCI_USB_CHARGE_TYPICAL 0x11 153 + #define SCI_USB_CHARGE_AUTO 0x21 158 154 #define SCI_USB_CHARGE_BAT_MASK 0x7 159 155 #define SCI_USB_CHARGE_BAT_LVL_OFF 0x1 160 156 #define SCI_USB_CHARGE_BAT_LVL_ON 0x4 ··· 180 174 int kbd_mode; 181 175 int kbd_time; 182 176 int usbsc_bat_level; 177 + int usbsc_mode_base; 178 + int hotkey_event_type; 183 179 184 180 unsigned int illumination_supported:1; 185 181 unsigned int video_supported:1; ··· 251 243 { KE_END, 0 }, 252 244 }; 253 245 254 - /* alternative keymap */ 255 - static const struct dmi_system_id toshiba_alt_keymap_dmi[] = { 256 - { 257 - .matches = { 258 - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 259 - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M840"), 260 - }, 261 - }, 262 - { 263 - .matches = { 264 - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 265 - DMI_MATCH(DMI_PRODUCT_NAME, "Qosmio X75-A"), 266 - }, 267 - }, 268 - { 269 - .matches = { 270 - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 271 - DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A50-A"), 272 - }, 273 - }, 274 - {} 275 - }; 276 - 277 246 static const struct key_entry toshiba_acpi_alt_keymap[] = { 278 247 { KE_KEY, 0x157, { KEY_MUTE } }, 279 248 { KE_KEY, 0x102, { KEY_ZOOMOUT } }, ··· 263 278 { KE_KEY, 0x158, { KEY_WLAN } }, 264 279 { KE_KEY, 0x13f, { KEY_TOUCHPAD_TOGGLE } }, 265 280 { KE_END, 0 }, 281 + }; 282 + 283 + /* 284 + * List of models which have a broken acpi-video backlight interface and thus 285 + * need to use the toshiba (vendor) interface instead. 286 + */ 287 + static const struct dmi_system_id toshiba_vendor_backlight_dmi[] = { 288 + {} 266 289 }; 267 290 268 291 /* ··· 812 819 } 813 820 814 821 /* Sleep (Charge and Music) utilities support */ 822 + static void toshiba_usb_sleep_charge_available(struct toshiba_acpi_dev *dev) 823 + { 824 + u32 in[TCI_WORDS] = { SCI_GET, SCI_USB_SLEEP_CHARGE, 0, 0, 0, 0 }; 825 + u32 out[TCI_WORDS]; 826 + acpi_status status; 827 + 828 + /* Set the feature to "not supported" in case of error */ 829 + dev->usb_sleep_charge_supported = 0; 830 + 831 + if (!sci_open(dev)) 832 + return; 833 + 834 + status = tci_raw(dev, in, out); 835 + if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { 836 + pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); 837 + sci_close(dev); 838 + return; 839 + } else if (out[0] == TOS_NOT_SUPPORTED) { 840 + pr_info("USB Sleep and Charge not supported\n"); 841 + sci_close(dev); 842 + return; 843 + } else if (out[0] == TOS_SUCCESS) { 844 + dev->usbsc_mode_base = out[4]; 845 + } 846 + 847 + in[5] = SCI_USB_CHARGE_BAT_LVL; 848 + status = tci_raw(dev, in, out); 849 + if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { 850 + pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); 851 + sci_close(dev); 852 + return; 853 + } else if (out[0] == TOS_NOT_SUPPORTED) { 854 + pr_info("USB Sleep and Charge not supported\n"); 855 + sci_close(dev); 856 + return; 857 + } else if (out[0] == TOS_SUCCESS) { 858 + dev->usbsc_bat_level = out[2]; 859 + /* 860 + * If we reach this point, it means that the laptop has support 861 + * for this feature and all values are initialized. 862 + * Set it as supported. 863 + */ 864 + dev->usb_sleep_charge_supported = 1; 865 + } 866 + 867 + sci_close(dev); 868 + } 869 + 815 870 static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, 816 871 u32 *mode) 817 872 { ··· 975 934 status = tci_raw(dev, in, out); 976 935 sci_close(dev); 977 936 if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { 978 - pr_err("ACPI call to get USB S&C battery level failed\n"); 937 + pr_err("ACPI call to get USB Rapid Charge failed\n"); 979 938 return -EIO; 980 939 } else if (out[0] == TOS_NOT_SUPPORTED || 981 940 out[0] == TOS_INPUT_DATA_ERROR) { 982 - pr_info("USB Sleep and Charge not supported\n"); 941 + pr_info("USB Rapid Charge not supported\n"); 983 942 return -ENODEV; 984 943 } 985 944 ··· 1003 962 status = tci_raw(dev, in, out); 1004 963 sci_close(dev); 1005 964 if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { 1006 - pr_err("ACPI call to set USB S&C battery level failed\n"); 965 + pr_err("ACPI call to set USB Rapid Charge failed\n"); 1007 966 return -EIO; 1008 967 } else if (out[0] == TOS_NOT_SUPPORTED) { 1009 - pr_info("USB Sleep and Charge not supported\n"); 968 + pr_info("USB Rapid Charge not supported\n"); 1010 969 return -ENODEV; 1011 970 } else if (out[0] == TOS_INPUT_DATA_ERROR) { 1012 971 return -EIO; ··· 1025 984 result = sci_read(dev, SCI_USB_SLEEP_MUSIC, state); 1026 985 sci_close(dev); 1027 986 if (result == TOS_FAILURE) { 1028 - pr_err("ACPI call to set USB S&C mode failed\n"); 987 + pr_err("ACPI call to get Sleep and Music failed\n"); 1029 988 return -EIO; 1030 989 } else if (result == TOS_NOT_SUPPORTED) { 1031 - pr_info("USB Sleep and Charge not supported\n"); 990 + pr_info("Sleep and Music not supported\n"); 1032 991 return -ENODEV; 1033 992 } else if (result == TOS_INPUT_DATA_ERROR) { 1034 993 return -EIO; ··· 1047 1006 result = sci_write(dev, SCI_USB_SLEEP_MUSIC, state); 1048 1007 sci_close(dev); 1049 1008 if (result == TOS_FAILURE) { 1050 - pr_err("ACPI call to set USB S&C mode failed\n"); 1009 + pr_err("ACPI call to set Sleep and Music failed\n"); 1051 1010 return -EIO; 1052 1011 } else if (result == TOS_NOT_SUPPORTED) { 1053 - pr_info("USB Sleep and Charge not supported\n"); 1012 + pr_info("Sleep and Music not supported\n"); 1054 1013 return -ENODEV; 1055 1014 } else if (result == TOS_INPUT_DATA_ERROR) { 1056 1015 return -EIO; ··· 1186 1145 } else if (result == TOS_INPUT_DATA_ERROR) { 1187 1146 return -EIO; 1188 1147 } 1148 + 1149 + return 0; 1150 + } 1151 + 1152 + /* Hotkey Event type */ 1153 + static int toshiba_hotkey_event_type_get(struct toshiba_acpi_dev *dev, 1154 + u32 *type) 1155 + { 1156 + u32 val1 = 0x03; 1157 + u32 val2 = 0; 1158 + u32 result; 1159 + 1160 + result = hci_read2(dev, HCI_SYSTEM_INFO, &val1, &val2); 1161 + if (result == TOS_FAILURE) { 1162 + pr_err("ACPI call to get System type failed\n"); 1163 + return -EIO; 1164 + } else if (result == TOS_NOT_SUPPORTED) { 1165 + pr_info("System type not supported\n"); 1166 + return -ENODEV; 1167 + } 1168 + 1169 + *type = val2; 1189 1170 1190 1171 return 0; 1191 1172 } ··· 2036 1973 * 0 - Disabled 2037 1974 * 1 - Alternate (Non USB conformant devices that require more power) 2038 1975 * 2 - Auto (USB conformant devices) 1976 + * 3 - Typical 2039 1977 */ 2040 - if (state != 0 && state != 1 && state != 2) 1978 + if (state != 0 && state != 1 && state != 2 && state != 3) 2041 1979 return -EINVAL; 2042 1980 2043 1981 /* Set the USB charging mode to internal value */ 1982 + mode = toshiba->usbsc_mode_base; 2044 1983 if (state == 0) 2045 - mode = SCI_USB_CHARGE_DISABLED; 1984 + mode |= SCI_USB_CHARGE_DISABLED; 2046 1985 else if (state == 1) 2047 - mode = SCI_USB_CHARGE_ALTERNATE; 1986 + mode |= SCI_USB_CHARGE_ALTERNATE; 2048 1987 else if (state == 2) 2049 - mode = SCI_USB_CHARGE_AUTO; 1988 + mode |= SCI_USB_CHARGE_AUTO; 1989 + else if (state == 3) 1990 + mode |= SCI_USB_CHARGE_TYPICAL; 2050 1991 2051 1992 ret = toshiba_usb_sleep_charge_set(toshiba, mode); 2052 1993 if (ret) ··· 2400 2333 return 0; 2401 2334 } 2402 2335 2336 + static void toshiba_acpi_enable_special_functions(struct toshiba_acpi_dev *dev) 2337 + { 2338 + u32 result; 2339 + 2340 + /* 2341 + * Re-activate the hotkeys, but this time, we are using the 2342 + * "Special Functions" mode. 2343 + */ 2344 + result = hci_write1(dev, HCI_HOTKEY_EVENT, 2345 + HCI_HOTKEY_SPECIAL_FUNCTIONS); 2346 + if (result != TOS_SUCCESS) 2347 + pr_err("Could not enable the Special Function mode\n"); 2348 + } 2349 + 2403 2350 static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, 2404 2351 struct serio *port) 2405 2352 { ··· 2515 2434 2516 2435 static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) 2517 2436 { 2518 - acpi_handle ec_handle; 2519 - int error; 2520 - u32 hci_result; 2521 2437 const struct key_entry *keymap = toshiba_acpi_keymap; 2438 + acpi_handle ec_handle; 2439 + u32 events_type; 2440 + u32 hci_result; 2441 + int error; 2442 + 2443 + error = toshiba_acpi_enable_hotkeys(dev); 2444 + if (error) 2445 + return error; 2446 + 2447 + error = toshiba_hotkey_event_type_get(dev, &events_type); 2448 + if (error) { 2449 + pr_err("Unable to query Hotkey Event Type\n"); 2450 + return error; 2451 + } 2452 + dev->hotkey_event_type = events_type; 2522 2453 2523 2454 dev->hotkey_dev = input_allocate_device(); 2524 2455 if (!dev->hotkey_dev) ··· 2540 2447 dev->hotkey_dev->phys = "toshiba_acpi/input0"; 2541 2448 dev->hotkey_dev->id.bustype = BUS_HOST; 2542 2449 2543 - if (dmi_check_system(toshiba_alt_keymap_dmi)) 2450 + if (events_type == HCI_SYSTEM_TYPE1 || 2451 + !dev->kbd_function_keys_supported) 2452 + keymap = toshiba_acpi_keymap; 2453 + else if (events_type == HCI_SYSTEM_TYPE2 || 2454 + dev->kbd_function_keys_supported) 2544 2455 keymap = toshiba_acpi_alt_keymap; 2456 + else 2457 + pr_info("Unknown event type received %x\n", events_type); 2545 2458 error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL); 2546 2459 if (error) 2547 2460 goto err_free_dev; ··· 2586 2487 2587 2488 if (!dev->info_supported && !dev->system_event_supported) { 2588 2489 pr_warn("No hotkey query interface found\n"); 2589 - goto err_remove_filter; 2590 - } 2591 - 2592 - error = toshiba_acpi_enable_hotkeys(dev); 2593 - if (error) { 2594 - pr_info("Unable to enable hotkeys\n"); 2595 2490 goto err_remove_filter; 2596 2491 } 2597 2492 ··· 2633 2540 /* Determine whether or not BIOS supports transflective backlight */ 2634 2541 ret = get_tr_backlight_status(dev, &enabled); 2635 2542 dev->tr_backlight_supported = !ret; 2543 + 2544 + /* 2545 + * Tell acpi-video-detect code to prefer vendor backlight on all 2546 + * systems with transflective backlight and on dmi matched systems. 2547 + */ 2548 + if (dev->tr_backlight_supported || 2549 + dmi_check_system(toshiba_vendor_backlight_dmi)) 2550 + acpi_video_dmi_promote_vendor(); 2551 + 2552 + if (acpi_video_backlight_support()) 2553 + return 0; 2554 + 2555 + /* acpi-video may have loaded before we called dmi_promote_vendor() */ 2556 + acpi_video_unregister_backlight(); 2636 2557 2637 2558 memset(&props, 0, sizeof(props)); 2638 2559 props.type = BACKLIGHT_PLATFORM; ··· 2731 2624 { 2732 2625 struct toshiba_acpi_dev *dev; 2733 2626 const char *hci_method; 2627 + u32 special_functions; 2734 2628 u32 dummy; 2735 2629 bool bt_present; 2736 2630 int ret = 0; ··· 2755 2647 dev->method_hci = hci_method; 2756 2648 acpi_dev->driver_data = dev; 2757 2649 dev_set_drvdata(&acpi_dev->dev, dev); 2650 + 2651 + /* Query the BIOS for supported features */ 2652 + 2653 + /* 2654 + * The "Special Functions" are always supported by the laptops 2655 + * with the new keyboard layout, query for its presence to help 2656 + * determine the keymap layout to use. 2657 + */ 2658 + ret = toshiba_function_keys_get(dev, &special_functions); 2659 + dev->kbd_function_keys_supported = !ret; 2758 2660 2759 2661 if (toshiba_acpi_setup_keyboard(dev)) 2760 2662 pr_info("Unable to activate hotkeys\n"); ··· 2834 2716 ret = toshiba_accelerometer_supported(dev); 2835 2717 dev->accelerometer_supported = !ret; 2836 2718 2837 - ret = toshiba_usb_sleep_charge_get(dev, &dummy); 2838 - dev->usb_sleep_charge_supported = !ret; 2719 + toshiba_usb_sleep_charge_available(dev); 2839 2720 2840 2721 ret = toshiba_usb_rapid_charge_get(dev, &dummy); 2841 2722 dev->usb_rapid_charge_supported = !ret; ··· 2842 2725 ret = toshiba_usb_sleep_music_get(dev, &dummy); 2843 2726 dev->usb_sleep_music_supported = !ret; 2844 2727 2845 - ret = toshiba_function_keys_get(dev, &dummy); 2846 - dev->kbd_function_keys_supported = !ret; 2847 - 2848 2728 ret = toshiba_panel_power_on_get(dev, &dummy); 2849 2729 dev->panel_power_on_supported = !ret; 2850 2730 2851 2731 ret = toshiba_usb_three_get(dev, &dummy); 2852 2732 dev->usb_three_supported = !ret; 2853 2733 2854 - /* Determine whether or not BIOS supports fan and video interfaces */ 2855 - 2856 2734 ret = get_video_status(dev, &dummy); 2857 2735 dev->video_supported = !ret; 2858 2736 2859 2737 ret = get_fan_status(dev, &dummy); 2860 2738 dev->fan_supported = !ret; 2739 + 2740 + /* 2741 + * Enable the "Special Functions" mode only if they are 2742 + * supported and if they are activated. 2743 + */ 2744 + if (dev->kbd_function_keys_supported && special_functions) 2745 + toshiba_acpi_enable_special_functions(dev); 2861 2746 2862 2747 ret = sysfs_create_group(&dev->acpi_dev->dev.kobj, 2863 2748 &toshiba_attr_group); ··· 2889 2770 case 0x80: /* Hotkeys and some system events */ 2890 2771 toshiba_acpi_process_hotkeys(dev); 2891 2772 break; 2773 + case 0x81: /* Dock events */ 2774 + case 0x82: 2775 + case 0x83: 2776 + pr_info("Dock event received %x\n", event); 2777 + break; 2778 + case 0x88: /* Thermal events */ 2779 + pr_info("Thermal event received\n"); 2780 + break; 2781 + case 0x8f: /* LID closed */ 2782 + case 0x90: /* LID is closed and Dock has been ejected */ 2783 + break; 2784 + case 0x8c: /* SATA power events */ 2785 + case 0x8b: 2786 + pr_info("SATA power event received %x\n", event); 2787 + break; 2892 2788 case 0x92: /* Keyboard backlight mode changed */ 2893 2789 /* Update sysfs entries */ 2894 2790 ret = sysfs_update_group(&acpi_dev->dev.kobj, ··· 2911 2777 if (ret) 2912 2778 pr_err("Unable to update sysfs entries\n"); 2913 2779 break; 2914 - case 0x81: /* Unknown */ 2915 - case 0x82: /* Unknown */ 2916 - case 0x83: /* Unknown */ 2917 - case 0x8c: /* Unknown */ 2780 + case 0x85: /* Unknown */ 2781 + case 0x8d: /* Unknown */ 2918 2782 case 0x8e: /* Unknown */ 2919 - case 0x8f: /* Unknown */ 2920 - case 0x90: /* Unknown */ 2783 + case 0x94: /* Unknown */ 2784 + case 0x95: /* Unknown */ 2921 2785 default: 2922 2786 pr_info("Unknown event received %x\n", event); 2923 2787 break; 2924 2788 } 2789 + 2790 + acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class, 2791 + dev_name(&acpi_dev->dev), 2792 + event, 0); 2925 2793 } 2926 2794 2927 2795 #ifdef CONFIG_PM_SLEEP
+104 -29
drivers/platform/x86/toshiba_bluetooth.c
··· 2 2 * Toshiba Bluetooth Enable Driver 3 3 * 4 4 * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com> 5 + * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com> 5 6 * 6 7 * Thanks to Matthew Garrett for background info on ACPI innards which 7 8 * normal people aren't meant to understand :-) ··· 25 24 #include <linux/init.h> 26 25 #include <linux/types.h> 27 26 #include <linux/acpi.h> 27 + 28 + #define BT_KILLSWITCH_MASK 0x01 29 + #define BT_PLUGGED_MASK 0x40 30 + #define BT_POWER_MASK 0x80 28 31 29 32 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); 30 33 MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver"); ··· 62 57 .drv.pm = &toshiba_bt_pm, 63 58 }; 64 59 60 + static int toshiba_bluetooth_present(acpi_handle handle) 61 + { 62 + acpi_status result; 63 + u64 bt_present; 64 + 65 + /* 66 + * Some Toshiba laptops may have a fake TOS6205 device in 67 + * their ACPI BIOS, so query the _STA method to see if there 68 + * is really anything there. 69 + */ 70 + result = acpi_evaluate_integer(handle, "_STA", NULL, &bt_present); 71 + if (ACPI_FAILURE(result)) { 72 + pr_err("ACPI call to query Bluetooth presence failed"); 73 + return -ENXIO; 74 + } else if (!bt_present) { 75 + pr_info("Bluetooth device not present\n"); 76 + return -ENODEV; 77 + } 78 + 79 + return 0; 80 + } 81 + 82 + static int toshiba_bluetooth_status(acpi_handle handle) 83 + { 84 + acpi_status result; 85 + u64 status; 86 + 87 + result = acpi_evaluate_integer(handle, "BTST", NULL, &status); 88 + if (ACPI_FAILURE(result)) { 89 + pr_err("Could not get Bluetooth device status\n"); 90 + return -ENXIO; 91 + } 92 + 93 + pr_info("Bluetooth status %llu\n", status); 94 + 95 + return status; 96 + } 65 97 66 98 static int toshiba_bluetooth_enable(acpi_handle handle) 67 99 { 68 - acpi_status res1, res2; 69 - u64 result; 100 + acpi_status result; 101 + bool killswitch; 102 + bool powered; 103 + bool plugged; 104 + int status; 70 105 71 106 /* 72 107 * Query ACPI to verify RFKill switch is set to 'on'. 73 108 * If not, we return silently, no need to report it as 74 109 * an error. 75 110 */ 76 - res1 = acpi_evaluate_integer(handle, "BTST", NULL, &result); 77 - if (ACPI_FAILURE(res1)) 78 - return res1; 79 - if (!(result & 0x01)) 111 + status = toshiba_bluetooth_status(handle); 112 + if (status < 0) 113 + return status; 114 + 115 + killswitch = (status & BT_KILLSWITCH_MASK) ? true : false; 116 + powered = (status & BT_POWER_MASK) ? true : false; 117 + plugged = (status & BT_PLUGGED_MASK) ? true : false; 118 + 119 + if (!killswitch) 120 + return 0; 121 + /* 122 + * This check ensures to only enable the device if it is powered 123 + * off or detached, as some recent devices somehow pass the killswitch 124 + * test, causing a loop enabling/disabling the device, see bug 93911. 125 + */ 126 + if (powered || plugged) 80 127 return 0; 81 128 82 - pr_info("Re-enabling Toshiba Bluetooth\n"); 83 - res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL); 84 - res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL); 85 - if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2)) 86 - return 0; 129 + result = acpi_evaluate_object(handle, "AUSB", NULL, NULL); 130 + if (ACPI_FAILURE(result)) { 131 + pr_err("Could not attach USB Bluetooth device\n"); 132 + return -ENXIO; 133 + } 87 134 88 - pr_warn("Failed to re-enable Toshiba Bluetooth\n"); 135 + result = acpi_evaluate_object(handle, "BTPO", NULL, NULL); 136 + if (ACPI_FAILURE(result)) { 137 + pr_err("Could not power ON Bluetooth device\n"); 138 + return -ENXIO; 139 + } 89 140 90 - return -ENODEV; 141 + return 0; 142 + } 143 + 144 + static int toshiba_bluetooth_disable(acpi_handle handle) 145 + { 146 + acpi_status result; 147 + 148 + result = acpi_evaluate_object(handle, "BTPF", NULL, NULL); 149 + if (ACPI_FAILURE(result)) { 150 + pr_err("Could not power OFF Bluetooth device\n"); 151 + return -ENXIO; 152 + } 153 + 154 + result = acpi_evaluate_object(handle, "DUSB", NULL, NULL); 155 + if (ACPI_FAILURE(result)) { 156 + pr_err("Could not detach USB Bluetooth device\n"); 157 + return -ENXIO; 158 + } 159 + 160 + return 0; 91 161 } 92 162 93 163 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) ··· 179 99 180 100 static int toshiba_bt_rfkill_add(struct acpi_device *device) 181 101 { 182 - acpi_status status; 183 - u64 bt_present; 184 - int result = -ENODEV; 102 + int result; 185 103 186 - /* 187 - * Some Toshiba laptops may have a fake TOS6205 device in 188 - * their ACPI BIOS, so query the _STA method to see if there 189 - * is really anything there, before trying to enable it. 190 - */ 191 - status = acpi_evaluate_integer(device->handle, "_STA", NULL, 192 - &bt_present); 104 + result = toshiba_bluetooth_present(device->handle); 105 + if (result) 106 + return result; 193 107 194 - if (!ACPI_FAILURE(status) && bt_present) { 195 - pr_info("Detected Toshiba ACPI Bluetooth device - " 196 - "installing RFKill handler\n"); 197 - result = toshiba_bluetooth_enable(device->handle); 198 - } 108 + pr_info("Toshiba ACPI Bluetooth device driver\n"); 109 + 110 + /* Enable the BT device */ 111 + result = toshiba_bluetooth_enable(device->handle); 112 + if (result) 113 + return result; 199 114 200 115 return result; 201 116 } ··· 198 123 static int toshiba_bt_rfkill_remove(struct acpi_device *device) 199 124 { 200 125 /* clean up */ 201 - return 0; 126 + return toshiba_bluetooth_disable(device->handle); 202 127 } 203 128 204 129 module_acpi_driver(toshiba_bt_rfkill_driver);
+2 -3
drivers/platform/x86/wmi.c
··· 45 45 46 46 #define ACPI_WMI_CLASS "wmi" 47 47 48 - static DEFINE_MUTEX(wmi_data_lock); 49 48 static LIST_HEAD(wmi_block_list); 50 49 51 50 struct guid_block { ··· 239 240 if (memcmp(block->guid, guid_input, 16) == 0) { 240 241 if (out) 241 242 *out = wblock; 242 - return 1; 243 + return true; 243 244 } 244 245 } 245 - return 0; 246 + return false; 246 247 } 247 248 248 249 static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)