[U-Boot] [PATCH v3 8/9] spi: davinci: add support for multiple bus and chip select
Jagan Teki
jagannadh.teki at gmail.com
Sun Mar 23 12:06:42 CET 2014
Hi,
On Sat, Mar 22, 2014 at 2:21 AM, Murali Karicheri <m-karicheri2 at 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 at ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> Acked-by: Tom Rini <trini at ti.com>
> ---
> drivers/spi/davinci_spi.c | 60 ++++++++++++++++++++++++++++++++++++++++++---
> drivers/spi/davinci_spi.h | 33 +++++++++++++++++++++++++
> 2 files changed, 90 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
> index e3fb321..b682bc4 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 */
> @@ -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
This code looks more static, can you try get the bus and cs from sf probe and
according assign the reg_base.
fyi: look at drivers/spi/zynq_spi.c where based on the bus number we assign the
reg_base and prior to that we can do the same for bus and cs.
Let me know for any more info.
thanks!
--
Jagan.
More information about the U-Boot
mailing list