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:
parent
80565764c7
commit
22c406c9bf
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user