+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Common SPI Interface: Controller-specific definitions
*
* (C) Copyright 2001
* Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _SPI_H_
#define _SPI_H_
+#include <common.h>
+
/* SPI mode flags */
#define SPI_CPHA BIT(0) /* clock phase */
#define SPI_CPOL BIT(1) /* clock polarity */
#define SPI_RX_DUAL BIT(12) /* receive with 2 wires */
#define SPI_RX_QUAD BIT(13) /* receive with 4 wires */
-/* SPI bus connection options - see enum spi_dual_flash */
-#define SPI_CONN_DUAL_SHARED (1 << 0)
-#define SPI_CONN_DUAL_SEPARATED (1 << 1)
-
/* Header byte that marks the start of the message */
#define SPI_PREAMBLE_END_BYTE 0xec
* @cs: ID of the chip select connected to the slave.
* @mode: SPI mode to use for this slave (see SPI mode flags)
* @wordlen: Size of SPI word in number of bits
+ * @max_read_size: If non-zero, the maximum number of bytes which can
+ * be read at once.
* @max_write_size: If non-zero, the maximum number of bytes which can
- * be written at once, excluding command bytes.
+ * be written at once.
* @memory_map: Address of read-only SPI flash access.
- * @option: Varies SPI bus options - separate, shared bus.
* @flags: Indication of SPI flags.
*/
struct spi_slave {
#endif
uint mode;
unsigned int wordlen;
+ unsigned int max_read_size;
unsigned int max_write_size;
void *memory_map;
- u8 option;
u8 flags;
#define SPI_XFER_BEGIN BIT(0) /* Assert CS before transfer */
#define SPI_XFER_ONCE (SPI_XFER_BEGIN | SPI_XFER_END)
#define SPI_XFER_MMAP BIT(2) /* Memory Mapped start */
#define SPI_XFER_MMAP_END BIT(3) /* Memory Mapped End */
-#define SPI_XFER_U_PAGE BIT(4)
};
-/**
- * Initialization, must be called once on start up.
- *
- * TODO: I don't think we really need this.
- */
-void spi_init(void);
-
/**
* spi_do_alloc_slave - Allocate a new SPI slave (internal)
*
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);
return ret < 0 ? ret : din[1];
}
-/**
- * Set up a SPI slave for a particular device tree node
- *
- * This calls spi_setup_slave() with the correct bus number. Call
- * spi_free_slave() to free it later.
- *
- * @param blob: Device tree blob
- * @param slave_node: Slave node to use
- * @param spi_node: SPI peripheral node to use
- * @return pointer to new spi_slave structure
- */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
- int spi_node);
-
-/**
- * spi_base_setup_slave_fdt() - helper function to set up a SPI slace
- *
- * This decodes SPI properties from the slave node to determine the
- * chip select and SPI parameters.
- *
- * @blob: Device tree blob
- * @busnum: Bus number to use
- * @node: Device tree node for the SPI bus
- */
-struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
- int node);
-
#ifdef CONFIG_DM_SPI
/**
int (*xfer)(struct udevice *dev, unsigned int bitlen, const void *dout,
void *din, unsigned long flags);
+ /**
+ * Optimized handlers for SPI memory-like operations.
+ *
+ * Optimized/dedicated operations for interactions with SPI memory. This
+ * field is optional and should only be implemented if the controller
+ * has native support for memory like operations.
+ */
+ const struct spi_controller_mem_ops *mem_ops;
+
/**
* Set transfer speed.
* This sets a new speed to be applied for next spi_xfer().
* @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 {
* device and slave device.
*
* If no such slave exists, and drv_name is not NULL, then a new slave device
- * is automatically bound on this chip select.
+ * is automatically bound on this chip select with requested speed and mode.
*
- * Ths new slave device is probed ready for use with the given speed and mode.
+ * Ths new slave device is probed ready for use with the speed and mode
+ * from platdata when available or the requested values.
*
* @busnum: SPI bus number
* @cs: Chip select to look for
- * @speed: SPI speed to use for this slave
- * @mode: SPI mode to use for this slave
+ * @speed: SPI speed to use for this slave when not available in platdata
+ * @mode: SPI mode to use for this slave when not available in platdata
* @drv_name: Name of driver to attach to this chip select
* @dev_name: Name of the new device thus created
* @busp: Returns bus device
* @node: Node offset to read from
* @plat: Place to put the decoded information
*/
-int spi_slave_ofdata_to_platdata(const void *blob, int node,
+int spi_slave_ofdata_to_platdata(struct udevice *dev,
struct dm_spi_slave_platdata *plat);
/**
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)