summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorKaricheri, Muralidharan <m-karicheri2@ti.com>2014-04-04 13:16:54 -0400
committerTom Rini <trini@ti.com>2014-04-17 17:24:39 -0400
commit2bcdf84d5820320724932199fddeed32d2d49e4a (patch)
treec06f57ba2eecebc37b037af0b4ce4a2f608b352f /drivers/spi
parentef509b9063fb702ce69d1a64ff293698a04075d6 (diff)
spi: davinci: add support for multiple bus and chip select
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> Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/davinci_spi.c49
-rw-r--r--drivers/spi/davinci_spi.h33
2 files changed, 79 insertions, 3 deletions
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index e3fb3212aa..28fb3a2e9f 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -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 */
@@ -264,7 +284,30 @@ out:
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
- return bus == 0 && cs == 0;
+ int ret = 0;
+
+ switch (bus) {
+ case SPI0_BUS:
+ if (cs < SPI0_NUM_CS)
+ ret = 1;
+ break;
+#ifdef CONFIG_SYS_SPI1
+ case SPI1_BUS:
+ if (cs < SPI1_NUM_CS)
+ ret = 1;
+ break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+ case SPI2_BUS:
+ if (cs < SPI2_NUM_CS)
+ ret = 1;
+ break;
+#endif
+ default:
+ /* Invalid bus number. Do nothing */
+ break;
+ }
+ return ret;
}
void spi_cs_activate(struct spi_slave *slave)
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h
index 33f69b5ca9..d4612d3527 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;