static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
 {
-       struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
        struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
        struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
+       snd_pcm_uframes_t pointer = 0;
+
+       rsnd_dai_call(pointer, io, &pointer);
 
-       return bytes_to_frames(runtime, io->byte_pos);
+       return pointer;
 }
 
 static struct snd_pcm_ops rsnd_pcm_ops = {
 
 
 struct rsnd_dmaen {
        struct dma_chan         *chan;
+       dma_cookie_t            cookie;
        dma_addr_t              dma_buf;
        unsigned int            dma_len;
        unsigned int            dma_period;
        for (i = 0; i < 2; i++)
                rsnd_dmaen_sync(dmaen, io, i);
 
-       if (dmaengine_submit(desc) < 0) {
+       dmaen->cookie = dmaengine_submit(desc);
+       if (dmaen->cookie < 0) {
                dev_err(dev, "dmaengine_submit() fail\n");
                return -EIO;
        }
        return 0;
 }
 
+static int rsnd_dmaen_pointer(struct rsnd_mod *mod,
+                             struct rsnd_dai_stream *io,
+                             snd_pcm_uframes_t *pointer)
+{
+       struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
+       struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
+       struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
+       struct dma_tx_state state;
+       enum dma_status status;
+       unsigned int pos = 0;
+
+       status = dmaengine_tx_status(dmaen->chan, dmaen->cookie, &state);
+       if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) {
+               if (state.residue > 0 && state.residue <= dmaen->dma_len)
+                       pos = dmaen->dma_len - state.residue;
+       }
+       *pointer = bytes_to_frames(runtime, pos);
+
+       return 0;
+}
+
 static struct rsnd_mod_ops rsnd_dmaen_ops = {
        .name   = "audmac",
        .nolock_start = rsnd_dmaen_nolock_start,
        .nolock_stop  = rsnd_dmaen_nolock_stop,
        .start  = rsnd_dmaen_start,
        .stop   = rsnd_dmaen_stop,
+       .pointer= rsnd_dmaen_pointer,
 };
 
 /*
 
                         struct rsnd_dai_stream *io,
                         struct snd_pcm_substream *substream,
                         struct snd_pcm_hw_params *hw_params);
+       int (*pointer)(struct rsnd_mod *mod,
+                      struct rsnd_dai_stream *io,
+                      snd_pcm_uframes_t *pointer);
        int (*fallback)(struct rsnd_mod *mod,
                        struct rsnd_dai_stream *io,
                        struct rsnd_priv *priv);
  * H   0: pcm_new
  * H   0: fallback
  * H   0: hw_params
+ * H   0: pointer
  */
 #define __rsnd_mod_shift_nolock_start  0
 #define __rsnd_mod_shift_nolock_stop   0
 #define __rsnd_mod_shift_pcm_new       28 /* always called */
 #define __rsnd_mod_shift_fallback      28 /* always called */
 #define __rsnd_mod_shift_hw_params     28 /* always called */
+#define __rsnd_mod_shift_pointer       28 /* always called */
 
 #define __rsnd_mod_add_probe           0
 #define __rsnd_mod_add_remove          0
 #define __rsnd_mod_add_pcm_new         0
 #define __rsnd_mod_add_fallback                0
 #define __rsnd_mod_add_hw_params       0
+#define __rsnd_mod_add_pointer         0
 
 #define __rsnd_mod_call_probe          0
 #define __rsnd_mod_call_remove         0
 #define __rsnd_mod_call_pcm_new                0
 #define __rsnd_mod_call_fallback       0
 #define __rsnd_mod_call_hw_params      0
+#define __rsnd_mod_call_pointer                0
 #define __rsnd_mod_call_nolock_start   0
 #define __rsnd_mod_call_nolock_stop    1
 
 
        return ret;
 }
 
+static int rsnd_ssi_pointer(struct rsnd_mod *mod,
+                           struct rsnd_dai_stream *io,
+                           snd_pcm_uframes_t *pointer)
+{
+       struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
+
+       *pointer = bytes_to_frames(runtime, io->byte_pos);
+
+       return 0;
+}
+
 static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
        .name   = SSI_NAME,
        .probe  = rsnd_ssi_common_probe,
        .start  = rsnd_ssi_start,
        .stop   = rsnd_ssi_stop,
        .irq    = rsnd_ssi_irq,
+       .pointer= rsnd_ssi_pointer,
        .pcm_new = rsnd_ssi_pcm_new,
        .hw_params = rsnd_ssi_hw_params,
 };