Merge tag 'iwlwifi-next-for-kalle-2015-02-03' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / drivers / platform / x86 / toshiba_acpi.c
index ab6151f..fc34a71 100644 (file)
@@ -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;