ath9k: Fix LED configuration
authorSujith Manoharan <c_manoha@qca.qualcomm.com>
Sun, 16 Nov 2014 00:41:02 +0000 (06:11 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 17 Nov 2014 20:32:16 +0000 (15:32 -0500)
On some x86 platforms, the LED gpio is active high
instead of active low. Identify such cards and modify
the GPIO usage to make sure LED works properly.

Cc: Russell Hu <rhu@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/pci.c

index d5a2019..0f6db12 100644 (file)
@@ -931,6 +931,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
 #define ATH9K_PCI_AR9565_2ANT     0x0100
 #define ATH9K_PCI_NO_PLL_PWRSAVE  0x0200
 #define ATH9K_PCI_KILLER          0x0400
+#define ATH9K_PCI_LED_ACT_HI      0x0800
 
 /*
  * Default cache line size, in bytes.
index b1956bf..2fef7a4 100644 (file)
@@ -25,7 +25,12 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
                               enum led_brightness brightness)
 {
        struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
-       ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
+       u32 val = (brightness == LED_OFF);
+
+       if (sc->sc_ah->config.led_active_high)
+               val = !val;
+
+       ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
 }
 
 void ath_deinit_leds(struct ath_softc *sc)
@@ -82,7 +87,7 @@ void ath_fill_led_pin(struct ath_softc *sc)
        ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 
        /* LED off, active low */
-       ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+       ath9k_hw_set_gpio(ah, ah->led_pin, (ah->config.led_active_high) ? 0 : 1);
 }
 #endif
 
index 55ee0a5..d2c0448 100644 (file)
@@ -329,6 +329,7 @@ struct ath9k_ops_config {
        bool alt_mingainidx;
        bool no_pll_pwrsave;
        bool tx_gain_buffalo;
+       bool led_active_high;
 };
 
 enum ath9k_int {
index 41736e5..39157ca 100644 (file)
@@ -441,6 +441,9 @@ static void ath9k_init_pcoem_platform(struct ath_softc *sc)
                ah->config.no_pll_pwrsave = true;
                ath_info(common, "Disable PLL PowerSave\n");
        }
+
+       if (sc->driver_data & ATH9K_PCI_LED_ACT_HI)
+               ah->config.led_active_high = true;
 }
 
 static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
index ca71f2f..5a2a8d2 100644 (file)
@@ -727,7 +727,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
        if (ah->led_pin >= 0) {
                ath9k_hw_cfg_output(ah, ah->led_pin,
                                    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-               ath9k_hw_set_gpio(ah, ah->led_pin, 0);
+               ath9k_hw_set_gpio(ah, ah->led_pin,
+                                 (ah->config.led_active_high) ? 1 : 0);
        }
 
        /*
@@ -869,7 +870,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
        spin_lock_bh(&sc->sc_pcu_lock);
 
        if (ah->led_pin >= 0) {
-               ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+               ath9k_hw_set_gpio(ah, ah->led_pin,
+                                 (ah->config.led_active_high) ? 0 : 1);
                ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
        }
 
index e3f60d5..f009b5b 100644 (file)
@@ -657,7 +657,9 @@ static const struct pci_device_id ath_pci_id_table[] = {
                         0x0036,
                         PCI_VENDOR_ID_DELL,
                         0x020E),
-         .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
+         .driver_data = ATH9K_PCI_AR9565_2ANT |
+                        ATH9K_PCI_BT_ANT_DIV |
+                        ATH9K_PCI_LED_ACT_HI},
 
        /* PCI-E AR9565 (WB335) */
        { PCI_VDEVICE(ATHEROS, 0x0036),