linux/arch/arm/mach-shark/leds.c
<<
>>
Prefs
   1/*
   2 * DIGITAL Shark LED control routines.
   3 *
   4 * Driver for the 3 user LEDs found on the Shark
   5 * Based on Versatile and RealView machine LED code
   6 *
   7 * License terms: GNU General Public License (GPL) version 2
   8 * Author: Bryan Wu <bryan.wu@canonical.com>
   9 */
  10#include <linux/kernel.h>
  11#include <linux/init.h>
  12#include <linux/io.h>
  13#include <linux/ioport.h>
  14#include <linux/slab.h>
  15#include <linux/leds.h>
  16
  17#include <asm/mach-types.h>
  18
  19#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
  20struct shark_led {
  21        struct led_classdev cdev;
  22        u8 mask;
  23};
  24
  25/*
  26 * The triggers lines up below will only be used if the
  27 * LED triggers are compiled in.
  28 */
  29static const struct {
  30        const char *name;
  31        const char *trigger;
  32} shark_leds[] = {
  33        { "shark:amber0", "default-on", },      /* Bit 5 */
  34        { "shark:green", "heartbeat", },        /* Bit 6 */
  35        { "shark:amber1", "cpu0" },             /* Bit 7 */
  36};
  37
  38static u16 led_reg_read(void)
  39{
  40        outw(0x09, 0x24);
  41        return inw(0x26);
  42}
  43
  44static void led_reg_write(u16 value)
  45{
  46        outw(0x09, 0x24);
  47        outw(value, 0x26);
  48}
  49
  50static void shark_led_set(struct led_classdev *cdev,
  51                              enum led_brightness b)
  52{
  53        struct shark_led *led = container_of(cdev,
  54                                                 struct shark_led, cdev);
  55        u16 reg = led_reg_read();
  56
  57        if (b != LED_OFF)
  58                reg |= led->mask;
  59        else
  60                reg &= ~led->mask;
  61
  62        led_reg_write(reg);
  63}
  64
  65static enum led_brightness shark_led_get(struct led_classdev *cdev)
  66{
  67        struct shark_led *led = container_of(cdev,
  68                                                 struct shark_led, cdev);
  69        u16 reg = led_reg_read();
  70
  71        return (reg & led->mask) ? LED_FULL : LED_OFF;
  72}
  73
  74static int __init shark_leds_init(void)
  75{
  76        int i;
  77        u16 reg;
  78
  79        if (!machine_is_shark())
  80                return -ENODEV;
  81
  82        for (i = 0; i < ARRAY_SIZE(shark_leds); i++) {
  83                struct shark_led *led;
  84
  85                led = kzalloc(sizeof(*led), GFP_KERNEL);
  86                if (!led)
  87                        break;
  88
  89                led->cdev.name = shark_leds[i].name;
  90                led->cdev.brightness_set = shark_led_set;
  91                led->cdev.brightness_get = shark_led_get;
  92                led->cdev.default_trigger = shark_leds[i].trigger;
  93
  94                /* Count in 5 bits offset */
  95                led->mask = BIT(i + 5);
  96
  97                if (led_classdev_register(NULL, &led->cdev) < 0) {
  98                        kfree(led);
  99                        break;
 100                }
 101        }
 102
 103        /* Make LEDs independent of power-state */
 104        request_region(0x24, 4, "led_reg");
 105        reg = led_reg_read();
 106        reg |= 1 << 10;
 107        led_reg_write(reg);
 108
 109        return 0;
 110}
 111
 112/*
 113 * Since we may have triggers on any subsystem, defer registration
 114 * until after subsystem_init.
 115 */
 116fs_initcall(shark_leds_init);
 117#endif
 118