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 <linux/io.h>
  24#include <mach/hardware.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 *) devm_ioremap(&pdev->dev,
 153                                                IXP4XX_EXP_BUS_BASE(2), 512);
 154        if (!latch_address)
 155                return -ENOMEM;
 156
 157        latch_value = 0xffff;
 158        *latch_address = latch_value;
 159
 160        ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
 161        if (ret < 0)
 162                goto failwlan;
 163
 164        ret = led_classdev_register(&pdev->dev, &fsg_wan_led);
 165        if (ret < 0)
 166                goto failwan;
 167
 168        ret = led_classdev_register(&pdev->dev, &fsg_sata_led);
 169        if (ret < 0)
 170                goto failsata;
 171
 172        ret = led_classdev_register(&pdev->dev, &fsg_usb_led);
 173        if (ret < 0)
 174                goto failusb;
 175
 176        ret = led_classdev_register(&pdev->dev, &fsg_sync_led);
 177        if (ret < 0)
 178                goto failsync;
 179
 180        ret = led_classdev_register(&pdev->dev, &fsg_ring_led);
 181        if (ret < 0)
 182                goto failring;
 183
 184        return ret;
 185
 186 failring:
 187        led_classdev_unregister(&fsg_sync_led);
 188 failsync:
 189        led_classdev_unregister(&fsg_usb_led);
 190 failusb:
 191        led_classdev_unregister(&fsg_sata_led);
 192 failsata:
 193        led_classdev_unregister(&fsg_wan_led);
 194 failwan:
 195        led_classdev_unregister(&fsg_wlan_led);
 196 failwlan:
 197
 198        return ret;
 199}
 200
 201static int fsg_led_remove(struct platform_device *pdev)
 202{
 203        led_classdev_unregister(&fsg_wlan_led);
 204        led_classdev_unregister(&fsg_wan_led);
 205        led_classdev_unregister(&fsg_sata_led);
 206        led_classdev_unregister(&fsg_usb_led);
 207        led_classdev_unregister(&fsg_sync_led);
 208        led_classdev_unregister(&fsg_ring_led);
 209
 210        return 0;
 211}
 212
 213
 214static struct platform_driver fsg_led_driver = {
 215        .probe          = fsg_led_probe,
 216        .remove         = fsg_led_remove,
 217        .driver         = {
 218                .name           = "fsg-led",
 219        },
 220};
 221
 222module_platform_driver(fsg_led_driver);
 223
 224MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
 225MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
 226MODULE_LICENSE("GPL");
 227
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.