summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJeeja KP <jeeja.kp@intel.com>2015-12-18 15:12:07 +0530
committerMark Brown <broonie@kernel.org>2016-01-10 12:19:03 +0000
commit748a1d5a3fb75e1102320214a8bde347d7b228c3 (patch)
treec1433d5c6240de76cdde8453038689fdaca3574f /sound
parent1f4956fd96c98e3fbe9a2818014cf36854398db0 (diff)
downloadlinux-748a1d5a3fb75e1102320214a8bde347d7b228c3.tar.bz2
ASoC: Intel: Skylake: Add DMA resume position in Trigger resume/suspend
Use the DMA resume capability to resume the DMA position when stream is suspended/resumed. In suspend we save the position and when stream is resumed the stream needs to be started from the position when the stream was suspended using the new DMA resume capabilities Signed-off-by: Jeeja KP <jeeja.kp@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 8039a0479053..5a532224cb47 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -393,6 +393,15 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
skl_pcm_prepare(substream, dai);
+ /*
+ * enable DMA Resume enable bit for the stream, set the dpib
+ * & lpib position to resune before starting the DMA
+ */
+ snd_hdac_ext_stream_drsm_enable(ebus, true,
+ hdac_stream(stream)->index);
+ snd_hdac_ext_stream_set_dpibr(ebus, stream, stream->dpib);
+ snd_hdac_ext_stream_set_lpib(stream, stream->lpib);
+
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
/*
@@ -421,8 +430,17 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
return ret;
ret = skl_decoupled_trigger(substream, cmd);
- if (cmd == SNDRV_PCM_TRIGGER_SUSPEND)
+ if (cmd == SNDRV_PCM_TRIGGER_SUSPEND) {
+ /* save the dpib and lpib positions */
+ stream->dpib = readl(ebus->bus.remap_addr +
+ AZX_REG_VS_SDXDPIB_XBASE +
+ (AZX_REG_VS_SDXDPIB_XINTERVAL *
+ hdac_stream(stream)->index));
+
+ stream->lpib = snd_hdac_stream_get_pos_lpib(
+ hdac_stream(stream));
snd_hdac_ext_stream_decouple(ebus, stream, false);
+ }
break;
default: