Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccd01559 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: rsnd: use dmaengine_prep_dma_cyclic() instead of original method



Current R-Car sound driver is using DMAEngine directly,
but, ASoC is requesting to use common DMA transfer method,
like snd_dmaengine_pcm_trigger() or dmaengine_pcm_ops.
It is difficult to switch at this point, since Renesas
driver is also supporting PIO transfer.
This patch uses dmaengine_prep_dma_cyclic() instead
of dmaengine_prep_slave_single().
It is used in requested method,
and is good first step to switch over.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent d9288d0b
Loading
Loading
Loading
Loading
+18 −58
Original line number Diff line number Diff line
@@ -164,26 +164,8 @@ void rsnd_mod_init(struct rsnd_priv *priv,
/*
 *	rsnd_dma functions
 */
static void __rsnd_dma_start(struct rsnd_dma *dma);
static void rsnd_dma_continue(struct rsnd_dma *dma)
{
	/* push next A or B plane */
	dma->submit_loop = 1;
	schedule_work(&dma->work);
}

void rsnd_dma_start(struct rsnd_dma *dma)
{
	/* push both A and B plane*/
	dma->offset = 0;
	dma->submit_loop = 2;
	__rsnd_dma_start(dma);
}

void rsnd_dma_stop(struct rsnd_dma *dma)
{
	dma->submit_loop = 0;
	cancel_work_sync(&dma->work);
	dmaengine_terminate_all(dma->chan);
}

@@ -191,11 +173,7 @@ static void rsnd_dma_complete(void *data)
{
	struct rsnd_dma *dma = (struct rsnd_dma *)data;
	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
	struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	unsigned long flags;

	rsnd_lock(priv, flags);

	/*
	 * Renesas sound Gen1 needs 1 DMAC,
@@ -208,35 +186,26 @@ static void rsnd_dma_complete(void *data)
	 * rsnd_dai_pointer_update() will be called twice,
	 * ant it will breaks io->byte_pos
	 */
	if (dma->submit_loop)
		rsnd_dma_continue(dma);

	rsnd_unlock(priv, flags);

	rsnd_dai_pointer_update(io, io->byte_per_period);
}

static void __rsnd_dma_start(struct rsnd_dma *dma)
void rsnd_dma_start(struct rsnd_dma *dma)
{
	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
	struct snd_pcm_substream *substream = io->substream;
	struct device *dev = rsnd_priv_to_dev(priv);
	struct dma_async_tx_descriptor *desc;
	dma_addr_t buf;
	size_t len = io->byte_per_period;
	int i;

	for (i = 0; i < dma->submit_loop; i++) {

		buf = runtime->dma_addr +
			rsnd_dai_pointer_offset(io, dma->offset + len);
		dma->offset = len;

		desc = dmaengine_prep_slave_single(
			dma->chan, buf, len, dma->dir,
	desc = dmaengine_prep_dma_cyclic(dma->chan,
					 substream->runtime->dma_addr,
					 snd_pcm_lib_buffer_bytes(substream),
					 snd_pcm_lib_period_bytes(substream),
					 dma->dir,
					 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);

	if (!desc) {
		dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
		return;
@@ -252,14 +221,6 @@ static void __rsnd_dma_start(struct rsnd_dma *dma)

	dma_async_issue_pending(dma->chan);
}
}

static void rsnd_dma_do_work(struct work_struct *work)
{
	struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work);

	__rsnd_dma_start(dma);
}

int rsnd_dma_available(struct rsnd_dma *dma)
{
@@ -372,7 +333,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
		goto rsnd_dma_init_err;

	dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
	INIT_WORK(&dma->work, rsnd_dma_do_work);

	return 0;

+0 −4
Original line number Diff line number Diff line
@@ -156,12 +156,8 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod);
 */
struct rsnd_dma {
	struct sh_dmae_slave	slave;
	struct work_struct	work;
	struct dma_chan		*chan;
	enum dma_transfer_direction dir;

	int submit_loop;
	int offset; /* it cares A/B plane */
};

void rsnd_dma_start(struct rsnd_dma *dma);