forked from Minki/linux
[PATCH] bcm43xx: fix LED code.
Signed-off-by: Michael Buesch <mbuesch@freenet.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
d5dd8e28aa
commit
dcfd720bd7
@ -35,12 +35,13 @@ static void bcm43xx_led_changestate(struct bcm43xx_led *led)
|
|||||||
{
|
{
|
||||||
struct bcm43xx_private *bcm = led->bcm;
|
struct bcm43xx_private *bcm = led->bcm;
|
||||||
const int index = bcm43xx_led_index(led);
|
const int index = bcm43xx_led_index(led);
|
||||||
|
const u16 mask = (1 << index);
|
||||||
u16 ledctl;
|
u16 ledctl;
|
||||||
|
|
||||||
assert(index >= 0 && index < BCM43xx_NR_LEDS);
|
assert(index >= 0 && index < BCM43xx_NR_LEDS);
|
||||||
assert(led->blink_interval);
|
assert(led->blink_interval);
|
||||||
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
|
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
|
||||||
__change_bit(index, (unsigned long *)(&ledctl));
|
ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask);
|
||||||
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
|
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +62,8 @@ static void bcm43xx_led_blink(unsigned long d)
|
|||||||
static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
|
static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
|
||||||
unsigned long interval)
|
unsigned long interval)
|
||||||
{
|
{
|
||||||
|
if (led->blink_interval)
|
||||||
|
return;
|
||||||
led->blink_interval = interval;
|
led->blink_interval = interval;
|
||||||
bcm43xx_led_changestate(led);
|
bcm43xx_led_changestate(led);
|
||||||
led->blink_timer.expires = jiffies + interval;
|
led->blink_timer.expires = jiffies + interval;
|
||||||
@ -91,6 +94,39 @@ static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
|
|||||||
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
|
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
|
||||||
|
struct bcm43xx_led *led,
|
||||||
|
int led_index)
|
||||||
|
{
|
||||||
|
/* This function is called, if the behaviour (and activelow)
|
||||||
|
* information for a LED is missing in the SPROM.
|
||||||
|
* We hardcode the behaviour values for various devices here.
|
||||||
|
* Note that the BCM43xx_LED_TEST_XXX behaviour values can
|
||||||
|
* be used to figure out which led is mapped to which index.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (led_index) {
|
||||||
|
case 0:
|
||||||
|
led->behaviour = BCM43xx_LED_ACTIVITY;
|
||||||
|
if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
|
||||||
|
led->behaviour = BCM43xx_LED_RADIO_ALL;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
led->behaviour = BCM43xx_LED_RADIO_B;
|
||||||
|
if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
|
||||||
|
led->behaviour = BCM43xx_LED_ASSOC;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
led->behaviour = BCM43xx_LED_RADIO_A;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
led->behaviour = BCM43xx_LED_OFF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int bcm43xx_leds_init(struct bcm43xx_private *bcm)
|
int bcm43xx_leds_init(struct bcm43xx_private *bcm)
|
||||||
{
|
{
|
||||||
struct bcm43xx_led *led;
|
struct bcm43xx_led *led;
|
||||||
@ -105,31 +141,12 @@ int bcm43xx_leds_init(struct bcm43xx_private *bcm)
|
|||||||
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
|
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
|
||||||
led = &(bcm->leds[i]);
|
led = &(bcm->leds[i]);
|
||||||
led->bcm = bcm;
|
led->bcm = bcm;
|
||||||
init_timer(&led->blink_timer);
|
setup_timer(&led->blink_timer,
|
||||||
led->blink_timer.data = (unsigned long)led;
|
bcm43xx_led_blink,
|
||||||
led->blink_timer.function = bcm43xx_led_blink;
|
(unsigned long)led);
|
||||||
|
|
||||||
if (sprom[i] == 0xFF) {
|
if (sprom[i] == 0xFF) {
|
||||||
/* SPROM information not set. */
|
bcm43xx_led_init_hardcoded(bcm, led, i);
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
|
|
||||||
led->behaviour = BCM43xx_LED_RADIO_ALL;
|
|
||||||
else
|
|
||||||
led->behaviour = BCM43xx_LED_ACTIVITY;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
led->behaviour = BCM43xx_LED_RADIO_B;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
led->behaviour = BCM43xx_LED_RADIO_A;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
led->behaviour = BCM43xx_LED_OFF;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
|
led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
|
||||||
led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
|
led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
|
||||||
@ -157,19 +174,19 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
|
|||||||
struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
|
struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
|
||||||
struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
|
struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
|
||||||
const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
|
const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
|
||||||
int i, turn_on = 0;
|
int i, turn_on;
|
||||||
unsigned long interval = 0;
|
unsigned long interval = 0;
|
||||||
u16 ledctl;
|
u16 ledctl;
|
||||||
|
|
||||||
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
|
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
|
||||||
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
|
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
|
||||||
led = &(bcm->leds[i]);
|
led = &(bcm->leds[i]);
|
||||||
if (led->behaviour == BCM43xx_LED_INACTIVE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
turn_on = 0;
|
||||||
switch (led->behaviour) {
|
switch (led->behaviour) {
|
||||||
|
case BCM43xx_LED_INACTIVE:
|
||||||
|
continue;
|
||||||
case BCM43xx_LED_OFF:
|
case BCM43xx_LED_OFF:
|
||||||
turn_on = 0;
|
|
||||||
break;
|
break;
|
||||||
case BCM43xx_LED_ON:
|
case BCM43xx_LED_ON:
|
||||||
turn_on = 1;
|
turn_on = 1;
|
||||||
@ -189,7 +206,6 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
|
|||||||
phy->type == BCM43xx_PHYTYPE_G));
|
phy->type == BCM43xx_PHYTYPE_G));
|
||||||
break;
|
break;
|
||||||
case BCM43xx_LED_MODE_BG:
|
case BCM43xx_LED_MODE_BG:
|
||||||
turn_on = 0;
|
|
||||||
if (phy->type == BCM43xx_PHYTYPE_G &&
|
if (phy->type == BCM43xx_PHYTYPE_G &&
|
||||||
1/*FIXME: using G rates.*/)
|
1/*FIXME: using G rates.*/)
|
||||||
turn_on = 1;
|
turn_on = 1;
|
||||||
@ -222,12 +238,22 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
|
|||||||
continue;
|
continue;
|
||||||
case BCM43xx_LED_WEIRD:
|
case BCM43xx_LED_WEIRD:
|
||||||
//TODO
|
//TODO
|
||||||
turn_on = 0;
|
|
||||||
break;
|
break;
|
||||||
case BCM43xx_LED_ASSOC:
|
case BCM43xx_LED_ASSOC:
|
||||||
if (1/*TODO: associated*/)
|
if (bcm->softmac->associated)
|
||||||
turn_on = 1;
|
turn_on = 1;
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_BCM43XX_DEBUG
|
||||||
|
case BCM43xx_LED_TEST_BLINKSLOW:
|
||||||
|
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW);
|
||||||
|
continue;
|
||||||
|
case BCM43xx_LED_TEST_BLINKMEDIUM:
|
||||||
|
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
|
||||||
|
continue;
|
||||||
|
case BCM43xx_LED_TEST_BLINKFAST:
|
||||||
|
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST);
|
||||||
|
continue;
|
||||||
|
#endif /* CONFIG_BCM43XX_DEBUG */
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@ struct bcm43xx_led {
|
|||||||
#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
|
#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
|
||||||
|
|
||||||
/* Delay between state changes when blinking in jiffies */
|
/* Delay between state changes when blinking in jiffies */
|
||||||
#define BCM43xx_LEDBLINK_SLOW (HZ / 2)
|
#define BCM43xx_LEDBLINK_SLOW (HZ / 1)
|
||||||
#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
|
#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
|
||||||
#define BCM43xx_LEDBLINK_FAST (HZ / 8)
|
#define BCM43xx_LEDBLINK_FAST (HZ / 8)
|
||||||
|
|
||||||
@ -37,6 +37,15 @@ enum { /* LED behaviour values */
|
|||||||
BCM43xx_LED_WEIRD,//FIXME
|
BCM43xx_LED_WEIRD,//FIXME
|
||||||
BCM43xx_LED_ASSOC,
|
BCM43xx_LED_ASSOC,
|
||||||
BCM43xx_LED_INACTIVE,
|
BCM43xx_LED_INACTIVE,
|
||||||
|
|
||||||
|
/* Behaviour values for testing.
|
||||||
|
* With these values it is easier to figure out
|
||||||
|
* the real behaviour of leds, in case the SPROM
|
||||||
|
* is missing information.
|
||||||
|
*/
|
||||||
|
BCM43xx_LED_TEST_BLINKSLOW,
|
||||||
|
BCM43xx_LED_TEST_BLINKMEDIUM,
|
||||||
|
BCM43xx_LED_TEST_BLINKFAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
int bcm43xx_leds_init(struct bcm43xx_private *bcm);
|
int bcm43xx_leds_init(struct bcm43xx_private *bcm);
|
||||||
|
@ -1943,7 +1943,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
|
|||||||
bcm43xx_pio_rx(bcm->current_core->pio->queue0);
|
bcm43xx_pio_rx(bcm->current_core->pio->queue0);
|
||||||
else
|
else
|
||||||
bcm43xx_dma_rx(bcm->current_core->dma->rx_ring0);
|
bcm43xx_dma_rx(bcm->current_core->dma->rx_ring0);
|
||||||
activity = 1;
|
/* We intentionally don't set "activity" to 1, here. */
|
||||||
}
|
}
|
||||||
if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
|
if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
|
||||||
if (likely(bcm->current_core->rev < 5)) {
|
if (likely(bcm->current_core->rev < 5)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user