2016-03-07 02:38:43

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 0/8] ath9k GPIO & BT-Coex bug fixes

From: Miaoqing Pan <[email protected]>

ath9k GPIO & BT-Coex bug fixes.

Notes:
v2: fix build warning
v3: move changelog to cover letter
v4: fix [5/8] comments

Miaoqing Pan (8):
ath9k: define correct GPIO numbers and bits mask
ath9k: make GPIO API to support both of WMAC and SOC
ath9k: free GPIO resource for SOC GPIOs
ath9k: cleanup led_pin initial
ath9k: Allow platform override BTCoex pin
ath9k: add bits definition of BTCoex MODE2/3 for SOC chips
ath9k: fix BTCoex access invalid registers for SOC chips
ath9k: fix BTCoex configuration for SOC chips

drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 +-
drivers/net/wireless/ath/ath9k/ar9003_mci.c | 39 ++--
drivers/net/wireless/ath/ath9k/ath9k.h | 4 -
drivers/net/wireless/ath/ath9k/btcoex.c | 138 +++++++++----
drivers/net/wireless/ath/ath9k/btcoex.h | 2 +
drivers/net/wireless/ath/ath9k/gpio.c | 69 ++++---
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 8 +-
drivers/net/wireless/ath/ath9k/hw.c | 267 ++++++++++++++++---------
drivers/net/wireless/ath/ath9k/hw.h | 11 +-
drivers/net/wireless/ath/ath9k/init.c | 1 -
drivers/net/wireless/ath/ath9k/main.c | 9 +-
drivers/net/wireless/ath/ath9k/reg.h | 90 +++++++--
include/linux/ath9k_platform.h | 4 +
13 files changed, 436 insertions(+), 210 deletions(-)

--
1.9.1



2016-03-07 02:39:01

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 2/8] ath9k: make GPIO API to support both of WMAC and SOC

From: Miaoqing Pan <[email protected]>

commit 61b559dea40e ("ath9k: add extra GPIO led support")
added ath9k to support access SOC's GPIOs, but implemented
in a separated API: ath9k_hw_request_gpio().

So this patch make the APIs more common, to support both
of WMAC and SOC GPIOs. The new APIs as below,

void ath9k_hw_gpio_request_in();
void ath9k_hw_gpio_request_out();
void ath9k_hw_gpio_free();

NOTE, the BSP of the SOC chips(AR9340, AR9531, AR9550, AR9561)
should set the corresponding MUX registers correctly.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 4 +-
drivers/net/wireless/ath/ath9k/ar9003_mci.c | 39 +++--
drivers/net/wireless/ath/ath9k/btcoex.c | 27 ++--
drivers/net/wireless/ath/ath9k/gpio.c | 6 +-
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 6 +-
drivers/net/wireless/ath/ath9k/hw.c | 196 +++++++++++++++----------
drivers/net/wireless/ath/ath9k/hw.h | 10 +-
drivers/net/wireless/ath/ath9k/main.c | 6 +-
8 files changed, 174 insertions(+), 120 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 8b4561e..e434869 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3590,8 +3590,8 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
else
gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;

- ath9k_hw_cfg_output(ah, gpio,
- AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
+ ath9k_hw_gpio_request_out(ah, gpio, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
}

value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index af5ee41..0fe9c83 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -427,21 +427,34 @@ static void ar9003_mci_observation_set_up(struct ath_hw *ah)
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;

if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
- ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
- ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
- ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
- ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
+ ath9k_hw_gpio_request_out(ah, 3, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
+ ath9k_hw_gpio_request_out(ah, 2, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
+ ath9k_hw_gpio_request_out(ah, 1, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
+ ath9k_hw_gpio_request_out(ah, 0, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
} else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) {
- ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
- ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
- ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
- ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
- ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(ah, 3, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
+ ath9k_hw_gpio_request_out(ah, 2, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
+ ath9k_hw_gpio_request_out(ah, 1, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
+ ath9k_hw_gpio_request_out(ah, 0, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
+ ath9k_hw_gpio_request_out(ah, 5, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
} else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) {
- ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
- ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
- ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
- ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
+ ath9k_hw_gpio_request_out(ah, 3, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
+ ath9k_hw_gpio_request_out(ah, 2, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
+ ath9k_hw_gpio_request_out(ah, 1, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
+ ath9k_hw_gpio_request_out(ah, 0, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
} else
return;

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 5a084d9..7719cb1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -142,7 +142,8 @@ void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
btcoex_hw->btactive_gpio);

/* Configure the desired gpio port for input */
- ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btactive_gpio);
+ ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio,
+ "ath9k-btactive");
}
EXPORT_SYMBOL(ath9k_hw_btcoex_init_2wire);

@@ -166,9 +167,10 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
btcoex_hw->btpriority_gpio);

/* Configure the desired GPIO ports for input */
-
- ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btactive_gpio);
- ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btpriority_gpio);
+ ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio,
+ "ath9k-btactive");
+ ath9k_hw_gpio_request_in(ah, btcoex_hw->btpriority_gpio,
+ "ath9k-btpriority");
}
EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire);

@@ -201,8 +203,9 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;

/* Configure the desired GPIO port for TX_FRAME output */
- ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
- AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+ ath9k_hw_gpio_request_out(ah, btcoex_hw->wlanactive_gpio,
+ "ath9k-wlanactive",
+ AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
}

/*
@@ -271,7 +274,6 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
REG_WRITE(ah, AR_BT_COEX_MODE, btcoex->bt_coex_mode);
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);

-
if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, btcoex->wlan_weight[0]);
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, btcoex->wlan_weight[1]);
@@ -281,8 +283,6 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
} else
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex->bt_coex_weights);

-
-
if (AR_SREV_9271(ah)) {
val = REG_READ(ah, 0x50040);
val &= 0xFFFFFEFF;
@@ -292,8 +292,9 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);

- ath9k_hw_cfg_output(ah, btcoex->wlanactive_gpio,
- AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+ ath9k_hw_gpio_request_out(ah, btcoex->wlanactive_gpio,
+ "ath9k-wlanactive",
+ AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
}

static void ath9k_hw_btcoex_enable_mci(struct ath_hw *ah)
@@ -364,8 +365,8 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
if (!AR_SREV_9300_20_OR_LATER(ah))
ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0);

- ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(ah, btcoex_hw->wlanactive_gpio,
+ NULL, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);

if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 2847067..b41dfb7 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -74,7 +74,8 @@ void ath_fill_led_pin(struct ath_softc *sc)

if (ah->led_pin >= 0) {
if (!((1 << ah->led_pin) & AR_GPIO_OE_OUT_MASK))
- ath9k_hw_request_gpio(ah, ah->led_pin, "ath9k-led");
+ ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
return;
}

@@ -90,7 +91,8 @@ void ath_fill_led_pin(struct ath_softc *sc)
ah->led_pin = ATH_LED_PIN_DEF;

/* Configure gpio 1 for output */
- ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);

