#include <linux/pci.h>
 #include <linux/pm_runtime.h>
+#include <linux/delay.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "skl.h"
         * HAD space reflects the actual data that is transferred.
         * Use the position buffer for capture, as DPIB write gets
         * completed earlier than the actual data written to the DDR.
+        *
+        * For capture stream following workaround is required to fix the
+        * incorrect position reporting.
+        *
+        * 1. Wait for 20us before reading the DMA position in buffer once
+        * the interrupt is generated for stream completion as update happens
+        * on the HDA frame boundary i.e. 20.833uSec.
+        * 2. Read DPIB register to flush the DMA position value. This dummy
+        * read is required to flush DMA position value.
+        * 3. Read the DMA Position-in-Buffer. This value now will be equal to
+        * or greater than period boundary.
         */
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
                                (AZX_REG_VS_SDXDPIB_XINTERVAL *
                                hdac_stream(hstream)->index));
-       else
+       } else {
+               udelay(20);
+               readl(ebus->bus.remap_addr +
+                               AZX_REG_VS_SDXDPIB_XBASE +
+                               (AZX_REG_VS_SDXDPIB_XINTERVAL *
+                                hdac_stream(hstream)->index));
                pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
+       }
 
        if (pos >= hdac_stream(hstream)->bufsize)
                pos = 0;