diff options
author | Simon Glass <sjg@chromium.org> | 2014-10-13 23:41:53 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-10-22 10:36:46 -0600 |
commit | c60e1f254747ac650f8290e5debcf8ad1567584b (patch) | |
tree | 08f5d2749d213bb008f84caaf9350479aa5ef234 | |
parent | d7af6a485126a0d08a0a9a56721e42a3e78b5b53 (diff) |
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>
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/spi-emul-uclass.c | 15 | ||||
-rw-r--r-- | include/dm/uclass-id.h | 1 | ||||
-rw-r--r-- | include/spi.h | 45 |
4 files changed, 62 insertions, 0 deletions
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index d1f1dd06660..a1de0288de2 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -8,6 +8,7 @@ # There are many options which enable SPI, so make this library available ifdef CONFIG_DM_SPI obj-y += spi-uclass.o +obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o else obj-y += spi.o endif diff --git a/drivers/spi/spi-emul-uclass.c b/drivers/spi/spi-emul-uclass.c new file mode 100644 index 00000000000..b436a0e99f9 --- /dev/null +++ b/drivers/spi/spi-emul-uclass.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <spi.h> +#include <spi_flash.h> + +UCLASS_DRIVER(spi_emul) = { + .id = UCLASS_SPI_EMUL, + .name = "spi_emul", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 0afdc753869..6e5638208b4 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -18,6 +18,7 @@ enum uclass_id { UCLASS_TEST, UCLASS_TEST_FDT, UCLASS_TEST_BUS, + UCLASS_SPI_EMUL, /* sandbox SPI device emulator */ /* U-Boot uclasses start here */ UCLASS_GPIO, /* Bank of general-purpose I/O pins */ diff --git a/include/spi.h b/include/spi.h index 89949b11b70..aa0a48ea627 100644 --- a/include/spi.h +++ b/include/spi.h @@ -456,6 +456,35 @@ struct dm_spi_ops { int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info); }; +struct dm_spi_emul_ops { + /** + * SPI transfer + * + * This writes "bitlen" bits out the SPI MOSI port and simultaneously + * clocks "bitlen" bits in the SPI MISO port. That's just the way SPI + * works. Here the device is a slave. + * + * The source of the outgoing bits is the "dout" parameter and the + * destination of the input bits is the "din" parameter. Note that + * "dout" and "din" can point to the same memory location, in which + * case the input data overwrites the output data (since both are + * buffered by temporary variables, this is OK). + * + * spi_xfer() interface: + * @slave: The SPI slave which will be sending/receiving the data. + * @bitlen: How many bits to write and read. + * @dout: Pointer to a string of bits sent to the device. The + * bits are held in a byte array and are sent MSB first. + * @din: Pointer to a string of bits that will be sent back to + * the master. + * @flags: A bitwise combination of SPI_XFER_* flags. + * + * Returns: 0 on success, not -1 on failure + */ + int (*xfer)(struct udevice *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags); +}; + /** * spi_find_bus_and_cs() - Find bus and slave devices by number * @@ -545,12 +574,28 @@ int spi_ofdata_to_platdata(const void *blob, int node, struct spi_slave *spi); int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info); struct sandbox_state; + +/** + * sandbox_spi_get_emul() - get an emulator for a SPI slave + * + * This provides a way to attach an emulated SPI device to a particular SPI + * slave, so that xfer() operations on the slave will be handled by the + * emulator. If a emulator already exists on that chip select it is returned. + * Otherwise one is created. + * + * @state: Sandbox state + * @bus: SPI bus requesting the emulator + * @slave: SPI slave device requesting the emulator + * @emuip: Returns pointer to emulator + * @return 0 if OK, -ve on error + */ int sandbox_spi_get_emul(struct sandbox_state *state, struct udevice *bus, struct udevice *slave, struct udevice **emulp); /* Access the serial operations for a device */ #define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops) +#define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops) #endif /* CONFIG_DM_SPI */ #endif /* _SPI_H_ */ |