diff options
author | Arnd Bergmann <arnd@arndb.de> | 2014-12-30 13:17:07 +0300 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2014-12-30 17:27:20 +0300 |
commit | 7ebdfaa52d15b947503f76474477f92854796d96 (patch) | |
tree | 27cd7acfcd264e8d643db86185f9e3a33a5cf367 /drivers/platform/x86/toshiba_acpi.c | |
parent | d6ad36913083d683aad4e02e53580c995f1a6ede (diff) | |
parent | d4b0833a65e8b9fc58d992ba0cc89cad1580db31 (diff) | |
download | linux-7ebdfaa52d15b947503f76474477f92854796d96.tar.xz |
Merge tag 'mvebu-fixes-3.19' of git://git.infradead.org/linux-mvebu into fixes
Pull "Fixes for 3.19" from Andrew Lunn:
Jason is taking a back seat this cycle and i'm doing all the patch
wrangling for mvebu.
* tag 'mvebu-fixes-3.19' of git://git.infradead.org/linux-mvebu:
ARM: mvebu: Fix pinctrl configuration for Armada 370 DB
Also update to Linux 3.19-rc1, which this was based on.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 166 |
1 files changed, 93 insertions, 73 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index ab6151f05420..fc34a71866ed 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -186,6 +186,7 @@ static struct toshiba_acpi_dev *toshiba_acpi; static const struct acpi_device_id toshiba_device_ids[] = { {"TOS6200", 0}, + {"TOS6207", 0}, {"TOS6208", 0}, {"TOS1900", 0}, {"", 0}, @@ -928,9 +929,7 @@ static int lcd_proc_open(struct inode *inode, struct file *file) static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) { - u32 in[TCI_WORDS] = { HCI_SET, HCI_LCD_BRIGHTNESS, 0, 0, 0, 0 }; - u32 out[TCI_WORDS]; - acpi_status status; + u32 hci_result; if (dev->tr_backlight_supported) { bool enable = !value; @@ -941,20 +940,9 @@ static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) value--; } - in[2] = value << HCI_LCD_BRIGHTNESS_SHIFT; - status = tci_raw(dev, in, out); - if (ACPI_FAILURE(status) || out[0] == TOS_FAILURE) { - pr_err("ACPI call to set brightness failed"); - return -EIO; - } - /* Extra check for "incomplete" backlight method, where the AML code - * doesn't check for HCI_SET or HCI_GET and returns TOS_SUCCESS, - * the actual brightness, and in some cases the max brightness. - */ - if (out[2] > 0 || out[3] == 0xE000) - return -ENODEV; - - return out[0] == TOS_SUCCESS ? 0 : -EIO; + value = value << HCI_LCD_BRIGHTNESS_SHIFT; + hci_result = hci_write1(dev, HCI_LCD_BRIGHTNESS, value); + return hci_result == TOS_SUCCESS ? 0 : -EIO; } static int set_lcd_status(struct backlight_device *bd) @@ -1406,12 +1394,6 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, if (ret) return ret; - /* Update sysfs entries on successful mode change*/ - ret = sysfs_update_group(&toshiba->acpi_dev->dev.kobj, - &toshiba_attr_group); - if (ret) - return ret; - toshiba->kbd_mode = mode; } @@ -1586,10 +1568,32 @@ static umode_t toshiba_sysfs_is_visible(struct kobject *kobj, return exists ? attr->mode : 0; } +/* + * Hotkeys + */ +static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev) +{ + acpi_status status; + u32 result; + + status = acpi_evaluate_object(dev->acpi_dev->handle, + "ENAB", NULL, NULL); + if (ACPI_FAILURE(status)) + return -ENODEV; + + result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); + if (result == TOS_FAILURE) + return -EIO; + else if (result == TOS_NOT_SUPPORTED) + return -ENODEV; + + return 0; +} + static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, struct serio *port) { - if (str & 0x20) + if (str & I8042_STR_AUXDATA) return false; if (unlikely(data == 0xe0)) @@ -1648,9 +1652,45 @@ static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, pr_info("Unknown key %x\n", scancode); } +static void toshiba_acpi_process_hotkeys(struct toshiba_acpi_dev *dev) +{ + u32 hci_result, value; + int retries = 3; + int scancode; + + if (dev->info_supported) { + scancode = toshiba_acpi_query_hotkey(dev); + if (scancode < 0) + pr_err("Failed to query hotkey event\n"); + else if (scancode != 0) + toshiba_acpi_report_hotkey(dev, scancode); + } else if (dev->system_event_supported) { + do { + hci_result = hci_read1(dev, HCI_SYSTEM_EVENT, &value); + switch (hci_result) { + case TOS_SUCCESS: + toshiba_acpi_report_hotkey(dev, (int)value); + break; + case TOS_NOT_SUPPORTED: + /* + * This is a workaround for an unresolved + * issue on some machines where system events + * sporadically become disabled. + */ + hci_result = + hci_write1(dev, HCI_SYSTEM_EVENT, 1); + pr_notice("Re-enabled hotkeys\n"); + /* fall through */ + default: + retries--; + break; + } + } while (retries && hci_result != TOS_FIFO_EMPTY); + } +} + static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) { - acpi_status status; acpi_handle ec_handle; int error; u32 hci_result; @@ -1677,7 +1717,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) * supported, so if it's present set up an i8042 key filter * for this purpose. */ - status = AE_ERROR; ec_handle = ec_get_handle(); if (ec_handle && acpi_has_method(ec_handle, "NTFY")) { INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); @@ -1708,10 +1747,9 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) goto err_remove_filter; } - status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); - if (ACPI_FAILURE(status)) { + error = toshiba_acpi_enable_hotkeys(dev); + if (error) { pr_info("Unable to enable hotkeys\n"); - error = -ENODEV; goto err_remove_filter; } @@ -1721,7 +1759,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) goto err_remove_filter; } - hci_result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); return 0; err_remove_filter: @@ -1810,8 +1847,7 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev) rfkill_destroy(dev->bt_rfk); } - if (dev->backlight_dev) - backlight_device_unregister(dev->backlight_dev); + backlight_device_unregister(dev->backlight_dev); if (dev->illumination_supported) led_classdev_unregister(&dev->led_dev); @@ -1967,41 +2003,29 @@ error: static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); - u32 hci_result, value; - int retries = 3; - int scancode; - - if (event != 0x80) - return; + int ret; - if (dev->info_supported) { - scancode = toshiba_acpi_query_hotkey(dev); - if (scancode < 0) - pr_err("Failed to query hotkey event\n"); - else if (scancode != 0) - toshiba_acpi_report_hotkey(dev, scancode); - } else if (dev->system_event_supported) { - do { - hci_result = hci_read1(dev, HCI_SYSTEM_EVENT, &value); - switch (hci_result) { - case TOS_SUCCESS: - toshiba_acpi_report_hotkey(dev, (int)value); - break; - case TOS_NOT_SUPPORTED: - /* - * This is a workaround for an unresolved - * issue on some machines where system events - * sporadically become disabled. - */ - hci_result = - hci_write1(dev, HCI_SYSTEM_EVENT, 1); - pr_notice("Re-enabled hotkeys\n"); - /* fall through */ - default: - retries--; - break; - } - } while (retries && hci_result != TOS_FIFO_EMPTY); + switch (event) { + case 0x80: /* Hotkeys and some system events */ + toshiba_acpi_process_hotkeys(dev); + break; + case 0x92: /* Keyboard backlight mode changed */ + /* Update sysfs entries */ + ret = sysfs_update_group(&acpi_dev->dev.kobj, + &toshiba_attr_group); + if (ret) + pr_err("Unable to update sysfs entries\n"); + break; + case 0x81: /* Unknown */ + case 0x82: /* Unknown */ + case 0x83: /* Unknown */ + case 0x8c: /* Unknown */ + case 0x8e: /* Unknown */ + case 0x8f: /* Unknown */ + case 0x90: /* Unknown */ + default: + pr_info("Unknown event received %x\n", event); + break; } } @@ -2020,16 +2044,12 @@ static int toshiba_acpi_suspend(struct device *device) static int toshiba_acpi_resume(struct device *device) { struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); - u32 result; - acpi_status status; + int error; if (dev->hotkey_dev) { - status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", - NULL, NULL); - if (ACPI_FAILURE(status)) + error = toshiba_acpi_enable_hotkeys(dev); + if (error) pr_info("Unable to re-enable hotkeys\n"); - - result = hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); } return 0; |