[PATCH v4 8/9] spi: spi-engine-ex: Add support for multi-CS devices
From: Jonathan Santos
Date: Tue Oct 20 2026 - 22:02:12 EST
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 <Jonathan.Santos@xxxxxxxxxx>
---
Changes in v4:
* Added the spi_engine_get_chipselect_bits() helper to reduce duplicated
code.
Changes in v3:
* None.
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 | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index 02bbc5d0cfc5..e4c40059e583 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -278,13 +278,25 @@ static void spi_engine_gen_sleep(struct spi_engine_program *p, bool dry,
}
}
+static unsigned long spi_engine_get_chipselect_bits(struct spi_device *spi,
+ unsigned long index_mask)
+{
+ unsigned long bits = 0;
+ unsigned int idx;
+
+ for_each_set_bit(idx, &index_mask, SPI_DEVICE_CS_CNT_MAX)
+ bits |= BIT(spi_get_chipselect(spi, idx));
+
+ return bits;
+}
+
static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry,
struct spi_device *spi, bool assert)
{
unsigned int mask = 0xff;
if (assert)
- mask ^= BIT(spi_get_chipselect(spi, 0));
+ mask ^= spi_engine_get_chipselect_bits(spi, spi->cs_index_mask);
spi_engine_program_add_cmd(p, dry, SPI_ENGINE_CMD_ASSERT(0, mask));
}
@@ -886,12 +898,14 @@ 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_bits;
unsigned int reg;
+ cs_bits = spi_engine_get_chipselect_bits(device, device->cs_index_mask);
if (device->mode & SPI_CS_HIGH)
- spi_engine->cs_inv |= BIT(spi_get_chipselect(device, 0));
+ spi_engine->cs_inv |= cs_bits;
else
- spi_engine->cs_inv &= ~BIT(spi_get_chipselect(device, 0));
+ spi_engine->cs_inv &= ~cs_bits;
writel_relaxed(SPI_ENGINE_CMD_SYNC(0),
spi_engine->base + SPI_ENGINE_REG_CMD_FIFO);
@@ -1222,6 +1236,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