uboot/drivers/spi/spi-uclass.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2014 Google, Inc
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <errno.h>
   9#include <malloc.h>
  10#include <spi.h>
  11#include <dm/device-internal.h>
  12#include <dm/uclass-internal.h>
  13#include <dm/lists.h>
  14#include <dm/util.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
  19{
  20        struct dm_spi_ops *ops;
  21        int ret;
  22
  23        ops = spi_get_ops(bus);
  24        if (ops->set_speed)
  25                ret = ops->set_speed(bus, speed);
  26        else
  27                ret = -EINVAL;
  28        if (ret) {
  29                printf("Cannot set speed (err=%d)\n", ret);
  30                return ret;
  31        }
  32
  33        if (ops->set_mode)
  34                ret = ops->set_mode(bus, mode);
  35        else
  36                ret = -EINVAL;
  37        if (ret) {
  38                printf("Cannot set mode (err=%d)\n", ret);
  39                return ret;
  40        }
  41
  42        return 0;
  43}
  44
  45int dm_spi_claim_bus(struct udevice *dev)
  46{
  47        struct udevice *bus = dev->parent;
  48        struct dm_spi_ops *ops = spi_get_ops(bus);
  49        struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
  50        struct spi_slave *slave = dev_get_parent_priv(dev);
  51        int speed;
  52
  53        speed = slave->max_hz;
  54        if (spi->max_hz) {
  55                if (speed)
  56                        speed = min(speed, (int)spi->max_hz);
  57                else
  58                        speed = spi->max_hz;
  59        }
  60        if (!speed)
  61                speed = 100000;
  62        if (speed != slave->speed) {
  63                int ret = spi_set_speed_mode(bus, speed, slave->mode);
  64
  65                if (ret)
  66                        return log_ret(ret);
  67                slave->speed = speed;
  68        }
  69
  70        return log_ret(ops->claim_bus ? ops->claim_bus(dev) : 0);
  71}
  72
  73void dm_spi_release_bus(struct udevice *dev)
  74{
  75        struct udevice *bus = dev->parent;
  76        struct dm_spi_ops *ops = spi_get_ops(bus);
  77
  78        if (ops->release_bus)
  79                ops->release_bus(dev);
  80}
  81
  82int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
  83                const void *dout, void *din, unsigned long flags)
  84{
  85        struct udevice *bus = dev->parent;
  86
  87        if (bus->uclass->uc_drv->id != UCLASS_SPI)
  88                return -EOPNOTSUPP;
  89
  90        return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
  91}
  92
  93int spi_claim_bus(struct spi_slave *slave)
  94{
  95        return log_ret(dm_spi_claim_bus(slave->dev));
  96}
  97
  98void spi_release_bus(struct spi_slave *slave)
  99{
 100        dm_spi_release_bus(slave->dev);
 101}
 102
 103int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 104             const void *dout, void *din, unsigned long flags)
 105{
 106        return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
 107}
 108
 109#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 110static int spi_child_post_bind(struct udevice *dev)
 111{
 112        struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 113
 114        if (!dev_of_valid(dev))
 115                return 0;
 116
 117        return spi_slave_ofdata_to_platdata(dev, plat);
 118}
 119#endif
 120
 121static int spi_post_probe(struct udevice *bus)
 122{
 123#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 124        struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
 125
 126        spi->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0);
 127#endif
 128#if defined(CONFIG_NEEDS_MANUAL_RELOC)
 129        struct dm_spi_ops *ops = spi_get_ops(bus);
 130
 131        if (ops->claim_bus)
 132                ops->claim_bus += gd->reloc_off;
 133        if (ops->release_bus)
 134                ops->release_bus += gd->reloc_off;
 135        if (ops->set_wordlen)
 136                ops->set_wordlen += gd->reloc_off;
 137        if (ops->xfer)
 138                ops->xfer += gd->reloc_off;
 139        if (ops->set_speed)
 140                ops->set_speed += gd->reloc_off;
 141        if (ops->set_mode)
 142                ops->set_mode += gd->reloc_off;
 143        if (ops->cs_info)
 144                ops->cs_info += gd->reloc_off;
 145#endif
 146
 147        return 0;
 148}
 149
 150static int spi_child_pre_probe(struct udevice *dev)
 151{
 152        struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 153        struct spi_slave *slave = dev_get_parent_priv(dev);
 154
 155        /*
 156         * This is needed because we pass struct spi_slave around the place
 157         * instead slave->dev (a struct udevice). So we have to have some
 158         * way to access the slave udevice given struct spi_slave. Once we
 159         * change the SPI API to use udevice instead of spi_slave, we can
 160         * drop this.
 161         */
 162        slave->dev = dev;
 163
 164        slave->max_hz = plat->max_hz;
 165        slave->mode = plat->mode;
 166        slave->wordlen = SPI_DEFAULT_WORDLEN;
 167
 168        return 0;
 169}
 170
 171int spi_chip_select(struct udevice *dev)
 172{
 173        struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 174
 175        return plat ? plat->cs : -ENOENT;
 176}
 177
 178int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
 179{
 180        struct udevice *dev;
 181
 182        for (device_find_first_child(bus, &dev); dev;
 183             device_find_next_child(&dev)) {
 184                struct dm_spi_slave_platdata *plat;
 185
 186                plat = dev_get_parent_platdata(dev);
 187                debug("%s: plat=%p, cs=%d\n", __func__, plat, plat->cs);
 188                if (plat->cs == cs) {
 189                        *devp = dev;
 190                        return 0;
 191                }
 192        }
 193
 194        return -ENODEV;
 195}
 196
 197int spi_cs_is_valid(unsigned int busnum, unsigned int cs)
 198{
 199        struct spi_cs_info info;
 200        struct udevice *bus;
 201        int ret;
 202
 203        ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
 204        if (ret) {
 205                debug("%s: No bus %d\n", __func__, busnum);
 206                return ret;
 207        }
 208
 209        return spi_cs_info(bus, cs, &info);
 210}
 211
 212int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
 213{
 214        struct spi_cs_info local_info;
 215        struct dm_spi_ops *ops;
 216        int ret;
 217
 218        if (!info)
 219                info = &local_info;
 220
 221        /* If there is a device attached, return it */
 222        info->dev = NULL;
 223        ret = spi_find_chip_select(bus, cs, &info->dev);
 224        if (!ret)
 225                return 0;
 226
 227        /*
 228         * Otherwise ask the driver. For the moment we don't have CS info.
 229         * When we do we could provide the driver with a helper function
 230         * to figure out what chip selects are valid, or just handle the
 231         * request.
 232         */
 233        ops = spi_get_ops(bus);
 234        if (ops->cs_info)
 235                return ops->cs_info(bus, cs, info);
 236
 237        /*
 238         * We could assume there is at least one valid chip select, but best
 239         * to be sure and return an error in this case. The driver didn't
 240         * care enough to tell us.
 241         */
 242        return -ENODEV;
 243}
 244
 245int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
 246                        struct udevice **devp)
 247{
 248        struct udevice *bus, *dev;
 249        int ret;
 250
 251        ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
 252        if (ret) {
 253                debug("%s: No bus %d\n", __func__, busnum);
 254                return ret;
 255        }
 256        ret = spi_find_chip_select(bus, cs, &dev);
 257        if (ret) {
 258                debug("%s: No cs %d\n", __func__, cs);
 259                return ret;
 260        }
 261        *busp = bus;
 262        *devp = dev;
 263
 264        return ret;
 265}
 266
 267int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
 268                       const char *drv_name, const char *dev_name,
 269                       struct udevice **busp, struct spi_slave **devp)
 270{
 271        struct udevice *bus, *dev;
 272        struct dm_spi_slave_platdata *plat;
 273        bool created = false;
 274        int ret;
 275
 276#if CONFIG_IS_ENABLED(OF_PLATDATA) || CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
 277        ret = uclass_first_device_err(UCLASS_SPI, &bus);
 278#else
 279        ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
 280#endif
 281        if (ret) {
 282                printf("Invalid bus %d (err=%d)\n", busnum, ret);
 283                return ret;
 284        }
 285        ret = spi_find_chip_select(bus, cs, &dev);
 286
 287        /*
 288         * If there is no such device, create one automatically. This means
 289         * that we don't need a device tree node or platform data for the
 290         * SPI flash chip - we will bind to the correct driver.
 291         */
 292        if (ret == -ENODEV && drv_name) {
 293                debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
 294                      __func__, dev_name, busnum, cs, drv_name);
 295                ret = device_bind_driver(bus, drv_name, dev_name, &dev);
 296                if (ret) {
 297                        debug("%s: Unable to bind driver (ret=%d)\n", __func__,
 298                              ret);
 299                        return ret;
 300                }
 301                plat = dev_get_parent_platdata(dev);
 302                plat->cs = cs;
 303                plat->max_hz = speed;
 304                plat->mode = mode;
 305                created = true;
 306        } else if (ret) {
 307                printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
 308                       ret);
 309                return ret;
 310        }
 311
 312        if (!device_active(dev)) {
 313                struct spi_slave *slave;
 314
 315                ret = device_probe(dev);
 316                if (ret)
 317                        goto err;
 318                slave = dev_get_parent_priv(dev);
 319                slave->dev = dev;
 320        }
 321
 322        plat = dev_get_parent_platdata(dev);
 323        if (!speed) {
 324                speed = plat->max_hz;
 325                mode = plat->mode;
 326        }
 327        ret = spi_set_speed_mode(bus, speed, mode);
 328        if (ret)
 329                goto err;
 330
 331        *busp = bus;
 332        *devp = dev_get_parent_priv(dev);
 333        debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp);
 334
 335        return 0;
 336
 337err:
 338        debug("%s: Error path, created=%d, device '%s'\n", __func__,
 339              created, dev->name);
 340        if (created) {
 341                device_remove(dev, DM_REMOVE_NORMAL);
 342                device_unbind(dev);
 343        }
 344
 345        return ret;
 346}
 347
 348/* Compatibility function - to be removed */
 349struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
 350                                  unsigned int speed, unsigned int mode)
 351{
 352        struct spi_slave *slave;
 353        struct udevice *dev;
 354        int ret;
 355
 356        ret = spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &dev,
 357                                 &slave);
 358        if (ret)
 359                return NULL;
 360
 361        return slave;
 362}
 363
 364void spi_free_slave(struct spi_slave *slave)
 365{
 366        device_remove(slave->dev, DM_REMOVE_NORMAL);
 367        slave->dev = NULL;
 368}
 369
 370int spi_slave_ofdata_to_platdata(struct udevice *dev,
 371                                 struct dm_spi_slave_platdata *plat)
 372{
 373        int mode = 0;
 374        int value;
 375
 376        plat->cs = dev_read_u32_default(dev, "reg", -1);
 377        plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0);
 378        if (dev_read_bool(dev, "spi-cpol"))
 379                mode |= SPI_CPOL;
 380        if (dev_read_bool(dev, "spi-cpha"))
 381                mode |= SPI_CPHA;
 382        if (dev_read_bool(dev, "spi-cs-high"))
 383                mode |= SPI_CS_HIGH;
 384        if (dev_read_bool(dev, "spi-3wire"))
 385                mode |= SPI_3WIRE;
 386        if (dev_read_bool(dev, "spi-half-duplex"))
 387                mode |= SPI_PREAMBLE;
 388
 389        /* Device DUAL/QUAD mode */
 390        value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
 391        switch (value) {
 392        case 1:
 393                break;
 394        case 2:
 395                mode |= SPI_TX_DUAL;
 396                break;
 397        case 4:
 398                mode |= SPI_TX_QUAD;
 399                break;
 400        default:
 401                warn_non_spl("spi-tx-bus-width %d not supported\n", value);
 402                break;
 403        }
 404
 405        value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
 406        switch (value) {
 407        case 1:
 408                break;
 409        case 2:
 410                mode |= SPI_RX_DUAL;
 411                break;
 412        case 4:
 413                mode |= SPI_RX_QUAD;
 414                break;
 415        default:
 416                warn_non_spl("spi-rx-bus-width %d not supported\n", value);
 417                break;
 418        }
 419
 420        plat->mode = mode;
 421
 422        return 0;
 423}
 424
 425UCLASS_DRIVER(spi) = {
 426        .id             = UCLASS_SPI,
 427        .name           = "spi",
 428        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 429#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 430        .post_bind      = dm_scan_fdt_dev,
 431#endif
 432        .post_probe     = spi_post_probe,
 433        .child_pre_probe = spi_child_pre_probe,
 434        .per_device_auto_alloc_size = sizeof(struct dm_spi_bus),
 435        .per_child_auto_alloc_size = sizeof(struct spi_slave),
 436        .per_child_platdata_auto_alloc_size =
 437                        sizeof(struct dm_spi_slave_platdata),
 438#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 439        .child_post_bind = spi_child_post_bind,
 440#endif
 441};
 442
 443UCLASS_DRIVER(spi_generic) = {
 444        .id             = UCLASS_SPI_GENERIC,
 445        .name           = "spi_generic",
 446};
 447
 448U_BOOT_DRIVER(spi_generic_drv) = {
 449        .name           = "spi_generic_drv",
 450        .id             = UCLASS_SPI_GENERIC,
 451};
 452