aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.26/1184-workaround-s3c24xx-i2s-stop-live-stream-stall-on-res.patch
blob: b9c892b289c6ca8b88bf810a7103ba25ffde3f40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
From f4dac01cd9cb5b7a33fb336fbf9065dbd7e38efe Mon Sep 17 00:00:00 2001
From: Andy Green <andy@openmoko.com>
Date: Fri, 25 Jul 2008 23:06:15 +0100
Subject: [PATCH] workaround-s3c24xx-i2s-stop-live-stream-stall-on-resume.patch
 Reported-by: Graeme Gregory <graeme@openmoko.org>
 Basically-solved-by: Graeme Gregory <graeme@openmoko.org>

Graeme found a while back that on resume, IISCON register in
s3c2442 does not show LRCK toggling in LRINDEX bit any more,
causing s3c24xx_snd_lrsync() to timeout and return an error,
aborting restart of any live stream that was playing at
suspend.

I confirmed it was true, meddled around for a bit looking
for some magic to restart LRCK or at least the reporting of
it, and in the end worked around it using the method noted
by Graeme: just ignore LRCK sync if it timed out.  The worst
that could happen would be L and R swap for the duration of
stream that was suspended into but probably not even that.

Signed-off-by: Andy Green <andy@openmoko.com>
---
 sound/soc/s3c24xx/s3c24xx-i2s.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 1ed6afd..fce667c 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -180,7 +180,7 @@ static void s3c24xx_snd_rxctrl(int on)
 static int s3c24xx_snd_lrsync(void)
 {
 	u32 iiscon;
-	unsigned long timeout = jiffies + msecs_to_jiffies(5);
+	int timeout = 5; /* 500us, 125 should be enough at 8kHz */
 
 	DBG("Entered %s\n", __func__);
 
@@ -286,11 +286,14 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (!s3c24xx_snd_is_clkmaster()) {
-			ret = s3c24xx_snd_lrsync();
-			if (ret)
-				goto exit_err;
-		}
+		if (!s3c24xx_snd_is_clkmaster())
+			/* we ignore the return code, if it sync'd then fine,
+			 * if it didn't sync, which happens after resume the
+			 * first time when there was a live stream at suspend,
+			 * just let it timeout, the stream picks up OK after
+			 * that and LRCK is evidently working again.
+			 */
+			s3c24xx_snd_lrsync();
 
 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 			s3c24xx_snd_rxctrl(1);
-- 
1.5.6.3