• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/leds/
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
25#define FSG_LED_WLAN_BIT	0
26#define FSG_LED_WAN_BIT		1
27#define FSG_LED_SATA_BIT	2
28#define FSG_LED_USB_BIT		4
29#define FSG_LED_RING_BIT	5
30#define FSG_LED_SYNC_BIT	7
31
32static short __iomem *latch_address;
33static unsigned short latch_value;
34
35
36static void fsg_led_wlan_set(struct led_classdev *led_cdev,
37			     enum led_brightness value)
38{
39	if (value) {
40		latch_value &= ~(1 << FSG_LED_WLAN_BIT);
41		*latch_address = latch_value;
42	} else {
43		latch_value |=  (1 << FSG_LED_WLAN_BIT);
44		*latch_address = latch_value;
45	}
46}
47
48static void fsg_led_wan_set(struct led_classdev *led_cdev,
49			    enum led_brightness value)
50{
51	if (value) {
52		latch_value &= ~(1 << FSG_LED_WAN_BIT);
53		*latch_address = latch_value;
54	} else {
55		latch_value |=  (1 << FSG_LED_WAN_BIT);
56		*latch_address = latch_value;
57	}
58}
59
60static void fsg_led_sata_set(struct led_classdev *led_cdev,
61			     enum led_brightness value)
62{
63	if (value) {
64		latch_value &= ~(1 << FSG_LED_SATA_BIT);
65		*latch_address = latch_value;
66	} else {
67		latch_value |=  (1 << FSG_LED_SATA_BIT);
68		*latch_address = latch_value;
69	}
70}
71
72static void fsg_led_usb_set(struct led_classdev *led_cdev,
73			    enum led_brightness value)
74{
75	if (value) {
76		latch_value &= ~(1 << FSG_LED_USB_BIT);
77		*latch_address = latch_value;
78	} else {
79		latch_value |=  (1 << FSG_LED_USB_BIT);
80		*latch_address = latch_value;
81	}
82}
83
84static void fsg_led_sync_set(struct led_classdev *led_cdev,
85			     enum led_brightness value)
86{
87	if (value) {
88		latch_value &= ~(1 << FSG_LED_SYNC_BIT);
89		*latch_address = latch_value;
90	} else {
91		latch_value |=  (1 << FSG_LED_SYNC_BIT);
92		*latch_address = latch_value;
93	}
94}
95
96static void fsg_led_ring_set(struct led_classdev *led_cdev,
97			     enum led_brightness value)
98{
99	if (value) {
100		latch_value &= ~(1 << FSG_LED_RING_BIT);
101		*latch_address = latch_value;
102	} else {
103		latch_value |=  (1 << FSG_LED_RING_BIT);
104		*latch_address = latch_value;
105	}
106}
107
108
109static struct led_classdev fsg_wlan_led = {
110	.name			= "fsg:blue:wlan",
111	.brightness_set		= fsg_led_wlan_set,
112	.flags			= LED_CORE_SUSPENDRESUME,
113};
114
115static struct led_classdev fsg_wan_led = {
116	.name			= "fsg:blue:wan",
117	.brightness_set		= fsg_led_wan_set,
118	.flags			= LED_CORE_SUSPENDRESUME,
119};
120
121static struct led_classdev fsg_sata_led = {
122	.name			= "fsg:blue:sata",
123	.brightness_set		= fsg_led_sata_set,
124	.flags			= LED_CORE_SUSPENDRESUME,
125};
126
127static struct led_classdev fsg_usb_led = {
128	.name			= "fsg:blue:usb",
129	.brightness_set		= fsg_led_usb_set,
130	.flags			= LED_CORE_SUSPENDRESUME,
131};
132
133static struct led_classdev fsg_sync_led = {
134	.name			= "fsg:blue:sync",
135	.brightness_set		= fsg_led_sync_set,
136	.flags			= LED_CORE_SUSPENDRESUME,
137};
138
139static struct led_classdev fsg_ring_led = {
140	.name			= "fsg:blue:ring",
141	.brightness_set		= fsg_led_ring_set,
142	.flags			= LED_CORE_SUSPENDRESUME,
143};
144
145
146static int fsg_led_probe(struct platform_device *pdev)
147{
148	int ret;
149
150	/* Map the LED chip select address space */
151	latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
152	if (!latch_address) {
153		ret = -ENOMEM;
154		goto failremap;
155	}
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	iounmap(latch_address);
198 failremap:
199
200	return ret;
201}
202
203static int fsg_led_remove(struct platform_device *pdev)
204{
205	led_classdev_unregister(&fsg_wlan_led);
206	led_classdev_unregister(&fsg_wan_led);
207	led_classdev_unregister(&fsg_sata_led);
208	led_classdev_unregister(&fsg_usb_led);
209	led_classdev_unregister(&fsg_sync_led);
210	led_classdev_unregister(&fsg_ring_led);
211
212	iounmap(latch_address);
213
214	return 0;
215}
216
217
218static struct platform_driver fsg_led_driver = {
219	.probe		= fsg_led_probe,
220	.remove		= fsg_led_remove,
221	.driver		= {
222		.name		= "fsg-led",
223	},
224};
225
226
227static int __init fsg_led_init(void)
228{
229	return platform_driver_register(&fsg_led_driver);
230}
231
232static void __exit fsg_led_exit(void)
233{
234	platform_driver_unregister(&fsg_led_driver);
235}
236
237
238module_init(fsg_led_init);
239module_exit(fsg_led_exit);
240
241MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
242MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
243MODULE_LICENSE("GPL");
244