/* LED off, active low */
ath9k_hw_set_gpio(ah, ah->led_pin, (ah->config.led_active_high) ? 0 : 1);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 2aabcbd..d9b640a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -259,11 +259,11 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
void ath9k_configure_leds(struct ath9k_htc_priv *priv)
{
/* Configure gpio 1 for output */
- ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(priv->ah, priv->ah->led_pin,
+ "ath9k-led",
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
/* LED off, active low */
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
-
}

void ath9k_init_leds(struct ath9k_htc_priv *priv)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0e80b3f..4046949 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1572,7 +1572,8 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
if (!(gpio_mask & 1))
continue;

- ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(ah, i, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
}
}
@@ -1948,7 +1949,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_init_qos(ah);

if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+ ath9k_hw_gpio_request_in(ah, ah->rfkill_gpio, "ath9k-rfkill");

ath9k_hw_init_global_settings(ah);

@@ -2644,8 +2645,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
/* GPIO / RFKILL / Antennae */
/****************************/

-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
- u32 gpio, u32 type)
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, u32 gpio, u32 type)
{
int addr;
u32 gpio_shift, tmp;
@@ -2659,8 +2659,8 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,

gpio_shift = (gpio % 6) * 5;

- if (AR_SREV_9280_20_OR_LATER(ah)
- || (addr != AR_GPIO_OUTPUT_MUX1)) {
+ if (AR_SREV_9280_20_OR_LATER(ah) ||
+ (addr != AR_GPIO_OUTPUT_MUX1)) {
REG_RMW(ah, addr, (type << gpio_shift),
(0x1f << gpio_shift));
} else {
@@ -2672,106 +2672,144 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
}
}

-void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
+/* BSP should set the corresponding MUX register correctly.
+ */
+static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out,
+ const char *label)
{
- u32 gpio_shift;
+ if (ah->caps.gpio_requested & BIT(gpio))
+ return;

- BUG_ON(gpio >= ah->caps.num_gpio_pins);
+ /* may be requested by BSP, free anyway */
+ gpio_free(gpio);

- if (AR_DEVID_7010(ah)) {
- gpio_shift = gpio;
- REG_RMW(ah, AR7010_GPIO_OE,
- (AR7010_GPIO_OE_AS_INPUT << gpio_shift),
- (AR7010_GPIO_OE_MASK << gpio_shift));
+ if (gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label))
return;
- }

- gpio_shift = gpio << 1;
- REG_RMW(ah,
- AR_GPIO_OE_OUT,
- (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
- (AR_GPIO_OE_OUT_DRV << gpio_shift));
+ ah->caps.gpio_requested |= BIT(gpio);
}
-EXPORT_SYMBOL(ath9k_hw_cfg_gpio_input);

-u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
+static void ath9k_hw_gpio_cfg_wmac(struct ath_hw *ah, u32 gpio, bool out,
+ u32 ah_signal_type)
{
-#define MS_REG_READ(x, y) \
- (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
-
- if (gpio >= ah->caps.num_gpio_pins)
- return 0xffffffff;
+ u32 gpio_set, gpio_shift = gpio;

if (AR_DEVID_7010(ah)) {
- u32 val;
- val = REG_READ(ah, AR7010_GPIO_IN);
- return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
- } else if (AR_SREV_9300_20_OR_LATER(ah))
- return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
- AR_GPIO_BIT(gpio)) != 0;
- else if (AR_SREV_9271(ah))
- return MS_REG_READ(AR9271, gpio) != 0;
- else if (AR_SREV_9287_11_OR_LATER(ah))
- return MS_REG_READ(AR9287, gpio) != 0;
- else if (AR_SREV_9285_12_OR_LATER(ah))
- return MS_REG_READ(AR9285, gpio) != 0;
- else if (AR_SREV_9280_20_OR_LATER(ah))
- return MS_REG_READ(AR928X, gpio) != 0;
- else
- return MS_REG_READ(AR, gpio) != 0;
+ gpio_set = out ?
+ AR7010_GPIO_OE_AS_OUTPUT : AR7010_GPIO_OE_AS_INPUT;
+ REG_RMW(ah, AR7010_GPIO_OE, gpio_set << gpio_shift,
+ AR7010_GPIO_OE_MASK << gpio_shift);
+ } else if (AR_SREV_SOC(ah)) {
+ gpio_set = out ? 1 : 0;
+ REG_RMW(ah, AR_GPIO_OE_OUT, gpio_set << gpio_shift,
+ gpio_set << gpio_shift);
+ } else {
+ gpio_shift = gpio << 1;
+ gpio_set = out ?
+ AR_GPIO_OE_OUT_DRV_ALL : AR_GPIO_OE_OUT_DRV_NO;
+ REG_RMW(ah, AR_GPIO_OE_OUT, gpio_set << gpio_shift,
+ AR_GPIO_OE_OUT_DRV << gpio_shift);
+
+ if (out)
+ ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
+ }
}
-EXPORT_SYMBOL(ath9k_hw_gpio_get);

-void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
- u32 ah_signal_type)
+static void ath9k_hw_gpio_request(struct ath_hw *ah, u32 gpio, bool out,
+ const char *label, u32 ah_signal_type)
{
- u32 gpio_shift;
+ WARN_ON(gpio >= ah->caps.num_gpio_pins);

- if (AR_DEVID_7010(ah)) {
- gpio_shift = gpio;
- REG_RMW(ah, AR7010_GPIO_OE,
- (AR7010_GPIO_OE_AS_OUTPUT << gpio_shift),
- (AR7010_GPIO_OE_MASK << gpio_shift));
- return;
- }
+ if (BIT(gpio) & ah->caps.gpio_mask)
+ ath9k_hw_gpio_cfg_wmac(ah, gpio, out, ah_signal_type);
+ else if (AR_SREV_SOC(ah))
+ ath9k_hw_gpio_cfg_soc(ah, gpio, out, label);
+ else
+ WARN_ON(1);
+}

- ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
- gpio_shift = 2 * gpio;
- REG_RMW(ah,
- AR_GPIO_OE_OUT,
- (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
- (AR_GPIO_OE_OUT_DRV << gpio_shift));
+void ath9k_hw_gpio_request_in(struct ath_hw *ah, u32 gpio, const char *label)
+{
+ ath9k_hw_gpio_request(ah, gpio, false, label, 0);
}
-EXPORT_SYMBOL(ath9k_hw_cfg_output);
+EXPORT_SYMBOL(ath9k_hw_gpio_request_in);

-void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
+void ath9k_hw_gpio_request_out(struct ath_hw *ah, u32 gpio, const char *label,
+ u32 ah_signal_type)
{
- if (AR_DEVID_7010(ah)) {
- val = val ? 0 : 1;
- REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio),
- AR_GPIO_BIT(gpio));
+ ath9k_hw_gpio_request(ah, gpio, true, label, ah_signal_type);
+}
+EXPORT_SYMBOL(ath9k_hw_gpio_request_out);
+
+void ath9k_hw_gpio_free(struct ath_hw *ah, u32 gpio)
+{
+ if (!AR_SREV_SOC(ah))
return;
+
+ WARN_ON(gpio >= ah->caps.num_gpio_pins);
+
+ if (ah->caps.gpio_requested & BIT(gpio)) {
+ gpio_free(gpio);
+ ah->caps.gpio_requested &= ~BIT(gpio);
}
+}
+EXPORT_SYMBOL(ath9k_hw_gpio_free);

- if (AR_SREV_9271(ah))
- val = ~val;
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
+{
+ u32 val = 0xffffffff;

- if ((1 << gpio) & AR_GPIO_OE_OUT_MASK)
- REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
- AR_GPIO_BIT(gpio));
- else
- gpio_set_value(gpio, val & 1);
+#define MS_REG_READ(x, y) \
+ (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & BIT(y))
+
+ WARN_ON(gpio >= ah->caps.num_gpio_pins);
+
+ if (BIT(gpio) & ah->caps.gpio_mask) {
+ if (AR_SREV_9271(ah))
+ val = MS_REG_READ(AR9271, gpio);
+ else if (AR_SREV_9287(ah))
+ val = MS_REG_READ(AR9287, gpio);
+ else if (AR_SREV_9285(ah))
+ val = MS_REG_READ(AR9285, gpio);
+ else if (AR_SREV_9280(ah))
+ val = MS_REG_READ(AR928X, gpio);
+ else if (AR_DEVID_7010(ah))
+ val = REG_READ(ah, AR7010_GPIO_IN) & BIT(gpio);
+ else if (AR_SREV_9300_20_OR_LATER(ah))
+ val = REG_READ(ah, AR_GPIO_IN) & BIT(gpio);
+ else
+ val = MS_REG_READ(AR, gpio);
+ } else if (BIT(gpio) & ah->caps.gpio_requested) {
+ val = gpio_get_value(gpio) & BIT(gpio);
+ } else {
+ WARN_ON(1);
+ }
+
+ return val;
}
-EXPORT_SYMBOL(ath9k_hw_set_gpio);
+EXPORT_SYMBOL(ath9k_hw_gpio_get);

-void ath9k_hw_request_gpio(struct ath_hw *ah, u32 gpio, const char *label)
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
{
- if (gpio >= ah->caps.num_gpio_pins)
- return;
+ WARN_ON(gpio >= ah->caps.num_gpio_pins);

- gpio_request_one(gpio, GPIOF_DIR_OUT | GPIOF_INIT_LOW, label);
+ if (AR_DEVID_7010(ah) || AR_SREV_9271(ah))
+ val = !val;
+ else
+ val = !!val;
+
+ if (BIT(gpio) & ah->caps.gpio_mask) {
+ u32 out_addr = AR_DEVID_7010(ah) ?
+ AR7010_GPIO_OUT : AR_GPIO_IN_OUT;
+
+ REG_RMW(ah, out_addr, val << gpio, BIT(gpio));
+ } else if (BIT(gpio) & ah->caps.gpio_requested) {
+ gpio_set_value(gpio, val);
+ } else {
+ WARN_ON(1);
+ }
}
-EXPORT_SYMBOL(ath9k_hw_request_gpio);
+EXPORT_SYMBOL(ath9k_hw_set_gpio);

void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
{
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c0740d6..9cbca12 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -160,7 +160,6 @@
#define AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA 0x1e

#define AR_GPIOD_MASK 0x00001FFF
-#define AR_GPIO_BIT(_gpio) (1 << (_gpio))

#define BASE_ACTIVATE_DELAY 100
#define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100)
@@ -302,6 +301,7 @@ struct ath9k_hw_capabilities {
u8 max_rxchains;
u8 num_gpio_pins;
u32 gpio_mask;
+ u32 gpio_requested;
u8 rx_hp_qdepth;
u8 rx_lp_qdepth;
u8 rx_status_len;
@@ -1020,12 +1020,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah);
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);

/* GPIO / RFKILL / Antennae */
-void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_gpio_request_in(struct ath_hw *ah, u32 gpio, const char *label);
+void ath9k_hw_gpio_request_out(struct ath_hw *ah, u32 gpio, const char *label,
+ u32 ah_signal_type);
+void ath9k_hw_gpio_free(struct ath_hw *ah, u32 gpio);
u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
-void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
- u32 ah_signal_type);
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
-void ath9k_hw_request_gpio(struct ath_hw *ah, u32 gpio, const char *label);
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);

/* General Operation */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c1b33fd..95d0a53 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -719,10 +719,10 @@ static int ath9k_start(struct ieee80211_hw *hw)
ah->reset_power_on = false;

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,
(ah->config.led_active_high) ? 1 : 0);
+ ath9k_hw_gpio_request_out(ah, ah->led_pin, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
}

