2 * LED Driver for the Freecom FSG-3
4 * Copyright (c) 2008 Rod Whitby <rod@whitby.id.au>
6 * Author: Rod Whitby <rod@whitby.id.au>
8 * Based on leds-spitz.c
9 * Copyright 2005-2006 Openedhand Ltd.
10 * Author: Richard Purdie <rpurdie@openedhand.com>
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.
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/platform_device.h>
21 #include <linux/leds.h>
22 #include <asm/arch/hardware.h>
25 static short __iomem *latch_address;
26 static unsigned short latch_value;
29 static void fsg_led_wlan_set(struct led_classdev *led_cdev,
30 enum led_brightness value)
33 latch_value &= ~(1 << FSG_LED_WLAN_BIT);
34 *latch_address = latch_value;
36 latch_value |= (1 << FSG_LED_WLAN_BIT);
37 *latch_address = latch_value;
41 static void fsg_led_wan_set(struct led_classdev *led_cdev,
42 enum led_brightness value)
45 latch_value &= ~(1 << FSG_LED_WAN_BIT);
46 *latch_address = latch_value;
48 latch_value |= (1 << FSG_LED_WAN_BIT);
49 *latch_address = latch_value;
53 static void fsg_led_sata_set(struct led_classdev *led_cdev,
54 enum led_brightness value)
57 latch_value &= ~(1 << FSG_LED_SATA_BIT);
58 *latch_address = latch_value;
60 latch_value |= (1 << FSG_LED_SATA_BIT);
61 *latch_address = latch_value;
65 static void fsg_led_usb_set(struct led_classdev *led_cdev,
66 enum led_brightness value)
69 latch_value &= ~(1 << FSG_LED_USB_BIT);
70 *latch_address = latch_value;
72 latch_value |= (1 << FSG_LED_USB_BIT);
73 *latch_address = latch_value;
77 static void fsg_led_sync_set(struct led_classdev *led_cdev,
78 enum led_brightness value)
81 latch_value &= ~(1 << FSG_LED_SYNC_BIT);
82 *latch_address = latch_value;
84 latch_value |= (1 << FSG_LED_SYNC_BIT);
85 *latch_address = latch_value;
89 static void fsg_led_ring_set(struct led_classdev *led_cdev,
90 enum led_brightness value)
93 latch_value &= ~(1 << FSG_LED_RING_BIT);
94 *latch_address = latch_value;
96 latch_value |= (1 << FSG_LED_RING_BIT);
97 *latch_address = latch_value;
103 static struct led_classdev fsg_wlan_led = {
104 .name = "fsg:blue:wlan",
105 .brightness_set = fsg_led_wlan_set,
108 static struct led_classdev fsg_wan_led = {
109 .name = "fsg:blue:wan",
110 .brightness_set = fsg_led_wan_set,
113 static struct led_classdev fsg_sata_led = {
114 .name = "fsg:blue:sata",
115 .brightness_set = fsg_led_sata_set,
118 static struct led_classdev fsg_usb_led = {
119 .name = "fsg:blue:usb",
120 .brightness_set = fsg_led_usb_set,
123 static struct led_classdev fsg_sync_led = {
124 .name = "fsg:blue:sync",
125 .brightness_set = fsg_led_sync_set,
128 static struct led_classdev fsg_ring_led = {
129 .name = "fsg:blue:ring",
130 .brightness_set = fsg_led_ring_set,
136 static int fsg_led_suspend(struct platform_device *dev, pm_message_t state)
138 led_classdev_suspend(&fsg_wlan_led);
139 led_classdev_suspend(&fsg_wan_led);
140 led_classdev_suspend(&fsg_sata_led);
141 led_classdev_suspend(&fsg_usb_led);
142 led_classdev_suspend(&fsg_sync_led);
143 led_classdev_suspend(&fsg_ring_led);
147 static int fsg_led_resume(struct platform_device *dev)
149 led_classdev_resume(&fsg_wlan_led);
150 led_classdev_resume(&fsg_wan_led);
151 led_classdev_resume(&fsg_sata_led);
152 led_classdev_resume(&fsg_usb_led);
153 led_classdev_resume(&fsg_sync_led);
154 led_classdev_resume(&fsg_ring_led);
160 static int fsg_led_probe(struct platform_device *pdev)
164 ret = led_classdev_register(&pdev->dev, &fsg_wlan_led);
168 ret = led_classdev_register(&pdev->dev, &fsg_wan_led);
172 ret = led_classdev_register(&pdev->dev, &fsg_sata_led);
176 ret = led_classdev_register(&pdev->dev, &fsg_usb_led);
180 ret = led_classdev_register(&pdev->dev, &fsg_sync_led);
184 ret = led_classdev_register(&pdev->dev, &fsg_ring_led);
188 /* Map the LED chip select address space */
189 latch_address = (unsigned short *) ioremap(IXP4XX_EXP_BUS_BASE(2), 512);
190 if (!latch_address) {
195 latch_value = 0xffff;
196 *latch_address = latch_value;
201 led_classdev_unregister(&fsg_ring_led);
203 led_classdev_unregister(&fsg_sync_led);
205 led_classdev_unregister(&fsg_usb_led);
207 led_classdev_unregister(&fsg_sata_led);
209 led_classdev_unregister(&fsg_wan_led);
211 led_classdev_unregister(&fsg_wlan_led);
217 static int fsg_led_remove(struct platform_device *pdev)
219 iounmap(latch_address);
221 led_classdev_unregister(&fsg_wlan_led);
222 led_classdev_unregister(&fsg_wan_led);
223 led_classdev_unregister(&fsg_sata_led);
224 led_classdev_unregister(&fsg_usb_led);
225 led_classdev_unregister(&fsg_sync_led);
226 led_classdev_unregister(&fsg_ring_led);
232 static struct platform_driver fsg_led_driver = {
233 .probe = fsg_led_probe,
234 .remove = fsg_led_remove,
236 .suspend = fsg_led_suspend,
237 .resume = fsg_led_resume,
245 static int __init fsg_led_init(void)
247 return platform_driver_register(&fsg_led_driver);
250 static void __exit fsg_led_exit(void)
252 platform_driver_unregister(&fsg_led_driver);
256 module_init(fsg_led_init);
257 module_exit(fsg_led_exit);
259 MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
260 MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
261 MODULE_LICENSE("GPL");