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

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

Pull x86 platform driver updates from Darren Hart:
"Significant work on toshiba_acpi, including new hardware support,
refactoring, and cleanups. Extend device support for asus, ideapad,
and acer systems. New surface pro 3 buttons driver. Misc minor
cleanups for thinkpad and hp-wireless.

acer-wmi:
- No rfkill on HP Omen 15 wifi

thinkpad_acpi:
- Remove side effects from vdbg_printk -> no_printk macro

surface pro 3:
- Add support driver for Surface Pro 3 buttons

hp-wireless:
- remove unneeded goto/label in hpwl_init

ideapad-laptop:
- add alternative representation for Yoga 2 to DMI table
- Add Lenovo Yoga 3 14 to no_hw_rfkill dmi list

asus-laptop:
- Add key found on Asus F3M

MAINTAINERS:
- Remove Toshiba Linux mailing list address

toshiba_acpi:
- Bump driver version to 0.23
- Remove unnecessary checks and returns in HCI/SCI functions
- Refactor *{get, set} functions return value
- Remove "*not supported" feature prints
- Change *available functions return type
- Add set_fan_status function
- Change some variables to avoid warnings from ninja-check
- Reorder toshiba_acpi_alt_keymap entries
- Remove unused wireless defines
- Transflective backlight updates
- Avoid registering input device on WMI event laptops
- Add /dev/toshiba_acpi device
- Adapt /proc/acpi/toshiba/keys to TOS1900 devices"

* tag 'platform-drivers-x86-v4.3-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: (21 commits)
acer-wmi: No rfkill on HP Omen 15 wifi
thinkpad_acpi: Remove side effects from vdbg_printk -> no_printk macro
surface pro 3: Add support driver for Surface Pro 3 buttons
hp-wireless: remove unneeded goto/label in hpwl_init
ideapad-laptop: add alternative representation for Yoga 2 to DMI table
asus-laptop: Add key found on Asus F3M
MAINTAINERS: Remove Toshiba Linux mailing list address
ideapad-laptop: Add Lenovo Yoga 3 14 to no_hw_rfkill dmi list
toshiba_acpi: Bump driver version to 0.23
toshiba_acpi: Remove unnecessary checks and returns in HCI/SCI functions
toshiba_acpi: Refactor *{get, set} functions return value
toshiba_acpi: Remove "*not supported" feature prints
toshiba_acpi: Change *available functions return type
toshiba_acpi: Add set_fan_status function
toshiba_acpi: Change some variables to avoid warnings from ninja-check
toshiba_acpi: Reorder toshiba_acpi_alt_keymap entries
toshiba_acpi: Remove unused wireless defines
toshiba_acpi: Transflective backlight updates
toshiba_acpi: Avoid registering input device on WMI event laptops
toshiba_acpi: Add /dev/toshiba_acpi device
...

