diff options
-rw-r--r-- | include/sound/pcm.h | 1 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 14 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 2 |
3 files changed, 12 insertions, 5 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index dd76cdede64..54c4ccf6fec 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -274,6 +274,7 @@ struct snd_pcm_runtime { | |||
274 | snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ | 274 | snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ |
275 | snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ | 275 | snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ |
276 | unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ | 276 | unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ |
277 | unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */ | ||
277 | snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ | 278 | snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ |
278 | 279 | ||
279 | /* -- HW params -- */ | 280 | /* -- HW params -- */ |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index e9d98be190c..d6ecca27bb6 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -329,11 +329,15 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
329 | /* delta = "expected next hw_ptr" for in_interrupt != 0 */ | 329 | /* delta = "expected next hw_ptr" for in_interrupt != 0 */ |
330 | delta = runtime->hw_ptr_interrupt + runtime->period_size; | 330 | delta = runtime->hw_ptr_interrupt + runtime->period_size; |
331 | if (delta > new_hw_ptr) { | 331 | if (delta > new_hw_ptr) { |
332 | hw_base += runtime->buffer_size; | 332 | /* check for double acknowledged interrupts */ |
333 | if (hw_base >= runtime->boundary) | 333 | hdelta = jiffies - runtime->hw_ptr_jiffies; |
334 | hw_base = 0; | 334 | if (hdelta > runtime->hw_ptr_buffer_jiffies/2) { |
335 | new_hw_ptr = hw_base + pos; | 335 | hw_base += runtime->buffer_size; |
336 | goto __delta; | 336 | if (hw_base >= runtime->boundary) |
337 | hw_base = 0; | ||
338 | new_hw_ptr = hw_base + pos; | ||
339 | goto __delta; | ||
340 | } | ||
337 | } | 341 | } |
338 | } | 342 | } |
339 | /* new_hw_ptr might be lower than old_hw_ptr in case when */ | 343 | /* new_hw_ptr might be lower than old_hw_ptr in case when */ |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 303ac04ff6e..2d2e1b65ee9 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -867,6 +867,8 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) | |||
867 | struct snd_pcm_runtime *runtime = substream->runtime; | 867 | struct snd_pcm_runtime *runtime = substream->runtime; |
868 | snd_pcm_trigger_tstamp(substream); | 868 | snd_pcm_trigger_tstamp(substream); |
869 | runtime->hw_ptr_jiffies = jiffies; | 869 | runtime->hw_ptr_jiffies = jiffies; |
870 | runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) / | ||
871 | runtime->rate; | ||
870 | runtime->status->state = state; | 872 | runtime->status->state = state; |
871 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && | 873 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
872 | runtime->silence_size > 0) | 874 | runtime->silence_size > 0) |