diff options
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 77244c9aa60d..5ad3a7183d33 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -57,6 +57,11 @@ module_param(turn_on_panel_on_resume, int, 0644); MODULE_PARM_DESC(turn_on_panel_on_resume, "Call HCI_PANEL_POWER_ON on resume (-1 = auto, 0 = no, 1 = yes"); +static int hci_hotkey_quickstart = -1; +module_param(hci_hotkey_quickstart, int, 0644); +MODULE_PARM_DESC(hci_hotkey_quickstart, + "Call HCI_HOTKEY_EVENT with value 0x5 for quickstart button support (-1 = auto, 0 = no, 1 = yes"); + #define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100" /* Scan code for Fn key on TOS1900 models */ @@ -136,6 +141,7 @@ MODULE_PARM_DESC(turn_on_panel_on_resume, #define HCI_ACCEL_MASK 0x7fff #define HCI_ACCEL_DIRECTION_MASK 0x8000 #define HCI_HOTKEY_DISABLE 0x0b +#define HCI_HOTKEY_ENABLE_QUICKSTART 0x05 #define HCI_HOTKEY_ENABLE 0x09 #define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 #define HCI_LCD_BRIGHTNESS_BITS 3 @@ -1815,12 +1821,7 @@ static DECLARE_WORK(kbd_bl_work, toshiba_acpi_kbd_bl_work); /* * Sysfs files */ -static ssize_t version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", TOSHIBA_ACPI_VERSION); -} -static DEVICE_ATTR_RO(version); +static DEVICE_STRING_ATTR_RO(version, 0444, TOSHIBA_ACPI_VERSION); static ssize_t fan_store(struct device *dev, struct device_attribute *attr, @@ -2429,7 +2430,7 @@ static ssize_t cooling_method_store(struct device *dev, static DEVICE_ATTR_RW(cooling_method); static struct attribute *toshiba_attributes[] = { - &dev_attr_version.attr, + &dev_attr_version.attr.attr, &dev_attr_fan.attr, &dev_attr_kbd_backlight_mode.attr, &dev_attr_kbd_type.attr, @@ -2731,10 +2732,15 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) return -ENODEV; /* + * Enable quickstart buttons if supported. + * * Enable the "Special Functions" mode only if they are * supported and if they are activated. */ - if (dev->kbd_function_keys_supported && dev->special_functions) + if (hci_hotkey_quickstart) + result = hci_write(dev, HCI_HOTKEY_EVENT, + HCI_HOTKEY_ENABLE_QUICKSTART); + else if (dev->kbd_function_keys_supported && dev->special_functions) result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_SPECIAL_FUNCTIONS); else @@ -2749,7 +2755,7 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) } static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, - struct serio *port) + struct serio *port, void *context) { if (str & I8042_STR_AUXDATA) return false; @@ -2909,7 +2915,7 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) if (ec_handle && acpi_has_method(ec_handle, "NTFY")) { INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); - error = i8042_install_filter(toshiba_acpi_i8042_filter); + error = i8042_install_filter(toshiba_acpi_i8042_filter, NULL); if (error) { pr_err("Error installing key filter\n"); goto err_free_dev; @@ -3258,7 +3264,14 @@ static const char *find_hci_method(acpi_handle handle) * works. toshiba_acpi_resume() uses HCI_PANEL_POWER_ON to avoid changing * the configured brightness level. */ -static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { +#define QUIRK_TURN_ON_PANEL_ON_RESUME BIT(0) +/* + * Some Toshibas use "quickstart" keys. On these, HCI_HOTKEY_EVENT must use + * the value HCI_HOTKEY_ENABLE_QUICKSTART. + */ +#define QUIRK_HCI_HOTKEY_QUICKSTART BIT(1) + +static const struct dmi_system_id toshiba_dmi_quirks[] __initconst = { { /* Toshiba Portégé R700 */ /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ @@ -3266,6 +3279,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"), }, + .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME, }, { /* Toshiba Satellite/Portégé R830 */ @@ -3275,6 +3289,7 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "R830"), }, + .driver_data = (void *)QUIRK_TURN_ON_PANEL_ON_RESUME, }, { /* Toshiba Satellite/Portégé Z830 */ @@ -3282,7 +3297,9 @@ static const struct dmi_system_id turn_on_panel_on_resume_dmi_ids[] = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), DMI_MATCH(DMI_PRODUCT_NAME, "Z830"), }, + .driver_data = (void *)(QUIRK_TURN_ON_PANEL_ON_RESUME | QUIRK_HCI_HOTKEY_QUICKSTART), }, + { } }; static int toshiba_acpi_add(struct acpi_device *acpi_dev) @@ -3442,9 +3459,6 @@ iio_error: } #endif - if (turn_on_panel_on_resume == -1) - turn_on_panel_on_resume = dmi_check_system(turn_on_panel_on_resume_dmi_ids); - toshiba_wwan_available(dev); if (dev->wwan_supported) toshiba_acpi_setup_wwan_rfkill(dev); @@ -3583,7 +3597,6 @@ static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, static struct acpi_driver toshiba_acpi_driver = { .name = "Toshiba ACPI driver", - .owner = THIS_MODULE, .ids = toshiba_device_ids, .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, .ops = { @@ -3594,10 +3607,27 @@ static struct acpi_driver toshiba_acpi_driver = { .drv.pm = &toshiba_acpi_pm, }; +static void __init toshiba_dmi_init(void) +{ + const struct dmi_system_id *dmi_id; + long quirks = 0; + + dmi_id = dmi_first_match(toshiba_dmi_quirks); + if (dmi_id) + quirks = (long)dmi_id->driver_data; + + if (turn_on_panel_on_resume == -1) + turn_on_panel_on_resume = !!(quirks & QUIRK_TURN_ON_PANEL_ON_RESUME); + + if (hci_hotkey_quickstart == -1) + hci_hotkey_quickstart = !!(quirks & QUIRK_HCI_HOTKEY_QUICKSTART); +} + static int __init toshiba_acpi_init(void) { int ret; + toshiba_dmi_init(); toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); if (!toshiba_proc_dir) { pr_err("Unable to create proc dir " PROC_TOSHIBA "\n"); |