Blame view
drivers/leds/leds-versatile.c
2.47 KB
b5417019a ARM: 6235/2: driv... |
1 2 3 4 5 6 7 8 9 |
/* * Driver for the 8 user LEDs found on the RealViews and Versatiles * Based on DaVinci's DM365 board code * * License terms: GNU General Public License (GPL) version 2 * Author: Linus Walleij <triad@df.lth.se> */ #include <linux/kernel.h> #include <linux/init.h> |
e4ecf2bda ARM: plat-versati... |
10 |
#include <linux/module.h> |
b5417019a ARM: 6235/2: driv... |
11 12 13 |
#include <linux/io.h> #include <linux/slab.h> #include <linux/leds.h> |
e4ecf2bda ARM: plat-versati... |
14 |
#include <linux/platform_device.h> |
b5417019a ARM: 6235/2: driv... |
15 16 |
struct versatile_led { |
e4ecf2bda ARM: plat-versati... |
17 |
void __iomem *base; |
b5417019a ARM: 6235/2: driv... |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
struct led_classdev cdev; u8 mask; }; /* * The triggers lines up below will only be used if the * LED triggers are compiled in. */ static const struct { const char *name; const char *trigger; } versatile_leds[] = { { "versatile:0", "heartbeat", }, { "versatile:1", "mmc0", }, |
e031cd513 ARM: mach-realvie... |
32 33 34 35 |
{ "versatile:2", "cpu0" }, { "versatile:3", "cpu1" }, { "versatile:4", "cpu2" }, { "versatile:5", "cpu3" }, |
b5417019a ARM: 6235/2: driv... |
36 37 38 39 40 41 42 43 44 |
{ "versatile:6", }, { "versatile:7", }, }; static void versatile_led_set(struct led_classdev *cdev, enum led_brightness b) { struct versatile_led *led = container_of(cdev, struct versatile_led, cdev); |
e4ecf2bda ARM: plat-versati... |
45 |
u32 reg = readl(led->base); |
b5417019a ARM: 6235/2: driv... |
46 47 48 49 50 |
if (b != LED_OFF) reg |= led->mask; else reg &= ~led->mask; |
e4ecf2bda ARM: plat-versati... |
51 |
writel(reg, led->base); |
b5417019a ARM: 6235/2: driv... |
52 53 54 55 56 57 |
} static enum led_brightness versatile_led_get(struct led_classdev *cdev) { struct versatile_led *led = container_of(cdev, struct versatile_led, cdev); |
e4ecf2bda ARM: plat-versati... |
58 |
u32 reg = readl(led->base); |
b5417019a ARM: 6235/2: driv... |
59 60 61 |
return (reg & led->mask) ? LED_FULL : LED_OFF; } |
e4ecf2bda ARM: plat-versati... |
62 |
static int versatile_leds_probe(struct platform_device *dev) |
b5417019a ARM: 6235/2: driv... |
63 64 |
{ int i; |
e4ecf2bda ARM: plat-versati... |
65 66 67 68 69 70 71 |
struct resource *res; void __iomem *base; res = platform_get_resource(dev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); |
b5417019a ARM: 6235/2: driv... |
72 |
|
d1cb3ecf3 ARM: plat-versati... |
73 |
/* All off */ |
e4ecf2bda ARM: plat-versati... |
74 |
writel(0, base); |
b5417019a ARM: 6235/2: driv... |
75 76 77 78 79 80 |
for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { struct versatile_led *led; led = kzalloc(sizeof(*led), GFP_KERNEL); if (!led) break; |
e4ecf2bda ARM: plat-versati... |
81 |
led->base = base; |
b5417019a ARM: 6235/2: driv... |
82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
led->cdev.name = versatile_leds[i].name; led->cdev.brightness_set = versatile_led_set; led->cdev.brightness_get = versatile_led_get; led->cdev.default_trigger = versatile_leds[i].trigger; led->mask = BIT(i); if (led_classdev_register(NULL, &led->cdev) < 0) { kfree(led); break; } } return 0; } |
e4ecf2bda ARM: plat-versati... |
96 97 98 99 100 101 102 103 104 105 106 107 |
static struct platform_driver versatile_leds_driver = { .driver = { .name = "versatile-leds", }, .probe = versatile_leds_probe, }; module_platform_driver(versatile_leds_driver); MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); MODULE_DESCRIPTION("ARM Versatile LED driver"); MODULE_LICENSE("GPL v2"); |