aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig27
-rw-r--r--drivers/leds/Makefile4
-rw-r--r--drivers/leds/led-class.c12
-rw-r--r--drivers/leds/leds-ams-delta.c20
-rw-r--r--drivers/leds/leds-cm-x270.c124
-rw-r--r--drivers/leds/leds-da903x.c176
-rw-r--r--drivers/leds/leds-hp-disk.c155
-rw-r--r--drivers/leds/leds-hp6xx.c2
-rw-r--r--drivers/leds/leds-pca955x.c2
-rw-r--r--drivers/leds/leds-wrap.c5
-rw-r--r--drivers/leds/ledtrig-backlight.c110
-rw-r--r--drivers/leds/ledtrig-timer.c8
12 files changed, 488 insertions, 157 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index e3e40427e00..e7fb7d2fcbf 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -113,11 +113,12 @@ config LEDS_GPIO
113 outputs. To be useful the particular board must have LEDs 113 outputs. To be useful the particular board must have LEDs
114 and they must be connected to the GPIO lines. 114 and they must be connected to the GPIO lines.
115 115
116config LEDS_CM_X270 116config LEDS_HP_DISK
117 tristate "LED Support for the CM-X270 LEDs" 117 tristate "LED Support for disk protection LED on HP notebooks"
118 depends on LEDS_CLASS && MACH_ARMCORE 118 depends on LEDS_CLASS && ACPI
119 help 119 help
120 This option enables support for the CM-X270 LEDs. 120 This option enable support for disk protection LED, found on
121 newer HP notebooks.
121 122
122config LEDS_CLEVO_MAIL 123config LEDS_CLEVO_MAIL
123 tristate "Mail LED on Clevo notebook (EXPERIMENTAL)" 124 tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
@@ -157,6 +158,13 @@ config LEDS_PCA955X
157 LED driver chips accessed via the I2C bus. Supported 158 LED driver chips accessed via the I2C bus. Supported
158 devices include PCA9550, PCA9551, PCA9552, and PCA9553. 159 devices include PCA9550, PCA9551, PCA9552, and PCA9553.
159 160
161config LEDS_DA903X
162 tristate "LED Support for DA9030/DA9034 PMIC"
163 depends on LEDS_CLASS && PMIC_DA903X
164 help
165 This option enables support for on-chip LED drivers found
166 on Dialog Semiconductor DA9030/DA9034 PMICs.
167
160comment "LED Triggers" 168comment "LED Triggers"
161 169
162config LEDS_TRIGGERS 170config LEDS_TRIGGERS
@@ -179,7 +187,7 @@ config LEDS_TRIGGER_TIMER
179 187
180config LEDS_TRIGGER_IDE_DISK 188config LEDS_TRIGGER_IDE_DISK
181 bool "LED IDE Disk Trigger" 189 bool "LED IDE Disk Trigger"
182 depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK 190 depends on LEDS_TRIGGERS && IDE_GD_ATA
183 help 191 help
184 This allows LEDs to be controlled by IDE disk activity. 192 This allows LEDs to be controlled by IDE disk activity.
185 If unsure, say Y. 193 If unsure, say Y.
@@ -193,6 +201,15 @@ config LEDS_TRIGGER_HEARTBEAT
193 load average. 201 load average.
194 If unsure, say Y. 202 If unsure, say Y.
195 203
204config LEDS_TRIGGER_BACKLIGHT
205 tristate "LED backlight Trigger"
206 depends on LEDS_TRIGGERS
207 help
208 This allows LEDs to be controlled as a backlight device: they
209 turn off and on when the display is blanked and unblanked.
210
211 If unsure, say N.
212
196config LEDS_TRIGGER_DEFAULT_ON 213config LEDS_TRIGGER_DEFAULT_ON
197 tristate "LED Default ON Trigger" 214 tristate "LED Default ON Trigger"
198 depends on LEDS_TRIGGERS 215 depends on LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index eb186c351a1..e1967a29850 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -17,14 +17,16 @@ obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
17obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o 17obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
18obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o 18obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o
19obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o 19obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
20obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
21obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 20obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
22obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o 21obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
23obj-$(CONFIG_LEDS_FSG) += leds-fsg.o 22obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
24obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o 23obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
24obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
25obj-$(CONFIG_LEDS_HP_DISK) += leds-hp-disk.o
25 26
26# LED Triggers 27# LED Triggers
27obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 28obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
28obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o 29obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
29obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o 30obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
31obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
30obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o 32obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index ee74ee7b2ac..6c4a326176d 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -34,14 +34,11 @@ static ssize_t led_brightness_show(struct device *dev,
34 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
35{ 35{
36 struct led_classdev *led_cdev = dev_get_drvdata(dev); 36 struct led_classdev *led_cdev = dev_get_drvdata(dev);
37 ssize_t ret = 0;
38 37
39 /* no lock needed for this */ 38 /* no lock needed for this */
40 led_update_brightness(led_cdev); 39 led_update_brightness(led_cdev);
41 sprintf(buf, "%u\n", led_cdev->brightness);
42 ret = strlen(buf) + 1;
43 40
44 return ret; 41 return sprintf(buf, "%u\n", led_cdev->brightness);
45} 42}
46 43
47static ssize_t led_brightness_store(struct device *dev, 44static ssize_t led_brightness_store(struct device *dev,
@@ -113,6 +110,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
113 if (rc) 110 if (rc)
114 goto err_out; 111 goto err_out;
115 112
113#ifdef CONFIG_LEDS_TRIGGERS
114 init_rwsem(&led_cdev->trigger_lock);
115#endif
116 /* add to the list of leds */ 116 /* add to the list of leds */
117 down_write(&leds_list_lock); 117 down_write(&leds_list_lock);
118 list_add_tail(&led_cdev->node, &leds_list); 118 list_add_tail(&led_cdev->node, &leds_list);
@@ -121,8 +121,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
121 led_update_brightness(led_cdev); 121 led_update_brightness(led_cdev);
122 122
123#ifdef CONFIG_LEDS_TRIGGERS 123#ifdef CONFIG_LEDS_TRIGGERS
124 init_rwsem(&led_cdev->trigger_lock);
125
126 rc = device_create_file(led_cdev->dev, &dev_attr_trigger); 124 rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
127 if (rc) 125 if (rc)
128 goto err_out_led_list; 126 goto err_out_led_list;
@@ -147,7 +145,7 @@ err_out:
147EXPORT_SYMBOL_GPL(led_classdev_register); 145EXPORT_SYMBOL_GPL(led_classdev_register);
148 146
149/** 147/**
150 * __led_classdev_unregister - unregisters a object of led_properties class. 148 * led_classdev_unregister - unregisters a object of led_properties class.
151 * @led_cdev: the led device to unregister 149 * @led_cdev: the led device to unregister
152 * 150 *
153 * Unregisters a previously registered via led_classdev_register object. 151 * Unregisters a previously registered via led_classdev_register object.
diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c
index 32c98b2efa3..1bd590bb3a6 100644
--- a/drivers/leds/leds-ams-delta.c
+++ b/drivers/leds/leds-ams-delta.c
@@ -107,27 +107,27 @@ static int ams_delta_led_resume(struct platform_device *dev)
107 107
108static int ams_delta_led_probe(struct platform_device *pdev) 108static int ams_delta_led_probe(struct platform_device *pdev)
109{ 109{
110 int i; 110 int i, ret;
111 int ret;
112 111
113 for (i = ret = 0; ret >= 0 && i < ARRAY_SIZE(ams_delta_leds); i++) { 112 for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) {
114 ret = led_classdev_register(&pdev->dev, 113 ret = led_classdev_register(&pdev->dev,
115 &ams_delta_leds[i].cdev); 114 &ams_delta_leds[i].cdev);
115 if (ret < 0)
116 goto fail;
116 } 117 }
117 118
118 if (ret < 0 && i > 1) { 119 return 0;
119 for (i = i - 2; i >= 0; i--) 120fail:
120 led_classdev_unregister(&ams_delta_leds[i].cdev); 121 while (--i >= 0)
121 } 122 led_classdev_unregister(&ams_delta_leds[i].cdev);
122 123 return ret;
123 return ret;
124} 124}
125 125
126static int ams_delta_led_remove(struct platform_device *pdev) 126static int ams_delta_led_remove(struct platform_device *pdev)
127{ 127{
128 int i; 128 int i;
129 129
130 for (i = ARRAY_SIZE(ams_delta_leds) - 1; i >= 0; i--) 130 for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i--)
131 led_classdev_unregister(&ams_delta_leds[i].cdev); 131 led_classdev_unregister(&ams_delta_leds[i].cdev);
132 132
133 return 0; 133 return 0;
diff --git a/drivers/leds/leds-cm-x270.c b/drivers/leds/leds-cm-x270.c
deleted file mode 100644
index 836a43d776e..00000000000
--- a/drivers/leds/leds-cm-x270.c
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * drivers/leds/leds-cm-x270.c
3 *
4 * Copyright 2007 CompuLab Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on leds-corgi.c
8 * Author: Richard Purdie <rpurdie@openedhand.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/leds.h>
20
21#include <mach/hardware.h>
22#include <mach/pxa-regs.h>
23
24#define GPIO_RED_LED (93)
25#define GPIO_GREEN_LED (94)
26
27static void cmx270_red_set(struct led_classdev *led_cdev,
28 enum led_brightness value)
29{
30 if (value)
31 GPCR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED);
32 else
33 GPSR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED);
34}
35
36static void cmx270_green_set(struct led_classdev *led_cdev,
37 enum led_brightness value)
38{
39 if (value)
40 GPCR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED);
41 else
42 GPSR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED);
43}
44
45static struct led_classdev cmx270_red_led = {
46 .name = "cm-x270:red",
47 .default_trigger = "nand-disk",
48 .brightness_set = cmx270_red_set,
49};
50
51static struct led_classdev cmx270_green_led = {
52 .name = "cm-x270:green",
53 .default_trigger = "heartbeat",
54 .brightness_set = cmx270_green_set,
55};
56
57#ifdef CONFIG_PM
58static int cmx270led_suspend(struct platform_device *dev, pm_message_t state)
59{
60 led_classdev_suspend(&cmx270_red_led);
61 led_classdev_suspend(&cmx270_green_led);
62 return 0;
63}
64
65static int cmx270led_resume(struct platform_device *dev)
66{
67 led_classdev_resume(&cmx270_red_led);
68 led_classdev_resume(&cmx270_green_led);
69 return 0;
70}
71#endif
72
73static int cmx270led_probe(struct platform_device *pdev)
74{
75 int ret;
76
77 ret = led_classdev_register(&pdev->dev, &cmx270_red_led);
78 if (ret < 0)
79 return ret;
80
81 ret = led_classdev_register(&pdev->dev, &cmx270_green_led);
82 if (ret < 0)
83 led_classdev_unregister(&cmx270_red_led);
84
85 return ret;
86}
87
88static int cmx270led_remove(struct platform_device *pdev)
89{
90 led_classdev_unregister(&cmx270_red_led);
91 led_classdev_unregister(&cmx270_green_led);
92 return 0;
93}
94
95static struct platform_driver cmx270led_driver = {
96 .probe = cmx270led_probe,
97 .remove = cmx270led_remove,
98#ifdef CONFIG_PM
99 .suspend = cmx270led_suspend,
100 .resume = cmx270led_resume,
101#endif
102 .driver = {
103 .name = "cm-x270-led",
104 .owner = THIS_MODULE,
105 },
106};
107
108static int __init cmx270led_init(void)
109{
110 return platform_driver_register(&cmx270led_driver);
111}
112
113static void __exit cmx270led_exit(void)
114{
115 platform_driver_unregister(&cmx270led_driver);
116}
117
118module_init(cmx270led_init);
119module_exit(cmx270led_exit);
120
121MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
122MODULE_DESCRIPTION("CM-x270 LED driver");
123MODULE_LICENSE("GPL");
124MODULE_ALIAS("platform:cm-x270-led");
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
new file mode 100644
index 00000000000..1f3cc512eff
--- /dev/null
+++ b/drivers/leds/leds-da903x.c
@@ -0,0 +1,176 @@
1/*
2 * LEDs driver for Dialog Semiconductor DA9030/DA9034
3 *
4 * Copyright (C) 2008 Compulab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il>
6 *
7 * Copyright (C) 2006-2008 Marvell International Ltd.
8 * Eric Miao <eric.miao@marvell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/leds.h>
20#include <linux/workqueue.h>
21#include <linux/mfd/da903x.h>
22
23#define DA9030_LED1_CONTROL 0x20
24#define DA9030_LED2_CONTROL 0x21
25#define DA9030_LED3_CONTROL 0x22
26#define DA9030_LED4_CONTROL 0x23
27#define DA9030_LEDPC_CONTROL 0x24
28#define DA9030_MISC_CONTROL_A 0x26 /* Vibrator Control */
29
30#define DA9034_LED1_CONTROL 0x35
31#define DA9034_LED2_CONTROL 0x36
32#define DA9034_VIBRA 0x40
33
34struct da903x_led {
35 struct led_classdev cdev;
36 struct work_struct work;
37 struct device *master;
38 enum led_brightness new_brightness;
39 int id;
40 int flags;
41};
42
43#define DA9030_LED_OFFSET(id) ((id) - DA9030_ID_LED_1)
44#define DA9034_LED_OFFSET(id) ((id) - DA9034_ID_LED_1)
45
46static void da903x_led_work(struct work_struct *work)
47{
48 struct da903x_led *led = container_of(work, struct da903x_led, work);
49 uint8_t val;
50 int offset;
51
52 switch (led->id) {
53 case DA9030_ID_LED_1:
54 case DA9030_ID_LED_2:
55 case DA9030_ID_LED_3:
56 case DA9030_ID_LED_4:
57 case DA9030_ID_LED_PC:
58 offset = DA9030_LED_OFFSET(led->id);
59 val = led->flags & ~0x87;
60 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
61 val |= (0x7 - (led->new_brightness >> 5)) & 0x7; /* PWM<2:0> */
62 da903x_write(led->master, DA9030_LED1_CONTROL + offset, val);
63 break;
64 case DA9030_ID_VIBRA:
65 val = led->flags & ~0x80;
66 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
67 da903x_write(led->master, DA9030_MISC_CONTROL_A, val);
68 break;
69 case DA9034_ID_LED_1:
70 case DA9034_ID_LED_2:
71 offset = DA9034_LED_OFFSET(led->id);
72 val = (led->new_brightness * 0x5f / LED_FULL) & 0x7f;
73 val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0;
74 da903x_write(led->master, DA9034_LED1_CONTROL + offset, val);
75 break;
76 case DA9034_ID_VIBRA:
77 val = led->new_brightness & 0xfe;
78 da903x_write(led->master, DA9034_VIBRA, val);
79 break;
80 }
81}
82
83static void da903x_led_set(struct led_classdev *led_cdev,
84 enum led_brightness value)
85{
86 struct da903x_led *led;
87
88 led = container_of(led_cdev, struct da903x_led, cdev);
89 led->new_brightness = value;
90 schedule_work(&led->work);
91}
92
93static int __devinit da903x_led_probe(struct platform_device *pdev)
94{
95 struct led_info *pdata = pdev->dev.platform_data;
96 struct da903x_led *led;
97 int id, ret;
98
99 if (pdata == NULL)
100 return 0;
101
102 id = pdev->id;
103
104 if (!((id >= DA9030_ID_LED_1 && id <= DA9030_ID_VIBRA) ||
105 (id >= DA9034_ID_LED_1 && id <= DA9034_ID_VIBRA))) {
106 dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", id);
107 return -EINVAL;
108 }
109
110 led = kzalloc(sizeof(struct da903x_led), GFP_KERNEL);
111 if (led == NULL) {
112 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
113 return -ENOMEM;
114 }
115
116 led->cdev.name = pdata->name;
117 led->cdev.default_trigger = pdata->default_trigger;
118 led->cdev.brightness_set = da903x_led_set;
119 led->cdev.brightness = LED_OFF;
120
121 led->id = id;
122 led->flags = pdata->flags;
123 led->master = pdev->dev.parent;
124 led->new_brightness = LED_OFF;
125
126 INIT_WORK(&led->work, da903x_led_work);
127
128 ret = led_classdev_register(led->master, &led->cdev);
129 if (ret) {
130 dev_err(&pdev->dev, "failed to register LED %d\n", id);
131 goto err;
132 }
133
134 platform_set_drvdata(pdev, led);
135 return 0;
136
137err:
138 kfree(led);
139 return ret;
140}
141
142static int __devexit da903x_led_remove(struct platform_device *pdev)
143{
144 struct da903x_led *led = platform_get_drvdata(pdev);
145
146 led_classdev_unregister(&led->cdev);
147 kfree(led);
148 return 0;
149}
150
151static struct platform_driver da903x_led_driver = {
152 .driver = {
153 .name = "da903x-led",
154 .owner = THIS_MODULE,
155 },
156 .probe = da903x_led_probe,
157 .remove = __devexit_p(da903x_led_remove),
158};
159
160static int __init da903x_led_init(void)
161{
162 return platform_driver_register(&da903x_led_driver);
163}
164module_init(da903x_led_init);
165
166static void __exit da903x_led_exit(void)
167{
168 platform_driver_unregister(&da903x_led_driver);
169}
170module_exit(da903x_led_exit);
171
172MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
173MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
174 "Mike Rapoport <mike@compulab.co.il>");
175MODULE_LICENSE("GPL");
176MODULE_ALIAS("platform:da903x-led");
diff --git a/drivers/leds/leds-hp-disk.c b/drivers/leds/leds-hp-disk.c
new file mode 100644
index 00000000000..44fa757d825
--- /dev/null
+++ b/drivers/leds/leds-hp-disk.c
@@ -0,0 +1,155 @@
1/*
2 * leds-hp-disk.c - driver for HP "hard disk protection" LED
3 *
4 * Copyright (C) 2008 Pavel Machek
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/dmi.h>
24#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/platform_device.h>
27#include <linux/interrupt.h>
28#include <linux/input.h>
29#include <linux/kthread.h>
30#include <linux/leds.h>
31#include <acpi/acpi_drivers.h>
32
33#define DRIVER_NAME "leds-hp-disk"
34#define ACPI_MDPS_CLASS "led"
35
36/* For automatic insertion of the module */
37static struct acpi_device_id hpled_device_ids[] = {
38 {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
39 {"", 0},
40};
41MODULE_DEVICE_TABLE(acpi, hpled_device_ids);
42
43struct acpi_hpled {
44 struct acpi_device *device; /* The ACPI device */
45};
46
47static struct acpi_hpled adev;
48
49static acpi_status hpled_acpi_write(acpi_handle handle, int reg)
50{
51 unsigned long long ret; /* Not used when writing */
52 union acpi_object in_obj[1];
53 struct acpi_object_list args = { 1, in_obj };
54
55 in_obj[0].type = ACPI_TYPE_INTEGER;
56 in_obj[0].integer.value = reg;
57
58 return acpi_evaluate_integer(handle, "ALED", &args, &ret);
59}
60
61static void hpled_set(struct led_classdev *led_cdev,
62 enum led_brightness value)
63{
64 hpled_acpi_write(adev.device->handle, !!value);
65}
66
67static struct led_classdev hpled_led = {
68 .name = "hp:red:hddprotection",
69 .default_trigger = "heartbeat",
70 .brightness_set = hpled_set,
71};
72
73#ifdef CONFIG_PM
74static int hpled_suspend(struct acpi_device *dev, pm_message_t state)
75{
76 led_classdev_suspend(&hpled_led);
77 return 0;
78}
79
80static int hpled_resume(struct acpi_device *dev)
81{
82 led_classdev_resume(&hpled_led);
83 return 0;
84}
85#else
86#define hpled_suspend NULL
87#define hpled_resume NULL
88#endif
89
90static int hpled_add(struct acpi_device *device)
91{
92 int ret;
93
94 if (!device)
95 return -EINVAL;
96
97 adev.device = device;
98 strcpy(acpi_device_name(device), DRIVER_NAME);
99 strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
100 device->driver_data = &adev;
101
102 ret = led_classdev_register(NULL, &hpled_led);
103 return ret;
104}
105
106static int hpled_remove(struct acpi_device *device, int type)
107{
108 if (!device)
109 return -EINVAL;
110
111 led_classdev_unregister(&hpled_led);
112 return 0;
113}
114
115
116
117static struct acpi_driver leds_hp_driver = {
118 .name = DRIVER_NAME,
119 .class = ACPI_MDPS_CLASS,
120 .ids = hpled_device_ids,
121 .ops = {
122 .add = hpled_add,
123 .remove = hpled_remove,
124 .suspend = hpled_suspend,
125 .resume = hpled_resume,
126 }
127};
128
129static int __init hpled_init_module(void)
130{
131 int ret;
132
133 if (acpi_disabled)
134 return -ENODEV;
135
136 ret = acpi_bus_register_driver(&leds_hp_driver);
137 if (ret < 0)
138 return ret;
139
140 printk(KERN_INFO DRIVER_NAME " driver loaded.\n");
141
142 return 0;
143}
144
145static void __exit hpled_exit_module(void)
146{
147 acpi_bus_unregister_driver(&leds_hp_driver);
148}
149
150MODULE_DESCRIPTION("Driver for HP disk protection LED");
151MODULE_AUTHOR("Pavel Machek <pavel@suse.cz>");
152MODULE_LICENSE("GPL");
153
154module_init(hpled_init_module);
155module_exit(hpled_exit_module);
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c
index 844d5979c90..e8fb1baf8a5 100644
--- a/drivers/leds/leds-hp6xx.c
+++ b/drivers/leds/leds-hp6xx.c
@@ -15,7 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/leds.h> 16#include <linux/leds.h>
17#include <asm/hd64461.h> 17#include <asm/hd64461.h>
18#include <asm/hp6xx.h> 18#include <mach/hp6xx.h>
19 19
20static void hp6xxled_green_set(struct led_classdev *led_cdev, 20static void hp6xxled_green_set(struct led_classdev *led_cdev,
21 enum led_brightness value) 21 enum led_brightness value)
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index f508729123b..4e2d1a42b48 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -226,7 +226,7 @@ static void pca955x_led_work(struct work_struct *work)
226 pca955x_write_ls(pca955x->client, chip_ls, ls); 226 pca955x_write_ls(pca955x->client, chip_ls, ls);
227} 227}
228 228
229void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value) 229static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value)
230{ 230{
231 struct pca955x_led *pca955x; 231 struct pca955x_led *pca955x;
232 232
diff --git a/drivers/leds/leds-wrap.c b/drivers/leds/leds-wrap.c
index 7ac61a7b56a..2f3aa87f2a1 100644
--- a/drivers/leds/leds-wrap.c
+++ b/drivers/leds/leds-wrap.c
@@ -53,8 +53,9 @@ static void wrap_extra_led_set(struct led_classdev *led_cdev,
53} 53}
54 54
55static struct led_classdev wrap_power_led = { 55static struct led_classdev wrap_power_led = {
56 .name = "wrap::power", 56 .name = "wrap::power",
57 .brightness_set = wrap_power_led_set, 57 .brightness_set = wrap_power_led_set,
58 .default_trigger = "default-on",
58}; 59};
59 60
60static struct led_classdev wrap_error_led = { 61static struct led_classdev wrap_error_led = {
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c
new file mode 100644
index 00000000000..d3dfcfb417b
--- /dev/null
+++ b/drivers/leds/ledtrig-backlight.c
@@ -0,0 +1,110 @@
1/*
2 * Backlight emulation LED trigger
3 *
4 * Copyright 2008 (C) Rodolfo Giometti <giometti@linux.it>
5 * Copyright 2008 (C) Eurotech S.p.A. <info@eurotech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/fb.h>
17#include <linux/leds.h>
18#include "leds.h"
19
20#define BLANK 1
21#define UNBLANK 0
22
23struct bl_trig_notifier {
24 struct led_classdev *led;
25 int brightness;
26 int old_status;
27 struct notifier_block notifier;
28};
29
30static int fb_notifier_callback(struct notifier_block *p,
31 unsigned long event, void *data)
32{
33 struct bl_trig_notifier *n = container_of(p,
34 struct bl_trig_notifier, notifier);
35 struct led_classdev *led = n->led;
36 struct fb_event *fb_event = data;
37 int *blank = fb_event->data;
38
39 switch (event) {
40 case FB_EVENT_BLANK :
41 if (*blank && n->old_status == UNBLANK) {
42 n->brightness = led->brightness;
43 led_set_brightness(led, LED_OFF);
44 n->old_status = BLANK;
45 } else if (!*blank && n->old_status == BLANK) {
46 led_set_brightness(led, n->brightness);
47 n->old_status = UNBLANK;
48 }
49 break;
50 }
51
52 return 0;
53}
54
55static void bl_trig_activate(struct led_classdev *led)
56{
57 int ret;
58
59 struct bl_trig_notifier *n;
60
61 n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL);
62 led->trigger_data = n;
63 if (!n) {
64 dev_err(led->dev, "unable to allocate backlight trigger\n");
65 return;
66 }
67
68 n->led = led;
69 n->brightness = led->brightness;
70 n->old_status = UNBLANK;
71 n->notifier.notifier_call = fb_notifier_callback;
72
73 ret = fb_register_client(&n->notifier);
74 if (ret)
75 dev_err(led->dev, "unable to register backlight trigger\n");
76}
77
78static void bl_trig_deactivate(struct led_classdev *led)
79{
80 struct bl_trig_notifier *n =
81 (struct bl_trig_notifier *) led->trigger_data;
82
83 if (n) {
84 fb_unregister_client(&n->notifier);
85 kfree(n);
86 }
87}
88
89static struct led_trigger bl_led_trigger = {
90 .name = "backlight",
91 .activate = bl_trig_activate,
92 .deactivate = bl_trig_deactivate
93};
94
95static int __init bl_trig_init(void)
96{
97 return led_trigger_register(&bl_led_trigger);
98}
99
100static void __exit bl_trig_exit(void)
101{
102 led_trigger_unregister(&bl_led_trigger);
103}
104
105module_init(bl_trig_init);
106module_exit(bl_trig_exit);
107
108MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
109MODULE_DESCRIPTION("Backlight emulation LED trigger");
110MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 5c99f4f0c69..db681962d7b 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -70,9 +70,7 @@ static ssize_t led_delay_on_show(struct device *dev,
70 struct led_classdev *led_cdev = dev_get_drvdata(dev); 70 struct led_classdev *led_cdev = dev_get_drvdata(dev);
71 struct timer_trig_data *timer_data = led_cdev->trigger_data; 71 struct timer_trig_data *timer_data = led_cdev->trigger_data;
72 72
73 sprintf(buf, "%lu\n", timer_data->delay_on); 73 return sprintf(buf, "%lu\n", timer_data->delay_on);
74
75 return strlen(buf) + 1;
76} 74}
77 75
78static ssize_t led_delay_on_store(struct device *dev, 76static ssize_t led_delay_on_store(struct device *dev,
@@ -116,9 +114,7 @@ static ssize_t led_delay_off_show(struct device *dev,
116 struct led_classdev *led_cdev = dev_get_drvdata(dev); 114 struct led_classdev *led_cdev = dev_get_drvdata(dev);
117 struct timer_trig_data *timer_data = led_cdev->trigger_data; 115 struct timer_trig_data *timer_data = led_cdev->trigger_data;
118 116
119 sprintf(buf, "%lu\n", timer_data->delay_off); 117 return sprintf(buf, "%lu\n", timer_data->delay_off);
120
121 return strlen(buf) + 1;
122} 118}
123 119
124static ssize_t led_delay_off_store(struct device *dev, 120static ssize_t led_delay_off_store(struct device *dev,