[U-Boot] [PATCH v10 15/27] spi: Add spi_write_then_read

Jagan Teki
2017-12-28T06:12:21Z

Add support for SPI synchronous write followed by read,
this is common interface call from spi-nor to spi drivers.

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
drivers/spi/spi-uclass.c | 24 ++++++++++++++++++++++++
include/spi.h | 20 ++++++++++++++++++++
2 files changed, 44 insertions(+)

diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index e06a603..b86c15b 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -107,6 +107,30 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
return dm_spi_xfer(slave->dev, bitlen, dout, din, flags);
}

+int spi_write_then_read(struct spi_slave *slave, const u8 *opcode,
+ size_t n_opcode, const u8 *txbuf, u8 *rxbuf,
+ size_t n_buf)
+{
+ unsigned long flags = SPI_XFER_BEGIN;
+ int ret;
+
+ if (n_buf == 0)
+ flags |= SPI_XFER_END;
+
+ ret = spi_xfer(slave, n_opcode * 8, opcode, NULL, flags);
+ if (ret) {
+ debug("spi: failed to send command (%zu bytes): %d\n",
+ n_opcode, ret);
+ } else if (n_buf != 0) {
+ ret = spi_xfer(slave, n_buf * 8, txbuf, rxbuf, SPI_XFER_END);
+ if (ret)
+ debug("spi: failed to transfer %zu bytes of data: %d\n",
+ n_buf, ret);
+ }
+
+ return ret;
+}
+
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
static int spi_child_post_bind(struct udevice *dev)
{
diff --git a/include/spi.h b/include/spi.h
index 8c4b882..c67ca23 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -252,6 +252,26 @@ int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
void *din, unsigned long flags);

+/**
+ * spi_write_then_read - SPI synchronous write followed by read
+ *
+ * This performs a half duplex transaction in which the first transaction
+ * is to send the opcode and if the length of buf is non-zero then it start
+ * the second transaction as tx or rx based on the need from respective slave.
+ *
+ * @slave: slave device with which opcode/data will be exchanged
+ * @opcode: opcode used for specific transfer
+ * @n_opcode: size of opcode, in bytes
+ * @txbuf: buffer into which data to be written
+ * @rxbuf: buffer into which data will be read
+ * @n_buf: size of buf (whether it's [tx|rx]buf), in bytes
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int spi_write_then_read(struct spi_slave *slave, const u8 *opcode,
+ size_t n_opcode, const u8 *txbuf, u8 *rxbuf,
+ size_t n_buf);
+
/* Copy memory mapped data */
void spi_flash_copy_mmap(void *data, void *offset, size_t len);

--
2.7.4