ASoC: rsnd: remove SSI dependent DMAEngine callback
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Fri, 24 Jan 2014 02:41:44 +0000 (18:41 -0800)
committerMark Brown <broonie@linaro.org>
Mon, 3 Feb 2014 12:41:38 +0000 (12:41 +0000)
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>
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/ssi.c

index 11eb0e35b9cee303f115e32424725675dbc51393..b5af6f5145ea6716fbfc939cc57f4c4afcad0943 100644 (file)
@@ -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);
 }
@@ -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);
@@ -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,
@@ -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;
@@ -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;
@@ -307,6 +321,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
        }
 
        list_add_tail(&mod->list, &io->head);
+       mod->io = io;
 
        return 0;
 }
@@ -314,6 +329,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
 int rsnd_dai_disconnect(struct rsnd_mod *mod)
 {
        list_del_init(&mod->list);
+       mod->io = NULL;
 
        return 0;
 }
index c397dc8edee533c62c834d8007c714014248809e..b2c717d2ba7ee903be48d55d4b6911980488acd3 100644 (file)
@@ -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);
 
@@ -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)
index b7f464ebcdc0c02ecf9913d61826f4ad12dccb58..d3371d798d54a5693f2228cdc8db7a061c77c2c8 100644 (file)
@@ -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;
 };
@@ -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 */
 
@@ -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;
 
@@ -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)) {
@@ -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));
 
@@ -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)
@@ -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);
 
@@ -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);
@@ -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