diff options
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/spi.c | 62 | ||||
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/wlan.c | 2 |
2 files changed, 60 insertions, 4 deletions
diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 5ace9e3a56fc..2c2ed4b09efd 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -8,6 +8,7 @@ #include <linux/spi/spi.h> #include <linux/crc7.h> #include <linux/crc-itu-t.h> +#include <linux/gpio/consumer.h> #include "netdev.h" #include "cfg80211.h" @@ -45,6 +46,10 @@ struct wilc_spi { bool probing_crc; /* true if we're probing chip's CRC config */ bool crc7_enabled; /* true if crc7 is currently enabled */ bool crc16_enabled; /* true if crc16 is currently enabled */ + struct wilc_gpios { + struct gpio_desc *enable; /* ENABLE GPIO or NULL */ + struct gpio_desc *reset; /* RESET GPIO or NULL */ + } gpios; }; static const struct wilc_hif_func wilc_hif_spi; @@ -152,6 +157,50 @@ struct wilc_spi_special_cmd_rsp { u8 status; } __packed; +static int wilc_parse_gpios(struct wilc *wilc) +{ + struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; + struct wilc_gpios *gpios = &spi_priv->gpios; + + /* get ENABLE pin and deassert it (if it is defined): */ + gpios->enable = devm_gpiod_get_optional(&spi->dev, + "enable", GPIOD_OUT_LOW); + /* get RESET pin and assert it (if it is defined): */ + if (gpios->enable) { + /* if enable pin exists, reset must exist as well */ + gpios->reset = devm_gpiod_get(&spi->dev, + "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpios->reset)) { + dev_err(&spi->dev, "missing reset gpio.\n"); + return PTR_ERR(gpios->reset); + } + } else { + gpios->reset = devm_gpiod_get_optional(&spi->dev, + "reset", GPIOD_OUT_HIGH); + } + return 0; +} + +static void wilc_wlan_power(struct wilc *wilc, bool on) +{ + struct wilc_spi *spi_priv = wilc->bus_data; + struct wilc_gpios *gpios = &spi_priv->gpios; + + if (on) { + /* assert ENABLE: */ + gpiod_set_value(gpios->enable, 1); + mdelay(5); + /* deassert RESET: */ + gpiod_set_value(gpios->reset, 0); + } else { + /* assert RESET: */ + gpiod_set_value(gpios->reset, 1); + /* deassert ENABLE: */ + gpiod_set_value(gpios->enable, 0); + } +} + static int wilc_bus_probe(struct spi_device *spi) { int ret; @@ -171,6 +220,10 @@ static int wilc_bus_probe(struct spi_device *spi) wilc->bus_data = spi_priv; wilc->dev_irq_num = spi->irq; + ret = wilc_parse_gpios(wilc); + if (ret < 0) + goto netdev_cleanup; + wilc->rtc_clk = devm_clk_get_optional(&spi->dev, "rtc"); if (IS_ERR(wilc->rtc_clk)) { ret = PTR_ERR(wilc->rtc_clk); @@ -983,9 +1036,10 @@ static int wilc_spi_reset(struct wilc *wilc) static int wilc_spi_deinit(struct wilc *wilc) { - /* - * TODO: - */ + struct wilc_spi *spi_priv = wilc->bus_data; + + spi_priv->isinit = false; + wilc_wlan_power(wilc, false); return 0; } @@ -1006,6 +1060,8 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) dev_err(&spi->dev, "Fail cmd read chip id...\n"); } + wilc_wlan_power(wilc, true); + /* * configure protocol */ diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index a2aa8894320f..fb5633a05fd5 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -1254,7 +1254,7 @@ void wilc_wlan_cleanup(struct net_device *dev) wilc->rx_buffer = NULL; kfree(wilc->tx_buffer); wilc->tx_buffer = NULL; - wilc->hif_func->hif_deinit(NULL); + wilc->hif_func->hif_deinit(wilc); } static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type, |