Message ID | 20210224033317.1507603-1-davidm@egauge.net |
---|---|
State | New |
Headers | show |
Series | wilc1000: Support chip sleep over SPI | expand |
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 <ajay.kathat@microchip.com> I will work on the wakeup sequence patch and try to submit it soon. > Signed-off-by: David Mosberger-Tang <davidm@egauge.net> > --- > .../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 <davidm@egauge.net> 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 <davidm@egauge.net> > Acked-by: Ajay Singh <ajay.kathat@microchip.com> Patch applied to wireless-drivers-next.git, thanks. f135a1571a05 wilc1000: Support chip sleep over SPI -- https://patchwork.kernel.org/project/linux-wireless/patch/20210224033317.1507603-1-davidm@egauge.net/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
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)
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 <davidm@egauge.net> --- .../net/wireless/microchip/wilc1000/wlan.c | 56 +++++++++++++++++-- .../net/wireless/microchip/wilc1000/wlan.h | 6 ++ 2 files changed, 58 insertions(+), 4 deletions(-)