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);
}
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);
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,
}
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;
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;
}
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;
}
return -ENOMEM;
}
+ priv->dai_nr = dai_nr;
+ priv->daidrv = drv;
+ priv->rdai = rdai;
+
for (i = 0; i < dai_nr; i++) {
pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1);
cmod ? "capture" : " -- ");
}
- priv->dai_nr = dai_nr;
- priv->daidrv = drv;
- priv->rdai = rdai;
-
return 0;
}
if (ret)
return ret;
- ret = rsnd_scu_probe(pdev, info, priv);
+ ret = rsnd_ssi_probe(pdev, info, priv);
if (ret)
return ret;
- ret = rsnd_adg_probe(pdev, info, priv);
+ ret = rsnd_scu_probe(pdev, info, priv);
if (ret)
return ret;
- ret = rsnd_ssi_probe(pdev, info, priv);
+ ret = rsnd_adg_probe(pdev, info, priv);
if (ret)
return ret;