]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/spi/atmel_spi.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / spi / atmel_spi.c
index 317c0b41b6fbc6636303ef3a4196a63f16fa05bc..f4b1bad22e85f787212194ff265908139946254e 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/io.h>
 
 #include <asm/arch/clk.h>
-#include <asm/arch/memory-map.h>
+#include <asm/arch/hardware.h>
 
 #include "atmel_spi.h"
 
@@ -43,26 +43,26 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        u32                     csrx;
        void                    *regs;
 
-       if (cs > 3 || !spi_cs_is_valid(bus, cs))
+       if (!spi_cs_is_valid(bus, cs))
                return NULL;
 
        switch (bus) {
        case 0:
-               regs = (void *)SPI0_BASE;
+               regs = (void *)ATMEL_BASE_SPI0;
                break;
-#ifdef SPI1_BASE
+#ifdef ATMEL_BASE_SPI1
        case 1:
-               regs = (void *)SPI1_BASE;
+               regs = (void *)ATMEL_BASE_SPI1;
                break;
 #endif
-#ifdef SPI2_BASE
+#ifdef ATMEL_BASE_SPI2
        case 2:
-               regs = (void *)SPI2_BASE;
+               regs = (void *)ATMEL_BASE_SPI2;
                break;
 #endif
-#ifdef SPI3_BASE
+#ifdef ATMEL_BASE_SPI3
        case 3:
-               regs = (void *)SPI3_BASE;
+               regs = (void *)ATMEL_BASE_SPI3;
                break;
 #endif
        default:
@@ -84,14 +84,15 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
        if (mode & SPI_CPOL)
                csrx |= ATMEL_SPI_CSRx_CPOL;
 
-       as = malloc(sizeof(struct atmel_spi_slave));
+       as = spi_alloc_slave(struct atmel_spi_slave, bus, cs);
        if (!as)
                return NULL;
 
-       as->slave.bus = bus;
-       as->slave.cs = cs;
        as->regs = regs;
        as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS
+#if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9M10G45)
+                       | ATMEL_SPI_MR_WDRBT
+#endif
                        | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf);
        spi_writel(as, CSR(cs), csrx);
 
@@ -136,13 +137,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
        unsigned int    len_tx;
        unsigned int    len_rx;
        unsigned int    len;
-       int             ret;
        u32             status;
        const u8        *txp = dout;
        u8              *rxp = din;
        u8              value;
 
-       ret = 0;
        if (bitlen == 0)
                /* Finish any previously submitted transfers */
                goto out;
@@ -168,8 +167,17 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
         * somewhat quirky, and it doesn't really buy us much anyway
         * in the context of U-Boot.
         */
-       if (flags & SPI_XFER_BEGIN)
+       if (flags & SPI_XFER_BEGIN) {
                spi_cs_activate(slave);
+               /*
+                * sometimes the RDR is not empty when we get here,
+                * in theory that should not happen, but it DOES happen.
+                * Read it here to be on the safe side.
+                * That also clears the OVRES flag. Required if the
+                * following loop exits due to OVRES!
+                */
+               spi_readl(as, RDR);
+       }
 
        for (len_tx = 0, len_rx = 0; len_rx < len; ) {
                status = spi_readl(as, SR);