]> err.no Git - linux-2.6/commitdiff
[PATCH] bcm43xx: fix LED code.
authorMichael Buesch <mbuesch@freenet.de>
Sun, 12 Feb 2006 19:25:55 +0000 (20:25 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 27 Mar 2006 16:18:34 +0000 (11:18 -0500)
Signed-off-by: Michael Buesch <mbuesch@freenet.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/bcm43xx/bcm43xx_leds.c
drivers/net/wireless/bcm43xx/bcm43xx_leds.h
drivers/net/wireless/bcm43xx/bcm43xx_main.c

index 455a0c743f73ed4f163c2069aaa0aafcc0880ba2..8f550c1a92edd272714e29d1664a8283e022e6a1 100644 (file)
@@ -35,12 +35,13 @@ static void bcm43xx_led_changestate(struct bcm43xx_led *led)
 {
        struct bcm43xx_private *bcm = led->bcm;
        const int index = bcm43xx_led_index(led);
+       const u16 mask = (1 << index);
        u16 ledctl;
 
        assert(index >= 0 && index < BCM43xx_NR_LEDS);
        assert(led->blink_interval);
        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);
 }
 
@@ -61,6 +62,8 @@ static void bcm43xx_led_blink(unsigned long d)
 static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
                                    unsigned long interval)
 {
+       if (led->blink_interval)
+               return;
        led->blink_interval = interval;
        bcm43xx_led_changestate(led);
        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);
 }
 
+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)
 {
        struct bcm43xx_led *led;
@@ -105,31 +141,12 @@ int bcm43xx_leds_init(struct bcm43xx_private *bcm)
        for (i = 0; i < BCM43xx_NR_LEDS; i++) {
                led = &(bcm->leds[i]);
                led->bcm = bcm;
-               init_timer(&led->blink_timer);
-               led->blink_timer.data = (unsigned long)led;
-               led->blink_timer.function = bcm43xx_led_blink;
+               setup_timer(&led->blink_timer,
+                           bcm43xx_led_blink,
+                           (unsigned long)led);
 
                if (sprom[i] == 0xFF) {
-                       /* SPROM information not set. */
-                       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);
-                       }
+                       bcm43xx_led_init_hardcoded(bcm, led, i);
                } else {
                        led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
                        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_phyinfo *phy = bcm->current_core->phy;
        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;
        u16 ledctl;
 
        ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
        for (i = 0; i < BCM43xx_NR_LEDS; i++) {
                led = &(bcm->leds[i]);
-               if (led->behaviour == BCM43xx_LED_INACTIVE)
-                       continue;
 
+               turn_on = 0;
                switch (led->behaviour) {
+               case BCM43xx_LED_INACTIVE:
+                       continue;
                case BCM43xx_LED_OFF:
-                       turn_on = 0;
                        break;
                case BCM43xx_LED_ON:
                        turn_on = 1;
@@ -189,7 +206,6 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
                                    phy->type == BCM43xx_PHYTYPE_G));
                        break;
                case BCM43xx_LED_MODE_BG:
-                       turn_on = 0;
                        if (phy->type == BCM43xx_PHYTYPE_G &&
                            1/*FIXME: using G rates.*/)
                                turn_on = 1;
@@ -222,12 +238,22 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
                        continue;
                case BCM43xx_LED_WEIRD:
                        //TODO
-                       turn_on = 0;
                        break;
                case BCM43xx_LED_ASSOC:
-                       if (1/*TODO: associated*/)
+                       if (bcm->softmac->associated)
                                turn_on = 1;
                        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:
                        assert(0);
                };
index 489a2b1e9068ec225f0e24aa7dbaccd558c8ec88..6f18e2f95db46f83927f938df73da3fce627b0ff 100644 (file)
@@ -16,7 +16,7 @@ struct bcm43xx_led {
 #define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
 
 /* 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_FAST          (HZ / 8)
 
@@ -37,6 +37,15 @@ enum { /* LED behaviour values */
        BCM43xx_LED_WEIRD,//FIXME
        BCM43xx_LED_ASSOC,
        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);
index 4e49da99818d1acedfec3ed17430cacc2b44f20b..fbf931d4a135ac69194957bd0cfdb015e51d5308 100644 (file)
@@ -1943,7 +1943,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
                        bcm43xx_pio_rx(bcm->current_core->pio->queue0);
                else
                        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 (likely(bcm->current_core->rev < 5)) {