uboot/drivers/spi/mxc_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2008, Guennadi Liakhovetski <lg@denx.de>
   4 */
   5
   6#include <common.h>
   7#include <clk.h>
   8#include <dm.h>
   9#include <log.h>
  10#include <malloc.h>
  11#include <spi.h>
  12#include <asm/global_data.h>
  13#include <dm/device_compat.h>
  14#include <linux/bitops.h>
  15#include <linux/delay.h>
  16#include <linux/errno.h>
  17#include <asm/io.h>
  18#include <asm/gpio.h>
  19#include <asm/arch/imx-regs.h>
  20#include <asm/arch/clock.h>
  21#include <asm/mach-imx/spi.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25/* MX35 and older is CSPI */
  26#if defined(CONFIG_MX31)
  27#define MXC_CSPI
  28struct cspi_regs {
  29        u32 rxdata;
  30        u32 txdata;
  31        u32 ctrl;
  32        u32 intr;
  33        u32 dma;
  34        u32 stat;
  35        u32 period;
  36        u32 test;
  37};
  38
  39#define MXC_CSPICTRL_EN                 BIT(0)
  40#define MXC_CSPICTRL_MODE               BIT(1)
  41#define MXC_CSPICTRL_XCH                BIT(2)
  42#define MXC_CSPICTRL_SMC                BIT(3)
  43#define MXC_CSPICTRL_POL                BIT(4)
  44#define MXC_CSPICTRL_PHA                BIT(5)
  45#define MXC_CSPICTRL_SSCTL              BIT(6)
  46#define MXC_CSPICTRL_SSPOL              BIT(7)
  47#define MXC_CSPICTRL_DATARATE(x)        (((x) & 0x7) << 16)
  48#define MXC_CSPICTRL_RXOVF              BIT(6)
  49#define MXC_CSPIPERIOD_32KHZ            BIT(15)
  50#define MAX_SPI_BYTES                   4
  51#define MXC_CSPICTRL_CHIPSELECT(x)      (((x) & 0x3) << 24)
  52#define MXC_CSPICTRL_BITCOUNT(x)        (((x) & 0x1f) << 8)
  53#define MXC_CSPICTRL_TC                 BIT(8)
  54#define MXC_CSPICTRL_MAXBITS            0x1f
  55
  56#else   /* MX51 and newer is ECSPI */
  57#define MXC_ECSPI
  58struct cspi_regs {
  59        u32 rxdata;
  60        u32 txdata;
  61        u32 ctrl;
  62        u32 cfg;
  63        u32 intr;
  64        u32 dma;
  65        u32 stat;
  66        u32 period;
  67};
  68
  69#define MXC_CSPICTRL_EN                 BIT(0)
  70#define MXC_CSPICTRL_MODE               BIT(1)
  71#define MXC_CSPICTRL_XCH                BIT(2)
  72#define MXC_CSPICTRL_MODE_MASK          (0xf << 4)
  73#define MXC_CSPICTRL_CHIPSELECT(x)      (((x) & 0x3) << 12)
  74#define MXC_CSPICTRL_BITCOUNT(x)        (((x) & 0xfff) << 20)
  75#define MXC_CSPICTRL_PREDIV(x)          (((x) & 0xF) << 12)
  76#define MXC_CSPICTRL_POSTDIV(x)         (((x) & 0xF) << 8)
  77#define MXC_CSPICTRL_SELCHAN(x)         (((x) & 0x3) << 18)
  78#define MXC_CSPICTRL_MAXBITS            0xfff
  79#define MXC_CSPICTRL_TC                 BIT(7)
  80#define MXC_CSPICTRL_RXOVF              BIT(6)
  81#define MXC_CSPIPERIOD_32KHZ            BIT(15)
  82#define MAX_SPI_BYTES                   32
  83
  84/* Bit position inside CTRL register to be associated with SS */
  85#define MXC_CSPICTRL_CHAN       18
  86
  87/* Bit position inside CON register to be associated with SS */
  88#define MXC_CSPICON_PHA         0  /* SCLK phase control */
  89#define MXC_CSPICON_POL         4  /* SCLK polarity */
  90#define MXC_CSPICON_SSPOL       12 /* SS polarity */
  91#define MXC_CSPICON_CTL         20 /* inactive state of SCLK */
  92#endif
  93
  94#ifdef CONFIG_MX27
  95/* i.MX27 has a completely wrong register layout and register definitions in the
  96 * datasheet, the correct one is in the Freescale's Linux driver */
  97
  98#error "i.MX27 CSPI not supported due to drastic differences in register definitions" \
  99"See linux mxc_spi driver from Freescale for details."
 100#endif
 101
 102__weak int board_spi_cs_gpio(unsigned bus, unsigned cs)
 103{
 104        return -1;
 105}
 106
 107#define OUT     MXC_GPIO_DIRECTION_OUT
 108
 109#define reg_read readl
 110#define reg_write(a, v) writel(v, a)
 111
 112#if !defined(CONFIG_SYS_SPI_MXC_WAIT)
 113#define CONFIG_SYS_SPI_MXC_WAIT         (CONFIG_SYS_HZ/100)     /* 10 ms */
 114#endif
 115
 116#define MAX_CS_COUNT    4
 117
 118struct mxc_spi_slave {
 119        struct spi_slave slave;
 120        unsigned long   base;
 121        u32             ctrl_reg;
 122#if defined(MXC_ECSPI)
 123        u32             cfg_reg;
 124#endif
 125        int             gpio;
 126        int             ss_pol;
 127        unsigned int    max_hz;
 128        unsigned int    mode;
 129        struct gpio_desc ss;
 130        struct gpio_desc cs_gpios[MAX_CS_COUNT];
 131        struct udevice *dev;
 132};
 133
 134static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave)
 135{
 136        return container_of(slave, struct mxc_spi_slave, slave);
 137}
 138
 139static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs)
 140{
 141#if CONFIG_IS_ENABLED(DM_SPI)
 142        struct udevice *dev = mxcs->dev;
 143        struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
 144
 145        u32 cs = slave_plat->cs;
 146
 147        if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs]))
 148                return;
 149
 150        dm_gpio_set_value(&mxcs->cs_gpios[cs], 1);
 151#else
 152        if (mxcs->gpio > 0)
 153                gpio_set_value(mxcs->gpio, mxcs->ss_pol);
 154#endif
 155}
 156
 157static void mxc_spi_cs_deactivate(struct mxc_spi_slave *mxcs)
 158{
 159#if CONFIG_IS_ENABLED(DM_SPI)
 160        struct udevice *dev = mxcs->dev;
 161        struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
 162
 163        u32 cs = slave_plat->cs;
 164
 165        if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs]))
 166                return;
 167
 168        dm_gpio_set_value(&mxcs->cs_gpios[cs], 0);
 169#else
 170        if (mxcs->gpio > 0)
 171                gpio_set_value(mxcs->gpio, !(mxcs->ss_pol));
 172#endif
 173}
 174
 175u32 get_cspi_div(u32 div)
 176{
 177        int i;
 178
 179        for (i = 0; i < 8; i++) {
 180                if (div <= (4 << i))
 181                        return i;
 182        }
 183        return i;
 184}
 185
 186#ifdef MXC_CSPI
 187static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs)
 188{
 189        unsigned int ctrl_reg;
 190        u32 clk_src;
 191        u32 div;
 192        unsigned int max_hz = mxcs->max_hz;
 193        unsigned int mode = mxcs->mode;
 194
 195        clk_src = mxc_get_clock(MXC_CSPI_CLK);
 196
 197        div = DIV_ROUND_UP(clk_src, max_hz);
 198        div = get_cspi_div(div);
 199
 200        debug("clk %d Hz, div %d, real clk %d Hz\n",
 201                max_hz, div, clk_src / (4 << div));
 202
 203        ctrl_reg = MXC_CSPICTRL_CHIPSELECT(cs) |
 204                MXC_CSPICTRL_BITCOUNT(MXC_CSPICTRL_MAXBITS) |
 205                MXC_CSPICTRL_DATARATE(div) |
 206                MXC_CSPICTRL_EN |
 207                MXC_CSPICTRL_MODE;
 208
 209        if (mode & SPI_CPHA)
 210                ctrl_reg |= MXC_CSPICTRL_PHA;
 211        if (mode & SPI_CPOL)
 212                ctrl_reg |= MXC_CSPICTRL_POL;
 213        if (mode & SPI_CS_HIGH)
 214                ctrl_reg |= MXC_CSPICTRL_SSPOL;
 215        mxcs->ctrl_reg = ctrl_reg;
 216
 217        return 0;
 218}
 219#endif
 220
 221#ifdef MXC_ECSPI
 222static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs)
 223{
 224        u32 clk_src = mxc_get_clock(MXC_CSPI_CLK);
 225        s32 reg_ctrl, reg_config;
 226        u32 ss_pol = 0, sclkpol = 0, sclkpha = 0, sclkctl = 0;
 227        u32 pre_div = 0, post_div = 0;
 228        struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
 229        unsigned int max_hz = mxcs->max_hz;
 230        unsigned int mode = mxcs->mode;
 231
 232        /*
 233         * Reset SPI and set all CSs to master mode, if toggling
 234         * between slave and master mode we might see a glitch
 235         * on the clock line
 236         */
 237        reg_ctrl = MXC_CSPICTRL_MODE_MASK;
 238        reg_write(&regs->ctrl, reg_ctrl);
 239        reg_ctrl |=  MXC_CSPICTRL_EN;
 240        reg_write(&regs->ctrl, reg_ctrl);
 241
 242        if (clk_src > max_hz) {
 243                pre_div = (clk_src - 1) / max_hz;
 244                /* fls(1) = 1, fls(0x80000000) = 32, fls(16) = 5 */
 245                post_div = fls(pre_div);
 246                if (post_div > 4) {
 247                        post_div -= 4;
 248                        if (post_div >= 16) {
 249                                printf("Error: no divider for the freq: %d\n",
 250                                        max_hz);
 251                                return -1;
 252                        }
 253                        pre_div >>= post_div;
 254                } else {
 255                        post_div = 0;
 256                }
 257        }
 258
 259        debug("pre_div = %d, post_div=%d\n", pre_div, post_div);
 260        reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_SELCHAN(3)) |
 261                MXC_CSPICTRL_SELCHAN(cs);
 262        reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_PREDIV(0x0F)) |
 263                MXC_CSPICTRL_PREDIV(pre_div);
 264        reg_ctrl = (reg_ctrl & ~MXC_CSPICTRL_POSTDIV(0x0F)) |
 265                MXC_CSPICTRL_POSTDIV(post_div);
 266
 267        if (mode & SPI_CS_HIGH)
 268                ss_pol = 1;
 269
 270        if (mode & SPI_CPOL) {
 271                sclkpol = 1;
 272                sclkctl = 1;
 273        }
 274
 275        if (mode & SPI_CPHA)
 276                sclkpha = 1;
 277
 278        reg_config = reg_read(&regs->cfg);
 279
 280        /*
 281         * Configuration register setup
 282         * The MX51 supports different setup for each SS
 283         */
 284        reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_SSPOL))) |
 285                (ss_pol << (cs + MXC_CSPICON_SSPOL));
 286        reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_POL))) |
 287                (sclkpol << (cs + MXC_CSPICON_POL));
 288        reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_CTL))) |
 289                (sclkctl << (cs + MXC_CSPICON_CTL));
 290        reg_config = (reg_config & ~(1 << (cs + MXC_CSPICON_PHA))) |
 291                (sclkpha << (cs + MXC_CSPICON_PHA));
 292
 293        debug("reg_ctrl = 0x%x\n", reg_ctrl);
 294        reg_write(&regs->ctrl, reg_ctrl);
 295        debug("reg_config = 0x%x\n", reg_config);
 296        reg_write(&regs->cfg, reg_config);
 297
 298        /* save config register and control register */
 299        mxcs->ctrl_reg = reg_ctrl;
 300        mxcs->cfg_reg = reg_config;
 301
 302        /* clear interrupt reg */
 303        reg_write(&regs->intr, 0);
 304        reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);
 305
 306        return 0;
 307}
 308#endif
 309
 310int spi_xchg_single(struct mxc_spi_slave *mxcs, unsigned int bitlen,
 311        const u8 *dout, u8 *din, unsigned long flags)
 312{
 313        int nbytes = DIV_ROUND_UP(bitlen, 8);
 314        u32 data, cnt, i;
 315        struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
 316        u32 ts;
 317        int status;
 318
 319        debug("%s: bitlen %d dout 0x%lx din 0x%lx\n",
 320                __func__, bitlen, (ulong)dout, (ulong)din);
 321
 322        mxcs->ctrl_reg = (mxcs->ctrl_reg &
 323                ~MXC_CSPICTRL_BITCOUNT(MXC_CSPICTRL_MAXBITS)) |
 324                MXC_CSPICTRL_BITCOUNT(bitlen - 1);
 325
 326        reg_write(&regs->ctrl, mxcs->ctrl_reg | MXC_CSPICTRL_EN);
 327#ifdef MXC_ECSPI
 328        reg_write(&regs->cfg, mxcs->cfg_reg);
 329#endif
 330
 331        /* Clear interrupt register */
 332        reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);
 333
 334        /*
 335         * The SPI controller works only with words,
 336         * check if less than a word is sent.
 337         * Access to the FIFO is only 32 bit
 338         */
 339        if (bitlen % 32) {
 340                data = 0;
 341                cnt = (bitlen % 32) / 8;
 342                if (dout) {
 343                        for (i = 0; i < cnt; i++) {
 344                                data = (data << 8) | (*dout++ & 0xFF);
 345                        }
 346                }
 347                debug("Sending SPI 0x%x\n", data);
 348
 349                reg_write(&regs->txdata, data);
 350                nbytes -= cnt;
 351        }
 352
 353        data = 0;
 354
 355        while (nbytes > 0) {
 356                data = 0;
 357                if (dout) {
 358                        /* Buffer is not 32-bit aligned */
 359                        if ((unsigned long)dout & 0x03) {
 360                                data = 0;
 361                                for (i = 0; i < 4; i++)
 362                                        data = (data << 8) | (*dout++ & 0xFF);
 363                        } else {
 364                                data = *(u32 *)dout;
 365                                data = cpu_to_be32(data);
 366                                dout += 4;
 367                        }
 368                }
 369                debug("Sending SPI 0x%x\n", data);
 370                reg_write(&regs->txdata, data);
 371                nbytes -= 4;
 372        }
 373
 374        /* FIFO is written, now starts the transfer setting the XCH bit */
 375        reg_write(&regs->ctrl, mxcs->ctrl_reg |
 376                MXC_CSPICTRL_EN | MXC_CSPICTRL_XCH);
 377
 378        ts = get_timer(0);
 379        status = reg_read(&regs->stat);
 380        /* Wait until the TC (Transfer completed) bit is set */
 381        while ((status & MXC_CSPICTRL_TC) == 0) {
 382                if (get_timer(ts) > CONFIG_SYS_SPI_MXC_WAIT) {
 383                        printf("spi_xchg_single: Timeout!\n");
 384                        return -1;
 385                }
 386                status = reg_read(&regs->stat);
 387        }
 388
 389        /* Transfer completed, clear any pending request */
 390        reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);
 391
 392        nbytes = DIV_ROUND_UP(bitlen, 8);
 393
 394        if (bitlen % 32) {
 395                data = reg_read(&regs->rxdata);
 396                cnt = (bitlen % 32) / 8;
 397                data = cpu_to_be32(data) >> ((sizeof(data) - cnt) * 8);
 398                debug("SPI Rx unaligned: 0x%x\n", data);
 399                if (din) {
 400                        memcpy(din, &data, cnt);
 401                        din += cnt;
 402                }
 403                nbytes -= cnt;
 404        }
 405
 406        while (nbytes > 0) {
 407                u32 tmp;
 408                tmp = reg_read(&regs->rxdata);
 409                data = cpu_to_be32(tmp);
 410                debug("SPI Rx: 0x%x 0x%x\n", tmp, data);
 411                cnt = min_t(u32, nbytes, sizeof(data));
 412                if (din) {
 413                        memcpy(din, &data, cnt);
 414                        din += cnt;
 415                }
 416                nbytes -= cnt;
 417        }
 418
 419        return 0;
 420
 421}
 422
 423static int mxc_spi_xfer_internal(struct mxc_spi_slave *mxcs,
 424                                 unsigned int bitlen, const void *dout,
 425                                 void *din, unsigned long flags)
 426{
 427        int n_bytes = DIV_ROUND_UP(bitlen, 8);
 428        int n_bits;
 429        int ret;
 430        u32 blk_size;
 431        u8 *p_outbuf = (u8 *)dout;
 432        u8 *p_inbuf = (u8 *)din;
 433
 434        if (!mxcs)
 435                return -EINVAL;
 436
 437        if (flags & SPI_XFER_BEGIN)
 438                mxc_spi_cs_activate(mxcs);
 439
 440        while (n_bytes > 0) {
 441                if (n_bytes < MAX_SPI_BYTES)
 442                        blk_size = n_bytes;
 443                else
 444                        blk_size = MAX_SPI_BYTES;
 445
 446                n_bits = blk_size * 8;
 447
 448                ret = spi_xchg_single(mxcs, n_bits, p_outbuf, p_inbuf, 0);
 449
 450                if (ret)
 451                        return ret;
 452                if (dout)
 453                        p_outbuf += blk_size;
 454                if (din)
 455                        p_inbuf += blk_size;
 456                n_bytes -= blk_size;
 457        }
 458
 459        if (flags & SPI_XFER_END) {
 460                mxc_spi_cs_deactivate(mxcs);
 461        }
 462
 463        return 0;
 464}
 465
 466static int mxc_spi_claim_bus_internal(struct mxc_spi_slave *mxcs, int cs)
 467{
 468        struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
 469        int ret;
 470
 471        reg_write(&regs->rxdata, 1);
 472        udelay(1);
 473        ret = spi_cfg_mxc(mxcs, cs);
 474        if (ret) {
 475                printf("mxc_spi: cannot setup SPI controller\n");
 476                return ret;
 477        }
 478        reg_write(&regs->period, MXC_CSPIPERIOD_32KHZ);
 479        reg_write(&regs->intr, 0);
 480
 481        return 0;
 482}
 483
 484#if !CONFIG_IS_ENABLED(DM_SPI)
 485int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 486                void *din, unsigned long flags)
 487{
 488        struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
 489
 490        return mxc_spi_xfer_internal(mxcs, bitlen, dout, din, flags);
 491}
 492
 493/*
 494 * Some SPI devices require active chip-select over multiple
 495 * transactions, we achieve this using a GPIO. Still, the SPI
 496 * controller has to be configured to use one of its own chipselects.
 497 * To use this feature you have to implement board_spi_cs_gpio() to assign
 498 * a gpio value for each cs (-1 if cs doesn't need to use gpio).
 499 * You must use some unused on this SPI controller cs between 0 and 3.
 500 */
 501static int setup_cs_gpio(struct mxc_spi_slave *mxcs,
 502                         unsigned int bus, unsigned int cs)
 503{
 504        int ret;
 505
 506        mxcs->gpio = board_spi_cs_gpio(bus, cs);
 507        if (mxcs->gpio == -1)
 508                return 0;
 509
 510        gpio_request(mxcs->gpio, "spi-cs");
 511        ret = gpio_direction_output(mxcs->gpio, !(mxcs->ss_pol));
 512        if (ret) {
 513                printf("mxc_spi: cannot setup gpio %d\n", mxcs->gpio);
 514                return -EINVAL;
 515        }
 516
 517        return 0;
 518}
 519
 520static unsigned long spi_bases[] = {
 521        MXC_SPI_BASE_ADDRESSES
 522};
 523
 524struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 525                        unsigned int max_hz, unsigned int mode)
 526{
 527        struct mxc_spi_slave *mxcs;
 528        int ret;
 529
 530        if (bus >= ARRAY_SIZE(spi_bases))
 531                return NULL;
 532
 533        if (max_hz == 0) {
 534                printf("Error: desired clock is 0\n");
 535                return NULL;
 536        }
 537
 538        mxcs = spi_alloc_slave(struct mxc_spi_slave, bus, cs);
 539        if (!mxcs) {
 540                puts("mxc_spi: SPI Slave not allocated !\n");
 541                return NULL;
 542        }
 543
 544        mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
 545
 546        ret = setup_cs_gpio(mxcs, bus, cs);
 547        if (ret < 0) {
 548                free(mxcs);
 549                return NULL;
 550        }
 551
 552        mxcs->base = spi_bases[bus];
 553        mxcs->max_hz = max_hz;
 554        mxcs->mode = mode;
 555
 556        return &mxcs->slave;
 557}
 558
 559void spi_free_slave(struct spi_slave *slave)
 560{
 561        struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
 562
 563        free(mxcs);
 564}
 565
 566int spi_claim_bus(struct spi_slave *slave)
 567{
 568        struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
 569
 570        return mxc_spi_claim_bus_internal(mxcs, slave->cs);
 571}
 572
 573void spi_release_bus(struct spi_slave *slave)
 574{
 575        /* TODO: Shut the controller down */
 576}
 577#else
 578
 579static int mxc_spi_probe(struct udevice *bus)
 580{
 581        struct mxc_spi_slave *mxcs = dev_get_plat(bus);
 582        int ret;
 583        int i;
 584
 585        ret = gpio_request_list_by_name(bus, "cs-gpios", mxcs->cs_gpios,
 586                                        ARRAY_SIZE(mxcs->cs_gpios), 0);
 587        if (ret < 0) {
 588                pr_err("Can't get %s gpios! Error: %d", bus->name, ret);
 589                return ret;
 590        }
 591
 592        for (i = 0; i < ARRAY_SIZE(mxcs->cs_gpios); i++) {
 593                if (!dm_gpio_is_valid(&mxcs->cs_gpios[i]))
 594                        continue;
 595
 596                ret = dm_gpio_set_dir_flags(&mxcs->cs_gpios[i],
 597                                            GPIOD_IS_OUT | GPIOD_ACTIVE_LOW);
 598                if (ret) {
 599                        dev_err(bus, "Setting cs %d error\n", i);
 600                        return ret;
 601                }
 602        }
 603
 604        mxcs->base = dev_read_addr(bus);
 605        if (mxcs->base == FDT_ADDR_T_NONE)
 606                return -ENODEV;
 607
 608#if CONFIG_IS_ENABLED(CLK)
 609        struct clk clk;
 610        ret = clk_get_by_index(bus, 0, &clk);
 611        if (ret)
 612                return ret;
 613
 614        clk_enable(&clk);
 615
 616        mxcs->max_hz = clk_get_rate(&clk);
 617#else
 618        int node = dev_of_offset(bus);
 619        const void *blob = gd->fdt_blob;
 620        mxcs->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
 621                                      20000000);
 622#endif
 623
 624        return 0;
 625}
 626
 627static int mxc_spi_xfer(struct udevice *dev, unsigned int bitlen,
 628                const void *dout, void *din, unsigned long flags)
 629{
 630        struct mxc_spi_slave *mxcs = dev_get_plat(dev->parent);
 631
 632
 633        return mxc_spi_xfer_internal(mxcs, bitlen, dout, din, flags);
 634}
 635
 636static int mxc_spi_claim_bus(struct udevice *dev)
 637{
 638        struct mxc_spi_slave *mxcs = dev_get_plat(dev->parent);
 639        struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
 640
 641        mxcs->dev = dev;
 642
 643        return mxc_spi_claim_bus_internal(mxcs, slave_plat->cs);
 644}
 645
 646static int mxc_spi_release_bus(struct udevice *dev)
 647{
 648        return 0;
 649}
 650
 651static int mxc_spi_set_speed(struct udevice *bus, uint speed)
 652{
 653        struct mxc_spi_slave *mxcs = dev_get_plat(bus);
 654
 655        mxcs->max_hz = speed;
 656
 657        return 0;
 658}
 659
 660static int mxc_spi_set_mode(struct udevice *bus, uint mode)
 661{
 662        struct mxc_spi_slave *mxcs = dev_get_plat(bus);
 663
 664        mxcs->mode = mode;
 665        mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
 666
 667        return 0;
 668}
 669
 670static const struct dm_spi_ops mxc_spi_ops = {
 671        .claim_bus      = mxc_spi_claim_bus,
 672        .release_bus    = mxc_spi_release_bus,
 673        .xfer           = mxc_spi_xfer,
 674        .set_speed      = mxc_spi_set_speed,
 675        .set_mode       = mxc_spi_set_mode,
 676};
 677
 678static const struct udevice_id mxc_spi_ids[] = {
 679        { .compatible = "fsl,imx51-ecspi" },
 680        { }
 681};
 682
 683U_BOOT_DRIVER(mxc_spi) = {
 684        .name   = "mxc_spi",
 685        .id     = UCLASS_SPI,
 686        .of_match = mxc_spi_ids,
 687        .ops    = &mxc_spi_ops,
 688        .plat_auto      = sizeof(struct mxc_spi_slave),
 689        .probe  = mxc_spi_probe,
 690};
 691#endif
 692