diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00leds.c')
| -rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00leds.c | 197 |
1 files changed, 112 insertions, 85 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index 9c29d17e0cc..c681d04b506 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 - 2008 rt2x00 SourceForge Project + Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> <http://rt2x00.serialmonkey.com> This program is free software; you can redistribute it and/or modify @@ -13,9 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* @@ -31,7 +29,10 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) { - if (!rt2x00dev->trigger_qual.registered) + struct rt2x00_led *led = &rt2x00dev->led_qual; + unsigned int brightness; + + if ((led->type != LED_TYPE_QUALITY) || !(led->flags & LED_REGISTERED)) return; /* @@ -62,156 +63,182 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) * is going to calculate the value and might use it in a * division. */ - led_trigger_event(&rt2x00dev->trigger_qual.trigger, - ((LED_FULL / 6) * rssi) + 1); + brightness = ((LED_FULL / 6) * rssi) + 1; + if (brightness != led->led_dev.brightness) { + led->led_dev.brightness_set(&led->led_dev, brightness); + led->led_dev.brightness = brightness; + } } -static int rt2x00leds_register_trigger(struct rt2x00_dev *rt2x00dev, - struct rt2x00_trigger *trigger, - const char *name) +static void rt2x00led_led_simple(struct rt2x00_led *led, bool enabled) { - int retval; + unsigned int brightness = enabled ? LED_FULL : LED_OFF; - trigger->trigger.name = name; - retval = led_trigger_register(&trigger->trigger); - if (retval) { - ERROR(rt2x00dev, "Failed to register led trigger.\n"); - return retval; - } + if (!(led->flags & LED_REGISTERED)) + return; - trigger->registered = 1; + led->led_dev.brightness_set(&led->led_dev, brightness); + led->led_dev.brightness = brightness; +} - return 0; +void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled) +{ + if (rt2x00dev->led_qual.type == LED_TYPE_ACTIVITY) + rt2x00led_led_simple(&rt2x00dev->led_qual, enabled); +} + +void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) +{ + if (rt2x00dev->led_assoc.type == LED_TYPE_ASSOC) + rt2x00led_led_simple(&rt2x00dev->led_assoc, enabled); +} + +void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) +{ + if (rt2x00dev->led_radio.type == LED_TYPE_RADIO) + rt2x00led_led_simple(&rt2x00dev->led_radio, enabled); } static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, struct rt2x00_led *led, - enum led_type type, - const char *name, char *trigger) + const char *name) { struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); int retval; led->led_dev.name = name; - led->led_dev.brightness_set = rt2x00dev->ops->lib->led_brightness; - led->led_dev.default_trigger = trigger; + led->led_dev.brightness = LED_OFF; retval = led_classdev_register(device, &led->led_dev); if (retval) { - ERROR(rt2x00dev, "Failed to register led handler.\n"); + rt2x00_err(rt2x00dev, "Failed to register led handler\n"); return retval; } - led->rt2x00dev = rt2x00dev; - led->type = type; - led->registered = 1; + led->flags |= LED_REGISTERED; return 0; } -int rt2x00leds_register(struct rt2x00_dev *rt2x00dev) +void rt2x00leds_register(struct rt2x00_dev *rt2x00dev) { - char *trigger; - char dev_name[16]; - char name[32]; + char name[36]; int retval; + unsigned long on_period; + unsigned long off_period; + const char *phy_name = wiphy_name(rt2x00dev->hw->wiphy); - if (!rt2x00dev->ops->lib->led_brightness) - return 0; - - snprintf(dev_name, sizeof(dev_name), "%s-%s", - rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); - - if (rt2x00dev->led_flags & LED_SUPPORT_RADIO) { - trigger = ieee80211_get_radio_led_name(rt2x00dev->hw); - snprintf(name, sizeof(name), "%s:radio", dev_name); + if (rt2x00dev->led_radio.flags & LED_INITIALIZED) { + snprintf(name, sizeof(name), "%s-%s::radio", + rt2x00dev->ops->name, phy_name); retval = rt2x00leds_register_led(rt2x00dev, &rt2x00dev->led_radio, - LED_TYPE_RADIO, - name, trigger); + name); if (retval) goto exit_fail; } - if (rt2x00dev->led_flags & LED_SUPPORT_ASSOC) { - trigger = ieee80211_get_assoc_led_name(rt2x00dev->hw); - snprintf(name, sizeof(name), "%s:assoc", dev_name); + if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) { + snprintf(name, sizeof(name), "%s-%s::assoc", + rt2x00dev->ops->name, phy_name); retval = rt2x00leds_register_led(rt2x00dev, &rt2x00dev->led_assoc, - LED_TYPE_ASSOC, - name, trigger); + name); if (retval) goto exit_fail; } - if (rt2x00dev->led_flags & LED_SUPPORT_QUALITY) { - snprintf(name, sizeof(name), "%s:quality", dev_name); - - retval = rt2x00leds_register_trigger(rt2x00dev, - &rt2x00dev->trigger_qual, - name); + if (rt2x00dev->led_qual.flags & LED_INITIALIZED) { + snprintf(name, sizeof(name), "%s-%s::quality", + rt2x00dev->ops->name, phy_name); retval = rt2x00leds_register_led(rt2x00dev, &rt2x00dev->led_qual, - LED_TYPE_QUALITY, - name, name); + name); if (retval) goto exit_fail; } - return 0; + /* + * Initialize blink time to default value: + * On period: 70ms + * Off period: 30ms + */ + if (rt2x00dev->led_radio.led_dev.blink_set) { + on_period = 70; + off_period = 30; + rt2x00dev->led_radio.led_dev.blink_set( + &rt2x00dev->led_radio.led_dev, &on_period, &off_period); + } + + return; exit_fail: rt2x00leds_unregister(rt2x00dev); - return retval; } -static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger) +static void rt2x00leds_unregister_led(struct rt2x00_led *led) { - if (!trigger->registered) - return; + led_classdev_unregister(&led->led_dev); - led_trigger_unregister(&trigger->trigger); - trigger->registered = 0; + /* + * This might look weird, but when we are unregistering while + * suspended the led is already off, and since we haven't + * fully resumed yet, access to the device might not be + * possible yet. + */ + if (!(led->led_dev.flags & LED_SUSPENDED)) + led->led_dev.brightness_set(&led->led_dev, LED_OFF); + + led->flags &= ~LED_REGISTERED; } -static void rt2x00leds_unregister_led(struct rt2x00_led *led) +void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) { - if (!led->registered) - return; + if (rt2x00dev->led_qual.flags & LED_REGISTERED) + rt2x00leds_unregister_led(&rt2x00dev->led_qual); + if (rt2x00dev->led_assoc.flags & LED_REGISTERED) + rt2x00leds_unregister_led(&rt2x00dev->led_assoc); + if (rt2x00dev->led_radio.flags & LED_REGISTERED) + rt2x00leds_unregister_led(&rt2x00dev->led_radio); +} - led_classdev_unregister(&led->led_dev); +static inline void rt2x00leds_suspend_led(struct rt2x00_led *led) +{ + led_classdev_suspend(&led->led_dev); + /* This shouldn't be needed, but just to be safe */ led->led_dev.brightness_set(&led->led_dev, LED_OFF); - led->registered = 0; + led->led_dev.brightness = LED_OFF; } -void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) +void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) { - rt2x00leds_unregister_trigger(&rt2x00dev->trigger_qual); - rt2x00leds_unregister_led(&rt2x00dev->led_qual); - rt2x00leds_unregister_led(&rt2x00dev->led_assoc); - rt2x00leds_unregister_led(&rt2x00dev->led_radio); + if (rt2x00dev->led_qual.flags & LED_REGISTERED) + rt2x00leds_suspend_led(&rt2x00dev->led_qual); + if (rt2x00dev->led_assoc.flags & LED_REGISTERED) + rt2x00leds_suspend_led(&rt2x00dev->led_assoc); + if (rt2x00dev->led_radio.flags & LED_REGISTERED) + rt2x00leds_suspend_led(&rt2x00dev->led_radio); } -void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) +static inline void rt2x00leds_resume_led(struct rt2x00_led *led) { - if (rt2x00dev->led_qual.registered) - led_classdev_suspend(&rt2x00dev->led_qual.led_dev); - if (rt2x00dev->led_assoc.registered) - led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); - if (rt2x00dev->led_radio.registered) - led_classdev_suspend(&rt2x00dev->led_radio.led_dev); + led_classdev_resume(&led->led_dev); + + /* Device might have enabled the LEDS during resume */ + led->led_dev.brightness_set(&led->led_dev, LED_OFF); + led->led_dev.brightness = LED_OFF; } void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) { - if (rt2x00dev->led_radio.registered) - led_classdev_resume(&rt2x00dev->led_radio.led_dev); - if (rt2x00dev->led_assoc.registered) - led_classdev_resume(&rt2x00dev->led_assoc.led_dev); - if (rt2x00dev->led_qual.registered) - led_classdev_resume(&rt2x00dev->led_qual.led_dev); + if (rt2x00dev->led_radio.flags & LED_REGISTERED) + rt2x00leds_resume_led(&rt2x00dev->led_radio); + if (rt2x00dev->led_assoc.flags & LED_REGISTERED) + rt2x00leds_resume_led(&rt2x00dev->led_assoc); + if (rt2x00dev->led_qual.flags & LED_REGISTERED) + rt2x00leds_resume_led(&rt2x00dev->led_qual); } |
