Unverified Commit 10c24e0d authored by Félix Piédallu's avatar Félix Piédallu Committed by Mark Brown
Browse files

spi: omap2-mcspi: Disable multi-mode when the previous message kept CS asserted



When the last transfer of a SPI message has the cs_change flag, the CS is kept
asserted after the message.
The next message can't use multi-mode because the CS will be briefly deasserted
before the first transfer.

Remove the early exit of the list_for_each_entry because the last transfer
actually needs to be always checked.

Fixes: d153ff40 ("spi: omap2-mcspi: Add support for MULTI-mode")
Signed-off-by: default avatarFélix Piédallu <felix.piedallu@non.se.com>
Link: https://patch.msgid.link/20250606-cs_change_fix-v1-2-27191a98a2e5@non.se.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent a5bf5272
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ struct omap2_mcspi {
	size_t			max_xfer_len;
	u32			ref_clk_hz;
	bool			use_multi_mode;
	bool			last_msg_kept_cs;
};

struct omap2_mcspi_cs {
@@ -1269,6 +1270,10 @@ static int omap2_mcspi_prepare_message(struct spi_controller *ctlr,
	 * multi-mode is applicable.
	 */
	mcspi->use_multi_mode = true;

	if (mcspi->last_msg_kept_cs)
		mcspi->use_multi_mode = false;

	list_for_each_entry(tr, &msg->transfers, transfer_list) {
		if (!tr->bits_per_word)
			bits_per_word = msg->spi->bits_per_word;
@@ -1289,22 +1294,17 @@ static int omap2_mcspi_prepare_message(struct spi_controller *ctlr,

		if (list_is_last(&tr->transfer_list, &msg->transfers)) {
			/* Check if transfer asks to keep the CS status after the whole message */
			if (tr->cs_change)
			if (tr->cs_change) {
				mcspi->use_multi_mode = false;
				mcspi->last_msg_kept_cs = true;
			} else {
				mcspi->last_msg_kept_cs = false;
			}
		} else {
			/* Check if transfer asks to change the CS status after the transfer */
			if (!tr->cs_change)
				mcspi->use_multi_mode = false;
		}

		/*
		 * If at least one message is not compatible, switch back to single mode
		 *
		 * The bits_per_word of certain transfer can be different, but it will have no
		 * impact on the signal itself.
		 */
		if (!mcspi->use_multi_mode)
			break;
	}

	omap2_mcspi_set_mode(ctlr);