diff options
Diffstat (limited to 'drivers/net/wireless/st')
-rw-r--r-- | drivers/net/wireless/st/cw1200/cw1200_sdio.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/st/cw1200/cw1200_spi.c | 75 | ||||
-rw-r--r-- | drivers/net/wireless/st/cw1200/main.c | 4 |
3 files changed, 71 insertions, 50 deletions
diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c index 4c30b5772c..00c4731d8f 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c +++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c @@ -8,7 +8,7 @@ #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/mmc/host.h> #include <linux/mmc/sdio_func.h> @@ -178,12 +178,15 @@ static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self) return ret; } +/* Like the rest of the driver, this only supports one device per system */ +static struct gpio_desc *cw1200_reset; +static struct gpio_desc *cw1200_powerup; + static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata) { - if (pdata->reset) { - gpio_set_value(pdata->reset, 0); + if (cw1200_reset) { + gpiod_set_value(cw1200_reset, 0); msleep(30); /* Min is 2 * CLK32K cycles */ - gpio_free(pdata->reset); } if (pdata->power_ctrl) @@ -196,16 +199,21 @@ static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata) static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata) { - /* Ensure I/Os are pulled low */ - if (pdata->reset) { - gpio_request(pdata->reset, "cw1200_wlan_reset"); - gpio_direction_output(pdata->reset, 0); + /* Ensure I/Os are pulled low (reset is active low) */ + cw1200_reset = devm_gpiod_get_optional(NULL, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(cw1200_reset)) { + pr_err("could not get CW1200 SDIO reset GPIO\n"); + return PTR_ERR(cw1200_reset); } - if (pdata->powerup) { - gpio_request(pdata->powerup, "cw1200_wlan_powerup"); - gpio_direction_output(pdata->powerup, 0); + gpiod_set_consumer_name(cw1200_reset, "cw1200_wlan_reset"); + cw1200_powerup = devm_gpiod_get_optional(NULL, "powerup", GPIOD_OUT_LOW); + if (IS_ERR(cw1200_powerup)) { + pr_err("could not get CW1200 SDIO powerup GPIO\n"); + return PTR_ERR(cw1200_powerup); } - if (pdata->reset || pdata->powerup) + gpiod_set_consumer_name(cw1200_powerup, "cw1200_wlan_powerup"); + + if (cw1200_reset || cw1200_powerup) msleep(10); /* Settle time? */ /* Enable 3v3 and 1v8 to hardware */ @@ -226,13 +234,13 @@ static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata) } /* Enable POWERUP signal */ - if (pdata->powerup) { - gpio_set_value(pdata->powerup, 1); + if (cw1200_powerup) { + gpiod_set_value(cw1200_powerup, 1); msleep(250); /* or more..? */ } - /* Enable RSTn signal */ - if (pdata->reset) { - gpio_set_value(pdata->reset, 1); + /* Deassert RSTn signal, note active low */ + if (cw1200_reset) { + gpiod_set_value(cw1200_reset, 0); msleep(50); /* Or more..? */ } return 0; diff --git a/drivers/net/wireless/st/cw1200/cw1200_spi.c b/drivers/net/wireless/st/cw1200/cw1200_spi.c index c82c0688b5..4f346fb977 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/st/cw1200/cw1200_spi.c @@ -11,7 +11,7 @@ */ #include <linux/module.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/spinlock.h> #include <linux/interrupt.h> @@ -38,6 +38,8 @@ struct hwbus_priv { const struct cw1200_platform_data_spi *pdata; spinlock_t lock; /* Serialize all bus operations */ wait_queue_head_t wq; + struct gpio_desc *reset; + struct gpio_desc *powerup; int claimed; }; @@ -80,7 +82,7 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self, #endif /* Header is LE16 */ - regaddr = cpu_to_le16(regaddr); + regaddr = (__force u16)cpu_to_le16(regaddr); /* We have to byteswap if the SPI bus is limited to 8b operation or we are running on a Big Endian system @@ -145,7 +147,7 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self, #endif /* Header is LE16 */ - regaddr = cpu_to_le16(regaddr); + regaddr = (__force u16)cpu_to_le16(regaddr); /* We have to byteswap if the SPI bus is limited to 8b operation or we are running on a Big Endian system @@ -275,12 +277,12 @@ static void cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) free_irq(self->func->irq, self); } -static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) +static int cw1200_spi_off(struct hwbus_priv *self, const struct cw1200_platform_data_spi *pdata) { - if (pdata->reset) { - gpio_set_value(pdata->reset, 0); + if (self->reset) { + /* Assert RESET, note active low */ + gpiod_set_value(self->reset, 1); msleep(30); /* Min is 2 * CLK32K cycles */ - gpio_free(pdata->reset); } if (pdata->power_ctrl) @@ -291,18 +293,12 @@ static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) return 0; } -static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata) +static int cw1200_spi_on(struct hwbus_priv *self, const struct cw1200_platform_data_spi *pdata) { /* Ensure I/Os are pulled low */ - if (pdata->reset) { - gpio_request(pdata->reset, "cw1200_wlan_reset"); - gpio_direction_output(pdata->reset, 0); - } - if (pdata->powerup) { - gpio_request(pdata->powerup, "cw1200_wlan_powerup"); - gpio_direction_output(pdata->powerup, 0); - } - if (pdata->reset || pdata->powerup) + gpiod_direction_output(self->reset, 1); /* Active low */ + gpiod_direction_output(self->powerup, 0); + if (self->reset || self->powerup) msleep(10); /* Settle time? */ /* Enable 3v3 and 1v8 to hardware */ @@ -323,13 +319,13 @@ static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata) } /* Enable POWERUP signal */ - if (pdata->powerup) { - gpio_set_value(pdata->powerup, 1); + if (self->powerup) { + gpiod_set_value(self->powerup, 1); msleep(250); /* or more..? */ } - /* Enable RSTn signal */ - if (pdata->reset) { - gpio_set_value(pdata->reset, 1); + /* Assert RSTn signal, note active low */ + if (self->reset) { + gpiod_set_value(self->reset, 0); msleep(50); /* Or more..? */ } return 0; @@ -381,20 +377,33 @@ static int cw1200_spi_probe(struct spi_device *func) spi_get_chipselect(func, 0), func->mode, func->bits_per_word, func->max_speed_hz); - if (cw1200_spi_on(plat_data)) { + self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL); + if (!self) { + pr_err("Can't allocate SPI hwbus_priv."); + return -ENOMEM; + } + + /* Request reset asserted */ + self->reset = devm_gpiod_get_optional(&func->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(self->reset)) + return dev_err_probe(&func->dev, PTR_ERR(self->reset), + "could not get reset GPIO\n"); + gpiod_set_consumer_name(self->reset, "cw1200_wlan_reset"); + + self->powerup = devm_gpiod_get_optional(&func->dev, "powerup", GPIOD_OUT_LOW); + if (IS_ERR(self->powerup)) + return dev_err_probe(&func->dev, PTR_ERR(self->powerup), + "could not get powerup GPIO\n"); + gpiod_set_consumer_name(self->reset, "cw1200_wlan_powerup"); + + if (cw1200_spi_on(self, plat_data)) { pr_err("spi_on() failed!\n"); - return -1; + return -ENODEV; } if (spi_setup(func)) { pr_err("spi_setup() failed!\n"); - return -1; - } - - self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL); - if (!self) { - pr_err("Can't allocate SPI hwbus_priv."); - return -ENOMEM; + return -ENODEV; } self->pdata = plat_data; @@ -416,7 +425,7 @@ static int cw1200_spi_probe(struct spi_device *func) if (status) { cw1200_spi_irq_unsubscribe(self); - cw1200_spi_off(plat_data); + cw1200_spi_off(self, plat_data); } return status; @@ -434,7 +443,7 @@ static void cw1200_spi_disconnect(struct spi_device *func) self->core = NULL; } } - cw1200_spi_off(dev_get_platdata(&func->dev)); + cw1200_spi_off(self, dev_get_platdata(&func->dev)); } static int __maybe_unused cw1200_spi_suspend(struct device *dev) diff --git a/drivers/net/wireless/st/cw1200/main.c b/drivers/net/wireless/st/cw1200/main.c index 381013e0db..a54a7b8686 100644 --- a/drivers/net/wireless/st/cw1200/main.c +++ b/drivers/net/wireless/st/cw1200/main.c @@ -203,6 +203,10 @@ static const unsigned long cw1200_ttl[] = { }; static const struct ieee80211_ops cw1200_ops = { + .add_chanctx = ieee80211_emulate_add_chanctx, + .remove_chanctx = ieee80211_emulate_remove_chanctx, + .change_chanctx = ieee80211_emulate_change_chanctx, + .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, .start = cw1200_start, .stop = cw1200_stop, .add_interface = cw1200_add_interface, |