aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h1
-rw-r--r--sound/core/pcm_lib.c14
-rw-r--r--sound/core/pcm_native.c2
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)