/*
@@ -870,7 +870,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
if (ah->led_pin >= 0) {
ath9k_hw_set_gpio(ah, ah->led_pin,
(ah->config.led_active_high) ? 0 : 1);
- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
+ ath9k_hw_gpio_request_in(ah, ah->led_pin, NULL);
}

ath_prepare_reset(sc);
--
1.9.1


2016-03-07 02:39:28

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 8/8] ath9k: fix BTCoex configuration for SOC chips

From: Miaoqing Pan <[email protected]>

Allow to set wl_active_time and wl_qc_time for SOC chips, also adjust
bt_time_extend and bt_first_slot_time.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 31 ++++++++++++++++++++++++++++---
drivers/net/wireless/ath/ath9k/btcoex.h | 1 +
2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index d46cd31..618c9df 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -36,6 +36,8 @@ struct ath_btcoex_config {
u8 bt_priority_time;
u8 bt_first_slot_time;
bool bt_hold_rx_clear;
+ u8 wl_active_time;
+ u8 wl_qc_time;
};

static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX]
@@ -67,25 +69,42 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
.bt_priority_time = 2,
.bt_first_slot_time = 5,
.bt_hold_rx_clear = true,
+ .wl_active_time = 0x20,
+ .wl_qc_time = 0x20,
};
bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
+ u8 time_extend = ath_bt_config.bt_time_extend;
+ u8 first_slot_time = ath_bt_config.bt_first_slot_time;

if (AR_SREV_9300_20_OR_LATER(ah))
rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;

+ if (AR_SREV_SOC(ah)) {
+ first_slot_time = 0x1d;
+ time_extend = 0xa;
+
+ btcoex_hw->bt_coex_mode3 =
+ SM(ath_bt_config.wl_active_time, AR_BT_WL_ACTIVE_TIME) |
+ SM(ath_bt_config.wl_qc_time, AR_BT_WL_QC_TIME);
+
+ btcoex_hw->bt_coex_mode2 =
+ AR_BT_PROTECT_BT_AFTER_WAKEUP |
+ AR_BT_PHY_ERR_BT_COLL_ENABLE;
+ }
+
btcoex_hw->bt_coex_mode =
(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
- SM(ath_bt_config.bt_time_extend, AR_BT_TIME_EXTEND) |
+ SM(time_extend, AR_BT_TIME_EXTEND) |
SM(ath_bt_config.bt_txstate_extend, AR_BT_TXSTATE_EXTEND) |
SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
SM(ath_bt_config.bt_mode, AR_BT_MODE) |
SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
- SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
+ SM(first_slot_time, AR_BT_FIRST_SLOT_TIME) |
SM(qnum, AR_BT_QCU_THRESH);

- btcoex_hw->bt_coex_mode2 =
+ btcoex_hw->bt_coex_mode2 |=
SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) |
SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
AR_BT_DISABLE_BT_ANT;
@@ -308,9 +327,15 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
* Program coex mode and weight registers to
* enable coex 3-wire
*/
+ if (AR_SREV_SOC(ah))
+ REG_CLR_BIT(ah, AR_BT_COEX_MODE2, AR_BT_PHY_ERR_BT_COLL_ENABLE);
+
REG_WRITE(ah, AR_BT_COEX_MODE, btcoex->bt_coex_mode);
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);

+ if (AR_SREV_SOC(ah))
+ REG_WRITE(ah, AR_BT_COEX_MODE3, btcoex->bt_coex_mode3);
+
if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, btcoex->wlan_weight[0]);
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, btcoex->wlan_weight[1]);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 0f7c4e6..1bdfa84 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -115,6 +115,7 @@ struct ath_btcoex_hw {
u32 bt_coex_mode; /* Register setting for AR_BT_COEX_MODE */
u32 bt_coex_weights; /* Register setting for AR_BT_COEX_WEIGHT */
u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
+ u32 bt_coex_mode3; /* Register setting for AR_BT_COEX_MODE3 */
u32 bt_weight[AR9300_NUM_BT_WEIGHTS];
u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
u8 tx_prio[ATH_BTCOEX_STOMP_MAX];
--
1.9.1


2016-03-11 12:19:41

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v4 0/8] ath9k GPIO & BT-Coex bug fixes

[email protected] writes:

> From: Miaoqing Pan <[email protected]>
>
> ath9k GPIO & BT-Coex bug fixes.
>
> Notes:
> v2: fix build warning
> v3: move changelog to cover letter
> v4: fix [5/8] comments
>
> Miaoqing Pan (8):
> ath9k: define correct GPIO numbers and bits mask
> ath9k: make GPIO API to support both of WMAC and SOC
> ath9k: free GPIO resource for SOC GPIOs
> ath9k: cleanup led_pin initial
> ath9k: Allow platform override BTCoex pin
> ath9k: add bits definition of BTCoex MODE2/3 for SOC chips
> ath9k: fix BTCoex access invalid registers for SOC chips
> ath9k: fix BTCoex configuration for SOC chips

Applied to ath.git, thanks.

--
Kalle Valo

2016-03-07 02:38:49

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 1/8] ath9k: define correct GPIO numbers and bits mask

From: Miaoqing Pan <[email protected]>

Define correct GPIO numbers and MASK bits to indicate the WMAC
GPIO resource.

Allow SOC chips(AR9340, AR9531, AR9550, AR9561) to access all GPIOs
which rely on gpiolib framework. But restrict SOC AR9330 only to
access WMAC GPIO which has the same design with the old chips.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 70 ++++++++++++++++++++++++++++--------
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/reg.h | 42 ++++++++++++++++++++--
3 files changed, 96 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 257f46e..0e80b3f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2375,6 +2375,61 @@ static bool ath9k_hw_dfs_tested(struct ath_hw *ah)
}
}

