diff options
author | Azael Avalos <coproscefalo@gmail.com> | 2014-03-25 22:38:33 -0400 |
---|---|---|
committer | Matthew Garrett <matthew.garrett@nebula.com> | 2014-04-06 12:58:14 -0400 |
commit | def6c4e25d31b874b939bd08e7941eaa9711653f (patch) | |
tree | 55dad04e42107752c13681197e6137aabff1f2c3 /drivers/platform | |
parent | 9d8658acd6be9139ef91dfe6c001796e7a03ded6 (diff) |
toshiba_acpi: Add ECO mode led support
Newer Toshiba laptops now come with a feature called
ECO Mode, where the system is put in low power consupmtion
state and a green (world shaped with leaves) icon illuminates
indicating that the system is in such power state.
This patch adds support to turn on/off the ECO led by
creating and registering the toshiba::eco_mode led.
Signed-off-by: Azael Avalos <coproscefalo@gmail.com>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 08c53768447b..c8e8bfb78c19 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -112,6 +112,7 @@ MODULE_LICENSE("GPL"); | |||
112 | #define HCI_LCD_BRIGHTNESS 0x002a | 112 | #define HCI_LCD_BRIGHTNESS 0x002a |
113 | #define HCI_WIRELESS 0x0056 | 113 | #define HCI_WIRELESS 0x0056 |
114 | #define HCI_KBD_ILLUMINATION 0x0095 | 114 | #define HCI_KBD_ILLUMINATION 0x0095 |
115 | #define HCI_ECO_MODE 0x0097 | ||
115 | #define SCI_ILLUMINATION 0x014e | 116 | #define SCI_ILLUMINATION 0x014e |
116 | #define SCI_KBD_ILLUM_STATUS 0x015c | 117 | #define SCI_KBD_ILLUM_STATUS 0x015c |
117 | #define SCI_TOUCHPAD 0x050e | 118 | #define SCI_TOUCHPAD 0x050e |
@@ -142,6 +143,7 @@ struct toshiba_acpi_dev { | |||
142 | struct backlight_device *backlight_dev; | 143 | struct backlight_device *backlight_dev; |
143 | struct led_classdev led_dev; | 144 | struct led_classdev led_dev; |
144 | struct led_classdev kbd_led; | 145 | struct led_classdev kbd_led; |
146 | struct led_classdev eco_led; | ||
145 | 147 | ||
146 | int force_fan; | 148 | int force_fan; |
147 | int last_key_event; | 149 | int last_key_event; |
@@ -159,6 +161,7 @@ struct toshiba_acpi_dev { | |||
159 | unsigned int kbd_illum_supported:1; | 161 | unsigned int kbd_illum_supported:1; |
160 | unsigned int kbd_led_registered:1; | 162 | unsigned int kbd_led_registered:1; |
161 | unsigned int touchpad_supported:1; | 163 | unsigned int touchpad_supported:1; |
164 | unsigned int eco_supported:1; | ||
162 | unsigned int sysfs_created:1; | 165 | unsigned int sysfs_created:1; |
163 | 166 | ||
164 | struct mutex mutex; | 167 | struct mutex mutex; |
@@ -571,6 +574,57 @@ static int toshiba_touchpad_get(struct toshiba_acpi_dev *dev, u32 *state) | |||
571 | return 0; | 574 | return 0; |
572 | } | 575 | } |
573 | 576 | ||
577 | /* Eco Mode support */ | ||
578 | static int toshiba_eco_mode_available(struct toshiba_acpi_dev *dev) | ||
579 | { | ||
580 | acpi_status status; | ||
581 | u32 in[HCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 }; | ||
582 | u32 out[HCI_WORDS]; | ||
583 | |||
584 | status = hci_raw(dev, in, out); | ||
585 | if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) { | ||
586 | pr_info("ACPI call to get ECO led failed\n"); | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | return 1; | ||
591 | } | ||
592 | |||
593 | static enum led_brightness toshiba_eco_mode_get_status(struct led_classdev *cdev) | ||
594 | { | ||
595 | struct toshiba_acpi_dev *dev = container_of(cdev, | ||
596 | struct toshiba_acpi_dev, eco_led); | ||
597 | u32 in[HCI_WORDS] = { HCI_GET, HCI_ECO_MODE, 0, 1, 0, 0 }; | ||
598 | u32 out[HCI_WORDS]; | ||
599 | acpi_status status; | ||
600 | |||
601 | status = hci_raw(dev, in, out); | ||
602 | if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) { | ||
603 | pr_err("ACPI call to get ECO led failed\n"); | ||
604 | return LED_OFF; | ||
605 | } | ||
606 | |||
607 | return out[2] ? LED_FULL : LED_OFF; | ||
608 | } | ||
609 | |||
610 | static void toshiba_eco_mode_set_status(struct led_classdev *cdev, | ||
611 | enum led_brightness brightness) | ||
612 | { | ||
613 | struct toshiba_acpi_dev *dev = container_of(cdev, | ||
614 | struct toshiba_acpi_dev, eco_led); | ||
615 | u32 in[HCI_WORDS] = { HCI_SET, HCI_ECO_MODE, 0, 1, 0, 0 }; | ||
616 | u32 out[HCI_WORDS]; | ||
617 | acpi_status status; | ||
618 | |||
619 | /* Switch the Eco Mode led on/off */ | ||
620 | in[2] = (brightness) ? 1 : 0; | ||
621 | status = hci_raw(dev, in, out); | ||
622 | if (ACPI_FAILURE(status) || out[0] == SCI_INPUT_DATA_ERROR) { | ||
623 | pr_err("ACPI call to set ECO led failed\n"); | ||
624 | return; | ||
625 | } | ||
626 | } | ||
627 | |||
574 | /* Bluetooth rfkill handlers */ | 628 | /* Bluetooth rfkill handlers */ |
575 | 629 | ||
576 | static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) | 630 | static u32 hci_get_bt_present(struct toshiba_acpi_dev *dev, bool *present) |
@@ -1469,6 +1523,9 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev) | |||
1469 | 1523 | ||
1470 | if (dev->kbd_led_registered) | 1524 | if (dev->kbd_led_registered) |
1471 | led_classdev_unregister(&dev->kbd_led); | 1525 | led_classdev_unregister(&dev->kbd_led); |
1526 | |||
1527 | if (dev->eco_supported) | ||
1528 | led_classdev_unregister(&dev->eco_led); | ||
1472 | 1529 | ||
1473 | if (toshiba_acpi) | 1530 | if (toshiba_acpi) |
1474 | toshiba_acpi = NULL; | 1531 | toshiba_acpi = NULL; |
@@ -1556,6 +1613,15 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
1556 | dev->illumination_supported = 1; | 1613 | dev->illumination_supported = 1; |
1557 | } | 1614 | } |
1558 | 1615 | ||
1616 | if (toshiba_eco_mode_available(dev)) { | ||
1617 | dev->eco_led.name = "toshiba::eco_mode"; | ||
1618 | dev->eco_led.max_brightness = 1; | ||
1619 | dev->eco_led.brightness_set = toshiba_eco_mode_set_status; | ||
1620 | dev->eco_led.brightness_get = toshiba_eco_mode_get_status; | ||
1621 | if (!led_classdev_register(&dev->acpi_dev->dev, &dev->eco_led)) | ||
1622 | dev->eco_supported = 1; | ||
1623 | } | ||
1624 | |||
1559 | ret = toshiba_kbd_illum_status_get(dev, &dummy); | 1625 | ret = toshiba_kbd_illum_status_get(dev, &dummy); |
1560 | if (!ret) { | 1626 | if (!ret) { |
1561 | dev->kbd_time = dummy >> HCI_MISC_SHIFT; | 1627 | dev->kbd_time = dummy >> HCI_MISC_SHIFT; |