From 52466277a4d2aeee2bb869e5391e3621fc75ef86 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Sun, 18 Mar 2012 18:32:46 +0100 Subject: [PATCH] LEDS: add initial support for WS2801 controller (PandaBoard) This adds initial support for the WS2801 RGB LED controller on the beaconboard for the Panda Board v2: - Make it compile on 3.2 and up Signed-off-by: Peter Huewe --- arch/arm/mach-omap2/board-omap4panda.c | 6 ++ drivers/leds/Kconfig | 6 ++ drivers/leds/Makefile | 1 + drivers/leds/leds-ws2801.c | 156 ++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 0 deletions(-) create mode 100644 drivers/leds/leds-ws2801.c diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 51b1c93..914b7d90 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -91,9 +91,15 @@ static struct platform_device leds_gpio = { }, }; +static struct platform_device ws2801_leds = { + .name = "ws2801-leds", + .id = -1, +}; + static struct platform_device *panda_devices[] __initdata = { &leds_gpio, &wl1271_device, + &ws2801_leds, }; static const struct usbhs_omap_board_data usbhs_bdata __initconst = { diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index ff203a4..7ac1cb5 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -298,6 +298,12 @@ config LEDS_BD2802 This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. +config LEDS_WS2801 + tristate "LED driver for WS2801 RGB LED" + depends on LEDS_CLASS + help + This option enables support for WS2801 RGB LED driver chips. + config LEDS_INTEL_SS4200 tristate "LED driver for Intel NAS SS4200 series" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index e4f6bf5..6bab3ad 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_WS2801) += leds-ws2801.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-ws2801.c b/drivers/leds/leds-ws2801.c new file mode 100644 index 0000000..4b226ca --- /dev/null +++ b/drivers/leds/leds-ws2801.c @@ -0,0 +1,156 @@ +/* + * LEDs driver for WS2801 RGB Controller + * + * Copyright (C) 2006 Kristian Kielhofner + * + * Based on leds-net48xx.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#define DRVNAME "ws2801-leds" +#define WS2801_LED_CLOCK_GPIO 135 +#define WS2801_LED_DATA_GPIO 136 + +static unsigned long rgb_color; + +static struct platform_device *pdev; + +static void ws2801_set_rgb(void) +{ + int count; + int color_bit; + + for (count = 23; count >= 0 ; count--) { + color_bit = (rgb_color>>count) & (1<<0); + gpio_set_value(WS2801_LED_DATA_GPIO, color_bit); + gpio_set_value(WS2801_LED_CLOCK_GPIO, 1); + gpio_set_value(WS2801_LED_CLOCK_GPIO, 0); + } + +} + +static void ws2801_red_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + rgb_color &= ((0x00<<16)|(0xff<<8)|(0xff<<0)); + rgb_color |= (value<<16); + ws2801_set_rgb(); +} + +static void ws2801_green_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + rgb_color &= ((0xff<<16)|(0x00<<8)|(0xff<<0)); + rgb_color |= (value<<8); + ws2801_set_rgb(); +} + +static void ws2801_blue_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + rgb_color &= ((0xff<<16)|(0xff<<8)|(0x00<<0)); + rgb_color |= (value<<0); + ws2801_set_rgb(); +} + +static struct led_classdev ws2801_red_led = { + .name = "ws2801-red", + .brightness_set = ws2801_red_led_set, + .flags = LED_CORE_SUSPENDRESUME, +}; + +static struct led_classdev ws2801_green_led = { + .name = "ws2801-green", + .brightness_set = ws2801_green_led_set, + .flags = LED_CORE_SUSPENDRESUME, +}; + +static struct led_classdev ws2801_blue_led = { + .name = "ws2801-blue", + .brightness_set = ws2801_blue_led_set, + .flags = LED_CORE_SUSPENDRESUME, +}; + +static int ws2801_led_probe(struct platform_device *pdev) +{ + int ret; + + ret = led_classdev_register(&pdev->dev, &ws2801_red_led); + if (ret < 0) + return ret; + + ret = led_classdev_register(&pdev->dev, &ws2801_green_led); + if (ret < 0) + goto err1; + + ret = led_classdev_register(&pdev->dev, &ws2801_blue_led); + if (ret < 0) + goto err2; + + gpio_request_one(WS2801_LED_DATA_GPIO, + GPIOF_OUT_INIT_LOW, "ws2801_data"); + + gpio_request_one(WS2801_LED_CLOCK_GPIO, + GPIOF_OUT_INIT_LOW, "ws2801_clock"); + + ws2801_set_rgb(); + return ret; + +err2: + led_classdev_unregister(&ws2801_green_led); +err1: + led_classdev_unregister(&ws2801_red_led); + + return ret; +} + +static int ws2801_led_remove(struct platform_device *pdev) +{ + led_classdev_unregister(&ws2801_red_led); + led_classdev_unregister(&ws2801_green_led); + led_classdev_unregister(&ws2801_blue_led); + return 0; +} + +static struct platform_driver ws2801_led_driver = { + .probe = ws2801_led_probe, + .remove = ws2801_led_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init ws2801_led_init(void) +{ + int ret; + + ret = platform_driver_register(&ws2801_led_driver); + if (ret < 0) + goto out; + +out: + return ret; +} + +static void __exit ws2801_led_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&ws2801_led_driver); +} + +module_init(ws2801_led_init); +module_exit(ws2801_led_exit); + +MODULE_AUTHOR("David Anders "); +MODULE_DESCRIPTION("WS2801 RGB LED driver"); +MODULE_LICENSE("GPL"); + -- 1.7.3.4