+static void ath9k_gpio_cap_init(struct ath_hw *ah)
+{
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+ if (AR_SREV_9271(ah)) {
+ pCap->num_gpio_pins = AR9271_NUM_GPIO;
+ pCap->gpio_mask = AR9271_GPIO_MASK;
+ } else if (AR_DEVID_7010(ah)) {
+ pCap->num_gpio_pins = AR7010_NUM_GPIO;
+ pCap->gpio_mask = AR7010_GPIO_MASK;
+ } else if (AR_SREV_9287(ah)) {
+ pCap->num_gpio_pins = AR9287_NUM_GPIO;
+ pCap->gpio_mask = AR9287_GPIO_MASK;
+ } else if (AR_SREV_9285(ah)) {
+ pCap->num_gpio_pins = AR9285_NUM_GPIO;
+ pCap->gpio_mask = AR9285_GPIO_MASK;
+ } else if (AR_SREV_9280(ah)) {
+ pCap->num_gpio_pins = AR9280_NUM_GPIO;
+ pCap->gpio_mask = AR9280_GPIO_MASK;
+ } else if (AR_SREV_9300(ah)) {
+ pCap->num_gpio_pins = AR9300_NUM_GPIO;
+ pCap->gpio_mask = AR9300_GPIO_MASK;
+ } else if (AR_SREV_9330(ah)) {
+ pCap->num_gpio_pins = AR9330_NUM_GPIO;
+ pCap->gpio_mask = AR9330_GPIO_MASK;
+ } else if (AR_SREV_9340(ah)) {
+ pCap->num_gpio_pins = AR9340_NUM_GPIO;
+ pCap->gpio_mask = AR9340_GPIO_MASK;
+ } else if (AR_SREV_9462(ah)) {
+ pCap->num_gpio_pins = AR9462_NUM_GPIO;
+ pCap->gpio_mask = AR9462_GPIO_MASK;
+ } else if (AR_SREV_9485(ah)) {
+ pCap->num_gpio_pins = AR9485_NUM_GPIO;
+ pCap->gpio_mask = AR9485_GPIO_MASK;
+ } else if (AR_SREV_9531(ah)) {
+ pCap->num_gpio_pins = AR9531_NUM_GPIO;
+ pCap->gpio_mask = AR9531_GPIO_MASK;
+ } else if (AR_SREV_9550(ah)) {
+ pCap->num_gpio_pins = AR9550_NUM_GPIO;
+ pCap->gpio_mask = AR9550_GPIO_MASK;
+ } else if (AR_SREV_9561(ah)) {
+ pCap->num_gpio_pins = AR9561_NUM_GPIO;
+ pCap->gpio_mask = AR9561_GPIO_MASK;
+ } else if (AR_SREV_9565(ah)) {
+ pCap->num_gpio_pins = AR9565_NUM_GPIO;
+ pCap->gpio_mask = AR9565_GPIO_MASK;
+ } else if (AR_SREV_9580(ah)) {
+ pCap->num_gpio_pins = AR9580_NUM_GPIO;
+ pCap->gpio_mask = AR9580_GPIO_MASK;
+ } else {
+ pCap->num_gpio_pins = AR_NUM_GPIO;
+ pCap->gpio_mask = AR_GPIO_MASK;
+ }
+}
+
int ath9k_hw_fill_cap_info(struct ath_hw *ah)
{
struct ath9k_hw_capabilities *pCap = &ah->caps;
@@ -2468,20 +2523,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->hw_caps &= ~ATH9K_HW_CAP_HT;

- if (AR_SREV_9271(ah))
- pCap->num_gpio_pins = AR9271_NUM_GPIO;
- else if (AR_DEVID_7010(ah))
- pCap->num_gpio_pins = AR7010_NUM_GPIO;
- else if (AR_SREV_9300_20_OR_LATER(ah))
- pCap->num_gpio_pins = AR9300_NUM_GPIO;
- else if (AR_SREV_9287_11_OR_LATER(ah))
- pCap->num_gpio_pins = AR9287_NUM_GPIO;
- else if (AR_SREV_9285_12_OR_LATER(ah))
- pCap->num_gpio_pins = AR9285_NUM_GPIO;
- else if (AR_SREV_9280_20_OR_LATER(ah))
- pCap->num_gpio_pins = AR928X_NUM_GPIO;
- else
- pCap->num_gpio_pins = AR_NUM_GPIO;
+ ath9k_gpio_cap_init(ah);

if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah))
pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 831a544..c0740d6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -301,6 +301,7 @@ struct ath9k_hw_capabilities {
u8 max_txchains;
u8 max_rxchains;
u8 num_gpio_pins;
+ u32 gpio_mask;
u8 rx_hp_qdepth;
u8 rx_lp_qdepth;
u8 rx_status_len;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index caba54d..8903f70 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -983,6 +983,10 @@
#define AR_SREV_9561(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9561))

+#define AR_SREV_SOC(_ah) \
+ (AR_SREV_9340(_ah) || AR_SREV_9531(_ah) || AR_SREV_9550(ah) || \
+ AR_SREV_9561(ah))
+
/* NOTE: When adding chips newer than Peacock, add chip check here */
#define AR_SREV_9580_10_OR_LATER(_ah) \
(AR_SREV_9580(_ah))
@@ -1102,14 +1106,46 @@ enum {

#define AR_PCIE_PHY_REG3 0x18c08

+/* Define correct GPIO numbers and MASK bits to indicate the WMAC
+ * GPIO resource.
+ * Allow SOC chips(AR9340, AR9531, AR9550, AR9561) to access all GPIOs
+ * which rely on gpiolib framework. But restrict SOC AR9330 only to
+ * access WMAC GPIO which has the same design with the old chips.
+ */
#define AR_NUM_GPIO 14
-#define AR928X_NUM_GPIO 10
+#define AR9280_NUM_GPIO 10
#define AR9285_NUM_GPIO 12
-#define AR9287_NUM_GPIO 11
+#define AR9287_NUM_GPIO 10
#define AR9271_NUM_GPIO 16
-#define AR9300_NUM_GPIO 17
+#define AR9300_NUM_GPIO 16
+#define AR9330_NUM_GPIO 16
+#define AR9340_NUM_GPIO 23
+#define AR9462_NUM_GPIO 10
+#define AR9485_NUM_GPIO 12
+#define AR9531_NUM_GPIO 18
+#define AR9550_NUM_GPIO 24
+#define AR9561_NUM_GPIO 23
+#define AR9565_NUM_GPIO 12
+#define AR9580_NUM_GPIO 16
#define AR7010_NUM_GPIO 16

+#define AR_GPIO_MASK 0x00003FFF
+#define AR9271_GPIO_MASK 0x0000FFFF
+#define AR9280_GPIO_MASK 0x000003FF
+#define AR9285_GPIO_MASK 0x00000FFF
+#define AR9287_GPIO_MASK 0x000003FF
+#define AR9300_GPIO_MASK 0x0000F4FF
+#define AR9330_GPIO_MASK 0x0000F4FF
+#define AR9340_GPIO_MASK 0x0000000F
+#define AR9462_GPIO_MASK 0x000003FF
+#define AR9485_GPIO_MASK 0x00000FFF
+#define AR9531_GPIO_MASK 0x0000000F
+#define AR9550_GPIO_MASK 0x0000000F
+#define AR9561_GPIO_MASK 0x0000000F
+#define AR9565_GPIO_MASK 0x00000FFF
+#define AR9580_GPIO_MASK 0x0000F4FF
+#define AR7010_GPIO_MASK 0x0000FFFF
+
#define AR_GPIO_IN_OUT (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
#define AR_GPIO_IN_VAL 0x0FFFC000
#define AR_GPIO_IN_VAL_S 14
--
1.9.1


2016-03-07 02:39:12

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 5/8] ath9k: Allow platform override BTCoex pin

From: Miaoqing Pan <[email protected]>

Add new platform data to allow override BTCoex default pin.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 45 +++++++++++++++++++++++++--------
include/linux/ath9k_platform.h | 4 +++
2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 4737aa9..95a810b 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -15,6 +15,8 @@
*/

#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/ath9k_platform.h>
#include "hw.h"

enum ath_bt_mode {
@@ -90,6 +92,29 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
}
EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);

