uboot/drivers/spi/omap3_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
   4 *                    Christophe Ricard <christophe.ricard@gmail.com>
   5 *
   6 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com>
   7 *
   8 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c
   9 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
  10 *
  11 * Copyright (C) 2007 Atmel Corporation
  12 *
  13 * Parts taken from linux/drivers/spi/omap2_mcspi.c
  14 * Copyright (C) 2005, 2006 Nokia Corporation
  15 *
  16 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com>
  17 */
  18
  19#include <common.h>
  20#include <dm.h>
  21#include <spi.h>
  22#include <malloc.h>
  23#include <asm/io.h>
  24
  25DECLARE_GLOBAL_DATA_PTR;
  26
  27#if defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX)
  28#define OMAP3_MCSPI1_BASE       0x48030100
  29#define OMAP3_MCSPI2_BASE       0x481A0100
  30#else
  31#define OMAP3_MCSPI1_BASE       0x48098000
  32#define OMAP3_MCSPI2_BASE       0x4809A000
  33#define OMAP3_MCSPI3_BASE       0x480B8000
  34#define OMAP3_MCSPI4_BASE       0x480BA000
  35#endif
  36
  37#define OMAP4_MCSPI_REG_OFFSET  0x100
  38
  39struct omap2_mcspi_platform_config {
  40        unsigned int regs_offset;
  41};
  42
  43/* per-register bitmasks */
  44#define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
  45#define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2)
  46#define OMAP3_MCSPI_SYSCONFIG_AUTOIDLE  BIT(0)
  47#define OMAP3_MCSPI_SYSCONFIG_SOFTRESET BIT(1)
  48
  49#define OMAP3_MCSPI_SYSSTATUS_RESETDONE BIT(0)
  50
  51#define OMAP3_MCSPI_MODULCTRL_SINGLE    BIT(0)
  52#define OMAP3_MCSPI_MODULCTRL_MS        BIT(2)
  53#define OMAP3_MCSPI_MODULCTRL_STEST     BIT(3)
  54
  55#define OMAP3_MCSPI_CHCONF_PHA          BIT(0)
  56#define OMAP3_MCSPI_CHCONF_POL          BIT(1)
  57#define OMAP3_MCSPI_CHCONF_CLKD_MASK    GENMASK(5, 2)
  58#define OMAP3_MCSPI_CHCONF_EPOL         BIT(6)
  59#define OMAP3_MCSPI_CHCONF_WL_MASK      GENMASK(11, 7)
  60#define OMAP3_MCSPI_CHCONF_TRM_RX_ONLY  BIT(12)
  61#define OMAP3_MCSPI_CHCONF_TRM_TX_ONLY  BIT(13)
  62#define OMAP3_MCSPI_CHCONF_TRM_MASK     GENMASK(13, 12)
  63#define OMAP3_MCSPI_CHCONF_DMAW         BIT(14)
  64#define OMAP3_MCSPI_CHCONF_DMAR         BIT(15)
  65#define OMAP3_MCSPI_CHCONF_DPE0         BIT(16)
  66#define OMAP3_MCSPI_CHCONF_DPE1         BIT(17)
  67#define OMAP3_MCSPI_CHCONF_IS           BIT(18)
  68#define OMAP3_MCSPI_CHCONF_TURBO        BIT(19)
  69#define OMAP3_MCSPI_CHCONF_FORCE        BIT(20)
  70
  71#define OMAP3_MCSPI_CHSTAT_RXS          BIT(0)
  72#define OMAP3_MCSPI_CHSTAT_TXS          BIT(1)
  73#define OMAP3_MCSPI_CHSTAT_EOT          BIT(2)
  74
  75#define OMAP3_MCSPI_CHCTRL_EN           BIT(0)
  76#define OMAP3_MCSPI_CHCTRL_DIS          (0 << 0)
  77
  78#define OMAP3_MCSPI_WAKEUPENABLE_WKEN   BIT(0)
  79#define MCSPI_PINDIR_D0_IN_D1_OUT       0
  80#define MCSPI_PINDIR_D0_OUT_D1_IN       1
  81
  82#define OMAP3_MCSPI_MAX_FREQ            48000000
  83#define SPI_WAIT_TIMEOUT                10
  84
  85/* OMAP3 McSPI registers */
  86struct mcspi_channel {
  87        unsigned int chconf;            /* 0x2C, 0x40, 0x54, 0x68 */
  88        unsigned int chstat;            /* 0x30, 0x44, 0x58, 0x6C */
  89        unsigned int chctrl;            /* 0x34, 0x48, 0x5C, 0x70 */
  90        unsigned int tx;                /* 0x38, 0x4C, 0x60, 0x74 */
  91        unsigned int rx;                /* 0x3C, 0x50, 0x64, 0x78 */
  92};
  93
  94struct mcspi {
  95        unsigned char res1[0x10];
  96        unsigned int sysconfig;         /* 0x10 */
  97        unsigned int sysstatus;         /* 0x14 */
  98        unsigned int irqstatus;         /* 0x18 */
  99        unsigned int irqenable;         /* 0x1C */
 100        unsigned int wakeupenable;      /* 0x20 */
 101        unsigned int syst;              /* 0x24 */
 102        unsigned int modulctrl;         /* 0x28 */
 103        struct mcspi_channel channel[4];
 104        /* channel0: 0x2C - 0x3C, bus 0 & 1 & 2 & 3 */
 105        /* channel1: 0x40 - 0x50, bus 0 & 1 */
 106        /* channel2: 0x54 - 0x64, bus 0 & 1 */
 107        /* channel3: 0x68 - 0x78, bus 0 */
 108};
 109
 110struct omap3_spi_priv {
 111#ifndef CONFIG_DM_SPI
 112        struct spi_slave slave;
 113#endif
 114        struct mcspi *regs;
 115        unsigned int cs;
 116        unsigned int freq;
 117        unsigned int mode;
 118        unsigned int wordlen;
 119        unsigned int pin_dir:1;
 120};
 121
 122static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val)
 123{
 124        writel(val, &priv->regs->channel[priv->cs].chconf);
 125        /* Flash post writes to make immediate effect */
 126        readl(&priv->regs->channel[priv->cs].chconf);
 127}
 128
 129static void omap3_spi_set_enable(struct omap3_spi_priv *priv, int enable)
 130{
 131        writel(enable, &priv->regs->channel[priv->cs].chctrl);
 132        /* Flash post writes to make immediate effect */
 133        readl(&priv->regs->channel[priv->cs].chctrl);
 134}
 135
 136static int omap3_spi_write(struct omap3_spi_priv *priv, unsigned int len,
 137                           const void *txp, unsigned long flags)
 138{
 139        ulong start;
 140        int i, chconf;
 141
 142        chconf = readl(&priv->regs->channel[priv->cs].chconf);
 143
 144        /* Enable the channel */
 145        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
 146
 147        chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
 148        chconf |= (priv->wordlen - 1) << 7;
 149        chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
 150        chconf |= OMAP3_MCSPI_CHCONF_FORCE;
 151        omap3_spi_write_chconf(priv, chconf);
 152
 153        for (i = 0; i < len; i++) {
 154                /* wait till TX register is empty (TXS == 1) */
 155                start = get_timer(0);
 156                while (!(readl(&priv->regs->channel[priv->cs].chstat) &
 157                         OMAP3_MCSPI_CHSTAT_TXS)) {
 158                        if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 159                                printf("SPI TXS timed out, status=0x%08x\n",
 160                                        readl(&priv->regs->channel[priv->cs].chstat));
 161                                return -1;
 162                        }
 163                }
 164                /* Write the data */
 165                unsigned int *tx = &priv->regs->channel[priv->cs].tx;
 166                if (priv->wordlen > 16)
 167                        writel(((u32 *)txp)[i], tx);
 168                else if (priv->wordlen > 8)
 169                        writel(((u16 *)txp)[i], tx);
 170                else
 171                        writel(((u8 *)txp)[i], tx);
 172        }
 173
 174        /* wait to finish of transfer */
 175        while ((readl(&priv->regs->channel[priv->cs].chstat) &
 176                        (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) !=
 177                        (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS))
 178                ;
 179
 180        /* Disable the channel otherwise the next immediate RX will get affected */
 181        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
 182
 183        if (flags & SPI_XFER_END) {
 184
 185                chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
 186                omap3_spi_write_chconf(priv, chconf);
 187        }
 188        return 0;
 189}
 190
 191static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len,
 192                          void *rxp, unsigned long flags)
 193{
 194        int i, chconf;
 195        ulong start;
 196
 197        chconf = readl(&priv->regs->channel[priv->cs].chconf);
 198
 199        /* Enable the channel */
 200        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
 201
 202        chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
 203        chconf |= (priv->wordlen - 1) << 7;
 204        chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
 205        chconf |= OMAP3_MCSPI_CHCONF_FORCE;
 206        omap3_spi_write_chconf(priv, chconf);
 207
 208        writel(0, &priv->regs->channel[priv->cs].tx);
 209
 210        for (i = 0; i < len; i++) {
 211                start = get_timer(0);
 212                /* Wait till RX register contains data (RXS == 1) */
 213                while (!(readl(&priv->regs->channel[priv->cs].chstat) &
 214                         OMAP3_MCSPI_CHSTAT_RXS)) {
 215                        if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 216                                printf("SPI RXS timed out, status=0x%08x\n",
 217                                        readl(&priv->regs->channel[priv->cs].chstat));
 218                                return -1;
 219                        }
 220                }
 221
 222                /* Disable the channel to prevent furher receiving */
 223                if (i == (len - 1))
 224                        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
 225
 226                /* Read the data */
 227                unsigned int *rx = &priv->regs->channel[priv->cs].rx;
 228                if (priv->wordlen > 16)
 229                        ((u32 *)rxp)[i] = readl(rx);
 230                else if (priv->wordlen > 8)
 231                        ((u16 *)rxp)[i] = (u16)readl(rx);
 232                else
 233                        ((u8 *)rxp)[i] = (u8)readl(rx);
 234        }
 235
 236        if (flags & SPI_XFER_END) {
 237                chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
 238                omap3_spi_write_chconf(priv, chconf);
 239        }
 240
 241        return 0;
 242}
 243
 244/*McSPI Transmit Receive Mode*/
 245static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len,
 246                          const void *txp, void *rxp, unsigned long flags)
 247{
 248        ulong start;
 249        int chconf, i = 0;
 250
 251        chconf = readl(&priv->regs->channel[priv->cs].chconf);
 252
 253        /*Enable SPI channel*/
 254        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
 255
 256        /*set TRANSMIT-RECEIVE Mode*/
 257        chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
 258        chconf |= (priv->wordlen - 1) << 7;
 259        chconf |= OMAP3_MCSPI_CHCONF_FORCE;
 260        omap3_spi_write_chconf(priv, chconf);
 261
 262        /*Shift in and out 1 byte at time*/
 263        for (i=0; i < len; i++){
 264                /* Write: wait for TX empty (TXS == 1)*/
 265                start = get_timer(0);
 266                while (!(readl(&priv->regs->channel[priv->cs].chstat) &
 267                         OMAP3_MCSPI_CHSTAT_TXS)) {
 268                        if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 269                                printf("SPI TXS timed out, status=0x%08x\n",
 270                                        readl(&priv->regs->channel[priv->cs].chstat));
 271                                return -1;
 272                        }
 273                }
 274                /* Write the data */
 275                unsigned int *tx = &priv->regs->channel[priv->cs].tx;
 276                if (priv->wordlen > 16)
 277                        writel(((u32 *)txp)[i], tx);
 278                else if (priv->wordlen > 8)
 279                        writel(((u16 *)txp)[i], tx);
 280                else
 281                        writel(((u8 *)txp)[i], tx);
 282
 283                /*Read: wait for RX containing data (RXS == 1)*/
 284                start = get_timer(0);
 285                while (!(readl(&priv->regs->channel[priv->cs].chstat) &
 286                         OMAP3_MCSPI_CHSTAT_RXS)) {
 287                        if (get_timer(start) > SPI_WAIT_TIMEOUT) {
 288                                printf("SPI RXS timed out, status=0x%08x\n",
 289                                        readl(&priv->regs->channel[priv->cs].chstat));
 290                                return -1;
 291                        }
 292                }
 293                /* Read the data */
 294                unsigned int *rx = &priv->regs->channel[priv->cs].rx;
 295                if (priv->wordlen > 16)
 296                        ((u32 *)rxp)[i] = readl(rx);
 297                else if (priv->wordlen > 8)
 298                        ((u16 *)rxp)[i] = (u16)readl(rx);
 299                else
 300                        ((u8 *)rxp)[i] = (u8)readl(rx);
 301        }
 302        /* Disable the channel */
 303        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
 304
 305        /*if transfer must be terminated disable the channel*/
 306        if (flags & SPI_XFER_END) {
 307                chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
 308                omap3_spi_write_chconf(priv, chconf);
 309        }
 310
 311        return 0;
 312}
 313
 314static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen,
 315                     const void *dout, void *din, unsigned long flags)
 316{
 317        unsigned int    len;
 318        int ret = -1;
 319
 320        if (priv->wordlen < 4 || priv->wordlen > 32) {
 321                printf("omap3_spi: invalid wordlen %d\n", priv->wordlen);
 322                return -1;
 323        }
 324
 325        if (bitlen % priv->wordlen)
 326                return -1;
 327
 328        len = bitlen / priv->wordlen;
 329
 330        if (bitlen == 0) {       /* only change CS */
 331                int chconf = readl(&priv->regs->channel[priv->cs].chconf);
 332
 333                if (flags & SPI_XFER_BEGIN) {
 334                        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
 335                        chconf |= OMAP3_MCSPI_CHCONF_FORCE;
 336                        omap3_spi_write_chconf(priv, chconf);
 337                }
 338                if (flags & SPI_XFER_END) {
 339                        chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
 340                        omap3_spi_write_chconf(priv, chconf);
 341                        omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
 342                }
 343                ret = 0;
 344        } else {
 345                if (dout != NULL && din != NULL)
 346                        ret = omap3_spi_txrx(priv, len, dout, din, flags);
 347                else if (dout != NULL)
 348                        ret = omap3_spi_write(priv, len, dout, flags);
 349                else if (din != NULL)
 350                        ret = omap3_spi_read(priv, len, din, flags);
 351        }
 352        return ret;
 353}
 354
 355static void _omap3_spi_set_speed(struct omap3_spi_priv *priv)
 356{
 357        uint32_t confr, div = 0;
 358
 359        confr = readl(&priv->regs->channel[priv->cs].chconf);
 360
 361        /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
 362        if (priv->freq) {
 363                while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
 364                                        > priv->freq)
 365                        div++;
 366        } else {
 367                 div = 0xC;
 368        }
 369
 370        /* set clock divisor */
 371        confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
 372        confr |= div << 2;
 373
 374        omap3_spi_write_chconf(priv, confr);
 375}
 376
 377static void _omap3_spi_set_mode(struct omap3_spi_priv *priv)
 378{
 379        uint32_t confr;
 380
 381        confr = readl(&priv->regs->channel[priv->cs].chconf);
 382
 383        /* standard 4-wire master mode:  SCK, MOSI/out, MISO/in, nCS
 384         * REVISIT: this controller could support SPI_3WIRE mode.
 385         */
 386        if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
 387                confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
 388                confr |= OMAP3_MCSPI_CHCONF_DPE0;
 389        } else {
 390                confr &= ~OMAP3_MCSPI_CHCONF_DPE0;
 391                confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1;
 392        }
 393
 394        /* set SPI mode 0..3 */
 395        confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA);
 396        if (priv->mode & SPI_CPHA)
 397                confr |= OMAP3_MCSPI_CHCONF_PHA;
 398        if (priv->mode & SPI_CPOL)
 399                confr |= OMAP3_MCSPI_CHCONF_POL;
 400
 401        /* set chipselect polarity; manage with FORCE */
 402        if (!(priv->mode & SPI_CS_HIGH))
 403                confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
 404        else
 405                confr &= ~OMAP3_MCSPI_CHCONF_EPOL;
 406
 407        /* Transmit & receive mode */
 408        confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
 409
 410        omap3_spi_write_chconf(priv, confr);
 411}
 412
 413static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv)
 414{
 415        unsigned int confr;
 416
 417        /* McSPI individual channel configuration */
 418        confr = readl(&priv->regs->channel[priv->cs].chconf);
 419
 420        /* wordlength */
 421        confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
 422        confr |= (priv->wordlen - 1) << 7;
 423
 424        omap3_spi_write_chconf(priv, confr);
 425}
 426
 427static void spi_reset(struct mcspi *regs)
 428{
 429        unsigned int tmp;
 430
 431        writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &regs->sysconfig);
 432        do {
 433                tmp = readl(&regs->sysstatus);
 434        } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE));
 435
 436        writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE |
 437               OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP |
 438               OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, &regs->sysconfig);
 439
 440        writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &regs->wakeupenable);
 441}
 442
 443static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
 444{
 445        unsigned int conf;
 446        /*
 447         * setup when switching from (reset default) slave mode
 448         * to single-channel master mode
 449         */
 450        conf = readl(&priv->regs->modulctrl);
 451        conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS);
 452        conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
 453
 454        writel(conf, &priv->regs->modulctrl);
 455}
 456
 457#ifndef CONFIG_DM_SPI
 458
 459static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave)
 460{
 461        return container_of(slave, struct omap3_spi_priv, slave);
 462}
 463
 464void spi_free_slave(struct spi_slave *slave)
 465{
 466        struct omap3_spi_priv *priv = to_omap3_spi(slave);
 467
 468        free(priv);
 469}
 470
 471int spi_claim_bus(struct spi_slave *slave)
 472{
 473        struct omap3_spi_priv *priv = to_omap3_spi(slave);
 474
 475        spi_reset(priv->regs);
 476
 477        _omap3_spi_claim_bus(priv);
 478        _omap3_spi_set_wordlen(priv);
 479        _omap3_spi_set_mode(priv);
 480        _omap3_spi_set_speed(priv);
 481
 482        return 0;
 483}
 484
 485void spi_release_bus(struct spi_slave *slave)
 486{
 487        struct omap3_spi_priv *priv = to_omap3_spi(slave);
 488
 489        writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
 490}
 491
 492struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 493                                     unsigned int max_hz, unsigned int mode)
 494{
 495        struct omap3_spi_priv *priv;
 496        struct mcspi *regs;
 497
 498        /*
 499         * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
 500         * with different number of chip selects (CS, channels):
 501         * McSPI1 has 4 CS (bus 0, cs 0 - 3)
 502         * McSPI2 has 2 CS (bus 1, cs 0 - 1)
 503         * McSPI3 has 2 CS (bus 2, cs 0 - 1)
 504         * McSPI4 has 1 CS (bus 3, cs 0)
 505         */
 506
 507        switch (bus) {
 508        case 0:
 509                 regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
 510                 break;
 511#ifdef OMAP3_MCSPI2_BASE
 512        case 1:
 513                 regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
 514                 break;
 515#endif
 516#ifdef OMAP3_MCSPI3_BASE
 517        case 2:
 518                 regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
 519                 break;
 520#endif
 521#ifdef OMAP3_MCSPI4_BASE
 522        case 3:
 523                 regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
 524                 break;
 525#endif
 526        default:
 527                 printf("SPI error: unsupported bus %i.  Supported busses 0 - 3\n", bus);
 528                 return NULL;
 529        }
 530
 531        if (((bus == 0) && (cs > 3)) ||
 532            ((bus == 1) && (cs > 1)) ||
 533            ((bus == 2) && (cs > 1)) ||
 534            ((bus == 3) && (cs > 0))) {
 535                printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus);
 536                return NULL;
 537        }
 538
 539        if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
 540                printf("SPI error: unsupported frequency %i Hz. Max frequency is 48 MHz\n",
 541                       max_hz);
 542                return NULL;
 543        }
 544
 545        if (mode > SPI_MODE_3) {
 546                printf("SPI error: unsupported SPI mode %i\n", mode);
 547                return NULL;
 548        }
 549
 550        priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs);
 551        if (!priv) {
 552                printf("SPI error: malloc of SPI structure failed\n");
 553                return NULL;
 554        }
 555
 556        priv->regs = regs;
 557        priv->cs = cs;
 558        priv->freq = max_hz;
 559        priv->mode = mode;
 560        priv->wordlen = priv->slave.wordlen;
 561#if 0
 562        /* Please migrate to DM_SPI support for this feature. */
 563        priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
 564#endif
 565
 566        return &priv->slave;
 567}
 568
 569int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 570             const void *dout, void *din, unsigned long flags)
 571{
 572        struct omap3_spi_priv *priv = to_omap3_spi(slave);
 573
 574        return _spi_xfer(priv, bitlen, dout, din, flags);
 575}
 576
 577#else
 578
 579static int omap3_spi_claim_bus(struct udevice *dev)
 580{
 581        struct udevice *bus = dev->parent;
 582        struct omap3_spi_priv *priv = dev_get_priv(bus);
 583        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 584
 585        priv->cs = slave_plat->cs;
 586        priv->freq = slave_plat->max_hz;
 587
 588        _omap3_spi_claim_bus(priv);
 589
 590        return 0;
 591}
 592
 593static int omap3_spi_release_bus(struct udevice *dev)
 594{
 595        struct udevice *bus = dev->parent;
 596        struct omap3_spi_priv *priv = dev_get_priv(bus);
 597
 598        writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
 599
 600        return 0;
 601}
 602
 603static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
 604{
 605        struct udevice *bus = dev->parent;
 606        struct omap3_spi_priv *priv = dev_get_priv(bus);
 607        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 608
 609        priv->cs = slave_plat->cs;
 610        priv->wordlen = wordlen;
 611        _omap3_spi_set_wordlen(priv);
 612
 613        return 0;
 614}
 615
 616static int omap3_spi_probe(struct udevice *dev)
 617{
 618        struct omap3_spi_priv *priv = dev_get_priv(dev);
 619        const void *blob = gd->fdt_blob;
 620        int node = dev_of_offset(dev);
 621
 622        struct omap2_mcspi_platform_config* data =
 623                (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
 624
 625        priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset);
 626        if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in"))
 627                priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
 628        else
 629                priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
 630        priv->wordlen = SPI_DEFAULT_WORDLEN;
 631
 632        spi_reset(priv->regs);
 633
 634        return 0;
 635}
 636
 637static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
 638                            const void *dout, void *din, unsigned long flags)
 639{
 640        struct udevice *bus = dev->parent;
 641        struct omap3_spi_priv *priv = dev_get_priv(bus);
 642
 643        return _spi_xfer(priv, bitlen, dout, din, flags);
 644}
 645
 646static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed)
 647{
 648
 649        struct omap3_spi_priv *priv = dev_get_priv(dev);
 650
 651        priv->freq = speed;
 652        _omap3_spi_set_speed(priv);
 653
 654        return 0;
 655}
 656
 657static int omap3_spi_set_mode(struct udevice *dev, uint mode)
 658{
 659        struct omap3_spi_priv *priv = dev_get_priv(dev);
 660
 661        priv->mode = mode;
 662
 663        _omap3_spi_set_mode(priv);
 664
 665        return 0;
 666}
 667
 668static const struct dm_spi_ops omap3_spi_ops = {
 669        .claim_bus      = omap3_spi_claim_bus,
 670        .release_bus    = omap3_spi_release_bus,
 671        .set_wordlen    = omap3_spi_set_wordlen,
 672        .xfer       = omap3_spi_xfer,
 673        .set_speed      = omap3_spi_set_speed,
 674        .set_mode       = omap3_spi_set_mode,
 675        /*
 676         * cs_info is not needed, since we require all chip selects to be
 677         * in the device tree explicitly
 678         */
 679};
 680
 681static struct omap2_mcspi_platform_config omap2_pdata = {
 682        .regs_offset = 0,
 683};
 684
 685static struct omap2_mcspi_platform_config omap4_pdata = {
 686        .regs_offset = OMAP4_MCSPI_REG_OFFSET,
 687};
 688
 689static const struct udevice_id omap3_spi_ids[] = {
 690        { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
 691        { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
 692        { }
 693};
 694
 695U_BOOT_DRIVER(omap3_spi) = {
 696        .name   = "omap3_spi",
 697        .id     = UCLASS_SPI,
 698        .of_match = omap3_spi_ids,
 699        .probe = omap3_spi_probe,
 700        .ops    = &omap3_spi_ops,
 701        .priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
 702};
 703#endif
 704