Unverified Commit 33a6969f authored by Herve Codina's avatar Herve Codina Committed by Mark Brown
Browse files

ASoC: fsl: fsl_qmc_audio: Introduce qmc_audio_pcm_{read,write}_submit()



Submitting data to QMC channels is done in several places: transfer
completions and DAI start. The operation done is simple and consist in
one function call.

With the future introduction of support for non-interleaved mode,
submitting data will be more complex.

To avoid copy/paste of code in several places, introduce
qmc_audio_pcm_{read,write}_submit() whose goal is to handle this
data submission.

Signed-off-by: default avatarHerve Codina <herve.codina@bootlin.com>
Link: https://patch.msgid.link/20240701113038.55144-6-herve.codina@bootlin.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5e51a1f9
Loading
Loading
Loading
Loading
+45 −48
Original line number Diff line number Diff line
@@ -90,11 +90,29 @@ static int qmc_audio_pcm_hw_params(struct snd_soc_component *component,
	return 0;
}

static void qmc_audio_pcm_write_complete(void *context);

static int qmc_audio_pcm_write_submit(struct qmc_dai_prtd *prtd)
{
	int ret;

	ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
				    prtd->ch_dma_addr_current, prtd->ch_dma_size,
				    qmc_audio_pcm_write_complete,
				    &prtd->qmc_dai->chan);
	if (ret) {
		dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
			ret);
		return ret;
	}

	return 0;
}

static void qmc_audio_pcm_write_complete(void *context)
{
	struct qmc_dai_chan *chan = context;
	struct qmc_dai_prtd *prtd;
	int ret;

	prtd = chan->prtd_tx;

@@ -106,23 +124,33 @@ static void qmc_audio_pcm_write_complete(void *context)
	if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
		prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;

	ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
	qmc_audio_pcm_write_submit(prtd);

	snd_pcm_period_elapsed(prtd->substream);
}

static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned int flags);

static int qmc_audio_pcm_read_submit(struct qmc_dai_prtd *prtd)
{
	int ret;

	ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
				   prtd->ch_dma_addr_current, prtd->ch_dma_size,
				    qmc_audio_pcm_write_complete,
				   qmc_audio_pcm_read_complete,
				   &prtd->qmc_dai->chan);
	if (ret) {
		dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
		dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
			ret);
	}

	snd_pcm_period_elapsed(prtd->substream);
	return 0;
}

static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned int flags)
{
	struct qmc_dai_chan *chan = context;
	struct qmc_dai_prtd *prtd;
	int ret;

	prtd = chan->prtd_rx;

@@ -139,14 +167,7 @@ static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned i
	if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
		prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;

	ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
				   prtd->ch_dma_addr_current, prtd->ch_dma_size,
				   qmc_audio_pcm_read_complete,
				   &prtd->qmc_dai->chan);
	if (ret) {
		dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
			ret);
	}
	qmc_audio_pcm_read_submit(prtd);

	snd_pcm_period_elapsed(prtd->substream);
}
@@ -168,15 +189,9 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
			prtd->qmc_dai->chan.prtd_tx = prtd;

			/* Submit first chunk ... */
			ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
						    prtd->ch_dma_addr_current, prtd->ch_dma_size,
						    qmc_audio_pcm_write_complete,
						    &prtd->qmc_dai->chan);
			if (ret) {
				dev_err(component->dev, "write_submit failed %d\n",
					ret);
			ret = qmc_audio_pcm_write_submit(prtd);
			if (ret)
				return ret;
			}

			/* ... prepare next one ... */
			prtd->ch_dma_addr_current += prtd->ch_dma_size;
@@ -184,28 +199,16 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
				prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;

			/* ... and send it */
			ret = qmc_chan_write_submit(prtd->qmc_dai->chan.qmc_chan,
						    prtd->ch_dma_addr_current, prtd->ch_dma_size,
						    qmc_audio_pcm_write_complete,
						    &prtd->qmc_dai->chan);
			if (ret) {
				dev_err(component->dev, "write_submit failed %d\n",
					ret);
			ret = qmc_audio_pcm_write_submit(prtd);
			if (ret)
				return ret;
			}
		} else {
			prtd->qmc_dai->chan.prtd_rx = prtd;

			/* Submit first chunk ... */
			ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
						   prtd->ch_dma_addr_current, prtd->ch_dma_size,
						   qmc_audio_pcm_read_complete,
						   &prtd->qmc_dai->chan);
			if (ret) {
				dev_err(component->dev, "read_submit failed %d\n",
					ret);
			ret = qmc_audio_pcm_read_submit(prtd);
			if (ret)
				return ret;
			}

			/* ... prepare next one ... */
			prtd->ch_dma_addr_current += prtd->ch_dma_size;
@@ -213,16 +216,10 @@ static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
				prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;

			/* ... and send it */
			ret = qmc_chan_read_submit(prtd->qmc_dai->chan.qmc_chan,
						   prtd->ch_dma_addr_current, prtd->ch_dma_size,
						   qmc_audio_pcm_read_complete,
						   &prtd->qmc_dai->chan);
			if (ret) {
				dev_err(component->dev, "write_submit failed %d\n",
					ret);
			ret = qmc_audio_pcm_read_submit(prtd);
			if (ret)
				return ret;
		}
		}
		break;

	case SNDRV_PCM_TRIGGER_RESUME: