[U-Boot] [PATCH] TI DaVinci: Driver for the davinci SPI controller

From: Sekhar Nori nsekhar@ti.com
This adds a driver for the SPI controller found on davinci based SoCs from Texas Instruments.
Signed-off-by: Sekhar Nori nsekhar@ti.com Signed-off-by: Sudhakar Rajashekhara sudhakar.raj@ti.com --- drivers/spi/Makefile | 1 + drivers/spi/davinci_spi.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/davinci_spi.h | 84 ++++++++++++++++++ 3 files changed, 290 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/davinci_spi.c create mode 100644 drivers/spi/davinci_spi.h
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 824d8e7..07b9611 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c new file mode 100644 index 0000000..1c988bb --- /dev/null +++ b/drivers/spi/davinci_spi.c @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ + * + * Driver for SPI controller on DaVinci. Based on atmel_spi.c + * by Atmel Corporation + * + * Copyright (C) 2007 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <spi.h> +#include <malloc.h> + +#include <asm/io.h> + +#include <asm/arch/hardware.h> + +#include "davinci_spi.h" + +static unsigned int data1_reg_val; + +void spi_init() +{ + /* do nothing */ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct davinci_spi_slave *ds; + + ds = malloc(sizeof(struct davinci_spi_slave)); + if (!ds) + return NULL; + + ds->slave.bus = bus; + ds->slave.cs = cs; + ds->regs = (void *)CONFIG_SYS_SPI_BASE; + ds->freq = max_hz; + + return &ds->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + + free(ds); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + unsigned int scalar; + + /* Enable the SPI hardware */ + spi_writel(ds, GCR0, SPIGCR0_SPIRST_MASK); + udelay(1000); + spi_writel(ds, GCR0, SPIGCR0_SPIENA_MASK); + + /* Set master mode, powered up and not activated */ + spi_writel(ds, GCR1, SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK); + + /* CS, CLK, SIMO and SOMI are functional pins */ + spi_writel(ds, PC0, (SPIPC0_EN0FUN_MASK) | (SPIPC0_CLKFUN_MASK) | + (SPIPC0_DOFUN_MASK) | (SPIPC0_DIFUN_MASK)); + + /* setup format */ + scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF; + + spi_writel(ds, FMT0, 8 | /* character length */ + (scalar << SPIFMT_PRESCALE_SHIFT) | + /* clock signal delayed by half clk cycle */ + (1 << SPIFMT_PHASE_SHIFT) | + /* clock low in idle state - Mode 0 */ + (0 << SPIFMT_POLARITY_SHIFT) | + /* MSB shifted out first */ + (0 << SPIFMT_SHIFTDIR_SHIFT)); + + /* hold cs active at end of transfer until explicitly de-asserted */ + data1_reg_val = (1 << SPIDAT1_CSHOLD_SHIFT) | + (slave->cs << SPIDAT1_CSNR_SHIFT); + spi_writel(ds, DAT1, data1_reg_val); + + /* + * Including a minor delay. No science here. Should be good even with + * no delay + */ + spi_writel(ds, DELAY, (50 << SPI_C2TDELAY_SHIFT) | + (50 << SPI_T2CDELAY_SHIFT)); + + /* default chip select register */ + spi_writel(ds, DEF, SPIDEF_CSDEF0_MASK); + + /* no interrupts */ + spi_writel(ds, INT0, 0); + spi_writel(ds, LVL, 0); + + /* enable SPI */ + spi_writel(ds, GCR1, spi_readl(ds, GCR1) | (SPIGCR1_SPIENA_MASK)); + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + + /* Disable the SPI hardware */ + spi_writel(ds, GCR0, SPIGCR0_SPIRST_MASK); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + unsigned int len; + int ret, i; + const u8 *txp = dout; + u8 *rxp = din; + + ret = 0; + + if (bitlen == 0) + /* Finish any previously submitted transfers */ + goto out; + + /* + * It's not clear how non-8-bit-aligned transfers are supposed to be + * represented as a stream of bytes...this is a limitation of + * the current SPI interface - here we terminate on receiving such a + * transfer request. + */ + if (bitlen % 8) { + /* Errors always terminate an ongoing transfer */ + flags |= SPI_XFER_END; + goto out; + } + + len = bitlen / 8; + + /* do an empty read to clear the current contents */ + spi_readl(ds, BUF); + + /* keep writing and reading 1 byte until done */ + for (i = 0; i < len; i++) { + /* wait till TXFULL is asserted */ + while (spi_readl(ds, BUF) & (SPIBUF_TXFULL_MASK)); + + /* write the data */ + data1_reg_val &= ~0xFFFF; + if (txp) { + data1_reg_val |= *txp & 0xFF; + txp++; + } + + /* + * Write to DAT1 is required to keep the serial transfer going. + * We just terminate when we reach the end. + */ + if ((i == (len - 1)) && (flags & SPI_XFER_END)) { + /* clear CS hold */ + spi_writel(ds, DAT1, data1_reg_val & + ~(1 << SPIDAT1_CSHOLD_SHIFT)); + } else { + spi_writel(ds, DAT1, data1_reg_val); + } + + /* read the data - wait for data availability */ + while (spi_readl(ds, BUF) & (SPIBUF_RXEMPTY_MASK)); + + if (rxp) { + *rxp = spi_readl(ds, BUF) & 0xFF; + rxp++; + } else { + spi_readl(ds, BUF); /* simply drop the read character */ + } + } + return 0; + +out: + if (flags & SPI_XFER_END) { + spi_writel(ds, DAT1, data1_reg_val & + ~(1 << SPIDAT1_CSHOLD_SHIFT)); + } + return 0; +} + diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h new file mode 100644 index 0000000..b3bf916 --- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/* + * Register definitions for the DaVinci SPI Controller + */ + +/* Register offsets */ +#define DAVINCI_SPI_GCR0 0x0000 +#define DAVINCI_SPI_GCR1 0x0004 +#define DAVINCI_SPI_INT0 0x0008 +#define DAVINCI_SPI_LVL 0x000c +#define DAVINCI_SPI_FLG 0x0010 +#define DAVINCI_SPI_PC0 0x0014 +#define DAVINCI_SPI_PC1 0x0018 +#define DAVINCI_SPI_PC2 0x001c +#define DAVINCI_SPI_PC3 0x0020 +#define DAVINCI_SPI_PC4 0x0024 +#define DAVINCI_SPI_PC5 0x0028 +#define DAVINCI_SPI_DAT0 0x0038 +#define DAVINCI_SPI_DAT1 0x003c +#define DAVINCI_SPI_BUF 0x0040 +#define DAVINCI_SPI_EMU 0x0044 +#define DAVINCI_SPI_DELAY 0x0048 +#define DAVINCI_SPI_DEF 0x004c +#define DAVINCI_SPI_FMT0 0x0050 +#define DAVINCI_SPI_FMT1 0x0054 +#define DAVINCI_SPI_FMT2 0x0058 +#define DAVINCI_SPI_FMT3 0x005c +#define DAVINCI_SPI_INTVEC0 0x0060 +#define DAVINCI_SPI_INTVEC1 0x0064 + +#define BIT(x) (1 << (x)) + +/* SPIGCR0 */ +#define SPIGCR0_SPIENA_MASK 0x1 +#define SPIGCR0_SPIRST_MASK 0x0 + +/* SPIGCR0 */ +#define SPIGCR1_CLKMOD_MASK BIT(1) +#define SPIGCR1_MASTER_MASK BIT(0) +#define SPIGCR1_SPIENA_MASK BIT(24) + +/* SPIPC0 */ +#define SPIPC0_DIFUN_MASK BIT(11) /* SIMO */ +#define SPIPC0_DOFUN_MASK BIT(10) /* SOMI */ +#define SPIPC0_CLKFUN_MASK BIT(9) /* CLK */ +#define SPIPC0_EN0FUN_MASK BIT(0) + +/* SPIFMT0 */ +#define SPIFMT_SHIFTDIR_SHIFT 20 +#define SPIFMT_POLARITY_SHIFT 17 +#define SPIFMT_PHASE_SHIFT 16 +#define SPIFMT_PRESCALE_SHIFT 8 + +/* SPIDAT1 */ +#define SPIDAT1_CSHOLD_SHIFT 28 +#define SPIDAT1_CSNR_SHIFT 16 + +/* SPIDELAY */ +#define SPI_C2TDELAY_SHIFT 24 +#define SPI_T2CDELAY_SHIFT 16 + +/* SPIBUF */ +#define SPIBUF_RXEMPTY_MASK BIT(31) +#define SPIBUF_TXFULL_MASK BIT(29) + +/* SPIDEF */ +#define SPIDEF_CSDEF0_MASK BIT(0) + +struct davinci_spi_slave { + struct spi_slave slave; + void *regs; + u32 mr; + unsigned int freq; +}; + +static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) +{ + return container_of(slave, struct davinci_spi_slave, slave); +} + +#define spi_readl(ds, reg) \ + readl(ds->regs + DAVINCI_SPI_##reg) +#define spi_writel(ds, reg, value) \ + writel(value, ds->regs + DAVINCI_SPI_##reg) +

