1 // SPDX-License-Identifier: GPL-2.0-only
3 * LED Driver for the Freecom FSG-3
5 * Copyright (c) 2008 Rod Whitby <rod@whitby.id.au>
7 * Author: Rod Whitby <rod@whitby.id.au>
9 * Based on leds-spitz.c
10 * Copyright 2005-2006 Openedhand Ltd.
11 * Author: Richard Purdie <rpurdie@openedhand.com>
14 #include <linux/kernel.h>
15 #include <linux/platform_device.h>
16 #include <linux/leds.h>
17 #include <linux/module.h>
19 #include <mach/hardware.h>
21 #define FSG_LED_WLAN_BIT 0
22 #define FSG_LED_WAN_BIT 1
23 #define FSG_LED_SATA_BIT 2
24 #define FSG_LED_USB_BIT 4
25 #define FSG_LED_RING_BIT 5
26 #define FSG_LED_SYNC_BIT 7
28 static short __iomem
*latch_address
;
29 static unsigned short latch_value
;
32 static void fsg_led_wlan_set(struct led_classdev
*led_cdev
,
33 enum led_brightness value
)
36 latch_value
&= ~(1 << FSG_LED_WLAN_BIT
);
37 *latch_address
= latch_value
;
39 latch_value
|= (1 << FSG_LED_WLAN_BIT
);
40 *latch_address
= latch_value
;
44 static void fsg_led_wan_set(struct led_classdev
*led_cdev
,
45 enum led_brightness value
)
48 latch_value
&= ~(1 << FSG_LED_WAN_BIT
);
49 *latch_address
= latch_value
;
51 latch_value
|= (1 << FSG_LED_WAN_BIT
);
52 *latch_address
= latch_value
;
56 static void fsg_led_sata_set(struct led_classdev
*led_cdev
,
57 enum led_brightness value
)
60 latch_value
&= ~(1 << FSG_LED_SATA_BIT
);
61 *latch_address
= latch_value
;
63 latch_value
|= (1 << FSG_LED_SATA_BIT
);
64 *latch_address
= latch_value
;
68 static void fsg_led_usb_set(struct led_classdev
*led_cdev
,
69 enum led_brightness value
)
72 latch_value
&= ~(1 << FSG_LED_USB_BIT
);
73 *latch_address
= latch_value
;
75 latch_value
|= (1 << FSG_LED_USB_BIT
);
76 *latch_address
= latch_value
;
80 static void fsg_led_sync_set(struct led_classdev
*led_cdev
,
81 enum led_brightness value
)
84 latch_value
&= ~(1 << FSG_LED_SYNC_BIT
);
85 *latch_address
= latch_value
;
87 latch_value
|= (1 << FSG_LED_SYNC_BIT
);
88 *latch_address
= latch_value
;
92 static void fsg_led_ring_set(struct led_classdev
*led_cdev
,
93 enum led_brightness value
)
96 latch_value
&= ~(1 << FSG_LED_RING_BIT
);
97 *latch_address
= latch_value
;
99 latch_value
|= (1 << FSG_LED_RING_BIT
);
100 *latch_address
= latch_value
;
105 static struct led_classdev fsg_wlan_led
= {
106 .name
= "fsg:blue:wlan",
107 .brightness_set
= fsg_led_wlan_set
,
108 .flags
= LED_CORE_SUSPENDRESUME
,
111 static struct led_classdev fsg_wan_led
= {
112 .name
= "fsg:blue:wan",
113 .brightness_set
= fsg_led_wan_set
,
114 .flags
= LED_CORE_SUSPENDRESUME
,
117 static struct led_classdev fsg_sata_led
= {
118 .name
= "fsg:blue:sata",
119 .brightness_set
= fsg_led_sata_set
,
120 .flags
= LED_CORE_SUSPENDRESUME
,
123 static struct led_classdev fsg_usb_led
= {
124 .name
= "fsg:blue:usb",
125 .brightness_set
= fsg_led_usb_set
,
126 .flags
= LED_CORE_SUSPENDRESUME
,
129 static struct led_classdev fsg_sync_led
= {
130 .name
= "fsg:blue:sync",
131 .brightness_set
= fsg_led_sync_set
,
132 .flags
= LED_CORE_SUSPENDRESUME
,
135 static struct led_classdev fsg_ring_led
= {
136 .name
= "fsg:blue:ring",
137 .brightness_set
= fsg_led_ring_set
,
138 .flags
= LED_CORE_SUSPENDRESUME
,
142 static int fsg_led_probe(struct platform_device
*pdev
)
146 /* Map the LED chip select address space */
147 latch_address
= (unsigned short *) devm_ioremap(&pdev
->dev
,
148 IXP4XX_EXP_BUS_BASE(2), 512);
152 latch_value
= 0xffff;
153 *latch_address
= latch_value
;
155 ret
= devm_led_classdev_register(&pdev
->dev
, &fsg_wlan_led
);
159 ret
= devm_led_classdev_register(&pdev
->dev
, &fsg_wan_led
);
163 ret
= devm_led_classdev_register(&pdev
->dev
, &fsg_sata_led
);
167 ret
= devm_led_classdev_register(&pdev
->dev
, &fsg_usb_led
);
171 ret
= devm_led_classdev_register(&pdev
->dev
, &fsg_sync_led
);
175 ret
= devm_led_classdev_register(&pdev
->dev
, &fsg_ring_led
);
182 static struct platform_driver fsg_led_driver
= {
183 .probe
= fsg_led_probe
,
189 module_platform_driver(fsg_led_driver
);
191 MODULE_AUTHOR("Rod Whitby <rod@whitby.id.au>");
192 MODULE_DESCRIPTION("Freecom FSG-3 LED driver");
193 MODULE_LICENSE("GPL");