aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/azt3328.c
diff options
context:
space:
mode:
authorAndreas Mohr <andi@lisas.de>2010-11-21 06:09:32 -0500
committerTakashi Iwai <tiwai@suse.de>2010-11-22 01:54:45 -0500
commit7974150c8524423f878e8269010e911c3cc7ddb8 (patch)
tree30b7116a13c2bd5b2252273a976c4997ec077829 /sound/pci/azt3328.c
parent86cbbad2b6712fbd25c07a17e86b4345cee82c6d (diff)
ALSA: azt3328: period bug fix (for PA), add missing ACK on stop timer
. Fix PulseAudio "ALSA driver bug" issue (if we have two alternated areas within a 64k DMA buffer, then max period size should obviously be 32k only). Back references: http://pulseaudio.org/wiki/AlsaIssues http://fedoraproject.org/wiki/Features/GlitchFreeAudio . In stop timer function, need to supply ACK in the timer control byte. . Minor log output correction When I did my first PA testing recently, the period size bug resulted in quite precisely observeable half-period-based playback distortion. PA-based operation is quite a bit more underrun-prone (despite its zero-copy optimizations etc.) than raw ALSA with this rather spartan sound hardware implementation on my puny Athlon. Note that even with this patch, azt3328 still doesn't work for both cases yet, PA tsched=0 and tsched (on tsched=0 it will playback tiny fragments of periods, leading to tiny stuttering sounds with some pauses in between, whereas with timer-scheduled operation playback works fine - minus some quite increased underrun trouble on PA vs. ALSA, that is). Signed-off-by: Andreas Mohr <andi@lisas.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/azt3328.c')
-rw-r--r--sound/pci/azt3328.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 4679ed83a43b..2f3cacbd5528 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
1129 1129
1130 count_areas = size/2; 1130 count_areas = size/2;
1131 addr_area2 = addr+count_areas; 1131 addr_area2 = addr+count_areas;
1132 count_areas--; /* max. index */
1133 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", 1132 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n",
1134 addr, count_areas, addr_area2, count_areas); 1133 addr, count_areas, addr_area2, count_areas);
1135 1134
1135 count_areas--; /* max. index */
1136
1136 /* build combined I/O buffer length word */ 1137 /* build combined I/O buffer length word */
1137 lengths = (count_areas << 16) | (count_areas); 1138 lengths = (count_areas << 16) | (count_areas);
1138 spin_lock_irqsave(&chip->reg_lock, flags); 1139 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware =
1740 .rate_max = AZF_FREQ_66200, 1741 .rate_max = AZF_FREQ_66200,
1741 .channels_min = 1, 1742 .channels_min = 1,
1742 .channels_max = 2, 1743 .channels_max = 2,
1743 .buffer_bytes_max = 65536, 1744 .buffer_bytes_max = (64*1024),
1744 .period_bytes_min = 64, 1745 .period_bytes_min = 1024,
1745 .period_bytes_max = 65536, 1746 .period_bytes_max = (32*1024),
1746 .periods_min = 1, 1747 /* We simply have two DMA areas (instead of a list of descriptors
1747 .periods_max = 1024, 1748 such as other cards); I believe that this is a fixed hardware
1749 attribute and there isn't much driver magic to be done to expand it.
1750 Thus indicate that we have at least and at most 2 periods. */
1751 .periods_min = 2,
1752 .periods_max = 2,
1748 /* FIXME: maybe that card actually has a FIFO? 1753 /* FIXME: maybe that card actually has a FIFO?
1749 * Hmm, it seems newer revisions do have one, but we still don't know 1754 * Hmm, it seems newer revisions do have one, but we still don't know
1750 * its size... */ 1755 * its size... */
@@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
1980 chip = snd_timer_chip(timer); 1985 chip = snd_timer_chip(timer);
1981 spin_lock_irqsave(&chip->reg_lock, flags); 1986 spin_lock_irqsave(&chip->reg_lock, flags);
1982 /* disable timer countdown and interrupt */ 1987 /* disable timer countdown and interrupt */
1983 /* FIXME: should we write TIMER_IRQ_ACK here? */ 1988 /* Hmm, should we write TIMER_IRQ_ACK here?
1984 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); 1989 YES indeed, otherwise a rogue timer operation - which prompts
1990 ALSA(?) to call repeated stop() in vain, but NOT start() -
1991 will never end (value 0x03 is kept shown in control byte).
1992 Simply manually poking 0x04 _once_ immediately successfully stops
1993 the hardware/ALSA interrupt activity. */
1994 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
1985 spin_unlock_irqrestore(&chip->reg_lock, flags); 1995 spin_unlock_irqrestore(&chip->reg_lock, flags);
1986 snd_azf3328_dbgcallleave(); 1996 snd_azf3328_dbgcallleave();
1987 return 0; 1997 return 0;