aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig22
-rw-r--r--drivers/leds/Makefile3
-rw-r--r--drivers/leds/led-class.c4
-rw-r--r--drivers/leds/leds-corgi.c124
-rw-r--r--drivers/leds/leds-fsg.c28
-rw-r--r--drivers/leds/leds-hp6xx.c2
-rw-r--r--drivers/leds/leds-pca955x.c70
-rw-r--r--drivers/leds/leds-spitz.c131
-rw-r--r--drivers/leds/leds-sunfire.c273
9 files changed, 337 insertions, 320 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9556262dda5a..e3e40427e00e 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -24,13 +24,6 @@ config LEDS_ATMEL_PWM
24 This option enables support for LEDs driven using outputs 24 This option enables support for LEDs driven using outputs
25 of the dedicated PWM controller found on newer Atmel SOCs. 25 of the dedicated PWM controller found on newer Atmel SOCs.
26 26
27config LEDS_CORGI
28 tristate "LED Support for the Sharp SL-C7x0 series"
29 depends on LEDS_CLASS && PXA_SHARP_C7xx
30 help
31 This option enables support for the LEDs on Sharp Zaurus
32 SL-C7x0 series (C700, C750, C760, C860).
33
34config LEDS_LOCOMO 27config LEDS_LOCOMO
35 tristate "LED Support for Locomo device" 28 tristate "LED Support for Locomo device"
36 depends on LEDS_CLASS && SHARP_LOCOMO 29 depends on LEDS_CLASS && SHARP_LOCOMO
@@ -38,13 +31,6 @@ config LEDS_LOCOMO
38 This option enables support for the LEDs on Sharp Locomo. 31 This option enables support for the LEDs on Sharp Locomo.
39 Zaurus models SL-5500 and SL-5600. 32 Zaurus models SL-5500 and SL-5600.
40 33
41config LEDS_SPITZ
42 tristate "LED Support for the Sharp SL-Cxx00 series"
43 depends on LEDS_CLASS && PXA_SHARP_Cxx00
44 help
45 This option enables support for the LEDs on Sharp Zaurus
46 SL-Cxx00 series (C1000, C3000, C3100).
47
48config LEDS_S3C24XX 34config LEDS_S3C24XX
49 tristate "LED Support for Samsung S3C24XX GPIO LEDs" 35 tristate "LED Support for Samsung S3C24XX GPIO LEDs"
50 depends on LEDS_CLASS && ARCH_S3C2410 36 depends on LEDS_CLASS && ARCH_S3C2410
@@ -96,6 +82,14 @@ config LEDS_COBALT_RAQ
96 help 82 help
97 This option enables support for the Cobalt Raq series LEDs. 83 This option enables support for the Cobalt Raq series LEDs.
98 84
85config LEDS_SUNFIRE
86 tristate "LED support for SunFire servers."
87 depends on LEDS_CLASS && SPARC64
88 select LEDS_TRIGGERS
89 help
90 This option enables support for the Left, Middle, and Right
91 LEDs on the I/O and CPU boards of SunFire UltraSPARC servers.
92
99config LEDS_HP6XX 93config LEDS_HP6XX
100 tristate "LED Support for the HP Jornada 6xx" 94 tristate "LED Support for the HP Jornada 6xx"
101 depends on LEDS_CLASS && SH_HP6XX 95 depends on LEDS_CLASS && SH_HP6XX
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index ff7982b44565..eb186c351a1c 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,9 +6,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
6 6
7# LED Platform Drivers 7# LED Platform Drivers
8obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o 8obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
9obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o
10obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o 9obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
11obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
12obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o 10obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
13obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o 11obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
14obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o 12obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
@@ -16,6 +14,7 @@ obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
16obj-$(CONFIG_LEDS_H1940) += leds-h1940.o 14obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
17obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o 15obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
18obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o 16obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
17obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
19obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o 18obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o
20obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o 19obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
21obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o 20obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 559a40861c39..ee74ee7b2acc 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -103,8 +103,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
103{ 103{
104 int rc; 104 int rc;
105 105
106 led_cdev->dev = device_create_drvdata(leds_class, parent, 0, led_cdev, 106 led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
107 "%s", led_cdev->name); 107 "%s", led_cdev->name);
108 if (IS_ERR(led_cdev->dev)) 108 if (IS_ERR(led_cdev->dev))
109 return PTR_ERR(led_cdev->dev); 109 return PTR_ERR(led_cdev->dev);
110 110
diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c
deleted file mode 100644
index bc2dcd89f635..000000000000
--- a/drivers/leds/leds-corgi.c
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/leds.h>
18#include <mach/corgi.h>
19#include <mach/hardware.h>
20#include <mach/pxa-regs.h>
21#include <asm/hardware/scoop.h>
22
23static void corgiled_amber_set(struct led_classdev *led_cdev,
24 enum led_brightness value)
25{
26 if (value)
27 GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
28 else
29 GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
30}
31
32static void corgiled_green_set(struct led_classdev *led_cdev,
33 enum led_brightness value)
34{
35 if (value)
36 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
37 else
38 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
39}
40
41static struct led_classdev corgi_amber_led = {
42 .name = "corgi:amber:charge",
43 .default_trigger = "sharpsl-charge",
44 .brightness_set = corgiled_amber_set,
45};
46
47static struct led_classdev corgi_green_led = {
48 .name = "corgi:green:mail",
49 .default_trigger = "nand-disk",
50 .brightness_set = corgiled_green_set,
51};
52
53#ifdef CONFIG_PM
54static int corgiled_suspend(struct platform_device *dev, pm_message_t state)
55{
56#ifdef CONFIG_LEDS_TRIGGERS
57 if (corgi_amber_led.trigger &&
58 strcmp(corgi_amber_led.trigger->name, "sharpsl-charge"))
59#endif
60 led_classdev_suspend(&corgi_amber_led);
61 led_classdev_suspend(&corgi_green_led);
62 return 0;
63}
64
65static int corgiled_resume(struct platform_device *dev)
66{
67 led_classdev_resume(&corgi_amber_led);
68 led_classdev_resume(&corgi_green_led);
69 return 0;
70}
71#endif
72
73static int corgiled_probe(struct platform_device *pdev)
74{
75 int ret;
76
77 ret = led_classdev_register(&pdev->dev, &corgi_amber_led);
78 if (ret < 0)
79 return ret;
80
81 ret = led_classdev_register(&pdev->dev, &corgi_green_led);
82 if (ret < 0)
83 led_classdev_unregister(&corgi_amber_led);
84
85 return ret;
86}
87
88static int corgiled_remove(struct platform_device *pdev)
89{
90 led_classdev_unregister(&corgi_amber_led);
91 led_classdev_unregister(&corgi_green_led);
92 return 0;
93}
94
95static struct platform_driver corgiled_driver = {
96 .probe = corgiled_probe,
97 .remove = corgiled_remove,
98#ifdef CONFIG_PM
99 .suspend = corgiled_suspend,
100 .resume = corgiled_resume,
101#endif
102 .driver = {
103 .name = "corgi-led",
104 .owner = THIS_MODULE,
105 },
106};
107
108static int __init corgiled_init(void)
109{
110 return platform_driver_register(&corgiled_driver);
111}
112
113static void __exit corgiled_exit(void)
114{
115 platform_driver_unregister(&corgiled_driver);
116}
117
118module_init(corgiled_init);
119module_exit(corgiled_exit);
120
121MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
122MODULE_DESCRIPTION("Corgi LED driver");
123MODULE_LICENSE("GPL");
124MODULE_ALIAS("platform:corgi-led");
diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c
index be0e12144b8b..34935155c1c0 100644
--- a/drivers/leds/leds-fsg.c
+++ b/drivers/leds/leds-fsg.c
@@ -161,6 +161,16 @@ static int fsg_led_probe(struct platform_device *pdev)
161{ 161{
162 int ret; 162 int ret;
163 163
164 /* Map the LED chip select address space */
165 latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
166 if (!latch_address) {
167 ret = -ENOMEM;
168 goto failremap;
169 }
170
171 latch_value = 0xffff;
172 *latch_address = latch_value;
173
164 ret = led_classdev_register(&pdev->dev, &fsg_wlan_led); 174 ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
165 if (ret < 0) 175 if (ret < 0)
166 goto failwlan; 176 goto failwlan;
@@ -185,20 +195,8 @@ static int fsg_led_probe(struct platform_device *pdev)
185 if (ret < 0) 195 if (ret < 0)
186 goto failring; 196 goto failring;
187 197
188 /* Map the LED chip select address space */
189 latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
190 if (!latch_address) {
191 ret = -ENOMEM;
192 goto failremap;
193 }
194
195 latch_value = 0xffff;
196 *latch_address = latch_value;
197
198 return ret; 198 return ret;
199 199
200 failremap:
201 led_classdev_unregister(&fsg_ring_led);
202 failring: 200 failring:
203 led_classdev_unregister(&fsg_sync_led); 201 led_classdev_unregister(&fsg_sync_led);
204 failsync: 202 failsync:
@@ -210,14 +208,14 @@ static int fsg_led_probe(struct platform_device *pdev)
210 failwan: 208 failwan:
211 led_classdev_unregister(&fsg_wlan_led); 209 led_classdev_unregister(&fsg_wlan_led);
212 failwlan: 210 failwlan:
211 iounmap(latch_address);
212 failremap:
213 213
214 return ret; 214 return ret;
215} 215}
216 216
217static int fsg_led_remove(struct platform_device *pdev) 217static int fsg_led_remove(struct platform_device *pdev)
218{ 218{
219 iounmap(latch_address);
220
221 led_classdev_unregister(&fsg_wlan_led); 219 led_classdev_unregister(&fsg_wlan_led);
222 led_classdev_unregister(&fsg_wan_led); 220 led_classdev_unregister(&fsg_wan_led);
223 led_classdev_unregister(&fsg_sata_led); 221 led_classdev_unregister(&fsg_sata_led);
@@ -225,6 +223,8 @@ static int fsg_led_remove(struct platform_device *pdev)
225 led_classdev_unregister(&fsg_sync_led); 223 led_classdev_unregister(&fsg_sync_led);
226 led_classdev_unregister(&fsg_ring_led); 224 led_classdev_unregister(&fsg_ring_led);
227 225
226 iounmap(latch_address);
227
228 return 0; 228 return 0;
229} 229}
230 230
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c
index 844d5979c904..e8fb1baf8a50 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 146c06972863..f508729123b5 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -248,11 +248,10 @@ static int __devinit pca955x_probe(struct i2c_client *client,
248 const struct i2c_device_id *id) 248 const struct i2c_device_id *id)
249{ 249{
250 struct pca955x_led *pca955x; 250 struct pca955x_led *pca955x;
251 int i;
252 int err = -ENODEV;
253 struct pca955x_chipdef *chip; 251 struct pca955x_chipdef *chip;
254 struct i2c_adapter *adapter; 252 struct i2c_adapter *adapter;
255 struct led_platform_data *pdata; 253 struct led_platform_data *pdata;
254 int i, err;
256 255
257 chip = &pca955x_chipdefs[id->driver_data]; 256 chip = &pca955x_chipdefs[id->driver_data];
258 adapter = to_i2c_adapter(client->dev.parent); 257 adapter = to_i2c_adapter(client->dev.parent);
@@ -282,43 +281,41 @@ static int __devinit pca955x_probe(struct i2c_client *client,
282 } 281 }
283 } 282 }
284 283
284 pca955x = kzalloc(sizeof(*pca955x) * chip->bits, GFP_KERNEL);
285 if (!pca955x)
286 return -ENOMEM;
287
288 i2c_set_clientdata(client, pca955x);
289
285 for (i = 0; i < chip->bits; i++) { 290 for (i = 0; i < chip->bits; i++) {
286 pca955x = kzalloc(sizeof(struct pca955x_led), GFP_KERNEL); 291 pca955x[i].chipdef = chip;
287 if (!pca955x) { 292 pca955x[i].client = client;
288 err = -ENOMEM; 293 pca955x[i].led_num = i;
289 goto exit;
290 }
291 294
292 pca955x->chipdef = chip;
293 pca955x->client = client;
294 pca955x->led_num = i;
295 /* Platform data can specify LED names and default triggers */ 295 /* Platform data can specify LED names and default triggers */
296 if (pdata) { 296 if (pdata) {
297 if (pdata->leds[i].name) 297 if (pdata->leds[i].name)
298 snprintf(pca955x->name, 32, "pca955x:%s", 298 snprintf(pca955x[i].name,
299 pdata->leds[i].name); 299 sizeof(pca955x[i].name), "pca955x:%s",
300 pdata->leds[i].name);
300 if (pdata->leds[i].default_trigger) 301 if (pdata->leds[i].default_trigger)
301 pca955x->led_cdev.default_trigger = 302 pca955x[i].led_cdev.default_trigger =
302 pdata->leds[i].default_trigger; 303 pdata->leds[i].default_trigger;
303 } else { 304 } else {
304 snprintf(pca955x->name, 32, "pca955x:%d", i); 305 snprintf(pca955x[i].name, sizeof(pca955x[i].name),
306 "pca955x:%d", i);
305 } 307 }
306 spin_lock_init(&pca955x->lock);
307 308
308 pca955x->led_cdev.name = pca955x->name; 309 spin_lock_init(&pca955x[i].lock);
309 pca955x->led_cdev.brightness_set =
310 pca955x_led_set;
311 310
312 /* 311 pca955x[i].led_cdev.name = pca955x[i].name;
313 * Client data is a pointer to the _first_ pca955x_led 312 pca955x[i].led_cdev.brightness_set = pca955x_led_set;
314 * struct
315 */
316 if (i == 0)
317 i2c_set_clientdata(client, pca955x);
318 313
319 INIT_WORK(&(pca955x->work), pca955x_led_work); 314 INIT_WORK(&pca955x[i].work, pca955x_led_work);
320 315
321 led_classdev_register(&client->dev, &(pca955x->led_cdev)); 316 err = led_classdev_register(&client->dev, &pca955x[i].led_cdev);
317 if (err < 0)
318 goto exit;
322 } 319 }
323 320
324 /* Turn off LEDs */ 321 /* Turn off LEDs */
@@ -336,23 +333,32 @@ static int __devinit pca955x_probe(struct i2c_client *client,
336 pca955x_write_psc(client, 1, 0); 333 pca955x_write_psc(client, 1, 0);
337 334
338 return 0; 335 return 0;
336
339exit: 337exit:
338 while (i--) {
339 led_classdev_unregister(&pca955x[i].led_cdev);
340 cancel_work_sync(&pca955x[i].work);
341 }
342
343 kfree(pca955x);
344 i2c_set_clientdata(client, NULL);
345
340 return err; 346 return err;
341} 347}
342 348
343static int __devexit pca955x_remove(struct i2c_client *client) 349static int __devexit pca955x_remove(struct i2c_client *client)
344{ 350{
345 struct pca955x_led *pca955x = i2c_get_clientdata(client); 351 struct pca955x_led *pca955x = i2c_get_clientdata(client);
346 int leds = pca955x->chipdef->bits;
347 int i; 352 int i;
348 353
349 for (i = 0; i < leds; i++) { 354 for (i = 0; i < pca955x->chipdef->bits; i++) {
350 led_classdev_unregister(&(pca955x->led_cdev)); 355 led_classdev_unregister(&pca955x[i].led_cdev);
351 cancel_work_sync(&(pca955x->work)); 356 cancel_work_sync(&pca955x[i].work);
352 kfree(pca955x);
353 pca955x = pca955x + 1;
354 } 357 }
355 358
359 kfree(pca955x);
360 i2c_set_clientdata(client, NULL);
361
356 return 0; 362 return 0;
357} 363}
358 364
diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c
deleted file mode 100644
index 178831c64bfb..000000000000
--- a/drivers/leds/leds-spitz.c
+++ /dev/null
@@ -1,131 +0,0 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/leds.h>
18#include <asm/hardware/scoop.h>
19#include <asm/mach-types.h>
20#include <mach/hardware.h>
21#include <mach/pxa-regs.h>
22#include <mach/spitz.h>
23
24static void spitzled_amber_set(struct led_classdev *led_cdev,
25 enum led_brightness value)
26{
27 if (value)
28 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
29 else
30 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
31}
32
33static void spitzled_green_set(struct led_classdev *led_cdev,
34 enum led_brightness value)
35{
36 if (value)
37 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
38 else
39 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
40}
41
42static struct led_classdev spitz_amber_led = {
43 .name = "spitz:amber:charge",
44 .default_trigger = "sharpsl-charge",
45 .brightness_set = spitzled_amber_set,
46};
47
48static struct led_classdev spitz_green_led = {
49 .name = "spitz:green:hddactivity",
50 .default_trigger = "ide-disk",
51 .brightness_set = spitzled_green_set,
52};
53
54#ifdef CONFIG_PM
55static int spitzled_suspend(struct platform_device *dev, pm_message_t state)
56{
57#ifdef CONFIG_LEDS_TRIGGERS
58 if (spitz_amber_led.trigger &&
59 strcmp(spitz_amber_led.trigger->name, "sharpsl-charge"))
60#endif
61 led_classdev_suspend(&spitz_amber_led);
62 led_classdev_suspend(&spitz_green_led);
63 return 0;
64}
65
66static int spitzled_resume(struct platform_device *dev)
67{
68 led_classdev_resume(&spitz_amber_led);
69 led_classdev_resume(&spitz_green_led);
70 return 0;
71}
72#endif
73
74static int spitzled_probe(struct platform_device *pdev)
75{
76 int ret;
77
78 if (machine_is_akita()) {
79 spitz_green_led.name = "spitz:green:mail";
80 spitz_green_led.default_trigger = "nand-disk";
81 }
82
83 ret = led_classdev_register(&pdev->dev, &spitz_amber_led);
84 if (ret < 0)
85 return ret;
86
87 ret = led_classdev_register(&pdev->dev, &spitz_green_led);
88 if (ret < 0)
89 led_classdev_unregister(&spitz_amber_led);
90
91 return ret;
92}
93
94static int spitzled_remove(struct platform_device *pdev)
95{
96 led_classdev_unregister(&spitz_amber_led);
97 led_classdev_unregister(&spitz_green_led);
98
99 return 0;
100}
101
102static struct platform_driver spitzled_driver = {
103 .probe = spitzled_probe,
104 .remove = spitzled_remove,
105#ifdef CONFIG_PM
106 .suspend = spitzled_suspend,
107 .resume = spitzled_resume,
108#endif
109 .driver = {
110 .name = "spitz-led",
111 .owner = THIS_MODULE,
112 },
113};
114
115static int __init spitzled_init(void)
116{
117 return platform_driver_register(&spitzled_driver);
118}
119
120static void __exit spitzled_exit(void)
121{
122 platform_driver_unregister(&spitzled_driver);
123}
124
125module_init(spitzled_init);
126module_exit(spitzled_exit);
127
128MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
129MODULE_DESCRIPTION("Spitz LED driver");
130MODULE_LICENSE("GPL");
131MODULE_ALIAS("platform:spitz-led");
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
new file mode 100644
index 000000000000..6b008f0c3f62
--- /dev/null
+++ b/drivers/leds/leds-sunfire.c
@@ -0,0 +1,273 @@
1/* leds-sunfire.c: SUNW,Ultra-Enterprise LED driver.
2 *
3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/leds.h>
10#include <linux/io.h>
11#include <linux/platform_device.h>
12
13#include <asm/fhc.h>
14#include <asm/upa.h>
15
16#define DRIVER_NAME "leds-sunfire"
17#define PFX DRIVER_NAME ": "
18
19MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
20MODULE_DESCRIPTION("Sun Fire LED driver");
21MODULE_LICENSE("GPL");
22
23struct sunfire_led {
24 struct led_classdev led_cdev;
25 void __iomem *reg;
26};
27#define to_sunfire_led(d) container_of(d, struct sunfire_led, led_cdev)
28
29static void __clockboard_set(struct led_classdev *led_cdev,
30 enum led_brightness led_val, u8 bit)
31{
32 struct sunfire_led *p = to_sunfire_led(led_cdev);
33 u8 reg = upa_readb(p->reg);
34
35 switch (bit) {
36 case CLOCK_CTRL_LLED:
37 if (led_val)
38 reg &= ~bit;
39 else
40 reg |= bit;
41 break;
42
43 default:
44 if (led_val)
45 reg |= bit;
46 else
47 reg &= ~bit;
48 break;
49 }
50 upa_writeb(reg, p->reg);
51}
52
53static void clockboard_left_set(struct led_classdev *led_cdev,
54 enum led_brightness led_val)
55{
56 __clockboard_set(led_cdev, led_val, CLOCK_CTRL_LLED);
57}
58
59static void clockboard_middle_set(struct led_classdev *led_cdev,
60 enum led_brightness led_val)
61{
62 __clockboard_set(led_cdev, led_val, CLOCK_CTRL_MLED);
63}
64
65static void clockboard_right_set(struct led_classdev *led_cdev,
66 enum led_brightness led_val)
67{
68 __clockboard_set(led_cdev, led_val, CLOCK_CTRL_RLED);
69}
70
71static void __fhc_set(struct led_classdev *led_cdev,
72 enum led_brightness led_val, u32 bit)
73{
74 struct sunfire_led *p = to_sunfire_led(led_cdev);
75 u32 reg = upa_readl(p->reg);
76
77 switch (bit) {
78 case FHC_CONTROL_LLED:
79 if (led_val)
80 reg &= ~bit;
81 else
82 reg |= bit;
83 break;
84
85 default:
86 if (led_val)
87 reg |= bit;
88 else
89 reg &= ~bit;
90 break;
91 }
92 upa_writel(reg, p->reg);
93}
94
95static void fhc_left_set(struct led_classdev *led_cdev,
96 enum led_brightness led_val)
97{
98 __fhc_set(led_cdev, led_val, FHC_CONTROL_LLED);
99}
100
101static void fhc_middle_set(struct led_classdev *led_cdev,
102 enum led_brightness led_val)
103{
104 __fhc_set(led_cdev, led_val, FHC_CONTROL_MLED);
105}
106
107static void fhc_right_set(struct led_classdev *led_cdev,
108 enum led_brightness led_val)
109{
110 __fhc_set(led_cdev, led_val, FHC_CONTROL_RLED);
111}
112
113typedef void (*set_handler)(struct led_classdev *, enum led_brightness);
114struct led_type {
115 const char *name;
116 set_handler handler;
117 const char *default_trigger;
118};
119
120#define NUM_LEDS_PER_BOARD 3
121struct sunfire_drvdata {
122 struct sunfire_led leds[NUM_LEDS_PER_BOARD];
123};
124
125static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
126 struct led_type *types)
127{
128 struct sunfire_drvdata *p;
129 int i, err = -EINVAL;
130
131 if (pdev->num_resources != 1) {
132 printk(KERN_ERR PFX "Wrong number of resources %d, should be 1\n",
133 pdev->num_resources);
134 goto out;
135 }
136
137 p = kzalloc(sizeof(*p), GFP_KERNEL);
138 if (!p) {
139 printk(KERN_ERR PFX "Could not allocate struct sunfire_drvdata\n");
140 goto out;
141 }
142
143 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) {
144 struct led_classdev *lp = &p->leds[i].led_cdev;
145
146 p->leds[i].reg = (void __iomem *) pdev->resource[0].start;
147 lp->name = types[i].name;
148 lp->brightness = LED_FULL;
149 lp->brightness_set = types[i].handler;
150 lp->default_trigger = types[i].default_trigger;
151
152 err = led_classdev_register(&pdev->dev, lp);
153 if (err) {
154 printk(KERN_ERR PFX "Could not register %s LED\n",
155 lp->name);
156 goto out_unregister_led_cdevs;
157 }
158 }
159
160 dev_set_drvdata(&pdev->dev, p);
161
162 err = 0;
163out:
164 return err;
165
166out_unregister_led_cdevs:
167 for (i--; i >= 0; i--)
168 led_classdev_unregister(&p->leds[i].led_cdev);
169 goto out;
170}
171
172static int __devexit sunfire_led_generic_remove(struct platform_device *pdev)
173{
174 struct sunfire_drvdata *p = dev_get_drvdata(&pdev->dev);
175 int i;
176
177 for (i = 0; i < NUM_LEDS_PER_BOARD; i++)
178 led_classdev_unregister(&p->leds[i].led_cdev);
179
180 kfree(p);
181
182 return 0;
183}
184
185static struct led_type clockboard_led_types[NUM_LEDS_PER_BOARD] = {
186 {
187 .name = "clockboard-left",
188 .handler = clockboard_left_set,
189 },
190 {
191 .name = "clockboard-middle",
192 .handler = clockboard_middle_set,
193 },
194 {
195 .name = "clockboard-right",
196 .handler = clockboard_right_set,
197 .default_trigger= "heartbeat",
198 },
199};
200
201static int __devinit sunfire_clockboard_led_probe(struct platform_device *pdev)
202{
203 return sunfire_led_generic_probe(pdev, clockboard_led_types);
204}
205
206static struct led_type fhc_led_types[NUM_LEDS_PER_BOARD] = {
207 {
208 .name = "fhc-left",
209 .handler = fhc_left_set,
210 },
211 {
212 .name = "fhc-middle",
213 .handler = fhc_middle_set,
214 },
215 {
216 .name = "fhc-right",
217 .handler = fhc_right_set,
218 .default_trigger= "heartbeat",
219 },
220};
221
222static int __devinit sunfire_fhc_led_probe(struct platform_device *pdev)
223{
224 return sunfire_led_generic_probe(pdev, fhc_led_types);
225}
226
227MODULE_ALIAS("platform:sunfire-clockboard-leds");
228MODULE_ALIAS("platform:sunfire-fhc-leds");
229
230static struct platform_driver sunfire_clockboard_led_driver = {
231 .probe = sunfire_clockboard_led_probe,
232 .remove = __devexit_p(sunfire_led_generic_remove),
233 .driver = {
234 .name = "sunfire-clockboard-leds",
235 .owner = THIS_MODULE,
236 },
237};
238
239static struct platform_driver sunfire_fhc_led_driver = {
240 .probe = sunfire_fhc_led_probe,
241 .remove = __devexit_p(sunfire_led_generic_remove),
242 .driver = {
243 .name = "sunfire-fhc-leds",
244 .owner = THIS_MODULE,
245 },
246};
247
248static int __init sunfire_leds_init(void)
249{
250 int err = platform_driver_register(&sunfire_clockboard_led_driver);
251
252 if (err) {
253 printk(KERN_ERR PFX "Could not register clock board LED driver\n");
254 return err;
255 }
256
257 err = platform_driver_register(&sunfire_fhc_led_driver);
258 if (err) {
259 printk(KERN_ERR PFX "Could not register FHC LED driver\n");
260 platform_driver_unregister(&sunfire_clockboard_led_driver);
261 }
262
263 return err;
264}
265
266static void __exit sunfire_leds_exit(void)
267{
268 platform_driver_unregister(&sunfire_clockboard_led_driver);
269 platform_driver_unregister(&sunfire_fhc_led_driver);
270}
271
272module_init(sunfire_leds_init);
273module_exit(sunfire_leds_exit);