toshiba_acpi: Adapt Illumination code to use SCI
authorAzael Avalos <coproscefalo@gmail.com>
Wed, 26 Mar 2014 02:38:30 +0000 (20:38 -0600)
committerMatthew Garrett <matthew.garrett@nebula.com>
Sun, 6 Apr 2014 16:58:13 +0000 (12:58 -0400)
Change the toshiba_illumination_* code to use the
newly introduced SCI functions, making the code
more robust in detecting Illumination capabilities
properly, since it was only opening the SCI and
the return value was never checked for errors or
actual Illumination support.

Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
drivers/platform/x86/toshiba_acpi.c

index c4680037bbfdee63ae4d7f202ad4430581a620ca..6ed5be030d5885a03306d39425e0951ea9da7129 100644 (file)
@@ -100,6 +100,7 @@ MODULE_LICENSE("GPL");
 #define SCI_OPEN_CLOSE_OK              0x0044
 #define SCI_ALREADY_OPEN               0x8100
 #define SCI_NOT_OPENED                 0x8200
+#define SCI_INPUT_DATA_ERROR           0x8300
 #define SCI_NOT_PRESENT                        0x8600
 
 /* registers */
@@ -110,6 +111,7 @@ MODULE_LICENSE("GPL");
 #define HCI_HOTKEY_EVENT               0x001e
 #define HCI_LCD_BRIGHTNESS             0x002a
 #define HCI_WIRELESS                   0x0056
+#define SCI_ILLUMINATION               0x014e
 
 /* field definitions */
 #define HCI_HOTKEY_DISABLE             0x0b
@@ -362,18 +364,23 @@ static acpi_status sci_write(struct toshiba_acpi_dev *dev, u32 reg,
 /* Illumination support */
 static int toshiba_illumination_available(struct toshiba_acpi_dev *dev)
 {
-       u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
+       u32 in[HCI_WORDS] = { SCI_GET, SCI_ILLUMINATION, 0, 0, 0, 0 };
        u32 out[HCI_WORDS];
        acpi_status status;
 
-       in[0] = 0xf100;
+       if (!sci_open(dev))
+               return 0;
+
        status = hci_raw(dev, in, out);
-       if (ACPI_FAILURE(status)) {
+       sci_close(dev);
+       if (ACPI_FAILURE(status) || out[0] == HCI_FAILURE) {
+               pr_err("ACPI call to query Illumination support failed\n");
+               return 0;
+       } else if (out[0] == HCI_NOT_SUPPORTED || out[1] != 1) {
                pr_info("Illumination device not available\n");
                return 0;
        }
-       in[0] = 0xf400;
-       status = hci_raw(dev, in, out);
+
        return 1;
 }
 
@@ -382,82 +389,49 @@ static void toshiba_illumination_set(struct led_classdev *cdev,
 {
        struct toshiba_acpi_dev *dev = container_of(cdev,
                        struct toshiba_acpi_dev, led_dev);
-       u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
-       u32 out[HCI_WORDS];
+       u32 state, result;
        acpi_status status;
 
        /* First request : initialize communication. */
-       in[0] = 0xf100;
-       status = hci_raw(dev, in, out);
-       if (ACPI_FAILURE(status)) {
-               pr_info("Illumination device not available\n");
+       if (!sci_open(dev))
                return;
-       }
 
-       if (brightness) {
-               /* Switch the illumination on */
-               in[0] = 0xf400;
-               in[1] = 0x14e;
-               in[2] = 1;
-               status = hci_raw(dev, in, out);
-               if (ACPI_FAILURE(status)) {
-                       pr_info("ACPI call for illumination failed\n");
-                       return;
-               }
-       } else {
-               /* Switch the illumination off */
-               in[0] = 0xf400;
-               in[1] = 0x14e;
-               in[2] = 0;
-               status = hci_raw(dev, in, out);
-               if (ACPI_FAILURE(status)) {
-                       pr_info("ACPI call for illumination failed.\n");
-                       return;
-               }
+       /* Switch the illumination on/off */
+       state = brightness ? 1 : 0;
+       status = sci_write(dev, SCI_ILLUMINATION, state, &result);
+       sci_close(dev);
+       if (ACPI_FAILURE(status)) {
+               pr_err("ACPI call for illumination failed\n");
+               return;
+       } else if (result == HCI_NOT_SUPPORTED) {
+               pr_info("Illumination not supported\n");
+               return;
        }
-
-       /* Last request : close communication. */
-       in[0] = 0xf200;
-       in[1] = 0;
-       in[2] = 0;
-       hci_raw(dev, in, out);
 }
 
 static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev)
 {
        struct toshiba_acpi_dev *dev = container_of(cdev,
                        struct toshiba_acpi_dev, led_dev);
-       u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
-       u32 out[HCI_WORDS];
+       u32 state, result;
        acpi_status status;
-       enum led_brightness result;
 
        /* First request : initialize communication. */
-       in[0] = 0xf100;
-       status = hci_raw(dev, in, out);
-       if (ACPI_FAILURE(status)) {
-               pr_info("Illumination device not available\n");
+       if (!sci_open(dev))
                return LED_OFF;
-       }
 
        /* Check the illumination */
-       in[0] = 0xf300;
-       in[1] = 0x14e;
-       status = hci_raw(dev, in, out);
-       if (ACPI_FAILURE(status)) {
-               pr_info("ACPI call for illumination failed.\n");
+       status = sci_read(dev, SCI_ILLUMINATION, &state, &result);
+       sci_close(dev);
+       if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
+               pr_err("ACPI call for illumination failed\n");
+               return LED_OFF;
+       } else if (result == HCI_NOT_SUPPORTED) {
+               pr_info("Illumination not supported\n");
                return LED_OFF;
        }
 
-       result = out[2] ? LED_FULL : LED_OFF;
-
-       /* Last request : close communication. */
-       in[0] = 0xf200;
-       in[1] = 0;
-       in[2] = 0;
-       hci_raw(dev, in, out);
-
-       return result;
+       return state ? LED_FULL : LED_OFF;
 }
 
 /* Bluetooth rfkill handlers */