+static void ath9k_hw_btcoex_pin_init(struct ath_hw *ah, u8 wlanactive_gpio,
+ u8 btactive_gpio, u8 btpriority_gpio)
+{
+ struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+ struct ath9k_platform_data *pdata = ah->dev->platform_data;
+
+ if (btcoex_hw->scheme != ATH_BTCOEX_CFG_2WIRE &&
+ btcoex_hw->scheme != ATH_BTCOEX_CFG_3WIRE)
+ return;
+
+ /* bt priority GPIO will be ignored by 2 wire scheme */
+ if (pdata && (pdata->bt_active_pin || pdata->bt_priority_pin ||
+ pdata->wlan_active_pin)) {
+ btcoex_hw->btactive_gpio = pdata->bt_active_pin;
+ btcoex_hw->wlanactive_gpio = pdata->wlan_active_pin;
+ btcoex_hw->btpriority_gpio = pdata->bt_priority_pin;
+ } else {
+ btcoex_hw->btactive_gpio = btactive_gpio;
+ btcoex_hw->wlanactive_gpio = wlanactive_gpio;
+ btcoex_hw->btpriority_gpio = btpriority_gpio;
+ }
+}
+
void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -107,19 +132,19 @@ void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
} else if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
- btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
- btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
- btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
- } else if (AR_SREV_9280_20_OR_LATER(ah)) {
- btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
- btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;

- if (AR_SREV_9285(ah)) {
+ ath9k_hw_btcoex_pin_init(ah, ATH_WLANACTIVE_GPIO_9300,
+ ATH_BTACTIVE_GPIO_9300,
+ ATH_BTPRIORITY_GPIO_9300);
+ } else if (AR_SREV_9280_20_OR_LATER(ah)) {
+ if (AR_SREV_9285(ah))
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
- btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9285;
- } else {
+ else
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
- }
+
+ ath9k_hw_btcoex_pin_init(ah, ATH_WLANACTIVE_GPIO_9280,
+ ATH_BTACTIVE_GPIO_9280,
+ ATH_BTPRIORITY_GPIO_9285);
}
}
EXPORT_SYMBOL(ath9k_hw_btcoex_init_scheme);
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index 33eb274..e66153d 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -31,6 +31,10 @@ struct ath9k_platform_data {
u32 gpio_mask;
u32 gpio_val;

+ u32 bt_active_pin;
+ u32 bt_priority_pin;
+ u32 wlan_active_pin;
+
bool endian_check;
bool is_clk_25mhz;
bool tx_gain_buffalo;
--
1.9.1


2016-03-07 02:39:08

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 4/8] ath9k: cleanup led_pin initial

From: Miaoqing Pan <[email protected]>

Make ath_init_leds() and ath_deinit_leds() pairs as the only
API to set leds, also removed direction configuration from
ath9k_start() and ath9k_stop(). So the initial is more clear
now.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 4 ---
drivers/net/wireless/ath/ath9k/gpio.c | 62 ++++++++++++++++------------------
drivers/net/wireless/ath/ath9k/init.c | 1 -
drivers/net/wireless/ath/ath9k/main.c | 9 ++---
drivers/net/wireless/ath/ath9k/reg.h | 2 --
5 files changed, 31 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 5294595..93b3793 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -813,7 +813,6 @@ static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size)
#ifdef CONFIG_MAC80211_LEDS
void ath_init_leds(struct ath_softc *sc);
void ath_deinit_leds(struct ath_softc *sc);
-void ath_fill_led_pin(struct ath_softc *sc);
#else
static inline void ath_init_leds(struct ath_softc *sc)
{
@@ -822,9 +821,6 @@ static inline void ath_init_leds(struct ath_softc *sc)
static inline void ath_deinit_leds(struct ath_softc *sc)
{
}
-static inline void ath_fill_led_pin(struct ath_softc *sc)
-{
-}
#endif

/************************/
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 4964bb3..490f74d 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -21,6 +21,33 @@
/********************************/

#ifdef CONFIG_MAC80211_LEDS
+
+void ath_fill_led_pin(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+
+ /* Set default led pin if invalid */
+ if (ah->led_pin < 0) {
+ if (AR_SREV_9287(ah))
+ ah->led_pin = ATH_LED_PIN_9287;
+ else if (AR_SREV_9485(ah))
+ ah->led_pin = ATH_LED_PIN_9485;
+ else if (AR_SREV_9300(ah))
+ ah->led_pin = ATH_LED_PIN_9300;
+ else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
+ ah->led_pin = ATH_LED_PIN_9462;
+ else
+ ah->led_pin = ATH_LED_PIN_DEF;
+ }
+
+ /* Configure gpio for output */
+ ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+
+ /* LED off, active low */
+ ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1);
+}
+
static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
@@ -51,6 +78,8 @@ void ath_init_leds(struct ath_softc *sc)
if (AR_SREV_9100(sc->sc_ah))
return;

