Skip to content

Commit

Permalink
ASoC: rsnd: remove SSI dependent DMAEngine callback
Browse files Browse the repository at this point in the history
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: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
  • Loading branch information
Kuninori Morimoto authored and Mark Brown committed Feb 3, 2014
1 parent 1b7b08e commit 4686a0a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 55 deletions.
38 changes: 27 additions & 11 deletions sound/soc/sh/rcar/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ static void rsnd_dma_continue(struct rsnd_dma *dma)
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);
}
Expand All @@ -157,12 +158,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma)
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);

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)
rsnd_dma_continue(dma);
Expand All @@ -172,17 +187,21 @@ static void rsnd_dma_complete(void *data)

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 dma_async_tx_descriptor *desc;
dma_addr_t buf;
size_t len;
size_t len = io->byte_per_period;
int i;

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

if (dma->inquiry(dma, &buf, &len) < 0)
return;
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,
Expand Down Expand Up @@ -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 is_play, int id,
int (*inquiry)(struct rsnd_dma *dma,
dma_addr_t *buf, int *len),
int (*complete)(struct rsnd_dma *dma))
int is_play, int id)
{
struct device *dev = rsnd_priv_to_dev(priv);
struct dma_slave_config cfg;
Expand Down Expand Up @@ -253,8 +269,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
goto rsnd_dma_init_err;

dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
dma->inquiry = inquiry;
dma->complete = complete;
INIT_WORK(&dma->work, rsnd_dma_do_work);

return 0;
Expand Down Expand Up @@ -307,13 +321,15 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
}

list_add_tail(&mod->list, &io->head);
mod->io = io;

return 0;
}

int rsnd_dai_disconnect(struct rsnd_mod *mod)
{
list_del_init(&mod->list);
mod->io = NULL;

return 0;
}
Expand Down
10 changes: 5 additions & 5 deletions sound/soc/sh/rcar/rsnd.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,16 @@ struct rsnd_dma {
struct work_struct work;
struct dma_chan *chan;
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 offset; /* it cares A/B plane */
};

void rsnd_dma_start(struct rsnd_dma *dma);
void rsnd_dma_stop(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 is_play, int id,
int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len),
int (*complete)(struct rsnd_dma *dma));
int is_play, int id);
void rsnd_dma_quit(struct rsnd_priv *priv,
struct rsnd_dma *dma);

Expand All @@ -137,17 +134,20 @@ struct rsnd_mod_ops {
struct rsnd_dai_stream *io);
};

struct rsnd_dai_stream;
struct rsnd_mod {
int id;
struct rsnd_priv *priv;
struct rsnd_mod_ops *ops;
struct list_head list; /* connect to rsnd_dai playback/capture */
struct rsnd_dma dma;
struct rsnd_dai_stream *io;
};

#define rsnd_mod_to_priv(mod) ((mod)->priv)
#define rsnd_mod_to_dma(mod) (&(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 for_each_rsnd_mod(pos, n, io) \
list_for_each_entry_safe(pos, n, &(io)->head, list)
Expand Down
47 changes: 8 additions & 39 deletions sound/soc/sh/rcar/ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ struct rsnd_ssi {
struct rsnd_mod mod;

struct rsnd_dai *rdai;
struct rsnd_dai_stream *io;
u32 cr_own;
u32 cr_clk;
u32 cr_etc;
int err;
int dma_offset;
unsigned int usrcnt;
unsigned int rate;
};
Expand Down Expand Up @@ -286,7 +284,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
* set ssi parameter
*/
ssi->rdai = rdai;
ssi->io = io;
ssi->cr_own = cr;
ssi->err = -1; /* ignore 1st error */

Expand All @@ -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);

ssi->rdai = NULL;
ssi->io = NULL;
ssi->cr_own = 0;
ssi->err = 0;

Expand All @@ -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)
{
struct rsnd_ssi *ssi = data;
struct rsnd_dai_stream *io = ssi->io;
u32 status = rsnd_mod_read(&ssi->mod, SSISR);
struct rsnd_mod *mod = &ssi->mod;
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
u32 status = rsnd_mod_read(mod, SSISR);
irqreturn_t ret = IRQ_NONE;

if (io && (status & DIRQ)) {
Expand All @@ -347,9 +344,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
* see rsnd_ssi_init()
*/
if (rsnd_dai_is_play(rdai, io))
rsnd_mod_write(&ssi->mod, SSITDR, *buf);
rsnd_mod_write(mod, SSITDR, *buf);
else
*buf = rsnd_mod_read(&ssi->mod, SSIRDR);
*buf = rsnd_mod_read(mod, SSIRDR);

rsnd_dai_pointer_update(io, sizeof(*buf));

Expand Down Expand Up @@ -394,33 +391,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
.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,
struct rsnd_dai *rdai,
struct rsnd_dai_stream *io)
Expand All @@ -430,7 +400,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,

/* enable DMA transfer */
ssi->cr_etc = DMEN;
ssi->dma_offset = 0;

rsnd_dma_start(dma);

Expand All @@ -452,6 +421,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,

ssi->cr_etc = 0;

rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));

rsnd_ssi_hw_stop(ssi, rdai);

rsnd_dma_stop(dma);
Expand Down Expand Up @@ -585,9 +556,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
ret = rsnd_dma_init(
priv, rsnd_mod_to_dma(&ssi->mod),
rsnd_ssi_is_play(&ssi->mod),
pinfo->dma_id,
rsnd_ssi_dma_inquiry,
rsnd_ssi_dma_complete);
pinfo->dma_id);
if (ret < 0)
dev_info(dev, "SSI DMA failed. try PIO transter\n");
else
Expand Down

0 comments on commit 4686a0a

Please sign in to comment.