Unverified Commit fb418fe2 authored by Christophe Leroy's avatar Christophe Leroy Committed by Mark Brown
Browse files

ASoC: fsl: fsl_qmc_audio: Ensure audio channels are ordered in TDM bus



To reduce complexity of interrupt handling in following patch, ensure
audio channels are configured in the same order as timeslots on the
TDM bus. If we need a given ordering of audio sources in the audio
frame, it is possible to re-order codecs on the TDM bus, no need to
mix up timeslots in channels.

Acked-by: default avatarHerve Codina <herve.codina@bootlin.com>
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Link: https://patch.msgid.link/4ff40afdf3d032b05dd4af6c0f777d4d4b445a76.1758209158.git.christophe.leroy@csgroup.eu


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c2a60426
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -791,12 +791,17 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *
			       struct qmc_dai *qmc_dai,
			       struct snd_soc_dai_driver *qmc_soc_dai_driver)
{
	struct qmc_chan_ts_info ts_info;
	struct qmc_chan_info info;
	unsigned long rx_fs_rate;
	unsigned long tx_fs_rate;
	int prev_last_rx_ts = 0;
	int prev_last_tx_ts = 0;
	unsigned int nb_tx_ts;
	unsigned int nb_rx_ts;
	unsigned int i;
	int last_rx_ts;
	int last_tx_ts;
	int count;
	u32 val;
	int ret;
@@ -879,6 +884,30 @@ static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *
				return -EINVAL;
			}
		}

		ret = qmc_chan_get_ts_info(qmc_dai->chans[i].qmc_chan, &ts_info);
		if (ret) {
			dev_err(qmc_audio->dev, "dai %d get QMC %d channel TS info failed %d\n",
				qmc_dai->id, i, ret);
			return ret;
		}

		last_rx_ts = fls64(ts_info.rx_ts_mask);
		last_tx_ts = fls64(ts_info.tx_ts_mask);

		if (prev_last_rx_ts > last_rx_ts) {
			dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (RX timeslot %d before %d)\n",
				qmc_dai->id, i, prev_last_rx_ts, last_rx_ts);
			return -EINVAL;
		}
		if (prev_last_tx_ts > last_tx_ts) {
			dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (TX timeslot %d before %d)\n",
				qmc_dai->id, i, prev_last_tx_ts, last_tx_ts);
			return -EINVAL;
		}

		prev_last_rx_ts = last_rx_ts;
		prev_last_tx_ts = last_tx_ts;
	}

	qmc_dai->nb_chans_avail = count;