spi: davinci: add support for wait enable timeouts
authorBrian Niebuhr <bniebuhr@efjohnson.com>
Thu, 19 Aug 2010 09:37:38 +0000 (15:07 +0530)
committerSekhar Nori <nsekhar@ti.com>
Thu, 18 Nov 2010 13:08:27 +0000 (18:38 +0530)
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>
arch/arm/mach-davinci/include/mach/spi.h
drivers/spi/davinci_spi.c

index 29c19c425b02b7fcf90f60ea4cc4d3de597f5c2a..483b055da4405ac59a522df9f19d1eae8279ba3f 100644 (file)
@@ -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 */
index d09b63cf58bf191d476e0eab06701268fe0589ea..e94c63813e9fcf4200ed47b1c1f069d12f06d82e 100644 (file)
 #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)
 #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);