1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
4 <http://rt2x00.serialmonkey.com>
10 Abstract: rt2x00 led specific routines.
13 #include <linux/kernel.h>
14 #include <linux/module.h>
17 #include "rt2x00lib.h"
19 void rt2x00leds_led_quality(struct rt2x00_dev
*rt2x00dev
, int rssi
)
21 struct rt2x00_led
*led
= &rt2x00dev
->led_qual
;
22 unsigned int brightness
;
24 if ((led
->type
!= LED_TYPE_QUALITY
) || !(led
->flags
& LED_REGISTERED
))
28 * Led handling requires a positive value for the rssi,
29 * to do that correctly we need to add the correction.
31 rssi
+= rt2x00dev
->rssi_offset
;
34 * Get the rssi level, this is used to convert the rssi
35 * to a LED value inside the range LED_OFF - LED_FULL.
51 * Note that we must _not_ send LED_OFF since the driver
52 * is going to calculate the value and might use it in a
55 brightness
= ((LED_FULL
/ 6) * rssi
) + 1;
56 if (brightness
!= led
->led_dev
.brightness
) {
57 led
->led_dev
.brightness_set(&led
->led_dev
, brightness
);
58 led
->led_dev
.brightness
= brightness
;
62 static void rt2x00led_led_simple(struct rt2x00_led
*led
, bool enabled
)
64 unsigned int brightness
= enabled
? LED_FULL
: LED_OFF
;
66 if (!(led
->flags
& LED_REGISTERED
))
69 led
->led_dev
.brightness_set(&led
->led_dev
, brightness
);
70 led
->led_dev
.brightness
= brightness
;
73 void rt2x00led_led_activity(struct rt2x00_dev
*rt2x00dev
, bool enabled
)
75 if (rt2x00dev
->led_qual
.type
== LED_TYPE_ACTIVITY
)
76 rt2x00led_led_simple(&rt2x00dev
->led_qual
, enabled
);
79 void rt2x00leds_led_assoc(struct rt2x00_dev
*rt2x00dev
, bool enabled
)
81 if (rt2x00dev
->led_assoc
.type
== LED_TYPE_ASSOC
)
82 rt2x00led_led_simple(&rt2x00dev
->led_assoc
, enabled
);
85 void rt2x00leds_led_radio(struct rt2x00_dev
*rt2x00dev
, bool enabled
)
87 if (rt2x00dev
->led_radio
.type
== LED_TYPE_RADIO
)
88 rt2x00led_led_simple(&rt2x00dev
->led_radio
, enabled
);
91 static int rt2x00leds_register_led(struct rt2x00_dev
*rt2x00dev
,
92 struct rt2x00_led
*led
,
95 struct device
*device
= wiphy_dev(rt2x00dev
->hw
->wiphy
);
98 led
->led_dev
.name
= name
;
99 led
->led_dev
.brightness
= LED_OFF
;
101 retval
= led_classdev_register(device
, &led
->led_dev
);
103 rt2x00_err(rt2x00dev
, "Failed to register led handler\n");
107 led
->flags
|= LED_REGISTERED
;
112 void rt2x00leds_register(struct rt2x00_dev
*rt2x00dev
)
116 unsigned long on_period
;
117 unsigned long off_period
;
118 const char *phy_name
= wiphy_name(rt2x00dev
->hw
->wiphy
);
120 if (rt2x00dev
->led_radio
.flags
& LED_INITIALIZED
) {
121 snprintf(name
, sizeof(name
), "%s-%s::radio",
122 rt2x00dev
->ops
->name
, phy_name
);
124 retval
= rt2x00leds_register_led(rt2x00dev
,
125 &rt2x00dev
->led_radio
,
131 if (rt2x00dev
->led_assoc
.flags
& LED_INITIALIZED
) {
132 snprintf(name
, sizeof(name
), "%s-%s::assoc",
133 rt2x00dev
->ops
->name
, phy_name
);
135 retval
= rt2x00leds_register_led(rt2x00dev
,
136 &rt2x00dev
->led_assoc
,
142 if (rt2x00dev
->led_qual
.flags
& LED_INITIALIZED
) {
143 snprintf(name
, sizeof(name
), "%s-%s::quality",
144 rt2x00dev
->ops
->name
, phy_name
);
146 retval
= rt2x00leds_register_led(rt2x00dev
,
147 &rt2x00dev
->led_qual
,
154 * Initialize blink time to default value:
158 if (rt2x00dev
->led_radio
.led_dev
.blink_set
) {
161 rt2x00dev
->led_radio
.led_dev
.blink_set(
162 &rt2x00dev
->led_radio
.led_dev
, &on_period
, &off_period
);
168 rt2x00leds_unregister(rt2x00dev
);
171 static void rt2x00leds_unregister_led(struct rt2x00_led
*led
)
173 led_classdev_unregister(&led
->led_dev
);
176 * This might look weird, but when we are unregistering while
177 * suspended the led is already off, and since we haven't
178 * fully resumed yet, access to the device might not be
181 if (!(led
->led_dev
.flags
& LED_SUSPENDED
))
182 led
->led_dev
.brightness_set(&led
->led_dev
, LED_OFF
);
184 led
->flags
&= ~LED_REGISTERED
;
187 void rt2x00leds_unregister(struct rt2x00_dev
*rt2x00dev
)
189 if (rt2x00dev
->led_qual
.flags
& LED_REGISTERED
)
190 rt2x00leds_unregister_led(&rt2x00dev
->led_qual
);
191 if (rt2x00dev
->led_assoc
.flags
& LED_REGISTERED
)
192 rt2x00leds_unregister_led(&rt2x00dev
->led_assoc
);
193 if (rt2x00dev
->led_radio
.flags
& LED_REGISTERED
)
194 rt2x00leds_unregister_led(&rt2x00dev
->led_radio
);
197 static inline void rt2x00leds_suspend_led(struct rt2x00_led
*led
)
199 led_classdev_suspend(&led
->led_dev
);
201 /* This shouldn't be needed, but just to be safe */
202 led
->led_dev
.brightness_set(&led
->led_dev
, LED_OFF
);
203 led
->led_dev
.brightness
= LED_OFF
;
206 void rt2x00leds_suspend(struct rt2x00_dev
*rt2x00dev
)
208 if (rt2x00dev
->led_qual
.flags
& LED_REGISTERED
)
209 rt2x00leds_suspend_led(&rt2x00dev
->led_qual
);
210 if (rt2x00dev
->led_assoc
.flags
& LED_REGISTERED
)
211 rt2x00leds_suspend_led(&rt2x00dev
->led_assoc
);
212 if (rt2x00dev
->led_radio
.flags
& LED_REGISTERED
)
213 rt2x00leds_suspend_led(&rt2x00dev
->led_radio
);
216 static inline void rt2x00leds_resume_led(struct rt2x00_led
*led
)
218 led_classdev_resume(&led
->led_dev
);
220 /* Device might have enabled the LEDS during resume */
221 led
->led_dev
.brightness_set(&led
->led_dev
, LED_OFF
);
222 led
->led_dev
.brightness
= LED_OFF
;
225 void rt2x00leds_resume(struct rt2x00_dev
*rt2x00dev
)
227 if (rt2x00dev
->led_radio
.flags
& LED_REGISTERED
)
228 rt2x00leds_resume_led(&rt2x00dev
->led_radio
);
229 if (rt2x00dev
->led_assoc
.flags
& LED_REGISTERED
)
230 rt2x00leds_resume_led(&rt2x00dev
->led_assoc
);
231 if (rt2x00dev
->led_qual
.flags
& LED_REGISTERED
)
232 rt2x00leds_resume_led(&rt2x00dev
->led_qual
);