Convert omap3_spi driver to DM and keep compatibility with previous
mode.

Signed-off-by: Christophe Ricard <christophe-h.ric...@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.arasla...@vitecmm.com>
  *
+ * Copyright (c) 2016 Christophe Ricard <christophe.ric...@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_ */
-- 
2.5.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to