OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | --- a/drivers/leds/Kconfig |
2 | +++ b/drivers/leds/Kconfig |
||
3 | @@ -312,6 +312,12 @@ config LEDS_LP8860 |
||
4 | on the LP8860 4 channel LED driver using the I2C communication |
||
5 | bus. |
||
6 | |||
7 | +config LEDS_LATCH |
||
8 | + tristate "LED Support for Memory Latched LEDs" |
||
9 | + depends on LEDS_CLASS |
||
10 | + help |
||
11 | + -- To Do -- |
||
12 | + |
||
13 | config LEDS_CLEVO_MAIL |
||
14 | tristate "Mail LED on Clevo notebook" |
||
15 | depends on LEDS_CLASS |
||
16 | --- a/drivers/leds/Makefile |
||
17 | +++ b/drivers/leds/Makefile |
||
18 | @@ -25,6 +25,7 @@ obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunf |
||
19 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o |
||
20 | obj-$(CONFIG_LEDS_GPIO_REGISTER) += leds-gpio-register.o |
||
21 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o |
||
22 | +obj-$(CONFIG_LEDS_LATCH) += leds-latch.o |
||
23 | obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o |
||
24 | obj-$(CONFIG_LEDS_LP3952) += leds-lp3952.o |
||
25 | obj-$(CONFIG_LEDS_LP55XX_COMMON) += leds-lp55xx-common.o |
||
26 | --- /dev/null |
||
27 | +++ b/drivers/leds/leds-latch.c |
||
28 | @@ -0,0 +1,152 @@ |
||
29 | +/* |
||
30 | + * LEDs driver for Memory Latched Devices |
||
31 | + * |
||
32 | + * Copyright (C) 2008 Gateworks Corp. |
||
33 | + * Chris Lang <clang@gateworks.com> |
||
34 | + * |
||
35 | + * This program is free software; you can redistribute it and/or modify |
||
36 | + * it under the terms of the GNU General Public License version 2 as |
||
37 | + * published by the Free Software Foundation. |
||
38 | + * |
||
39 | + */ |
||
40 | +#include <linux/kernel.h> |
||
41 | +#include <linux/slab.h> |
||
42 | +#include <linux/init.h> |
||
43 | +#include <linux/platform_device.h> |
||
44 | +#include <linux/leds.h> |
||
45 | +#include <linux/workqueue.h> |
||
46 | +#include <asm/io.h> |
||
47 | +#include <linux/spinlock.h> |
||
48 | +#include <linux/slab.h> |
||
49 | +#include <linux/module.h> |
||
50 | +#include <linux/export.h> |
||
51 | + |
||
52 | +static unsigned int mem_keep = 0xFF; |
||
53 | +static spinlock_t mem_lock; |
||
54 | +static unsigned char *iobase; |
||
55 | + |
||
56 | +struct latch_led_data { |
||
57 | + struct led_classdev cdev; |
||
58 | + struct work_struct work; |
||
59 | + u8 new_level; |
||
60 | + u8 bit; |
||
61 | + void (*set_led)(u8 bit, enum led_brightness value); |
||
62 | +}; |
||
63 | + |
||
64 | +static void latch_set_led(u8 bit, enum led_brightness value) |
||
65 | +{ |
||
66 | + if (value == LED_OFF) |
||
67 | + mem_keep |= (0x1 << bit); |
||
68 | + else |
||
69 | + mem_keep &= ~(0x1 << bit); |
||
70 | + |
||
71 | + writeb(mem_keep, iobase); |
||
72 | +} |
||
73 | + |
||
74 | +static void latch_led_set(struct led_classdev *led_cdev, |
||
75 | + enum led_brightness value) |
||
76 | +{ |
||
77 | + struct latch_led_data *led_dat = |
||
78 | + container_of(led_cdev, struct latch_led_data, cdev); |
||
79 | + |
||
80 | + raw_spin_lock(mem_lock); |
||
81 | + |
||
82 | + led_dat->set_led(led_dat->bit, value); |
||
83 | + |
||
84 | + raw_spin_unlock(mem_lock); |
||
85 | +} |
||
86 | + |
||
87 | +static int latch_led_probe(struct platform_device *pdev) |
||
88 | +{ |
||
89 | + struct latch_led_platform_data *pdata = pdev->dev.platform_data; |
||
90 | + struct latch_led *cur_led; |
||
91 | + struct latch_led_data *leds_data, *led_dat; |
||
92 | + int i, ret = 0; |
||
93 | + |
||
94 | + if (!pdata) |
||
95 | + return -EBUSY; |
||
96 | + |
||
97 | + leds_data = kzalloc(sizeof(struct latch_led_data) * pdata->num_leds, |
||
98 | + GFP_KERNEL); |
||
99 | + if (!leds_data) |
||
100 | + return -ENOMEM; |
||
101 | + |
||
102 | + for (i = 0; i < pdata->num_leds; i++) { |
||
103 | + cur_led = &pdata->leds[i]; |
||
104 | + led_dat = &leds_data[i]; |
||
105 | + |
||
106 | + led_dat->cdev.name = cur_led->name; |
||
107 | + led_dat->cdev.default_trigger = cur_led->default_trigger; |
||
108 | + led_dat->cdev.brightness_set = latch_led_set; |
||
109 | + led_dat->cdev.brightness = LED_OFF; |
||
110 | + led_dat->bit = cur_led->bit; |
||
111 | + led_dat->set_led = pdata->set_led ? pdata->set_led : latch_set_led; |
||
112 | + |
||
113 | + ret = led_classdev_register(&pdev->dev, &led_dat->cdev); |
||
114 | + if (ret < 0) { |
||
115 | + goto err; |
||
116 | + } |
||
117 | + } |
||
118 | + |
||
119 | + if (!pdata->set_led) { |
||
120 | + iobase = ioremap_nocache(pdata->mem, 0x1000); |
||
121 | + writeb(0xFF, iobase); |
||
122 | + } |
||
123 | + platform_set_drvdata(pdev, leds_data); |
||
124 | + |
||
125 | + return 0; |
||
126 | + |
||
127 | +err: |
||
128 | + if (i > 0) { |
||
129 | + for (i = i - 1; i >= 0; i--) { |
||
130 | + led_classdev_unregister(&leds_data[i].cdev); |
||
131 | + } |
||
132 | + } |
||
133 | + |
||
134 | + kfree(leds_data); |
||
135 | + |
||
136 | + return ret; |
||
137 | +} |
||
138 | + |
||
139 | +static int latch_led_remove(struct platform_device *pdev) |
||
140 | +{ |
||
141 | + int i; |
||
142 | + struct latch_led_platform_data *pdata = pdev->dev.platform_data; |
||
143 | + struct latch_led_data *leds_data; |
||
144 | + |
||
145 | + leds_data = platform_get_drvdata(pdev); |
||
146 | + |
||
147 | + for (i = 0; i < pdata->num_leds; i++) { |
||
148 | + led_classdev_unregister(&leds_data[i].cdev); |
||
149 | + cancel_work_sync(&leds_data[i].work); |
||
150 | + } |
||
151 | + |
||
152 | + kfree(leds_data); |
||
153 | + |
||
154 | + return 0; |
||
155 | +} |
||
156 | + |
||
157 | +static struct platform_driver latch_led_driver = { |
||
158 | + .probe = latch_led_probe, |
||
159 | + .remove = latch_led_remove, |
||
160 | + .driver = { |
||
161 | + .name = "leds-latch", |
||
162 | + .owner = THIS_MODULE, |
||
163 | + }, |
||
164 | +}; |
||
165 | + |
||
166 | +static int __init latch_led_init(void) |
||
167 | +{ |
||
168 | + return platform_driver_register(&latch_led_driver); |
||
169 | +} |
||
170 | + |
||
171 | +static void __exit latch_led_exit(void) |
||
172 | +{ |
||
173 | + platform_driver_unregister(&latch_led_driver); |
||
174 | +} |
||
175 | + |
||
176 | +module_init(latch_led_init); |
||
177 | +module_exit(latch_led_exit); |
||
178 | + |
||
179 | +MODULE_AUTHOR("Chris Lang <clang@gateworks.com>"); |
||
180 | +MODULE_DESCRIPTION("Latch LED driver"); |
||
181 | --- a/include/linux/leds.h |
||
182 | +++ b/include/linux/leds.h |
||
183 | @@ -423,4 +423,18 @@ static inline void ledtrig_cpu(enum cpu_ |
||
184 | } |
||
185 | #endif |
||
186 | |||
187 | +/* For the leds-latch driver */ |
||
188 | +struct latch_led { |
||
189 | + const char *name; |
||
190 | + char *default_trigger; |
||
191 | + unsigned bit; |
||
192 | +}; |
||
193 | + |
||
194 | +struct latch_led_platform_data { |
||
195 | + int num_leds; |
||
196 | + u32 mem; |
||
197 | + struct latch_led *leds; |
||
198 | + void (*set_led)(u8 bit, enum led_brightness value); |
||
199 | +}; |
||
200 | + |
||
201 | #endif /* __LINUX_LEDS_H_INCLUDED */ |