9a18e7d3a64b69fe66fb20d0761bea3a7e61fdc2
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-3.0 / ulcd / 0002-LEDS-add-initial-support-for-WS2801-controller.patch
1 From 846578cb98e201d771098968c7022a125cb6bb07 Mon Sep 17 00:00:00 2001
2 From: David Anders <x0132446@ti.com>
3 Date: Mon, 22 Aug 2011 11:00:38 -0500
4 Subject: [PATCH 2/2] LEDS: add initial support for WS2801 controller
6 This adds initial support for the WS2801 RGB LED controller.
8 Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
9 ---
10 arch/arm/mach-omap2/board-omap3beagle.c | 11 ++
11 drivers/leds/Kconfig | 6 +
12 drivers/leds/Makefile | 1 +
13 drivers/leds/leds-ws2801.c | 159 +++++++++++++++++++++++++++++++
14 4 files changed, 177 insertions(+), 0 deletions(-)
15 create mode 100644 drivers/leds/leds-ws2801.c
17 diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
18 index 787891d..0e73089 100644
19 --- a/arch/arm/mach-omap2/board-omap3beagle.c
20 +++ b/arch/arm/mach-omap2/board-omap3beagle.c
21 @@ -802,6 +802,11 @@ static struct platform_device leds_gpio = {
22 },
23 };
25 +static struct platform_device ws2801_leds = {
26 + .name = "ws2801-leds",
27 + .id = -1,
28 +};
29 +
30 static struct gpio_keys_button gpio_buttons[] = {
31 {
32 .code = BTN_EXTRA,
33 @@ -1018,6 +1023,12 @@ static void __init omap3_beagle_init(void)
34 lcd_panel.name = beagle_config.lcd_driver_name;
35 }
37 + if(!strcmp(expansionboard_name, "beacon"))
38 + {
39 + printk(KERN_INFO "Beagle expansionboard: registering TinCanTools Beacon LED driver\n");
40 + platform_device_register(&ws2801_leds);
41 + }
42 +
43 usb_musb_init(NULL);
44 usbhs_init(&usbhs_bdata);
45 omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
46 diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
47 index 713d43b..fd2c4b3 100644
48 --- a/drivers/leds/Kconfig
49 +++ b/drivers/leds/Kconfig
50 @@ -323,6 +323,12 @@ config LEDS_BD2802
51 This option enables support for BD2802GU RGB LED driver chips
52 accessed via the I2C bus.
54 +config LEDS_WS2801
55 + tristate "LED driver for WS2801 RGB LED"
56 + depends on LEDS_CLASS
57 + help
58 + This option enables support for WS2801 RGB LED driver chips.
59 +
60 config LEDS_INTEL_SS4200
61 tristate "LED driver for Intel NAS SS4200 series"
62 depends on LEDS_CLASS
63 diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
64 index bbfd2e3..14f849e 100644
65 --- a/drivers/leds/Makefile
66 +++ b/drivers/leds/Makefile
67 @@ -43,6 +43,7 @@ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
68 obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
69 obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
70 obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
71 +obj-$(CONFIG_LEDS_WS2801) += leds-ws2801.o
73 # LED SPI Drivers
74 obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
75 diff --git a/drivers/leds/leds-ws2801.c b/drivers/leds/leds-ws2801.c
76 new file mode 100644
77 index 0000000..17d0666
78 --- /dev/null
79 +++ b/drivers/leds/leds-ws2801.c
80 @@ -0,0 +1,159 @@
81 +/*
82 + * LEDs driver for WS2801 RGB Controller
83 + *
84 + * Copyright (C) 2006 Kristian Kielhofner <kris@krisk.org>
85 + *
86 + * Based on leds-net48xx.c
87 + *
88 + * This program is free software; you can redistribute it and/or modify
89 + * it under the terms of the GNU General Public License version 2 as
90 + * published by the Free Software Foundation.
91 + */
92 +
93 +#include <linux/kernel.h>
94 +#include <linux/init.h>
95 +#include <linux/platform_device.h>
96 +#include <linux/leds.h>
97 +#include <linux/err.h>
98 +#include <linux/gpio.h>
99 +#include <linux/io.h>
100 +
101 +#define DRVNAME "ws2801-leds"
102 +#define WS2801_LED_CLOCK_GPIO 159
103 +#define WS2801_LED_DATA_GPIO 158
104 +
105 +static unsigned long rgb_color;
106 +
107 +static struct platform_device *pdev;
108 +
109 +static void ws2801_set_rgb(void)
110 +{
111 + int count;
112 + int color_bit;
113 +
114 + for (count = 23; count >= 0 ; count--) {
115 + color_bit = (rgb_color>>count) & (1<<0);
116 + gpio_set_value(WS2801_LED_DATA_GPIO, color_bit);
117 + gpio_set_value(WS2801_LED_CLOCK_GPIO, 1);
118 + gpio_set_value(WS2801_LED_CLOCK_GPIO, 0);
119 + }
120 +
121 +}
122 +
123 +static void ws2801_red_led_set(struct led_classdev *led_cdev,
124 + enum led_brightness value)
125 +{
126 + rgb_color &= ((0x00<<16)|(0xff<<8)|(0xff<<0));
127 + rgb_color |= (value<<16);
128 + ws2801_set_rgb();
129 +}
130 +
131 +static void ws2801_green_led_set(struct led_classdev *led_cdev,
132 + enum led_brightness value)
133 +{
134 + rgb_color &= ((0xff<<16)|(0x00<<8)|(0xff<<0));
135 + rgb_color |= (value<<8);
136 + ws2801_set_rgb();
137 +}
138 +
139 +static void ws2801_blue_led_set(struct led_classdev *led_cdev,
140 + enum led_brightness value)
141 +{
142 + rgb_color &= ((0xff<<16)|(0xff<<8)|(0x00<<0));
143 + rgb_color |= (value<<0);
144 + ws2801_set_rgb();
145 +}
146 +
147 +static struct led_classdev ws2801_red_led = {
148 + .name = "ws2801-red",
149 + .brightness_set = ws2801_red_led_set,
150 + .flags = LED_CORE_SUSPENDRESUME,
151 +};
152 +
153 +static struct led_classdev ws2801_green_led = {
154 + .name = "ws2801-green",
155 + .brightness_set = ws2801_green_led_set,
156 + .flags = LED_CORE_SUSPENDRESUME,
157 +};
158 +
159 +static struct led_classdev ws2801_blue_led = {
160 + .name = "ws2801-blue",
161 + .brightness_set = ws2801_blue_led_set,
162 + .flags = LED_CORE_SUSPENDRESUME,
163 +};
164 +
165 +static int ws2801_led_probe(struct platform_device *pdev)
166 +{
167 + int ret;
168 +
169 + ret = led_classdev_register(&pdev->dev, &ws2801_red_led);
170 + if (ret < 0)
171 + return ret;
172 +
173 + ret = led_classdev_register(&pdev->dev, &ws2801_green_led);
174 + if (ret < 0)
175 + goto err1;
176 +
177 + ret = led_classdev_register(&pdev->dev, &ws2801_blue_led);
178 + if (ret < 0)
179 + goto err2;
180 +
181 + gpio_request_one(WS2801_LED_DATA_GPIO,
182 + GPIOF_OUT_INIT_LOW, "ws2801_data");
183 +
184 + gpio_request_one(WS2801_LED_CLOCK_GPIO,
185 + GPIOF_OUT_INIT_LOW, "ws2801_clock");
186 +
187 + ws2801_set_rgb();
188 + return ret;
189 +
190 +err2:
191 + led_classdev_unregister(&ws2801_green_led);
192 +err1:
193 + led_classdev_unregister(&ws2801_red_led);
194 +
195 + return ret;
196 +}
197 +
198 +static int ws2801_led_remove(struct platform_device *pdev)
199 +{
200 + led_classdev_unregister(&ws2801_red_led);
201 + led_classdev_unregister(&ws2801_green_led);
202 + led_classdev_unregister(&ws2801_blue_led);
203 + return 0;
204 +}
205 +
206 +static struct platform_driver ws2801_led_driver = {
207 + .probe = ws2801_led_probe,
208 + .remove = ws2801_led_remove,
209 + .driver = {
210 + .name = DRVNAME,
211 + .owner = THIS_MODULE,
212 + },
213 +};
214 +
215 +static int __init ws2801_led_init(void)
216 +{
217 + int ret;
218 +
219 + ret = platform_driver_register(&ws2801_led_driver);
220 + if (ret < 0)
221 + goto out;
222 +
223 +out:
224 + return ret;
225 +}
226 +
227 +static void __exit ws2801_led_exit(void)
228 +{
229 + platform_device_unregister(pdev);
230 + platform_driver_unregister(&ws2801_led_driver);
231 +}
232 +
233 +module_init(ws2801_led_init);
234 +module_exit(ws2801_led_exit);
235 +
236 +MODULE_AUTHOR("David Anders <danders@tincantools.com>");
237 +MODULE_DESCRIPTION("WS2801 RGB LED driver");
238 +MODULE_LICENSE("GPL");
239 +
240 --
241 1.6.6.1