
Convert omap3_spi driver to DM and keep compatibility with previous mode.
Signed-off-by: Christophe Ricard christophe-h.ricard@st.com ---
drivers/spi/Kconfig | 6 + drivers/spi/omap3_spi.c | 439 ++++++++++++++++++++++++++++++++++++++++++------ drivers/spi/omap3_spi.h | 14 +- 3 files changed, 402 insertions(+), 57 deletions(-)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2cdb110..b8c2498 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -155,6 +155,12 @@ config ZYNQ_QSPI Zynq QSPI IP core. This IP is used to connect the flash in 4-bit qspi, 8-bit dual stacked and shared 4-bit dual parallel.
+config OMAP3_SPI + bool "McSPI driver for OMAP" + help + SPI master controller for OMAP24XX and later Multichannel SPI + (McSPI) modules. + endif # if DM_SPI
config FSL_ESPI diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 95cdfa3..09fb1ef 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -11,10 +11,14 @@ * * Modified by Ruslan Araslanov ruslan.araslanov@vitecmm.com * + * Copyright (c) 2016 Christophe Ricard christophe.ricard@gmail.com + * - Added support for DM_SPI + * * SPDX-License-Identifier: GPL-2.0+ */
#include <common.h> +#include <dm.h> #include <spi.h> #include <malloc.h> #include <asm/io.h> @@ -22,9 +26,17 @@
#define SPI_WAIT_TIMEOUT 10
+#ifdef CONFIG_DM_SPI +static void spi_reset(struct udevice *dev) +#else static void spi_reset(struct omap3_spi_slave *ds) +#endif { unsigned int tmp; +#ifdef CONFIG_DM_SPI + struct omap3_spi_slave *ds = dev_get_priv(dev->parent); + +#endif
writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &ds->regs->sysconfig); do { @@ -39,20 +51,50 @@ static void spi_reset(struct omap3_spi_slave *ds) writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable); }
+#ifdef CONFIG_DM_SPI +static void omap3_spi_write_chconf(struct udevice *dev, int val) +#else static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val) +#endif { - writel(val, &ds->regs->channel[ds->slave.cs].chconf); + unsigned int cs; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct omap3_spi_slave *ds = dev_get_priv(dev->parent); + + + cs = platdata->cs; +#else + cs = ds->slave.cs; +#endif + + writel(val, &ds->regs->channel[cs].chconf); /* Flash post writes to make immediate effect */ - readl(&ds->regs->channel[ds->slave.cs].chconf); + readl(&ds->regs->channel[cs].chconf); }
+#ifdef CONFIG_DM_SPI +static void omap3_spi_set_enable(struct udevice *dev, int enable) +#else static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable) +#endif { - writel(enable, &ds->regs->channel[ds->slave.cs].chctrl); + unsigned int cs; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct omap3_spi_slave *ds = dev_get_priv(dev->parent); + + cs = platdata->cs; +#else + cs = ds->slave.cs; +#endif + + writel(enable, &ds->regs->channel[cs].chctrl); /* Flash post writes to make immediate effect */ - readl(&ds->regs->channel[ds->slave.cs].chctrl); + readl(&ds->regs->channel[cs].chctrl); }
+#ifndef CONFIG_DM_SPI void spi_init() { /* do nothing */ @@ -138,10 +180,32 @@ void spi_free_slave(struct spi_slave *slave) free(ds); }
+int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return 1; +} +#endif + +#ifdef CONFIG_DM_SPI +static int omap3_spi_claim_bus(struct udevice *dev) +#else int spi_claim_bus(struct spi_slave *slave) +#endif { - struct omap3_spi_slave *ds = to_omap3_spi(slave); + unsigned int cs; + struct omap3_spi_slave *ds; unsigned int conf, div = 0; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); + + ds = dev_get_priv(dev->parent); + cs = platdata->cs; + ds->freq = slave->max_hz; +#else + ds = to_omap3_spi(slave); + cs = ds->slave.cs; +#endif
/* McSPI global module configuration */
@@ -149,7 +213,11 @@ int spi_claim_bus(struct spi_slave *slave) * setup when switching from (reset default) slave mode * to single-channel master mode */ +#ifdef CONFIG_DM_SPI + spi_reset(dev); +#else spi_reset(ds); +#endif conf = readl(&ds->regs->modulctrl); conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS); conf |= OMAP3_MCSPI_MODULCTRL_SINGLE; @@ -165,8 +233,7 @@ int spi_claim_bus(struct spi_slave *slave) } else div = 0xC;
- conf = readl(&ds->regs->channel[ds->slave.cs].chconf); - + conf = readl(&ds->regs->channel[cs].chconf); /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS * REVISIT: this controller could support SPI_3WIRE mode. */ @@ -184,7 +251,7 @@ int spi_claim_bus(struct spi_slave *slave)
/* wordlength */ conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK; - conf |= (ds->slave.wordlen - 1) << 7; + conf |= (slave->wordlen - 1) << 7;
/* set chipselect polarity; manage with FORCE */ if (!(ds->mode & SPI_CS_HIGH)) @@ -209,113 +276,222 @@ int spi_claim_bus(struct spi_slave *slave) /* Transmit & receive mode */ conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
+#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, conf); +#else omap3_spi_write_chconf(ds,conf); +#endif
return 0; }
+#ifdef CONFIG_DM_SPI +int omap3_spi_release_bus(struct udevice *dev) +#else void spi_release_bus(struct spi_slave *slave) +#endif { +#ifndef CONFIG_DM_SPI struct omap3_spi_slave *ds = to_omap3_spi(slave); - +#endif /* Reset the SPI hardware */ +#ifdef CONFIG_DM_SPI + spi_reset(dev); +#else spi_reset(ds); +#endif + +#ifdef CONFIG_DM_SPI + return 0; +#endif }
+#ifdef CONFIG_DM_SPI +int omap3_spi_write(struct udevice *dev, unsigned int len, const void *txp, + unsigned long flags) +#else int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp, unsigned long flags) +#endif { - struct omap3_spi_slave *ds = to_omap3_spi(slave); - int i; + struct omap3_spi_slave *ds; + int i, chconf; ulong start; - int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); + unsigned int cs; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); +
+ ds = dev_get_priv(dev->parent); + cs = platdata->cs; +#else + ds = to_omap3_spi(slave); + cs = ds->slave.cs; +#endif + + chconf = readl(&ds->regs->channel[cs].chconf); + +#ifdef CONFIG_DM_SPI /* Enable the channel */ - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_EN); +#else + /* Enable the channel */ + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_EN); +#endif
chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); +#ifdef CONFIG_DM_SPI + chconf |= (slave->wordlen - 1) << 7; +#else chconf |= (ds->slave.wordlen - 1) << 7; +#endif chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; chconf |= OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif
for (i = 0; i < len; i++) { /* wait till TX register is empty (TXS == 1) */ start = get_timer(0); - while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & + while (!(readl(&ds->regs->channel[cs].chstat) & OMAP3_MCSPI_CHSTAT_TXS)) { if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI TXS timed out, status=0x%08x\n", - readl(&ds->regs->channel[ds->slave.cs].chstat)); + readl(&ds->regs->channel[cs].chstat)); return -1; } } + /* Write the data */ - unsigned int *tx = &ds->regs->channel[ds->slave.cs].tx; + unsigned int *tx = &ds->regs->channel[cs].tx; +#ifdef CONFIG_DM_SPI + if (slave->wordlen > 16) +#else if (ds->slave.wordlen > 16) +#endif writel(((u32 *)txp)[i], tx); +#ifdef CONFIG_DM_SPI + else if (slave->wordlen > 8) +#else else if (ds->slave.wordlen > 8) +#endif writel(((u16 *)txp)[i], tx); else writel(((u8 *)txp)[i], tx); }
/* wait to finish of transfer */ - while ((readl(&ds->regs->channel[ds->slave.cs].chstat) & + while ((readl(&ds->regs->channel[cs].chstat) & (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) != - (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)); + (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) + ;
+#ifdef CONFIG_DM_SPI + /* Disable the channel otherwise the next immediate RX will get affected */ + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_DIS); +#else /* Disable the channel otherwise the next immediate RX will get affected */ - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_DIS); +#endif
if (flags & SPI_XFER_END) {
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif } + return 0; }
+#ifdef CONFIG_DM_SPI +int omap3_spi_read(struct udevice *dev, unsigned int len, void *rxp, + unsigned long flags) +#else int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp, unsigned long flags) +#endif { - struct omap3_spi_slave *ds = to_omap3_spi(slave); - int i; + struct omap3_spi_slave *ds; + int i, chconf; ulong start; - int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); + unsigned int cs; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev);
+ + ds = dev_get_priv(dev->parent); + cs = platdata->cs; +#else + ds = to_omap3_spi(slave); + cs = ds->slave.cs; +#endif + chconf = readl(&ds->regs->channel[cs].chconf); + +#ifdef CONFIG_DM_SPI + /* Enable the channel */ + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_EN); +#else /* Enable the channel */ - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_EN); +#endif
chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); +#ifdef CONFIG_DM_SPI + chconf |= (slave->wordlen - 1) << 7; +#else chconf |= (ds->slave.wordlen - 1) << 7; +#endif chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; chconf |= OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif
- writel(0, &ds->regs->channel[ds->slave.cs].tx); + writel(0, &ds->regs->channel[cs].tx);
for (i = 0; i < len; i++) { start = get_timer(0); /* Wait till RX register contains data (RXS == 1) */ - while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & + while (!(readl(&ds->regs->channel[cs].chstat) & OMAP3_MCSPI_CHSTAT_RXS)) { if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI RXS timed out, status=0x%08x\n", - readl(&ds->regs->channel[ds->slave.cs].chstat)); + readl(&ds->regs->channel[cs].chstat)); return -1; } } - /* Disable the channel to prevent furher receiving */ if(i == (len - 1)) - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); +#ifdef CONFIG_DM_SPI + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_DIS); +#else + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_DIS); +#endif
/* Read the data */ - unsigned int *rx = &ds->regs->channel[ds->slave.cs].rx; + unsigned int *rx = &ds->regs->channel[cs].rx; +#ifdef CONFIG_DM_SPI + if (slave->wordlen > 16) +#else if (ds->slave.wordlen > 16) +#endif ((u32 *)rxp)[i] = readl(rx); +#ifdef CONFIG_DM_SPI + else if (slave->wordlen > 8) +#else else if (ds->slave.wordlen > 8) +#endif ((u16 *)rxp)[i] = (u16)readl(rx); else ((u8 *)rxp)[i] = (u8)readl(rx); @@ -323,89 +499,177 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif }
return 0; }
+#ifdef CONFIG_DM_SPI +/*McSPI Transmit Receive Mode*/ +int omap3_spi_txrx(struct udevice *dev, unsigned int len, + const void *txp, void *rxp, unsigned long flags) +#else /*McSPI Transmit Receive Mode*/ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, const void *txp, void *rxp, unsigned long flags) +#endif { - struct omap3_spi_slave *ds = to_omap3_spi(slave); + struct omap3_spi_slave *ds; ulong start; - int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); + int chconf; int i=0; + unsigned int cs; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); +
+ ds = dev_get_priv(dev->parent); + cs = platdata->cs; +#else + ds = to_omap3_spi(slave); + cs = ds->slave.cs; +#endif + chconf = readl(&ds->regs->channel[cs].chconf); + +#ifdef CONFIG_DM_SPI + /*Enable SPI channel*/ + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_EN); +#else /*Enable SPI channel*/ - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_EN); +#endif
/*set TRANSMIT-RECEIVE Mode*/ chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); +#ifdef CONFIG_DM_SPI + chconf |= (slave->wordlen - 1) << 7; +#else chconf |= (ds->slave.wordlen - 1) << 7; +#endif chconf |= OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif
/*Shift in and out 1 byte at time*/ for (i=0; i < len; i++){ /* Write: wait for TX empty (TXS == 1)*/ start = get_timer(0); - while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & + while (!(readl(&ds->regs->channel[cs].chstat) & OMAP3_MCSPI_CHSTAT_TXS)) { if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI TXS timed out, status=0x%08x\n", - readl(&ds->regs->channel[ds->slave.cs].chstat)); + readl(&ds->regs->channel[cs].chstat)); return -1; } } /* Write the data */ - unsigned int *tx = &ds->regs->channel[ds->slave.cs].tx; + unsigned int *tx = &ds->regs->channel[cs].tx; +#ifdef CONFIG_DM_SPI + if (slave->wordlen > 16) +#else if (ds->slave.wordlen > 16) +#endif writel(((u32 *)txp)[i], tx); +#ifdef CONFIG_DM_SPI + else if (slave->wordlen > 8) +#else else if (ds->slave.wordlen > 8) +#endif writel(((u16 *)txp)[i], tx); else writel(((u8 *)txp)[i], tx);
/*Read: wait for RX containing data (RXS == 1)*/ start = get_timer(0); - while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & + while (!(readl(&ds->regs->channel[cs].chstat) & OMAP3_MCSPI_CHSTAT_RXS)) { if (get_timer(start) > SPI_WAIT_TIMEOUT) { printf("SPI RXS timed out, status=0x%08x\n", - readl(&ds->regs->channel[ds->slave.cs].chstat)); + readl(&ds->regs->channel[cs].chstat)); return -1; } } /* Read the data */ - unsigned int *rx = &ds->regs->channel[ds->slave.cs].rx; + unsigned int *rx = &ds->regs->channel[cs].rx; +#ifdef CONFIG_DM_SPI + if (slave->wordlen > 16) +#else if (ds->slave.wordlen > 16) +#endif ((u32 *)rxp)[i] = readl(rx); +#ifdef CONFIG_DM_SPI + else if (slave->wordlen > 8) +#else else if (ds->slave.wordlen > 8) +#endif ((u16 *)rxp)[i] = (u16)readl(rx); else ((u8 *)rxp)[i] = (u8)readl(rx); } + +#ifdef CONFIG_DM_SPI + /* Disable the channel */ + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_DIS); +#else /* Disable the channel */ - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_DIS); +#endif
/*if transfer must be terminated disable the channel*/ if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif }
return 0; }
+#ifdef CONFIG_DM_SPI +int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +#else int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) +#endif { - struct omap3_spi_slave *ds = to_omap3_spi(slave); - unsigned int len; + struct omap3_spi_slave *ds; + unsigned int len, cs; int ret = -1; +#ifdef CONFIG_DM_SPI + struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); + + ds = dev_get_priv(dev->parent); + cs = platdata->cs; +#else + ds = to_omap3_spi(slave); + cs = ds->slave.cs; +#endif
+#ifdef CONFIG_DM_SPI + if (slave->wordlen < 4 || slave->wordlen > 32) { + printf("omap3_spi: invalid wordlen %d\n", slave->wordlen); + return -1; + } + + if (bitlen % slave->wordlen) + return -1; + + len = bitlen / slave->wordlen; +#else if (ds->slave.wordlen < 4 || ds->slave.wordlen > 32) { printf("omap3_spi: invalid wordlen %d\n", ds->slave.wordlen); return -1; @@ -415,41 +679,104 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, return -1;
len = bitlen / ds->slave.wordlen; +#endif
if (bitlen == 0) { /* only change CS */ - int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); + int chconf = readl(&ds->regs->channel[cs].chconf);
if (flags & SPI_XFER_BEGIN) { - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); +#ifdef CONFIG_DM_SPI + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_EN); +#else + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_EN); +#endif chconf |= OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); +#else + omap3_spi_write_chconf(ds, chconf); +#endif } if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - omap3_spi_write_chconf(ds,chconf); - omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); +#ifdef CONFIG_DM_SPI + omap3_spi_write_chconf(dev, chconf); + omap3_spi_set_enable(dev, OMAP3_MCSPI_CHCTRL_DIS); +#else + omap3_spi_write_chconf(ds, chconf); + omap3_spi_set_enable(ds, OMAP3_MCSPI_CHCTRL_DIS); +#endif } ret = 0; } else { +#ifdef CONFIG_DM_SPI + if (dout != NULL && din != NULL) + ret = omap3_spi_txrx(dev, len, dout, din, flags); + else if (dout != NULL) + ret = omap3_spi_write(dev, len, dout, flags); + else if (din != NULL) + ret = omap3_spi_read(dev, len, din, flags); +#else if (dout != NULL && din != NULL) ret = omap3_spi_txrx(slave, len, dout, din, flags); else if (dout != NULL) ret = omap3_spi_write(slave, len, dout, flags); else if (din != NULL) ret = omap3_spi_read(slave, len, din, flags); +#endif } return ret; }
-int spi_cs_is_valid(unsigned int bus, unsigned int cs) +void spi_cs_activate(struct spi_slave *slave) { - return 1; }
-void spi_cs_activate(struct spi_slave *slave) +void spi_cs_deactivate(struct spi_slave *slave) { }
-void spi_cs_deactivate(struct spi_slave *slave) +#ifdef CONFIG_DM_SPI +static int omap3_spi_probe(struct udevice *dev) { + struct omap3_spi_slave *ds = dev_get_priv(dev); + + ds->regs = (struct mcspi *)dev_get_addr(dev); + + return 0; } + +static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed) +{ + return 0; +} + +static int omap3_spi_set_mode(struct udevice *bus, uint mode) +{ + return 0; +} + + +static const struct dm_spi_ops omap3_spi_ops = { + .claim_bus = omap3_spi_claim_bus, + .release_bus = omap3_spi_release_bus, + .xfer = omap3_spi_xfer, + .set_speed = omap3_spi_set_speed, + .set_mode = omap3_spi_set_mode, +}; + +static const struct udevice_id omap3_spi_ids[] = { + { .compatible = "ti,omap2-mcspi" }, + { .compatible = "ti,omap4-mcspi" }, + { } +}; + +U_BOOT_DRIVER(omap3_spi) = { + .name = "omap3_spi", + .id = UCLASS_SPI, + .of_match = omap3_spi_ids, + .probe = omap3_spi_probe, + .ops = &omap3_spi_ops, + .priv_auto_alloc_size = sizeof(struct omap3_spi_slave), +}; +#endif diff --git a/drivers/spi/omap3_spi.h b/drivers/spi/omap3_spi.h index 6a07c6d..a974ca3 100644 --- a/drivers/spi/omap3_spi.h +++ b/drivers/spi/omap3_spi.h @@ -88,22 +88,34 @@ struct mcspi { #define OMAP3_MCSPI_WAKEUPENABLE_WKEN BIT(0)
struct omap3_spi_slave { +#ifndef CONFIG_DM_SPI struct spi_slave slave; +#endif struct mcspi *regs; unsigned int freq; unsigned int mode; };
+#ifndef CONFIG_DM_SPI static inline struct omap3_spi_slave *to_omap3_spi(struct spi_slave *slave) { return container_of(slave, struct omap3_spi_slave, slave); } +#endif
+#ifdef CONFIG_DM_SPI +int omap3_spi_txrx(struct udevice *dev, unsigned int len, const void *txp, + void *rxp, unsigned long flags); +int omap3_spi_write(struct udevice *dev, unsigned int len, const void *txp, + unsigned long flags); +int omap3_spi_read(struct udevice *dev, unsigned int len, void *rxp, + unsigned long flags); +#else int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, const void *txp, void *rxp, unsigned long flags); int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp, unsigned long flags); int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp, unsigned long flags); - +#endif #endif /* _OMAP3_SPI_H_ */