linux/drivers/leds/leds-fsg.c
<<
>>
Prefs
   1/*
   2 * LED Driver for the Freecom FSG-3
   3 *
   4 * Copyright (c) 2008 Rod Whitby <rod@whitby.id.au>
   5 *
   6 * Author: Rod Whitby <rod@whitby.id.au>
   7 *
   8 * Based on leds-spitz.c
   9 * Copyright 2005-2006 Openedhand Ltd.
  10 * Author: Richard Purdie <rpurdie@openedhand.com>
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License version 2 as
  14 * published by the Free Software Foundation.
  15 *
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/init.h>
  20#include <linux/platform_device.h>
  21#include <linux/leds.h>
  22#include <linux/module.h>
  23#include <mach/hardware.h>
  24#include <asm/io.h>
  25
  26#define FSG_LED_WLAN_BIT        0
  27#define FSG_LED_WAN_BIT         1
  28#define FSG_LED_SATA_BIT        2
  29#define FSG_LED_USB_BIT         4
  30#define FSG_LED_RING_BIT        5
  31#define FSG_LED_SYNC_BIT        7
  32
  33static short __iomem *latch_address;
  34static unsigned short latch_value;
  35
  36
  37static void fsg_led_wlan_set(struct led_classdev *led_cdev,
  38                             enum led_brightness value)
  39{
  40        if (value) {
  41                latch_value &= ~(1 << FSG_LED_WLAN_BIT);
  42                *latch_address = latch_value;
  43        } else {
  44                latch_value |=  (1 << FSG_LED_WLAN_BIT);
  45                *latch_address = latch_value;
  46        }
  47}
  48
  49static void fsg_led_wan_set(struct led_classdev *led_cdev,
  50                            enum led_brightness value)
  51{
  52        if (value) {
  53                latch_value &= ~(1 << FSG_LED_WAN_BIT);
  54                *latch_address = latch_value;
  55        } else {
  56                latch_value |=  (1 << FSG_LED_WAN_BIT);
  57                *latch_address = latch_value;
  58        }
  59}
  60
  61static void fsg_led_sata_set(struct led_classdev *led_cdev,
  62                             enum led_brightness value)
  63{
  64        if (value) {
  65                latch_value &= ~(1 << FSG_LED_SATA_BIT);
  66                *latch_address = latch_value;
  67        } else {
  68                latch_value |=  (1 << FSG_LED_SATA_BIT);
  69                *latch_address = latch_value;
  70        }
  71}
  72
  73static void fsg_led_usb_set(struct led_classdev *led_cdev,
  74                            enum led_brightness value)
  75{
  76        if (value) {
  77                latch_value &= ~(1 << FSG_LED_USB_BIT);
  78                *latch_address = latch_value;
  79        } else {
  80                latch_value |=  (1 << FSG_LED_USB_BIT);
  81                *latch_address = latch_value;
  82        }
  83}
  84
  85static void fsg_led_sync_set(struct led_classdev *led_cdev,
  86                             enum led_brightness value)
  87{
  88        if (value) {
  89                latch_value &= ~(1 << FSG_LED_SYNC_BIT);
  90                *latch_address = latch_value;
  91        } else {
  92                latch_value |=  (1 << FSG_LED_SYNC_BIT);
  93                *latch_address = latch_value;
  94        }
  95}
  96
  97static void fsg_led_ring_set(struct led_classdev *led_cdev,
  98                             enum led_brightness value)
  99{
 100        if (value) {
 101                latch_value &= ~(1 << FSG_LED_RING_BIT);
 102                *latch_address = latch_value;
 103        } else {
 104                latch_value |=  (1 << FSG_LED_RING_BIT);
 105                *latch_address = latch_value;
 106        }
 107}
 108
 109
 110static struct led_classdev fsg_wlan_led = {
 111        .name                   = "fsg:blue:wlan",
 112        .brightness_set         = fsg_led_wlan_set,
 113        .flags                  = LED_CORE_SUSPENDRESUME,
 114};
 115
 116static struct led_classdev fsg_wan_led = {
 117        .name                   = "fsg:blue:wan",
 118        .brightness_set         = fsg_led_wan_set,
 119        .flags                  = LED_CORE_SUSPENDRESUME,
 120};
 121
 122static struct led_classdev fsg_sata_led = {
 123        .name                   = "fsg:blue:sata",
 124        .brightness_set         = fsg_led_sata_set,
 125        .flags                  = LED_CORE_SUSPENDRESUME,
 126};
 127
 128static struct led_classdev fsg_usb_led = {
 129        .name                   = "fsg:blue:usb",
 130        .brightness_set         = fsg_led_usb_set,
 131        .flags                  = LED_CORE_SUSPENDRESUME,
 132};
 133
 134static struct led_classdev fsg_sync_led = {
 135        .name                   = "fsg:blue:sync",
 136        .brightness_set         = fsg_led_sync_set,
 137        .flags                  = LED_CORE_SUSPENDRESUME,
 138};
 139
 140static struct led_classdev fsg_ring_led = {
 141        .name                   = "fsg:blue:ring",
 142        .brightness_set         = fsg_led_ring_set,
 143        .flags                  = LED_CORE_SUSPENDRESUME,
 144};
 145
 146
 147static int fsg_led_probe(struct platform_device *pdev)
 148{
 149        int ret;
 150
 151        /* Map the LED chip select address space */
 152        latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
 153        if (!latch_address) {
 154                ret = -ENOMEM;
 155                goto failremap;
 156        }
 157
 158        latch_value = 0xffff;
 159        *latch_address = latch_value;
 160
 161        ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
 162        if (ret < 0)
 163                goto failwlan;
 164
 165        ret = led_classdev_register(&pdev->dev, &fsg_wan_led);
 166        if (ret < 0)
 167                goto failwan;
 168
 169        ret = led_classdev_register(&pdev->dev, &fsg_sata_led);
 170        if (ret < 0)
 171                goto failsata;
 172
 173        ret = led_classdev_register(&pdev->dev, &fsg_usb_led);
 174        if (ret < 0)
 175                goto failusb;
 176
 177        ret = led_classdev_register(&pdev->dev, &fsg_sync_led);
 178        if (ret < 0)
 179                goto failsync;
 180
 181        ret = led_classdev_register(&pdev->dev, &fsg_ring_led);
 182        if (ret < 0)
 183                goto failring;
 184
 185        return ret;
 186
 187 failring:
 188        led_classdev_unregister(&fsg_sync_led);
 189 failsync:
 190        led_classdev_unregister(&fsg_usb_led);
 191 failusb:
 192        led_classdev_unregister(&fsg_sata_led);
 193 failsata:
 194        led_classdev_unregister(&fsg_wan_led);
 195 failwan:
 196        led_classdev_unregister(&fsg_wlan_led);
 197 failwlan:
 198        iounmap(latch_address);
 199 failremap:
 200
 201        return ret;
 202}
 203
 204static int fsg_led_remove(struct platform_device *pdev)
 205{
 206        led_classdev_unregister(&fsg_wlan_led);
 207        led_classdev_unregister(&fsg_wan_led);
 208        led_classdev_unregister(&fsg_sata_led);
 209        led_classdev_unregister(&fsg_usb_led);
 210        led_classdev_unregister(&fsg_sync_led);
 211        led_classdev_unregister(&fsg_ring_led);
 212
 213        iounmap(latch_address);
 214
 215        return 0;
 216}
 217
 218
 219static struct platform_driver fsg_led_driver = {
 220        .probe          = fsg_led_probe,
 221        .remove         = fsg_led_remove,
 222        .driver         = {
 223                .name           = "fsg-led",
 224        },
 225};
 226
 227module_platform_driver(fsg_led_driver);
 228
 229MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
 230MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
 231MODULE_LICENSE("GPL");
 232
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.