Commit b2d70d49 authored by Miaoqing Pan's avatar Miaoqing Pan Committed by Kalle Valo

ath9k: make GPIO API to support both of WMAC and SOC

commit 61b559de ("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: default avatarMiaoqing Pan <miaoqing@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent a01ab81b
...@@ -3590,7 +3590,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) ...@@ -3590,7 +3590,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
else else
gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485; gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
ath9k_hw_cfg_output(ah, gpio, ath9k_hw_gpio_request_out(ah, gpio, NULL,
AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED); AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
} }
......
...@@ -427,21 +427,34 @@ static void ar9003_mci_observation_set_up(struct ath_hw *ah) ...@@ -427,21 +427,34 @@ static void ar9003_mci_observation_set_up(struct ath_hw *ah)
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
if (mci->config & ATH_MCI_CONFIG_MCI_OBS_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_gpio_request_out(ah, 3, NULL,
ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK); AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA); ath9k_hw_gpio_request_out(ah, 2, NULL,
ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK); 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) { } 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_gpio_request_out(ah, 3, NULL,
ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX); AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX); ath9k_hw_gpio_request_out(ah, 2, NULL,
ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX); AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 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) { } 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_gpio_request_out(ah, 3, NULL,
ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX); AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA); ath9k_hw_gpio_request_out(ah, 2, NULL,
ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK); 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 } else
return; return;
......
...@@ -142,7 +142,8 @@ void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah) ...@@ -142,7 +142,8 @@ void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
btcoex_hw->btactive_gpio); btcoex_hw->btactive_gpio);
/* Configure the desired gpio port for input */ /* 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); EXPORT_SYMBOL(ath9k_hw_btcoex_init_2wire);
...@@ -166,9 +167,10 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah) ...@@ -166,9 +167,10 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
btcoex_hw->btpriority_gpio); btcoex_hw->btpriority_gpio);
/* Configure the desired GPIO ports for input */ /* Configure the desired GPIO ports for input */
ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio,
ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btactive_gpio); "ath9k-btactive");
ath9k_hw_cfg_gpio_input(ah, btcoex_hw->btpriority_gpio); ath9k_hw_gpio_request_in(ah, btcoex_hw->btpriority_gpio,
"ath9k-btpriority");
} }
EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire); EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire);
...@@ -201,7 +203,8 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) ...@@ -201,7 +203,8 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
/* Configure the desired GPIO port for TX_FRAME output */ /* Configure the desired GPIO port for TX_FRAME output */
ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, ath9k_hw_gpio_request_out(ah, btcoex_hw->wlanactive_gpio,
"ath9k-wlanactive",
AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
} }
...@@ -271,7 +274,6 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) ...@@ -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_MODE, btcoex->bt_coex_mode);
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2); REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2);
if (AR_SREV_9300_20_OR_LATER(ah)) { 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_WEIGHTS0, btcoex->wlan_weight[0]);
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, btcoex->wlan_weight[1]); 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) ...@@ -281,8 +283,6 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
} else } else
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex->bt_coex_weights); REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex->bt_coex_weights);
if (AR_SREV_9271(ah)) { if (AR_SREV_9271(ah)) {
val = REG_READ(ah, 0x50040); val = REG_READ(ah, 0x50040);
val &= 0xFFFFFEFF; val &= 0xFFFFFEFF;
...@@ -292,7 +292,8 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) ...@@ -292,7 +292,8 @@ 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_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
ath9k_hw_cfg_output(ah, btcoex->wlanactive_gpio, ath9k_hw_gpio_request_out(ah, btcoex->wlanactive_gpio,
"ath9k-wlanactive",
AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL); AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
} }
...@@ -364,8 +365,8 @@ void ath9k_hw_btcoex_disable(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)) if (!AR_SREV_9300_20_OR_LATER(ah))
ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0);
ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, ath9k_hw_gpio_request_out(ah, btcoex_hw->wlanactive_gpio,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT); NULL, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
......
...@@ -74,7 +74,8 @@ void ath_fill_led_pin(struct ath_softc *sc) ...@@ -74,7 +74,8 @@ void ath_fill_led_pin(struct ath_softc *sc)
if (ah->led_pin >= 0) { if (ah->led_pin >= 0) {
if (!((1 << ah->led_pin) & AR_GPIO_OE_OUT_MASK)) 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; return;
} }
...@@ -90,7 +91,8 @@ void ath_fill_led_pin(struct ath_softc *sc) ...@@ -90,7 +91,8 @@ void ath_fill_led_pin(struct ath_softc *sc)
ah->led_pin = ATH_LED_PIN_DEF; ah->led_pin = ATH_LED_PIN_DEF;
/* Configure gpio 1 for output */ /* 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 */ /* LED off, active low */
ath9k_hw_set_gpio(ah, ah->led_pin, (ah->config.led_active_high) ? 0 : 1); ath9k_hw_set_gpio(ah, ah->led_pin, (ah->config.led_active_high) ? 0 : 1);
......
...@@ -259,11 +259,11 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv) ...@@ -259,11 +259,11 @@ void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
void ath9k_configure_leds(struct ath9k_htc_priv *priv) void ath9k_configure_leds(struct ath9k_htc_priv *priv)
{ {
/* Configure gpio 1 for output */ /* Configure gpio 1 for output */
ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin, ath9k_hw_gpio_request_out(priv->ah, priv->ah->led_pin,
"ath9k-led",
AR_GPIO_OUTPUT_MUX_AS_OUTPUT); AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
/* LED off, active low */ /* LED off, active low */
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
} }
void ath9k_init_leds(struct ath9k_htc_priv *priv) void ath9k_init_leds(struct ath9k_htc_priv *priv)
......
...@@ -1582,7 +1582,8 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah) ...@@ -1582,7 +1582,8 @@ static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
if (!(gpio_mask & 1)) if (!(gpio_mask & 1))
continue; 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))); ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
} }
} }
...@@ -1958,7 +1959,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ...@@ -1958,7 +1959,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_init_qos(ah); ath9k_hw_init_qos(ah);
if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 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); ath9k_hw_init_global_settings(ah);
...@@ -2654,8 +2655,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ...@@ -2654,8 +2655,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
/* GPIO / RFKILL / Antennae */ /* GPIO / RFKILL / Antennae */
/****************************/ /****************************/
static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, u32 gpio, u32 type)
u32 gpio, u32 type)
{ {
int addr; int addr;
u32 gpio_shift, tmp; u32 gpio_shift, tmp;
...@@ -2669,8 +2669,8 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, ...@@ -2669,8 +2669,8 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
gpio_shift = (gpio % 6) * 5; gpio_shift = (gpio % 6) * 5;
if (AR_SREV_9280_20_OR_LATER(ah) if (AR_SREV_9280_20_OR_LATER(ah) ||
|| (addr != AR_GPIO_OUTPUT_MUX1)) { (addr != AR_GPIO_OUTPUT_MUX1)) {
REG_RMW(ah, addr, (type << gpio_shift), REG_RMW(ah, addr, (type << gpio_shift),
(0x1f << gpio_shift)); (0x1f << gpio_shift));
} else { } else {
...@@ -2682,106 +2682,144 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah, ...@@ -2682,106 +2682,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)) { if (gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label))
gpio_shift = gpio;
REG_RMW(ah, AR7010_GPIO_OE,
(AR7010_GPIO_OE_AS_INPUT << gpio_shift),
(AR7010_GPIO_OE_MASK << gpio_shift));
return; return;
}
gpio_shift = gpio << 1; ah->caps.gpio_requested |= BIT(gpio);
REG_RMW(ah,
AR_GPIO_OE_OUT,
(AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
(AR_GPIO_OE_OUT_DRV << gpio_shift));
} }
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) \ u32 gpio_set, gpio_shift = gpio;
(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;
if (AR_DEVID_7010(ah)) { if (AR_DEVID_7010(ah)) {
u32 val; gpio_set = out ?
val = REG_READ(ah, AR7010_GPIO_IN); AR7010_GPIO_OE_AS_OUTPUT : AR7010_GPIO_OE_AS_INPUT;
return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; REG_RMW(ah, AR7010_GPIO_OE, gpio_set << gpio_shift,
} else if (AR_SREV_9300_20_OR_LATER(ah)) AR7010_GPIO_OE_MASK << gpio_shift);
return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) & } else if (AR_SREV_SOC(ah)) {
AR_GPIO_BIT(gpio)) != 0; gpio_set = out ? 1 : 0;
else if (AR_SREV_9271(ah)) REG_RMW(ah, AR_GPIO_OE_OUT, gpio_set << gpio_shift,
return MS_REG_READ(AR9271, gpio) != 0; gpio_set << gpio_shift);
else if (AR_SREV_9287_11_OR_LATER(ah)) } else {
return MS_REG_READ(AR9287, gpio) != 0; gpio_shift = gpio << 1;
else if (AR_SREV_9285_12_OR_LATER(ah)) gpio_set = out ?
return MS_REG_READ(AR9285, gpio) != 0; AR_GPIO_OE_OUT_DRV_ALL : AR_GPIO_OE_OUT_DRV_NO;
else if (AR_SREV_9280_20_OR_LATER(ah)) REG_RMW(ah, AR_GPIO_OE_OUT, gpio_set << gpio_shift,
return MS_REG_READ(AR928X, gpio) != 0; AR_GPIO_OE_OUT_DRV << gpio_shift);
if (out)
ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
}
}
static void ath9k_hw_gpio_request(struct ath_hw *ah, u32 gpio, bool out,
const char *label, u32 ah_signal_type)
{
WARN_ON(gpio >= ah->caps.num_gpio_pins);
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 else
return MS_REG_READ(AR, gpio) != 0; WARN_ON(1);
} }
EXPORT_SYMBOL(ath9k_hw_gpio_get);
void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, 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_gpio_request_in);
void ath9k_hw_gpio_request_out(struct ath_hw *ah, u32 gpio, const char *label,
u32 ah_signal_type) u32 ah_signal_type)
{ {
u32 gpio_shift; ath9k_hw_gpio_request(ah, gpio, true, label, ah_signal_type);
}
EXPORT_SYMBOL(ath9k_hw_gpio_request_out);
if (AR_DEVID_7010(ah)) { void ath9k_hw_gpio_free(struct ath_hw *ah, u32 gpio)
gpio_shift = gpio; {
REG_RMW(ah, AR7010_GPIO_OE, if (!AR_SREV_SOC(ah))
(AR7010_GPIO_OE_AS_OUTPUT << gpio_shift),
(AR7010_GPIO_OE_MASK << gpio_shift));
return; return;
}
ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); WARN_ON(gpio >= ah->caps.num_gpio_pins);
gpio_shift = 2 * gpio;
REG_RMW(ah, if (ah->caps.gpio_requested & BIT(gpio)) {
AR_GPIO_OE_OUT, gpio_free(gpio);
(AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), ah->caps.gpio_requested &= ~BIT(gpio);
(AR_GPIO_OE_OUT_DRV << gpio_shift)); }
} }
EXPORT_SYMBOL(ath9k_hw_cfg_output); EXPORT_SYMBOL(ath9k_hw_gpio_free);
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
{ {
if (AR_DEVID_7010(ah)) { u32 val = 0xffffffff;
val = val ? 0 : 1;
REG_RMW(ah, AR7010_GPIO_OUT, ((val&1) << gpio),
AR_GPIO_BIT(gpio));
return;
}
if (AR_SREV_9271(ah)) #define MS_REG_READ(x, y) \
val = ~val; (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & BIT(y))
if ((1 << gpio) & AR_GPIO_OE_OUT_MASK) WARN_ON(gpio >= ah->caps.num_gpio_pins);
REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
AR_GPIO_BIT(gpio)); 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 else
gpio_set_value(gpio, val & 1); 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) WARN_ON(gpio >= ah->caps.num_gpio_pins);
return;
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) void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
{ {
......
...@@ -160,7 +160,6 @@ ...@@ -160,7 +160,6 @@
#define AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA 0x1e #define AR_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA 0x1e
#define AR_GPIOD_MASK 0x00001FFF #define AR_GPIOD_MASK 0x00001FFF
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
#define BASE_ACTIVATE_DELAY 100 #define BASE_ACTIVATE_DELAY 100
#define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100) #define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100)
...@@ -302,6 +301,7 @@ struct ath9k_hw_capabilities { ...@@ -302,6 +301,7 @@ struct ath9k_hw_capabilities {
u8 max_rxchains; u8 max_rxchains;
u8 num_gpio_pins; u8 num_gpio_pins;
u32 gpio_mask; u32 gpio_mask;
u32 gpio_requested;
u8 rx_hp_qdepth; u8 rx_hp_qdepth;
u8 rx_lp_qdepth; u8 rx_lp_qdepth;
u8 rx_status_len; u8 rx_status_len;
...@@ -1020,12 +1020,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah); ...@@ -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); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
/* GPIO / RFKILL / Antennae */ /* 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);
u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); void ath9k_hw_gpio_request_out(struct ath_hw *ah, u32 gpio, const char *label,
void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
u32 ah_signal_type); 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_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); 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); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
/* General Operation */ /* General Operation */
......
...@@ -719,10 +719,10 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -719,10 +719,10 @@ static int ath9k_start(struct ieee80211_hw *hw)
ah->reset_power_on = false; ah->reset_power_on = false;
if (ah->led_pin >= 0) { 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, ath9k_hw_set_gpio(ah, ah->led_pin,
(ah->config.led_active_high) ? 1 : 0); (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) ...@@ -870,7 +870,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
if (ah->led_pin >= 0) { if (ah->led_pin >= 0) {
ath9k_hw_set_gpio(ah, ah->led_pin, ath9k_hw_set_gpio(ah, ah->led_pin,
(ah->config.led_active_high) ? 0 : 1); (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); ath_prepare_reset(sc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment