diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2009-10-02 15:34:25 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2009-10-02 15:34:25 +0200 |
commit | 5931e20907203970a6f6e39ab158857751422e0b (patch) | |
tree | aa69785d24d23755006ed44ea18da3c953d00f9a /drivers | |
parent | d13f32d50aa41c0e570040376ab4c47e98598e33 (diff) | |
download | barebox-5931e20907203970a6f6e39ab158857751422e0b.tar.gz barebox-5931e20907203970a6f6e39ab158857751422e0b.tar.xz |
imx spi: Use gpio as chip selects
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/imx_spi.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c index 81302022f8..8a483082ef 100644 --- a/drivers/spi/imx_spi.c +++ b/drivers/spi/imx_spi.c @@ -24,6 +24,8 @@ #include <spi/spi.h> #include <xfuncs.h> #include <asm/io.h> +#include <gpio.h> +#include <asm/arch/spi.h> #define MXC_CSPIRXDATA 0x00 #define MXC_CSPITXDATA 0x04 @@ -53,23 +55,20 @@ #define MXC_CSPISTAT_TE (1 << 0) #define MXC_CSPISTAT_TH (1 << 1) #define MXC_CSPISTAT_TF (1 << 2) -#define MXC_CSPISTAT_RR (1 << 3) -#define MXC_CSPISTAT_RH (1 << 4) -#define MXC_CSPISTAT_RF (1 << 5) -#define MXC_CSPISTAT_RO (1 << 6) -#define MXC_CSPISTAT_TC_0_7 (1 << 7) -#define MXC_CSPISTAT_TC_0_5 (1 << 8) -#define MXC_CSPISTAT_TC_0_4 (1 << 8) -#define MXC_CSPISTAT_TC_0_0 (1 << 3) -#define MXC_CSPISTAT_BO_0_7 0 -#define MXC_CSPISTAT_BO_0_5 (1 << 7) -#define MXC_CSPISTAT_BO_0_4 (1 << 7) -#define MXC_CSPISTAT_BO_0_0 (1 << 8) +#define MXC_CSPISTAT_RR (1 << 4) +#define MXC_CSPISTAT_RH (1 << 5) +#define MXC_CSPISTAT_RF (1 << 6) +#define MXC_CSPISTAT_RO (1 << 7) #define MXC_CSPIPERIOD_32KHZ (1 << 15) #define MXC_CSPITEST_LBC (1 << 14) +struct imx_spi { + struct spi_master master; + int *chipselect; +}; + static int imx_spi_setup(struct spi_device *spi) { debug("%s mode 0x%08x bits_per_word: %d speed: %d\n", @@ -89,7 +88,7 @@ static unsigned int spi_xchg_single(ulong base, unsigned int data) writel(cfg_reg, base + MXC_CSPICTRL); - while (readl(base + MXC_CSPICTRL) & MXC_CSPICTRL_XCH); + while (!(readl(base + MXC_CSPIINT) & MXC_CSPISTAT_RR)); return readl(base + MXC_CSPIRXDATA); } @@ -97,23 +96,41 @@ static unsigned int spi_xchg_single(ulong base, unsigned int data) static void mxc_spi_chipselect(struct spi_device *spi, int is_active) { struct spi_master *master = spi->master; + struct imx_spi *imx = container_of(master, struct imx_spi, master); ulong base = master->dev->map_base; + unsigned int cs = 0; + int gpio = imx->chipselect[spi->chip_select]; u32 ctrl_reg; - ctrl_reg = MXC_CSPICTRL_CS(spi->chip_select) - | MXC_CSPICTRL_BITCOUNT(spi->bits_per_word - 1) + if (spi->mode & SPI_CS_HIGH) + cs = 1; + + if (!is_active) { + if (gpio >= 0) + gpio_set_value(gpio, !cs); + return; + } + + ctrl_reg = MXC_CSPICTRL_BITCOUNT(spi->bits_per_word - 1) | MXC_CSPICTRL_DATARATE(7) /* FIXME: calculate data rate */ | MXC_CSPICTRL_ENABLE | MXC_CSPICTRL_MASTER; + if (gpio < 0) { + ctrl_reg |= MXC_CSPICTRL_CS(gpio + 32); + } + if (spi->mode & SPI_CPHA) ctrl_reg |= MXC_CSPICTRL_PHA; - if (!(spi->mode & SPI_CPOL)) + if (spi->mode & SPI_CPOL) ctrl_reg |= MXC_CSPICTRL_LOWPOL; if (spi->mode & SPI_CS_HIGH) ctrl_reg |= MXC_CSPICTRL_HIGHSSPOL; writel(ctrl_reg, base + MXC_CSPICTRL); + + if (gpio >= 0) + gpio_set_value(gpio, cs); } static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg) @@ -134,28 +151,34 @@ static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg) i++; } } + + mxc_spi_chipselect(spi, 0); + return 0; } static int imx_spi_probe(struct device_d *dev) { struct spi_master *master; + struct imx_spi *imx; + struct spi_imx_master *pdata = dev->platform_data; - debug("%s\n", __FUNCTION__); - - master = xzalloc(sizeof(struct spi_master)); - debug("master: %p %d\n", master, sizeof(struct spi_master)); + imx = xzalloc(sizeof(*imx)); + master = &imx->master; master->dev = dev; master->setup = imx_spi_setup; master->transfer = imx_spi_transfer; - master->num_chipselect = 1; /* FIXME: Board dependent */ + master->num_chipselect = pdata->num_chipselect; + imx->chipselect = pdata->chipselect; writel(MXC_CSPICTRL_ENABLE | MXC_CSPICTRL_MASTER, dev->map_base + MXC_CSPICTRL); writel(MXC_CSPIPERIOD_32KHZ, dev->map_base + MXC_CSPIPERIOD); + while (readl(dev->map_base + MXC_CSPIINT) & MXC_CSPISTAT_RR) + readl(dev->map_base + MXC_CSPIRXDATA); writel(0, dev->map_base + MXC_CSPIINT); spi_register_master(master); |