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;
 }
 
        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);
 
                    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)
 
        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;
 };
         * set ssi parameter
         */
        ssi->rdai       = rdai;
-       ssi->io         = io;
        ssi->cr_own     = cr;
        ssi->err        = -1; /* ignore 1st error */
 
                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;
 
 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)) {
                 * 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));
 
        .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)
 
        /* enable DMA transfer */
        ssi->cr_etc = DMEN;
-       ssi->dma_offset = 0;
 
        rsnd_dma_start(dma);
 
 
        ssi->cr_etc = 0;
 
+       rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
+
        rsnd_ssi_hw_stop(ssi, rdai);
 
        rsnd_dma_stop(dma);
                        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