[ltp] [Patch 2/3] ibm-acpi: LED Subsystem integration.
linux-thinkpad@linux-thinkpad.org
linux-thinkpad@linux-thinkpad.org
Thu, 26 Oct 2006 01:54:39 +0200
This patch integrates the led and thinklight feature of ibm-acpi into the LED
subsystem.
The old proc interface is still in place for backwards compatibility, but should
considered for removal.
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
---
Index: linux/drivers/acpi/Kconfig
===================================================================
--- linux.orig/drivers/acpi/Kconfig 2006-10-26 01:00:27.000000000 +0200
+++ linux/drivers/acpi/Kconfig 2006-10-26 01:04:16.000000000 +0200
@@ -222,6 +222,17 @@
If you are not sure, say N here.
+config ACPI_IBM_LED
+ bool "IBM ThinkPad LED subsystem integration"
+ depends on ACPI_IBM
+ depends on LEDS_CLASS
+ ---help---
+ This adds support for the LED subsystem to the ibm_acpi driver. All
+ controllable LEDs and your ThinkLight will show up in the
+ /sys/class/leds directory.
+
+ If you are not sure, say Y here.
+
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86
Index: linux/drivers/acpi/ibm_acpi.c
===================================================================
--- linux.orig/drivers/acpi/ibm_acpi.c 2006-10-26 01:03:44.000000000 +0200
+++ linux/drivers/acpi/ibm_acpi.c 2006-10-26 01:05:09.000000000 +0200
@@ -19,11 +19,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define IBM_VERSION "0.12a"
+#define IBM_VERSION "0.13"
/*
* Changelog:
*
+ * 2006-10-22 0.13 LED subsystem integration.
+ * Stefan Schmidt <stefan@datenfreihafen.org>
* 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels
* 2005-03-17 0.11 support for 600e, 770x
* thanks to Jamie Lentin <lentinj@dial.pipex.com>
@@ -78,6 +80,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
+#include <linux/leds.h>
#include <asm/uaccess.h>
#include <acpi/acpi_drivers.h>
@@ -1245,6 +1248,210 @@
return 0;
}
+#ifdef CONFIG_ACPI_IBM_LED
+
+static struct led_classdev power_led, battery_amber_led, battery_green_led,
+ ultrabase_led, ultrabay_led, standby_led;
+
+/* led 0 */
+static void led_power_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_led(0, 1);
+ else
+ set_led(0, 0);
+}
+
+/* led 1 */
+static void led_battery_amber_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_led(1, 1);
+ else
+ set_led(1, 0);
+}
+
+/* led 2 */
+static void led_battery_green_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_led(2, 1);
+ else
+ set_led(2, 0);
+}
+
+/* led 3 */
+static void led_ultrabase_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_led(3, 1);
+ else
+ set_led(3, 0);
+}
+
+/* led 4 */
+static void led_ultrabay_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_led(4, 1);
+ else
+ set_led(4, 0);
+}
+
+/* led 7 */
+static void led_standby_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_led(7, 1);
+ else
+ set_led(7, 0);
+}
+
+static void led_thinklight_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ set_light(1);
+ else
+ set_light(0);
+}
+
+static struct led_classdev power_led = {
+ .name = "power:green",
+ .default_trigger = "none",
+ .brightness_set = led_power_set,
+};
+
+static struct led_classdev battery_amber_led = {
+ .name = "battery:amber",
+ .default_trigger = "none",
+ .brightness_set = led_battery_amber_set,
+};
+
+static struct led_classdev battery_green_led = {
+ .name = "battery:green",
+ .default_trigger = "none",
+ .brightness_set = led_battery_green_set,
+};
+
+static struct led_classdev ultrabase_led = {
+ .name = "ultrabase:green",
+ .default_trigger = "none",
+ .brightness_set = led_ultrabase_set,
+};
+
+static struct led_classdev ultrabay_led = {
+ .name = "ultrabay:green",
+ .default_trigger = "none",
+ .brightness_set = led_ultrabay_set,
+};
+
+static struct led_classdev standby_led = {
+ .name = "standby:green",
+ .default_trigger = "none",
+ .brightness_set = led_standby_set,
+};
+
+static struct led_classdev thinklight_led = {
+ .name = "thinklight:white",
+ .default_trigger = "none",
+ .brightness_set = led_thinklight_set,
+};
+
+static int led_probe(struct device *parent)
+{
+ int ret;
+
+ ret = led_classdev_register(parent, &power_led);
+ if (ret < 0)
+ return ret;
+
+ ret = led_classdev_register(parent, &battery_amber_led);
+ if (ret < 0)
+ led_classdev_unregister(&power_led);
+
+ ret = led_classdev_register(parent, &battery_green_led);
+ if (ret < 0) {
+ led_classdev_unregister(&power_led);
+ led_classdev_unregister(&battery_amber_led);
+ }
+
+ ret = led_classdev_register(parent, &ultrabase_led);
+ if (ret < 0) {
+ led_classdev_unregister(&power_led);
+ led_classdev_unregister(&battery_amber_led);
+ led_classdev_unregister(&battery_green_led);
+ }
+
+ ret = led_classdev_register(parent, &ultrabay_led);
+ if (ret < 0) {
+ led_classdev_unregister(&power_led);
+ led_classdev_unregister(&battery_amber_led);
+ led_classdev_unregister(&battery_green_led);
+ led_classdev_unregister(&ultrabase_led);
+ }
+
+ ret = led_classdev_register(parent, &standby_led);
+ if (ret < 0) {
+ led_classdev_unregister(&power_led);
+ led_classdev_unregister(&battery_amber_led);
+ led_classdev_unregister(&battery_green_led);
+ led_classdev_unregister(&ultrabase_led);
+ led_classdev_unregister(&ultrabay_led);
+ }
+
+ ret = led_classdev_register(parent, &thinklight_led);
+ if (ret < 0) {
+ led_classdev_unregister(&power_led);
+ led_classdev_unregister(&battery_amber_led);
+ led_classdev_unregister(&battery_green_led);
+ led_classdev_unregister(&ultrabase_led);
+ led_classdev_unregister(&ultrabay_led);
+ led_classdev_unregister(&standby_led);
+ }
+
+ return ret;
+}
+
+static int led_remove(void)
+{
+ led_classdev_unregister(&power_led);
+ led_classdev_unregister(&battery_amber_led);
+ led_classdev_unregister(&battery_green_led);
+ led_classdev_unregister(&ultrabase_led);
+ led_classdev_unregister(&ultrabay_led);
+ led_classdev_unregister(&standby_led);
+ led_classdev_unregister(&thinklight_led);
+ return 0;
+}
+
+static int __init led_driver_init(void)
+{
+ return led_probe(acpi_get_physical_device(root_handle));
+}
+
+static void __exit led_driver_exit(void)
+{
+ led_remove();
+}
+
+#else
+
+static inline int __init led_driver_init(void)
+{
+}
+
+static inline void __exit led_driver_exit(void)
+{
+}
+#endif
+
static int beep_read(char *p)
{
int len = 0;
@@ -2007,6 +2214,8 @@
for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
ibm_exit(&ibms[i]);
+ led_driver_exit();
+
remove_proc_entry(IBM_DIR, acpi_root_dir);
}
@@ -2071,6 +2280,8 @@
}
}
+ led_driver_init();
+
return 0;
}
--