aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-alix2.c239
-rw-r--r--drivers/leds/leds-ams-delta.c137
-rw-r--r--drivers/leds/leds-net5501.c96
-rw-r--r--drivers/leds/ledtrig-sleep.c80
4 files changed, 552 insertions, 0 deletions
diff --git a/drivers/leds/leds-alix2.c b/drivers/leds/leds-alix2.c
new file mode 100644
index 00000000000..f59ffadf512
--- /dev/null
+++ b/drivers/leds/leds-alix2.c
@@ -0,0 +1,239 @@
1/*
2 * LEDs driver for PCEngines ALIX.2 and ALIX.3
3 *
4 * Copyright (C) 2008 Constantin Baranov <const@mimas.ru>
5 */
6
7#include <linux/err.h>
8#include <linux/io.h>
9#include <linux/kernel.h>
10#include <linux/leds.h>
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/string.h>
14#include <linux/pci.h>
15
16static int force = 0;
17module_param(force, bool, 0444);
18MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs");
19
20#define MSR_LBAR_GPIO 0x5140000C
21#define CS5535_GPIO_SIZE 256
22
23static u32 gpio_base;
24
25static struct pci_device_id divil_pci[] = {
26 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
27 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
28 { } /* NULL entry */
29};
30MODULE_DEVICE_TABLE(pci, divil_pci);
31
32struct alix_led {
33 struct led_classdev cdev;
34 unsigned short port;
35 unsigned int on_value;
36 unsigned int off_value;
37};
38
39static void alix_led_set(struct led_classdev *led_cdev,
40 enum led_brightness brightness)
41{
42 struct alix_led *led_dev =
43 container_of(led_cdev, struct alix_led, cdev);
44
45 if (brightness)
46 outl(led_dev->on_value, gpio_base + led_dev->port);
47 else
48 outl(led_dev->off_value, gpio_base + led_dev->port);
49}
50
51static struct alix_led alix_leds[] = {
52 {
53 .cdev = {
54 .name = "alix:1",
55 .brightness_set = alix_led_set,
56 },
57 .port = 0x00,
58 .on_value = 1 << 22,
59 .off_value = 1 << 6,
60 },
61 {
62 .cdev = {
63 .name = "alix:2",
64 .brightness_set = alix_led_set,
65 },
66 .port = 0x80,
67 .on_value = 1 << 25,
68 .off_value = 1 << 9,
69 },
70 {
71 .cdev = {
72 .name = "alix:3",
73 .brightness_set = alix_led_set,
74 },
75 .port = 0x80,
76 .on_value = 1 << 27,
77 .off_value = 1 << 11,
78 },
79};
80
81static int __init alix_led_probe(struct platform_device *pdev)
82{
83 int i;
84 int ret;
85
86 for (i = 0; i < ARRAY_SIZE(alix_leds); i++) {
87 alix_leds[i].cdev.flags |= LED_CORE_SUSPENDRESUME;
88 ret = led_classdev_register(&pdev->dev, &alix_leds[i].cdev);
89 if (ret < 0)
90 goto fail;
91 }
92 return 0;
93
94fail:
95 while (--i >= 0)
96 led_classdev_unregister(&alix_leds[i].cdev);
97 return ret;
98}
99
100static int alix_led_remove(struct platform_device *pdev)
101{
102 int i;
103
104 for (i = 0; i < ARRAY_SIZE(alix_leds); i++)
105 led_classdev_unregister(&alix_leds[i].cdev);
106 return 0;
107}
108
109static struct platform_driver alix_led_driver = {
110 .remove = alix_led_remove,
111 .driver = {
112 .name = KBUILD_MODNAME,
113 .owner = THIS_MODULE,
114 },
115};
116
117static int __init alix_present(unsigned long bios_phys,
118 const char *alix_sig,
119 size_t alix_sig_len)
120{
121 const size_t bios_len = 0x00010000;
122 const char *bios_virt;
123 const char *scan_end;
124 const char *p;
125 char name[64];
126
127 if (force) {
128 printk(KERN_NOTICE "%s: forced to skip BIOS test, "
129 "assume system has ALIX.2 style LEDs\n",
130 KBUILD_MODNAME);
131 return 1;
132 }
133
134 bios_virt = phys_to_virt(bios_phys);
135 scan_end = bios_virt + bios_len - (alix_sig_len + 2);
136 for (p = bios_virt; p < scan_end; p++) {
137 const char *tail;
138 char *a;
139
140 if (memcmp(p, alix_sig, alix_sig_len) != 0)
141 continue;
142
143 memcpy(name, p, sizeof(name));
144
145 /* remove the first \0 character from string */
146 a = strchr(name, '\0');
147 if (a)
148 *a = ' ';
149
150 /* cut the string at a newline */
151 a = strchr(name, '\r');
152 if (a)
153 *a = '\0';
154
155 tail = p + alix_sig_len;
156 if ((tail[0] == '2' || tail[0] == '3')) {
157 printk(KERN_INFO
158 "%s: system is recognized as \"%s\"\n",
159 KBUILD_MODNAME, name);
160 return 1;
161 }
162 }
163
164 return 0;
165}
166
167static struct platform_device *pdev;
168
169static int __init alix_pci_led_init(void)
170{
171 u32 low, hi;
172
173 if (pci_dev_present(divil_pci) == 0) {
174 printk(KERN_WARNING KBUILD_MODNAME": DIVIL not found\n");
175 return -ENODEV;
176 }
177
178 /* Grab the GPIO I/O range */
179 rdmsr(MSR_LBAR_GPIO, low, hi);
180
181 /* Check the mask and whether GPIO is enabled (sanity check) */
182 if (hi != 0x0000f001) {
183 printk(KERN_WARNING KBUILD_MODNAME": GPIO not enabled\n");
184 return -ENODEV;
185 }
186
187 /* Mask off the IO base address */
188 gpio_base = low & 0x0000ff00;
189
190 if (!request_region(gpio_base, CS5535_GPIO_SIZE, KBUILD_MODNAME)) {
191 printk(KERN_ERR KBUILD_MODNAME": can't allocate I/O for GPIO\n");
192 return -ENODEV;
193 }
194
195 /* Set GPIO function to output */
196 outl(1 << 6, gpio_base + 0x04);
197 outl(1 << 9, gpio_base + 0x84);
198 outl(1 << 11, gpio_base + 0x84);
199
200 return 0;
201}
202
203static int __init alix_led_init(void)
204{
205 int ret = -ENODEV;
206 const char tinybios_sig[] = "PC Engines ALIX.";
207 const char coreboot_sig[] = "PC Engines\0ALIX.";
208
209 if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) ||
210 alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1))
211 ret = alix_pci_led_init();
212
213 if (ret < 0)
214 return ret;
215
216 pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0);
217 if (!IS_ERR(pdev)) {
218 ret = platform_driver_probe(&alix_led_driver, alix_led_probe);
219 if (ret)
220 platform_device_unregister(pdev);
221 } else
222 ret = PTR_ERR(pdev);
223
224 return ret;
225}
226
227static void __exit alix_led_exit(void)
228{
229 platform_device_unregister(pdev);
230 platform_driver_unregister(&alix_led_driver);
231 release_region(gpio_base, CS5535_GPIO_SIZE);
232}
233
234module_init(alix_led_init);
235module_exit(alix_led_exit);
236
237MODULE_AUTHOR("Constantin Baranov <const@mimas.ru>");
238MODULE_DESCRIPTION("PCEngines ALIX.2 and ALIX.3 LED driver");
239MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c
new file mode 100644
index 00000000000..8c00937bf7e
--- /dev/null
+++ b/drivers/leds/leds-ams-delta.c
@@ -0,0 +1,137 @@
1/*
2 * LEDs driver for Amstrad Delta (E3)
3 *
4 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/leds.h>
16#include <plat/board-ams-delta.h>
17
18/*
19 * Our context
20 */
21struct ams_delta_led {
22 struct led_classdev cdev;
23 u8 bitmask;
24};
25
26static void ams_delta_led_set(struct led_classdev *led_cdev,
27 enum led_brightness value)
28{
29 struct ams_delta_led *led_dev =
30 container_of(led_cdev, struct ams_delta_led, cdev);
31
32 if (value)
33 ams_delta_latch1_write(led_dev->bitmask, led_dev->bitmask);
34 else
35 ams_delta_latch1_write(led_dev->bitmask, 0);
36}
37
38static struct ams_delta_led ams_delta_leds[] = {
39 {
40 .cdev = {
41 .name = "ams-delta::camera",
42 .brightness_set = ams_delta_led_set,
43 },
44 .bitmask = AMS_DELTA_LATCH1_LED_CAMERA,
45 },
46 {
47 .cdev = {
48 .name = "ams-delta::advert",
49 .brightness_set = ams_delta_led_set,
50 },
51 .bitmask = AMS_DELTA_LATCH1_LED_ADVERT,
52 },
53 {
54 .cdev = {
55 .name = "ams-delta::email",
56 .brightness_set = ams_delta_led_set,
57 },
58 .bitmask = AMS_DELTA_LATCH1_LED_EMAIL,
59 },
60 {
61 .cdev = {
62 .name = "ams-delta::handsfree",
63 .brightness_set = ams_delta_led_set,
64 },
65 .bitmask = AMS_DELTA_LATCH1_LED_HANDSFREE,
66 },
67 {
68 .cdev = {
69 .name = "ams-delta::voicemail",
70 .brightness_set = ams_delta_led_set,
71 },
72 .bitmask = AMS_DELTA_LATCH1_LED_VOICEMAIL,
73 },
74 {
75 .cdev = {
76 .name = "ams-delta::voice",
77 .brightness_set = ams_delta_led_set,
78 },
79 .bitmask = AMS_DELTA_LATCH1_LED_VOICE,
80 },
81};
82
83static int ams_delta_led_probe(struct platform_device *pdev)
84{
85 int i, ret;
86
87 for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) {
88 ams_delta_leds[i].cdev.flags |= LED_CORE_SUSPENDRESUME;
89 ret = led_classdev_register(&pdev->dev,
90 &ams_delta_leds[i].cdev);
91 if (ret < 0)
92 goto fail;
93 }
94
95 return 0;
96fail:
97 while (--i >= 0)
98 led_classdev_unregister(&ams_delta_leds[i].cdev);
99 return ret;
100}
101
102static int ams_delta_led_remove(struct platform_device *pdev)
103{
104 int i;
105
106 for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++)
107 led_classdev_unregister(&ams_delta_leds[i].cdev);
108
109 return 0;
110}
111
112static struct platform_driver ams_delta_led_driver = {
113 .probe = ams_delta_led_probe,
114 .remove = ams_delta_led_remove,
115 .driver = {
116 .name = "ams-delta-led",
117 .owner = THIS_MODULE,
118 },
119};
120
121static int __init ams_delta_led_init(void)
122{
123 return platform_driver_register(&ams_delta_led_driver);
124}
125
126static void __exit ams_delta_led_exit(void)
127{
128 platform_driver_unregister(&ams_delta_led_driver);
129}
130
131module_init(ams_delta_led_init);
132module_exit(ams_delta_led_exit);
133
134MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
135MODULE_DESCRIPTION("Amstrad Delta LED driver");
136MODULE_LICENSE("GPL");
137MODULE_ALIAS("platform:ams-delta-led");
diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c
new file mode 100644
index 00000000000..7e764b8365e
--- /dev/null
+++ b/drivers/leds/leds-net5501.c
@@ -0,0 +1,96 @@
1/*
2 * Soekris board support code
3 *
4 * Copyright (C) 2008-2009 Tower Technologies
5 * Written by Alessandro Zummo <a.zummo@towertech.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
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/string.h>
16#include <linux/leds.h>
17#include <linux/platform_device.h>
18#include <linux/gpio.h>
19
20#include <asm/geode.h>
21
22static const struct gpio_led net5501_leds[] = {
23 {
24 .name = "error",
25 .gpio = 6,
26 .default_trigger = "default-on",
27 },
28};
29
30static struct gpio_led_platform_data net5501_leds_data = {
31 .num_leds = ARRAY_SIZE(net5501_leds),
32 .leds = net5501_leds,
33};
34
35static struct platform_device net5501_leds_dev = {
36 .name = "leds-gpio",
37 .id = -1,
38 .dev.platform_data = &net5501_leds_data,
39};
40
41static void __init init_net5501(void)
42{
43 platform_device_register(&net5501_leds_dev);
44}
45
46struct soekris_board {
47 u16 offset;
48 char *sig;
49 u8 len;
50 void (*init)(void);
51};
52
53static struct soekris_board __initdata boards[] = {
54 { 0xb7b, "net5501", 7, init_net5501 }, /* net5501 v1.33/1.33c */
55 { 0xb1f, "net5501", 7, init_net5501 }, /* net5501 v1.32i */
56};
57
58static int __init soekris_init(void)
59{
60 int i;
61 unsigned char *rombase, *bios;
62
63 if (!is_geode())
64 return 0;
65
66 rombase = ioremap(0xffff0000, 0xffff);
67 if (!rombase) {
68 printk(KERN_INFO "Soekris net5501 LED driver failed to get rombase");
69 return 0;
70 }
71
72 bios = rombase + 0x20; /* null terminated */
73
74 if (strncmp(bios, "comBIOS", 7))
75 goto unmap;
76
77 for (i = 0; i < ARRAY_SIZE(boards); i++) {
78 unsigned char *model = rombase + boards[i].offset;
79
80 if (strncmp(model, boards[i].sig, boards[i].len) == 0) {
81 printk(KERN_INFO "Soekris %s: %s\n", model, bios);
82
83 if (boards[i].init)
84 boards[i].init();
85 break;
86 }
87 }
88
89unmap:
90 iounmap(rombase);
91 return 0;
92}
93
94arch_initcall(soekris_init);
95
96MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-sleep.c b/drivers/leds/ledtrig-sleep.c
new file mode 100644
index 00000000000..f1640421215
--- /dev/null
+++ b/drivers/leds/ledtrig-sleep.c
@@ -0,0 +1,80 @@
1/* drivers/leds/ledtrig-sleep.c
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/earlysuspend.h>
17#include <linux/leds.h>
18#include <linux/suspend.h>
19
20static int ledtrig_sleep_pm_callback(struct notifier_block *nfb,
21 unsigned long action,
22 void *ignored);
23
24DEFINE_LED_TRIGGER(ledtrig_sleep)
25static struct notifier_block ledtrig_sleep_pm_notifier = {
26 .notifier_call = ledtrig_sleep_pm_callback,
27 .priority = 0,
28};
29
30static void ledtrig_sleep_early_suspend(struct early_suspend *h)
31{
32 led_trigger_event(ledtrig_sleep, LED_FULL);
33}
34
35static void ledtrig_sleep_early_resume(struct early_suspend *h)
36{
37 led_trigger_event(ledtrig_sleep, LED_OFF);
38}
39
40static struct early_suspend ledtrig_sleep_early_suspend_handler = {
41 .suspend = ledtrig_sleep_early_suspend,
42 .resume = ledtrig_sleep_early_resume,
43};
44
45static int ledtrig_sleep_pm_callback(struct notifier_block *nfb,
46 unsigned long action,
47 void *ignored)
48{
49 switch (action) {
50 case PM_HIBERNATION_PREPARE:
51 case PM_SUSPEND_PREPARE:
52 led_trigger_event(ledtrig_sleep, LED_OFF);
53 return NOTIFY_OK;
54 case PM_POST_HIBERNATION:
55 case PM_POST_SUSPEND:
56 led_trigger_event(ledtrig_sleep, LED_FULL);
57 return NOTIFY_OK;
58 }
59
60 return NOTIFY_DONE;
61}
62
63static int __init ledtrig_sleep_init(void)
64{
65 led_trigger_register_simple("sleep", &ledtrig_sleep);
66 register_pm_notifier(&ledtrig_sleep_pm_notifier);
67 register_early_suspend(&ledtrig_sleep_early_suspend_handler);
68 return 0;
69}
70
71static void __exit ledtrig_sleep_exit(void)
72{
73 unregister_early_suspend(&ledtrig_sleep_early_suspend_handler);
74 unregister_pm_notifier(&ledtrig_sleep_pm_notifier);
75 led_trigger_unregister_simple(ledtrig_sleep);
76}
77
78module_init(ledtrig_sleep_init);
79module_exit(ledtrig_sleep_exit);
80