1

ASoC: rsnd: use pcm_dmaengine code

rsnd is implementing own DMAEngine code, but we can replace it with
pcm_dmaengine code, because these are almost same.
Let's use existing and stable code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://patch.msgid.link/87cymvk3t5.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Kuninori Morimoto 2024-07-30 02:32:22 +00:00 committed by Mark Brown
parent 80565764c7
commit 22c406c9bf
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
5 changed files with 9 additions and 87 deletions

View File

@ -41,6 +41,7 @@ config SND_SOC_RCAR
depends on COMMON_CLK depends on COMMON_CLK
depends on OF depends on OF
select SND_SIMPLE_CARD_UTILS select SND_SIMPLE_CARD_UTILS
select SND_DMAENGINE_PCM
select REGMAP_MMIO select REGMAP_MMIO
help help
This option enables R-Car SRU/SCU/SSIU/SSI sound support This option enables R-Car SRU/SCU/SSIU/SSI sound support

View File

@ -660,23 +660,6 @@ static struct rsnd_dai *rsnd_dai_to_rdai(struct snd_soc_dai *dai)
return rsnd_rdai_get(priv, dai->id); return rsnd_rdai_get(priv, dai->id);
} }
/*
* rsnd_soc_dai functions
*/
void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io)
{
struct snd_pcm_substream *substream = io->substream;
/*
* this function should be called...
*
* - if rsnd_dai_pointer_update() returns true
* - without spin lock
*/
snd_pcm_period_elapsed(substream);
}
static void rsnd_dai_stream_init(struct rsnd_dai_stream *io, static void rsnd_dai_stream_init(struct rsnd_dai_stream *io,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {

View File

@ -7,6 +7,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of_dma.h> #include <linux/of_dma.h>
#include <sound/dmaengine_pcm.h>
#include "rsnd.h" #include "rsnd.h"
/* /*
@ -22,8 +23,6 @@
struct rsnd_dmaen { struct rsnd_dmaen {
struct dma_chan *chan; struct dma_chan *chan;
dma_cookie_t cookie;
unsigned int dma_len;
}; };
struct rsnd_dmapp { struct rsnd_dmapp {
@ -66,20 +65,6 @@ static struct rsnd_mod mem = {
/* /*
* Audio DMAC * Audio DMAC
*/ */
static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
struct rsnd_dai_stream *io)
{
if (rsnd_io_is_working(io))
rsnd_dai_period_elapsed(io);
}
static void rsnd_dmaen_complete(void *data)
{
struct rsnd_mod *mod = data;
rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
}
static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io, static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
struct rsnd_mod *mod_from, struct rsnd_mod *mod_from,
struct rsnd_mod *mod_to) struct rsnd_mod *mod_to)
@ -98,13 +83,7 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
struct rsnd_priv *priv) struct rsnd_priv *priv)
{ {
struct rsnd_dma *dma = rsnd_mod_to_dma(mod); return snd_dmaengine_pcm_trigger(io->substream, SNDRV_PCM_TRIGGER_STOP);
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
if (dmaen->chan)
dmaengine_terminate_async(dmaen->chan);
return 0;
} }
static int rsnd_dmaen_cleanup(struct rsnd_mod *mod, static int rsnd_dmaen_cleanup(struct rsnd_mod *mod,
@ -120,7 +99,7 @@ static int rsnd_dmaen_cleanup(struct rsnd_mod *mod,
* Let's call it under prepare * Let's call it under prepare
*/ */
if (dmaen->chan) if (dmaen->chan)
dma_release_channel(dmaen->chan); snd_dmaengine_pcm_close_release_chan(io->substream);
dmaen->chan = NULL; dmaen->chan = NULL;
@ -153,7 +132,7 @@ static int rsnd_dmaen_prepare(struct rsnd_mod *mod,
return -EIO; return -EIO;
} }
return 0; return snd_dmaengine_pcm_open(io->substream, dmaen->chan);
} }
static int rsnd_dmaen_start(struct rsnd_mod *mod, static int rsnd_dmaen_start(struct rsnd_mod *mod,
@ -162,12 +141,9 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
{ {
struct rsnd_dma *dma = rsnd_mod_to_dma(mod); struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
struct snd_pcm_substream *substream = io->substream;
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct dma_async_tx_descriptor *desc;
struct dma_slave_config cfg = {}; struct dma_slave_config cfg = {};
enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
int is_play = rsnd_io_is_play(io);
int ret; int ret;
/* /*
@ -195,7 +171,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
} }
} }
cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; cfg.direction = snd_pcm_substream_to_dma_direction(io->substream);
cfg.src_addr = dma->src_addr; cfg.src_addr = dma->src_addr;
cfg.dst_addr = dma->dst_addr; cfg.dst_addr = dma->dst_addr;
cfg.src_addr_width = buswidth; cfg.src_addr_width = buswidth;
@ -209,32 +185,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
if (ret < 0) if (ret < 0)
return ret; return ret;
desc = dmaengine_prep_dma_cyclic(dmaen->chan, return snd_dmaengine_pcm_trigger(io->substream, SNDRV_PCM_TRIGGER_START);
substream->runtime->dma_addr,
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream),
is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
return -EIO;
}
desc->callback = rsnd_dmaen_complete;
desc->callback_param = rsnd_mod_get(dma);
dmaen->dma_len = snd_pcm_lib_buffer_bytes(substream);
dmaen->cookie = dmaengine_submit(desc);
if (dmaen->cookie < 0) {
dev_err(dev, "dmaengine_submit() fail\n");
return -EIO;
}
dma_async_issue_pending(dmaen->chan);
return 0;
} }
struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *name, struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *name,
@ -307,19 +258,7 @@ static int rsnd_dmaen_pointer(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
snd_pcm_uframes_t *pointer) snd_pcm_uframes_t *pointer)
{ {
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); *pointer = snd_dmaengine_pcm_pointer(io->substream);
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
struct dma_tx_state state;
enum dma_status status;
unsigned int pos = 0;
status = dmaengine_tx_status(dmaen->chan, dmaen->cookie, &state);
if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) {
if (state.residue > 0 && state.residue <= dmaen->dma_len)
pos = dmaen->dma_len - state.residue;
}
*pointer = bytes_to_frames(runtime, pos);
return 0; return 0;
} }

View File

@ -576,7 +576,6 @@ int rsnd_rdai_ssi_lane_ctrl(struct rsnd_dai *rdai,
#define rsnd_rdai_width_get(rdai) \ #define rsnd_rdai_width_get(rdai) \
rsnd_rdai_width_ctrl(rdai, 0) rsnd_rdai_width_ctrl(rdai, 0)
int rsnd_rdai_width_ctrl(struct rsnd_dai *rdai, int width); int rsnd_rdai_width_ctrl(struct rsnd_dai *rdai, int width);
void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io);
int rsnd_dai_connect(struct rsnd_mod *mod, int rsnd_dai_connect(struct rsnd_mod *mod,
struct rsnd_dai_stream *io, struct rsnd_dai_stream *io,
enum rsnd_mod_type type); enum rsnd_mod_type type);

View File

@ -706,7 +706,7 @@ rsnd_ssi_interrupt_out:
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
if (elapsed) if (elapsed)
rsnd_dai_period_elapsed(io); snd_pcm_period_elapsed(io->substream);
if (stop) if (stop)
snd_pcm_stop_xrun(io->substream); snd_pcm_stop_xrun(io->substream);