chip_allow_sleep() only supported wakeup via SDIO, which made the
driver unusable over SPI. This code is a straight forward port from
the driver in the linux-at91 repository.
Signed-off-by: David Mosberger-Tang <[email protected]>
---
.../net/wireless/microchip/wilc1000/wlan.c | 56 +++++++++++++++++--
.../net/wireless/microchip/wilc1000/wlan.h | 6 ++
2 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index 31d51385ba93..d4a90c490084 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -552,12 +552,60 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
void chip_allow_sleep(struct wilc *wilc)
{
u32 reg = 0;
+ const struct wilc_hif_func *hif_func = wilc->hif_func;
+ u32 wakeup_reg, wakeup_bit;
+ u32 to_host_from_fw_reg, to_host_from_fw_bit;
+ u32 from_host_to_fw_reg, from_host_to_fw_bit;
+ u32 trials = 100;
+ int ret;
+
+ if (wilc->io_type == WILC_HIF_SDIO) {
+ wakeup_reg = WILC_SDIO_WAKEUP_REG;
+ wakeup_bit = WILC_SDIO_WAKEUP_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;
+ 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;
+ }
+
+ while (trials--) {
+ ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, ®);
+ if (ret)
+ return;
+ if ((reg & to_host_from_fw_bit) == 0)
+ break;
+ }
+ if (!trials)
+ pr_warn("FW not responding\n");
- wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
+ /* Clear bit 1 */
+ ret = hif_func->hif_read_reg(wilc, wakeup_reg, ®);
+ if (ret)
+ return;
+ if (reg & wakeup_bit) {
+ reg &= ~wakeup_bit;
+ ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
+ if (ret)
+ return;
+ }
- wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
- reg & ~WILC_SDIO_WAKEUP_BIT);
- wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
+ ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, ®);
+ if (ret)
+ return;
+ if (reg & from_host_to_fw_bit) {
+ reg &= ~from_host_to_fw_bit;
+ ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
+ if (ret)
+ return;
+
+ }
}
EXPORT_SYMBOL_GPL(chip_allow_sleep);
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h
index d55eb6b3a12a..6479acc12b95 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.h
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.h
@@ -97,6 +97,12 @@
#define WILC_SPI_WAKEUP_REG 0x1
#define WILC_SPI_WAKEUP_BIT BIT(1)
+#define WILC_SPI_HOST_TO_FW_REG 0x0b
+#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
+
+#define WILC_SPI_FW_TO_HOST_REG 0x10
+#define WILC_SPI_FW_TO_HOST_BIT BIT(0)
+
#define WILC_SPI_PROTOCOL_OFFSET (WILC_SPI_PROTOCOL_CONFIG - \
WILC_SPI_REG_BASE)
--
2.25.1
On 24/02/21 9:03 am, David Mosberger-Tang wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> chip_allow_sleep() only supported wakeup via SDIO, which made the
> driver unusable over SPI. This code is a straight forward port from
> the driver in the linux-at91 repository.
>
Thanks David. The patch looks good to me.
Acked-by: Ajay Singh <[email protected]>
I will work on the wakeup sequence patch and try to submit it soon.
> Signed-off-by: David Mosberger-Tang <[email protected]>
> ---
> .../net/wireless/microchip/wilc1000/wlan.c | 56 +++++++++++++++++--
> .../net/wireless/microchip/wilc1000/wlan.h | 6 ++
> 2 files changed, 58 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
> index 31d51385ba93..d4a90c490084 100644
> --- a/drivers/net/wireless/microchip/wilc1000/wlan.c
> +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
> @@ -552,12 +552,60 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
> void chip_allow_sleep(struct wilc *wilc)
> {
> u32 reg = 0;
> + const struct wilc_hif_func *hif_func = wilc->hif_func;
> + u32 wakeup_reg, wakeup_bit;
> + u32 to_host_from_fw_reg, to_host_from_fw_bit;
> + u32 from_host_to_fw_reg, from_host_to_fw_bit;
> + u32 trials = 100;
> + int ret;
> +
> + if (wilc->io_type == WILC_HIF_SDIO) {
> + wakeup_reg = WILC_SDIO_WAKEUP_REG;
> + wakeup_bit = WILC_SDIO_WAKEUP_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;
> + 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;
> + }
> +
> + while (trials--) {
> + ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, ®);
> + if (ret)
> + return;
> + if ((reg & to_host_from_fw_bit) == 0)
> + break;
> + }
> + if (!trials)
> + pr_warn("FW not responding\n");
>
> - wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
> + /* Clear bit 1 */
> + ret = hif_func->hif_read_reg(wilc, wakeup_reg, ®);
> + if (ret)
> + return;
> + if (reg & wakeup_bit) {
> + reg &= ~wakeup_bit;
> + ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
> + if (ret)
> + return;
> + }
>
> - wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
> - reg & ~WILC_SDIO_WAKEUP_BIT);
> - wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
> + ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, ®);
> + if (ret)
> + return;
> + if (reg & from_host_to_fw_bit) {
> + reg &= ~from_host_to_fw_bit;
> + ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
> + if (ret)
> + return;
> +
> + }
> }
> EXPORT_SYMBOL_GPL(chip_allow_sleep);
>
> diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.h b/drivers/net/wireless/microchip/wilc1000/wlan.h
> index d55eb6b3a12a..6479acc12b95 100644
> --- a/drivers/net/wireless/microchip/wilc1000/wlan.h
> +++ b/drivers/net/wireless/microchip/wilc1000/wlan.h
> @@ -97,6 +97,12 @@
> #define WILC_SPI_WAKEUP_REG 0x1
> #define WILC_SPI_WAKEUP_BIT BIT(1)
>
> +#define WILC_SPI_HOST_TO_FW_REG 0x0b
> +#define WILC_SPI_HOST_TO_FW_BIT BIT(0)
> +
> +#define WILC_SPI_FW_TO_HOST_REG 0x10
> +#define WILC_SPI_FW_TO_HOST_BIT BIT(0)
> +
> #define WILC_SPI_PROTOCOL_OFFSET (WILC_SPI_PROTOCOL_CONFIG - \
> WILC_SPI_REG_BASE)
>
> --
> 2.25.1
>
David Mosberger-Tang <[email protected]> wrote:
> chip_allow_sleep() only supported wakeup via SDIO, which made the
> driver unusable over SPI. This code is a straight forward port from
> the driver in the linux-at91 repository.
>
> Signed-off-by: David Mosberger-Tang <[email protected]>
> Acked-by: Ajay Singh <[email protected]>
Patch applied to wireless-drivers-next.git, thanks.
f135a1571a05 wilc1000: Support chip sleep over SPI
--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches