diff options
author | Kristian Kielhofner <kris@krisk.org> | 2006-12-06 23:37:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 11:39:36 -0500 |
commit | 0d75565f1e8f098b80a34ccf70db450f60618ec8 (patch) | |
tree | e8a1e7c661463ef7daea98c814066413cd35ad3e | |
parent | 40fcfc87222e2e8af6379ec366f0cb2a411570cd (diff) |
[PATCH] PCEngines WRAP LED Support
A driver for the PCEngines WRAP boards (http://www.pcengines.ch), which are
very similar to the Soekris net4801 (same NS SC1100 geode reference
design).
The LEDs on the WRAP are on different GPIO lines and I have modified and
copied the net48xx error led support for this. It also includes support
for an "extra" led (in addition to error). The three LEDs on the WRAP are
at GPIO lines 2,3,18 (WRAP LEDs from left to right). This driver gives
access to the second and third LEDs by twiddling GPIO lines 3 & 18.
Because these boards are so similar to the net48xx, I basically sed-ed that
driver to form the basis for leds-wrap.c. The only changes from
leds-net48xx.c are:
- #define WRAP_EXTRA_LED_GPIO
- name changes
- duplicate relevant sections to provide support for the "extra" led
- reverse the various *_led_set values. The WRAP is "backwards" from the
net48xx, and these needed to be updated for that.
[akpm@osdl.org: build fix]
Signed-off-by: Kristian Kielhofner <kris@krisk.org>
Acked-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/leds/Kconfig | 6 | ||||
-rw-r--r-- | drivers/leds/Makefile | 1 | ||||
-rw-r--r-- | drivers/leds/leds-wrap.c | 142 |
3 files changed, 149 insertions, 0 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 9c39b98d5a5b..176142c61492 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -76,6 +76,12 @@ config LEDS_NET48XX | |||
76 | This option enables support for the Soekris net4801 and net4826 error | 76 | This option enables support for the Soekris net4801 and net4826 error |
77 | LED. | 77 | LED. |
78 | 78 | ||
79 | config LEDS_WRAP | ||
80 | tristate "LED Support for the WRAP series LEDs" | ||
81 | depends on LEDS_CLASS && SCx200_GPIO | ||
82 | help | ||
83 | This option enables support for the PCEngines WRAP programmable LEDs. | ||
84 | |||
79 | comment "LED Triggers" | 85 | comment "LED Triggers" |
80 | 86 | ||
81 | config LEDS_TRIGGERS | 87 | config LEDS_TRIGGERS |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 6aa2aed7539d..500de3dc962a 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o | |||
13 | obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o | 13 | obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o |
14 | obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o | 14 | obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o |
15 | obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o | 15 | obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o |
16 | obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o | ||
16 | 17 | ||
17 | # LED Triggers | 18 | # LED Triggers |
18 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o | 19 | obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o |
diff --git a/drivers/leds/leds-wrap.c b/drivers/leds/leds-wrap.c new file mode 100644 index 000000000000..27fb2d8e991f --- /dev/null +++ b/drivers/leds/leds-wrap.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * LEDs driver for PCEngines WRAP | ||
3 | * | ||
4 | * Copyright (C) 2006 Kristian Kielhofner <kris@krisk.org> | ||
5 | * | ||
6 | * Based on leds-net48xx.c | ||
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 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/leds.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <linux/scx200_gpio.h> | ||
20 | |||
21 | #define DRVNAME "wrap-led" | ||
22 | #define WRAP_ERROR_LED_GPIO 3 | ||
23 | #define WRAP_EXTRA_LED_GPIO 18 | ||
24 | |||
25 | static struct platform_device *pdev; | ||
26 | |||
27 | static void wrap_error_led_set(struct led_classdev *led_cdev, | ||
28 | enum led_brightness value) | ||
29 | { | ||
30 | if (value) | ||
31 | scx200_gpio_set_low(WRAP_ERROR_LED_GPIO); | ||
32 | else | ||
33 | scx200_gpio_set_high(WRAP_ERROR_LED_GPIO); | ||
34 | } | ||
35 | |||
36 | static void wrap_extra_led_set(struct led_classdev *led_cdev, | ||
37 | enum led_brightness value) | ||
38 | { | ||
39 | if (value) | ||
40 | scx200_gpio_set_low(WRAP_EXTRA_LED_GPIO); | ||
41 | else | ||
42 | scx200_gpio_set_high(WRAP_EXTRA_LED_GPIO); | ||
43 | } | ||
44 | |||
45 | static struct led_classdev wrap_error_led = { | ||
46 | .name = "wrap:error", | ||
47 | .brightness_set = wrap_error_led_set, | ||
48 | }; | ||
49 | |||
50 | static struct led_classdev wrap_extra_led = { | ||
51 | .name = "wrap:extra", | ||
52 | .brightness_set = wrap_extra_led_set, | ||
53 | }; | ||
54 | |||
55 | #ifdef CONFIG_PM | ||
56 | static int wrap_led_suspend(struct platform_device *dev, | ||
57 | pm_message_t state) | ||
58 | { | ||
59 | led_classdev_suspend(&wrap_error_led); | ||
60 | led_classdev_suspend(&wrap_extra_led); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int wrap_led_resume(struct platform_device *dev) | ||
65 | { | ||
66 | led_classdev_resume(&wrap_error_led); | ||
67 | led_classdev_resume(&wrap_extra_led); | ||
68 | return 0; | ||
69 | } | ||
70 | #else | ||
71 | #define wrap_led_suspend NULL | ||
72 | #define wrap_led_resume NULL | ||
73 | #endif | ||
74 | |||
75 | static int wrap_led_probe(struct platform_device *pdev) | ||
76 | { | ||
77 | int ret; | ||
78 | |||
79 | ret = led_classdev_register(&pdev->dev, &wrap_error_led); | ||
80 | if (ret == 0) { | ||
81 | ret = led_classdev_register(&pdev->dev, &wrap_extra_led); | ||
82 | if (ret < 0) | ||
83 | led_classdev_unregister(&wrap_error_led); | ||
84 | } | ||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | static int wrap_led_remove(struct platform_device *pdev) | ||
89 | { | ||
90 | led_classdev_unregister(&wrap_error_led); | ||
91 | led_classdev_unregister(&wrap_extra_led); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static struct platform_driver wrap_led_driver = { | ||
96 | .probe = wrap_led_probe, | ||
97 | .remove = wrap_led_remove, | ||
98 | .suspend = wrap_led_suspend, | ||
99 | .resume = wrap_led_resume, | ||
100 | .driver = { | ||
101 | .name = DRVNAME, | ||
102 | .owner = THIS_MODULE, | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | static int __init wrap_led_init(void) | ||
107 | { | ||
108 | int ret; | ||
109 | |||
110 | if (!scx200_gpio_present()) { | ||
111 | ret = -ENODEV; | ||
112 | goto out; | ||
113 | } | ||
114 | |||
115 | ret = platform_driver_register(&wrap_led_driver); | ||
116 | if (ret < 0) | ||
117 | goto out; | ||
118 | |||
119 | pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); | ||
120 | if (IS_ERR(pdev)) { | ||
121 | ret = PTR_ERR(pdev); | ||
122 | platform_driver_unregister(&wrap_led_driver); | ||
123 | goto out; | ||
124 | } | ||
125 | |||
126 | out: | ||
127 | return ret; | ||
128 | } | ||
129 | |||
130 | static void __exit wrap_led_exit(void) | ||
131 | { | ||
132 | platform_device_unregister(pdev); | ||
133 | platform_driver_unregister(&wrap_led_driver); | ||
134 | } | ||
135 | |||
136 | module_init(wrap_led_init); | ||
137 | module_exit(wrap_led_exit); | ||
138 | |||
139 | MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>"); | ||
140 | MODULE_DESCRIPTION("PCEngines WRAP LED driver"); | ||
141 | MODULE_LICENSE("GPL"); | ||
142 | |||