aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2013-07-16 06:32:08 -0400
committerSimon Horman <horms+renesas@verge.net.au>2013-07-21 21:16:54 -0400
commitae3e4c277669e16093f0e71ca927cf33e7dde053 (patch)
tree04be516b49337d7f6f90dc99528348a6ce9dd756 /drivers/leds
parente6909dcedb55b8790f5b79599987d84eea5888b1 (diff)
leds: Remove leds-renesas-tpu driver
The driver is superseded by the generic pwm-renesas-tpu driver used with leds-pwm. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Acked-by: Bryan Wu <cooloney@gmail.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig12
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-renesas-tpu.c337
3 files changed, 0 insertions, 350 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index e43402dd1dea..074bcb3892b5 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -429,18 +429,6 @@ config LEDS_ASIC3
429 cannot be used. This driver supports hardware blinking with an on+off 429 cannot be used. This driver supports hardware blinking with an on+off
430 period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700. 430 period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700.
431 431
432config LEDS_RENESAS_TPU
433 bool "LED support for Renesas TPU"
434 depends on LEDS_CLASS=y && HAVE_CLK && GPIOLIB
435 help
436 This option enables build of the LED TPU platform driver,
437 suitable to drive any TPU channel on newer Renesas SoCs.
438 The driver controls the GPIO pin connected to the LED via
439 the GPIO framework and expects the LED to be connected to
440 a pin that can be driven in both GPIO mode and using TPU
441 pin function. The latter to support brightness control.
442 Brightness control is supported but hardware blinking is not.
443
444config LEDS_TCA6507 432config LEDS_TCA6507
445 tristate "LED Support for TCA6507 I2C chip" 433 tristate "LED Support for TCA6507 I2C chip"
446 depends on LEDS_CLASS && I2C 434 depends on LEDS_CLASS && I2C
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index ac2897732b02..ae4b6135f665 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
49obj-$(CONFIG_LEDS_NS2) += leds-ns2.o 49obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
50obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o 50obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
51obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o 51obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
52obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
53obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o 52obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
54obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o 53obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
55obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o 54obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c
deleted file mode 100644
index adebf4931e1e..000000000000
--- a/drivers/leds/leds-renesas-tpu.c
+++ /dev/null
@@ -1,337 +0,0 @@
1/*
2 * LED control using Renesas TPU
3 *
4 * Copyright (C) 2011 Magnus Damm
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
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
24#include <linux/printk.h>
25#include <linux/ioport.h>
26#include <linux/io.h>
27#include <linux/clk.h>
28#include <linux/leds.h>
29#include <linux/platform_data/leds-renesas-tpu.h>
30#include <linux/gpio.h>
31#include <linux/err.h>
32#include <linux/slab.h>
33#include <linux/pm_runtime.h>
34#include <linux/workqueue.h>
35
36enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN };
37enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON };
38
39struct r_tpu_priv {
40 struct led_classdev ldev;
41 void __iomem *mapbase;
42 struct clk *clk;
43 struct platform_device *pdev;
44 enum r_tpu_pin pin_state;
45 enum r_tpu_timer timer_state;
46 unsigned long min_rate;
47 unsigned int refresh_rate;
48 struct work_struct work;
49 enum led_brightness new_brightness;
50};
51
52static DEFINE_SPINLOCK(r_tpu_lock);
53
54#define TSTR -1 /* Timer start register (shared register) */
55#define TCR 0 /* Timer control register (+0x00) */
56#define TMDR 1 /* Timer mode register (+0x04) */
57#define TIOR 2 /* Timer I/O control register (+0x08) */
58#define TIER 3 /* Timer interrupt enable register (+0x0c) */
59#define TSR 4 /* Timer status register (+0x10) */
60#define TCNT 5 /* Timer counter (+0x14) */
61#define TGRA 6 /* Timer general register A (+0x18) */
62#define TGRB 7 /* Timer general register B (+0x1c) */
63#define TGRC 8 /* Timer general register C (+0x20) */
64#define TGRD 9 /* Timer general register D (+0x24) */
65
66static inline u16 r_tpu_read(struct r_tpu_priv *p, int reg_nr)
67{
68 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
69 void __iomem *base = p->mapbase;
70 unsigned long offs = reg_nr << 2;
71
72 if (reg_nr == TSTR)
73 return ioread16(base - cfg->channel_offset);
74
75 return ioread16(base + offs);
76}
77
78static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr, u16 value)
79{
80 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
81 void __iomem *base = p->mapbase;
82 unsigned long offs = reg_nr << 2;
83
84 if (reg_nr == TSTR) {
85 iowrite16(value, base - cfg->channel_offset);
86 return;
87 }
88
89 iowrite16(value, base + offs);
90}
91
92static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start)
93{
94 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
95 unsigned long flags;
96 u16 value;
97
98 /* start stop register shared by multiple timer channels */
99 spin_lock_irqsave(&r_tpu_lock, flags);
100 value = r_tpu_read(p, TSTR);
101
102 if (start)
103 value |= 1 << cfg->timer_bit;
104 else
105 value &= ~(1 << cfg->timer_bit);
106
107 r_tpu_write(p, TSTR, value);
108 spin_unlock_irqrestore(&r_tpu_lock, flags);
109}
110
111static int r_tpu_enable(struct r_tpu_priv *p, enum led_brightness brightness)
112{
113 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
114 int prescaler[] = { 1, 4, 16, 64 };
115 int k, ret;
116 unsigned long rate, tmp;
117
118 if (p->timer_state == R_TPU_TIMER_ON)
119 return 0;
120
121 /* wake up device and enable clock */
122 pm_runtime_get_sync(&p->pdev->dev);
123 ret = clk_enable(p->clk);
124 if (ret) {
125 dev_err(&p->pdev->dev, "cannot enable clock\n");
126 return ret;
127 }
128
129 /* make sure channel is disabled */
130 r_tpu_start_stop_ch(p, 0);
131
132 /* get clock rate after enabling it */
133 rate = clk_get_rate(p->clk);
134
135 /* pick the lowest acceptable rate */
136 for (k = ARRAY_SIZE(prescaler) - 1; k >= 0; k--)
137 if ((rate / prescaler[k]) >= p->min_rate)
138 break;
139
140 if (k < 0) {
141 dev_err(&p->pdev->dev, "clock rate mismatch\n");
142 goto err0;
143 }
144 dev_dbg(&p->pdev->dev, "rate = %lu, prescaler %u\n",
145 rate, prescaler[k]);
146
147 /* clear TCNT on TGRB match, count on rising edge, set prescaler */
148 r_tpu_write(p, TCR, 0x0040 | k);
149
150 /* output 0 until TGRA, output 1 until TGRB */
151 r_tpu_write(p, TIOR, 0x0002);
152
153 rate /= prescaler[k] * p->refresh_rate;
154 r_tpu_write(p, TGRB, rate);
155 dev_dbg(&p->pdev->dev, "TRGB = 0x%04lx\n", rate);
156
157 tmp = (cfg->max_brightness - brightness) * rate;
158 r_tpu_write(p, TGRA, tmp / cfg->max_brightness);
159 dev_dbg(&p->pdev->dev, "TRGA = 0x%04lx\n", tmp / cfg->max_brightness);
160
161 /* PWM mode */
162 r_tpu_write(p, TMDR, 0x0002);
163
164 /* enable channel */
165 r_tpu_start_stop_ch(p, 1);
166
167 p->timer_state = R_TPU_TIMER_ON;
168 return 0;
169 err0:
170 clk_disable(p->clk);
171 pm_runtime_put_sync(&p->pdev->dev);
172 return -ENOTSUPP;
173}
174
175static void r_tpu_disable(struct r_tpu_priv *p)
176{
177 if (p->timer_state == R_TPU_TIMER_UNUSED)
178 return;
179
180 /* disable channel */
181 r_tpu_start_stop_ch(p, 0);
182
183 /* stop clock and mark device as idle */
184 clk_disable(p->clk);
185 pm_runtime_put_sync(&p->pdev->dev);
186
187 p->timer_state = R_TPU_TIMER_UNUSED;
188}
189
190static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state,
191 enum led_brightness brightness)
192{
193 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
194
195 if (p->pin_state == new_state) {
196 if (p->pin_state == R_TPU_PIN_GPIO)
197 gpio_set_value(cfg->pin_gpio, brightness);
198 return;
199 }
200
201 if (p->pin_state == R_TPU_PIN_GPIO)
202 gpio_free(cfg->pin_gpio);
203
204 if (p->pin_state == R_TPU_PIN_GPIO_FN)
205 gpio_free(cfg->pin_gpio_fn);
206
207 if (new_state == R_TPU_PIN_GPIO)
208 gpio_request_one(cfg->pin_gpio, !!brightness ?
209 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
210 cfg->name);
211
212 if (new_state == R_TPU_PIN_GPIO_FN)
213 gpio_request(cfg->pin_gpio_fn, cfg->name);
214
215 p->pin_state = new_state;
216}
217
218static void r_tpu_work(struct work_struct *work)
219{
220 struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work);
221 enum led_brightness brightness = p->new_brightness;
222
223 r_tpu_disable(p);
224
225 /* off and maximum are handled as GPIO pins, in between PWM */
226 if ((brightness == 0) || (brightness == p->ldev.max_brightness))
227 r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness);
228 else {
229 r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0);
230 r_tpu_enable(p, brightness);
231 }
232}
233
234static void r_tpu_set_brightness(struct led_classdev *ldev,
235 enum led_brightness brightness)
236{
237 struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev);
238 p->new_brightness = brightness;
239 schedule_work(&p->work);
240}
241
242static int r_tpu_probe(struct platform_device *pdev)
243{
244 struct led_renesas_tpu_config *cfg = pdev->dev.platform_data;
245 struct r_tpu_priv *p;
246 struct resource *res;
247 int ret;
248
249 if (!cfg) {
250 dev_err(&pdev->dev, "missing platform data\n");
251 return -ENODEV;
252 }
253
254 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
255 if (p == NULL) {
256 dev_err(&pdev->dev, "failed to allocate driver data\n");
257 return -ENOMEM;
258 }
259
260 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
261 if (!res) {
262 dev_err(&pdev->dev, "failed to get I/O memory\n");
263 return -ENXIO;
264 }
265
266 /* map memory, let mapbase point to our channel */
267 p->mapbase = devm_ioremap_nocache(&pdev->dev, res->start,
268 resource_size(res));
269 if (p->mapbase == NULL) {
270 dev_err(&pdev->dev, "failed to remap I/O memory\n");
271 return -ENXIO;
272 }
273
274 /* get hold of clock */
275 p->clk = devm_clk_get(&pdev->dev, NULL);
276 if (IS_ERR(p->clk)) {
277 dev_err(&pdev->dev, "cannot get clock\n");
278 return PTR_ERR(p->clk);
279 }
280
281 p->pdev = pdev;
282 p->pin_state = R_TPU_PIN_UNUSED;
283 p->timer_state = R_TPU_TIMER_UNUSED;
284 p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100;
285 r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF);
286 platform_set_drvdata(pdev, p);
287
288 INIT_WORK(&p->work, r_tpu_work);
289
290 p->ldev.name = cfg->name;
291 p->ldev.brightness = LED_OFF;
292 p->ldev.max_brightness = cfg->max_brightness;
293 p->ldev.brightness_set = r_tpu_set_brightness;
294 p->ldev.flags |= LED_CORE_SUSPENDRESUME;
295 ret = led_classdev_register(&pdev->dev, &p->ldev);
296 if (ret < 0)
297 goto err0;
298
299 /* max_brightness may be updated by the LED core code */
300 p->min_rate = p->ldev.max_brightness * p->refresh_rate;
301
302 pm_runtime_enable(&pdev->dev);
303 return 0;
304
305 err0:
306 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
307 return ret;
308}
309
310static int r_tpu_remove(struct platform_device *pdev)
311{
312 struct r_tpu_priv *p = platform_get_drvdata(pdev);
313
314 r_tpu_set_brightness(&p->ldev, LED_OFF);
315 led_classdev_unregister(&p->ldev);
316 cancel_work_sync(&p->work);
317 r_tpu_disable(p);
318 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
319
320 pm_runtime_disable(&pdev->dev);
321
322 return 0;
323}
324
325static struct platform_driver r_tpu_device_driver = {
326 .probe = r_tpu_probe,
327 .remove = r_tpu_remove,
328 .driver = {
329 .name = "leds-renesas-tpu",
330 }
331};
332
333module_platform_driver(r_tpu_device_driver);
334
335MODULE_AUTHOR("Magnus Damm");
336MODULE_DESCRIPTION("Renesas TPU LED Driver");
337MODULE_LICENSE("GPL v2");