+ ath_fill_led_pin(sc);
+
if (!ath9k_led_blink)
sc->led_cdev.default_trigger =
ieee80211_get_radio_led_name(sc->hw);
@@ -66,39 +95,6 @@ void ath_init_leds(struct ath_softc *sc)

sc->led_registered = true;
}
-
-void ath_fill_led_pin(struct ath_softc *sc)
-{
- struct ath_hw *ah = sc->sc_ah;
-
- if (AR_SREV_9100(ah))
- return;
-
- if (ah->led_pin >= 0) {
- if (!((1 << ah->led_pin) & AR_GPIO_OE_OUT_MASK))
- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- return;
- }
-
- if (AR_SREV_9287(ah))
- ah->led_pin = ATH_LED_PIN_9287;
- else if (AR_SREV_9485(sc->sc_ah))
- ah->led_pin = ATH_LED_PIN_9485;
- else if (AR_SREV_9300(sc->sc_ah))
- ah->led_pin = ATH_LED_PIN_9300;
- else if (AR_SREV_9462(sc->sc_ah) || AR_SREV_9565(sc->sc_ah))
- ah->led_pin = ATH_LED_PIN_9462;
- else
- ah->led_pin = ATH_LED_PIN_DEF;
-
- /* Configure gpio 1 for output */
- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-
- /* LED off, active low */
- ath9k_hw_set_gpio(ah, ah->led_pin, (ah->config.led_active_high) ? 0 : 1);
-}
#endif

/*******************/
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 2e2b92b..95c12fd 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -660,7 +660,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,

ath9k_cmn_init_crypto(sc->sc_ah);
ath9k_init_misc(sc);
- ath_fill_led_pin(sc);
ath_chanctx_init(sc);
ath9k_offchannel_init(sc);

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 95d0a53..f469a7c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -718,12 +718,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (!ath_complete_reset(sc, false))
ah->reset_power_on = false;

- if (ah->led_pin >= 0) {
+ if (ah->led_pin >= 0)
ath9k_hw_set_gpio(ah, ah->led_pin,
(ah->config.led_active_high) ? 1 : 0);
- ath9k_hw_gpio_request_out(ah, ah->led_pin, NULL,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- }

/*
* Reset key cache to sane defaults (all entries cleared) instead of
@@ -867,11 +864,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)

spin_lock_bh(&sc->sc_pcu_lock);

- if (ah->led_pin >= 0) {
+ if (ah->led_pin >= 0)
ath9k_hw_set_gpio(ah, ah->led_pin,
(ah->config.led_active_high) ? 0 : 1);
- ath9k_hw_gpio_request_in(ah, ah->led_pin, NULL);
- }

ath_prepare_reset(sc);

diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8903f70..f82a4ad 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1166,8 +1166,6 @@ enum {

#define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c))
-#define AR_GPIO_OE_OUT_MASK (AR_SREV_9550_OR_LATER(ah) ? \
- 0x0000000F : 0xFFFFFFFF)
#define AR_GPIO_OE_OUT_DRV 0x3
#define AR_GPIO_OE_OUT_DRV_NO 0x0
#define AR_GPIO_OE_OUT_DRV_LOW 0x1
--
1.9.1


2016-03-07 02:39:01

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 3/8] ath9k: free GPIO resource for SOC GPIOs

From: Miaoqing Pan <[email protected]>

For SOC GPIOs, should call ath9k_hw_gpio_free() to release
the GPIO resource.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 10 ++++++++++
drivers/net/wireless/ath/ath9k/btcoex.h | 1 +
drivers/net/wireless/ath/ath9k/gpio.c | 9 +++++++++
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 2 ++
drivers/net/wireless/ath/ath9k/hw.c | 1 +
5 files changed, 23 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 7719cb1..4737aa9 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -174,6 +174,16 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire);

+void ath9k_hw_btcoex_deinit(struct ath_hw *ah)
+{
+ struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
+
+ ath9k_hw_gpio_free(ah, btcoex_hw->btactive_gpio);
+ ath9k_hw_gpio_free(ah, btcoex_hw->btpriority_gpio);
+ ath9k_hw_gpio_free(ah, btcoex_hw->wlanactive_gpio);
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_deinit);
+
void ath9k_hw_btcoex_init_mci(struct ath_hw *ah)
{
ah->btcoex_hw.mci.ready = false;
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index cd2f0a2..0f7c4e6 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -123,6 +123,7 @@ struct ath_btcoex_hw {
void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah);
void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
+void ath9k_hw_btcoex_deinit(struct ath_hw *ah);
void ath9k_hw_btcoex_init_mci(struct ath_hw *ah);
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index b41dfb7..4964bb3 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -40,6 +40,8 @@ void ath_deinit_leds(struct ath_softc *sc)

ath_led_brightness(&sc->led_cdev, LED_OFF);
led_classdev_unregister(&sc->led_cdev);
+
+ ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin);
}

void ath_init_leds(struct ath_softc *sc)
@@ -404,6 +406,13 @@ void ath9k_deinit_btcoex(struct ath_softc *sc)

if (ath9k_hw_mci_is_enabled(ah))
ath_mci_cleanup(sc);
+ else {
+ enum ath_btcoex_scheme scheme = ath9k_hw_get_btcoex_scheme(ah);
+
+ if (scheme == ATH_BTCOEX_CFG_2WIRE ||
+ scheme == ATH_BTCOEX_CFG_3WIRE)
+ ath9k_hw_btcoex_deinit(sc->sc_ah);
+ }
}

int ath9k_init_btcoex(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index d9b640a..ecb848b 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -253,6 +253,8 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
ath9k_led_brightness(&priv->led_cdev, LED_OFF);
led_classdev_unregister(&priv->led_cdev);
cancel_work_sync(&priv->led_work);
+
+ ath9k_hw_gpio_free(priv->ah, priv->ah->led_pin);
}


diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4046949..1fd6155 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1575,6 +1575,7 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
ath9k_hw_gpio_request_out(ah, i, NULL,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
+ ath9k_hw_gpio_free(ah, i);
}
}

--
1.9.1


2016-03-07 02:39:23

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 7/8] ath9k: fix BTCoex access invalid registers for SOC chips

From: Miaoqing Pan <[email protected]>

The registers of AR_GPIO_INPUT_MUX1 and AR_GPIO_PDPU were removed
from SOC chips, fix invalid accessing

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 95a810b..d46cd31 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -162,9 +162,10 @@ void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);

/* Set input mux for bt_active to gpio pin */
- REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
- AR_GPIO_INPUT_MUX1_BT_ACTIVE,
- btcoex_hw->btactive_gpio);
+ if (!AR_SREV_SOC(ah))
+ REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+ AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ btcoex_hw->btactive_gpio);

