diff options
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 94 |
1 files changed, 34 insertions, 60 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c4680037bbfd..6ed5be030d58 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -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 */ |