linux/arch/arm/plat-versatile/leds.c
<<
>>
Prefs
   1/*
   2 * Driver for the 8 user LEDs found on the RealViews and Versatiles
   3 * Based on DaVinci's DM365 board code
   4 *
   5 * License terms: GNU General Public License (GPL) version 2
   6 * Author: Linus Walleij <triad@df.lth.se>
   7 */
   8#include <linux/kernel.h>
   9#include <linux/init.h>
  10#include <linux/io.h>
  11#include <linux/slab.h>
  12#include <linux/leds.h>
  13
  14#include <mach/hardware.h>
  15#include <mach/platform.h>
  16
  17#ifdef VERSATILE_SYS_BASE
  18#define LEDREG  (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
  19#endif
  20
  21#ifdef REALVIEW_SYS_BASE
  22#define LEDREG  (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
  23#endif
  24
  25struct versatile_led {
  26        struct led_classdev     cdev;
  27        u8                      mask;
  28};
  29
  30/*
  31 * The triggers lines up below will only be used if the
  32 * LED triggers are compiled in.
  33 */
  34static const struct {
  35        const char *name;
  36        const char *trigger;
  37} versatile_leds[] = {
  38        { "versatile:0", "heartbeat", },
  39        { "versatile:1", "mmc0", },
  40        { "versatile:2", "cpu0" },
  41        { "versatile:3", "cpu1" },
  42        { "versatile:4", "cpu2" },
  43        { "versatile:5", "cpu3" },
  44        { "versatile:6", },
  45        { "versatile:7", },
  46};
  47
  48static void versatile_led_set(struct led_classdev *cdev,
  49                              enum led_brightness b)
  50{
  51        struct versatile_led *led = container_of(cdev,
  52                                                 struct versatile_led, cdev);
  53        u32 reg = readl(LEDREG);
  54
  55        if (b != LED_OFF)
  56                reg |= led->mask;
  57        else
  58                reg &= ~led->mask;
  59        writel(reg, LEDREG);
  60}
  61
  62static enum led_brightness versatile_led_get(struct led_classdev *cdev)
  63{
  64        struct versatile_led *led = container_of(cdev,
  65                                                 struct versatile_led, cdev);
  66        u32 reg = readl(LEDREG);
  67
  68        return (reg & led->mask) ? LED_FULL : LED_OFF;
  69}
  70
  71static int __init versatile_leds_init(void)
  72{
  73        int i;
  74
  75        /* All ON */
  76        writel(0xff, LEDREG);
  77        for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) {
  78                struct versatile_led *led;
  79
  80                led = kzalloc(sizeof(*led), GFP_KERNEL);
  81                if (!led)
  82                        break;
  83
  84                led->cdev.name = versatile_leds[i].name;
  85                led->cdev.brightness_set = versatile_led_set;
  86                led->cdev.brightness_get = versatile_led_get;
  87                led->cdev.default_trigger = versatile_leds[i].trigger;
  88                led->mask = BIT(i);
  89
  90                if (led_classdev_register(NULL, &led->cdev) < 0) {
  91                        kfree(led);
  92                        break;
  93                }
  94        }
  95
  96        return 0;
  97}
  98
  99/*
 100 * Since we may have triggers on any subsystem, defer registration
 101 * until after subsystem_init.
 102 */
 103fs_initcall(versatile_leds_init);
 104