/* Configure the desired gpio port for input */
ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio,
@@ -183,13 +184,14 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)

/* Set input mux for bt_prority_async and
* bt_active_async to GPIO pins */
- REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
- AR_GPIO_INPUT_MUX1_BT_ACTIVE,
- btcoex_hw->btactive_gpio);
-
- REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
- AR_GPIO_INPUT_MUX1_BT_PRIORITY,
- btcoex_hw->btpriority_gpio);
+ if (!AR_SREV_SOC(ah)) {
+ REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+ AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ btcoex_hw->btactive_gpio);
+ REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+ AR_GPIO_INPUT_MUX1_BT_PRIORITY,
+ btcoex_hw->btpriority_gpio);
+ }

/* Configure the desired GPIO ports for input */
ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio,
@@ -285,13 +287,13 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
txprio_shift[i-1]);
}
}
+
/* Last WLAN weight has to be adjusted wrt tx priority */
if (concur_tx) {
btcoex_hw->wlan_weight[i-1] &= ~(0xff << txprio_shift[i-1]);
btcoex_hw->wlan_weight[i-1] |= (btcoex_hw->tx_prio[stomp_type]
<< txprio_shift[i-1]);
}
-
}
EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);

@@ -375,7 +377,8 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
break;
}

- if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI) {
+ if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI &&
+ !AR_SREV_SOC(ah)) {
REG_RMW(ah, AR_GPIO_PDPU,
(0x2 << (btcoex_hw->btactive_gpio * 2)),
(0x3 << (btcoex_hw->btactive_gpio * 2)));
--
1.9.1


2016-03-07 02:39:19

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH v4 6/8] ath9k: add bits definition of BTCoex MODE2/3 for SOC chips

From: Miaoqing Pan <[email protected]>

Add bits definition for AR_BT_COEX_MODE2 and AR_BT_COEX_MODE3, which
needed by SOC chips (AR9340, AR9531, AR9550, AR9561).

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/reg.h | 46 +++++++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index f82a4ad..f8a96f6 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1890,15 +1890,33 @@ enum {

#define AR9300_BT_WGHT 0xcccc4444

-#define AR_BT_COEX_MODE2 0x817c
-#define AR_BT_BCN_MISS_THRESH 0x000000ff
-#define AR_BT_BCN_MISS_THRESH_S 0
-#define AR_BT_BCN_MISS_CNT 0x0000ff00
-#define AR_BT_BCN_MISS_CNT_S 8
-#define AR_BT_HOLD_RX_CLEAR 0x00010000
-#define AR_BT_HOLD_RX_CLEAR_S 16
-#define AR_BT_DISABLE_BT_ANT 0x00100000
-#define AR_BT_DISABLE_BT_ANT_S 20
+#define AR_BT_COEX_MODE2 0x817c
+#define AR_BT_BCN_MISS_THRESH 0x000000ff
+#define AR_BT_BCN_MISS_THRESH_S 0
+#define AR_BT_BCN_MISS_CNT 0x0000ff00
+#define AR_BT_BCN_MISS_CNT_S 8
+#define AR_BT_HOLD_RX_CLEAR 0x00010000
+#define AR_BT_HOLD_RX_CLEAR_S 16
+#define AR_BT_PROTECT_BT_AFTER_WAKEUP 0x00080000
+#define AR_BT_PROTECT_BT_AFTER_WAKEUP_S 19
+#define AR_BT_DISABLE_BT_ANT 0x00100000
+#define AR_BT_DISABLE_BT_ANT_S 20
+#define AR_BT_QUIET_2_WIRE 0x00200000
+#define AR_BT_QUIET_2_WIRE_S 21
+#define AR_BT_WL_ACTIVE_MODE 0x00c00000
+#define AR_BT_WL_ACTIVE_MODE_S 22
+#define AR_BT_WL_TXRX_SEPARATE 0x01000000
+#define AR_BT_WL_TXRX_SEPARATE_S 24
+#define AR_BT_RS_DISCARD_EXTEND 0x02000000
+#define AR_BT_RS_DISCARD_EXTEND_S 25
+#define AR_BT_TSF_BT_ACTIVE_CTRL 0x0c000000
+#define AR_BT_TSF_BT_ACTIVE_CTRL_S 26
+#define AR_BT_TSF_BT_PRIORITY_CTRL 0x30000000
+#define AR_BT_TSF_BT_PRIORITY_CTRL_S 28
+#define AR_BT_INTERRUPT_ENABLE 0x40000000
+#define AR_BT_INTERRUPT_ENABLE_S 30
+#define AR_BT_PHY_ERR_BT_COLL_ENABLE 0x80000000
+#define AR_BT_PHY_ERR_BT_COLL_ENABLE_S 31

#define AR_TXSIFS 0x81d0
#define AR_TXSIFS_TIME 0x000000FF
@@ -1907,6 +1925,16 @@ enum {
#define AR_TXSIFS_ACK_SHIFT 0x00007000
#define AR_TXSIFS_ACK_SHIFT_S 12

+#define AR_BT_COEX_MODE3 0x81d4
+#define AR_BT_WL_ACTIVE_TIME 0x000000ff
+#define AR_BT_WL_ACTIVE_TIME_S 0
+#define AR_BT_WL_QC_TIME 0x0000ff00
+#define AR_BT_WL_QC_TIME_S 8
+#define AR_BT_ALLOW_CONCURRENT_ACCESS 0x000f0000
+#define AR_BT_ALLOW_CONCURRENT_ACCESS_S 16
+#define AR_BT_AGC_SATURATION_CNT_ENABLE 0x00100000
+#define AR_BT_AGC_SATURATION_CNT_ENABLE_S 20
+
#define AR_TXOP_X 0x81ec
#define AR_TXOP_X_VAL 0x000000FF

--
1.9.1