Merge tag 'u-boot-stm32-20200619' of https://gitlab.denx.de/u-boot/custodians/u-boot-stm
[oweals/u-boot.git] / include / spi.h
index 378594163b874246e606a41edf6e404e81412f81..5cc6d6e0087fa5b00eff5d9489ff4838cf2e0a6a 100644 (file)
@@ -10,6 +10,7 @@
 #define _SPI_H_
 
 #include <common.h>
+#include <linux/bitops.h>
 
 /* SPI mode flags */
 #define SPI_CPHA       BIT(0)                  /* clock phase */
@@ -30,6 +31,8 @@
 #define SPI_RX_SLOW    BIT(11)                 /* receive with 1 wire slow */
 #define SPI_RX_DUAL    BIT(12)                 /* receive with 2 wires */
 #define SPI_RX_QUAD    BIT(13)                 /* receive with 4 wires */
+#define SPI_TX_OCTAL   BIT(14)                 /* transmit with 8 wires */
+#define SPI_RX_OCTAL   BIT(15)                 /* receive with 8 wires */
 
 /* Header byte that marks the start of the message */
 #define SPI_PREAMBLE_END_BYTE  0xec
@@ -64,6 +67,39 @@ struct dm_spi_slave_platdata {
 
 #endif /* CONFIG_DM_SPI */
 
+/**
+ * enum spi_clock_phase - indicates  the clock phase to use for SPI (CPHA)
+ *
+ * @SPI_CLOCK_PHASE_FIRST: Data sampled on the first phase
+ * @SPI_CLOCK_PHASE_SECOND: Data sampled on the second phase
+ */
+enum spi_clock_phase {
+       SPI_CLOCK_PHASE_FIRST,
+       SPI_CLOCK_PHASE_SECOND,
+};
+
+/**
+ * enum spi_wire_mode - indicates the number of wires used for SPI
+ *
+ * @SPI_4_WIRE_MODE: Normal bidirectional mode with MOSI and MISO
+ * @SPI_3_WIRE_MODE: Unidirectional version with a single data line SISO
+ */
+enum spi_wire_mode {
+       SPI_4_WIRE_MODE,
+       SPI_3_WIRE_MODE,
+};
+
+/**
+ * enum spi_polarity - indicates the polarity of the SPI bus (CPOL)
+ *
+ * @SPI_POLARITY_LOW: Clock is low in idle state
+ * @SPI_POLARITY_HIGH: Clock is high in idle state
+ */
+enum spi_polarity {
+       SPI_POLARITY_LOW,
+       SPI_POLARITY_HIGH,
+};
+
 /**
  * struct spi_slave - Representation of a SPI slave
  *
@@ -224,7 +260,7 @@ void spi_release_bus(struct spi_slave *slave);
 int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);
 
 /**
- * SPI transfer
+ * SPI transfer (optional if mem_ops is used)
  *
  * 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.
@@ -248,6 +284,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);
 
@@ -438,10 +494,23 @@ struct dm_spi_ops {
         * @cs:         The chip select (0..n-1)
         * @info:       Returns information about the chip select, if valid.
         *              On entry info->dev is NULL
-        * @return 0 if OK (and @info is set up), -ENODEV if the chip select
+        * @return 0 if OK (and @info is set up), -EINVAL if the chip select
         *         is invalid, other -ve value on error
         */
        int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info);
+
+       /**
+        * get_mmap() - Get memory-mapped SPI
+        *
+        * @dev:        The SPI flash slave device
+        * @map_basep:  Returns base memory address for mapped SPI
+        * @map_sizep:  Returns size of mapped SPI
+        * @offsetp:    Returns start offset of SPI flash where the map works
+        *      correctly (offsets before this are not visible)
+        * @return 0 if OK, -EFAULT if memory mapping is not available
+        */
+       int (*get_mmap)(struct udevice *dev, ulong *map_basep,
+                       uint *map_sizep, uint *offsetp);
 };
 
 struct dm_spi_emul_ops {
@@ -528,7 +597,8 @@ int spi_chip_select(struct udevice *slave);
  * @bus:       SPI bus to search
  * @cs:                Chip select to look for
  * @devp:      Returns the slave device if found
- * @return 0 if found, -ENODEV on error
+ * @return 0 if found, -EINVAL if cs is invalid, -ENODEV if no device attached,
+ *        other -ve value on error
  */
 int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp);
 
@@ -630,6 +700,20 @@ void dm_spi_release_bus(struct udevice *dev);
 int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
                const void *dout, void *din, unsigned long flags);
 
+/**
+ * spi_get_mmap() - Get memory-mapped SPI
+ *
+ * @dev:       SPI slave device to check
+ * @map_basep: Returns base memory address for mapped SPI
+ * @map_sizep: Returns size of mapped SPI
+ * @offsetp:   Returns start offset of SPI flash where the map works
+ *     correctly (offsets before this are not visible)
+ * @return 0 if OK, -ENOSYS if no operation, -EFAULT if memory mapping is not
+ *     available
+ */
+int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
+                   uint *offsetp);
+
 /* Access the operations for a SPI 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)