175388acd0cd827dc1498043daa7d1c760902cd67Larry Finger/*
275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
3ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger  Broadcom B43 wireless driver
4ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger  LED control
575388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
71f21ad2a4f7f66855dae600ddd635ff5fb299bbdStefano Brivio  Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
8eb032b9837a958e21ca000358a5bde5e17192ddbMichael Buesch  Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
9ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger  Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
10ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger  Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
1175388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
1275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  This program is free software; you can redistribute it and/or modify
1375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  it under the terms of the GNU General Public License as published by
1475388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  the Free Software Foundation; either version 2 of the License, or
1575388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  (at your option) any later version.
1675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
1775388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  This program is distributed in the hope that it will be useful,
1875388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  but WITHOUT ANY WARRANTY; without even the implied warranty of
1975388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2075388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  GNU General Public License for more details.
2175388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
2275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  You should have received a copy of the GNU General Public License
2375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  along with this program; see the file COPYING.  If not, write to
2475388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
2575388acd0cd827dc1498043daa7d1c760902cd67Larry Finger  Boston, MA 02110-1301, USA.
2675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
2775388acd0cd827dc1498043daa7d1c760902cd67Larry Finger*/
2875388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
2975388acd0cd827dc1498043daa7d1c760902cd67Larry Finger#include "b43legacy.h"
30ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger#include "leds.h"
31f41f3f373dd72344c65d801d6381fe83ef3a2c54Johannes Berg#include "rfkill.h"
3275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
3375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
34ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingerstatic void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index,
35ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			    bool activelow)
3675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger{
37ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	struct b43legacy_wl *wl = dev->wl;
3875388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	unsigned long flags;
39ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	u16 ctl;
4075388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
41ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	spin_lock_irqsave(&wl->leds_lock, flags);
42ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
43ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (activelow)
44ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		ctl &= ~(1 << led_index);
45ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	else
46ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		ctl |= (1 << led_index);
47ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl);
48ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	spin_unlock_irqrestore(&wl->leds_lock, flags);
4975388acd0cd827dc1498043daa7d1c760902cd67Larry Finger}
5075388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
51ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingerstatic void b43legacy_led_turn_off(struct b43legacy_wldev *dev, u8 led_index,
52ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			     bool activelow)
5375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger{
54ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	struct b43legacy_wl *wl = dev->wl;
55ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	unsigned long flags;
56ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	u16 ctl;
57ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
58ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	spin_lock_irqsave(&wl->leds_lock, flags);
59ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
60ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (activelow)
61ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		ctl |= (1 << led_index);
62ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	else
63ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		ctl &= ~(1 << led_index);
64ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl);
65ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	spin_unlock_irqrestore(&wl->leds_lock, flags);
6675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger}
6775388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
68ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger/* Callback from the LED subsystem. */
69ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingerstatic void b43legacy_led_brightness_set(struct led_classdev *led_dev,
70ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				   enum led_brightness brightness)
7175388acd0cd827dc1498043daa7d1c760902cd67Larry Finger{
72ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	struct b43legacy_led *led = container_of(led_dev, struct b43legacy_led,
73ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				    led_dev);
7475388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	struct b43legacy_wldev *dev = led->dev;
75ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	bool radio_enabled;
7675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
77ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	/* Checking the radio-enabled status here is slightly racy,
78ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	 * but we want to avoid the locking overhead and we don't care
79ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	 * whether the LED has the wrong state for a second. */
80ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable);
8175388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
82ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (brightness == LED_OFF || !radio_enabled)
83ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_led_turn_off(dev, led->index, led->activelow);
8475388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	else
85ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_led_turn_on(dev, led->index, led->activelow);
8675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger}
8775388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
88ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingerstatic int b43legacy_register_led(struct b43legacy_wldev *dev,
89ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				  struct b43legacy_led *led,
9019d337dff95cbf76edd3ad95c0cee2732c3e1ec5Johannes Berg				  const char *name,
9119d337dff95cbf76edd3ad95c0cee2732c3e1ec5Johannes Berg				  const char *default_trigger,
92ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				  u8 led_index, bool activelow)
9375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger{
94ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	int err;
95ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
96ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_led_turn_off(dev, led_index, activelow);
97ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (led->dev)
98ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		return -EEXIST;
99ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (!default_trigger)
100ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		return -EINVAL;
101ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->dev = dev;
102ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->index = led_index;
103ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->activelow = activelow;
104ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	strncpy(led->name, name, sizeof(led->name));
105ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
106ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->led_dev.name = led->name;
107ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->led_dev.default_trigger = default_trigger;
108ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->led_dev.brightness_set = b43legacy_led_brightness_set;
109ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
110ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	err = led_classdev_register(dev->dev->dev, &led->led_dev);
111ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (err) {
112ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacywarn(dev->wl, "LEDs: Failed to register %s\n", name);
113ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		led->dev = NULL;
114ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		return err;
115ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	}
116ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	return 0;
117ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger}
11875388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
119ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingerstatic void b43legacy_unregister_led(struct b43legacy_led *led)
120ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger{
121ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	if (!led->dev)
122ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		return;
123ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led_classdev_unregister(&led->led_dev);
124ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_led_turn_off(led->dev, led->index, led->activelow);
125ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	led->dev = NULL;
126ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger}
127ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
128ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingerstatic void b43legacy_map_led(struct b43legacy_wldev *dev,
129ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			u8 led_index,
130ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			enum b43legacy_led_behaviour behaviour,
131ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			bool activelow)
132ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger{
133ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	struct ieee80211_hw *hw = dev->wl->hw;
134ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	char name[B43legacy_LED_MAX_NAME_LEN + 1];
13575388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
136ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	/* Map the b43 specific LED behaviour value to the
137ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	 * generic LED triggers. */
138ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	switch (behaviour) {
139ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_INACTIVE:
14075388acd0cd827dc1498043daa7d1c760902cd67Larry Finger		break;
141ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_OFF:
142ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_led_turn_off(dev, led_index, activelow);
14375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger		break;
144ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_ON:
145ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_led_turn_on(dev, led_index, activelow);
14675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger		break;
147ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_ACTIVITY:
148ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_TRANSFER:
149ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_APTRANSFER:
150ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		snprintf(name, sizeof(name),
151b157b5e60b2e4eefa8fb13936e0d2642ccc1d02cDanny Kukawka			 "b43legacy-%s::tx", wiphy_name(hw->wiphy));
152ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_register_led(dev, &dev->led_tx, name,
153ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				 ieee80211_get_tx_led_name(hw),
154ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				 led_index, activelow);
155ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		snprintf(name, sizeof(name),
156b157b5e60b2e4eefa8fb13936e0d2642ccc1d02cDanny Kukawka			 "b43legacy-%s::rx", wiphy_name(hw->wiphy));
157ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_register_led(dev, &dev->led_rx, name,
158ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				 ieee80211_get_rx_led_name(hw),
159ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				 led_index, activelow);
160ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		break;
161ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_RADIO_ALL:
162ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_RADIO_A:
163ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_RADIO_B:
164ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_MODE_BG:
16593bb7f3a7bb5c95da10242d9763994a466c90b1dLarry Finger		snprintf(name, sizeof(name),
166b157b5e60b2e4eefa8fb13936e0d2642ccc1d02cDanny Kukawka			 "b43legacy-%s::radio", wiphy_name(hw->wiphy));
16793bb7f3a7bb5c95da10242d9763994a466c90b1dLarry Finger		b43legacy_register_led(dev, &dev->led_radio, name,
168f41f3f373dd72344c65d801d6381fe83ef3a2c54Johannes Berg				 ieee80211_get_radio_led_name(hw),
16993bb7f3a7bb5c95da10242d9763994a466c90b1dLarry Finger				 led_index, activelow);
170f41f3f373dd72344c65d801d6381fe83ef3a2c54Johannes Berg		/* Sync the RF-kill LED state with radio and switch states. */
171f41f3f373dd72344c65d801d6381fe83ef3a2c54Johannes Berg		if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev))
1724ad36d780caf34630d1a4cc39f9bc11017f5b81dLarry Finger			b43legacy_led_turn_on(dev, led_index, activelow);
17393bb7f3a7bb5c95da10242d9763994a466c90b1dLarry Finger		break;
174ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_WEIRD:
175ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	case B43legacy_LED_ASSOC:
176ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		snprintf(name, sizeof(name),
177b157b5e60b2e4eefa8fb13936e0d2642ccc1d02cDanny Kukawka			 "b43legacy-%s::assoc", wiphy_name(hw->wiphy));
178ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_register_led(dev, &dev->led_assoc, name,
179ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				 ieee80211_get_assoc_led_name(hw),
180ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				 led_index, activelow);
18175388acd0cd827dc1498043daa7d1c760902cd67Larry Finger		break;
18275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	default:
183ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacywarn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n",
184ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			behaviour);
185ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		break;
18675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	}
18775388acd0cd827dc1498043daa7d1c760902cd67Larry Finger}
18875388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
189ba48f7bb8062982ec916868cc8c90360aad82e53Larry Fingervoid b43legacy_leds_init(struct b43legacy_wldev *dev)
19075388acd0cd827dc1498043daa7d1c760902cd67Larry Finger{
191ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	struct ssb_bus *bus = dev->dev->bus;
19275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	u8 sprom[4];
19375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	int i;
194ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	enum b43legacy_led_behaviour behaviour;
195ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	bool activelow;
196ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
1977797aa384870e3bb5bfd3b6a0eae61e7c7a4c993Larry Finger	sprom[0] = bus->sprom.gpio0;
1987797aa384870e3bb5bfd3b6a0eae61e7c7a4c993Larry Finger	sprom[1] = bus->sprom.gpio1;
1997797aa384870e3bb5bfd3b6a0eae61e7c7a4c993Larry Finger	sprom[2] = bus->sprom.gpio2;
2007797aa384870e3bb5bfd3b6a0eae61e7c7a4c993Larry Finger	sprom[3] = bus->sprom.gpio3;
201ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger
202ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	for (i = 0; i < 4; i++) {
203ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		if (sprom[i] == 0xFF) {
204ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			/* There is no LED information in the SPROM
205ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			 * for this LED. Hardcode it here. */
2063db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell			activelow = false;
207ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			switch (i) {
208ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			case 0:
209ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				behaviour = B43legacy_LED_ACTIVITY;
2103db1cd5c05f35fb43eb134df6f321de4e63141f2Rusty Russell				activelow = true;
211ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
212ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger					behaviour = B43legacy_LED_RADIO_ALL;
213ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				break;
214ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			case 1:
215ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				behaviour = B43legacy_LED_RADIO_B;
216ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
217ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger					behaviour = B43legacy_LED_ASSOC;
218ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				break;
219ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			case 2:
220ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				behaviour = B43legacy_LED_RADIO_A;
221ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				break;
222ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			case 3:
223ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				behaviour = B43legacy_LED_OFF;
224ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				break;
225ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			default:
226ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				B43legacy_WARN_ON(1);
227ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger				return;
228ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			}
229ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		} else {
230ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR;
231ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger			activelow = !!(sprom[i] & B43legacy_LED_ACTIVELOW);
23275388acd0cd827dc1498043daa7d1c760902cd67Larry Finger		}
233ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger		b43legacy_map_led(dev, i, behaviour, activelow);
23475388acd0cd827dc1498043daa7d1c760902cd67Larry Finger	}
23575388acd0cd827dc1498043daa7d1c760902cd67Larry Finger}
23675388acd0cd827dc1498043daa7d1c760902cd67Larry Finger
23775388acd0cd827dc1498043daa7d1c760902cd67Larry Fingervoid b43legacy_leds_exit(struct b43legacy_wldev *dev)
23875388acd0cd827dc1498043daa7d1c760902cd67Larry Finger{
239ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_unregister_led(&dev->led_tx);
240ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_unregister_led(&dev->led_rx);
241ba48f7bb8062982ec916868cc8c90360aad82e53Larry Finger	b43legacy_unregister_led(&dev->led_assoc);
2424ad36d780caf34630d1a4cc39f9bc11017f5b81dLarry Finger	b43legacy_unregister_led(&dev->led_radio);
24375388acd0cd827dc1498043daa7d1c760902cd67Larry Finger}
244