Commit fdb79081 authored by Azael Avalos's avatar Azael Avalos Committed by Matthew Garrett

toshiba_acpi: Adapt Illumination code to use SCI

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: default avatarAzael Avalos <coproscefalo@gmail.com>
Signed-off-by: default avatarMatthew Garrett <matthew.garrett@nebula.com>
parent 84a6273f
...@@ -100,6 +100,7 @@ MODULE_LICENSE("GPL"); ...@@ -100,6 +100,7 @@ MODULE_LICENSE("GPL");
#define SCI_OPEN_CLOSE_OK 0x0044 #define SCI_OPEN_CLOSE_OK 0x0044
#define SCI_ALREADY_OPEN 0x8100 #define SCI_ALREADY_OPEN 0x8100
#define SCI_NOT_OPENED 0x8200 #define SCI_NOT_OPENED 0x8200
#define SCI_INPUT_DATA_ERROR 0x8300
#define SCI_NOT_PRESENT 0x8600 #define SCI_NOT_PRESENT 0x8600
/* registers */ /* registers */
...@@ -110,6 +111,7 @@ MODULE_LICENSE("GPL"); ...@@ -110,6 +111,7 @@ MODULE_LICENSE("GPL");
#define HCI_HOTKEY_EVENT 0x001e #define HCI_HOTKEY_EVENT 0x001e
#define HCI_LCD_BRIGHTNESS 0x002a #define HCI_LCD_BRIGHTNESS 0x002a
#define HCI_WIRELESS 0x0056 #define HCI_WIRELESS 0x0056
#define SCI_ILLUMINATION 0x014e
/* field definitions */ /* field definitions */
#define HCI_HOTKEY_DISABLE 0x0b #define HCI_HOTKEY_DISABLE 0x0b
...@@ -362,18 +364,23 @@ static acpi_status sci_write(struct toshiba_acpi_dev *dev, u32 reg, ...@@ -362,18 +364,23 @@ static acpi_status sci_write(struct toshiba_acpi_dev *dev, u32 reg,
/* Illumination support */ /* Illumination support */
static int toshiba_illumination_available(struct toshiba_acpi_dev *dev) 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]; u32 out[HCI_WORDS];
acpi_status status; acpi_status status;
in[0] = 0xf100; if (!sci_open(dev))
return 0;
status = hci_raw(dev, in, out); 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"); pr_info("Illumination device not available\n");
return 0; return 0;
} }
in[0] = 0xf400;
status = hci_raw(dev, in, out);
return 1; return 1;
} }
...@@ -382,82 +389,49 @@ static void toshiba_illumination_set(struct led_classdev *cdev, ...@@ -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 *dev = container_of(cdev,
struct toshiba_acpi_dev, led_dev); struct toshiba_acpi_dev, led_dev);
u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; u32 state, result;
u32 out[HCI_WORDS];
acpi_status status; acpi_status status;
/* First request : initialize communication. */ /* First request : initialize communication. */
in[0] = 0xf100; if (!sci_open(dev))
status = hci_raw(dev, in, out);
if (ACPI_FAILURE(status)) {
pr_info("Illumination device not available\n");
return; return;
}
if (brightness) { /* Switch the illumination on/off */
/* Switch the illumination on */ state = brightness ? 1 : 0;
in[0] = 0xf400; status = sci_write(dev, SCI_ILLUMINATION, state, &result);
in[1] = 0x14e; sci_close(dev);
in[2] = 1;
status = hci_raw(dev, in, out);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
pr_info("ACPI call for illumination failed\n"); pr_err("ACPI call for illumination failed\n");
return; return;
} } else if (result == HCI_NOT_SUPPORTED) {
} else { pr_info("Illumination not supported\n");
/* 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; 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) static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev)
{ {
struct toshiba_acpi_dev *dev = container_of(cdev, struct toshiba_acpi_dev *dev = container_of(cdev,
struct toshiba_acpi_dev, led_dev); struct toshiba_acpi_dev, led_dev);
u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 }; u32 state, result;
u32 out[HCI_WORDS];
acpi_status status; acpi_status status;
enum led_brightness result;
/* First request : initialize communication. */ /* First request : initialize communication. */
in[0] = 0xf100; if (!sci_open(dev))
status = hci_raw(dev, in, out);
if (ACPI_FAILURE(status)) {
pr_info("Illumination device not available\n");
return LED_OFF; return LED_OFF;
}
/* Check the illumination */ /* Check the illumination */
in[0] = 0xf300; status = sci_read(dev, SCI_ILLUMINATION, &state, &result);
in[1] = 0x14e; sci_close(dev);
status = hci_raw(dev, in, out); if (ACPI_FAILURE(status) || result == SCI_INPUT_DATA_ERROR) {
if (ACPI_FAILURE(status)) { pr_err("ACPI call for illumination failed\n");
pr_info("ACPI call for illumination failed.\n"); return LED_OFF;
} else if (result == HCI_NOT_SUPPORTED) {
pr_info("Illumination not supported\n");
return LED_OFF; return LED_OFF;
} }
result = out[2] ? LED_FULL : LED_OFF; return state ? LED_FULL : LED_OFF;
/* Last request : close communication. */
in[0] = 0xf200;
in[1] = 0;
in[2] = 0;
hci_raw(dev, in, out);
return result;
} }
/* Bluetooth rfkill handlers */ /* Bluetooth rfkill handlers */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment