[PATCH v2 4/5] spi: spi-engine-ex: Add support for multi-CS devices
Jonathan Santos <[email protected]> Mon, 3 Aug 2026 00:02:29 -0300
| Newsgroups | org.kernel.vger.linux-spi,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <a595944fda10f801dd3d11640f3a3726401c40d9.1785725359.git.Jonathan.Santos@analog.com> |
The SPI Engine controller only handled the first chip select when asserting CS lines and configuring CS polarity inversion, ignoring additional CS indices present in cs_index_mask. Update spi_engine_gen_cs() to iterate over all set bits in cs_index_mask and toggle each corresponding CS line in the assert mask. Update spi_engine_setup() likewise so that SPI_CS_HIGH polarity is applied to every active CS index rather than only index 0. Set SPI_CONTROLLER_MULTI_CS in the controller flags to reflect the capability to the SPI core. Signed-off-by: Jonathan Santos <[email protected]> --- Changes in v2: * Adaptation of the patch "spi: spi-engine-ex: Add support for multi-CS devices" from v1, discarding the per transfer CS mask and keeping the Multi-CS support only. --- drivers/spi/spi-axi-spi-engine.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 02bbc5d0cfc5..8a2cae81aea6 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -46,6 +46,7 @@ #define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xec #define SPI_ENGINE_MAX_NUM_OFFLOADS 32 +#define SPI_ENGINE_MAX_CS 8 #define SPI_ENGINE_REG_OFFLOAD_CTRL(x) (0x100 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) #define SPI_ENGINE_REG_OFFLOAD_STATUS(x) (0x104 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) @@ -281,10 +282,14 @@ static void spi_engine_gen_sleep(struct spi_engine_program *p, bool dry, static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry, struct spi_device *spi, bool assert) { + unsigned long cs_index_mask = spi->cs_index_mask; unsigned int mask = 0xff; + unsigned int cs_bit; - if (assert) - mask ^= BIT(spi_get_chipselect(spi, 0)); + if (assert) { + for_each_set_bit(cs_bit, &cs_index_mask, SPI_ENGINE_MAX_CS) + mask ^= BIT(spi_get_chipselect(spi, cs_bit)); + } spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_ASSERT(0, mask)); } @@ -886,12 +891,16 @@ static int spi_engine_setup(struct spi_device *device) { struct spi_controller *host = device->controller; struct spi_engine *spi_engine = spi_controller_get_devdata(host); + unsigned long cs_index_mask = device->cs_index_mask; unsigned int reg; + u32 cs_bit; - if (device->mode & SPI_CS_HIGH) - spi_engine->cs_inv |= BIT(spi_get_chipselect(device, 0)); - else - spi_engine->cs_inv &= ~BIT(spi_get_chipselect(device, 0)); + for_each_set_bit(cs_bit, &cs_index_mask, SPI_ENGINE_MAX_CS) { + if (device->mode & SPI_CS_HIGH) + spi_engine->cs_inv |= BIT(spi_get_chipselect(device, cs_bit)); + else + spi_engine->cs_inv &= ~BIT(spi_get_chipselect(device, cs_bit)); + } writel_relaxed(SPI_ENGINE_CMD_SYNC(0), spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); @@ -1222,6 +1231,7 @@ static int spi_engine_probe(struct platform_device *pdev) host->unoptimize_message = spi_engine_unoptimize_message; host->get_offload = spi_engine_get_offload; host->put_offload = spi_engine_put_offload; + host->flags |= SPI_CONTROLLER_MULTI_CS; host->num_chipselect = 8; if (adi_axi_pcore_ver_gteq(version, 1, 2)) { -- 2.34.1