i.MX31: fix SPI driver for shorter than 32 bit
authorGuennadi Liakhovetski <lg@denx.de>
Fri, 6 Feb 2009 23:09:12 +0000 (00:09 +0100)
committerAnatolij Gustschin <agust@denx.de>
Tue, 24 Feb 2009 08:39:44 +0000 (09:39 +0100)
Fix setting the SPI Control register, 8 and 16-bit transfers
and a wrong pointer in the free routine in the mxc_spi driver.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
drivers/spi/mxc_spi.c

index 5957ada3a4a626aba3584093d2018ae0e88a3946..0ac4e908e38ff53868cd49ad322c689f98dfb11a 100644 (file)
@@ -90,17 +90,15 @@ static u32 spi_xchg_single(struct spi_slave *slave, u32 data, int bitlen)
        struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
        unsigned int cfg_reg = reg_read(mxcs->base + MXC_CSPICTRL);
 
-       if (MXC_CSPICTRL_BITCOUNT(bitlen - 1) != (cfg_reg & MXC_CSPICTRL_BITCOUNT(31))) {
-               cfg_reg = (cfg_reg & ~MXC_CSPICTRL_BITCOUNT(31)) |
-                       MXC_CSPICTRL_BITCOUNT(bitlen - 1);
-               reg_write(mxcs->base + MXC_CSPICTRL, cfg_reg);
-       }
+       mxcs->ctrl_reg = (mxcs->ctrl_reg & ~MXC_CSPICTRL_BITCOUNT(31)) |
+               MXC_CSPICTRL_BITCOUNT(bitlen - 1);
 
-       reg_write(mxcs->base + MXC_CSPITXDATA, data);
+       if (cfg_reg != mxcs->ctrl_reg)
+               reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg);
 
-       cfg_reg |= MXC_CSPICTRL_XCH;
+       reg_write(mxcs->base + MXC_CSPITXDATA, data);
 
-       reg_write(mxcs->base + MXC_CSPICTRL, cfg_reg);
+       reg_write(mxcs->base + MXC_CSPICTRL, mxcs->ctrl_reg | MXC_CSPICTRL_XCH);
 
        while (reg_read(mxcs->base + MXC_CSPICTRL) & MXC_CSPICTRL_XCH)
                ;
@@ -122,8 +120,17 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 
        for (i = 0, in_l = (u32 *)din, out_l = (u32 *)dout;
             i < n_blks;
-            i++, in_l++, out_l++, bitlen -= 32)
-               *in_l = spi_xchg_single(slave, *out_l, bitlen);
+            i++, in_l++, out_l++, bitlen -= 32) {
+               u32 data = spi_xchg_single(slave, *out_l, bitlen);
+
+               /* Check if we're only transfering 8 or 16 bits */
+               if (!i) {
+                       if (bitlen < 9)
+                               *(u8 *)din = data;
+                       else if (bitlen < 17)
+                               *(u16 *)din = data;
+               }
+       }
 
        return 0;
 }
@@ -169,7 +176,9 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 
 void spi_free_slave(struct spi_slave *slave)
 {
-       free(slave);
+       struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
+
+       free(mxcs);
 }
 
 int spi_claim_bus(struct spi_slave *slave)