[U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select

Murali Karicheri
2014-02-20T17:55:13Z

From: Rex Chang <rchang@ti.com>

Currently davinci spi driver supports only bus 0 cs 0.
This patch allows driver to support bus 1 and bus 2 with
configurable number of chip selects. Also defaults are
selected in a way to avoid regression on other platforms
that uses davinci spi driver and has only one spi bus.

Signed-off-by: Rex Chang <rchang@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
drivers/spi/davinci_spi.c | 62 ++++++++++++++++++++++++++++++++++++++++++---
drivers/spi/davinci_spi.h | 33 ++++++++++++++++++++++++
2 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index e3fb321..c708a04 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -23,7 +23,7 @@ void spi_init()
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
- struct davinci_spi_slave *ds;
+ struct davinci_spi_slave *ds;

if (!spi_cs_is_valid(bus, cs))
return NULL;
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!ds)
return NULL;

- ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+ ds->slave.bus = bus;
+ ds->slave.cs = cs;
+
+ switch (bus) {
+ case SPI0_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+ break;
+#ifdef CONFIG_SYS_SPI1
+ case SPI1_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+ break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+ case SPI2_BUS:
+ ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+ break;
+#endif
+ default: /* Invalid bus number */
+ return NULL;
+ }
+
ds->freq = max_hz;

return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);

/* CS, CLK, SIMO and SOMI are functional pins */
- writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+ writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);

/* setup format */
@@ -262,9 +282,43 @@ out:
return 0;
}

+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+ if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+ return 1;
+ return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+ if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+ return 1;
+ return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+ return 0;
+}
+#endif
+
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
- return bus == 0 && cs == 0;
+ if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+ return 1;
+ else if (bus1_cs_valid(bus, cs))
+ return 1;
+ else if (bus2_cs_valid(bus, cs))
+ return 1;
+ return 0;
}

void spi_cs_activate(struct spi_slave *slave)
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h
index 33f69b5..d4612d3 100644
--- a/drivers/spi/davinci_spi.h
+++ b/drivers/spi/davinci_spi.h
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
/* SPIDEF */
#define SPIDEF_CSDEF0_MASK BIT(0)

+#define SPI0_BUS 0
+#define SPI0_BASE CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
+ * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS 1
+#else
+#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI1
+#define SPI1_BUS 1
+#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI2
+#define SPI2_BUS 2
+#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE CONFIG_SYS_SPI2_BASE
+#endif
+
struct davinci_spi_slave {
struct spi_slave slave;
struct davinci_spi_regs *regs;
--
1.7.9.5