From 5132b3d283710d196cd8af99b5585507e8b30709 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 1 Nov 2018 22:25:04 +0100 Subject: spi: gpio: Support 3WIRE high-impedance turn-around Some devices such as the TPO TPG110 display panel require a "high-impedance turn-around", in effect a clock cycle after switching the line from output to input mode. Support this in the GPIO driver to begin with. Other driver may implement it if they can, it is unclear if this can be achieved with anything else than GPIO bit-banging. Cc: Andrzej Hajda Acked-by: Lorenzo Bianconi Signed-off-by: Linus Walleij Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 6be77fa5ab90..3ced58eebe1b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -155,6 +155,7 @@ struct spi_device { #define SPI_RX_DUAL 0x400 /* receive with 2 wires */ #define SPI_RX_QUAD 0x800 /* receive with 4 wires */ #define SPI_CS_WORD 0x1000 /* toggle cs after each word */ +#define SPI_3WIRE_HIZ 0x2000 /* high impedance turnaround */ int irq; void *controller_state; void *controller_data; -- cgit v1.2.3 From ec93cb6f827b3e1a81b0721b8c893d2a5e37e7d6 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 13 Nov 2018 11:22:25 +0100 Subject: spi: pxa2xx: Add slave mode support Tested on an OLPC XO-1.75 machine, where the Embedded Controller happens to be a SPI master. Signed-off-by: Lubomir Rintel Acked-by: Pavel Machek Signed-off-by: Mark Brown --- include/linux/spi/pxa2xx_spi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index 9ec4c147abbc..b0674e330ef6 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -25,6 +25,7 @@ struct dma_chan; struct pxa2xx_spi_master { u16 num_chipselect; u8 enable_dma; + bool is_slave; /* DMA engine specific config */ bool (*dma_filter)(struct dma_chan *chan, void *param); -- cgit v1.2.3 From 6afe76a6723975391d06c42a422370a588395f84 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 6 Nov 2018 17:05:30 +0100 Subject: spi: spi-mem: Add missing word in the SPI_MEM_DATA_OUT description Missing 'to' in the SPI_MEM_DATA_OUT description. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Mark Brown --- include/linux/spi/spi-mem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 69ee30456864..867839cc69a7 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -58,7 +58,7 @@ * enum spi_mem_data_dir - describes the direction of a SPI memory data * transfer from the controller perspective * @SPI_MEM_DATA_IN: data coming from the SPI memory - * @SPI_MEM_DATA_OUT: data sent the SPI memory + * @SPI_MEM_DATA_OUT: data sent to the SPI memory */ enum spi_mem_data_dir { SPI_MEM_DATA_IN, -- cgit v1.2.3 From 0ebb261a0b2d090de618a383d2378d4a00834958 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 6 Nov 2018 17:05:31 +0100 Subject: spi: spi-mem: Add SPI_MEM_NO_DATA to the spi_mem_data_dir enum When defining spi_mem_op templates we don't necessarily know the size that will be passed when the template is actually used, and basing the supports_op() check on op->data.nbytes to know whether there will be data transferred for a specific operation is this not possible. Add SPI_MEM_NO_DATA to the spi_mem_data_dir enum so that we can base our checks on op->data.dir instead of op->data.nbytes. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Mark Brown --- include/linux/spi/spi-mem.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 867839cc69a7..250b6f5c47c2 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -57,10 +57,12 @@ /** * enum spi_mem_data_dir - describes the direction of a SPI memory data * transfer from the controller perspective + * @SPI_MEM_NO_DATA: no data transferred * @SPI_MEM_DATA_IN: data coming from the SPI memory * @SPI_MEM_DATA_OUT: data sent to the SPI memory */ enum spi_mem_data_dir { + SPI_MEM_NO_DATA, SPI_MEM_DATA_IN, SPI_MEM_DATA_OUT, }; -- cgit v1.2.3 From aa167f3fed0c37e0e4c707d4331d827661f46644 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Tue, 6 Nov 2018 17:05:33 +0100 Subject: spi: spi-mem: Add a new API to support direct mapping Most modern SPI controllers can directly map a SPI memory (or a portion of the SPI memory) in the CPU address space. Most of the time this brings significant performance improvements as it automates the whole process of sending SPI memory operations every time a new region is accessed. This new API allows SPI memory drivers to create direct mappings and then use them to access the memory instead of using spi_mem_exec_op(). Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Mark Brown --- include/linux/spi/spi-mem.h | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'include') diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 250b6f5c47c2..3fe24500c5ee 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -124,6 +124,49 @@ struct spi_mem_op { .data = __data, \ } +/** + * struct spi_mem_dirmap_info - Direct mapping information + * @op_tmpl: operation template that should be used by the direct mapping when + * the memory device is accessed + * @offset: absolute offset this direct mapping is pointing to + * @length: length in byte of this direct mapping + * + * These information are used by the controller specific implementation to know + * the portion of memory that is directly mapped and the spi_mem_op that should + * be used to access the device. + * A direct mapping is only valid for one direction (read or write) and this + * direction is directly encoded in the ->op_tmpl.data.dir field. + */ +struct spi_mem_dirmap_info { + struct spi_mem_op op_tmpl; + u64 offset; + u64 length; +}; + +/** + * struct spi_mem_dirmap_desc - Direct mapping descriptor + * @mem: the SPI memory device this direct mapping is attached to + * @info: information passed at direct mapping creation time + * @nodirmap: set to 1 if the SPI controller does not implement + * ->mem_ops->dirmap_create() or when this function returned an + * error. If @nodirmap is true, all spi_mem_dirmap_{read,write}() + * calls will use spi_mem_exec_op() to access the memory. This is a + * degraded mode that allows spi_mem drivers to use the same code + * no matter whether the controller supports direct mapping or not + * @priv: field pointing to controller specific data + * + * Common part of a direct mapping descriptor. This object is created by + * spi_mem_dirmap_create() and controller implementation of ->create_dirmap() + * can create/attach direct mapping resources to the descriptor in the ->priv + * field. + */ +struct spi_mem_dirmap_desc { + struct spi_mem *mem; + struct spi_mem_dirmap_info info; + unsigned int nodirmap; + void *priv; +}; + /** * struct spi_mem - describes a SPI memory device * @spi: the underlying SPI device @@ -179,10 +222,32 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) * Note that if the implementation of this function allocates memory * dynamically, then it should do so with devm_xxx(), as we don't * have a ->free_name() function. + * @dirmap_create: create a direct mapping descriptor that can later be used to + * access the memory device. This method is optional + * @dirmap_destroy: destroy a memory descriptor previous created by + * ->dirmap_create() + * @dirmap_read: read data from the memory device using the direct mapping + * created by ->dirmap_create(). The function can return less + * data than requested (for example when the request is crossing + * the currently mapped area), and the caller of + * spi_mem_dirmap_read() is responsible for calling it again in + * this case. + * @dirmap_write: write data to the memory device using the direct mapping + * created by ->dirmap_create(). The function can return less + * data than requested (for example when the request is crossing + * the currently mapped area), and the caller of + * spi_mem_dirmap_write() is responsible for calling it again in + * this case. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually the * case for QSPI controllers. + * + * Note on ->dirmap_{read,write}(): drivers should avoid accessing the direct + * mapping from the CPU because doing that can stall the CPU waiting for the + * SPI mem transaction to finish, and this will make real-time maintainers + * unhappy and might make your system less reactive. Instead, drivers should + * use DMA to access this direct mapping. */ struct spi_controller_mem_ops { int (*adjust_op_size)(struct spi_mem *mem, struct spi_mem_op *op); @@ -191,6 +256,12 @@ struct spi_controller_mem_ops { int (*exec_op)(struct spi_mem *mem, const struct spi_mem_op *op); const char *(*get_name)(struct spi_mem *mem); + int (*dirmap_create)(struct spi_mem_dirmap_desc *desc); + void (*dirmap_destroy)(struct spi_mem_dirmap_desc *desc); + ssize_t (*dirmap_read)(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf); + ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf); }; /** @@ -251,6 +322,15 @@ int spi_mem_exec_op(struct spi_mem *mem, const char *spi_mem_get_name(struct spi_mem *mem); +struct spi_mem_dirmap_desc * +spi_mem_dirmap_create(struct spi_mem *mem, + const struct spi_mem_dirmap_info *info); +void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc); +ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf); +ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf); + int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, struct module *owner); -- cgit v1.2.3 From 6b03061f882de49b83ccf44beb3a12c920a2da1b Mon Sep 17 00:00:00 2001 From: Yogesh Narayan Gaur Date: Mon, 3 Dec 2018 08:39:06 +0000 Subject: spi: add support for octal mode I/O data transfer Add flags for Octal mode I/O data transfer Required for the SPI controller which can do the data transfer (TX/RX) on 8 data lines e.g. NXP FlexSPI controller. SPI_TX_OCTAL: transmit with 8 wires SPI_RX_OCTAL: receive with 8 wires Signed-off-by: Yogesh Gaur Reviewed-by: Boris Brezillon Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 6be77fa5ab90..0c1ca5dedbb4 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -154,7 +154,9 @@ struct spi_device { #define SPI_TX_QUAD 0x200 /* transmit with 4 wires */ #define SPI_RX_DUAL 0x400 /* receive with 2 wires */ #define SPI_RX_QUAD 0x800 /* receive with 4 wires */ -#define SPI_CS_WORD 0x1000 /* toggle cs after each word */ +#define SPI_CS_WORD 0x1000 /* toggle cs after each word */ +#define SPI_TX_OCTAL 0x2000 /* transmit with 8 wires */ +#define SPI_RX_OCTAL 0x4000 /* receive with 8 wires */ int irq; void *controller_state; void *controller_data; -- cgit v1.2.3