+703 -390
+1 -1
Documentation/ioctl/ioctl-number.txt
··· 265 265 's' all linux/cdk.h 266 266 't' 00-7F linux/ppp-ioctl.h 267 267 't' 80-8F linux/isdn_ppp.h 268 - 't' 90 linux/toshiba.h 268 + 't' 90-91 linux/toshiba.h toshiba and toshiba_acpi SMM 269 269 'u' 00-1F linux/smb_fs.h gone 270 270 'u' 20-3F linux/uvcvideo.h USB video class host driver 271 271 'v' 00-1F linux/ext2_fs.h conflict!
+6 -1
MAINTAINERS
··· 6847 6847 S: Supported 6848 6848 F: arch/microblaze/ 6849 6849 6850 + MICROSOFT SURFACE PRO 3 BUTTON DRIVER 6851 + M: Chen Yu <yu.c.chen@intel.com> 6852 + L: platform-driver-x86@vger.kernel.org 6853 + S: Supported 6854 + F: drivers/platform/x86/surfacepro3_button.c 6855 + 6850 6856 MICROTEK X6 SCANNER 6851 6857 M: Oliver Neukum <oliver@neukum.org> 6852 6858 S: Maintained ··· 10495 10489 10496 10490 TOSHIBA SMM DRIVER 10497 10491 M: Jonathan Buzzard <jonathan@buzzard.org.uk> 10498 - L: tlinux-users@tce.toshiba-dme.co.jp 10499 10492 W: http://www.buzzard.org.uk/toshiba/ 10500 10493 S: Maintained 10501 10494 F: drivers/char/toshiba.c
+5
drivers/platform/x86/Kconfig
··· 919 919 The PMC is an ARC processor which defines IPC commands for communication 920 920 with other entities in the CPU. 921 921 922 + config SURFACE_PRO3_BUTTON 923 + tristate "Power/home/volume buttons driver for Microsoft Surface Pro 3 tablet" 924 + depends on ACPI && INPUT 925 + ---help--- 926 + This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3 tablet. 922 927 endif # X86_PLATFORM_DEVICES
+1
drivers/platform/x86/Makefile
··· 60 60 obj-$(CONFIG_PVPANIC) += pvpanic.o 61 61 obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o 62 62 obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o 63 + obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o
+1
drivers/platform/x86/acer-wmi.c
··· 807 807 { "IBM0068", 0}, 808 808 { "LEN0068", 0}, 809 809 { "SNY5001", 0}, /* sony-laptop in charge */ 810 + { "HPQ6601", 0}, 810 811 { "", 0}, 811 812 }; 812 813
+1
drivers/platform/x86/asus-laptop.c
··· 332 332 {KE_KEY, 0x65, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV */ 333 333 {KE_KEY, 0x66, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV */ 334 334 {KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */ 335 + {KE_KEY, 0x6A, { KEY_TOUCHPAD_TOGGLE } }, /* Lock Touchpad Fn + F9 */ 335 336 {KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, /* Lock Touchpad */ 336 337 {KE_KEY, 0x6C, { KEY_SLEEP } }, /* Suspend */ 337 338 {KE_KEY, 0x6D, { KEY_SLEEP } }, /* Hibernate */
+1 -6
drivers/platform/x86/hp-wireless.c
··· 114 114 115 115 pr_info("Initializing HPQ6001 module\n"); 116 116 err = acpi_bus_register_driver(&hpwl_driver); 117 - if (err) { 117 + if (err) 118 118 pr_err("Unable to register HP wireless control driver.\n"); 119 - goto error_acpi_register; 120 - } 121 119 122 - return 0; 123 - 124 - error_acpi_register: 125 120 return err; 126 121 } 127 122
+14
drivers/platform/x86/ideapad-laptop.c
··· 853 853 }, 854 854 }, 855 855 { 856 + .ident = "Lenovo Yoga 3 14", 857 + .matches = { 858 + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 859 + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 3 14"), 860 + }, 861 + }, 862 + { 863 + .ident = "Lenovo Yoga 2 11 / 13 / Pro", 864 + .matches = { 865 + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 866 + DMI_MATCH(DMI_BOARD_NAME, "Yoga2"), 867 + }, 868 + }, 869 + { 856 870 .ident = "Lenovo Yoga 3 Pro 1370", 857 871 .matches = { 858 872 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+216
drivers/platform/x86/surfacepro3_button.c
··· 1 + /* 2 + * power/home/volume button support for 3 + * Microsoft Surface Pro 3 tablet. 4 + * 5 + * Copyright (c) 2015 Intel Corporation. 6 + * All rights reserved. 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * as published by the Free Software Foundation; version 2 11 + * of the License. 12 + */ 13 + 14 + #include <linux/kernel.h> 15 + #include <linux/module.h> 16 + #include <linux/init.h> 17 + #include <linux/types.h> 18 + #include <linux/input.h> 19 + #include <linux/acpi.h> 20 + #include <acpi/button.h> 21 + 22 + #define SURFACE_BUTTON_HID "MSHW0028" 23 + #define SURFACE_BUTTON_OBJ_NAME "VGBI" 24 + #define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3 Buttons" 25 + 26 + #define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6 27 + #define SURFACE_BUTTON_NOTIFY_RELEASE_POWER 0xc7 28 + 29 + #define SURFACE_BUTTON_NOTIFY_PRESS_HOME 0xc4 30 + #define SURFACE_BUTTON_NOTIFY_RELEASE_HOME 0xc5 31 + 32 + #define SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_UP 0xc0 33 + #define SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_UP 0xc1 34 + 35 + #define SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_DOWN 0xc2 36 + #define SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_DOWN 0xc3 37 + 38 + ACPI_MODULE_NAME("surface pro 3 button"); 39 + 40 + MODULE_AUTHOR("Chen Yu"); 41 + MODULE_DESCRIPTION("Surface Pro3 Button Driver"); 42 + MODULE_LICENSE("GPL v2"); 43 + 44 + /* 45 + * Power button, Home button, Volume buttons support is supposed to 46 + * be covered by drivers/input/misc/soc_button_array.c, which is implemented 47 + * according to "Windows ACPI Design Guide for SoC Platforms". 48 + * However surface pro3 seems not to obey the specs, instead it uses 49 + * device VGBI(MSHW0028) for dispatching the events. 50 + * We choose acpi_driver rather than platform_driver/i2c_driver because 51 + * although VGBI has an i2c resource connected to i2c controller, it 52 + * is not embedded in any i2c controller's scope, thus neither platform_device 53 + * will be created, nor i2c_client will be enumerated, we have to use 54 + * acpi_driver. 55 + */ 56 + static const struct acpi_device_id surface_button_device_ids[] = { 57 + {SURFACE_BUTTON_HID, 0}, 58 + {"", 0}, 59 + }; 60 + MODULE_DEVICE_TABLE(acpi, surface_button_device_ids); 61 + 62 + struct surface_button { 63 + unsigned int type; 64 + struct input_dev *input; 65 + char phys[32]; /* for input device */ 66 + unsigned long pushed; 67 + bool suspended; 68 + }; 69 + 70 + static void surface_button_notify(struct acpi_device *device, u32 event) 71 + { 72 + struct surface_button *button = acpi_driver_data(device); 73 + struct input_dev *input; 74 + int key_code = KEY_RESERVED; 75 + bool pressed = false; 76 + 77 + switch (event) { 78 + /* Power button press,release handle */ 79 + case SURFACE_BUTTON_NOTIFY_PRESS_POWER: 80 + pressed = true; 81 + /*fall through*/ 82 + case SURFACE_BUTTON_NOTIFY_RELEASE_POWER: 83 + key_code = KEY_POWER; 84 + break; 85 + /* Home button press,release handle */ 86 + case SURFACE_BUTTON_NOTIFY_PRESS_HOME: 87 + pressed = true; 88 + /*fall through*/ 89 + case SURFACE_BUTTON_NOTIFY_RELEASE_HOME: 90 + key_code = KEY_LEFTMETA; 91 + break; 92 + /* Volume up button press,release handle */ 93 + case SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_UP: 94 + pressed = true; 95 + /*fall through*/ 96 + case SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_UP: 97 + key_code = KEY_VOLUMEUP; 98 + break; 99 + /* Volume down button press,release handle */ 100 + case SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_DOWN: 101 + pressed = true; 102 + /*fall through*/ 103 + case SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_DOWN: 104 + key_code = KEY_VOLUMEDOWN; 105 + break; 106 + default: 107 + dev_info_ratelimited(&device->dev, 108 + "Unsupported event [0x%x]\n", event); 109 + break; 110 + } 111 + input = button->input; 112 + if (KEY_RESERVED == key_code) 113 + return; 114 + if (pressed) 115 + pm_wakeup_event(&device->dev, 0); 116 + if (button->suspended) 117 + return; 118 + input_report_key(input, key_code, pressed?1:0); 119 + input_sync(input); 120 + } 121 + 122 + #ifdef CONFIG_PM_SLEEP 123 + static int surface_button_suspend(struct device *dev) 124 + { 125 + struct acpi_device *device = to_acpi_device(dev); 126 + struct surface_button *button = acpi_driver_data(device); 127 + 128 + button->suspended = true; 129 + return 0; 130 + } 131 + 132 + static int surface_button_resume(struct device *dev) 133 + { 134 + struct acpi_device *device = to_acpi_device(dev); 135 + struct surface_button *button = acpi_driver_data(device); 136 + 137 + button->suspended = false; 138 + return 0; 139 + } 140 + #endif 141 + 142 + static int surface_button_add(struct acpi_device *device) 143 + { 144 + struct surface_button *button; 145 + struct input_dev *input; 146 + const char *hid = acpi_device_hid(device); 147 + char *name; 148 + int error; 149 + 150 + if (strncmp(acpi_device_bid(device), SURFACE_BUTTON_OBJ_NAME, 151 + strlen(SURFACE_BUTTON_OBJ_NAME))) 152 + return -ENODEV; 153 + 154 + button = kzalloc(sizeof(struct surface_button), GFP_KERNEL); 155 + if (!button) 156 + return -ENOMEM; 157 + 158 + device->driver_data = button; 159 + button->input = input = input_allocate_device(); 160 + if (!input) { 161 + error = -ENOMEM; 162 + goto err_free_button; 163 + } 164 + 165 + name = acpi_device_name(device); 166 + strcpy(name, SURFACE_BUTTON_DEVICE_NAME); 167 + snprintf(button->phys, sizeof(button->phys), "%s/buttons", hid); 168 + 169 + input->name = name; 170 + input->phys = button->phys; 171 + input->id.bustype = BUS_HOST; 172 + input->dev.parent = &device->dev; 173 + input_set_capability(input, EV_KEY, KEY_POWER); 174 + input_set_capability(input, EV_KEY, KEY_LEFTMETA); 175 + input_set_capability(input, EV_KEY, KEY_VOLUMEUP); 176 + input_set_capability(input, EV_KEY, KEY_VOLUMEDOWN); 177 + 178 + error = input_register_device(input); 179 + if (error) 180 + goto err_free_input; 181 + dev_info(&device->dev, 182 + "%s [%s]\n", name, acpi_device_bid(device)); 183 + return 0; 184 + 185 + err_free_input: 186 + input_free_device(input); 187 + err_free_button: 188 + kfree(button); 189 + return error; 190 + } 191 + 192 + static int surface_button_remove(struct acpi_device *device) 193 + { 194 + struct surface_button *button = acpi_driver_data(device); 195 + 196 + input_unregister_device(button->input); 197 + kfree(button); 198 + return 0; 199 + } 200 + 201 + static SIMPLE_DEV_PM_OPS(surface_button_pm, 202 + surface_button_suspend, surface_button_resume); 203 + 204 + static struct acpi_driver surface_button_driver = { 205 + .name = "surface_pro3_button", 206 + .class = "SurfacePro3", 207 + .ids = surface_button_device_ids, 208 + .ops = { 209 + .add = surface_button_add, 210 + .remove = surface_button_remove, 211 + .notify = surface_button_notify, 212 + }, 213 + .drv.pm = &surface_button_pm, 214 + }; 215 + 216 + module_acpi_driver(surface_button_driver);
+1 -1
drivers/platform/x86/thinkpad_acpi.c
··· 402 402 #else 403 403 static inline const char *str_supported(int is_supported) { return ""; } 404 404 #define vdbg_printk(a_dbg_level, format, arg...) \ 405 - no_printk(format, ##arg) 405 + do { if (0) no_printk(format, ##arg); } while (0) 406 406 #endif 407 407 408 408 static void tpacpi_log_usertask(const char * const what)
+427 -378
drivers/platform/x86/toshiba_acpi.c
··· 31 31 32 32 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 33 33 34 - #define TOSHIBA_ACPI_VERSION "0.22" 34 + #define TOSHIBA_ACPI_VERSION "0.23" 35 35 #define PROC_INTERFACE_VERSION 1 36 36 37 37 #include <linux/kernel.h> ··· 50 50 #include <linux/acpi.h> 51 51 #include <linux/dmi.h> 52 52 #include <linux/uaccess.h> 53 + #include <linux/miscdevice.h> 54 + #include <linux/toshiba.h> 53 55 #include <acpi/video.h> 54 56 55 57 MODULE_AUTHOR("John Belmonte"); ··· 93 91 94 92 /* Return codes */ 95 93 #define TOS_SUCCESS 0x0000 94 + #define TOS_SUCCESS2 0x0001 96 95 #define TOS_OPEN_CLOSE_OK 0x0044 97 96 #define TOS_FAILURE 0x1000 98 97 #define TOS_NOT_SUPPORTED 0x8000 ··· 114 111 #define HCI_VIDEO_OUT 0x001c 115 112 #define HCI_HOTKEY_EVENT 0x001e 116 113 #define HCI_LCD_BRIGHTNESS 0x002a 117 - #define HCI_WIRELESS 0x0056 118 114 #define HCI_ACCELEROMETER 0x006d 119 115 #define HCI_KBD_ILLUMINATION 0x0095 120 116 #define HCI_ECO_MODE 0x0097 ··· 142 140 #define HCI_VIDEO_OUT_LCD 0x1 143 141 #define HCI_VIDEO_OUT_CRT 0x2 144 142 #define HCI_VIDEO_OUT_TV 0x4 145 - #define HCI_WIRELESS_KILL_SWITCH 0x01 146 - #define HCI_WIRELESS_BT_PRESENT 0x0f 147 - #define HCI_WIRELESS_BT_ATTACH 0x40 148 - #define HCI_WIRELESS_BT_POWER 0x80 149 143 #define SCI_KBD_MODE_MASK 0x1f 150 144 #define SCI_KBD_MODE_FNZ 0x1 151 145 #define SCI_KBD_MODE_AUTO 0x2 ··· 168 170 struct led_classdev led_dev; 169 171 struct led_classdev kbd_led; 170 172 struct led_classdev eco_led; 173 + struct miscdevice miscdev; 171 174 172 175 int force_fan; 173 176 int last_key_event; ··· 188 189 unsigned int info_supported:1; 189 190 unsigned int tr_backlight_supported:1; 190 191 unsigned int kbd_illum_supported:1; 191 - unsigned int kbd_led_registered:1; 192 192 unsigned int touchpad_supported:1; 193 193 unsigned int eco_supported:1; 194 194 unsigned int accelerometer_supported:1; ··· 198 200 unsigned int panel_power_on_supported:1; 199 201 unsigned int usb_three_supported:1; 200 202 unsigned int sysfs_created:1; 203 + 204 + bool kbd_led_registered; 205 + bool illumination_led_registered; 206 + bool eco_led_registered; 201 207 }; 202 208 203 209 static struct toshiba_acpi_dev *toshiba_acpi; ··· 250 248 }; 251 249 252 250 static const struct key_entry toshiba_acpi_alt_keymap[] = { 253 - { KE_KEY, 0x157, { KEY_MUTE } }, 254 251 { KE_KEY, 0x102, { KEY_ZOOMOUT } }, 255 252 { KE_KEY, 0x103, { KEY_ZOOMIN } }, 256 253 { KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } }, 257 254 { KE_KEY, 0x139, { KEY_ZOOMRESET } }, 258 - { KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } }, 259 255 { KE_KEY, 0x13c, { KEY_BRIGHTNESSDOWN } }, 260 256 { KE_KEY, 0x13d, { KEY_BRIGHTNESSUP } }, 261 - { KE_KEY, 0x158, { KEY_WLAN } }, 257 + { KE_KEY, 0x13e, { KEY_SWITCHVIDEOMODE } }, 262 258 { KE_KEY, 0x13f, { KEY_TOUCHPAD_TOGGLE } }, 259 + { KE_KEY, 0x157, { KEY_MUTE } }, 260 + { KE_KEY, 0x158, { KEY_WLAN } }, 263 261 { KE_END, 0 }, 264 262 }; 265 263 ··· 443 441 } 444 442 445 443 /* Illumination support */ 446 - static int toshiba_illumination_available(struct toshiba_acpi_dev *dev) 444 + static void toshiba_illumination_available(struct toshiba_acpi_dev *dev) 447 445 { 448 446 u32 in[TCI_WORDS] = { SCI_GET, SCI_ILLUMINATION, 0, 0, 0, 0 }; 449 447 u32 out[TCI_WORDS]; 450 448 acpi_status status; 451 449 450 + dev->illumination_supported = 0; 451 + dev->illumination_led_registered = false; 452 + 452 453 if (!sci_open(dev)) 453 - return 0; 454 + return; 454 455 455 456 status = tci_raw(dev, in, out); 456 457 sci_close(dev); 457 - if (ACPI_FAILURE(status)) { 458 + if (ACPI_FAILURE(status)) 458 459 pr_err("ACPI call to query Illumination support failed\n"); 459 - return 0; 460 - } else if (out[0] == TOS_NOT_SUPPORTED) { 461 - pr_info("Illumination device not available\n"); 462 - return 0; 463 - } 464 - 465 - return 1; 460 + else if (out[0] == TOS_SUCCESS) 461 + dev->illumination_supported = 1; 466 462 } 467 463 468 464 static void toshiba_illumination_set(struct led_classdev *cdev, ··· 468 468 { 469 469 struct toshiba_acpi_dev *dev = container_of(cdev, 470 470 struct toshiba_acpi_dev, led_dev); 471 - u32 state, result; 471 + u32 result; 472 + u32 state; 472 473 473 474 /* First request : initialize communication. */ 474 475 if (!sci_open(dev)) ··· 479 478 state = brightness ? 1 : 0; 480 479 result = sci_write(dev, SCI_ILLUMINATION, state); 481 480 sci_close(dev); 482 - if (result == TOS_FAILURE) { 481 + if (result == TOS_FAILURE) 483 482 pr_err("ACPI call for illumination failed\n"); 484 - return; 485 - } else if (result == TOS_NOT_SUPPORTED) { 486 - pr_info("Illumination not supported\n"); 487 - return; 488 - } 489 483 } 490 484 491 485 static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) ··· 496 500 /* Check the illumination */ 497 501 result = sci_read(dev, SCI_ILLUMINATION, &state); 498 502 sci_close(dev); 499 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 503 + if (result == TOS_FAILURE) { 500 504 pr_err("ACPI call for illumination failed\n"); 501 505 return LED_OFF; 502 - } else if (result == TOS_NOT_SUPPORTED) { 503 - pr_info("Illumination not supported\n"); 506 + } else if (result != TOS_SUCCESS) { 504 507 return LED_OFF; 505 508 } 506 509 ··· 507 512 } 508 513 509 514 /* KBD Illumination */ 510 - static int toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev) 515 + static void toshiba_kbd_illum_available(struct toshiba_acpi_dev *dev) 511 516 { 512 517 u32 in[TCI_WORDS] = { SCI_GET, SCI_KBD_ILLUM_STATUS, 0, 0, 0, 0 }; 513 518 u32 out[TCI_WORDS]; 514 519 acpi_status status; 515 520 521 + dev->kbd_illum_supported = 0; 522 + dev->kbd_led_registered = false; 523 + 516 524 if (!sci_open(dev)) 517 - return 0; 525 + return; 518 526 519 527 status = tci_raw(dev, in, out); 520 528 sci_close(dev); 521 - if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { 529 + if (ACPI_FAILURE(status)) { 522 530 pr_err("ACPI call to query kbd illumination support failed\n"); 523 - return 0; 524 - } else if (out[0] == TOS_NOT_SUPPORTED) { 525 - pr_info("Keyboard illumination not available\n"); 526 - return 0; 531 + } else if (out[0] == TOS_SUCCESS) { 532 + /* 533 + * Check for keyboard backlight timeout max value, 534 + * previous kbd backlight implementation set this to 535 + * 0x3c0003, and now the new implementation set this 536 + * to 0x3c001a, use this to distinguish between them. 537 + */ 538 + if (out[3] == SCI_KBD_TIME_MAX) 539 + dev->kbd_type = 2; 540 + else 541 + dev->kbd_type = 1; 542 + /* Get the current keyboard backlight mode */ 543 + dev->kbd_mode = out[2] & SCI_KBD_MODE_MASK; 544 + /* Get the current time (1-60 seconds) */ 545 + dev->kbd_time = out[2] >> HCI_MISC_SHIFT; 546 + /* Flag as supported */ 547 + dev->kbd_illum_supported = 1; 527 548 } 528 - 529 - /* 530 - * Check for keyboard backlight timeout max value, 531 - * previous kbd backlight implementation set this to 532 - * 0x3c0003, and now the new implementation set this 533 - * to 0x3c001a, use this to distinguish between them. 534 - */ 535 - if (out[3] == SCI_KBD_TIME_MAX) 536 - dev->kbd_type = 2; 537 - else 538 - dev->kbd_type = 1; 539 - /* Get the current keyboard backlight mode */ 540 - dev->kbd_mode = out[2] & SCI_KBD_MODE_MASK; 541 - /* Get the current time (1-60 seconds) */ 542 - dev->kbd_time = out[2] >> HCI_MISC_SHIFT; 543 - 544 - return 1; 545 549 } 546 550 547 551 static int toshiba_kbd_illum_status_set(struct toshiba_acpi_dev *dev, u32 time) ··· 552 558 553 559 result = sci_write(dev, SCI_KBD_ILLUM_STATUS, time); 554 560 sci_close(dev); 555 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 561 + if (result == TOS_FAILURE) 556 562 pr_err("ACPI call to set KBD backlight status failed\n"); 557 - return -EIO; 558 - } else if (result == TOS_NOT_SUPPORTED) { 559 - pr_info("Keyboard backlight status not supported\n"); 563 + else if (result == TOS_NOT_SUPPORTED) 560 564 return -ENODEV; 561 - } 562 565 563 - return 0; 566 + return result == TOS_SUCCESS ? 0 : -EIO; 564 567 } 565 568 566 569 static int toshiba_kbd_illum_status_get(struct toshiba_acpi_dev *dev, u32 *time) ··· 569 578 570 579 result = sci_read(dev, SCI_KBD_ILLUM_STATUS, time); 571 580 sci_close(dev); 572 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 581 + if (result == TOS_FAILURE) 573 582 pr_err("ACPI call to get KBD backlight status failed\n"); 574 - return -EIO; 575 - } else if (result == TOS_NOT_SUPPORTED) { 576 - pr_info("Keyboard backlight status not supported\n"); 583 + else if (result == TOS_NOT_SUPPORTED) 577 584 return -ENODEV; 578 - } 579 585 580 - return 0; 586 + return result == TOS_SUCCESS ? 0 : -EIO; 581 587 } 582 588 583 589 static enum led_brightness toshiba_kbd_backlight_get(struct led_classdev *cdev) 584 590 { 585 591 struct toshiba_acpi_dev *dev = container_of(cdev, 586 592 struct toshiba_acpi_dev, kbd_led); 587 - u32 state, result; 593 + u32 result; 594 + u32 state; 588 595 589 596 /* Check the keyboard backlight state */ 590 597 result = hci_read(dev, HCI_KBD_ILLUMINATION, &state); 591 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 598 + if (result == TOS_FAILURE) { 592 599 pr_err("ACPI call to get the keyboard backlight failed\n"); 593 600 return LED_OFF; 594 - } else if (result == TOS_NOT_SUPPORTED) { 595 - pr_info("Keyboard backlight not supported\n"); 601 + } else if (result != TOS_SUCCESS) { 596 602 return LED_OFF; 597 603 } 598 604 ··· 601 613 { 602 614 struct toshiba_acpi_dev *dev = container_of(cdev, 603 615 struct toshiba_acpi_dev, kbd_led); 604 - u32 state, result; 616 + u32 result; 617 + u32 state; 605 618 606 619 /* Set the keyboard backlight state */ 607 620 state = brightness ? 1 : 0; 608 621 result = hci_write(dev, HCI_KBD_ILLUMINATION, state); 609 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 622 + if (result == TOS_FAILURE) 610 623 pr_err("ACPI call to set KBD Illumination mode failed\n"); 611 - return; 612 - } else if (result == TOS_NOT_SUPPORTED) { 613 - pr_info("Keyboard backlight not supported\n"); 614 - return; 615 - } 616 624 } 617 625 618 626 /* TouchPad support */ ··· 621 637 622 638 result = sci_write(dev, SCI_TOUCHPAD, state); 623 639 sci_close(dev); 624 - if (result == TOS_FAILURE) { 640 + if (result == TOS_FAILURE) 625 641 pr_err("ACPI call to set the touchpad failed\n"); 626 - return -EIO; 627 - } else if (result == TOS_NOT_SUPPORTED) { 642 + else if (result == TOS_NOT_SUPPORTED) 628 643 return -ENODEV; 629 - } 630 644 631 - return 0; 645 + return result == TOS_SUCCESS ? 0 : -EIO; 632 646 } 633 647 634 648 static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state) ··· 638 656 639 657 result = sci_read(dev, SCI_TOUCHPAD, state); 640 658 sci_close(dev); 641 - if (result == TOS_FAILURE) { 659 + if (result == TOS_FAILURE) 642 660 pr_err("ACPI call to query the touchpad failed\n"); 643 - return -EIO; 644 - } else if (result == TOS_NOT_SUPPORTED) { 661 + else if (result == TOS_NOT_SUPPORTED) 645 662 return -ENODEV; 646 - } 647 663 648 - return 0; 664 + return result == TOS_SUCCESS ? 0 : -EIO; 649 665 } 650 666 651 667 /* Eco Mode support */ 652 - static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) 668 + static void toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) 653 669 { 654 670 acpi_status status; 655 671 u32 in[TCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 0, 0, 0 }; 656 672 u32 out[TCI_WORDS]; 657 673 674 + dev->eco_supported = 0; 675 + dev->eco_led_registered = false; 676 + 658 677 status = tci_raw(dev, in, out); 659 678 if (ACPI_FAILURE(status)) { 660 679 pr_err("ACPI call to get ECO led failed\n"); 661 - } else if (out[0] == TOS_NOT_INSTALLED) { 662 - pr_info("ECO led not installed"); 663 680 } else if (out[0] == TOS_INPUT_DATA_ERROR) { 664 681 /* 665 682 * If we receive 0x8300 (Input Data Error), it means that the ··· 671 690 */ 672 691 in[3] = 1; 673 692 status = tci_raw(dev, in, out); 674 - if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) 693 + if (ACPI_FAILURE(status)) 675 694 pr_err("ACPI call to get ECO led failed\n"); 676 695 else if (out[0] == TOS_SUCCESS) 677 - return 1; 696 + dev->eco_supported = 1; 678 697 } 679 - 680 - return 0; 681 698 } 682 699 683 700 static enum led_brightness ··· 688 709 acpi_status status; 689 710 690 711 status = tci_raw(dev, in, out); 691 - if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { 712 + if (ACPI_FAILURE(status)) { 692 713 pr_err("ACPI call to get ECO led failed\n"); 714 + return LED_OFF; 715 + } else if (out[0] != TOS_SUCCESS) { 693 716 return LED_OFF; 694 717 } 695 718 ··· 710 729 /* Switch the Eco Mode led on/off */ 711 730 in[2] = (brightness) ? 1 : 0; 712 731 status = tci_raw(dev, in, out); 713 - if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { 732 + if (ACPI_FAILURE(status)) 714 733 pr_err("ACPI call to set ECO led failed\n"); 715 - return; 716 - } 717 734 } 718 735 719 736 /* Accelerometer support */ 720 - static int toshiba_accelerometer_supported(struct toshiba_acpi_dev *dev) 737 + static void toshiba_accelerometer_available(struct toshiba_acpi_dev *dev) 721 738 { 722 739 u32 in[TCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER2, 0, 0, 0, 0 }; 723 740 u32 out[TCI_WORDS]; 724 741 acpi_status status; 742 + 743 + dev->accelerometer_supported = 0; 725 744 726 745 /* 727 746 * Check if the accelerometer call exists, 728 747 * this call also serves as initialization 729 748 */ 730 749 status = tci_raw(dev, in, out); 731 - if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { 750 + if (ACPI_FAILURE(status)) 732 751 pr_err("ACPI call to query the accelerometer failed\n"); 733 - return -EIO; 734 - } else if (out[0] == TOS_DATA_NOT_AVAILABLE || 735 - out[0] == TOS_NOT_INITIALIZED) { 736 - pr_err("Accelerometer not initialized\n"); 737 - return -EIO; 738 - } else if (out[0] == TOS_NOT_SUPPORTED) { 739 - pr_info("Accelerometer not supported\n"); 740 - return -ENODEV; 741 - } 742 - 743 - return 0; 752 + else if (out[0] == TOS_SUCCESS) 753 + dev->accelerometer_supported = 1; 744 754 } 745 755 746 756 static int toshiba_accelerometer_get(struct toshiba_acpi_dev *dev, 747 - u32 *xy, u32 *z) 757 + u32 *xy, u32 *z) 748 758 { 749 759 u32 in[TCI_WORDS] = { HCI_GET, HCI_ACCELEROMETER, 0, 1, 0, 0 }; 750 760 u32 out[TCI_WORDS]; ··· 743 771 744 772 /* Check the Accelerometer status */ 745 773 status = tci_raw(dev, in, out); 746 - if (ACPI_FAILURE(status) || out[0] == TOS_INPUT_DATA_ERROR) { 774 + if (ACPI_FAILURE(status)) { 747 775 pr_err("ACPI call to query the accelerometer failed\n"); 748 776 return -EIO; 777 + } else if (out[0] == TOS_NOT_SUPPORTED) { 778 + return -ENODEV; 779 + } else if (out[0] == TOS_SUCCESS) { 780 + *xy = out[2]; 781 + *z = out[4]; 782 + return 0; 749 783 } 750 784 751 - *xy = out[2]; 752 - *z = out[4]; 753 - 754 - return 0; 785 + return -EIO; 755 786 } 756 787 757 788 /* Sleep (Charge and Music) utilities support */ ··· 764 789 u32 out[TCI_WORDS]; 765 790 acpi_status status; 766 791 767 - /* Set the feature to "not supported" in case of error */ 768 792 dev->usb_sleep_charge_supported = 0; 769 793 770 794 if (!sci_open(dev)) ··· 775 801 sci_close(dev); 776 802 return; 777 803 } else if (out[0] == TOS_NOT_SUPPORTED) { 778 - pr_info("USB Sleep and Charge not supported\n"); 779 804 sci_close(dev); 780 805 return; 781 806 } else if (out[0] == TOS_SUCCESS) { ··· 783 810 784 811 in[5] = SCI_USB_CHARGE_BAT_LVL; 785 812 status = tci_raw(dev, in, out); 813 + sci_close(dev); 786 814 if (ACPI_FAILURE(status)) { 787 815 pr_err("ACPI call to get USB Sleep and Charge mode failed\n"); 788 - sci_close(dev); 789 - return; 790 - } else if (out[0] == TOS_NOT_SUPPORTED) { 791 - pr_info("USB Sleep and Charge not supported\n"); 792 - sci_close(dev); 793 - return; 794 816 } else if (out[0] == TOS_SUCCESS) { 795 817 dev->usbsc_bat_level = out[2]; 796 - /* 797 - * If we reach this point, it means that the laptop has support 798 - * for this feature and all values are initialized. 799 - * Set it as supported. 800 - */ 818 + /* Flag as supported */ 801 819 dev->usb_sleep_charge_supported = 1; 802 820 } 803 821 804 - sci_close(dev); 805 822 } 806 823 807 824 static int toshiba_usb_sleep_charge_get(struct toshiba_acpi_dev *dev, ··· 804 841 805 842 result = sci_read(dev, SCI_USB_SLEEP_CHARGE, mode); 806 843 sci_close(dev); 807 - if (result == TOS_FAILURE) { 844 + if (result == TOS_FAILURE) 808 845 pr_err("ACPI call to set USB S&C mode failed\n"); 809 - return -EIO; 810 - } else if (result == TOS_NOT_SUPPORTED) { 811 - pr_info("USB Sleep and Charge not supported\n"); 846 + else if (result == TOS_NOT_SUPPORTED) 812 847 return -ENODEV; 813 - } else if (result == TOS_INPUT_DATA_ERROR) { 814 - return -EIO; 815 - } 816 848 817 - return 0; 849 + return result == TOS_SUCCESS ? 0 : -EIO; 818 850 } 819 851 820 852 static int toshiba_usb_sleep_charge_set(struct toshiba_acpi_dev *dev, ··· 822 864 823 865 result = sci_write(dev, SCI_USB_SLEEP_CHARGE, mode); 824 866 sci_close(dev); 825 - if (result == TOS_FAILURE) { 867 + if (result == TOS_FAILURE) 826 868 pr_err("ACPI call to set USB S&C mode failed\n"); 827 - return -EIO; 828 - } else if (result == TOS_NOT_SUPPORTED) { 829 - pr_info("USB Sleep and Charge not supported\n"); 869 + else if (result == TOS_NOT_SUPPORTED) 830 870 return -ENODEV; 831 - } else if (result == TOS_INPUT_DATA_ERROR) { 832 - return -EIO; 833 - } 834 871 835 - return 0; 872 + return result == TOS_SUCCESS ? 0 : -EIO; 836 873 } 837 874 838 875 static int toshiba_sleep_functions_status_get(struct toshiba_acpi_dev *dev, ··· 845 892 sci_close(dev); 846 893 if (ACPI_FAILURE(status)) { 847 894 pr_err("ACPI call to get USB S&C battery level failed\n"); 848 - return -EIO; 849 895 } else if (out[0] == TOS_NOT_SUPPORTED) { 850 - pr_info("USB Sleep and Charge not supported\n"); 851 896 return -ENODEV; 852 - } else if (out[0] == TOS_INPUT_DATA_ERROR) { 853 - return -EIO; 897 + } else if (out[0] == TOS_SUCCESS) { 898 + *mode = out[2]; 899 + return 0; 854 900 } 855 901 856 - *mode = out[2]; 857 - 858 - return 0; 902 + return -EIO; 859 903 } 860 904 861 905 static int toshiba_sleep_functions_status_set(struct toshiba_acpi_dev *dev, ··· 869 919 in[5] = SCI_USB_CHARGE_BAT_LVL; 870 920 status = tci_raw(dev, in, out); 871 921 sci_close(dev); 872 - if (ACPI_FAILURE(status)) { 922 + if (ACPI_FAILURE(status)) 873 923 pr_err("ACPI call to set USB S&C battery level failed\n"); 874 - return -EIO; 875 - } else if (out[0] == TOS_NOT_SUPPORTED) { 876 - pr_info("USB Sleep and Charge not supported\n"); 924 + else if (out[0] == TOS_NOT_SUPPORTED) 877 925 return -ENODEV; 878 - } else if (out[0] == TOS_INPUT_DATA_ERROR) { 879 - return -EIO; 880 - } 881 926 882 - return 0; 927 + return out[0] == TOS_SUCCESS ? 0 : -EIO; 883 928 } 884 929 885 930 static int toshiba_usb_rapid_charge_get(struct toshiba_acpi_dev *dev, ··· 892 947 sci_close(dev); 893 948 if (ACPI_FAILURE(status)) { 894 949 pr_err("ACPI call to get USB Rapid Charge failed\n"); 895 - return -EIO; 896 - } else if (out[0] == TOS_NOT_SUPPORTED || 897 - out[0] == TOS_INPUT_DATA_ERROR) { 898 - pr_info("USB Rapid Charge not supported\n"); 950 + } else if (out[0] == TOS_NOT_SUPPORTED) { 899 951 return -ENODEV; 952 + } else if (out[0] == TOS_SUCCESS || out[0] == TOS_SUCCESS2) { 953 + *state = out[2]; 954 + return 0; 900 955 } 901 956 902 - *state = out[2]; 903 - 904 - return 0; 957 + return -EIO; 905 958 } 906 959 907 960 static int toshiba_usb_rapid_charge_set(struct toshiba_acpi_dev *dev, ··· 916 973 in[5] = SCI_USB_CHARGE_RAPID_DSP; 917 974 status = tci_raw(dev, in, out); 918 975 sci_close(dev); 919 - if (ACPI_FAILURE(status)) { 976 + if (ACPI_FAILURE(status)) 920 977 pr_err("ACPI call to set USB Rapid Charge failed\n"); 921 - return -EIO; 922 - } else if (out[0] == TOS_NOT_SUPPORTED) { 923 - pr_info("USB Rapid Charge not supported\n"); 978 + else if (out[0] == TOS_NOT_SUPPORTED) 924 979 return -ENODEV; 925 - } else if (out[0] == TOS_INPUT_DATA_ERROR) { 926 - return -EIO; 927 - } 928 980 929 - return 0; 981 + return (out[0] == TOS_SUCCESS || out[0] == TOS_SUCCESS2) ? 0 : -EIO; 930 982 } 931 983 932 984 static int toshiba_usb_sleep_music_get(struct toshiba_acpi_dev *dev, u32 *state) ··· 933 995 934 996 result = sci_read(dev, SCI_USB_SLEEP_MUSIC, state); 935 997 sci_close(dev); 936 - if (result == TOS_FAILURE) { 998 + if (result == TOS_FAILURE) 937 999 pr_err("ACPI call to get Sleep and Music failed\n"); 938 - return -EIO; 939 - } else if (result == TOS_NOT_SUPPORTED) { 940 - pr_info("Sleep and Music not supported\n"); 1000 + else if (result == TOS_NOT_SUPPORTED) 941 1001 return -ENODEV; 942 - } else if (result == TOS_INPUT_DATA_ERROR) { 943 - return -EIO; 944 - } 945 1002 946 - return 0; 1003 + return result = TOS_SUCCESS ? 0 : -EIO; 947 1004 } 948 1005 949 1006 static int toshiba_usb_sleep_music_set(struct toshiba_acpi_dev *dev, u32 state) ··· 950 1017 951 1018 result = sci_write(dev, SCI_USB_SLEEP_MUSIC, state); 952 1019 sci_close(dev); 953 - if (result == TOS_FAILURE) { 1020 + if (result == TOS_FAILURE) 954 1021 pr_err("ACPI call to set Sleep and Music failed\n"); 955 - return -EIO; 956 - } else if (result == TOS_NOT_SUPPORTED) { 957 - pr_info("Sleep and Music not supported\n"); 1022 + else if (result == TOS_NOT_SUPPORTED) 958 1023 return -ENODEV; 959 - } else if (result == TOS_INPUT_DATA_ERROR) { 960 - return -EIO; 961 - } 962 1024 963 - return 0; 1025 + return result == TOS_SUCCESS ? 0 : -EIO; 964 1026 } 965 1027 966 1028 /* Keyboard function keys */ ··· 968 1040 969 1041 result = sci_read(dev, SCI_KBD_FUNCTION_KEYS, mode); 970 1042 sci_close(dev); 971 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 1043 + if (result == TOS_FAILURE) 972 1044 pr_err("ACPI call to get KBD function keys failed\n"); 973 - return -EIO; 974 - } else if (result == TOS_NOT_SUPPORTED) { 975 - pr_info("KBD function keys not supported\n"); 1045 + else if (result == TOS_NOT_SUPPORTED) 976 1046 return -ENODEV; 977 - } 978 1047 979 - return 0; 1048 + return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO; 980 1049 } 981 1050 982 1051 static int toshiba_function_keys_set(struct toshiba_acpi_dev *dev, u32 mode) ··· 985 1060 986 1061 result = sci_write(dev, SCI_KBD_FUNCTION_KEYS, mode); 987 1062 sci_close(dev); 988 - if (result == TOS_FAILURE || result == TOS_INPUT_DATA_ERROR) { 1063 + if (result == TOS_FAILURE) 989 1064 pr_err("ACPI call to set KBD function keys failed\n"); 990 - return -EIO; 991 - } else if (result == TOS_NOT_SUPPORTED) { 992 - pr_info("KBD function keys not supported\n"); 1065 + else if (result == TOS_NOT_SUPPORTED) 993 1066 return -ENODEV; 994 - } 995 1067 996 - return 0; 1068 + return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO; 997 1069 } 998 1070 999 1071 /* Panel Power ON */ ··· 1003 1081 1004 1082 result = sci_read(dev, SCI_PANEL_POWER_ON, state); 1005 1083 sci_close(dev); 1006 - if (result == TOS_FAILURE) { 1084 + if (result == TOS_FAILURE) 1007 1085 pr_err("ACPI call to get Panel Power ON failed\n"); 1008 - return -EIO; 1009 - } else if (result == TOS_NOT_SUPPORTED) { 1010 - pr_info("Panel Power on not supported\n"); 1086 + else if (result == TOS_NOT_SUPPORTED) 1011 1087 return -ENODEV; 1012 - } else if (result == TOS_INPUT_DATA_ERROR) { 1013 - return -EIO; 1014 - } 1015 1088 1016 - return 0; 1089 + return result == TOS_SUCCESS ? 0 : -EIO; 1017 1090 } 1018 1091 1019 1092 static int toshiba_panel_power_on_set(struct toshiba_acpi_dev *dev, u32 state) ··· 1020 1103 1021 1104 result = sci_write(dev, SCI_PANEL_POWER_ON, state); 1022 1105 sci_close(dev); 1023 - if (result == TOS_FAILURE) { 1106 + if (result == TOS_FAILURE) 1024 1107 pr_err("ACPI call to set Panel Power ON failed\n"); 1025 - return -EIO; 1026 - } else if (result == TOS_NOT_SUPPORTED) { 1027 - pr_info("Panel Power ON not supported\n"); 1108 + else if (result == TOS_NOT_SUPPORTED) 1028 1109 return -ENODEV; 1029 - } else if (result == TOS_INPUT_DATA_ERROR) { 1030 - return -EIO; 1031 - } 1032 1110 1033 - return 0; 1111 + return result == TOS_SUCCESS ? 0 : -EIO; 1034 1112 } 1035 1113 1036 1114 /* USB Three */ ··· 1038 1126 1039 1127 result = sci_read(dev, SCI_USB_THREE, state); 1040 1128 sci_close(dev); 1041 - if (result == TOS_FAILURE) { 1129 + if (result == TOS_FAILURE) 1042 1130 pr_err("ACPI call to get USB 3 failed\n"); 1043 - return -EIO; 1044 - } else if (result == TOS_NOT_SUPPORTED) { 1045 - pr_info("USB 3 not supported\n"); 1131 + else if (result == TOS_NOT_SUPPORTED) 1046 1132 return -ENODEV; 1047 - } else if (result == TOS_INPUT_DATA_ERROR) { 1048 - return -EIO; 1049 - } 1050 1133 1051 - return 0; 1134 + return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO; 1052 1135 } 1053 1136 1054 1137 static int toshiba_usb_three_set(struct toshiba_acpi_dev *dev, u32 state) ··· 1055 1148 1056 1149 result = sci_write(dev, SCI_USB_THREE, state); 1057 1150 sci_close(dev); 1058 - if (result == TOS_FAILURE) { 1151 + if (result == TOS_FAILURE) 1059 1152 pr_err("ACPI call to set USB 3 failed\n"); 1060 - return -EIO; 1061 - } else if (result == TOS_NOT_SUPPORTED) { 1062 - pr_info("USB 3 not supported\n"); 1153 + else if (result == TOS_NOT_SUPPORTED) 1063 1154 return -ENODEV; 1064 - } else if (result == TOS_INPUT_DATA_ERROR) { 1065 - return -EIO; 1066 - } 1067 1155 1068 - return 0; 1156 + return (result == TOS_SUCCESS || result == TOS_SUCCESS2) ? 0 : -EIO; 1069 1157 } 1070 1158 1071 1159 /* Hotkey Event type */ ··· 1074 1172 status = tci_raw(dev, in, out); 1075 1173 if (ACPI_FAILURE(status)) { 1076 1174 pr_err("ACPI call to get System type failed\n"); 1077 - return -EIO; 1078 1175 } else if (out[0] == TOS_NOT_SUPPORTED) { 1079 - pr_info("System type not supported\n"); 1080 1176 return -ENODEV; 1177 + } else if (out[0] == TOS_SUCCESS) { 1178 + *type = out[3]; 1179 + return 0; 1081 1180 } 1082 1181 1083 - *type = out[3]; 1084 - 1085 - return 0; 1182 + return -EIO; 1086 1183 } 1087 1184 1088 1185 /* Transflective Backlight */ 1089 - static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, bool *enabled) 1186 + static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 *status) 1090 1187 { 1091 - u32 hci_result; 1092 - u32 status; 1188 + u32 result = hci_read(dev, HCI_TR_BACKLIGHT, status); 1093 1189 1094 - hci_result = hci_read(dev, HCI_TR_BACKLIGHT, &status); 1095 - *enabled = !status; 1096 - return hci_result == TOS_SUCCESS ? 0 : -EIO; 1190 + if (result == TOS_FAILURE) 1191 + pr_err("ACPI call to get Transflective Backlight failed\n"); 1192 + else if (result == TOS_NOT_SUPPORTED) 1193 + return -ENODEV; 1194 + 1195 + return result == TOS_SUCCESS ? 0 : -EIO; 1097 1196 } 1098 1197 1099 - static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, bool enable) 1198 + static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, u32 status) 1100 1199 { 1101 - u32 hci_result; 1102 - u32 value = !enable; 1200 + u32 result = hci_write(dev, HCI_TR_BACKLIGHT, !status); 1103 1201 1104 - hci_result = hci_write(dev, HCI_TR_BACKLIGHT, value); 1105 - return hci_result == TOS_SUCCESS ? 0 : -EIO; 1202 + if (result == TOS_FAILURE) 1203 + pr_err("ACPI call to set Transflective Backlight failed\n"); 1204 + else if (result == TOS_NOT_SUPPORTED) 1205 + return -ENODEV; 1206 + 1207 + return result == TOS_SUCCESS ? 0 : -EIO; 1106 1208 } 1107 1209 1108 1210 static struct proc_dir_entry *toshiba_proc_dir; ··· 1114 1208 /* LCD Brightness */ 1115 1209 static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) 1116 1210 { 1117 - u32 hci_result; 1211 + u32 result; 1118 1212 u32 value; 1119 1213 int brightness = 0; 1120 1214 1121 1215 if (dev->tr_backlight_supported) { 1122 - bool enabled; 1123 - int ret = get_tr_backlight_status(dev, &enabled); 1216 + int ret = get_tr_backlight_status(dev, &value); 1124 1217 1125 1218 if (ret) 1126 1219 return ret; 1127 - if (enabled) 1220 + if (value) 1128 1221 return 0; 1129 1222 brightness++; 1130 1223 } 1131 1224 1132 - hci_result = hci_read(dev, HCI_LCD_BRIGHTNESS, &value); 1133 - if (hci_result == TOS_SUCCESS) 1225 + result = hci_read(dev, HCI_LCD_BRIGHTNESS, &value); 1226 + if (result == TOS_FAILURE) 1227 + pr_err("ACPI call to get LCD Brightness failed\n"); 1228 + else if (result == TOS_NOT_SUPPORTED) 1229 + return -ENODEV; 1230 + if (result == TOS_SUCCESS) 1134 1231 return brightness + (value >> HCI_LCD_BRIGHTNESS_SHIFT); 1135 1232 1136 1233 return -EIO; ··· 1149 1240 static int lcd_proc_show(struct seq_file *m, void *v) 1150 1241 { 1151 1242 struct toshiba_acpi_dev *dev = m->private; 1152 - int value; 1153 1243 int levels; 1244 + int value; 1154 1245 1155 1246 if (!dev->backlight_dev) 1156 1247 return -ENODEV; ··· 1164 1255 } 1165 1256 1166 1257 pr_err("Error reading LCD brightness\n"); 1258 + 1167 1259 return -EIO; 1168 1260 } 1169 1261 ··· 1175 1265 1176 1266 static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) 1177 1267 { 1178 - u32 hci_result; 1268 + u32 result; 1179 1269 1180 1270 if (dev->tr_backlight_supported) { 1181 - bool enable = !value; 1182 - int ret = set_tr_backlight_status(dev, enable); 1271 + int ret = set_tr_backlight_status(dev, !value); 1183 1272 1184 1273 if (ret) 1185 1274 return ret; ··· 1187 1278 } 1188 1279 1189 1280 value = value << HCI_LCD_BRIGHTNESS_SHIFT; 1190 - hci_result = hci_write(dev, HCI_LCD_BRIGHTNESS, value); 1191 - return hci_result == TOS_SUCCESS ? 0 : -EIO; 1281 + result = hci_write(dev, HCI_LCD_BRIGHTNESS, value); 1282 + if (result == TOS_FAILURE) 1283 + pr_err("ACPI call to set LCD Brightness failed\n"); 1284 + else if (result == TOS_NOT_SUPPORTED) 1285 + return -ENODEV; 1286 + 1287 + return result == TOS_SUCCESS ? 0 : -EIO; 1192 1288 } 1193 1289 1194 1290 static int set_lcd_status(struct backlight_device *bd) ··· 1209 1295 struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); 1210 1296 char cmd[42]; 1211 1297 size_t len; 1212 - int value; 1213 - int ret; 1214 1298 int levels = dev->backlight_dev->props.max_brightness + 1; 1299 + int value; 1215 1300 1216 1301 len = min(count, sizeof(cmd) - 1); 1217 1302 if (copy_from_user(cmd, buf, len)) 1218 1303 return -EFAULT; 1219 1304 cmd[len] = '\0'; 1220 1305 1221 - if (sscanf(cmd, " brightness : %i", &value) == 1 && 1222 - value >= 0 && value < levels) { 1223 - ret = set_lcd_brightness(dev, value); 1224 - if (ret == 0) 1225 - ret = count; 1226 - } else { 1227 - ret = -EINVAL; 1228 - } 1229 - return ret; 1306 + if (sscanf(cmd, " brightness : %i", &value) != 1 && 1307 + value < 0 && value > levels) 1308 + return -EINVAL; 1309 + 1310 + if (set_lcd_brightness(dev, value)) 1311 + return -EIO; 1312 + 1313 + return count; 1230 1314 } 1231 1315 1232 1316 static const struct file_operations lcd_proc_fops = { ··· 1236 1324 .write = lcd_proc_write, 1237 1325 }; 1238 1326 1327 + /* Video-Out */ 1239 1328 static int get_video_status(struct toshiba_acpi_dev *dev, u32 *status) 1240 1329 { 1241 - u32 hci_result; 1330 + u32 result = hci_read(dev, HCI_VIDEO_OUT, status); 1242 1331 1243 - hci_result = hci_read(dev, HCI_VIDEO_OUT, status); 1244 - return hci_result == TOS_SUCCESS ? 0 : -EIO; 1332 + if (result == TOS_FAILURE) 1333 + pr_err("ACPI call to get Video-Out failed\n"); 1334 + else if (result == TOS_NOT_SUPPORTED) 1335 + return -ENODEV; 1336 + 1337 + return result == TOS_SUCCESS ? 0 : -EIO; 1245 1338 } 1246 1339 1247 1340 static int video_proc_show(struct seq_file *m, void *v) 1248 1341 { 1249 1342 struct toshiba_acpi_dev *dev = m->private; 1250 1343 u32 value; 1251 - int ret; 1252 1344 1253 - ret = get_video_status(dev, &value); 1254 - if (!ret) { 1345 + if (!get_video_status(dev, &value)) { 1255 1346 int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; 1256 1347 int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; 1257 1348 int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; ··· 1262 1347 seq_printf(m, "lcd_out: %d\n", is_lcd); 1263 1348 seq_printf(m, "crt_out: %d\n", is_crt); 1264 1349 seq_printf(m, "tv_out: %d\n", is_tv); 1350 + return 0; 1265 1351 } 1266 1352 1267 - return ret; 1353 + return -EIO; 1268 1354 } 1269 1355 1270 1356 static int video_proc_open(struct inode *inode, struct file *file) ··· 1277 1361 size_t count, loff_t *pos) 1278 1362 { 1279 1363 struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); 1280 - char *cmd, *buffer; 1281 - int ret; 1282 - int value; 1364 + char *buffer; 1365 + char *cmd; 1283 1366 int remain = count; 1284 1367 int lcd_out = -1; 1285 1368 int crt_out = -1; 1286 1369 int tv_out = -1; 1370 + int value; 1371 + int ret; 1287 1372 u32 video_out; 1288 1373 1289 1374 cmd = kmalloc(count + 1, GFP_KERNEL); ··· 1336 1419 ret = write_acpi_int(METHOD_VIDEO_OUT, new_video_out); 1337 1420 } 1338 1421 1339 - return ret ? ret : count; 1422 + return ret ? -EIO : count; 1340 1423 } 1341 1424 1342 1425 static const struct file_operations video_proc_fops = { ··· 1348 1431 .write = video_proc_write, 1349 1432 }; 1350 1433 1434 + /* Fan status */ 1351 1435 static int get_fan_status(struct toshiba_acpi_dev *dev, u32 *status) 1352 1436 { 1353 - u32 hci_result; 1437 + u32 result = hci_read(dev, HCI_FAN, status); 1354 1438 1355 - hci_result = hci_read(dev, HCI_FAN, status); 1356 - return hci_result == TOS_SUCCESS ? 0 : -EIO; 1439 + if (result == TOS_FAILURE) 1440 + pr_err("ACPI call to get Fan status failed\n"); 1441 + else if (result == TOS_NOT_SUPPORTED) 1442 + return -ENODEV; 1443 + 1444 + return result == TOS_SUCCESS ? 0 : -EIO; 1445 + } 1446 + 1447 + static int set_fan_status(struct toshiba_acpi_dev *dev, u32 status) 1448 + { 1449 + u32 result = hci_write(dev, HCI_FAN, status); 1450 + 1451 + if (result == TOS_FAILURE) 1452 + pr_err("ACPI call to set Fan status failed\n"); 1453 + else if (result == TOS_NOT_SUPPORTED) 1454 + return -ENODEV; 1455 + 1456 + return result == TOS_SUCCESS ? 0 : -EIO; 1357 1457 } 1358 1458 1359 1459 static int fan_proc_show(struct seq_file *m, void *v) 1360 1460 { 1361 1461 struct toshiba_acpi_dev *dev = m->private; 1362 - int ret; 1363 1462 u32 value; 1364 1463 1365 - ret = get_fan_status(dev, &value); 1366 - if (!ret) { 1367 - seq_printf(m, "running: %d\n", (value > 0)); 1368 - seq_printf(m, "force_on: %d\n", dev->force_fan); 1369 - } 1464 + if (get_fan_status(dev, &value)) 1465 + return -EIO; 1370 1466 1371 - return ret; 1467 + seq_printf(m, "running: %d\n", (value > 0)); 1468 + seq_printf(m, "force_on: %d\n", dev->force_fan); 1469 + 1470 + return 0; 1372 1471 } 1373 1472 1374 1473 static int fan_proc_open(struct inode *inode, struct file *file) ··· 1399 1466 char cmd[42]; 1400 1467 size_t len; 1401 1468 int value; 1402 - u32 hci_result; 1403 1469 1404 1470 len = min(count, sizeof(cmd) - 1); 1405 1471 if (copy_from_user(cmd, buf, len)) 1406 1472 return -EFAULT; 1407 1473 cmd[len] = '\0'; 1408 1474 1409 - if (sscanf(cmd, " force_on : %i", &value) == 1 && 1410 - value >= 0 && value <= 1) { 1411 - hci_result = hci_write(dev, HCI_FAN, value); 1412 - if (hci_result == TOS_SUCCESS) 1413 - dev->force_fan = value; 1414 - else 1415 - return -EIO; 1416 - } else { 1475 + if (sscanf(cmd, " force_on : %i", &value) != 1 && 1476 + value != 0 && value != 1) 1417 1477 return -EINVAL; 1418 - } 1478 + 1479 + if (set_fan_status(dev, value)) 1480 + return -EIO; 1481 + 1482 + dev->force_fan = value; 1419 1483 1420 1484 return count; 1421 1485 } ··· 1429 1499 static int keys_proc_show(struct seq_file *m, void *v) 1430 1500 { 1431 1501 struct toshiba_acpi_dev *dev = m->private; 1432 - u32 hci_result; 1433 - u32 value; 1434 - 1435 - if (!dev->key_event_valid && dev->system_event_supported) { 1436 - hci_result = hci_read(dev, HCI_SYSTEM_EVENT, &value); 1437 - if (hci_result == TOS_SUCCESS) { 1438 - dev->key_event_valid = 1; 1439 - dev->last_key_event = value; 1440 - } else if (hci_result == TOS_FIFO_EMPTY) { 1441 - /* Better luck next time */ 1442 - } else if (hci_result == TOS_NOT_SUPPORTED) { 1443 - /* 1444 - * This is a workaround for an unresolved issue on 1445 - * some machines where system events sporadically 1446 - * become disabled. 1447 - */ 1448 - hci_result = hci_write(dev, HCI_SYSTEM_EVENT, 1); 1449 - pr_notice("Re-enabled hotkeys\n"); 1450 - } else { 1451 - pr_err("Error reading hotkey status\n"); 1452 - return -EIO; 1453 - } 1454 - } 1455 1502 1456 1503 seq_printf(m, "hotkey_ready: %d\n", dev->key_event_valid); 1457 1504 seq_printf(m, "hotkey: 0x%04x\n", dev->last_key_event); 1505 + 1458 1506 return 0; 1459 1507 } 1460 1508 ··· 1549 1641 const char *buf, size_t count) 1550 1642 { 1551 1643 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); 1552 - u32 result; 1553 1644 int state; 1554 1645 int ret; 1555 1646 ··· 1559 1652 if (state != 0 && state != 1) 1560 1653 return -EINVAL; 1561 1654 1562 - result = hci_write(toshiba, HCI_FAN, state); 1563 - if (result == TOS_FAILURE) 1564 - return -EIO; 1565 - else if (result == TOS_NOT_SUPPORTED) 1566 - return -ENODEV; 1655 + ret = set_fan_status(toshiba, state); 1656 + if (ret) 1657 + return ret; 1567 1658 1568 1659 return count; 1569 1660 } ··· 1587 1682 { 1588 1683 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); 1589 1684 int mode; 1590 - int time; 1591 1685 int ret; 1592 1686 1593 1687 ··· 1617 1713 /* Only make a change if the actual mode has changed */ 1618 1714 if (toshiba->kbd_mode != mode) { 1619 1715 /* Shift the time to "base time" (0x3c0000 == 60 seconds) */ 1620 - time = toshiba->kbd_time << HCI_MISC_SHIFT; 1716 + int time = toshiba->kbd_time << HCI_MISC_SHIFT; 1621 1717 1622 1718 /* OR the "base time" to the actual method format */ 1623 1719 if (toshiba->kbd_type == 1) { ··· 2166 2262 }; 2167 2263 2168 2264 /* 2265 + * Misc device 2266 + */ 2267 + static int toshiba_acpi_smm_bridge(SMMRegisters *regs) 2268 + { 2269 + u32 in[TCI_WORDS] = { regs->eax, regs->ebx, regs->ecx, 2270 + regs->edx, regs->esi, regs->edi }; 2271 + u32 out[TCI_WORDS]; 2272 + acpi_status status; 2273 + 2274 + status = tci_raw(toshiba_acpi, in, out); 2275 + if (ACPI_FAILURE(status)) { 2276 + pr_err("ACPI call to query SMM registers failed\n"); 2277 + return -EIO; 2278 + } 2279 + 2280 + /* Fillout the SMM struct with the TCI call results */ 2281 + regs->eax = out[0]; 2282 + regs->ebx = out[1]; 2283 + regs->ecx = out[2]; 2284 + regs->edx = out[3]; 2285 + regs->esi = out[4]; 2286 + regs->edi = out[5]; 2287 + 2288 + return 0; 2289 + } 2290 + 2291 + static long toshiba_acpi_ioctl(struct file *fp, unsigned int cmd, 2292 + unsigned long arg) 2293 + { 2294 + SMMRegisters __user *argp = (SMMRegisters __user *)arg; 2295 + SMMRegisters regs; 2296 + int ret; 2297 + 2298 + if (!argp) 2299 + return -EINVAL; 2300 + 2301 + switch (cmd) { 2302 + case TOSH_SMM: 2303 + if (copy_from_user(&regs, argp, sizeof(SMMRegisters))) 2304 + return -EFAULT; 2305 + ret = toshiba_acpi_smm_bridge(&regs); 2306 + if (ret) 2307 + return ret; 2308 + if (copy_to_user(argp, &regs, sizeof(SMMRegisters))) 2309 + return -EFAULT; 2310 + break; 2311 + case TOSHIBA_ACPI_SCI: 2312 + if (copy_from_user(&regs, argp, sizeof(SMMRegisters))) 2313 + return -EFAULT; 2314 + /* Ensure we are being called with a SCI_{GET, SET} register */ 2315 + if (regs.eax != SCI_GET && regs.eax != SCI_SET) 2316 + return -EINVAL; 2317 + if (!sci_open(toshiba_acpi)) 2318 + return -EIO; 2319 + ret = toshiba_acpi_smm_bridge(&regs); 2320 + sci_close(toshiba_acpi); 2321 + if (ret) 2322 + return ret; 2323 + if (copy_to_user(argp, &regs, sizeof(SMMRegisters))) 2324 + return -EFAULT; 2325 + break; 2326 + default: 2327 + return -EINVAL; 2328 + } 2329 + 2330 + return 0; 2331 + } 2332 + 2333 + static const struct file_operations toshiba_acpi_fops = { 2334 + .owner = THIS_MODULE, 2335 + .unlocked_ioctl = toshiba_acpi_ioctl, 2336 + .llseek = noop_llseek, 2337 + }; 2338 + 2339 + /* 2169 2340 * Hotkeys 2170 2341 */ 2171 2342 static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) ··· 2340 2361 2341 2362 static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev) 2342 2363 { 2343 - u32 hci_result, value; 2344 - int retries = 3; 2345 - int scancode; 2346 - 2347 2364 if (dev->info_supported) { 2348 - scancode = toshiba_acpi_query_hotkey(dev); 2349 - if (scancode < 0) 2365 + int scancode = toshiba_acpi_query_hotkey(dev); 2366 + 2367 + if (scancode < 0) { 2350 2368 pr_err("Failed to query hotkey event\n"); 2351 - else if (scancode != 0) 2369 + } else if (scancode != 0) { 2352 2370 toshiba_acpi_report_hotkey(dev, scancode); 2371 + dev->key_event_valid = 1; 2372 + dev->last_key_event = scancode; 2373 + } 2353 2374 } else if (dev->system_event_supported) { 2375 + u32 result; 2376 + u32 value; 2377 + int retries = 3; 2378 + 2354 2379 do { 2355 - hci_result = hci_read(dev, HCI_SYSTEM_EVENT, &value); 2356 - switch (hci_result) { 2380 + result = hci_read(dev, HCI_SYSTEM_EVENT, &value); 2381 + switch (result) { 2357 2382 case TOS_SUCCESS: 2358 2383 toshiba_acpi_report_hotkey(dev, (int)value); 2384 + dev->key_event_valid = 1; 2385 + dev->last_key_event = value; 2359 2386 break; 2360 2387 case TOS_NOT_SUPPORTED: 2361 2388 /* ··· 2369 2384 * issue on some machines where system events 2370 2385 * sporadically become disabled. 2371 2386 */ 2372 - hci_result = 2373 - hci_write(dev, HCI_SYSTEM_EVENT, 1); 2374 - pr_notice("Re-enabled hotkeys\n"); 2387 + result = hci_write(dev, HCI_SYSTEM_EVENT, 1); 2388 + if (result == TOS_SUCCESS) 2389 + pr_notice("Re-enabled hotkeys\n"); 2375 2390 /* Fall through */ 2376 2391 default: 2377 2392 retries--; 2378 2393 break; 2379 2394 } 2380 - } while (retries && hci_result != TOS_FIFO_EMPTY); 2395 + } while (retries && result != TOS_FIFO_EMPTY); 2381 2396 } 2382 2397 } 2383 2398 ··· 2388 2403 u32 events_type; 2389 2404 u32 hci_result; 2390 2405 int error; 2406 + 2407 + if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) { 2408 + pr_info("WMI event detected, hotkeys will not be monitored\n"); 2409 + return 0; 2410 + } 2391 2411 2392 2412 error = toshiba_acpi_enable_hotkeys(dev); 2393 2413 if (error) ··· 2486 2496 struct backlight_properties props; 2487 2497 int brightness; 2488 2498 int ret; 2489 - bool enabled; 2490 2499 2491 2500 /* 2492 2501 * Some machines don't support the backlight methods at all, and ··· 2501 2512 pr_debug("Backlight method is read-only, disabling backlight support\n"); 2502 2513 return 0; 2503 2514 } 2504 - 2505 - /* Determine whether or not BIOS supports transflective backlight */ 2506 - ret = get_tr_backlight_status(dev, &enabled); 2507 - dev->tr_backlight_supported = !ret; 2508 2515 2509 2516 /* 2510 2517 * Tell acpi-video-detect code to prefer vendor backlight on all ··· 2537 2552 return 0; 2538 2553 } 2539 2554 2555 + static void print_supported_features(struct toshiba_acpi_dev *dev) 2556 + { 2557 + pr_info("Supported laptop features:"); 2558 + 2559 + if (dev->hotkey_dev) 2560 + pr_cont(" hotkeys"); 2561 + if (dev->backlight_dev) 2562 + pr_cont(" backlight"); 2563 + if (dev->video_supported) 2564 + pr_cont(" video-out"); 2565 + if (dev->fan_supported) 2566 + pr_cont(" fan"); 2567 + if (dev->tr_backlight_supported) 2568 + pr_cont(" transflective-backlight"); 2569 + if (dev->illumination_supported) 2570 + pr_cont(" illumination"); 2571 + if (dev->kbd_illum_supported) 2572 + pr_cont(" keyboard-backlight"); 2573 + if (dev->touchpad_supported) 2574 + pr_cont(" touchpad"); 2575 + if (dev->eco_supported) 2576 + pr_cont(" eco-led"); 2577 + if (dev->accelerometer_supported) 2578 + pr_cont(" accelerometer-axes"); 2579 + if (dev->usb_sleep_charge_supported) 2580 + pr_cont(" usb-sleep-charge"); 2581 + if (dev->usb_rapid_charge_supported) 2582 + pr_cont(" usb-rapid-charge"); 2583 + if (dev->usb_sleep_music_supported) 2584 + pr_cont(" usb-sleep-music"); 2585 + if (dev->kbd_function_keys_supported) 2586 + pr_cont(" special-function-keys"); 2587 + if (dev->panel_power_on_supported) 2588 + pr_cont(" panel-power-on"); 2589 + if (dev->usb_three_supported) 2590 + pr_cont(" usb3"); 2591 + 2592 + pr_cont("\n"); 2593 + } 2594 + 2540 2595 static int toshiba_acpi_remove(struct acpi_device *acpi_dev) 2541 2596 { 2542 2597 struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); 2598 + 2599 + misc_deregister(&dev->miscdev); 2543 2600 2544 2601 remove_toshiba_proc_entries(dev); 2545 2602 ··· 2601 2574 2602 2575 backlight_device_unregister(dev->backlight_dev); 2603 2576 2604 - if (dev->illumination_supported) 2577 + if (dev->illumination_led_registered) 2605 2578 led_classdev_unregister(&dev->led_dev); 2606 2579 2607 2580 if (dev->kbd_led_registered) 2608 2581 led_classdev_unregister(&dev->kbd_led); 2609 2582 2610 - if (dev->eco_supported) 2583 + if (dev->eco_led_registered) 2611 2584 led_classdev_unregister(&dev->eco_led); 2612 2585 2613 2586 if (toshiba_acpi) ··· 2654 2627 return -ENOMEM; 2655 2628 dev->acpi_dev = acpi_dev; 2656 2629 dev->method_hci = hci_method; 2630 + dev->miscdev.minor = MISC_DYNAMIC_MINOR; 2631 + dev->miscdev.name = "toshiba_acpi"; 2632 + dev->miscdev.fops = &toshiba_acpi_fops; 2633 + 2634 + ret = misc_register(&dev->miscdev); 2635 + if (ret) { 2636 + pr_err("Failed to register miscdevice\n"); 2637 + kfree(dev); 2638 + return ret; 2639 + } 2640 + 2657 2641 acpi_dev->driver_data = dev; 2658 2642 dev_set_drvdata(&acpi_dev->dev, dev); 2659 2643 ··· 2681 2643 if (toshiba_acpi_setup_keyboard(dev)) 2682 2644 pr_info("Unable to activate hotkeys\n"); 2683 2645 2646 + /* Determine whether or not BIOS supports transflective backlight */ 2647 + ret = get_tr_backlight_status(dev, &dummy); 2648 + dev->tr_backlight_supported = !ret; 2649 + 2684 2650 ret = toshiba_acpi_setup_backlight(dev); 2685 2651 if (ret) 2686 2652 goto error; 2687 2653 2688 - if (toshiba_illumination_available(dev)) { 2654 + toshiba_illumination_available(dev); 2655 + if (dev->illumination_supported) { 2689 2656 dev->led_dev.name = "toshiba::illumination"; 2690 2657 dev->led_dev.max_brightness = 1; 2691 2658 dev->led_dev.brightness_set = toshiba_illumination_set; 2692 2659 dev->led_dev.brightness_get = toshiba_illumination_get; 2693 2660 if (!led_classdev_register(&acpi_dev->dev, &dev->led_dev)) 2694 - dev->illumination_supported = 1; 2661 + dev->illumination_led_registered = true; 2695 2662 } 2696 2663 2697 - if (toshiba_eco_mode_available(dev)) { 2664 + toshiba_eco_mode_available(dev); 2665 + if (dev->eco_supported) { 2698 2666 dev->eco_led.name = "toshiba::eco_mode"; 2699 2667 dev->eco_led.max_brightness = 1; 2700 2668 dev->eco_led.brightness_set = toshiba_eco_mode_set_status; 2701 2669 dev->eco_led.brightness_get = toshiba_eco_mode_get_status; 2702 2670 if (!led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led)) 2703 - dev->eco_supported = 1; 2671 + dev->eco_led_registered = true; 2704 2672 } 2705 2673 2706 - dev->kbd_illum_supported = toshiba_kbd_illum_available(dev); 2674 + toshiba_kbd_illum_available(dev); 2707 2675 /* 2708 2676 * Only register the LED if KBD illumination is supported 2709 2677 * and the keyboard backlight operation mode is set to FN-Z ··· 2720 2676 dev->kbd_led.brightness_set = toshiba_kbd_backlight_set; 2721 2677 dev->kbd_led.brightness_get = toshiba_kbd_backlight_get; 2722 2678 if (!led_classdev_register(&dev->acpi_dev->dev, &dev->kbd_led)) 2723 - dev->kbd_led_registered = 1; 2679 + dev->kbd_led_registered = true; 2724 2680 } 2725 2681 2726 2682 ret = toshiba_touchpad_get(dev, &dummy); 2727 2683 dev->touchpad_supported = !ret; 2728 2684 2729 - ret = toshiba_accelerometer_supported(dev); 2730 - dev->accelerometer_supported = !ret; 2685 + toshiba_accelerometer_available(dev); 2731 2686 2732 2687 toshiba_usb_sleep_charge_available(dev); 2733 2688 ··· 2747 2704 2748 2705 ret = get_fan_status(dev, &dummy); 2749 2706 dev->fan_supported = !ret; 2707 + 2708 + print_supported_features(dev); 2750 2709 2751 2710 /* 2752 2711 * Enable the "Special Functions" mode only if they are ··· 2783 2738 2784 2739 switch (event) { 2785 2740 case 0x80: /* Hotkeys and some system events */ 2741 + /* 2742 + * Machines with this WMI GUID aren't supported due to bugs in 2743 + * their AML. 2744 + * 2745 + * Return silently to avoid triggering a netlink event. 2746 + */ 2747 + if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) 2748 + return; 2786 2749 toshiba_acpi_process_hotkeys(dev); 2787 2750 break; 2788 2751 case 0x81: /* Dock events */ ··· 2834 2781 static int toshiba_acpi_suspend(struct device *device) 2835 2782 { 2836 2783 struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); 2837 - u32 result; 2838 2784 2839 - if (dev->hotkey_dev) 2785 + if (dev->hotkey_dev) { 2786 + u32 result; 2787 + 2840 2788 result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_DISABLE); 2789 + if (result != TOS_SUCCESS) 2790 + pr_info("Unable to disable hotkeys\n"); 2791 + } 2841 2792 2842 2793 return 0; 2843 2794 } ··· 2849 2792 static int toshiba_acpi_resume(struct device *device) 2850 2793 { 2851 2794 struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); 2852 - int error; 2853 2795 2854 2796 if (dev->hotkey_dev) { 2855 - error = toshiba_acpi_enable_hotkeys(dev); 2797 + int error = toshiba_acpi_enable_hotkeys(dev); 2798 + 2856 2799 if (error) 2857 2800 pr_info("Unable to re-enable hotkeys\n"); 2858 2801 } ··· 2880 2823 static int __init toshiba_acpi_init(void) 2881 2824 { 2882 2825 int ret; 2883 - 2884 - /* 2885 - * Machines with this WMI guid aren't supported due to bugs in 2886 - * their AML. This check relies on wmi initializing before 2887 - * toshiba_acpi to guarantee guids have been identified. 2888 - */ 2889 - if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) 2890 - return -ENODEV; 2891 2826 2892 2827 toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); 2893 2828 if (!toshiba_proc_dir) {
+29 -3
include/uapi/linux/toshiba.h
··· 1 1 /* toshiba.h -- Linux driver for accessing the SMM on Toshiba laptops 2 2 * 3 3 * Copyright (c) 1996-2000 Jonathan A. Buzzard (jonathan@buzzard.org.uk) 4 + * Copyright (c) 2015 Azael Avalos <coproscefalo@gmail.com> 4 5 * 5 6 * Thanks to Juergen Heinzl <juergen@monocerus.demon.co.uk> for the pointers 6 7 * on making sure the structure is aligned and packed. ··· 21 20 #ifndef _UAPI_LINUX_TOSHIBA_H 22 21 #define _UAPI_LINUX_TOSHIBA_H 23 22 24 - #define TOSH_PROC "/proc/toshiba" 25 - #define TOSH_DEVICE "/dev/toshiba" 26 - #define TOSH_SMM _IOWR('t', 0x90, int) /* broken: meant 24 bytes */ 23 + /* 24 + * Toshiba modules paths 25 + */ 26 + 27 + #define TOSH_PROC "/proc/toshiba" 28 + #define TOSH_DEVICE "/dev/toshiba" 29 + #define TOSHIBA_ACPI_PROC "/proc/acpi/toshiba" 30 + #define TOSHIBA_ACPI_DEVICE "/dev/toshiba_acpi" 31 + 32 + /* 33 + * Toshiba SMM structure 34 + */ 27 35 28 36 typedef struct { 29 37 unsigned int eax; ··· 42 32 unsigned int esi __attribute__ ((packed)); 43 33 unsigned int edi __attribute__ ((packed)); 44 34 } SMMRegisters; 35 + 36 + /* 37 + * IOCTLs (0x90 - 0x91) 38 + */ 39 + 40 + #define TOSH_SMM _IOWR('t', 0x90, SMMRegisters) 41 + /* 42 + * Convenience toshiba_acpi command. 43 + * 44 + * The System Configuration Interface (SCI) is opened/closed internally 45 + * to avoid userspace of buggy BIOSes. 46 + * 47 + * The toshiba_acpi module checks whether the eax register is set with 48 + * SCI_GET (0xf300) or SCI_SET (0xf400), returning -EINVAL if not. 49 + */ 50 + #define TOSHIBA_ACPI_SCI _IOWR('t', 0x91, SMMRegisters) 45 51 46 52 47 53 #endif /* _UAPI_LINUX_TOSHIBA_H */