summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Niebuhr <bniebuhr@efjohnson.com>2010-08-19 15:07:38 +0530
committerSekhar Nori <nsekhar@ti.com>2010-11-18 18:38:27 +0530
commit7abbf23c5903e14b0cff1cdeab906eab164be767 (patch)
treeec2fd9962d900f334630ec5a9c999da1c8bf8fb5
parentfd764463fe28ac53371565f851240e74775fb1aa (diff)
spi: davinci: add support for wait enable timeouts
Just enabling WAITENA in SPIFMTn register waits for the enable signal from the slave indefinitely. Allow support for finite waiting by adding support for c2e delay (maximum time for addressed slave to respond) and t2e delay (maximum time for slave to respond after transmit data finished). While at it, modify the T2C and C2T defines by prepending the register name as is the convention followed for other register field elsewhere in the driver. Signed-off-by: Brian Niebuhr <bniebuhr@efjohnson.com> Tested-By: Michael Williamson <michael.williamson@criticallink.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--arch/arm/mach-davinci/include/mach/spi.h2
-rw-r--r--drivers/spi/davinci_spi.c36
2 files changed, 29 insertions, 9 deletions
diff --git a/arch/arm/mach-davinci/include/mach/spi.h b/arch/arm/mach-davinci/include/mach/spi.h
index 29c19c425b02..483b055da440 100644
--- a/arch/arm/mach-davinci/include/mach/spi.h
+++ b/arch/arm/mach-davinci/include/mach/spi.h
@@ -43,6 +43,8 @@ struct davinci_spi_config {
u8 timer_disable;
u8 c2tdelay;
u8 t2cdelay;
+ u8 t2edelay;
+ u8 c2edelay;
};
#endif /* __ARCH_ARM_DAVINCI_SPI_H */
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index d09b63cf58bf..e94c63813e9f 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -78,6 +78,16 @@
#define SPIBUF_TXFULL_MASK BIT(29)
#define SPIBUF_RXEMPTY_MASK BIT(31)
+/* SPIDELAY */
+#define SPIDELAY_C2TDELAY_SHIFT 24
+#define SPIDELAY_C2TDELAY_MASK (0xFF << SPIDELAY_C2TDELAY_SHIFT)
+#define SPIDELAY_T2CDELAY_SHIFT 16
+#define SPIDELAY_T2CDELAY_MASK (0xFF << SPIDELAY_T2CDELAY_SHIFT)
+#define SPIDELAY_T2EDELAY_SHIFT 8
+#define SPIDELAY_T2EDELAY_MASK (0xFF << SPIDELAY_T2EDELAY_SHIFT)
+#define SPIDELAY_C2EDELAY_SHIFT 0
+#define SPIDELAY_C2EDELAY_MASK 0xFF
+
/* Error Masks */
#define SPIFLG_DLEN_ERR_MASK BIT(0)
#define SPIFLG_TIMEOUT_MASK BIT(1)
@@ -95,9 +105,6 @@
#define SPIINT_TX_INTR BIT(9)
#define SPIINT_DMA_REQ_EN BIT(16)
-#define SPI_T2CDELAY_SHIFT 16
-#define SPI_C2TDELAY_SHIFT 24
-
/* SPI Controller registers */
#define SPIGCR0 0x00
#define SPIGCR1 0x04
@@ -363,6 +370,8 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
if (davinci_spi->version == SPI_VERSION_2) {
+ u32 delay = 0;
+
spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT)
& SPIFMT_WDELAY_MASK);
@@ -372,15 +381,24 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
if (spicfg->parity_enable)
spifmt |= SPIFMT_PARITYENA_MASK;
- if (spicfg->timer_disable)
+ if (spicfg->timer_disable) {
spifmt |= SPIFMT_DISTIMER_MASK;
- else
- iowrite32((spicfg->c2tdelay << SPI_C2TDELAY_SHIFT) |
- (spicfg->t2cdelay << SPI_T2CDELAY_SHIFT),
- davinci_spi->base + SPIDELAY);
+ } else {
+ delay |= (spicfg->c2tdelay << SPIDELAY_C2TDELAY_SHIFT)
+ & SPIDELAY_C2TDELAY_MASK;
+ delay |= (spicfg->t2cdelay << SPIDELAY_T2CDELAY_SHIFT)
+ & SPIDELAY_T2CDELAY_MASK;
+ }
- if (spi->mode & SPI_READY)
+ if (spi->mode & SPI_READY) {
spifmt |= SPIFMT_WAITENA_MASK;
+ delay |= (spicfg->t2edelay << SPIDELAY_T2EDELAY_SHIFT)
+ & SPIDELAY_T2EDELAY_MASK;
+ delay |= (spicfg->c2edelay << SPIDELAY_C2EDELAY_SHIFT)
+ & SPIDELAY_C2EDELAY_MASK;
+ }
+
+ iowrite32(delay, davinci_spi->base + SPIDELAY);
}
iowrite32(spifmt, davinci_spi->base + SPIFMT0);