diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2012-09-21 19:39:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-09-22 03:28:10 -0400 |
commit | 172d3b209622785ce7c4f4104319df06d9814b62 (patch) | |
tree | 83584dcecb552bc87b3c628fcdfdc0d240370aed /sound/pci | |
parent | cf55e904516947597d75fd3844acc24891a95772 (diff) |
ALSA: hda - force use of SSYNC bits
SSYNC bits are typically used to start multiple
streams synchronously. It makes sense to use them
for a single stream for a more predictable startup
sequence. The transfers only start once the DMA and
FIFOs are ready. This results in a better correlation
between timestamps and number of samples played.
Credits to Kar Leong Wang for suggesting this
improvement.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 207d0a20f31..f4070a4f39f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1986,14 +1986,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1986 | } | 1986 | } |
1987 | 1987 | ||
1988 | spin_lock(&chip->reg_lock); | 1988 | spin_lock(&chip->reg_lock); |
1989 | if (nsync > 1) { | 1989 | |
1990 | /* first, set SYNC bits of corresponding streams */ | 1990 | /* first, set SYNC bits of corresponding streams */ |
1991 | if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC) | 1991 | if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC) |
1992 | azx_writel(chip, OLD_SSYNC, | 1992 | azx_writel(chip, OLD_SSYNC, |
1993 | azx_readl(chip, OLD_SSYNC) | sbits); | 1993 | azx_readl(chip, OLD_SSYNC) | sbits); |
1994 | else | 1994 | else |
1995 | azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits); | 1995 | azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits); |
1996 | } | 1996 | |
1997 | snd_pcm_group_for_each_entry(s, substream) { | 1997 | snd_pcm_group_for_each_entry(s, substream) { |
1998 | if (s->pcm->card != substream->pcm->card) | 1998 | if (s->pcm->card != substream->pcm->card) |
1999 | continue; | 1999 | continue; |
@@ -2011,8 +2011,6 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
2011 | } | 2011 | } |
2012 | spin_unlock(&chip->reg_lock); | 2012 | spin_unlock(&chip->reg_lock); |
2013 | if (start) { | 2013 | if (start) { |
2014 | if (nsync == 1) | ||
2015 | return 0; | ||
2016 | /* wait until all FIFOs get ready */ | 2014 | /* wait until all FIFOs get ready */ |
2017 | for (timeout = 5000; timeout; timeout--) { | 2015 | for (timeout = 5000; timeout; timeout--) { |
2018 | nwait = 0; | 2016 | nwait = 0; |
@@ -2045,16 +2043,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
2045 | cpu_relax(); | 2043 | cpu_relax(); |
2046 | } | 2044 | } |
2047 | } | 2045 | } |
2048 | if (nsync > 1) { | 2046 | spin_lock(&chip->reg_lock); |
2049 | spin_lock(&chip->reg_lock); | 2047 | /* reset SYNC bits */ |
2050 | /* reset SYNC bits */ | 2048 | if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC) |
2051 | if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC) | 2049 | azx_writel(chip, OLD_SSYNC, |
2052 | azx_writel(chip, OLD_SSYNC, | 2050 | azx_readl(chip, OLD_SSYNC) & ~sbits); |
2053 | azx_readl(chip, OLD_SSYNC) & ~sbits); | 2051 | else |
2054 | else | 2052 | azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits); |
2055 | azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits); | 2053 | spin_unlock(&chip->reg_lock); |
2056 | spin_unlock(&chip->reg_lock); | ||
2057 | } | ||
2058 | return 0; | 2054 | return 0; |
2059 | } | 2055 | } |
2060 | 2056 | ||