spi: Add spi_write_then_read
authorJagan Teki <jagan@amarulasolutions.com>
Mon, 22 Jul 2019 11:52:56 +0000 (17:22 +0530)
committerJagan Teki <jagan@amarulasolutions.com>
Mon, 16 Sep 2019 02:39:22 +0000 (08:09 +0530)
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>
Tested-by: Adam Ford <aford173@gmail.com> #da850-evm
drivers/spi/spi-uclass.c
include/spi.h

index 88cb2a126227156d18342796d4022f25c3aefbba..76c4b53c165c764e496a40c101e6e34c65b8a887 100644 (file)
@@ -108,6 +108,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)
 {
index 378594163b874246e606a41edf6e404e81412f81..5eec0c4775e5c9a3122f772841e1952fb803b6ac 100644 (file)
@@ -248,6 +248,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:     The SPI 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);