Re: [PATCH 2/6] spi: add per-transfer CS mask
From: Nuno Sá
Date: Tue Jul 14 2026 - 05:13:11 EST
On Tue, Jul 14, 2026 at 02:56:02AM -0300, Jonathan Santos wrote:
> Multi-CS devices assert all their chip selects simultaneously by default
> via cs_index_mask. Some use cases require selecting a subset of those CS
> lines per transfer (e.g. routing data to one of several subdevices sharing
> the bus).
>
> Add a cs_select_mask field to spi_transfer. When the mask is set and the
> controller has SPI_CONTROLLER_MULTI_CS, spi_set_cs() builds a temporary
> spi_device whose chip_select[] and cs_gpiod[] arrays contain only the lines
> indicated by the mask, then delegates to the renamed _spi_set_cs().
> When cs_select_mask is 0 or the controller does not support multi-CS,
> the device default (cs_index_mask) is used unchanged.
>
> Update spi_transfer_one_message() to pass the relevant spi_transfer to
> every spi_set_cs() call so CS transitions between transfers with
> different masks are handled correctly.
>
> Signed-off-by: Jonathan Santos <Jonathan.Santos@xxxxxxxxxx>
> ---
> drivers/spi/spi.c | 88 +++++++++++++++++++++++++++++++++++------
> include/linux/spi/spi.h | 4 ++
> 2 files changed, 81 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 55fb96fea243..6d644adf8445 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1071,7 +1071,7 @@ static void spi_toggle_csgpiod(struct spi_device *spi, u8 idx, bool enable, bool
> spi_delay_exec(&spi->cs_inactive, NULL);
> }
>
> -static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
Might be missing something but spi_set_cs() in the current code does:
spi_get_chipselect(spi, 0);
And I'm not really seeing nothing in the patch handling it. Is that not
an issue?
> +static void _spi_set_cs(struct spi_device *spi, bool enable, bool force)
> {
> bool activate = enable;
> u8 idx;
> @@ -1129,6 +1129,61 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
> }
> }
>
> +static void spi_set_cs(struct spi_device *spi,
> + struct spi_transfer *xfer,
> + bool enable, bool force)
> +{
> + struct spi_controller *ctlr = spi->controller;
> + struct spi_device temp_spi;
Not sure what to feel about the above temp_spi dance. Can't we just pass a cs_mask
into _spi_set_cs() and change the code accordingly? And for the default
case we would just pass spi->cs_index_mask.
- Nuno Sá