On Wednesday 23 December 2009 02:44:36 Sudhakar Rajashekhara wrote:
--- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
this is a sorted list
--- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller
- */
missing license/copyright
+#define spi_readl(ds, reg) \
- readl(ds->regs + DAVINCI_SPI_##reg)
+#define spi_writel(ds, reg, value) \
- writel(value, ds->regs + DAVINCI_SPI_##reg)
should be (ds)->regs -mike

Hi,
On Thu, Dec 24, 2009 at 07:04:18, Mike Frysinger wrote:
On Wednesday 23 December 2009 02:44:36 Sudhakar Rajashekhara wrote:
--- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
this is a sorted list
Will fix it. Thanks for pointing it out.
--- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller */
missing license/copyright
Will add copyright/license.
+#define spi_readl(ds, reg) \
- readl(ds->regs + DAVINCI_SPI_##reg)
+#define spi_writel(ds, reg, value) \
- writel(value, ds->regs + DAVINCI_SPI_##reg)
should be (ds)->regs
I'll modify it and resubmit the patch.
Thanks, Sudhakar

On 23.12.2009 08:44, Sudhakar Rajashekhara wrote:
From: Sekhar Norinsekhar@ti.com
This adds a driver for the SPI controller found on davinci based SoCs from Texas Instruments.
Signed-off-by: Sekhar Norinsekhar@ti.com Signed-off-by: Sudhakar Rajashekharasudhakar.raj@ti.com
drivers/spi/Makefile | 1 + drivers/spi/davinci_spi.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/davinci_spi.h | 84 ++++++++++++++++++ 3 files changed, 290 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/davinci_spi.c create mode 100644 drivers/spi/davinci_spi.h
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 824d8e7..07b9611 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
Should this list be kept sorted alphabetically? I.e.
... COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_CF_SPI) += cf_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o ...
?
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c new file mode 100644 index 0000000..1c988bb --- /dev/null +++ b/drivers/spi/davinci_spi.c @@ -0,0 +1,205 @@
...
+void spi_init()
...
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
...
+void spi_free_slave(struct spi_slave *slave)
....
+int spi_claim_bus(struct spi_slave *slave)
....
+void spi_release_bus(struct spi_slave *slave)
....
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
I wonder if all (SPI API) functions from include/spi.h should be implemented? I.e. do we need (dummy) functions for spi_cs_is_valid(), spi_cs_activate() and spi_cs_deactivate(), too? Just in case a driver does use them.
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h new file mode 100644 index 0000000..b3bf916 --- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller
- */
Do we want a complete GPL header, like in the .c file, here, too?
Do we want a protection against multiple inclusion
#ifndef _DAVINCI_SPI_H_ #define _DAVINCI_SPI_H_
in this header file?
Best regards
Dirk

Hi,
On Fri, Dec 25, 2009 at 22:41:13, Dirk Behme wrote:
On 23.12.2009 08:44, Sudhakar Rajashekhara wrote:
From: Sekhar Norinsekhar@ti.com
This adds a driver for the SPI controller found on davinci based SoCs from Texas Instruments.
Signed-off-by: Sekhar Norinsekhar@ti.com Signed-off-by: Sudhakar Rajashekharasudhakar.raj@ti.com
drivers/spi/Makefile | 1 + drivers/spi/davinci_spi.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/davinci_spi.h | 84 ++++++++++++++++++ 3 files changed, 290 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/davinci_spi.c create mode 100644 drivers/spi/davinci_spi.h
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 824d8e7..07b9611 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
Should this list be kept sorted alphabetically? I.e.
I'll arrange them alphabetically.
... COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_CF_SPI) += cf_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o ...
?
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c new file mode 100644 index 0000000..1c988bb --- /dev/null +++ b/drivers/spi/davinci_spi.c @@ -0,0 +1,205 @@
...
+void spi_init()
...
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
...
+void spi_free_slave(struct spi_slave *slave)
....
+int spi_claim_bus(struct spi_slave *slave)
....
+void spi_release_bus(struct spi_slave *slave)
....
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
I wonder if all (SPI API) functions from include/spi.h should be implemented? I.e. do we need (dummy) functions for spi_cs_is_valid(), spi_cs_activate() and spi_cs_deactivate(), too? Just in case a driver does use them.
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h new file mode 100644 index 0000000..b3bf916 --- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller
- */
Do we want a complete GPL header, like in the .c file, here, too?
Do we want a protection against multiple inclusion
#ifndef _DAVINCI_SPI_H_ #define _DAVINCI_SPI_H_
in this header file?
Best regards
Dirk

Hi,
On Fri, Dec 25, 2009 at 22:41:13, Dirk Behme wrote:
On 23.12.2009 08:44, Sudhakar Rajashekhara wrote:
From: Sekhar Norinsekhar@ti.com
This adds a driver for the SPI controller found on davinci based SoCs from Texas Instruments.
Signed-off-by: Sekhar Norinsekhar@ti.com Signed-off-by: Sudhakar Rajashekharasudhakar.raj@ti.com
drivers/spi/Makefile | 1 + drivers/spi/davinci_spi.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/davinci_spi.h | 84 ++++++++++++++++++ 3 files changed, 290 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/davinci_spi.c create mode 100644 drivers/spi/davinci_spi.h
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 824d8e7..07b9611 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
Should this list be kept sorted alphabetically? I.e.
I'll arrange them alphabetically.
... COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_CF_SPI) += cf_spi.o +COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o ...
?
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c new file mode 100644 index 0000000..1c988bb --- /dev/null +++ b/drivers/spi/davinci_spi.c @@ -0,0 +1,205 @@
...
+void spi_init()
...
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
...
+void spi_free_slave(struct spi_slave *slave)
....
+int spi_claim_bus(struct spi_slave *slave)
....
+void spi_release_bus(struct spi_slave *slave)
....
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
I wonder if all (SPI API) functions from include/spi.h should be implemented? I.e. do we need (dummy) functions for spi_cs_is_valid(), spi_cs_activate() and spi_cs_deactivate(), too? Just in case a driver does use them.
Currently none of the SPI Flash drivers are using the above functions. I'll implement the above functions as dummy and later as and when the need arises, these functions will be implemented.
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h new file mode 100644 index 0000000..b3bf916 --- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller
- */
Do we want a complete GPL header, like in the .c file, here, too?
Do we want a protection against multiple inclusion
#ifndef _DAVINCI_SPI_H_ #define _DAVINCI_SPI_H_
in this header file?
I'll add the GPL header and guard against multiple inclusion.
Thanks for the comments. I'll submit an updated version of the patch soon.
Regards, Sudhakar

On 23/12/09 07:44, Sudhakar Rajashekhara wrote:
From: Sekhar Nori nsekhar@ti.com
This adds a driver for the SPI controller found on davinci based SoCs from Texas Instruments.
Signed-off-by: Sekhar Nori nsekhar@ti.com Signed-off-by: Sudhakar Rajashekhara sudhakar.raj@ti.com
drivers/spi/Makefile | 1 + drivers/spi/davinci_spi.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/davinci_spi.h | 84 ++++++++++++++++++ 3 files changed, 290 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/davinci_spi.c create mode 100644 drivers/spi/davinci_spi.h
...
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h new file mode 100644 index 0000000..b3bf916 --- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller
- */
+/* Register offsets */ +#define DAVINCI_SPI_GCR0 0x0000 +#define DAVINCI_SPI_GCR1 0x0004 +#define DAVINCI_SPI_INT0 0x0008 +#define DAVINCI_SPI_LVL 0x000c +#define DAVINCI_SPI_FLG 0x0010 +#define DAVINCI_SPI_PC0 0x0014 +#define DAVINCI_SPI_PC1 0x0018 +#define DAVINCI_SPI_PC2 0x001c +#define DAVINCI_SPI_PC3 0x0020 +#define DAVINCI_SPI_PC4 0x0024 +#define DAVINCI_SPI_PC5 0x0028 +#define DAVINCI_SPI_DAT0 0x0038 +#define DAVINCI_SPI_DAT1 0x003c +#define DAVINCI_SPI_BUF 0x0040 +#define DAVINCI_SPI_EMU 0x0044 +#define DAVINCI_SPI_DELAY 0x0048 +#define DAVINCI_SPI_DEF 0x004c +#define DAVINCI_SPI_FMT0 0x0050 +#define DAVINCI_SPI_FMT1 0x0054 +#define DAVINCI_SPI_FMT2 0x0058 +#define DAVINCI_SPI_FMT3 0x005c +#define DAVINCI_SPI_INTVEC0 0x0060 +#define DAVINCI_SPI_INTVEC1 0x0064
I think this ought to be a C structure, rather than register offsets?
...
+struct davinci_spi_slave {
- struct spi_slave slave;
- void *regs;
This should have the type of the C structure to be defined above.
- u32 mr;
- unsigned int freq;
+};
...
+#define spi_readl(ds, reg) \
- readl(ds->regs + DAVINCI_SPI_##reg)
+#define spi_writel(ds, reg, value) \
- writel(value, ds->regs + DAVINCI_SPI_##reg)
These can be rewritten (and the usages changed slightly) to access via the structure. You will then not be circumventing any type checking.
Maybe these defs then become too trivial and can be dropped altogether?
Regards, Nick.

Hi Nick,
On Mon, Jan 04, 2010 at 15:17:51, Nick Thompson wrote:
On 23/12/09 07:44, Sudhakar Rajashekhara wrote:
From: Sekhar Nori nsekhar@ti.com
This adds a driver for the SPI controller found on davinci based SoCs from Texas Instruments.
Signed-off-by: Sekhar Nori nsekhar@ti.com Signed-off-by: Sudhakar Rajashekhara sudhakar.raj@ti.com
drivers/spi/Makefile | 1 + drivers/spi/davinci_spi.c | 205 +++++++++++++++++++++++++++++++++++++++++++++ drivers/spi/davinci_spi.h | 84 ++++++++++++++++++ 3 files changed, 290 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/davinci_spi.c create mode 100644 drivers/spi/davinci_spi.h
...
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h new file mode 100644 index 0000000..b3bf916 --- /dev/null +++ b/drivers/spi/davinci_spi.h @@ -0,0 +1,84 @@ +/*
- Register definitions for the DaVinci SPI Controller
- */
+/* Register offsets */ +#define DAVINCI_SPI_GCR0 0x0000 +#define DAVINCI_SPI_GCR1 0x0004 +#define DAVINCI_SPI_INT0 0x0008 +#define DAVINCI_SPI_LVL 0x000c +#define DAVINCI_SPI_FLG 0x0010 +#define DAVINCI_SPI_PC0 0x0014 +#define DAVINCI_SPI_PC1 0x0018 +#define DAVINCI_SPI_PC2 0x001c +#define DAVINCI_SPI_PC3 0x0020 +#define DAVINCI_SPI_PC4 0x0024 +#define DAVINCI_SPI_PC5 0x0028 +#define DAVINCI_SPI_DAT0 0x0038 +#define DAVINCI_SPI_DAT1 0x003c +#define DAVINCI_SPI_BUF 0x0040 +#define DAVINCI_SPI_EMU 0x0044 +#define DAVINCI_SPI_DELAY 0x0048 +#define DAVINCI_SPI_DEF 0x004c +#define DAVINCI_SPI_FMT0 0x0050 +#define DAVINCI_SPI_FMT1 0x0054 +#define DAVINCI_SPI_FMT2 0x0058 +#define DAVINCI_SPI_FMT3 0x005c +#define DAVINCI_SPI_INTVEC0 0x0060 +#define DAVINCI_SPI_INTVEC1 0x0064
I think this ought to be a C structure, rather than register offsets?
I see that existing SPI drivers are not using structures for register defines. Off-late is there a shift in u-boot in favor of structures than macros for register definitions?
Regards, Sudhakar
participants (4)
-
Dirk Behme
-
Mike Frysinger
-
Nick Thompson
-
Sudhakar Rajashekhara