diff options
author | Guennadi Liakhovetski <lg@denx.de> | 2009-02-07 00:09:12 +0100 |
---|---|---|
committer | Anatolij Gustschin <agust@denx.de> | 2009-02-24 09:39:44 +0100 |
commit | f9b6a1575d9f1ca192e4cb60e547aa66f08baa3f (patch) | |
tree | 071f07007676225c3abaa2f3b3d84bde49aad846 | |
parent | bd76729bcbfd64b5d016a9b936f058931fc06eaf (diff) | |
download | u-boot-imx-f9b6a1575d9f1ca192e4cb60e547aa66f08baa3f.zip u-boot-imx-f9b6a1575d9f1ca192e4cb60e547aa66f08baa3f.tar.gz u-boot-imx-f9b6a1575d9f1ca192e4cb60e547aa66f08baa3f.tar.bz2 |
i.MX31: fix SPI driver for shorter than 32 bit
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>
-rw-r--r-- | drivers/spi/mxc_spi.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index 5957ada..0ac4e90 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -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) |