aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-12-06 11:15:01 -0500
committerTakashi Iwai <tiwai@suse.de>2013-12-06 11:28:49 -0500
commite8648e5e33e45fa2bb8706107eafc8ef42ed0774 (patch)
treeb0d29ff5c211490269ee4b540bea44684332af83
parent4f7f67fb774168a25802919493cdff41c8b9e384 (diff)
ALSA: hda - Ignore small negative LPIB delay correction
Sometimes the hardware reports LPIB being advanced than POSBUF. When this happens, the driver adjusts to a positive value by adding the buffer size. Then the driver detects it as an error (greater than the period size), and stops the LPIB delay account from this point on. When I took a close look at these conditions, the values shown are all very small numbers, and it'd be better to just ignore these values instead of discontinuing the LPIB delay correction. In this patch, the driver checks a negative delay value and ignores if it's a significantly small error. Currently the threshold is set to 64 frames, but could be smaller. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_intel.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 80c5f14e8ecd..af86c71f27bf 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -431,6 +431,8 @@ struct azx_dev {
431 struct timecounter azx_tc; 431 struct timecounter azx_tc;
432 struct cyclecounter azx_cc; 432 struct cyclecounter azx_cc;
433 433
434 int delay_negative_threshold;
435
434#ifdef CONFIG_SND_HDA_DSP_LOADER 436#ifdef CONFIG_SND_HDA_DSP_LOADER
435 struct mutex dsp_mutex; 437 struct mutex dsp_mutex;
436#endif 438#endif
@@ -2195,6 +2197,15 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
2195 goto unlock; 2197 goto unlock;
2196 } 2198 }
2197 2199
2200 /* when LPIB delay correction gives a small negative value,
2201 * we ignore it; currently set the threshold statically to
2202 * 64 frames
2203 */
2204 if (runtime->period_size > 64)
2205 azx_dev->delay_negative_threshold = -frames_to_bytes(runtime, 64);
2206 else
2207 azx_dev->delay_negative_threshold = 0;
2208
2198 /* wallclk has 24Mhz clock source */ 2209 /* wallclk has 24Mhz clock source */
2199 azx_dev->period_wallclk = (((runtime->period_size * 24000) / 2210 azx_dev->period_wallclk = (((runtime->period_size * 24000) /
2200 runtime->rate) * 1000); 2211 runtime->rate) * 1000);
@@ -2447,8 +2458,12 @@ static unsigned int azx_get_position(struct azx *chip,
2447 delay = pos - lpib_pos; 2458 delay = pos - lpib_pos;
2448 else 2459 else
2449 delay = lpib_pos - pos; 2460 delay = lpib_pos - pos;
2450 if (delay < 0) 2461 if (delay < 0) {
2451 delay += azx_dev->bufsize; 2462 if (delay >= azx_dev->delay_negative_threshold)
2463 delay = 0;
2464 else
2465 delay += azx_dev->bufsize;
2466 }
2452 if (delay >= azx_dev->period_bytes) { 2467 if (delay >= azx_dev->period_bytes) {
2453 snd_printk(KERN_WARNING SFX 2468 snd_printk(KERN_WARNING SFX
2454 "%s: Unstable LPIB (%d >= %d); " 2469 "%s: Unstable LPIB (%d >= %d); "