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