diff mbox

[U-Boot,v4,06/29] dm: sandbox: Add a SPI emulation uclass

Message ID 1413265336-9571-7-git-send-email-sjg@chromium.org
State Awaiting Upstream
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass Oct. 14, 2014, 5:41 a.m. UTC
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>
---

Changes in v4: None
Changes in v3:
- Add a function comment for sandbox_spi_get_emul()

Changes in v2:
- Fix comment on 'slave' parameter to match the parameter name

 drivers/spi/Makefile          |  1 +
 drivers/spi/spi-emul-uclass.c | 15 +++++++++++++++
 include/dm/uclass-id.h        |  1 +
 include/spi.h                 | 45 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 62 insertions(+)
 create mode 100644 drivers/spi/spi-emul-uclass.c

Comments

Simon Glass Oct. 23, 2014, 3:03 a.m. UTC | #1
On 13 October 2014 23:41, Simon Glass <sjg@chromium.org> wrote:
> 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>
> ---
>
> Changes in v4: None
> Changes in v3:
> - Add a function comment for sandbox_spi_get_emul()
>
> Changes in v2:
> - Fix comment on 'slave' parameter to match the parameter name
>
>  drivers/spi/Makefile          |  1 +
>  drivers/spi/spi-emul-uclass.c | 15 +++++++++++++++
>  include/dm/uclass-id.h        |  1 +
>  include/spi.h                 | 45 +++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 62 insertions(+)

Applied to u-boot-dm/master.
diff mbox

Patch

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d1f1dd0..a1de028 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 0000000..b436a0e
--- /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 0afdc75..6e56382 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 89949b1..aa0a48e 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_ */