Commit c60e1f254747ac650f8290e5debcf8ad1567584b

Authored by Simon Glass
1 parent d7af6a4851

dm: sandbox: Add a SPI emulation uclass

U-Boot includes a SPI emulation driver already but it is not explicit, and
is hidden in the SPI flash code.

Conceptually with sandbox's SPI implementation we have a layer which
creates SPI bus transitions and a layer which interprets them, currently
only for SPI flash. The latter is actually an emulation, and it should be
possible to add more than one emulation - not just SPI flash.

Add a SPI emulation uclass so that other emulations can be plugged in to
support different types of emulated devices on difference buses/chip
selects.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>

Showing 4 changed files with 62 additions and 0 deletions Side-by-side Diff

drivers/spi/Makefile
... ... @@ -8,6 +8,7 @@
8 8 # There are many options which enable SPI, so make this library available
9 9 ifdef CONFIG_DM_SPI
10 10 obj-y += spi-uclass.o
  11 +obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o
11 12 else
12 13 obj-y += spi.o
13 14 endif
drivers/spi/spi-emul-uclass.c
  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 <spi.h>
  10 +#include <spi_flash.h>
  11 +
  12 +UCLASS_DRIVER(spi_emul) = {
  13 + .id = UCLASS_SPI_EMUL,
  14 + .name = "spi_emul",
  15 +};
include/dm/uclass-id.h
... ... @@ -18,6 +18,7 @@
18 18 UCLASS_TEST,
19 19 UCLASS_TEST_FDT,
20 20 UCLASS_TEST_BUS,
  21 + UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
21 22  
22 23 /* U-Boot uclasses start here */
23 24 UCLASS_GPIO, /* Bank of general-purpose I/O pins */
... ... @@ -456,6 +456,35 @@
456 456 int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info);
457 457 };
458 458  
  459 +struct dm_spi_emul_ops {
  460 + /**
  461 + * SPI transfer
  462 + *
  463 + * This writes "bitlen" bits out the SPI MOSI port and simultaneously
  464 + * clocks "bitlen" bits in the SPI MISO port. That's just the way SPI
  465 + * works. Here the device is a slave.
  466 + *
  467 + * The source of the outgoing bits is the "dout" parameter and the
  468 + * destination of the input bits is the "din" parameter. Note that
  469 + * "dout" and "din" can point to the same memory location, in which
  470 + * case the input data overwrites the output data (since both are
  471 + * buffered by temporary variables, this is OK).
  472 + *
  473 + * spi_xfer() interface:
  474 + * @slave: The SPI slave which will be sending/receiving the data.
  475 + * @bitlen: How many bits to write and read.
  476 + * @dout: Pointer to a string of bits sent to the device. The
  477 + * bits are held in a byte array and are sent MSB first.
  478 + * @din: Pointer to a string of bits that will be sent back to
  479 + * the master.
  480 + * @flags: A bitwise combination of SPI_XFER_* flags.
  481 + *
  482 + * Returns: 0 on success, not -1 on failure
  483 + */
  484 + int (*xfer)(struct udevice *slave, unsigned int bitlen,
  485 + const void *dout, void *din, unsigned long flags);
  486 +};
  487 +
459 488 /**
460 489 * spi_find_bus_and_cs() - Find bus and slave devices by number
461 490 *
462 491  
... ... @@ -545,12 +574,28 @@
545 574 int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info);
546 575  
547 576 struct sandbox_state;
  577 +
  578 +/**
  579 + * sandbox_spi_get_emul() - get an emulator for a SPI slave
  580 + *
  581 + * This provides a way to attach an emulated SPI device to a particular SPI
  582 + * slave, so that xfer() operations on the slave will be handled by the
  583 + * emulator. If a emulator already exists on that chip select it is returned.
  584 + * Otherwise one is created.
  585 + *
  586 + * @state: Sandbox state
  587 + * @bus: SPI bus requesting the emulator
  588 + * @slave: SPI slave device requesting the emulator
  589 + * @emuip: Returns pointer to emulator
  590 + * @return 0 if OK, -ve on error
  591 + */
548 592 int sandbox_spi_get_emul(struct sandbox_state *state,
549 593 struct udevice *bus, struct udevice *slave,
550 594 struct udevice **emulp);
551 595  
552 596 /* Access the serial operations for a device */
553 597 #define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops)
  598 +#define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops)
554 599 #endif /* CONFIG_DM_SPI */
555 600  
556 601 #endif /* _SPI_H_ */