aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 19:07:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-23 19:07:32 -0400
commitea541686d8454efac4f2b5c0767affb12d4b6a52 (patch)
treeef0812fcc3e07c067042add6388146b3485c793e
parent0d876c6a96e2cabf8632e8066b617d9c2dec9518 (diff)
parent601a1b92ed3ce0025f7bec6fc591cceaef8d9d69 (diff)
Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds: leds/acpi: Fix merge fallout from acpi_driver_data change leds: Simplify logic in leds-ams-delta leds: Fix trigger registration race leds: Fix leds-class.c comment leds: Add driver for HP harddisk protection LEDs leds: leds-pca955x - Mark pca955x_led_set() static leds: Remove uneeded leds-cm-x270 driver leds: Remove uneeded strlen calls leds: Add leds-wrap default-trigger leds: Make default trigger fields const leds: Add backlight LED trigger leds: da903x: Add support for LEDs found on DA9030/DA9034
-rw-r--r--drivers/leds/Kconfig25
-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.c175
-rw-r--r--drivers/leds/leds-hp-disk.c156
-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
-rw-r--r--include/linux/leds.h4
12 files changed, 488 insertions, 157 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index c7ff1e11ea85..e7fb7d2fcbfc 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
@@ -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 eb186c351a1c..e1967a29850e 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 ee74ee7b2acc..6c4a326176d7 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 32c98b2efa3f..1bd590bb3a6e 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 836a43d776e6..000000000000
--- 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 000000000000..f1fddb18d70d
--- /dev/null
+++ b/drivers/leds/leds-da903x.c
@@ -0,0 +1,175 @@
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/mfd/da903x.h>
21
22#define DA9030_LED1_CONTROL 0x20
23#define DA9030_LED2_CONTROL 0x21
24#define DA9030_LED3_CONTROL 0x22
25#define DA9030_LED4_CONTROL 0x23
26#define DA9030_LEDPC_CONTROL 0x24
27#define DA9030_MISC_CONTROL_A 0x26 /* Vibrator Control */
28
29#define DA9034_LED1_CONTROL 0x35
30#define DA9034_LED2_CONTROL 0x36
31#define DA9034_VIBRA 0x40
32
33struct da903x_led {
34 struct led_classdev cdev;
35 struct work_struct work;
36 struct device *master;
37 enum led_brightness new_brightness;
38 int id;
39 int flags;
40};
41
42#define DA9030_LED_OFFSET(id) ((id) - DA9030_ID_LED_1)
43#define DA9034_LED_OFFSET(id) ((id) - DA9034_ID_LED_1)
44
45static void da903x_led_work(struct work_struct *work)
46{
47 struct da903x_led *led = container_of(work, struct da903x_led, work);
48 uint8_t val;
49 int offset;
50
51 switch (led->id) {
52 case DA9030_ID_LED_1:
53 case DA9030_ID_LED_2:
54 case DA9030_ID_LED_3:
55 case DA9030_ID_LED_4:
56 case DA9030_ID_LED_PC:
57 offset = DA9030_LED_OFFSET(led->id);
58 val = led->flags & ~0x87;
59 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
60 val |= (led->new_brightness >> 5) & 0x7; /* PWM<2:0> */
61 da903x_write(led->master, DA9030_LED1_CONTROL + offset, val);
62 break;
63 case DA9030_ID_VIBRA:
64 val = led->flags & ~0x80;
65 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
66 da903x_write(led->master, DA9030_MISC_CONTROL_A, val);
67 break;
68 case DA9034_ID_LED_1:
69 case DA9034_ID_LED_2:
70 offset = DA9034_LED_OFFSET(led->id);
71 val = (led->new_brightness * 0x5f / LED_FULL) & 0x7f;
72 val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0;
73 da903x_write(led->master, DA9034_LED1_CONTROL + offset, val);
74 break;
75 case DA9034_ID_VIBRA:
76 val = led->new_brightness & 0xfe;
77 da903x_write(led->master, DA9034_VIBRA, val);
78 break;
79 }
80}
81
82static void da903x_led_set(struct led_classdev *led_cdev,
83 enum led_brightness value)
84{
85 struct da903x_led *led;
86
87 led = container_of(led_cdev, struct da903x_led, cdev);
88 led->new_brightness = value;
89 schedule_work(&led->work);
90}
91
92static int __devinit da903x_led_probe(struct platform_device *pdev)
93{
94 struct led_info *pdata = pdev->dev.platform_data;
95 struct da903x_led *led;
96 int id, ret;
97
98 if (pdata == NULL)
99 return 0;
100
101 id = pdev->id;
102
103 if (!((id >= DA9030_ID_LED_1 && id <= DA9030_ID_VIBRA) ||
104 (id >= DA9034_ID_LED_1 && id <= DA9034_ID_VIBRA))) {
105 dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", id);
106 return -EINVAL;
107 }
108
109 led = kzalloc(sizeof(struct da903x_led), GFP_KERNEL);
110 if (led == NULL) {
111 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
112 return -ENOMEM;
113 }
114
115 led->cdev.name = pdata->name;
116 led->cdev.default_trigger = pdata->default_trigger;
117 led->cdev.brightness_set = da903x_led_set;
118 led->cdev.brightness = LED_OFF;
119
120 led->id = id;
121 led->flags = pdata->flags;
122 led->master = pdev->dev.parent;
123 led->new_brightness = LED_OFF;
124
125 INIT_WORK(&led->work, da903x_led_work);
126
127 ret = led_classdev_register(led->master, &led->cdev);
128 if (ret) {
129 dev_err(&pdev->dev, "failed to register LED %d\n", id);
130 goto err;
131 }
132
133 platform_set_drvdata(pdev, led);
134 return 0;
135
136err:
137 kfree(led);
138 return ret;
139}
140
141static int __devexit da903x_led_remove(struct platform_device *pdev)
142{
143 struct da903x_led *led = platform_get_drvdata(pdev);
144
145 led_classdev_unregister(&led->cdev);
146 kfree(led);
147 return 0;
148}
149
150static struct platform_driver da903x_led_driver = {
151 .driver = {
152 .name = "da903x-led",
153 .owner = THIS_MODULE,
154 },
155 .probe = da903x_led_probe,
156 .remove = __devexit_p(da903x_led_remove),
157};
158
159static int __init da903x_led_init(void)
160{
161 return platform_driver_register(&da903x_led_driver);
162}
163module_init(da903x_led_init);
164
165static void __exit da903x_led_exit(void)
166{
167 platform_driver_unregister(&da903x_led_driver);
168}
169module_exit(da903x_led_exit);
170
171MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
172MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
173 "Mike Rapoport <mike@compulab.co.il>");
174MODULE_LICENSE("GPL");
175MODULE_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 000000000000..53a25b1c2dae
--- /dev/null
+++ b/drivers/leds/leds-hp-disk.c
@@ -0,0 +1,156 @@
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/version.h>
31#include <linux/leds.h>
32#include <acpi/acpi_drivers.h>
33
34#define DRIVER_NAME "leds-hp-disk"
35#define ACPI_MDPS_CLASS "led"
36
37/* For automatic insertion of the module */
38static struct acpi_device_id hpled_device_ids[] = {
39 {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
40 {"", 0},
41};
42MODULE_DEVICE_TABLE(acpi, hpled_device_ids);
43
44struct acpi_hpled {
45 struct acpi_device *device; /* The ACPI device */
46};
47
48static struct acpi_hpled adev;
49
50static acpi_status hpled_acpi_write(acpi_handle handle, int reg)
51{
52 unsigned long ret; /* Not used when writing */
53 union acpi_object in_obj[1];
54 struct acpi_object_list args = { 1, in_obj };
55
56 in_obj[0].type = ACPI_TYPE_INTEGER;
57 in_obj[0].integer.value = reg;
58
59 return acpi_evaluate_integer(handle, "ALED", &args, &ret);
60}
61
62static void hpled_set(struct led_classdev *led_cdev,
63 enum led_brightness value)
64{
65 hpled_acpi_write(adev.device->handle, !!value);
66}
67
68static struct led_classdev hpled_led = {
69 .name = "hp:red:hddprotection",
70 .default_trigger = "heartbeat",
71 .brightness_set = hpled_set,
72};
73
74#ifdef CONFIG_PM
75static int hpled_suspend(struct acpi_device *dev, pm_message_t state)
76{
77 led_classdev_suspend(&hpled_led);
78 return 0;
79}
80
81static int hpled_resume(struct acpi_device *dev)
82{
83 led_classdev_resume(&hpled_led);
84 return 0;
85}
86#else
87#define hpled_suspend NULL
88#define hpled_resume NULL
89#endif
90
91static int hpled_add(struct acpi_device *device)
92{
93 int ret;
94
95 if (!device)
96 return -EINVAL;
97
98 adev.device = device;
99 strcpy(acpi_device_name(device), DRIVER_NAME);
100 strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
101 device->driver_data = &adev;
102
103 ret = led_classdev_register(NULL, &hpled_led);
104 return ret;
105}
106
107static int hpled_remove(struct acpi_device *device, int type)
108{
109 if (!device)
110 return -EINVAL;
111
112 led_classdev_unregister(&hpled_led);
113 return 0;
114}
115
116
117
118static struct acpi_driver leds_hp_driver = {
119 .name = DRIVER_NAME,
120 .class = ACPI_MDPS_CLASS,
121 .ids = hpled_device_ids,
122 .ops = {
123 .add = hpled_add,
124 .remove = hpled_remove,
125 .suspend = hpled_suspend,
126 .resume = hpled_resume,
127 }
128};
129
130static int __init hpled_init_module(void)
131{
132 int ret;
133
134 if (acpi_disabled)
135 return -ENODEV;
136
137 ret = acpi_bus_register_driver(&leds_hp_driver);
138 if (ret < 0)
139 return ret;
140
141 printk(KERN_INFO DRIVER_NAME " driver loaded.\n");
142
143 return 0;
144}
145
146static void __exit hpled_exit_module(void)
147{
148 acpi_bus_unregister_driver(&leds_hp_driver);
149}
150
151MODULE_DESCRIPTION("Driver for HP disk protection LED");
152MODULE_AUTHOR("Pavel Machek <pavel@suse.cz>");
153MODULE_LICENSE("GPL");
154
155module_init(hpled_init_module);
156module_exit(hpled_exit_module);
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index f508729123b5..4e2d1a42b48f 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 7ac61a7b56ad..2f3aa87f2a1f 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 000000000000..d3dfcfb417b8
--- /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 5c99f4f0c692..db681962d7bb 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,
diff --git a/include/linux/leds.h b/include/linux/leds.h
index d41ccb56146a..d3a73f5a48c3 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -123,7 +123,7 @@ extern void ledtrig_ide_activity(void);
123 */ 123 */
124struct led_info { 124struct led_info {
125 const char *name; 125 const char *name;
126 char *default_trigger; 126 const char *default_trigger;
127 int flags; 127 int flags;
128}; 128};
129 129
@@ -135,7 +135,7 @@ struct led_platform_data {
135/* For the leds-gpio driver */ 135/* For the leds-gpio driver */
136struct gpio_led { 136struct gpio_led {
137 const char *name; 137 const char *name;
138 char *default_trigger; 138 const char *default_trigger;
139 unsigned gpio; 139 unsigned gpio;
140 u8 active_low; 140 u8 active_low;
141}; 141};