diff options
author | Ajay Singh <ajay.kathat@microchip.com> | 2021-09-16 16:49:19 +0000 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2021-09-21 18:08:15 +0300 |
commit | 5bb9de8bcb18c38ea089a287b77944ef8ee71abd (patch) | |
tree | f6fb84c6b2c475c928f9d2f2f7102a00cbbeed9c /drivers/net/wireless/microchip/wilc1000/wlan.c | |
parent | 0ec5408cd44855956f7741bd776f44db167801b7 (diff) |
wilc1000: configure registers to handle chip wakeup sequence
Use the correct sequence to configure clockless registers for chip wake-up.
The following sequence is expected from WILC chip for wakeup:
- set wakeup bit in wakeup_reg register
- after setting the wakeup bit, read back the clock status bit for wakeup
complete.
For SDIO/SPI modules, the wakeup sequence is the same except uses different
register values so refactored the code to use common function for both
SDIO/SPI bus.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210916164902.74629-5-ajay.kathat@microchip.com
Diffstat (limited to 'drivers/net/wireless/microchip/wilc1000/wlan.c')
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/wlan.c | 98 |
1 files changed, 51 insertions, 47 deletions
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index 200a103a0a85..1aad537c468f 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -10,6 +10,8 @@ #include "cfg80211.h" #include "wlan_cfg.h" +#define WAKE_UP_TRIAL_RETRY 10000 + static inline bool is_wilc1000(u32 id) { return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID; @@ -611,60 +613,62 @@ EXPORT_SYMBOL_GPL(chip_allow_sleep); void chip_wakeup(struct wilc *wilc) { - u32 reg, clk_status_reg; - const struct wilc_hif_func *h = wilc->hif_func; - - if (wilc->io_type == WILC_HIF_SPI) { - do { - h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®); - h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG, - reg | WILC_SPI_WAKEUP_BIT); - h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG, - reg & ~WILC_SPI_WAKEUP_BIT); - - do { - usleep_range(2000, 2500); - wilc_get_chipid(wilc, true); - } while (wilc_get_chipid(wilc, true) == 0); - } while (wilc_get_chipid(wilc, true) == 0); - } else if (wilc->io_type == WILC_HIF_SDIO) { - h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, - WILC_SDIO_HOST_TO_FW_BIT); - usleep_range(200, 400); - h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®); - do { - h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG, - reg | WILC_SDIO_WAKEUP_BIT); - h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG, - &clk_status_reg); - - while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) { - usleep_range(2000, 2500); + u32 ret = 0; + u32 clk_status_val = 0, trials = 0; + u32 wakeup_reg, wakeup_bit; + u32 clk_status_reg, clk_status_bit; + u32 to_host_from_fw_reg, to_host_from_fw_bit; + u32 from_host_to_fw_reg, from_host_to_fw_bit; + const struct wilc_hif_func *hif_func = wilc->hif_func; - h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG, - &clk_status_reg); - } - if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) { - h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG, - reg & ~WILC_SDIO_WAKEUP_BIT); - } - } while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)); + if (wilc->io_type == WILC_HIF_SDIO) { + wakeup_reg = WILC_SDIO_WAKEUP_REG; + wakeup_bit = WILC_SDIO_WAKEUP_BIT; + clk_status_reg = WILC_SDIO_CLK_STATUS_REG; + clk_status_bit = WILC_SDIO_CLK_STATUS_BIT; + from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG; + from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT; + to_host_from_fw_reg = WILC_SDIO_FW_TO_HOST_REG; + to_host_from_fw_bit = WILC_SDIO_FW_TO_HOST_BIT; + } else { + wakeup_reg = WILC_SPI_WAKEUP_REG; + wakeup_bit = WILC_SPI_WAKEUP_BIT; + clk_status_reg = WILC_SPI_CLK_STATUS_REG; + clk_status_bit = WILC_SPI_CLK_STATUS_BIT; + from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG; + from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT; + to_host_from_fw_reg = WILC_SPI_FW_TO_HOST_REG; + to_host_from_fw_bit = WILC_SPI_FW_TO_HOST_BIT; } - if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) { - if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) { - u32 val32; + /* indicate host wakeup */ + ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, + from_host_to_fw_bit); + if (ret) + return; - h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32); - val32 |= BIT(6); - h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32); + /* Set wake-up bit */ + ret = hif_func->hif_write_reg(wilc, wakeup_reg, + wakeup_bit); + if (ret) + return; - h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32); - val32 |= BIT(6); - h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32); + while (trials < WAKE_UP_TRIAL_RETRY) { + ret = hif_func->hif_read_reg(wilc, clk_status_reg, + &clk_status_val); + if (ret) { + pr_err("Bus error %d %x\n", ret, clk_status_val); + return; } + if (clk_status_val & clk_status_bit) + break; + + trials++; + } + if (trials >= WAKE_UP_TRIAL_RETRY) { + pr_err("Failed to wake-up the chip\n"); + return; } - wilc->chip_ps_state = WILC_CHIP_WAKEDUP; } EXPORT_SYMBOL_GPL(chip_wakeup); |