#include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
 
 #include "tegra_pcm.h"
 
        .fifo_size              = 4,
 };
 
+#if defined(CONFIG_TEGRA_SYSTEM_DMA)
 static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
 {
        struct snd_pcm_substream *substream = prtd->substream;
        .pointer        = tegra_pcm_pointer,
        .mmap           = tegra_pcm_mmap,
 };
+#else
+static int tegra_pcm_open(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct device *dev = rtd->platform->dev;
+       int ret;
+
+       /* Set HW params now that initialization is complete */
+       snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
+
+       ret = snd_dmaengine_pcm_open(substream, NULL, NULL);
+       if (ret) {
+               dev_err(dev, "dmaengine pcm open failed with err %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int tegra_pcm_close(struct snd_pcm_substream *substream)
+{
+       snd_dmaengine_pcm_close(substream);
+       return 0;
+}
+
+static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct device *dev = rtd->platform->dev;
+       struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
+       struct tegra_pcm_dma_params *dmap;
+       struct dma_slave_config slave_config;
+       int ret;
+
+       dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+       ret = snd_hwparams_to_dma_slave_config(substream, params,
+                                               &slave_config);
+       if (ret) {
+               dev_err(dev, "hw params config failed with err %d\n", ret);
+               return ret;
+       }
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+               slave_config.dst_addr = dmap->addr;
+               slave_config.src_maxburst = 0;
+       } else {
+               slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+               slave_config.src_addr = dmap->addr;
+               slave_config.dst_maxburst = 0;
+       }
+       slave_config.slave_id = dmap->req_sel;
+
+       ret = dmaengine_slave_config(chan, &slave_config);
+       if (ret < 0) {
+               dev_err(dev, "dma slave config failed with err %d\n", ret);
+               return ret;
+       }
+
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+       return 0;
+}
+
+static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+       snd_pcm_set_runtime_buffer(substream, NULL);
+       return 0;
+}
+
+static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               return snd_dmaengine_pcm_trigger(substream,
+                                       SNDRV_PCM_TRIGGER_START);
+
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               return snd_dmaengine_pcm_trigger(substream,
+                                       SNDRV_PCM_TRIGGER_STOP);
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
+                               struct vm_area_struct *vma)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+
+       return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+                                       runtime->dma_area,
+                                       runtime->dma_addr,
+                                       runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops tegra_pcm_ops = {
+       .open           = tegra_pcm_open,
+       .close          = tegra_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = tegra_pcm_hw_params,
+       .hw_free        = tegra_pcm_hw_free,
+       .trigger        = tegra_pcm_trigger,
+       .pointer        = snd_dmaengine_pcm_pointer,
+       .mmap           = tegra_pcm_mmap,
+};
+#endif
 
 static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
 {