aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/samsung/idma.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
index e45dd90..31fa305 100644
--- a/sound/soc/samsung/idma.c
+++ b/sound/soc/samsung/idma.c
@@ -25,6 +25,7 @@
#include "dma.h"
/*#define ENABLE_REG_LOG*/
+#define ENABLE_TRNCNT_WA
#define ST_RUNNING (1<<0)
#define ST_OPENED (1<<1)
@@ -68,6 +69,9 @@ static struct idma_info {
spinlock_t lock;
void __iomem *regs;
int trigger_stat;
+#ifdef ENABLE_TRNCNT_WA
+ bool trncnt_wa_enabled;
+#endif
} idma;
static void idma_getpos(dma_addr_t *src, struct snd_pcm_substream *substream)
@@ -76,6 +80,14 @@ static void idma_getpos(dma_addr_t *src, struct snd_pcm_substream *substream)
struct idma_ctrl *prtd = runtime->private_data;
*src = prtd->start + (readl(idma.regs + I2STRNCNT) & 0xffffff) * 4;
+
+#ifdef ENABLE_TRNCNT_WA
+ if (idma.trncnt_wa_enabled && (idma.trigger_stat == LPAM_DMA_START)) {
+ *src -= 4;
+ if (*src < prtd->start)
+ *src = prtd->end - 4;
+ }
+#endif
}
static int idma_enqueue(struct snd_pcm_substream *substream)
@@ -503,6 +515,12 @@ void idma_init(void *regs)
{
spin_lock_init(&idma.lock);
idma.regs = regs;
+#if defined(ENABLE_TRNCNT_WA) && defined(CONFIG_ARCH_EXYNOS4)
+ idma.trncnt_wa_enabled = (soc_is_exynos4412() || soc_is_exynos4212()) ?
+ true : false;
+#else
+ idma.trncnt_wa_enabled = false;
+#endif
}
#ifdef CONFIG_SND_SAMSUNG_RP