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 85f1c6bf8566..dfd9b76b1853 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -278,6 +278,7 @@ struct snd_pcm_runtime { | |||
278 | snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ | 278 | snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ |
279 | snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ | 279 | snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */ |
280 | unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ | 280 | unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ |
281 | unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */ | ||
281 | snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ | 282 | snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ |
282 | 283 | ||
283 | /* -- HW params -- */ | 284 | /* -- HW params -- */ |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index e23e0e7ab26f..a1707cca9c66 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -334,11 +334,15 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
334 | /* delta = "expected next hw_ptr" for in_interrupt != 0 */ | 334 | /* delta = "expected next hw_ptr" for in_interrupt != 0 */ |
335 | delta = runtime->hw_ptr_interrupt + runtime->period_size; | 335 | delta = runtime->hw_ptr_interrupt + runtime->period_size; |
336 | if (delta > new_hw_ptr) { | 336 | if (delta > new_hw_ptr) { |
337 | hw_base += runtime->buffer_size; | 337 | /* check for double acknowledged interrupts */ |
338 | if (hw_base >= runtime->boundary) | 338 | hdelta = jiffies - runtime->hw_ptr_jiffies; |
339 | hw_base = 0; | 339 | if (hdelta > runtime->hw_ptr_buffer_jiffies/2) { |
340 | new_hw_ptr = hw_base + pos; | 340 | hw_base += runtime->buffer_size; |
341 | goto __delta; | 341 | if (hw_base >= runtime->boundary) |
342 | hw_base = 0; | ||
343 | new_hw_ptr = hw_base + pos; | ||
344 | goto __delta; | ||
345 | } | ||
342 | } | 346 | } |
343 | } | 347 | } |
344 | /* new_hw_ptr might be lower than old_hw_ptr in case when */ | 348 | /* 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 134fc6c2e08d..e2e73895db12 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -864,6 +864,8 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) | |||
864 | struct snd_pcm_runtime *runtime = substream->runtime; | 864 | struct snd_pcm_runtime *runtime = substream->runtime; |
865 | snd_pcm_trigger_tstamp(substream); | 865 | snd_pcm_trigger_tstamp(substream); |
866 | runtime->hw_ptr_jiffies = jiffies; | 866 | runtime->hw_ptr_jiffies = jiffies; |
867 | runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) / | ||
868 | runtime->rate; | ||
867 | runtime->status->state = state; | 869 | runtime->status->state = state; |
868 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && | 870 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && |
869 | runtime->silence_size > 0) | 871 | runtime->silence_size > 0) |