diff options
author | Lukas Funke | 2023-04-28 14:38:50 +0200 |
---|---|---|
committer | Jagan Teki | 2023-07-13 13:59:57 +0530 |
commit | 47d9ae54a103980576d2267699d609f431981446 (patch) | |
tree | e323897f3ff3ff049f300965fe2627eb46382e78 /drivers/spi | |
parent | 03612861a722ebd478c63bf055783fe8c3fcb3bd (diff) |
spi: pl022: Add chip-select gpio support
Add support for an optional external chip-select gpio.
Signed-off-by: Lukas Funke <lukas.funke@weidmueller.com>
Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/pl022_spi.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/spi/pl022_spi.c b/drivers/spi/pl022_spi.c index 9e4caac16fa..fc7388b379d 100644 --- a/drivers/spi/pl022_spi.c +++ b/drivers/spi/pl022_spi.c @@ -12,9 +12,11 @@ #include <clk.h> #include <common.h> #include <dm.h> +#include <dm/device_compat.h> #include <fdtdec.h> #include <linux/io.h> #include <asm/global_data.h> +#include <asm/gpio.h> #include <spi.h> #define SSP_CR0 0x000 @@ -70,6 +72,9 @@ struct pl022_spi_pdata { fdt_addr_t addr; fdt_size_t size; unsigned int freq; +#if CONFIG_IS_ENABLED(DM_GPIO) + struct gpio_desc cs_gpio; +#endif }; struct pl022_spi_slave { @@ -153,6 +158,17 @@ static int pl022_spi_release_bus(struct udevice *dev) return 0; } +static void pl022_spi_set_cs(struct udevice *dev, bool on) +{ +#if CONFIG_IS_ENABLED(DM_GPIO) + struct udevice *bus = dev->parent; + struct pl022_spi_pdata *plat = dev_get_plat(bus); + + if (dm_gpio_is_valid(&plat->cs_gpio)) + dm_gpio_set_value(&plat->cs_gpio, on ? 1 : 0); +#endif +} + static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { @@ -165,7 +181,7 @@ static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen, if (bitlen == 0) /* Finish any previously submitted transfers */ - return 0; + goto done; /* * TODO: The controller can do non-multiple-of-8 bit @@ -178,9 +194,13 @@ static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen, if (bitlen % 8) { /* Errors always terminate an ongoing transfer */ flags |= SPI_XFER_END; - return -1; + ret = -1; + goto done; } + if (flags & SPI_XFER_BEGIN) + pl022_spi_set_cs(dev, true); + len = bitlen / 8; while (len_tx < len) { @@ -207,6 +227,10 @@ static int pl022_spi_xfer(struct udevice *dev, unsigned int bitlen, } } +done: + if (flags & SPI_XFER_END) + pl022_spi_set_cs(dev, false); + return ret; } @@ -309,6 +333,13 @@ static int pl022_spi_of_to_plat(struct udevice *bus) plat->freq = clk_get_rate(&clkdev); +#if CONFIG_IS_ENABLED(DM_GPIO) + ret = gpio_request_by_name(bus, "cs-gpios", 0, &plat->cs_gpio, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret < 0 && ret != -ENOENT) + return ret; +#endif + return 0; } |