summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-10-14 13:51:56 -0400
committerTom Rini <trini@konsulko.com>2020-10-14 13:51:56 -0400
commit0f35d96bfd8565da2c5ba0f540827fff0e82eb32 (patch)
tree753688442ed5b0dbed5f5e56c0c56398775ed6f8 /drivers/spi
parent6731c5a5ef30e1581e3042b11893627f42949cd7 (diff)
parent8369886b401d85e49d52ff5f877cf14b1619bd43 (diff)
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell
- Octeon TX: Add NAND driver (Suneel) - Octeon TX: Add NIC driver driver (Suneel) - Octeon TX2: Add NIC driver driver (Suneel) - Armada 8040: Add iEi Puzzle-M80 board support (Luka) - Armada A37xx SPI: Add support for CS-GPIO (George) - Espressobin: Use Linux model/compatible strings (Andre) - Espressobin: Add armada-3720-espressobin-emmc.dts from Linux (Andre) - Armada A37xx: Small cleanup of config header (Pali)
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/mvebu_a3700_spi.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index e860b9ec64b..eb13cf349ef 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -15,6 +15,7 @@
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
+#include <asm/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -27,6 +28,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define MVEBU_SPI_A3700_SPI_EN_0 BIT(16)
#define MVEBU_SPI_A3700_CLK_PRESCALE_MASK 0x1f
+#define MAX_CS_COUNT 4
/* SPI registers */
struct spi_reg {
@@ -39,16 +41,23 @@ struct spi_reg {
struct mvebu_spi_platdata {
struct spi_reg *spireg;
struct clk clk;
+ struct gpio_desc cs_gpios[MAX_CS_COUNT];
};
-static void spi_cs_activate(struct spi_reg *reg, int cs)
+static void spi_cs_activate(struct mvebu_spi_platdata *plat, int cs)
{
- setbits_le32(&reg->ctrl, MVEBU_SPI_A3700_SPI_EN_0 << cs);
+ if (CONFIG_IS_ENABLED(DM_GPIO) && dm_gpio_is_valid(&plat->cs_gpios[cs]))
+ dm_gpio_set_value(&plat->cs_gpios[cs], 1);
+ else
+ setbits_le32(&plat->spireg->ctrl, MVEBU_SPI_A3700_SPI_EN_0 << cs);
}
-static void spi_cs_deactivate(struct spi_reg *reg, int cs)
+static void spi_cs_deactivate(struct mvebu_spi_platdata *plat, int cs)
{
- clrbits_le32(&reg->ctrl, MVEBU_SPI_A3700_SPI_EN_0 << cs);
+ if (CONFIG_IS_ENABLED(DM_GPIO) && dm_gpio_is_valid(&plat->cs_gpios[cs]))
+ dm_gpio_set_value(&plat->cs_gpios[cs], 0);
+ else
+ clrbits_le32(&plat->spireg->ctrl, MVEBU_SPI_A3700_SPI_EN_0 << cs);
}
/**
@@ -150,7 +159,7 @@ static int mvebu_spi_xfer(struct udevice *dev, unsigned int bitlen,
/* Activate CS */
if (flags & SPI_XFER_BEGIN) {
debug("SPI: activate cs.\n");
- spi_cs_activate(reg, spi_chip_select(dev));
+ spi_cs_activate(plat, spi_chip_select(dev));
}
/* Send and/or receive */
@@ -169,7 +178,7 @@ static int mvebu_spi_xfer(struct udevice *dev, unsigned int bitlen,
return ret;
debug("SPI: deactivate cs.\n");
- spi_cs_deactivate(reg, spi_chip_select(dev));
+ spi_cs_deactivate(plat, spi_chip_select(dev));
}
return 0;
@@ -247,6 +256,26 @@ static int mvebu_spi_probe(struct udevice *bus)
writel(data, &reg->cfg);
+ /* Set up CS GPIOs in device tree, if any */
+ if (CONFIG_IS_ENABLED(DM_GPIO) && gpio_get_list_count(bus, "cs-gpios") > 0) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(plat->cs_gpios); i++) {
+ ret = gpio_request_by_name(bus, "cs-gpios", i, &plat->cs_gpios[i], 0);
+ if (ret < 0 || !dm_gpio_is_valid(&plat->cs_gpios[i])) {
+ /* Use the native CS function for this line */
+ continue;
+ }
+
+ ret = dm_gpio_set_dir_flags(&plat->cs_gpios[i],
+ GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
+ if (ret) {
+ dev_err(bus, "Setting cs %d error\n", i);
+ return ret;
+ }
+ }
+ }
+
return 0;
}