lkml.org 
[lkml]   [2012]   [Jan]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v2] add led driver for Bachmann's ot200
     From a7fecf3426ef98fdd19e9d2610665b9d1ce358a0 Mon Sep 17 00:00:00 2001
    From: Sebastian Andrzej Siewior <bigeasy@linutronix.de
    <mailto:bigeasy@linutronix.de>>
    Date: Mon, 9 Jan 2012 10:09:50 +0100
    Subject: [PATCH v2] add led driver for Bachmann's ot200

    This patch adds support for leds on Bachmann's ot200 visualisation device.
    The device has three leds on the back panel (led_err, led_init and led_run)
    and can handle up to seven leds on the front panel.

    The driver was written by Linutronix on behalf of
    Bachmann electronic GmbH.

    Changes in v2:
    - *incorporated* feedback from Andrew Morton and Lars-Peter Clausen

    Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de
    <mailto:bigeasy@linutronix.de>>
    Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com
    <mailto:christian.gmeiner@gmail.com>>
    ---
    drivers/leds/Kconfig | 7 ++
    drivers/leds/Makefile | 1 +
    drivers/leds/leds-ot200.c | 177
    +++++++++++++++++++++++++++++++++++++++++++++
    3 files changed, 185 insertions(+), 0 deletions(-)
    create mode 100644 drivers/leds/leds-ot200.c

    diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
    index ff203a4..71cb89b 100644
    --- a/drivers/leds/Kconfig
    +++ b/drivers/leds/Kconfig
    @@ -387,6 +387,13 @@ config LEDS_RENESAS_TPU
    pin function. The latter to support brightness control.
    Brightness control is supported but hardware blinking is not.

    +config LEDS_OT200
    + tristate "LED support for the Bachmann OT200"
    + depends on LEDS_CLASS
    + help
    + This option enables support for the LEDs on the Bachmann OT200.
    + Say Y to enable LEDs on the Bachmann OT200.
    +
    config LEDS_TRIGGERS
    bool "LED Trigger support"
    depends on LEDS_CLASS
    diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
    index e4f6bf5..0814d42 100644
    --- a/drivers/leds/Makefile
    +++ b/drivers/leds/Makefile
    @@ -43,6 +43,7 @@ obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
    obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
    obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
    obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
    +obj-$(CONFIG_LEDS_OT200) += leds-ot200.o

    # LED SPI Drivers
    obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
    diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
    new file mode 100644
    index 0000000..4d000ac
    --- /dev/null
    +++ b/drivers/leds/leds-ot200.c
    @@ -0,0 +1,177 @@
    +/*
    + * Bachmann ot200 leds driver.
    + *
    + * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    + * Christian Gmeiner <christian.gmeiner@gmail.com>
    + *
    + * License: GPL as published by the FSF.
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/init.h>
    +#include <linux/platform_device.h>
    +#include <linux/slab.h>
    +#include <linux/leds.h>
    +#include <linux/io.h>
    +#include <linux/module.h>
    +
    +
    +struct ot200_led {
    + struct led_classdev cdev;
    + const char *name;
    + unsigned long port;
    + u8 mask;
    +};
    +
    +/*
    + * The device has three leds on the back panel (led_err, led_init and
    led_run)
    + * and can handle up to seven leds on the front panel.
    + */
    +
    +static struct ot200_led leds[] = {
    + {
    + .name = "led_run",
    + .port = 0x5a,
    + .mask = BIT(0),
    + },
    + {
    + .name = "led_init",
    + .port = 0x5a,
    + .mask = BIT(1),
    + },
    + {
    + .name = "led_err",
    + .port = 0x5a,
    + .mask = BIT(2),
    + },
    + {
    + .name = "led_1",
    + .port = 0x49,
    + .mask = BIT(7),
    + },
    + {
    + .name = "led_2",
    + .port = 0x49,
    + .mask = BIT(6),
    + },
    + {
    + .name = "led_3",
    + .port = 0x49,
    + .mask = BIT(5),
    + },
    + {
    + .name = "led_4",
    + .port = 0x49,
    + .mask = BIT(4),
    + },
    + {
    + .name = "led_5",
    + .port = 0x49,
    + .mask = BIT(3),
    + },
    + {
    + .name = "led_6",
    + .port = 0x49,
    + .mask = BIT(2),
    + },
    + {
    + .name = "led_7",
    + .port = 0x49,
    + .mask = BIT(1),
    + }
    +};
    +
    +static DEFINE_SPINLOCK(value_lock);
    +
    +/*
    + * we need to store the current led states, as it is not
    + * possible to read the current led state via inb().
    + */
    +static u8 leds_back;
    +static u8 leds_front;
    +
    +static void ot200_led_brightness_set(struct led_classdev *led_cdev,
    + enum led_brightness value)
    +{
    + struct ot200_led *led = container_of(led_cdev, struct ot200_led, cdev);
    + u8 *val;
    + unsigned long flags;
    +
    + spin_lock_irqsave(&value_lock, flags);
    +
    + if (led->port == 0x49)
    + val = &leds_front;
    + else if (led->port == 0x5a)
    + val = &leds_back;
    + else
    + BUG();
    +
    + if (value == LED_OFF)
    + *val &= ~led->mask;
    + else
    + *val |= led->mask;
    +
    + outb(*val, led->port);
    + spin_unlock_irqrestore(&value_lock, flags);
    +}
    +
    +static int __devinit ot200_led_probe(struct platform_device *pdev)
    +{
    + int i;
    + int ret;
    +
    + for (i = 0; i < ARRAY_SIZE(leds); i++) {
    +
    + leds[i].cdev.name = leds[i].name;
    + leds[i].cdev.default_trigger = NULL;
    + leds[i].cdev.blink_set = NULL;
    + leds[i].cdev.brightness_set = ot200_led_brightness_set;
    +
    + ret = led_classdev_register(&pdev->dev, &leds[i].cdev);
    + if (ret < 0)
    + goto err;
    +
    + dev_set_drvdata(leds[i].cdev.dev, &leds[i]);
    + }
    +
    + platform_set_drvdata(pdev, leds);
    +
    + outb(0x0, 0x49); /* turn off all front leds */
    + outb(0x2, 0x5a); /* turn on init led */
    + leds_front = 0;
    + leds_back = BIT(1);
    +
    + return 0;
    +
    +err:
    + for (i = i - 1; i >= 0; i--)
    + led_classdev_unregister(&leds[i].cdev);
    +
    + return ret;
    +}
    +
    +static int __devexit ot200_led_remove(struct platform_device *pdev)
    +{
    + int i;
    +
    + for (i = 0; i < ARRAY_SIZE(leds); i++)
    + led_classdev_unregister(&leds[i].cdev);
    +
    + return 0;
    +}
    +
    +static struct platform_driver ot200_led_driver = {
    + .probe = ot200_led_probe,
    + .remove = __devexit_p(ot200_led_remove),
    + .driver = {
    + .name = "leds-ot200",
    + .owner = THIS_MODULE,
    + },
    +};
    +
    +module_platform_driver(ot200_led_driver);
    +
    +MODULE_AUTHOR("Sebastian A. Siewior <bigeasy@linutronix.de>");
    +MODULE_DESCRIPTION("ot200 LED driver");
    +MODULE_LICENSE("GPL");
    +MODULE_ALIAS("platform:leds-ot200");
    --
    1.7.5.4


    \
     
     \ /
      Last update: 2012-01-09 11:23    [W:0.030 / U:58.876 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site