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