Message ID | 1396631815-5735-9-git-send-email-m-karicheri2@ti.com |
---|---|
State | Accepted |
Delegated to: | Tom Rini |
Headers | show |
On Fri, Apr 4, 2014 at 10:46 PM, Murali Karicheri <m-karicheri2@ti.com> wrote: > 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 | 49 ++++++++++++++++++++++++++++++++++++++++++--- > drivers/spi/davinci_spi.h | 33 ++++++++++++++++++++++++++++++ > 2 files changed, 79 insertions(+), 3 deletions(-) > > diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c > index e3fb321..28fb3a2 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 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; > -- Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com> thanks!
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index e3fb321..28fb3a2 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 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;