Commit 4686a0ad authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: rsnd: remove SSI dependent DMAEngine callback

Renesas Gen2 sound will use 2 DMAC
which are Audio-DMAC, and Audio-DMAC-peri-peri.
Current driver has callback function for each DMAC,
because it assumed each DMAC needs special settings.
But it became clear that these can share settings.
This patch removes unnecessary callback
Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 1b7b08ef
...@@ -143,6 +143,7 @@ static void rsnd_dma_continue(struct rsnd_dma *dma) ...@@ -143,6 +143,7 @@ static void rsnd_dma_continue(struct rsnd_dma *dma)
void rsnd_dma_start(struct rsnd_dma *dma) void rsnd_dma_start(struct rsnd_dma *dma)
{ {
/* push both A and B plane*/ /* push both A and B plane*/
dma->offset = 0;
dma->submit_loop = 2; dma->submit_loop = 2;
__rsnd_dma_start(dma); __rsnd_dma_start(dma);
} }
...@@ -157,12 +158,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma) ...@@ -157,12 +158,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma)
static void rsnd_dma_complete(void *data) static void rsnd_dma_complete(void *data)
{ {
struct rsnd_dma *dma = (struct rsnd_dma *)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_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
unsigned long flags; unsigned long flags;
rsnd_lock(priv, flags); rsnd_lock(priv, flags);
dma->complete(dma); /*
* Renesas sound Gen1 needs 1 DMAC,
* Gen2 needs 2 DMAC.
* In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
* But, Audio-DMAC-peri-peri doesn't have interrupt,
* and this driver is assuming that here.
*
* If Audio-DMAC-peri-peri has interrpt,
* rsnd_dai_pointer_update() will be called twice,
* ant it will breaks io->byte_pos
*/
rsnd_dai_pointer_update(io, io->byte_per_period);
if (dma->submit_loop) if (dma->submit_loop)
rsnd_dma_continue(dma); rsnd_dma_continue(dma);
...@@ -172,17 +187,21 @@ static void rsnd_dma_complete(void *data) ...@@ -172,17 +187,21 @@ static void rsnd_dma_complete(void *data)
static void __rsnd_dma_start(struct rsnd_dma *dma) static void __rsnd_dma_start(struct rsnd_dma *dma)
{ {
struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(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 device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc;
dma_addr_t buf; dma_addr_t buf;
size_t len; size_t len = io->byte_per_period;
int i; int i;
for (i = 0; i < dma->submit_loop; i++) { for (i = 0; i < dma->submit_loop; i++) {
if (dma->inquiry(dma, &buf, &len) < 0) buf = runtime->dma_addr +
return; rsnd_dai_pointer_offset(io, dma->offset + len);
dma->offset = len;
desc = dmaengine_prep_slave_single( desc = dmaengine_prep_slave_single(
dma->chan, buf, len, dma->dir, dma->chan, buf, len, dma->dir,
...@@ -217,10 +236,7 @@ int rsnd_dma_available(struct rsnd_dma *dma) ...@@ -217,10 +236,7 @@ int rsnd_dma_available(struct rsnd_dma *dma)
} }
int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
int is_play, int id, int is_play, int id)
int (*inquiry)(struct rsnd_dma *dma,
dma_addr_t *buf, int *len),
int (*complete)(struct rsnd_dma *dma))
{ {
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct dma_slave_config cfg; struct dma_slave_config cfg;
...@@ -253,8 +269,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, ...@@ -253,8 +269,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
goto rsnd_dma_init_err; goto rsnd_dma_init_err;
dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
dma->inquiry = inquiry;
dma->complete = complete;
INIT_WORK(&dma->work, rsnd_dma_do_work); INIT_WORK(&dma->work, rsnd_dma_do_work);
return 0; return 0;
...@@ -307,6 +321,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, ...@@ -307,6 +321,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
} }
list_add_tail(&mod->list, &io->head); list_add_tail(&mod->list, &io->head);
mod->io = io;
return 0; return 0;
} }
...@@ -314,6 +329,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, ...@@ -314,6 +329,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
int rsnd_dai_disconnect(struct rsnd_mod *mod) int rsnd_dai_disconnect(struct rsnd_mod *mod)
{ {
list_del_init(&mod->list); list_del_init(&mod->list);
mod->io = NULL;
return 0; return 0;
} }
......
...@@ -100,19 +100,16 @@ struct rsnd_dma { ...@@ -100,19 +100,16 @@ struct rsnd_dma {
struct work_struct work; struct work_struct work;
struct dma_chan *chan; struct dma_chan *chan;
enum dma_data_direction dir; enum dma_data_direction dir;
int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len);
int (*complete)(struct rsnd_dma *dma);
int submit_loop; int submit_loop;
int offset; /* it cares A/B plane */
}; };
void rsnd_dma_start(struct rsnd_dma *dma); void rsnd_dma_start(struct rsnd_dma *dma);
void rsnd_dma_stop(struct rsnd_dma *dma); void rsnd_dma_stop(struct rsnd_dma *dma);
int rsnd_dma_available(struct rsnd_dma *dma); int rsnd_dma_available(struct rsnd_dma *dma);
int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
int is_play, int id, int is_play, int id);
int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len),
int (*complete)(struct rsnd_dma *dma));
void rsnd_dma_quit(struct rsnd_priv *priv, void rsnd_dma_quit(struct rsnd_priv *priv,
struct rsnd_dma *dma); struct rsnd_dma *dma);
...@@ -137,17 +134,20 @@ struct rsnd_mod_ops { ...@@ -137,17 +134,20 @@ struct rsnd_mod_ops {
struct rsnd_dai_stream *io); struct rsnd_dai_stream *io);
}; };
struct rsnd_dai_stream;
struct rsnd_mod { struct rsnd_mod {
int id; int id;
struct rsnd_priv *priv; struct rsnd_priv *priv;
struct rsnd_mod_ops *ops; struct rsnd_mod_ops *ops;
struct list_head list; /* connect to rsnd_dai playback/capture */ struct list_head list; /* connect to rsnd_dai playback/capture */
struct rsnd_dma dma; struct rsnd_dma dma;
struct rsnd_dai_stream *io;
}; };
#define rsnd_mod_to_priv(mod) ((mod)->priv) #define rsnd_mod_to_priv(mod) ((mod)->priv)
#define rsnd_mod_to_dma(mod) (&(mod)->dma) #define rsnd_mod_to_dma(mod) (&(mod)->dma)
#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
#define rsnd_mod_to_io(mod) ((mod)->io)
#define rsnd_mod_id(mod) ((mod)->id) #define rsnd_mod_id(mod) ((mod)->id)
#define for_each_rsnd_mod(pos, n, io) \ #define for_each_rsnd_mod(pos, n, io) \
list_for_each_entry_safe(pos, n, &(io)->head, list) list_for_each_entry_safe(pos, n, &(io)->head, list)
......
...@@ -64,12 +64,10 @@ struct rsnd_ssi { ...@@ -64,12 +64,10 @@ struct rsnd_ssi {
struct rsnd_mod mod; struct rsnd_mod mod;
struct rsnd_dai *rdai; struct rsnd_dai *rdai;
struct rsnd_dai_stream *io;
u32 cr_own; u32 cr_own;
u32 cr_clk; u32 cr_clk;
u32 cr_etc; u32 cr_etc;
int err; int err;
int dma_offset;
unsigned int usrcnt; unsigned int usrcnt;
unsigned int rate; unsigned int rate;
}; };
...@@ -286,7 +284,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, ...@@ -286,7 +284,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
* set ssi parameter * set ssi parameter
*/ */
ssi->rdai = rdai; ssi->rdai = rdai;
ssi->io = io;
ssi->cr_own = cr; ssi->cr_own = cr;
ssi->err = -1; /* ignore 1st error */ ssi->err = -1; /* ignore 1st error */
...@@ -305,7 +302,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod, ...@@ -305,7 +302,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err);
ssi->rdai = NULL; ssi->rdai = NULL;
ssi->io = NULL;
ssi->cr_own = 0; ssi->cr_own = 0;
ssi->err = 0; ssi->err = 0;
...@@ -329,8 +325,9 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) ...@@ -329,8 +325,9 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
{ {
struct rsnd_ssi *ssi = data; struct rsnd_ssi *ssi = data;
struct rsnd_dai_stream *io = ssi->io; struct rsnd_mod *mod = &ssi->mod;
u32 status = rsnd_mod_read(&ssi->mod, SSISR); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
u32 status = rsnd_mod_read(mod, SSISR);
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
if (io && (status & DIRQ)) { if (io && (status & DIRQ)) {
...@@ -347,9 +344,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) ...@@ -347,9 +344,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
* see rsnd_ssi_init() * see rsnd_ssi_init()
*/ */
if (rsnd_dai_is_play(rdai, io)) if (rsnd_dai_is_play(rdai, io))
rsnd_mod_write(&ssi->mod, SSITDR, *buf); rsnd_mod_write(mod, SSITDR, *buf);
else else
*buf = rsnd_mod_read(&ssi->mod, SSIRDR); *buf = rsnd_mod_read(mod, SSIRDR);
rsnd_dai_pointer_update(io, sizeof(*buf)); rsnd_dai_pointer_update(io, sizeof(*buf));
...@@ -394,33 +391,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { ...@@ -394,33 +391,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
.stop = rsnd_ssi_pio_stop, .stop = rsnd_ssi_pio_stop,
}; };
static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len)
{
struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
struct rsnd_dai_stream *io = ssi->io;
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
*len = io->byte_per_period;
*buf = runtime->dma_addr +
rsnd_dai_pointer_offset(io, ssi->dma_offset + *len);
ssi->dma_offset = *len; /* it cares A/B plane */
return 0;
}
static int rsnd_ssi_dma_complete(struct rsnd_dma *dma)
{
struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
struct rsnd_dai_stream *io = ssi->io;
u32 status = rsnd_mod_read(&ssi->mod, SSISR);
rsnd_ssi_record_error(ssi, status);
rsnd_dai_pointer_update(ssi->io, io->byte_per_period);
return 0;
}
static int rsnd_ssi_dma_start(struct rsnd_mod *mod, static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
struct rsnd_dai *rdai, struct rsnd_dai *rdai,
struct rsnd_dai_stream *io) struct rsnd_dai_stream *io)
...@@ -430,7 +400,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, ...@@ -430,7 +400,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
/* enable DMA transfer */ /* enable DMA transfer */
ssi->cr_etc = DMEN; ssi->cr_etc = DMEN;
ssi->dma_offset = 0;
rsnd_dma_start(dma); rsnd_dma_start(dma);
...@@ -452,6 +421,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, ...@@ -452,6 +421,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
ssi->cr_etc = 0; ssi->cr_etc = 0;
rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
rsnd_ssi_hw_stop(ssi, rdai); rsnd_ssi_hw_stop(ssi, rdai);
rsnd_dma_stop(dma); rsnd_dma_stop(dma);
...@@ -585,9 +556,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, ...@@ -585,9 +556,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
ret = rsnd_dma_init( ret = rsnd_dma_init(
priv, rsnd_mod_to_dma(&ssi->mod), priv, rsnd_mod_to_dma(&ssi->mod),
rsnd_ssi_is_play(&ssi->mod), rsnd_ssi_is_play(&ssi->mod),
pinfo->dma_id, pinfo->dma_id);
rsnd_ssi_dma_inquiry,
rsnd_ssi_dma_complete);
if (ret < 0) if (ret < 0)
dev_info(dev, "SSI DMA failed. try PIO transter\n"); dev_info(dev, "SSI DMA failed. try PIO transter\n");
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment