http://linux-sound.bkbits.net/linux-sound
perex@suse.cz|ChangeSet|20050322081729|47043 perex

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/22 13:55:48-08:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/22 13:55:44-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/via82xx.c
#   2005/03/22 13:55:43-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1968.c
#   2005/03/22 13:55:43-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ens1370.c
#   2005/03/22 13:55:43-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2005/03/22 13:55:43-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/22 09:17:29+01:00 perex@suse.cz 
#   [ALSA] Increase buffer sizes for the CA0106 driver
#   
#   CA0106 driver
#   This patch increases the buffer size for the ca0106 driver, so this
#   might help prevent over/underruns.
#   
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ca0106/ca0106_main.c
#   2005/03/21 12:56:50+01:00 perex@suse.cz +6 -4
#   [ALSA] Increase buffer sizes for the CA0106 driver
#   
#   D:2005/03/21 19:56:50
#   C:CA0106 driver
#   F:pci/ca0106/ca0106_main.c:1.4->1.5 
#   L:This patch increases the buffer size for the ca0106 driver, so this
#   L:might help prevent over/underruns.
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:16:48+01:00 perex@suse.cz 
#   [ALSA] Fix 96000 SPDIF out from Audigy 2 P16V
#   
#   EMU10K1/EMU10K2 driver
#   This allows one to output at 96000 to the SPDIF using the P16V chip.
#   Note: The sample phase is wrong when using the P16V chip, but at least
#   no resampling is done.
#   
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/p16v.c
#   2005/03/21 12:52:21+01:00 perex@suse.cz +6 -4
#   [ALSA] Fix 96000 SPDIF out from Audigy 2 P16V
#   
#   D:2005/03/21 19:52:21
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/p16v.c:1.1->1.2 
#   L:This allows one to output at 96000 to the SPDIF using the P16V chip.
#   L:Note: The sample phase is wrong when using the P16V chip, but at least
#   L:no resampling is done.
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:16:05+01:00 perex@suse.cz 
#   [ALSA] emu10k1 external tram size
#   
#   EMU10K1/EMU10K2 driver
#   This patch fixes wrong size reported by driver for external tram. It
#   reports size in bytes and should report it in samples as for internal tram.
#   
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emuproc.c
#   2005/03/21 12:45:01+01:00 perex@suse.cz +1 -1
#   [ALSA] emu10k1 external tram size
#   
#   D:2005/03/21 19:45:01
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emufx.c:1.69->1.70 
#   F:pci/emu10k1/emuproc.c:1.25->1.26 
#   L:This patch fixes wrong size reported by driver for external tram. It
#   L:reports size in bytes and should report it in samples as for internal tram.
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emufx.c
#   2005/03/21 12:45:01+01:00 perex@suse.cz +1 -1
#   [ALSA] emu10k1 external tram size
#   
#   D:2005/03/21 19:45:01
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emufx.c:1.69->1.70 
#   F:pci/emu10k1/emuproc.c:1.25->1.26 
#   L:This patch fixes wrong size reported by driver for external tram. It
#   L:reports size in bytes and should report it in samples as for internal tram.
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:15:23+01:00 perex@suse.cz 
#   [ALSA] use amp capabilities from afg if amp override not set
#   
#   HDA Codec driver
#   Fix by Matt <matt@embeddedalley.com>:
#   
#   Some HDA codec nodes contain an amp, but do not provide local amp
#   capabilities.  In these cases, AC_WCAP_AMP_OVRD is not set so we
#   should query the AFG nid in order to get the general amp capabilities.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/hda_codec.c
#   2005/03/21 12:42:00+01:00 perex@suse.cz +2 -0
#   [ALSA] use amp capabilities from afg if amp override not set
#   
#   D:2005/03/21 19:42:00
#   C:HDA Codec driver
#   F:pci/hda/hda_codec.c:1.8->1.9 
#   L:Fix by Matt <matt@embeddedalley.com>:
#   L:
#   L:Some HDA codec nodes contain an amp, but do not provide local amp
#   L:capabilities.  In these cases, AC_WCAP_AMP_OVRD is not set so we
#   L:should query the AFG nid in order to get the general amp capabilities.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:14:43+01:00 perex@suse.cz 
#   [ALSA] fix bug with pci hotplug mode
#   
#   MIXART driver
#   Fix the Oops with hotplug fw loader.
#   (Theis fix is missing in the last commit to mixart.c accidentally.)
#   
#   Signed-off-by: Markus Bollinger <bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart_hwdep.c
#   2005/03/21 12:36:01+01:00 perex@suse.cz +6 -3
#   [ALSA] fix bug with pci hotplug mode
#   
#   D:2005/03/21 19:36:01
#   C:MIXART driver
#   F:pci/mixart/mixart.h:1.6->1.7 
#   F:pci/mixart/mixart_hwdep.c:1.8->1.9 
#   L:Fix the Oops with hotplug fw loader.
#   L:(Theis fix is missing in the last commit to mixart.c accidentally.)
#   Signed-off-by: Markus Bollinger <bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart.h
#   2005/03/21 12:36:01+01:00 perex@suse.cz +1 -1
#   [ALSA] fix bug with pci hotplug mode
#   
#   D:2005/03/21 19:36:01
#   C:MIXART driver
#   F:pci/mixart/mixart.h:1.6->1.7 
#   F:pci/mixart/mixart_hwdep.c:1.8->1.9 
#   L:Fix the Oops with hotplug fw loader.
#   L:(Theis fix is missing in the last commit to mixart.c accidentally.)
#   Signed-off-by: Markus Bollinger <bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:13:58+01:00 perex@suse.cz 
#   [ALSA] add HPET support
#   
#   Timer Midlevel,ALSA Core
#   add a wrapper for the HPET driver
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/core/timer.c
#   2005/03/21 01:17:26+01:00 perex@suse.cz +5 -3
#   [ALSA] add HPET support
#   
#   D:2005/03/21 08:17:26
#   C:Timer Midlevel,ALSA Core
#   F:core/timer.c:1.67->1.68 
#   F:include/asound.h:1.48->1.49 
#   L:add a wrapper for the HPET driver
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# include/sound/asound.h
#   2005/03/21 01:17:26+01:00 perex@suse.cz +1 -0
#   [ALSA] add HPET support
#   
#   D:2005/03/21 08:17:26
#   C:Timer Midlevel,ALSA Core
#   F:core/timer.c:1.67->1.68 
#   F:include/asound.h:1.48->1.49 
#   L:add a wrapper for the HPET driver
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:13:15+01:00 perex@suse.cz 
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   CS46xx driver,EMU10K1/EMU10K2 driver
#   Now that the output trigger callback is called from a softirq instead
#   of an hardirq, we don't need anymore to disable interrupts in our
#   interrupt handlers.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ens1370.c
#   2005/03/21 01:13:29+01:00 perex@suse.cz +6 -8
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/emu10k1/emumpu401.c
#   2005/03/21 01:13:32+01:00 perex@suse.cz +2 -3
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/emu10k1/emu10k1x.c
#   2005/03/21 01:13:32+01:00 perex@suse.cz +2 -3
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/21 01:13:29+01:00 perex@suse.cz +2 -3
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/cs4281.c
#   2005/03/21 01:13:28+01:00 perex@suse.cz +6 -7
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/drivers/serial-u16550.c
#   2005/03/21 01:13:27+01:00 perex@suse.cz +3 -4
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/drivers/mtpav.c
#   2005/03/21 01:13:27+01:00 perex@suse.cz +2 -3
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/drivers/mpu401/mpu401_uart.c
#   2005/03/21 01:13:28+01:00 perex@suse.cz +4 -6
#   [ALSA] remove unneeded interrupt locks in rawmidi drivers
#   
#   D:2005/03/21 08:13:27
#   C:Generic drivers,MPU401 UART,CS4281 driver,ENS1370/1+ driver
#   C:CS46xx driver,EMU10K1/EMU10K2 driver
#   F:drivers/mtpav.c:1.30->1.31 
#   F:drivers/serial-u16550.c:1.33->1.34 
#   F:drivers/mpu401/mpu401_uart.c:1.35->1.36 
#   F:pci/cs4281.c:1.72->1.73 
#   F:pci/ens1370.c:1.76->1.77 
#   F:pci/cs46xx/cs46xx_lib.c:1.96->1.97 
#   F:pci/emu10k1/emu10k1x.c:1.6->1.7 
#   F:pci/emu10k1/emumpu401.c:1.13->1.14 
#   L:Now that the output trigger callback is called from a softirq instead
#   L:of an hardirq, we don't need anymore to disable interrupts in our
#   L:interrupt handlers.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:12:31+01:00 perex@suse.cz 
#   [ALSA] rawmidi - move output trigger into a tasklet
#   
#   Documentation,RawMidi Midlevel
#   Calling the output trigger callback from another interrupt handler
#   can lead to unintuitive locking requirements (i.e., spin_lock_irqsave)
#   in the sound card interrupt handler.  Moving the call to the callback
#   into a tasklet cures this, and has the added benefit that the callback
#   is called only once if more that one sequencer event has been
#   delivered in one timer interrupt tick.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/core/rawmidi.c
#   2005/03/21 01:06:49+01:00 perex@suse.cz +37 -18
#   [ALSA] rawmidi - move output trigger into a tasklet
#   
#   D:2005/03/21 08:06:48
#   C:Documentation,RawMidi Midlevel
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.50->1.51 
#   F:core/rawmidi.c:1.61->1.62 
#   F:include/rawmidi.h:1.14->1.15 
#   L:Calling the output trigger callback from another interrupt handler
#   L:can lead to unintuitive locking requirements (i.e., spin_lock_irqsave)
#   L:in the sound card interrupt handler.  Moving the call to the callback
#   L:into a tasklet cures this, and has the added benefit that the callback
#   L:is called only once if more that one sequencer event has been
#   L:delivered in one timer interrupt tick.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# include/sound/rawmidi.h
#   2005/03/21 01:06:49+01:00 perex@suse.cz +3 -2
#   [ALSA] rawmidi - move output trigger into a tasklet
#   
#   D:2005/03/21 08:06:48
#   C:Documentation,RawMidi Midlevel
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.50->1.51 
#   F:core/rawmidi.c:1.61->1.62 
#   F:include/rawmidi.h:1.14->1.15 
#   L:Calling the output trigger callback from another interrupt handler
#   L:can lead to unintuitive locking requirements (i.e., spin_lock_irqsave)
#   L:in the sound card interrupt handler.  Moving the call to the callback
#   L:into a tasklet cures this, and has the added benefit that the callback
#   L:is called only once if more that one sequencer event has been
#   L:delivered in one timer interrupt tick.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2005/03/21 01:06:48+01:00 perex@suse.cz +0 -9
#   [ALSA] rawmidi - move output trigger into a tasklet
#   
#   D:2005/03/21 08:06:48
#   C:Documentation,RawMidi Midlevel
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.50->1.51 
#   F:core/rawmidi.c:1.61->1.62 
#   F:include/rawmidi.h:1.14->1.15 
#   L:Calling the output trigger callback from another interrupt handler
#   L:can lead to unintuitive locking requirements (i.e., spin_lock_irqsave)
#   L:in the sound card interrupt handler.  Moving the call to the callback
#   L:into a tasklet cures this, and has the added benefit that the callback
#   L:is called only once if more that one sequencer event has been
#   L:delivered in one timer interrupt tick.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:11:47+01:00 perex@suse.cz 
#   [ALSA] rawmidi - fix locking in drop_output and drain_input
#   
#   RawMidi Midlevel
#   The comments in snd_rawmidi_drop_output and snd_rawmidi_drain_input
#   are wrong -- interrupts _are_ enabled, and spinlocks _are_ required.
#   So remove the comments and add spinlocks.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/core/rawmidi.c
#   2005/03/21 00:56:51+01:00 perex@suse.cz +6 -3
#   [ALSA] rawmidi - fix locking in drop_output and drain_input
#   
#   D:2005/03/21 07:56:51
#   C:RawMidi Midlevel
#   F:core/rawmidi.c:1.60->1.61 
#   L:The comments in snd_rawmidi_drop_output and snd_rawmidi_drain_input
#   L:are wrong -- interrupts _are_ enabled, and spinlocks _are_ required.
#   L:So remove the comments and add spinlocks.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:11:04+01:00 perex@suse.cz 
#   [ALSA] Replace '/' with commas in ac97 codec names
#   
#   AC97 Codec
#   Replaced '/' letters with commas in ac97 codec names, so that
#   they can be used for sysfs entries in ac97_bus.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2005/03/18 09:58:15+01:00 perex@suse.cz +18 -18
#   [ALSA] Replace '/' with commas in ac97 codec names
#   
#   D:2005/03/18 16:58:15
#   C:AC97 Codec
#   F:pci/ac97/ac97_codec.c:1.177->1.178 
#   L:Replaced '/' letters with commas in ac97 codec names, so that
#   L:they can be used for sysfs entries in ac97_bus.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:10:24+01:00 perex@suse.cz 
#   [ALSA] Fix SPDIF output on CMI9880
#   
#   HDA Codec driver
#   There is mute control on 9880's spdif (IEC958) out, so it needs to be
#   turned on/off in mixer.
#   The patch is for CVS version and I think it can be patched to azx too.
#   Hope this also fix the 9880 SPDIF-out bug.
#   
#   Signed-off-by: ChenLi Tien <cltien@cmedia.com.tw>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/hda_codec.c
#   2005/03/18 09:21:56+01:00 perex@suse.cz +3 -0
#   [ALSA] Fix SPDIF output on CMI9880
#   
#   D:2005/03/18 16:21:56
#   C:HDA Codec driver
#   F:pci/hda/hda_codec.c:1.7->1.8 
#   L:There is mute control on 9880's spdif (IEC958) out, so it needs to be
#   L:turned on/off in mixer.
#   L:The patch is for CVS version and I think it can be patched to azx too.
#   L:Hope this also fix the 9880 SPDIF-out bug.
#   Signed-off-by: ChenLi Tien <cltien@cmedia.com.tw>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:09:39+01:00 perex@suse.cz 
#   [ALSA] fix bug with pci hotplug mode
#   
#   MIXART driver
#   There is a bug with mixart driver, when using hotplug:
#   accessing NULL pointer -> segmentation fault
#   
#   Signed-off-by: Markus Bollinger <bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart.c
#   2005/03/18 06:48:22+01:00 perex@suse.cz +3 -3
#   [ALSA] fix bug with pci hotplug mode
#   
#   D:2005/03/18 13:48:22
#   C:MIXART driver
#   F:pci/mixart/mixart.c:1.24->1.25 
#   L:There is a bug with mixart driver, when using hotplug:
#   L:accessing NULL pointer -> segmentation fault
#   Signed-off-by: Markus Bollinger <bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:08:57+01:00 perex@suse.cz 
#   [ALSA] rme32 - remove superfluous spin_lock_irqsave call
#   
#   RME32 driver
#   In the PCM trigger callback, replace spin_lock_irqsave() with
#   spin_lock() because interrupts are already guaranteed to be disabled.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/rme32.c
#   2005/03/18 01:47:00+01:00 perex@suse.cz +2 -3
#   [ALSA] rme32 - remove superfluous spin_lock_irqsave call
#   
#   D:2005/03/18 08:47:00
#   C:RME32 driver
#   F:pci/rme32.c:1.51->1.52 
#   L:In the PCM trigger callback, replace spin_lock_irqsave() with
#   L:spin_lock() because interrupts are already guaranteed to be disabled.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:08:16+01:00 perex@suse.cz 
#   [ALSA] Fix typos
#   
#   ALSA sequencer,ALSA Core
#   Fix typos in alsa-kernel code for MIDI sostenuto.
#   
#   Signed-off-by: William <walsac3c AT orthoset.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_midi_emul.c
#   2005/03/17 09:04:41+01:00 perex@suse.cz +6 -6
#   [ALSA] Fix typos
#   
#   D:2005/03/17 16:04:41
#   C:ALSA sequencer,ALSA Core
#   F:core/seq/seq_midi_emul.c:1.14->1.15 
#   F:include/asoundef.h:1.5->1.6 
#   F:include/seq_midi_emul.h:1.4->1.5 
#   L:Fix typos in alsa-kernel code for MIDI sostenuto.
#   Signed-off-by: William <walsac3c AT orthoset.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/seq_midi_emul.h
#   2005/03/17 09:04:42+01:00 perex@suse.cz +2 -2
#   [ALSA] Fix typos
#   
#   D:2005/03/17 16:04:41
#   C:ALSA sequencer,ALSA Core
#   F:core/seq/seq_midi_emul.c:1.14->1.15 
#   F:include/asoundef.h:1.5->1.6 
#   F:include/seq_midi_emul.h:1.4->1.5 
#   L:Fix typos in alsa-kernel code for MIDI sostenuto.
#   Signed-off-by: William <walsac3c AT orthoset.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/asoundef.h
#   2005/03/17 09:04:41+01:00 perex@suse.cz +1 -1
#   [ALSA] Fix typos
#   
#   D:2005/03/17 16:04:41
#   C:ALSA sequencer,ALSA Core
#   F:core/seq/seq_midi_emul.c:1.14->1.15 
#   F:include/asoundef.h:1.5->1.6 
#   F:include/seq_midi_emul.h:1.4->1.5 
#   L:Fix typos in alsa-kernel code for MIDI sostenuto.
#   Signed-off-by: William <walsac3c AT orthoset.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:07:30+01:00 perex@suse.cz 
#   [ALSA] fix misc oopses
#   
#   EMU10K1/EMU10K2 driver
#   Fix Oops with Multi-channel (EFX) mixer controls.
#   
#   Signed-off-by: Arnaud Patard <apatard@mandrakesoft.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emumixer.c
#   2005/03/17 09:00:43+01:00 perex@suse.cz +18 -8
#   [ALSA] fix misc oopses
#   
#   D:2005/03/17 16:00:43
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emumixer.c:1.32->1.33 
#   L:Fix Oops with Multi-channel (EFX) mixer controls.
#   Signed-off-by: Arnaud Patard <apatard@mandrakesoft.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:06:46+01:00 perex@suse.cz 
#   [ALSA] fix P16V breakage for non Audigy2 cards
#   
#   EMU10K1/EMU10K2 driver
#   The P16V patch unconditionally checks the IPR2 register in the interrupt
#   handler resulting in infinite loop and system lockup on any non Audigy2
#   cards.  I really hate checking emu->is_audigy and emu->revision in a
#   fast path like the IRQ handler but I don't see another way.
#   
#   Also, don't bother allocating/freeing the DMA buffer for P16V unless
#   it's really present.
#   
#   This is a critical fix and should trigger an immediate rc2 release IMO.
#   Currently any emu10k1 users other than Audigy 2 will lock up hard as
#   soon as they play any sound.
#   
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/irq.c
#   2005/03/17 08:55:16+01:00 perex@suse.cz +12 -11
#   [ALSA] fix P16V breakage for non Audigy2 cards
#   
#   D:2005/03/17 15:55:16
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emu10k1.c:1.32->1.33 
#   F:pci/emu10k1/emu10k1_main.c:1.44->1.45 
#   F:pci/emu10k1/irq.c:1.13->1.14 
#   L:The P16V patch unconditionally checks the IPR2 register in the interrupt
#   L:handler resulting in infinite loop and system lockup on any non Audigy2
#   L:cards.  I really hate checking emu->is_audigy and emu->revision in a
#   L:fast path like the IRQ handler but I don't see another way.
#   L:
#   L:Also, don't bother allocating/freeing the DMA buffer for P16V unless
#   L:it's really present.
#   L:
#   L:This is a critical fix and should trigger an immediate rc2 release IMO.
#   L:Currently any emu10k1 users other than Audigy 2 will lock up hard as
#   L:soon as they play any sound.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1_main.c
#   2005/03/17 08:55:16+01:00 perex@suse.cz +2 -1
#   [ALSA] fix P16V breakage for non Audigy2 cards
#   
#   D:2005/03/17 15:55:16
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emu10k1.c:1.32->1.33 
#   F:pci/emu10k1/emu10k1_main.c:1.44->1.45 
#   F:pci/emu10k1/irq.c:1.13->1.14 
#   L:The P16V patch unconditionally checks the IPR2 register in the interrupt
#   L:handler resulting in infinite loop and system lockup on any non Audigy2
#   L:cards.  I really hate checking emu->is_audigy and emu->revision in a
#   L:fast path like the IRQ handler but I don't see another way.
#   L:
#   L:Also, don't bother allocating/freeing the DMA buffer for P16V unless
#   L:it's really present.
#   L:
#   L:This is a critical fix and should trigger an immediate rc2 release IMO.
#   L:Currently any emu10k1 users other than Audigy 2 will lock up hard as
#   L:soon as they play any sound.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1.c
#   2005/03/17 08:55:16+01:00 perex@suse.cz +5 -3
#   [ALSA] fix P16V breakage for non Audigy2 cards
#   
#   D:2005/03/17 15:55:16
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emu10k1.c:1.32->1.33 
#   F:pci/emu10k1/emu10k1_main.c:1.44->1.45 
#   F:pci/emu10k1/irq.c:1.13->1.14 
#   L:The P16V patch unconditionally checks the IPR2 register in the interrupt
#   L:handler resulting in infinite loop and system lockup on any non Audigy2
#   L:cards.  I really hate checking emu->is_audigy and emu->revision in a
#   L:fast path like the IRQ handler but I don't see another way.
#   L:
#   L:Also, don't bother allocating/freeing the DMA buffer for P16V unless
#   L:it's really present.
#   L:
#   L:This is a critical fix and should trigger an immediate rc2 release IMO.
#   L:Currently any emu10k1 users other than Audigy 2 will lock up hard as
#   L:soon as they play any sound.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:06:04+01:00 perex@suse.cz 
#   [ALSA] remove superfluous spin_lock_irqsave calls
#   
#   MPU401 UART,CS4281 driver,ENS1370/1+ driver,CS46xx driver
#   RME HDSP driver
#   In PCM trigger and pointer callbacks, replace spin_lock_irqsave() with
#   spin_lock() because interrupts are already guaranteed to be disabled.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/rme9652/hdsp.c
#   2005/03/17 01:24:39+01:00 perex@suse.cz +3 -4
#   [ALSA] remove superfluous spin_lock_irqsave calls
#   
#   D:2005/03/17 08:24:38
#   C:MPU401 UART,CS4281 driver,ENS1370/1+ driver,CS46xx driver
#   C:RME HDSP driver
#   F:drivers/mpu401/mpu401_uart.c:1.34->1.35 
#   F:pci/cs4281.c:1.71->1.72 
#   F:pci/ens1370.c:1.75->1.76 
#   F:pci/cs46xx/cs46xx_lib.c:1.95->1.96 
#   F:pci/rme9652/hdsp.c:1.84->1.85 
#   L:In PCM trigger and pointer callbacks, replace spin_lock_irqsave() with
#   L:spin_lock() because interrupts are already guaranteed to be disabled.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ens1370.c
#   2005/03/17 01:24:38+01:00 perex@suse.cz +10 -15
#   [ALSA] remove superfluous spin_lock_irqsave calls
#   
#   D:2005/03/17 08:24:38
#   C:MPU401 UART,CS4281 driver,ENS1370/1+ driver,CS46xx driver
#   C:RME HDSP driver
#   F:drivers/mpu401/mpu401_uart.c:1.34->1.35 
#   F:pci/cs4281.c:1.71->1.72 
#   F:pci/ens1370.c:1.75->1.76 
#   F:pci/cs46xx/cs46xx_lib.c:1.95->1.96 
#   F:pci/rme9652/hdsp.c:1.84->1.85 
#   L:In PCM trigger and pointer callbacks, replace spin_lock_irqsave() with
#   L:spin_lock() because interrupts are already guaranteed to be disabled.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/17 01:24:39+01:00 perex@suse.cz +6 -10
#   [ALSA] remove superfluous spin_lock_irqsave calls
#   
#   D:2005/03/17 08:24:38
#   C:MPU401 UART,CS4281 driver,ENS1370/1+ driver,CS46xx driver
#   C:RME HDSP driver
#   F:drivers/mpu401/mpu401_uart.c:1.34->1.35 
#   F:pci/cs4281.c:1.71->1.72 
#   F:pci/ens1370.c:1.75->1.76 
#   F:pci/cs46xx/cs46xx_lib.c:1.95->1.96 
#   F:pci/rme9652/hdsp.c:1.84->1.85 
#   L:In PCM trigger and pointer callbacks, replace spin_lock_irqsave() with
#   L:spin_lock() because interrupts are already guaranteed to be disabled.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/cs4281.c
#   2005/03/17 01:24:38+01:00 perex@suse.cz +3 -4
#   [ALSA] remove superfluous spin_lock_irqsave calls
#   
#   D:2005/03/17 08:24:38
#   C:MPU401 UART,CS4281 driver,ENS1370/1+ driver,CS46xx driver
#   C:RME HDSP driver
#   F:drivers/mpu401/mpu401_uart.c:1.34->1.35 
#   F:pci/cs4281.c:1.71->1.72 
#   F:pci/ens1370.c:1.75->1.76 
#   F:pci/cs46xx/cs46xx_lib.c:1.95->1.96 
#   F:pci/rme9652/hdsp.c:1.84->1.85 
#   L:In PCM trigger and pointer callbacks, replace spin_lock_irqsave() with
#   L:spin_lock() because interrupts are already guaranteed to be disabled.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/drivers/mpu401/mpu401_uart.c
#   2005/03/17 01:24:38+01:00 perex@suse.cz +2 -3
#   [ALSA] remove superfluous spin_lock_irqsave calls
#   
#   D:2005/03/17 08:24:38
#   C:MPU401 UART,CS4281 driver,ENS1370/1+ driver,CS46xx driver
#   C:RME HDSP driver
#   F:drivers/mpu401/mpu401_uart.c:1.34->1.35 
#   F:pci/cs4281.c:1.71->1.72 
#   F:pci/ens1370.c:1.75->1.76 
#   F:pci/cs46xx/cs46xx_lib.c:1.95->1.96 
#   F:pci/rme9652/hdsp.c:1.84->1.85 
#   L:In PCM trigger and pointer callbacks, replace spin_lock_irqsave() with
#   L:spin_lock() because interrupts are already guaranteed to be disabled.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:05:21+01:00 perex@suse.cz 
#   [ALSA] documentation - clarify information about atomic callbacks
#   
#   Documentation
#   Document that the ack callback is atomic, too, and that the atomic
#   callbacks are called with disabled interrupts.  Additionally, clarify
#   the description of the rawmidi trigger callback.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2005/03/17 01:23:31+01:00 perex@suse.cz +20 -5
#   [ALSA] documentation - clarify information about atomic callbacks
#   
#   D:2005/03/17 08:23:31
#   C:Documentation
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.49->1.50 
#   L:Document that the ack callback is atomic, too, and that the atomic
#   L:callbacks are called with disabled interrupts.  Additionally, clarify
#   L:the description of the rawmidi trigger callback.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/22 09:04:37+01:00 perex@suse.cz 
#   [ALSA] Add new C-Media 9880 codec ID
#   
#   HDA Codec driver
#   Following change need to be added for newer C-Media 9880 codec ID.
#   
#   Signed-off-by: ChenLi Tien <cltien@cmedia.com.tw>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/patch_cmedia.c
#   2005/03/16 06:37:09+01:00 perex@suse.cz +1 -0
#   [ALSA] Add new C-Media 9880 codec ID
#   
#   D:2005/03/16 13:37:09
#   C:HDA Codec driver
#   F:pci/hda/hda_codec.c:1.6->1.7 
#   F:pci/hda/patch_cmedia.c:1.4->1.5 
#   L:Following change need to be added for newer C-Media 9880 codec ID.
#   Signed-off-by: ChenLi Tien <cltien@cmedia.com.tw>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/hda_codec.c
#   2005/03/16 06:37:09+01:00 perex@suse.cz +1 -0
#   [ALSA] Add new C-Media 9880 codec ID
#   
#   D:2005/03/16 13:37:09
#   C:HDA Codec driver
#   F:pci/hda/hda_codec.c:1.6->1.7 
#   F:pci/hda/patch_cmedia.c:1.4->1.5 
#   L:Following change need to be added for newer C-Media 9880 codec ID.
#   Signed-off-by: ChenLi Tien <cltien@cmedia.com.tw>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:03:57+01:00 perex@suse.cz 
#   [ALSA] Use full-digital model as default for CMI9880
#   
#   HDA Codec driver
#   Use full-digital model as default for CMI9880 rather than the
#   minimal model.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/patch_cmedia.c
#   2005/03/16 06:35:52+01:00 perex@suse.cz +1 -1
#   [ALSA] Use full-digital model as default for CMI9880
#   
#   D:2005/03/16 13:35:52
#   C:HDA Codec driver
#   F:pci/hda/patch_cmedia.c:1.3->1.4 
#   L:Use full-digital model as default for CMI9880 rather than the
#   L:minimal model.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:03:14+01:00 perex@suse.cz 
#   [ALSA] ak4114 (Juli@) - increased delay between statistics update & rate check
#   
#   AK4114 receiver
#   
#   
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/i2c/other/ak4114.c
#   2005/03/15 09:56:07+01:00 perex@suse.cz +2 -2
#   [ALSA] ak4114 (Juli@) - increased delay between statistics update & rate check
#   
#   D:2005/03/15 16:56:07
#   C:AK4114 receiver
#   F:i2c/other/ak4114.c:1.3->1.4 
#   L:
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2005/03/22 09:02:33+01:00 perex@suse.cz 
#   [ALSA] Wake up polls and signals at timer notification
#   
#   Timer Midlevel
#   Wake up polls and signals at timer notification (TREAD mode only).
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/timer.c
#   2005/03/15 04:33:32+01:00 perex@suse.cz +2 -0
#   [ALSA] Wake up polls and signals at timer notification
#   
#   D:2005/03/15 11:33:32
#   C:Timer Midlevel
#   F:core/timer.c:1.66->1.67 
#   L:Wake up polls and signals at timer notification (TREAD mode only).
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:01:52+01:00 perex@suse.cz 
#   [ALSA] Fix resume of es1968
#   
#   ES1968 driver
#   Fixed the resume of es1968.
#    - restore the running PCM set up properly in resume
#    - ignore spurious hw-vol irqs during resume
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/es1968.c
#   2005/03/15 04:27:27+01:00 perex@suse.cz +19 -0
#   [ALSA] Fix resume of es1968
#   
#   D:2005/03/15 11:27:27
#   C:ES1968 driver
#   F:pci/es1968.c:1.83->1.84 
#   L:Fixed the resume of es1968.
#   L: - restore the running PCM set up properly in resume
#   L: - ignore spurious hw-vol irqs during resume
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:01:11+01:00 perex@suse.cz 
#   [ALSA] Fix Oops with timer notifying
#   
#   Timer Midlevel
#   Fixed Oops with timer notifying after TIMER_TREAD ioctl.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/timer.c
#   2005/03/15 04:25:51+01:00 perex@suse.cz +2 -1
#   [ALSA] Fix Oops with timer notifying
#   
#   D:2005/03/15 11:25:51
#   C:Timer Midlevel
#   F:core/timer.c:1.65->1.66 
#   L:Fixed Oops with timer notifying after TIMER_TREAD ioctl.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 09:00:28+01:00 perex@suse.cz 
#   [ALSA] Fix suspend/resume with ATIIXP
#   
#   ATIIXP driver
#   Fixed the suspend/resume with ATIIXP driver.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/atiixp.c
#   2005/03/14 10:31:52+01:00 perex@suse.cz +17 -1
#   [ALSA] Fix suspend/resume with ATIIXP
#   
#   D:2005/03/14 17:31:52
#   C:ATIIXP driver
#   F:pci/atiixp.c:1.32->1.33 
#   L:Fixed the suspend/resume with ATIIXP driver.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 08:59:49+01:00 perex@suse.cz 
#   [ALSA] Add proper spin/irq locks to suspend
#   
#   PCM Midlevel
#   Add the proper spin/irq locks to PCM suspend functions so that PCM
#   trigger and pointer callbacks can be called safely without irqsave.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm_native.c
#   2005/03/14 10:28:55+01:00 perex@suse.cz +9 -6
#   [ALSA] Add proper spin/irq locks to suspend
#   
#   D:2005/03/14 17:28:55
#   C:PCM Midlevel
#   F:core/pcm_native.c:1.115->1.116 
#   L:Add the proper spin/irq locks to PCM suspend functions so that PCM
#   L:trigger and pointer callbacks can be called safely without irqsave.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 08:59:10+01:00 perex@suse.cz 
#   [ALSA] isa/Kconfig - added SND_AD1848_LIB and SND_CS4231_LIB tristates
#   
#   ISA
#   This patch fixes problem with missing SND_GENERIC_PM for isa cards using
#   ad1848 and cs4231 library modules.
#   
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/isa/Kconfig
#   2005/03/14 02:24:58+01:00 perex@suse.cz +25 -20
#   [ALSA] isa/Kconfig - added SND_AD1848_LIB and SND_CS4231_LIB tristates
#   
#   D:2005/03/14 09:24:58
#   C:ISA
#   F:isa/Kconfig:1.15->1.16 
#   L:This patch fixes problem with missing SND_GENERIC_PM for isa cards using
#   L:ad1848 and cs4231 library modules.
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2005/03/22 08:58:26+01:00 perex@suse.cz 
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   EMU10K1/EMU10K2 driver
#   Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/p16v.h
#   2005/03/22 08:41:41+01:00 perex@suse.cz +299 -0
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/p16v.h
#   2005/03/22 08:41:41+01:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/emu10k1/p16v.h
# 
# sound/pci/emu10k1/irq.c
#   2005/03/13 05:17:10+01:00 perex@suse.cz +16 -2
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/io.c
#   2005/03/13 05:17:09+01:00 perex@suse.cz +32 -0
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emuproc.c
#   2005/03/13 05:17:09+01:00 perex@suse.cz +6 -6
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emumixer.c
#   2005/03/13 05:17:09+01:00 perex@suse.cz +5 -1
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emu10k1_main.c
#   2005/03/13 05:17:08+01:00 perex@suse.cz +11 -6
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emu10k1.c
#   2005/03/13 05:17:08+01:00 perex@suse.cz +14 -3
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/Makefile
#   2005/03/13 05:17:08+01:00 perex@suse.cz +1 -1
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# include/sound/emu10k1.h
#   2005/03/13 05:17:08+01:00 perex@suse.cz +51 -0
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/p16v.c
#   2005/03/22 08:41:37+01:00 perex@suse.cz +734 -0
#   [ALSA] emu10k1 - add support for p16v chip (24-bit playback)
#   
#   D:2005/03/13 12:17:08
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.58->1.59 
#   F:pci/emu10k1/Makefile:1.12->1.13 
#   F:pci/emu10k1/emu10k1.c:1.31->1.32 
#   F:pci/emu10k1/emu10k1_main.c:1.43->1.44 
#   F:pci/emu10k1/emumixer.c:1.31->1.32 
#   F:pci/emu10k1/emuproc.c:1.24->1.25 
#   F:pci/emu10k1/io.c:1.9->1.10 
#   F:pci/emu10k1/irq.c:1.12->1.13 
#   F:pci/emu10k1/p16v.c:INITIAL->1.1 
#   F:pci/emu10k1/p16v.h:INITIAL->1.1 
#   L:Add 24bit, 96khz support for multichannel playback on the Audigy 2 sound cards.
#   Signed-off-by: James Courtier-Dutton <James@superbug.demon.co.uk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/p16v.c
#   2005/03/22 08:41:37+01:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/emu10k1/p16v.c
# 
# ChangeSet
#   2005/03/22 08:57:43+01:00 perex@suse.cz 
#   [ALSA] emu10k1 - copyright additions/fixes
#   
#   EMU10K1/EMU10K2 driver
#   The next two patches add my copyright for adding the multichannel PCM
#   support to emupcm.c and emumixer.c.
#   
#   The final patch adds Clemens Ladisch to the copyright on timer.c, rather
#   than just saying 'Copied from similar code by CL'.  This has been
#   bugging me for a while, since I just copied and pasted from the ymfpci
#   driver & changed the registers.
#   
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/timer.c
#   2005/03/13 01:55:50+01:00 perex@suse.cz +1 -3
#   [ALSA] emu10k1 - copyright additions/fixes
#   
#   D:2005/03/13 08:55:49
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emumixer.c:1.30->1.31 
#   F:pci/emu10k1/emupcm.c:1.44->1.45 
#   F:pci/emu10k1/timer.c:1.1->1.2 
#   L:The next two patches add my copyright for adding the multichannel PCM
#   L:support to emupcm.c and emumixer.c.
#   L:
#   L:The final patch adds Clemens Ladisch to the copyright on timer.c, rather
#   L:than just saying 'Copied from similar code by CL'.  This has been
#   L:bugging me for a while, since I just copied and pasted from the ymfpci
#   L:driver & changed the registers.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emupcm.c
#   2005/03/13 01:55:50+01:00 perex@suse.cz +1 -0
#   [ALSA] emu10k1 - copyright additions/fixes
#   
#   D:2005/03/13 08:55:49
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emumixer.c:1.30->1.31 
#   F:pci/emu10k1/emupcm.c:1.44->1.45 
#   F:pci/emu10k1/timer.c:1.1->1.2 
#   L:The next two patches add my copyright for adding the multichannel PCM
#   L:support to emupcm.c and emumixer.c.
#   L:
#   L:The final patch adds Clemens Ladisch to the copyright on timer.c, rather
#   L:than just saying 'Copied from similar code by CL'.  This has been
#   L:bugging me for a while, since I just copied and pasted from the ymfpci
#   L:driver & changed the registers.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emumixer.c
#   2005/03/13 01:55:49+01:00 perex@suse.cz +1 -0
#   [ALSA] emu10k1 - copyright additions/fixes
#   
#   D:2005/03/13 08:55:49
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emumixer.c:1.30->1.31 
#   F:pci/emu10k1/emupcm.c:1.44->1.45 
#   F:pci/emu10k1/timer.c:1.1->1.2 
#   L:The next two patches add my copyright for adding the multichannel PCM
#   L:support to emupcm.c and emumixer.c.
#   L:
#   L:The final patch adds Clemens Ladisch to the copyright on timer.c, rather
#   L:than just saying 'Copied from similar code by CL'.  This has been
#   L:bugging me for a while, since I just copied and pasted from the ymfpci
#   L:driver & changed the registers.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2005/03/22 08:57:02+01:00 perex@suse.cz 
#   [ALSA] emu10k1 - Silence the 'BUG (or not enough voices)' message
#   
#   EMU10K1/EMU10K2 driver
#   Silence the 'BUG (or not enough voices)' message. This does not in fact
#   represent a bug; it's a normal ocurrence when the wavetable synth is in use.
#   
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/voice.c
#   2005/03/13 01:53:53+01:00 perex@suse.cz +1 -5
#   [ALSA] emu10k1 - Silence the 'BUG (or not enough voices)' message
#   
#   D:2005/03/13 08:53:53
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/voice.c:1.7->1.8 
#   L:Silence the 'BUG (or not enough voices)' message. This does not in fact
#   L:represent a bug; it's a normal ocurrence when the wavetable synth is in use.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2005/03/22 08:56:19+01:00 perex@suse.cz 
#   [ALSA] emu10k1 - give the subdevices descriptive names
#   
#   EMU10K1/EMU10K2 driver
#   Give the subdevices descriptive names, like 'ADC Capture/Standard PCM Playback' instead of 'EMU10K1' for
#   hw:x,0 and 'Multichannel Capture/PT Playback' instead of 'EMU10K1 EFX'
#   for hw:x,2.  Now that qjackctl enumerates the devices automatically,
#   this is a significant usability improvement.
#   
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/emu10k1/emupcm.c
#   2005/03/13 01:52:26+01:00 perex@suse.cz +4 -4
#   [ALSA] emu10k1 - give the subdevices descriptive names
#   
#   D:2005/03/13 08:52:26
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emupcm.c:1.43->1.44 
#   L:Give the subdevices descriptive names, like 'ADC Capture/Standard PCM Playback' instead of 'EMU10K1' for
#   L:hw:x,0 and 'Multichannel Capture/PT Playback' instead of 'EMU10K1 EFX'
#   L:for hw:x,2.  Now that qjackctl enumerates the devices automatically,
#   L:this is a significant usability improvement.
#   Signed-off-by: Lee Revell <rlrevell@joe-job.com>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2005/03/22 08:55:39+01:00 perex@suse.cz 
#   [ALSA] Fix voice allocation corruption
#   
#   EMU10K1/EMU10K2 driver
#   Fixed the corrupted voice allocation in snd_emu10k1_pcm_channel_alloc().
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emupcm.c
#   2005/03/11 09:32:21+01:00 perex@suse.cz +11 -8
#   [ALSA] Fix voice allocation corruption
#   
#   D:2005/03/11 16:32:21
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emupcm.c:1.42->1.43 
#   L:Fixed the corrupted voice allocation in snd_emu10k1_pcm_channel_alloc().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 08:54:56+01:00 perex@suse.cz 
#   [ALSA] Add DXS support for MSI K8T Neo2-FI
#   
#   VIA82xx driver
#   Added the DXS entry for MSI K8T Neo2-FI.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2005/03/11 09:21:55+01:00 perex@suse.cz +1 -0
#   [ALSA] Add DXS support for MSI K8T Neo2-FI
#   
#   D:2005/03/11 16:21:55
#   C:VIA82xx driver
#   F:pci/via82xx.c:1.137->1.138 
#   L:Added the DXS entry for MSI K8T Neo2-FI.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/22 08:54:10+01:00 perex@suse.cz 
#   [ALSA] Fix ALC655/658/850 SPDIF playback route
#   
#   AC97 Codec
#   Fix ALC655/658/850 IEC958 (SPDIF) playback route control.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_patch.c
#   2005/03/11 09:20:18+01:00 perex@suse.cz +1 -1
#   [ALSA] Fix ALC655/658/850 SPDIF playback route
#   
#   D:2005/03/11 16:20:18
#   C:AC97 Codec
#   F:pci/ac97/ac97_patch.c:1.76->1.77 
#   L:Fix ALC655/658/850 IEC958 (SPDIF) playback route control.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/11 13:04:09-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/ymfpci/ymfpci_main.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/via82xx.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/trident/trident_main.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1968.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1938.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ens1370.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cmipci.c
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/sound/ymfpci.h
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/sound/trident.h
#   2005/03/11 13:04:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/10 13:12:17-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/ymfpci/ymfpci_main.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/via82xx.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/trident/trident_main.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1968.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1938.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ens1370.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cmipci.c
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/sound/ymfpci.h
#   2005/03/10 13:12:12-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/sound/trident.h
#   2005/03/10 13:12:11-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/10 12:19:01-08:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/usb/usbmixer.c
#   2005/03/10 12:18:57-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/08 23:46:28-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/usb/usbmixer.c
#   2005/03/08 23:46:23-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2005-03-23 19:29:42 -08:00
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2005-03-23 19:29:42 -08:00
@@ -3011,6 +3011,9 @@
 	current appl_ptr for the internal buffer, and this callback
 	is useful only for such a purpose.
 	</para>
+	<para>
+	  This callback is atomic.
+	</para>
       </section>
 
       <section id="pcm-interface-operators-page-callback">
@@ -3208,6 +3211,11 @@
       <function>udelay()</function> or <function>mdelay()</function>.
       </para>
 
+      <para>
+      All three atomic callbacks (trigger, pointer, and ack) are
+      called with local interrupts disabled.
+      </para>
+
     </section>
     <section id="pcm-interface-constraints">
       <title>Constraints</title>
@@ -4596,14 +4604,6 @@
         zero <parameter>up</parameter> parameter when the transmission
         of data should be aborted.
         </para>
-
-        <para>
-        The <function>trigger</function> callback may be called from
-        another hardware interrupt handler.  This means that all
-        spinlocks taken in the <function>trigger</function> callback
-        must be taken with <function>spin_lock_irqsave</function>
-        everywhere.
-        </para>
       </section>
 
       <section id="rawmidi-interface-op-trigger-in">
@@ -4622,6 +4622,12 @@
         This is called with a nonzero <parameter>up</parameter>
         parameter to enable receiving data, or with a zero
         <parameter>up</parameter> parameter do disable receiving data.
+        </para>
+
+        <para>
+        The <function>trigger</function> callback must not sleep; the
+        actual reading of data from the device is usually done in an
+        interrupt handler.
         </para>
 
         <para>
diff -Nru a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h	2005-03-23 19:29:42 -08:00
+++ b/include/sound/asound.h	2005-03-23 19:29:42 -08:00
@@ -582,6 +582,7 @@
 /* global timers (device member) */
 #define SNDRV_TIMER_GLOBAL_SYSTEM	0
 #define SNDRV_TIMER_GLOBAL_RTC		1
+#define SNDRV_TIMER_GLOBAL_HPET		2
 
 /* info flags */
 #define SNDRV_TIMER_FLG_SLAVE		(1<<0)	/* cannot be controlled */
diff -Nru a/include/sound/asoundef.h b/include/sound/asoundef.h
--- a/include/sound/asoundef.h	2005-03-23 19:29:42 -08:00
+++ b/include/sound/asoundef.h	2005-03-23 19:29:42 -08:00
@@ -185,7 +185,7 @@
 #define MIDI_CTL_LSB_GENERAL_PURPOSE4 	0x33
 #define MIDI_CTL_SUSTAIN              	0x40
 #define MIDI_CTL_PORTAMENTO           	0x41
-#define MIDI_CTL_SUSTENUTO            	0x42
+#define MIDI_CTL_SOSTENUTO            	0x42
 #define MIDI_CTL_SOFT_PEDAL           	0x43
 #define MIDI_CTL_LEGATO_FOOTSWITCH	0x44
 #define MIDI_CTL_HOLD2                	0x45
diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	2005-03-23 19:29:42 -08:00
+++ b/include/sound/emu10k1.h	2005-03-23 19:29:42 -08:00
@@ -280,6 +280,46 @@
 #define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
 #define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
 
+/* Available on the Audigy 2 and Audigy 4 only. This is the P16V chip. */
+#define PTR2			0x20		/* Indexed register set pointer register	*/
+#define DATA2			0x24		/* Indexed register set data register		*/
+#define IPR2			0x28		/* P16V interrupt pending register		*/
+#define IPR2_PLAYBACK_CH_0_LOOP      0x00001000 /* Playback Channel 0 loop                               */
+#define IPR2_PLAYBACK_CH_0_HALF_LOOP 0x00000100 /* Playback Channel 0 half loop                          */
+#define IPR2_CAPTURE_CH_0_LOOP       0x00100000 /* Capture Channel 0 loop                               */
+#define IPR2_CAPTURE_CH_0_HALF_LOOP  0x00010000 /* Capture Channel 0 half loop                          */
+						/* 0x00000100 Playback. Only in once per period.
+						 * 0x00110000 Capture. Int on half buffer.
+						 */
+#define INTE2			0x2c		/* P16V Interrupt enable register. 	*/
+#define INTE2_PLAYBACK_CH_0_LOOP      0x00001000 /* Playback Channel 0 loop                               */
+#define INTE2_PLAYBACK_CH_0_HALF_LOOP 0x00000100 /* Playback Channel 0 half loop                          */
+#define INTE2_PLAYBACK_CH_1_LOOP      0x00002000 /* Playback Channel 1 loop                               */
+#define INTE2_PLAYBACK_CH_1_HALF_LOOP 0x00000200 /* Playback Channel 1 half loop                          */
+#define INTE2_PLAYBACK_CH_2_LOOP      0x00004000 /* Playback Channel 2 loop                               */
+#define INTE2_PLAYBACK_CH_2_HALF_LOOP 0x00000400 /* Playback Channel 2 half loop                          */
+#define INTE2_PLAYBACK_CH_3_LOOP      0x00008000 /* Playback Channel 3 loop                               */
+#define INTE2_PLAYBACK_CH_3_HALF_LOOP 0x00000800 /* Playback Channel 3 half loop                          */
+#define INTE2_CAPTURE_CH_0_LOOP       0x00100000 /* Capture Channel 0 loop                               */
+#define INTE2_CAPTURE_CH_0_HALF_LOOP  0x00010000 /* Caputre Channel 0 half loop                          */
+#define HCFG2			0x34		/* Defaults: 0, win2000 sets it to 00004201 */
+						/* 0x00000000 2-channel output. */
+						/* 0x00000200 8-channel output. */
+						/* 0x00000004 pauses stream/irq fail. */
+						/* Rest of bits no nothing to sound output */
+						/* bit 0: Enable P16V audio.
+						 * bit 1: Lock P16V record memory cache.
+						 * bit 2: Lock P16V playback memory cache.
+						 * bit 3: Dummy record insert zero samples.
+						 * bit 8: Record 8-channel in phase.
+						 * bit 9: Playback 8-channel in phase.
+						 * bit 11-12: Playback mixer attenuation: 0=0dB, 1=-6dB, 2=-12dB, 3=Mute.
+						 * bit 13: Playback mixer enable.
+						 * bit 14: Route SRC48 mixer output to fx engine.
+						 * bit 15: Enable IEEE 1394 chip.
+						 */
+#define IPR3			0x38		/* Cdif interrupt pending register		*/
+#define INTE3			0x3c		/* Cdif interrupt enable register. 	*/
 /************************************************************************************************/
 /* PCI function 1 registers, address = <val> + PCIBASE1						*/
 /************************************************************************************************/
@@ -1014,6 +1054,9 @@
 	int max_cache_pages;			/* max memory size / PAGE_SIZE */
 	struct snd_dma_buffer silent_page;	/* silent page */
 	struct snd_dma_buffer ptb_pages;	/* page table pages */
+	struct snd_dma_device p16v_dma_dev;
+	struct snd_dma_buffer p16v_buffer;
+
 	snd_util_memhdr_t *memhdr;		/* page allocation list */
 	emu10k1_memblk_t *reserved_page;	/* reserved page */
 
@@ -1035,6 +1078,7 @@
 	snd_pcm_t *pcm;
 	snd_pcm_t *pcm_mic;
 	snd_pcm_t *pcm_efx;
+	snd_pcm_t *pcm_p16v;
 
 	spinlock_t synth_lock;
 	void *synth;
@@ -1046,6 +1090,8 @@
 	struct semaphore ptb_lock;
 
 	emu10k1_voice_t voices[NUM_G];
+	emu10k1_voice_t p16v_voices[4];
+	int p16v_device_offset;
 	emu10k1_pcm_mixer_t pcm_mixer[32];
 	emu10k1_pcm_mixer_t efx_pcm_mixer[NUM_EFX_PLAYBACK];
 	snd_kcontrol_t *ctl_send_routing;
@@ -1087,6 +1133,9 @@
 int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_p16v_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_p16v_free(emu10k1_t * emu);
+int snd_p16v_mixer(emu10k1_t * emu);
 int snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
 int snd_emu10k1_mixer(emu10k1_t * emu);
@@ -1104,6 +1153,8 @@
 /* I/O functions */
 unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
 void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
+unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr20_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
 void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
 void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
diff -Nru a/include/sound/rawmidi.h b/include/sound/rawmidi.h
--- a/include/sound/rawmidi.h	2005-03-23 19:29:42 -08:00
+++ b/include/sound/rawmidi.h	2005-03-23 19:29:42 -08:00
@@ -79,9 +79,10 @@
 	/* misc */
 	spinlock_t lock;
 	wait_queue_head_t sleep;
-	/* event handler (room [output] or new bytes [input]) */
-	struct tasklet_struct event_tasklet;
+	/* event handler (new bytes, input only) */
 	void (*event)(snd_rawmidi_substream_t *substream);
+	/* defers calls to event [input] or ops->trigger [output] */
+	struct tasklet_struct tasklet;
 	/* private data */
 	void *private_data;
 	void (*private_free)(snd_rawmidi_substream_t *substream);
diff -Nru a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
--- a/include/sound/seq_midi_emul.h	2005-03-23 19:29:42 -08:00
+++ b/include/sound/seq_midi_emul.h	2005-03-23 19:29:42 -08:00
@@ -136,7 +136,7 @@
 #define gm_sustain	 	control[MIDI_CTL_SUSTAIN]
 #define gm_hold			gm_sustain
 #define gm_portamento		control[MIDI_CTL_PORTAMENTO]
-#define gm_sustenuto		control[MIDI_CTL_SUSTENUTO]
+#define gm_sostenuto		control[MIDI_CTL_SOSTENUTO]
 
 /*
  * These macros give the complete value of the controls that consist
@@ -166,7 +166,7 @@
 #define SNDRV_MIDI_NOTE_OFF		0x00
 #define SNDRV_MIDI_NOTE_ON		0x01
 #define SNDRV_MIDI_NOTE_RELEASED		0x02
-#define SNDRV_MIDI_NOTE_SUSTENUTO		0x04
+#define SNDRV_MIDI_NOTE_SOSTENUTO		0x04
  
 #define SNDRV_MIDI_PARAM_TYPE_REGISTERED		0
 #define SNDRV_MIDI_PARAM_TYPE_NONREGISTERED	1
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c	2005-03-23 19:29:42 -08:00
+++ b/sound/core/pcm_native.c	2005-03-23 19:29:42 -08:00
@@ -1038,7 +1038,13 @@
  */
 int snd_pcm_suspend(snd_pcm_substream_t *substream)
 {
-	return snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
+	int err;
+	unsigned long flags;
+
+	snd_pcm_stream_lock_irqsave(substream, flags);
+	err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
+	snd_pcm_stream_unlock_irqrestore(substream, flags);
+	return err;
 }
 
 /**
@@ -1057,11 +1063,8 @@
 			/* FIXME: the open/close code should lock this as well */
 			if (substream->runtime == NULL)
 				continue;
-			snd_pcm_stream_lock(substream);
-			if (substream->runtime->status->state != SNDRV_PCM_STATE_SUSPENDED)
-				err = snd_pcm_suspend(substream);
-			snd_pcm_stream_unlock(substream);
-			if (err < 0)
+			err = snd_pcm_suspend(substream);
+			if (err < 0 && err != -EBUSY)
 				return err;
 		}
 	}
diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c
--- a/sound/core/rawmidi.c	2005-03-23 19:29:42 -08:00
+++ b/sound/core/rawmidi.c	2005-03-23 19:29:42 -08:00
@@ -85,12 +85,18 @@
 	       (!substream->append || runtime->avail >= count);
 }
 
-static void snd_rawmidi_event_tasklet(unsigned long data)
+static void snd_rawmidi_input_event_tasklet(unsigned long data)
 {
 	snd_rawmidi_substream_t *substream = (snd_rawmidi_substream_t *)data;
 	substream->runtime->event(substream);
 }
 
+static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
+{
+	snd_rawmidi_substream_t *substream = (snd_rawmidi_substream_t *)data;
+	substream->ops->trigger(substream, 1);
+}
+
 static int snd_rawmidi_runtime_create(snd_rawmidi_substream_t * substream)
 {
 	snd_rawmidi_runtime_t *runtime;
@@ -99,8 +105,14 @@
 		return -ENOMEM;
 	spin_lock_init(&runtime->lock);
 	init_waitqueue_head(&runtime->sleep);
-	tasklet_init(&runtime->event_tasklet, snd_rawmidi_event_tasklet,
-		     (unsigned long)substream);
+	if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
+		tasklet_init(&runtime->tasklet,
+			     snd_rawmidi_input_event_tasklet,
+			     (unsigned long)substream);
+	else
+		tasklet_init(&runtime->tasklet,
+			     snd_rawmidi_output_trigger_tasklet,
+			     (unsigned long)substream);
 	runtime->event = NULL;
 	runtime->buffer_size = PAGE_SIZE;
 	runtime->avail_min = 1;
@@ -127,23 +139,34 @@
 	return 0;
 }
 
-static void snd_rawmidi_trigger(snd_rawmidi_substream_t * substream, int up)
+static inline void snd_rawmidi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	if (up) {
+		tasklet_hi_schedule(&substream->runtime->tasklet);
+	} else {
+		tasklet_kill(&substream->runtime->tasklet);
+		substream->ops->trigger(substream, 0);
+	}
+}
+
+static void snd_rawmidi_input_trigger(snd_rawmidi_substream_t * substream, int up)
 {
 	substream->ops->trigger(substream, up);
 	if (!up && substream->runtime->event)
-		tasklet_kill(&substream->runtime->event_tasklet);
+		tasklet_kill(&substream->runtime->tasklet);
 }
 
 int snd_rawmidi_drop_output(snd_rawmidi_substream_t * substream)
 {
+	unsigned long flags;
 	snd_rawmidi_runtime_t *runtime = substream->runtime;
 
-	snd_rawmidi_trigger(substream, 0);
+	snd_rawmidi_output_trigger(substream, 0);
 	runtime->drain = 0;
-	/* interrupts are not enabled at this moment,
-	   so spinlock is not required */
+	spin_lock_irqsave(&runtime->lock, flags);
 	runtime->appl_ptr = runtime->hw_ptr = 0;
 	runtime->avail = runtime->buffer_size;
+	spin_unlock_irqrestore(&runtime->lock, flags);
 	return 0;
 }
 
@@ -178,13 +201,15 @@
 
 int snd_rawmidi_drain_input(snd_rawmidi_substream_t * substream)
 {
+	unsigned long flags;
 	snd_rawmidi_runtime_t *runtime = substream->runtime;
 
-	snd_rawmidi_trigger(substream, 0);
+	snd_rawmidi_input_trigger(substream, 0);
 	runtime->drain = 0;
-	/* interrupts aren't enabled at this moment, so spinlock isn't needed */
+	spin_lock_irqsave(&runtime->lock, flags);
 	runtime->appl_ptr = runtime->hw_ptr = 0;
 	runtime->avail = 0;
+	spin_unlock_irqrestore(&runtime->lock, flags);
 	return 0;
 }
 
@@ -458,7 +483,7 @@
 		substream = rfile->input;
 		rfile->input = NULL;
 		runtime = substream->runtime;
-		snd_rawmidi_trigger(substream, 0);
+		snd_rawmidi_input_trigger(substream, 0);
 		substream->ops->close(substream);
 		if (runtime->private_free != NULL)
 			runtime->private_free(substream);
@@ -477,7 +502,7 @@
 				snd_rawmidi_kernel_write(substream, &buf, 1);
 			}
 			if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS)
-				snd_rawmidi_trigger(substream, 0);
+				snd_rawmidi_output_trigger(substream, 0);
 			substream->ops->close(substream);
 			if (runtime->private_free != NULL)
 				runtime->private_free(substream);
@@ -875,7 +900,7 @@
 	}
 	if (result > 0) {
 		if (runtime->event)
-			tasklet_hi_schedule(&runtime->event_tasklet);
+			tasklet_hi_schedule(&runtime->tasklet);
 		else if (snd_rawmidi_ready(substream))
 			wake_up(&runtime->sleep);
 	}
@@ -919,7 +944,7 @@
 
 long snd_rawmidi_kernel_read(snd_rawmidi_substream_t *substream, unsigned char *buf, long count)
 {
-	snd_rawmidi_trigger(substream, 1);
+	snd_rawmidi_input_trigger(substream, 1);
 	return snd_rawmidi_kernel_read1(substream, buf, count, 1);
 }
 
@@ -936,7 +961,7 @@
 	if (substream == NULL)
 		return -EIO;
 	runtime = substream->runtime;
-	snd_rawmidi_trigger(substream, 1);
+	snd_rawmidi_input_trigger(substream, 1);
 	result = 0;
 	while (count > 0) {
 		spin_lock_irq(&runtime->lock);
@@ -1072,11 +1097,8 @@
 	runtime->avail += count;
 	substream->bytes += count;
 	if (count > 0) {
-		if (runtime->drain ||
-		    (runtime->event == NULL && snd_rawmidi_ready(substream)))
+		if (runtime->drain || snd_rawmidi_ready(substream))
 			wake_up(&runtime->sleep);
-		if (runtime->event)
-			tasklet_hi_schedule(&runtime->event_tasklet);
 	}
 	spin_unlock_irqrestore(&runtime->lock, flags);
 	return count;
@@ -1146,7 +1168,7 @@
 	count1 = runtime->avail < runtime->buffer_size;
 	spin_unlock_irqrestore(&runtime->lock, flags);
 	if (count1)
-		snd_rawmidi_trigger(substream, 1);
+		snd_rawmidi_output_trigger(substream, 1);
 	return result;
 }
 
@@ -1231,7 +1253,7 @@
 	rfile = file->private_data;
 	if (rfile->input != NULL) {
 		runtime = rfile->input->runtime;
-		snd_rawmidi_trigger(rfile->input, 1);
+		snd_rawmidi_input_trigger(rfile->input, 1);
 		poll_wait(file, &runtime->sleep, wait);
 	}
 	if (rfile->output != NULL) {
diff -Nru a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
--- a/sound/core/seq/seq_midi_emul.c	2005-03-23 19:29:42 -08:00
+++ b/sound/core/seq/seq_midi_emul.c	2005-03-23 19:29:42 -08:00
@@ -244,8 +244,8 @@
 	if (chan->gm_hold) {
 		/* Hold this note until pedal is turned off */
 		chan->note[note] |= SNDRV_MIDI_NOTE_RELEASED;
-	} else if (chan->note[note] & SNDRV_MIDI_NOTE_SUSTENUTO) {
-		/* Mark this note as release; it will be turned off when sustenuto
+	} else if (chan->note[note] & SNDRV_MIDI_NOTE_SOSTENUTO) {
+		/* Mark this note as release; it will be turned off when sostenuto
 		 * is turned off */
 		chan->note[note] |= SNDRV_MIDI_NOTE_RELEASED;
 	} else {
@@ -287,18 +287,18 @@
 		break;
 	case MIDI_CTL_PORTAMENTO:
 		break;
-	case MIDI_CTL_SUSTENUTO:
+	case MIDI_CTL_SOSTENUTO:
 		if (value) {
 			/* Mark each note that is currently held down */
 			for (i = 0; i < 128; i++) {
 				if (chan->note[i] & SNDRV_MIDI_NOTE_ON)
-					chan->note[i] |= SNDRV_MIDI_NOTE_SUSTENUTO;
+					chan->note[i] |= SNDRV_MIDI_NOTE_SOSTENUTO;
 			}
 		} else {
 			/* release all notes that were held */
 			for (i = 0; i < 128; i++) {
-				if (chan->note[i] & SNDRV_MIDI_NOTE_SUSTENUTO) {
-					chan->note[i] &= ~SNDRV_MIDI_NOTE_SUSTENUTO;
+				if (chan->note[i] & SNDRV_MIDI_NOTE_SOSTENUTO) {
+					chan->note[i] &= ~SNDRV_MIDI_NOTE_SOSTENUTO;
 					if (chan->note[i] & SNDRV_MIDI_NOTE_RELEASED) {
 						chan->note[i] = SNDRV_MIDI_NOTE_OFF;
 						if (ops->note_off)
diff -Nru a/sound/core/timer.c b/sound/core/timer.c
--- a/sound/core/timer.c	2005-03-23 19:29:42 -08:00
+++ b/sound/core/timer.c	2005-03-23 19:29:42 -08:00
@@ -37,10 +37,12 @@
 #include <linux/kerneld.h>
 #endif
 
-#if !defined(CONFIG_SND_RTCTIMER) && !defined(CONFIG_SND_RTCTIMER_MODULE)
-#define DEFAULT_TIMER_LIMIT 1
-#else
+#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE)
+#define DEFAULT_TIMER_LIMIT 3
+#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
 #define DEFAULT_TIMER_LIMIT 2
+#else
+#define DEFAULT_TIMER_LIMIT 1
 #endif
 
 static int timer_limit = DEFAULT_TIMER_LIMIT;
@@ -1117,7 +1119,8 @@
 	if (tu->qused >= tu->queue_size) {
 		tu->overrun++;
 	} else {
-		memcpy(&tu->queue[tu->qtail++], tread, sizeof(*tread));
+		memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread));
+		tu->qtail %= tu->queue_size;
 		tu->qused++;
 	}
 }
@@ -1140,6 +1143,8 @@
 	spin_lock(&tu->qlock);
 	snd_timer_user_append_to_tqueue(tu, &r1);
 	spin_unlock(&tu->qlock);
+	kill_fasync(&tu->fasync, SIGIO, POLL_IN);
+	wake_up(&tu->qchange_sleep);
 }
 
 static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
diff -Nru a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
--- a/sound/drivers/mpu401/mpu401_uart.c	2005-03-23 19:29:42 -08:00
+++ b/sound/drivers/mpu401/mpu401_uart.c	2005-03-23 19:29:42 -08:00
@@ -92,21 +92,19 @@
 
 static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&mpu->input_lock, flags);
+	spin_lock(&mpu->input_lock);
 	if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
 		snd_mpu401_uart_input_read(mpu);
 	} else {
 		snd_mpu401_uart_clear_rx(mpu);
 	}
-	spin_unlock_irqrestore(&mpu->input_lock, flags);
+	spin_unlock(&mpu->input_lock);
  	/* ok. for better Tx performance try do some output when input is done */
 	if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
 	    test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
-		spin_lock_irqsave(&mpu->output_lock, flags);
+		spin_lock(&mpu->output_lock);
 		snd_mpu401_uart_output_write(mpu);
-		spin_unlock_irqrestore(&mpu->output_lock, flags);
+		spin_unlock(&mpu->output_lock);
 	}
 }
 
@@ -134,14 +132,13 @@
  */
 static void snd_mpu401_uart_timer(unsigned long data)
 {
-	unsigned long flags;
 	mpu401_t *mpu = (mpu401_t *)data;
 
-	spin_lock_irqsave(&mpu->timer_lock, flags);
+	spin_lock(&mpu->timer_lock);
 	/*mpu->mode |= MPU401_MODE_TIMER;*/
 	mpu->timer.expires = 1 + jiffies;
 	add_timer(&mpu->timer);
-	spin_unlock_irqrestore(&mpu->timer_lock, flags);
+	spin_unlock(&mpu->timer_lock);
 	if (mpu->rmidi)
 		_snd_mpu401_uart_interrupt(mpu);
 }
diff -Nru a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
--- a/sound/drivers/mtpav.c	2005-03-23 19:29:42 -08:00
+++ b/sound/drivers/mtpav.c	2005-03-23 19:29:42 -08:00
@@ -580,13 +580,12 @@
 
 static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs)
 {
-	unsigned long flags;
 	mtpav_t *mcard = dev_id;
 
 	//printk("irqh()\n");
-	spin_lock_irqsave(&mcard->spinlock, flags);
+	spin_lock(&mcard->spinlock);
 	snd_mtpav_read_bytes(mcard);
-	spin_unlock_irqrestore(&mcard->spinlock, flags);
+	spin_unlock(&mcard->spinlock);
 	return IRQ_HANDLED;
 }
 
diff -Nru a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
--- a/sound/drivers/serial-u16550.c	2005-03-23 19:29:42 -08:00
+++ b/sound/drivers/serial-u16550.c	2005-03-23 19:29:42 -08:00
@@ -292,18 +292,17 @@
  */
 static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	unsigned long flags;
 	snd_uart16550_t *uart;
 
 	uart = (snd_uart16550_t *) dev_id;
-	spin_lock_irqsave(&uart->open_lock, flags);
+	spin_lock(&uart->open_lock);
 	if (uart->filemode == SERIAL_MODE_NOT_OPENED) {
-		spin_unlock_irqrestore(&uart->open_lock, flags);
+		spin_unlock(&uart->open_lock);
 		return IRQ_NONE;
 	}
 	inb(uart->base + UART_IIR);		/* indicate to the UART that the interrupt has been serviced */
 	snd_uart16550_io_loop(uart);
-	spin_unlock_irqrestore(&uart->open_lock, flags);
+	spin_unlock(&uart->open_lock);
 	return IRQ_HANDLED;
 }
 
diff -Nru a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
--- a/sound/i2c/other/ak4114.c	2005-03-23 19:29:42 -08:00
+++ b/sound/i2c/other/ak4114.c	2005-03-23 19:29:42 -08:00
@@ -159,7 +159,7 @@
 	/* bring up statistics / event queing */
 	chip->init = 0;
 	INIT_WORK(&chip->work, ak4114_stats, chip);
-	queue_delayed_work(chip->workqueue, &chip->work, 1);
+	queue_delayed_work(chip->workqueue, &chip->work, HZ / 10);
 }
 
 static unsigned int external_rate(unsigned char rcs1)
@@ -569,7 +569,7 @@
 	if (chip->init)
 		return;
 	snd_ak4114_check_rate_and_errors(chip, 0);
-	queue_delayed_work(chip->workqueue, &chip->work, 1);
+	queue_delayed_work(chip->workqueue, &chip->work, HZ / 10);
 }
 
 EXPORT_SYMBOL(snd_ak4114_create);
diff -Nru a/sound/isa/Kconfig b/sound/isa/Kconfig
--- a/sound/isa/Kconfig	2005-03-23 19:29:42 -08:00
+++ b/sound/isa/Kconfig	2005-03-23 19:29:42 -08:00
@@ -3,6 +3,16 @@
 menu "ISA devices"
 	depends on SND!=n && ISA
 
+config SND_AD1848_LIB
+        tristate
+        select SND_PCM
+	select SND_GENERIC_PM
+
+config SND_CS4231_LIB
+        tristate
+        select SND_PCM
+	select SND_GENERIC_PM
+
 config SND_AD1816A
 	tristate "Analog Devices SoundPort AD1816A"
 	depends on SND && ISAPNP
@@ -19,8 +29,7 @@
 config SND_AD1848
 	tristate "Generic AD1848/CS4248 driver"
 	depends on SND
-	select SND_PCM
-	select SND_GENERIC_PM
+	select SND_AD1848_LIB
 	help
 	  Say Y here to include support for AD1848 (Analog Devices) or
 	  CS4248 (Cirrus Logic - Crystal Semiconductors) chips.
@@ -35,8 +44,7 @@
 	tristate "Generic Cirrus Logic CS4231 driver"
 	depends on SND
 	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_PM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for CS4231 chips from Cirrus
 	  Logic - Crystal Semiconductors.
@@ -49,8 +57,7 @@
 	depends on SND
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_PM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for CS4232 chips from Cirrus
 	  Logic - Crystal Semiconductors.
@@ -63,8 +70,7 @@
 	depends on SND
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_PM
+	select SND_CS4231_LIB
 	help
 	  Say Y to include support for CS4235,CS4236,CS4237B,CS4238B,
 	  CS4239 chips from Cirrus Logic - Crystal Semiconductors.
@@ -143,7 +149,7 @@
 	tristate "Gravis UltraSound MAX"
 	depends on SND
 	select SND_RAWMIDI
-	select SND_PCM
+	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
 	help
 	  Say Y here to include support for Gravis UltraSound MAX
@@ -156,7 +162,7 @@
 	tristate "AMD InterWave, Gravis UltraSound PnP"
 	depends on SND
 	select SND_RAWMIDI
-	select SND_PCM
+	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
 	help
 	  Say Y here to include support for AMD InterWave based
@@ -170,7 +176,7 @@
 	tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
 	depends on SND
 	select SND_RAWMIDI
-	select SND_PCM
+	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
 	help
 	  Say Y here to include support for AMD InterWave based
@@ -186,7 +192,7 @@
 	select SND_OPL3_LIB
 	select SND_OPL4_LIB
 	select SND_MPU401_UART
-	select SND_PCM
+	select SND_AD1848_LIB
 	help
 	  Say Y here to include support for soundcards based on Opti
 	  82C92x or OTI-601 chips and using an AD1848 codec.
@@ -200,7 +206,7 @@
 	select SND_OPL3_LIB
 	select SND_OPL4_LIB
 	select SND_MPU401_UART
-	select SND_PCM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for soundcards based on Opti
 	  82C92x chips and using a CS4231 codec.
@@ -273,7 +279,7 @@
 	depends on SND
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
-	select SND_PCM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for Turtle Beach Maui, Tropez
 	  and Tropez+ soundcards based on the Wavefront chip.
@@ -299,7 +305,7 @@
 	depends on SND && ISAPNP
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
-	select SND_PCM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for soundcards based on the
 	  Aztech Systems AZT2320 chip.
@@ -310,7 +316,7 @@
 config SND_CMI8330
 	tristate "C-Media CMI8330"
 	depends on SND
-	select SND_PCM
+	select SND_AD1848_LIB
 	help
 	  Say Y here to include support for soundcards based on the
 	  C-Media CMI8330 chip.
@@ -336,8 +342,7 @@
 	depends on SND
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_PM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3
 	  chips.
@@ -348,7 +353,7 @@
 config SND_SGALAXY
 	tristate "Aztech Sound Galaxy"
 	depends on SND
-	select SND_PCM
+	select SND_AD1848_LIB
 	help
 	  Say Y here to include support for Aztech Sound Galaxy
 	  soundcards.
@@ -361,7 +366,7 @@
 	depends on SND
 	select SND_HWDEP
 	select SND_MPU401_UART
-	select SND_PCM
+	select SND_CS4231_LIB
 	help
 	  Say Y here to include support for Ensoniq SoundScape PnP
 	  soundcards.
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/ac97/ac97_codec.c	2005-03-23 19:29:42 -08:00
@@ -105,8 +105,8 @@
 { 0x41445374, 0xffffffff, "AD1981B",		patch_ad1981b,	NULL },
 { 0x41445375, 0xffffffff, "AD1985",		patch_ad1985,	NULL },
 { 0x41445378, 0xffffffff, "AD1986",		patch_ad1985,	NULL },
-{ 0x414c4300, 0xffffff00, "ALC100/100P", 	NULL,		NULL },
-{ 0x414c4710, 0xfffffff0, "ALC200/200P",	NULL,		NULL },
+{ 0x414c4300, 0xffffff00, "ALC100,100P", 	NULL,		NULL },
+{ 0x414c4710, 0xfffffff0, "ALC200,200P",	NULL,		NULL },
 { 0x414c4721, 0xffffffff, "ALC650D",		NULL,	NULL }, /* already patched */
 { 0x414c4722, 0xffffffff, "ALC650E",		NULL,	NULL }, /* already patched */
 { 0x414c4723, 0xffffffff, "ALC650F",		NULL,	NULL }, /* already patched */
@@ -145,11 +145,11 @@
 { 0x49434552, 0xffffffff, "VT1616i",		patch_vt1616,	NULL }, // VT1616 compatible (chipset integrated)
 { 0x49544520, 0xffffffff, "IT2226E",		NULL,		NULL },
 { 0x49544561, 0xffffffff, "IT2646E",		patch_it2646,	NULL },
-{ 0x4e534300, 0xffffffff, "LM4540/43/45/46/48",	NULL,		NULL }, // only guess --jk
+{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48",	NULL,		NULL }, // only guess --jk
 { 0x4e534331, 0xffffffff, "LM4549",		NULL,		NULL },
 { 0x4e534350, 0xffffffff, "LM4550",		NULL,		NULL },
 { 0x50534304, 0xffffffff, "UCB1400",		NULL,		NULL },
-{ 0x53494c20, 0xffffffe0, "Si3036/8",		NULL,		mpatch_si3036 },
+{ 0x53494c20, 0xffffffe0, "Si3036,8",		NULL,		mpatch_si3036 },
 { 0x54524102, 0xffffffff, "TR28022",		NULL,		NULL },
 { 0x54524106, 0xffffffff, "TR28026",		NULL,		NULL },
 { 0x54524108, 0xffffffff, "TR28028",		patch_tritech_tr28028,	NULL }, // added by xin jin [07/09/99]
@@ -158,26 +158,26 @@
 { 0x56494161, 0xffffffff, "VIA1612A",		NULL,		NULL }, // modified ICE1232 with S/PDIF
 { 0x57454301, 0xffffffff, "W83971D",		NULL,		NULL },
 { 0x574d4c00, 0xffffffff, "WM9701A",		NULL,		NULL },
-{ 0x574d4C03, 0xffffffff, "WM9703/WM9707/WM9708/WM9717", patch_wolfson03, NULL},
-{ 0x574d4C04, 0xffffffff, "WM9704M/WM9704Q",	patch_wolfson04, NULL},
-{ 0x574d4C05, 0xffffffff, "WM9705/WM9710",	patch_wolfson05, NULL},
+{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
+{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q",	patch_wolfson04, NULL},
+{ 0x574d4C05, 0xffffffff, "WM9705,WM9710",	patch_wolfson05, NULL},
 { 0x574d4C09, 0xffffffff, "WM9709",		NULL,		NULL},
-{ 0x574d4C12, 0xffffffff, "WM9711/WM9712",	patch_wolfson11, NULL},
-{ 0x574d4c13, 0xffffffff, "WM9713/WM9714",	patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
+{ 0x574d4C12, 0xffffffff, "WM9711,WM9712",	patch_wolfson11, NULL},
+{ 0x574d4c13, 0xffffffff, "WM9713,WM9714",	patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
 { 0x594d4800, 0xffffffff, "YMF743",		NULL,		NULL },
 { 0x594d4802, 0xffffffff, "YMF752",		NULL,		NULL },
 { 0x594d4803, 0xffffffff, "YMF753",		patch_yamaha_ymf753,	NULL },
-{ 0x83847600, 0xffffffff, "STAC9700/83/84",	patch_sigmatel_stac9700,	NULL },
-{ 0x83847604, 0xffffffff, "STAC9701/3/4/5",	NULL,		NULL },
+{ 0x83847600, 0xffffffff, "STAC9700,83,84",	patch_sigmatel_stac9700,	NULL },
+{ 0x83847604, 0xffffffff, "STAC9701,3,4,5",	NULL,		NULL },
 { 0x83847605, 0xffffffff, "STAC9704",		NULL,		NULL },
-{ 0x83847608, 0xffffffff, "STAC9708/11",	patch_sigmatel_stac9708,	NULL },
-{ 0x83847609, 0xffffffff, "STAC9721/23",	patch_sigmatel_stac9721,	NULL },
+{ 0x83847608, 0xffffffff, "STAC9708,11",	patch_sigmatel_stac9708,	NULL },
+{ 0x83847609, 0xffffffff, "STAC9721,23",	patch_sigmatel_stac9721,	NULL },
 { 0x83847644, 0xffffffff, "STAC9744",		patch_sigmatel_stac9744,	NULL },
-{ 0x83847650, 0xffffffff, "STAC9750/51",	NULL,		NULL },	// patch?
-{ 0x83847652, 0xffffffff, "STAC9752/53",	NULL,		NULL }, // patch?
-{ 0x83847656, 0xffffffff, "STAC9756/57",	patch_sigmatel_stac9756,	NULL },
-{ 0x83847658, 0xffffffff, "STAC9758/59",	patch_sigmatel_stac9758,	NULL },
-{ 0x83847666, 0xffffffff, "STAC9766/67",	NULL,		NULL }, // patch?
+{ 0x83847650, 0xffffffff, "STAC9750,51",	NULL,		NULL },	// patch?
+{ 0x83847652, 0xffffffff, "STAC9752,53",	NULL,		NULL }, // patch?
+{ 0x83847656, 0xffffffff, "STAC9756,57",	patch_sigmatel_stac9756,	NULL },
+{ 0x83847658, 0xffffffff, "STAC9758,59",	patch_sigmatel_stac9758,	NULL },
+{ 0x83847666, 0xffffffff, "STAC9766,67",	NULL,		NULL }, // patch?
 { 0, 	      0,	  NULL,			NULL,		NULL }
 };
 
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/ac97/ac97_patch.c	2005-03-23 19:29:42 -08:00
@@ -1728,7 +1728,7 @@
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 
 	return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
-				     (unsigned short)ucontrol->value.enumerated.item[0],
+				     (unsigned short)ucontrol->value.enumerated.item[0] << 12,
 				     0);
 }
 
diff -Nru a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/atiixp.c	2005-03-23 19:29:42 -08:00
@@ -250,6 +250,7 @@
 	int running;
 	int pcm_open_flag;
 	int ac97_pcm_type;	/* index # of ac97_pcm to access, -1 = not used */
+	unsigned int saved_curptr;
 };
 
 /*
@@ -1404,8 +1405,12 @@
 	int i;
 
 	for (i = 0; i < NUM_ATI_PCMDEVS; i++)
-		if (chip->pcmdevs[i])
+		if (chip->pcmdevs[i]) {
+			atiixp_dma_t *dma = &chip->dmas[i];
+			if (dma->substream && dma->running)
+				dma->saved_curptr = readl(chip->remap_addr + dma->ops->dt_cur);
 			snd_pcm_suspend_all(chip->pcmdevs[i]);
+		}
 	for (i = 0; i < NUM_ATI_CODECS; i++)
 		if (chip->ac97[i])
 			snd_ac97_suspend(chip->ac97[i]);
@@ -1432,6 +1437,17 @@
 	for (i = 0; i < NUM_ATI_CODECS; i++)
 		if (chip->ac97[i])
 			snd_ac97_resume(chip->ac97[i]);
+
+	for (i = 0; i < NUM_ATI_PCMDEVS; i++)
+		if (chip->pcmdevs[i]) {
+			atiixp_dma_t *dma = &chip->dmas[i];
+			if (dma->substream && dma->running) {
+				dma->ops->enable_dma(chip, 1);
+				writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
+				       chip->remap_addr + dma->ops->llp_offset);
+				writel(dma->saved_curptr, chip->remap_addr + dma->ops->dt_cur);
+			}
+		}
 
 	return 0;
 }
diff -Nru a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
--- a/sound/pci/ca0106/ca0106_main.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/ca0106/ca0106_main.c	2005-03-23 19:29:42 -08:00
@@ -187,9 +187,9 @@
 	.rate_max =		192000,
 	.channels_min =		2,  //1,
 	.channels_max =		2,  //6,
-	.buffer_bytes_max =	(32*1024),
+	.buffer_bytes_max =	((65536 - 64) * 8),
 	.period_bytes_min =	64,
-	.period_bytes_max =	(16*1024),
+	.period_bytes_max =	(65536 - 64),
 	.periods_min =		2,
 	.periods_max =		8,
 	.fifo_size =		0,
@@ -206,9 +206,9 @@
 	.rate_max =		48000,
 	.channels_min =		2,
 	.channels_max =		2,
-	.buffer_bytes_max =	(32*1024),
+	.buffer_bytes_max =	((65536 - 64) * 8),
 	.period_bytes_min =	64,
-	.period_bytes_max =	(16*1024),
+	.period_bytes_max =	(65536 - 64),
 	.periods_min =		2,
 	.periods_max =		2,
 	.fifo_size =		0,
@@ -513,6 +513,8 @@
 	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_PTR, channel, 0);
 	snd_ca0106_ptr_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
 	snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
+	/* FIXME  test what 0 bytes does. */
+	snd_ca0106_ptr_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
 	snd_ca0106_ptr_write(emu, PLAYBACK_POINTER, channel, 0);
 	snd_ca0106_ptr_write(emu, 0x07, channel, 0x0);
 	snd_ca0106_ptr_write(emu, 0x08, channel, 0);
diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c
--- a/sound/pci/cs4281.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/cs4281.c	2005-03-23 19:29:42 -08:00
@@ -697,11 +697,10 @@
 
 static int snd_cs4281_trigger(snd_pcm_substream_t *substream, int cmd)
 {
-	unsigned long flags;
 	cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
 	cs4281_t *chip = snd_pcm_substream_chip(substream);
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
+	spin_lock(&chip->reg_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		dma->valDCR |= BA0_DCR_MSK;
@@ -728,13 +727,13 @@
 			dma->valFCR &= ~BA0_FCR_FEN;
 		break;
 	default:
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
+		spin_unlock(&chip->reg_lock);
 		return -EINVAL;
 	}
 	snd_cs4281_pokeBA0(chip, dma->regDMR, dma->valDMR);
 	snd_cs4281_pokeBA0(chip, dma->regFCR, dma->valFCR);
 	snd_cs4281_pokeBA0(chip, dma->regDCR, dma->valDCR);
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	spin_unlock(&chip->reg_lock);
 	return 0;
 }
 
@@ -1849,7 +1848,6 @@
 static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	cs4281_t *chip = dev_id;
-	unsigned long flags;
 	unsigned int status, dma, val;
 	cs4281_dma_t *cdma;
 
@@ -1865,7 +1863,7 @@
 		for (dma = 0; dma < 4; dma++)
 			if (status & BA0_HISR_DMA(dma)) {
 				cdma = &chip->dma[dma];
-				spin_lock_irqsave(&chip->reg_lock, flags);
+				spin_lock(&chip->reg_lock);
 				/* ack DMA IRQ */
 				val = snd_cs4281_peekBA0(chip, cdma->regHDSR);
 				/* workaround, sometimes CS4281 acknowledges */
@@ -1874,16 +1872,16 @@
 				if ((val & BA0_HDSR_DHTC) && !(cdma->frag & 1)) {
 					cdma->frag--;
 					chip->spurious_dhtc_irq++;
-					spin_unlock_irqrestore(&chip->reg_lock, flags);
+					spin_unlock(&chip->reg_lock);
 					continue;
 				}
 				if ((val & BA0_HDSR_DTC) && (cdma->frag & 1)) {
 					cdma->frag--;
 					chip->spurious_dtc_irq++;
-					spin_unlock_irqrestore(&chip->reg_lock, flags);
+					spin_unlock(&chip->reg_lock);
 					continue;
 				}
-				spin_unlock_irqrestore(&chip->reg_lock, flags);
+				spin_unlock(&chip->reg_lock);
 				snd_pcm_period_elapsed(cdma->substream);
 			}
 	}
@@ -1891,7 +1889,7 @@
 	if ((status & BA0_HISR_MIDI) && chip->rmidi) {
 		unsigned char c;
 		
-		spin_lock_irqsave(&chip->reg_lock, flags);
+		spin_lock(&chip->reg_lock);
 		while ((snd_cs4281_peekBA0(chip, BA0_MIDSR) & BA0_MIDSR_RBE) == 0) {
 			c = snd_cs4281_peekBA0(chip, BA0_MIDRP);
 			if ((chip->midcr & BA0_MIDCR_RIE) == 0)
@@ -1908,7 +1906,7 @@
 			}
 			snd_cs4281_pokeBA0(chip, BA0_MIDWP, c);
 		}
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
+		spin_unlock(&chip->reg_lock);
 	}
 
 	/* EOI to the PCI part... reenables interrupts */
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/cs46xx/cs46xx_lib.c	2005-03-23 19:29:42 -08:00
@@ -765,9 +765,6 @@
 static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
 				       int cmd)
 {
-#ifndef CONFIG_SND_CS46XX_NEW_DSP
-	unsigned long flags;
-#endif
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	/*snd_pcm_runtime_t *runtime = substream->runtime;*/
 	int result = 0;
@@ -792,7 +789,7 @@
 		if (substream->runtime->periods != CS46XX_FRAGS)
 			snd_cs46xx_playback_transfer(substream);
 #else
-		spin_lock_irqsave(&chip->reg_lock, flags);
+		spin_lock(&chip->reg_lock);
 		if (substream->runtime->periods != CS46XX_FRAGS)
 			snd_cs46xx_playback_transfer(substream);
 		{ unsigned int tmp;
@@ -800,7 +797,7 @@
 		tmp &= 0x0000ffff;
 		snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp);
 		}
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
+		spin_unlock(&chip->reg_lock);
 #endif
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -813,13 +810,13 @@
 		if (!cpcm->pcm_channel->unlinked)
 			cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel);
 #else
-		spin_lock_irqsave(&chip->reg_lock, flags);
+		spin_lock(&chip->reg_lock);
 		{ unsigned int tmp;
 		tmp = snd_cs46xx_peek(chip, BA1_PCTL);
 		tmp &= 0x0000ffff;
 		snd_cs46xx_poke(chip, BA1_PCTL, tmp);
 		}
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
+		spin_unlock(&chip->reg_lock);
 #endif
 		break;
 	default:
@@ -833,12 +830,11 @@
 static int snd_cs46xx_capture_trigger(snd_pcm_substream_t * substream,
 				      int cmd)
 {
-	unsigned long flags;
 	cs46xx_t *chip = snd_pcm_substream_chip(substream);
 	unsigned int tmp;
 	int result = 0;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
+	spin_lock(&chip->reg_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -856,7 +852,7 @@
 		result = -EINVAL;
 		break;
 	}
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	spin_unlock(&chip->reg_lock);
 
 	return result;
 }
@@ -1153,7 +1149,6 @@
 
 static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	unsigned long flags;
 	cs46xx_t *chip = dev_id;
 	u32 status1;
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -1217,7 +1212,7 @@
 	if ((status1 & HISR_MIDI) && chip->rmidi) {
 		unsigned char c;
 		
-		spin_lock_irqsave(&chip->reg_lock, flags);
+		spin_lock(&chip->reg_lock);
 		while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_RBE) == 0) {
 			c = snd_cs46xx_peekBA0(chip, BA0_MIDRP);
 			if ((chip->midcr & MIDCR_RIE) == 0)
@@ -1234,7 +1229,7 @@
 			}
 			snd_cs46xx_pokeBA0(chip, BA0_MIDWP, c);
 		}
-		spin_unlock_irqrestore(&chip->reg_lock, flags);
+		spin_unlock(&chip->reg_lock);
 	}
 	/*
 	 *  EOI to the PCI part....reenables interrupts
diff -Nru a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
--- a/sound/pci/emu10k1/Makefile	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/Makefile	2005-03-23 19:29:42 -08:00
@@ -5,7 +5,7 @@
 
 snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
 		    irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
-		    emuproc.o emumixer.o emufx.o timer.o
+		    emuproc.o emumixer.o emufx.o timer.o p16v.o
 snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
 snd-emu10k1x-objs := emu10k1x.o
 
diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
--- a/sound/pci/emu10k1/emu10k1.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emu10k1.c	2005-03-23 19:29:42 -08:00
@@ -138,7 +138,15 @@
 	if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) {
 		snd_card_free(card);
 		return err;
-	}		
+	}
+	/* This stores the periods table. */
+	if (emu->audigy && emu->revision == 4) { /* P16V */	
+		if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) {
+			snd_p16v_free(emu);
+			return -ENOMEM;
+		}
+	}
+
 	if ((err = snd_emu10k1_mixer(emu)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -152,8 +160,13 @@
 	if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) {
 		snd_card_free(card);
 		return err;
-	}		
-
+	}
+	if (emu->audigy && emu->revision == 4) { /* P16V */	
+		if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) {
+			snd_card_free(card);
+			return err;
+		}
+	}
 	if (emu->audigy) {
 		if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
 			snd_card_free(card);
diff -Nru a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
--- a/sound/pci/emu10k1/emu10k1_main.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emu10k1_main.c	2005-03-23 19:29:42 -08:00
@@ -39,6 +39,7 @@
 
 #include <sound/core.h>
 #include <sound/emu10k1.h>
+#include "p16v.h"
 
 #if 0
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc.");
@@ -178,14 +179,17 @@
 		tmp &= 0xfffff1ff;
 		tmp |= (0x2<<9);
 		snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
-
+		
 		/* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
-		outl(0x600000, emu->port + 0x20);
-		outl(0x14, emu->port + 0x24);
-
+		snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
 		/* Setup SRCMulti Input Audio Enable */
-		outl(0x6E0000, emu->port + 0x20);
-		outl(0xFF00FF00, emu->port + 0x24);
+		/* Use 0xFFFFFFFF to enable P16V sounds. */
+		snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
+
+		/* Enabled Phased (8-channel) P16V playback */
+		outl(0x0201, emu->port + HCFG2);
+		/* Set playback routing. */
+		snd_emu10k1_ptr_write(emu, CAPTURE_P16V_SOURCE, 0, 78e4);
 	}
 	if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */
 		/* Hacks for Alice3 to work independent of haP16V driver */
@@ -596,6 +600,8 @@
 	if (emu->port)
 		pci_release_regions(emu->pci);
 	pci_disable_device(emu->pci);
+	if (emu->audigy && emu->revision == 4) /* P16V */	
+		snd_p16v_free(emu);
 	kfree(emu);
 	return 0;
 }
diff -Nru a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
--- a/sound/pci/emu10k1/emu10k1x.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emu10k1x.c	2005-03-23 19:29:42 -08:00
@@ -1265,7 +1265,6 @@
 
 static void do_emu10k1x_midi_interrupt(emu10k1x_t *emu, emu10k1x_midi_t *midi, unsigned int status)
 {
-	unsigned long flags;
 	unsigned char byte;
 
 	if (midi->rmidi == NULL) {
@@ -1285,7 +1284,7 @@
 	}
 	spin_unlock(&midi->input_lock);
 
-	spin_lock_irqsave(&midi->output_lock, flags);
+	spin_lock(&midi->output_lock);
 	if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
 		if (midi->substream_output &&
 		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
@@ -1294,7 +1293,7 @@
 			snd_emu10k1x_intr_disable(emu, midi->tx_enable);
 		}
 	}
-	spin_unlock_irqrestore(&midi->output_lock, flags);
+	spin_unlock(&midi->output_lock);
 }
 
 static void snd_emu10k1x_midi_interrupt(emu10k1x_t *emu, unsigned int status)
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emufx.c	2005-03-23 19:29:42 -08:00
@@ -2092,7 +2092,7 @@
 	memset(info, 0, sizeof(info));
 	info->card = emu->card_type;
 	info->internal_tram_size = emu->fx8010.itram_size;
-	info->external_tram_size = emu->fx8010.etram_pages.bytes;
+	info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
 	fxbus = fxbuses;
 	extin = emu->audigy ? audigy_ins : creative_ins;
 	extout = emu->audigy ? audigy_outs : creative_outs;
diff -Nru a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
--- a/sound/pci/emu10k1/emumixer.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emumixer.c	2005-03-23 19:29:42 -08:00
@@ -3,6 +3,7 @@
  *                   Takashi Iwai <tiwai@suse.de>
  *                   Creative Labs, Inc.
  *  Routines for control of EMU10K1 chips / mixer routines
+ *  Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
  *
  *  BUGS:
  *    --
@@ -481,9 +482,13 @@
 			change = 1;
 		}
 	}	
-	if (change && mix->epcm->voices[ch])
-		update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
-				    &mix->send_routing[0][0]);
+
+	if (change && mix->epcm) {
+		if (mix->epcm->voices[ch]) {
+			update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
+					&mix->send_routing[0][0]);
+		}
+	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
 	return change;
 }
@@ -543,9 +548,12 @@
 			change = 1;
 		}
 	}
-	if (change && mix->epcm->voices[ch])
-		update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
-					   &mix->send_volume[0][0]);
+	if (change && mix->epcm) {
+		if (mix->epcm->voices[ch]) {
+			update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
+						   &mix->send_volume[0][0]);
+		}
+	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
 	return change;
 }
@@ -599,8 +607,11 @@
 		mix->attn[0] = val;
 		change = 1;
 	}
-	if (change && mix->epcm->voices[ch])
-		snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
+	if (change && mix->epcm) {
+		if (mix->epcm->voices[ch]) {
+			snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
+		}
+	}
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
 	return change;
 }
@@ -939,6 +950,10 @@
 		if ((err = snd_ctl_add(card, kctl)))
 			return err;
 	}
-
+	if (emu->audigy && emu->revision == 4) { /* P16V */
+		if ((err = snd_p16v_mixer(emu)))
+			return err;
+	}
+		
 	return 0;
 }
diff -Nru a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
--- a/sound/pci/emu10k1/emumpu401.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emumpu401.c	2005-03-23 19:29:42 -08:00
@@ -73,7 +73,6 @@
 
 static void do_emu10k1_midi_interrupt(emu10k1_t *emu, emu10k1_midi_t *midi, unsigned int status)
 {
-	unsigned long flags;
 	unsigned char byte;
 
 	if (midi->rmidi == NULL) {
@@ -93,7 +92,7 @@
 	}
 	spin_unlock(&midi->input_lock);
 
-	spin_lock_irqsave(&midi->output_lock, flags);
+	spin_lock(&midi->output_lock);
 	if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
 		if (midi->substream_output &&
 		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
@@ -102,7 +101,7 @@
 			snd_emu10k1_intr_disable(emu, midi->tx_enable);
 		}
 	}
-	spin_unlock_irqrestore(&midi->output_lock, flags);
+	spin_unlock(&midi->output_lock);
 }
 
 static void snd_emu10k1_midi_interrupt(emu10k1_t *emu, unsigned int status)
diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emupcm.c	2005-03-23 19:29:42 -08:00
@@ -2,6 +2,7 @@
  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  *                   Creative Labs, Inc.
  *  Routines for control of EMU10K1 chips / PCM routines
+ *  Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
  *
  *  BUGS:
  *    --
@@ -109,14 +110,17 @@
 		snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
 		epcm->voices[1] = NULL;
 	}
-	if (voices == 1 && epcm->voices[0] != NULL)
-		return 0;		/* already allocated */
-	if (voices == 2 && epcm->voices[0] != NULL && epcm->voices[1] != NULL)
-		return 0;
-	if (voices > 1) {
-		if (epcm->voices[0] != NULL && epcm->voices[1] == NULL) {
-			snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]);
-			epcm->voices[0] = NULL;
+	for (i = 0; i < voices; i++) {
+		if (epcm->voices[i] == NULL)
+			break;
+	}
+	if (i == voices)
+		return 0; /* already allocated */
+
+	for (i = 0; i < ARRAY_SIZE(epcm->voices); i++) {
+		if (epcm->voices[i]) {
+			snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
+			epcm->voices[i] = NULL;
 		}
 	}
 	err = snd_emu10k1_voice_alloc(epcm->emu,
@@ -1273,7 +1277,7 @@
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
-	strcpy(pcm->name, "EMU10K1");
+	strcpy(pcm->name, "ADC Capture/Standard PCM Playback");
 	emu->pcm = pcm;
 
 	for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
@@ -1308,7 +1312,7 @@
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
-	strcpy(pcm->name, "EMU10K1 multichannel EFX");
+	strcpy(pcm->name, "Multichannel Playback");
 	emu->pcm = pcm;
 
 	for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
@@ -1357,7 +1361,7 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_mic_ops);
 
 	pcm->info_flags = 0;
-	strcpy(pcm->name, "EMU10K1 MIC");
+	strcpy(pcm->name, "Mic Capture");
 	emu->pcm_mic = pcm;
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
@@ -1695,7 +1699,7 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
 
 	pcm->info_flags = 0;
-	strcpy(pcm->name, "EMU10K1 EFX");
+	strcpy(pcm->name, "Multichannel Capture/PT Playback");
 	emu->pcm_efx = pcm;
 	if (rpcm)
 		*rpcm = pcm;
diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/emuproc.c	2005-03-23 19:29:42 -08:00
@@ -184,7 +184,7 @@
 	snd_iprintf(buffer, "Card                  : %s\n",
 		    emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative"));
 	snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
-	snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes);
+	snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2);
 	snd_iprintf(buffer, "\n");
 	snd_iprintf(buffer, "Effect Send Routing   :\n");
 	for (idx = 0; idx < NUM_G; idx++) {
@@ -413,7 +413,7 @@
 
 
 static void snd_emu_proc_ptr_reg_read(snd_info_entry_t *entry,
-				      snd_info_buffer_t * buffer, int iobase, int offset, int length)
+				      snd_info_buffer_t * buffer, int iobase, int offset, int length, int voices)
 {
 	emu10k1_t *emu = entry->private_data;
 	unsigned long value;
@@ -425,7 +425,7 @@
 	snd_iprintf(buffer, "Registers 0x%x\n", iobase);
 	for(i = offset; i < offset+length; i++) {
 		snd_iprintf(buffer, "%02X: ",i);
-		for (j = 0; j < 64; j++) {
+		for (j = 0; j < voices; j++) {
 			if(iobase == 0)
                 		value = snd_ptr_read(emu, 0, i, j);
 			else
@@ -466,25 +466,25 @@
 static void snd_emu_proc_ptr_reg_read00a(snd_info_entry_t *entry,
 					 snd_info_buffer_t * buffer)
 {
-	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40);
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40, 64);
 }
 
 static void snd_emu_proc_ptr_reg_read00b(snd_info_entry_t *entry,
 					 snd_info_buffer_t * buffer)
 {
-	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40);
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40, 64);
 }
 
 static void snd_emu_proc_ptr_reg_read20a(snd_info_entry_t *entry,
 					 snd_info_buffer_t * buffer)
 {
-	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40);
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40, 4);
 }
 
 static void snd_emu_proc_ptr_reg_read20b(snd_info_entry_t *entry,
 					 snd_info_buffer_t * buffer)
 {
-	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40);
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40, 4);
 }
 #endif
 
diff -Nru a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
--- a/sound/pci/emu10k1/io.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/io.c	2005-03-23 19:29:42 -08:00
@@ -91,6 +91,38 @@
 	}
 }
 
+unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu, 
+					  unsigned int reg, 
+					  unsigned int chn)
+{
+	unsigned long flags;
+	unsigned int regptr, val;
+  
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + 0x20 + PTR);
+	val = inl(emu->port + 0x20 + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+	return val;
+}
+
+void snd_emu10k1_ptr20_write(emu10k1_t *emu, 
+				   unsigned int reg, 
+				   unsigned int chn, 
+				   unsigned int data)
+{
+	unsigned int regptr;
+	unsigned long flags;
+
+	regptr = (reg << 16) | chn;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	outl(regptr, emu->port + 0x20 + PTR);
+	outl(data, emu->port + 0x20 + DATA);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
 void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb)
 {
 	unsigned long flags;
diff -Nru a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
--- a/sound/pci/emu10k1/irq.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/irq.c	2005-03-23 19:29:42 -08:00
@@ -33,7 +33,7 @@
 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	emu10k1_t *emu = dev_id;
-	unsigned int status, orig_status;
+	unsigned int status, status2, orig_status, orig_status2;
 	int handled = 0;
 
 	while ((status = inl(emu->port + IPR)) != 0) {
@@ -149,7 +149,7 @@
 		}
 		if (status) {
 			unsigned int bits;
-			snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
+			//snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
 			//make sure any interrupts we don't handle are disabled:
 			bits = INTE_FXDSPENABLE |
 				INTE_PCIERRORENABLE |
@@ -169,6 +169,21 @@
 			snd_emu10k1_intr_disable(emu, bits);
 		}
 		outl(orig_status, emu->port + IPR); /* ack all */
+	}
+	if (emu->audigy && emu->revision == 4) { /* P16V */	
+		while ((status2 = inl(emu->port + IPR2)) != 0) {
+			u32 mask = INTE2_PLAYBACK_CH_0_LOOP;  /* Full Loop */
+			emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
+			orig_status2 = status2;
+			if(status2 & mask) {
+				if(pvoice->use) {
+					snd_pcm_period_elapsed(pvoice->epcm->substream);
+				} else { 
+					snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
+				}
+			}
+			outl(orig_status2, emu->port + IPR2); /* ack all */
+		}
 	}
 	return IRQ_RETVAL(handled);
 }
diff -Nru a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/emu10k1/p16v.c	2005-03-23 19:29:42 -08:00
@@ -0,0 +1,736 @@
+/*
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *  Driver p16v chips
+ *  Version: 0.22
+ *
+ *  FEATURES currently supported:
+ *    Output fixed at S32_LE, 2 channel to hw:0,0
+ *    Rates: 44.1, 48, 96, 192.
+ *
+ *  Changelog:
+ *  0.8
+ *    Use separate card based buffer for periods table.
+ *  0.9
+ *    Use 2 channel output streams instead of 8 channel.
+ *       (8 channel output streams might be good for ASIO type output)
+ *    Corrected speaker output, so Front -> Front etc.
+ *  0.10
+ *    Fixed missed interrupts.
+ *  0.11
+ *    Add Sound card model number and names.
+ *    Add Analog volume controls.
+ *  0.12
+ *    Corrected playback interrupts. Now interrupt per period, instead of half period.
+ *  0.13
+ *    Use single trigger for multichannel.
+ *  0.14
+ *    Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
+ *  0.15
+ *    Force buffer_size / period_size == INTEGER.
+ *  0.16
+ *    Update p16v.c to work with changed alsa api.
+ *  0.17
+ *    Update p16v.c to work with changed alsa api. Removed boot_devs.
+ *  0.18
+ *    Merging with snd-emu10k1 driver.
+ *  0.19
+ *    One stereo channel at 24bit now works.
+ *  0.20
+ *    Added better register defines.
+ *  0.21
+ *    Integrated with snd-emu10k1 driver.
+ *  0.22
+ *    Removed #if 0 ... #endif
+ *
+ *
+ *  BUGS:
+ *    Some stability problems when unloading the snd-p16v kernel module.
+ *    --
+ *
+ *  TODO:
+ *    SPDIF out.
+ *    Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
+ *    Currently capture fixed at 48000Hz.
+ *
+ *    --
+ *  GENERAL INFO:
+ *    Model: SB0240
+ *    P16V Chip: CA0151-DBS
+ *    Audigy 2 Chip: CA0102-IAT
+ *    AC97 Codec: STAC 9721
+ *    ADC: Philips 1361T (Stereo 24bit)
+ *    DAC: CS4382-K (8-channel, 24bit, 192Khz)
+ *
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+#include <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <sound/info.h>
+#include <sound/emu10k1.h>
+#include "p16v.h"
+
+#define SET_CHANNEL 0  /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
+#define PCM_FRONT_CHANNEL 0
+#define PCM_REAR_CHANNEL 1
+#define PCM_CENTER_LFE_CHANNEL 2
+#define PCM_UNKNOWN_CHANNEL 3
+#define CONTROL_FRONT_CHANNEL 0
+#define CONTROL_REAR_CHANNEL 3
+#define CONTROL_CENTER_LFE_CHANNEL 1
+#define CONTROL_UNKNOWN_CHANNEL 2
+
+/* Card IDs:
+ * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
+ * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1    Model:SB0240
+ * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum  Model:SB msb0240230009266
+ * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E
+ *
+ */
+
+ /* hardware definition */
+static snd_pcm_hardware_t snd_p16v_playback_hw = {
+	.info =			(SNDRV_PCM_INFO_MMAP | 
+				 SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID),
+	.formats =		SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
+	.rates =		SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 ,
+	.rate_min =		48000,
+	.rate_max =		192000,
+	.channels_min =		8, 
+	.channels_max =		8,
+	.buffer_bytes_max =	(32*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(16*1024),
+	.periods_min =		2,
+	.periods_max =		8,
+	.fifo_size =		0,
+};
+
+static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime)
+{
+	snd_pcm_t *epcm = runtime->private_data;
+  
+	if (epcm) {
+        	//snd_printk("epcm free: %p\n", epcm);
+		kfree(epcm);
+	}
+}
+
+/* open_playback callback */
+static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+        emu10k1_voice_t *channel = &(emu->p16v_voices[channel_id]);
+	emu10k1_pcm_t *epcm;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+        //snd_printk("epcm kcalloc: %p\n", epcm);
+
+	if (epcm == NULL)
+		return -ENOMEM;
+	epcm->emu = emu;
+	epcm->substream = substream;
+        //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id);
+  
+	runtime->private_data = epcm;
+	runtime->private_free = snd_p16v_pcm_free_substream;
+  
+	runtime->hw = snd_p16v_playback_hw;
+
+        channel->emu = emu;
+        channel->number = channel_id;
+
+        channel->use=1;
+	//snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use);
+        //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
+        //channel->interrupt = snd_p16v_pcm_channel_interrupt;
+        channel->epcm=epcm;
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+                return err;
+
+	return 0;
+}
+
+/* close callback */
+static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	//snd_pcm_runtime_t *runtime = substream->runtime;
+        //emu10k1_pcm_t *epcm = runtime->private_data;
+        emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
+/* FIXME: maybe zero others */
+	return 0;
+}
+
+static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream)
+{
+	return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
+}
+
+/* hw_params callback */
+static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream,
+				      snd_pcm_hw_params_t * hw_params)
+{
+	int result;
+        //snd_printk("hw_params alloc: substream=%p\n", substream);
+	result = snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+        //snd_printk("hw_params alloc: result=%d\n", result);
+	//dump_stack();
+	return result;
+}
+
+/* hw_free callback */
+static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream)
+{
+	int result;
+        //snd_printk("hw_params free: substream=%p\n", substream);
+	result = snd_pcm_lib_free_pages(substream);
+        //snd_printk("hw_params free: result=%d\n", result);
+	//dump_stack();
+	return result;
+}
+
+/* prepare playback callback */
+static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	//emu10k1_pcm_t *epcm = runtime->private_data;
+	int channel = substream->pcm->device - emu->p16v_device_offset;
+	u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
+	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
+	int i;
+	u32 tmp;
+	
+        //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
+        //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
+	//snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->p16v_buffer.addr, emu->p16v_buffer.area, emu->p16v_buffer.bytes);
+	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
+        switch (runtime->rate) {
+	case 44100:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */
+	  break;
+	case 48000:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */
+	  break;
+	case 96000:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */
+	  break;
+	case 192000:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */
+	  break;
+	default:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */
+	  break;
+	}
+	/* FIXME: Check emu->buffer.size before actually writing to it. */
+        for(i=0; i < runtime->periods; i++) {
+		table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
+		table_base[(i*2)+1]=period_size_bytes<<16;
+	}
+ 
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
+	snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
+	snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
+
+	return 0;
+}
+
+static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int enable;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	enable = inl(emu->port + INTE2) | intrenb;
+	outl(enable, emu->port + INTE2);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+static void snd_p16v_intr_disable(emu10k1_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int disable;
+
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	disable = inl(emu->port + INTE2) & (~intrenb);
+	outl(disable, emu->port + INTE2);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+/* trigger_playback callback */
+static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream,
+				    int cmd)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime;
+	emu10k1_pcm_t *epcm;
+	int channel;
+	int result = 0;
+	struct list_head *pos;
+        snd_pcm_substream_t *s;
+	u32 basic = 0;
+	u32 inte = 0;
+	int running=0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		running=1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	default:
+		running=0;
+		break;
+	}
+        snd_pcm_group_for_each(pos, substream) {
+                s = snd_pcm_group_substream_entry(pos);
+		runtime = s->runtime;
+		epcm = runtime->private_data;
+		channel = substream->pcm->device-emu->p16v_device_offset;
+		//snd_printk("p16v channel=%d\n",channel);
+		epcm->running = running;
+		basic |= (0x1<<channel);
+		inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
+                snd_pcm_trigger_done(s, substream);
+        }
+	//snd_printk("basic=0x%x, inte=0x%x\n",basic, inte);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_p16v_intr_enable(emu, inte);
+		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
+		snd_p16v_intr_disable(emu, inte);
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+	return result;
+}
+
+/* pointer_playback callback */
+static snd_pcm_uframes_t
+snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1_pcm_t *epcm = runtime->private_data;
+	snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
+	int channel = substream->pcm->device - emu->p16v_device_offset;
+	if (!epcm->running)
+		return 0;
+
+	ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
+	ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
+	ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
+	if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
+	ptr2 = bytes_to_frames(runtime, ptr1);
+	ptr2+= (ptr4 >> 3) * runtime->period_size;
+	ptr=ptr2;
+        if (ptr >= runtime->buffer_size)
+		ptr -= runtime->buffer_size;
+
+	return ptr;
+}
+
+/* operators */
+static snd_pcm_ops_t snd_p16v_playback_front_ops = {
+	.open =        snd_p16v_pcm_open_playback_front,
+	.close =       snd_p16v_pcm_close_playback,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_p16v_pcm_hw_params_playback,
+	.hw_free =     snd_p16v_pcm_hw_free_playback,
+	.prepare =     snd_p16v_pcm_prepare_playback,
+	.trigger =     snd_p16v_pcm_trigger_playback,
+	.pointer =     snd_p16v_pcm_pointer_playback,
+};
+
+int snd_p16v_free(emu10k1_t *chip)
+{
+	// release the data
+	if (chip->p16v_buffer.area) {
+		snd_dma_free_pages(&chip->p16v_buffer);
+		//snd_printk("period lables free: %p\n", &chip->p16v_buffer);
+	}
+	return 0;
+}
+
+static void snd_p16v_pcm_free(snd_pcm_t *pcm)
+{
+	emu10k1_t *emu = pcm->private_data;
+	//snd_printk("snd_p16v_pcm_free pcm: called\n");
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+	emu->pcm = NULL;
+}
+
+int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm)
+{
+	snd_pcm_t *pcm;
+	snd_pcm_substream_t *substream;
+	int err;
+        int capture=0;
+  
+	//snd_printk("snd_p16v_pcm called. device=%d\n", device);
+	emu->p16v_device_offset = device;
+	if (rpcm)
+		*rpcm = NULL;
+        //if (device == 0) capture=1; 
+	if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
+		return err;
+  
+	pcm->private_data = emu;
+	pcm->private_free = snd_p16v_pcm_free;
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
+
+	pcm->info_flags = 0;
+	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
+	strcpy(pcm->name, "p16v");
+	emu->pcm = pcm;
+
+	for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 
+	    substream; 
+	    substream = substream->next) {
+		if ((err = snd_pcm_lib_preallocate_pages(substream, 
+							 SNDRV_DMA_TYPE_DEV, 
+							 snd_dma_pci_data(emu->pci), 
+							 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
+			return err;
+		//snd_printk("preallocate playback substream: err=%d\n", err);
+	}
+
+	for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 
+	      substream; 
+	      substream = substream->next) {
+ 		if ((err = snd_pcm_lib_preallocate_pages(substream, 
+	                                           SNDRV_DMA_TYPE_DEV, 
+	                                           snd_dma_pci_data(emu->pci), 
+	                                           64*1024, 64*1024)) < 0)
+			return err;
+		//snd_printk("preallocate capture substream: err=%d\n", err);
+	}
+  
+	if (rpcm)
+		*rpcm = pcm;
+  
+	return 0;
+}
+
+static int snd_p16v_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+        uinfo->count = 2;
+        uinfo->value.integer.min = 0;
+        uinfo->value.integer.max = 255;
+        return 0;
+}
+
+static int snd_p16v_volume_get(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
+{
+        emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+        u32 value;
+
+        value = snd_emu10k1_ptr20_read(emu, reg, high_low);
+	if (high_low == 1) {
+        	ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
+        	ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
+	} else {
+        	ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
+        	ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
+	}
+        return 0;
+}
+
+static int snd_p16v_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER7;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER7;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+static int snd_p16v_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER8;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+static int snd_p16v_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER8;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_get_analog_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER9;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER9;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+static int snd_p16v_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER10;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER10;
+        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
+{
+        emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+        u32 value;
+        value = snd_emu10k1_ptr20_read(emu, reg, 0);
+        //value = value & 0xffff;
+	if (high_low == 1) {
+		value &= 0xffff;
+	        value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
+	} else {
+		value &= 0xffff0000;
+        	value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
+	}
+        	snd_emu10k1_ptr20_write(emu, reg, 0, value);
+        return 1;
+}
+
+static int snd_p16v_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER7;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER7;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER8;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER8;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_analog_front(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER9;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER9;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 1;
+	int reg = PLAYBACK_VOLUME_MIXER10;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
+                                       snd_ctl_elem_value_t * ucontrol)
+{
+	int high_low = 0;
+	int reg = PLAYBACK_VOLUME_MIXER10;
+        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
+}
+
+static snd_kcontrol_new_t snd_p16v_volume_control_analog_front =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD Analog Front Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_analog_front,
+        .put =          snd_p16v_volume_put_analog_front
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD Analog Center/LFE Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_analog_center_lfe,
+        .put =          snd_p16v_volume_put_analog_center_lfe
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD Analog Unknown Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_analog_unknown,
+        .put =          snd_p16v_volume_put_analog_unknown
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD Analog Rear Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_analog_rear,
+        .put =          snd_p16v_volume_put_analog_rear
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD SPDIF Front Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_spdif_front,
+        .put =          snd_p16v_volume_put_spdif_front
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD SPDIF Center/LFE Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_spdif_center_lfe,
+        .put =          snd_p16v_volume_put_spdif_center_lfe
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD SPDIF Unknown Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_spdif_unknown,
+        .put =          snd_p16v_volume_put_spdif_unknown
+};
+
+static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear =
+{
+        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
+        .name =         "HD SPDIF Rear Volume",
+        .info =         snd_p16v_volume_info,
+        .get =          snd_p16v_volume_get_spdif_rear,
+        .put =          snd_p16v_volume_put_spdif_rear
+};
+
+int snd_p16v_mixer(emu10k1_t *emu)
+{
+        int err;
+        snd_kcontrol_t *kctl;
+        snd_card_t *card = emu->card;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        return 0;
+}
+
diff -Nru a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/emu10k1/p16v.h	2005-03-23 19:29:42 -08:00
@@ -0,0 +1,299 @@
+/*
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *  Driver p16v chips
+ *  Version: 0.21
+ *
+ *  FEATURES currently supported:
+ *    Output fixed at S32_LE, 2 channel to hw:0,0
+ *    Rates: 44.1, 48, 96, 192.
+ *
+ *  Changelog:
+ *  0.8
+ *    Use separate card based buffer for periods table.
+ *  0.9
+ *    Use 2 channel output streams instead of 8 channel.
+ *       (8 channel output streams might be good for ASIO type output)
+ *    Corrected speaker output, so Front -> Front etc.
+ *  0.10
+ *    Fixed missed interrupts.
+ *  0.11
+ *    Add Sound card model number and names.
+ *    Add Analog volume controls.
+ *  0.12
+ *    Corrected playback interrupts. Now interrupt per period, instead of half period.
+ *  0.13
+ *    Use single trigger for multichannel.
+ *  0.14
+ *    Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
+ *  0.15
+ *    Force buffer_size / period_size == INTEGER.
+ *  0.16
+ *    Update p16v.c to work with changed alsa api.
+ *  0.17
+ *    Update p16v.c to work with changed alsa api. Removed boot_devs.
+ *  0.18
+ *    Merging with snd-emu10k1 driver.
+ *  0.19
+ *    One stereo channel at 24bit now works.
+ *  0.20
+ *    Added better register defines.
+ *  0.21
+ *    Split from p16v.c
+ *
+ *
+ *  BUGS:
+ *    Some stability problems when unloading the snd-p16v kernel module.
+ *    --
+ *
+ *  TODO:
+ *    SPDIF out.
+ *    Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
+ *    Currently capture fixed at 48000Hz.
+ *
+ *    --
+ *  GENERAL INFO:
+ *    Model: SB0240
+ *    P16V Chip: CA0151-DBS
+ *    Audigy 2 Chip: CA0102-IAT
+ *    AC97 Codec: STAC 9721
+ *    ADC: Philips 1361T (Stereo 24bit)
+ *    DAC: CS4382-K (8-channel, 24bit, 192Khz)
+ *
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/********************************************************************************************************/
+/* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers                     */
+/********************************************************************************************************/
+                                                                                                                           
+/* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE.
+ * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters.
+ */
+
+/* Initally all registers from 0x00 to 0x3f have zero contents. */
+#define PLAYBACK_LIST_ADDR	0x00		/* Base DMA address of a list of pointers to each period/size */
+						/* One list entry: 4 bytes for DMA address, 
+						 * 4 bytes for period_size << 16.
+						 * One list entry is 8 bytes long.
+						 * One list entry for each period in the buffer.
+						 */
+#define PLAYBACK_LIST_SIZE	0x01		/* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000  */
+#define PLAYBACK_LIST_PTR	0x02		/* Pointer to the current period being played */
+#define PLAYBACK_UNKNOWN3	0x03		/* Not used */
+#define PLAYBACK_DMA_ADDR	0x04		/* Playback DMA addresss */
+#define PLAYBACK_PERIOD_SIZE	0x05		/* Playback period size. win2000 uses 0x04000000 */
+#define PLAYBACK_POINTER	0x06		/* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
+#define PLAYBACK_FIFO_END_ADDRESS	0x07		/* Playback FIFO end address */
+#define PLAYBACK_FIFO_POINTER	0x08		/* Playback FIFO pointer and number of valid sound samples in cache */
+#define PLAYBACK_UNKNOWN9	0x09		/* Not used */
+#define CAPTURE_DMA_ADDR	0x10		/* Capture DMA address */
+#define CAPTURE_BUFFER_SIZE	0x11		/* Capture buffer size */
+#define CAPTURE_POINTER		0x12		/* Capture buffer pointer. Sample currently in ADC */
+#define CAPTURE_FIFO_POINTER	0x13		/* Capture FIFO pointer and number of valid sound samples in cache */
+#define CAPTURE_P16V_VOLUME1	0x14		/* Low: Capture volume 0xXXXX3030 */
+#define CAPTURE_P16V_VOLUME2	0x15		/* High:Has no effect on capture volume */
+#define CAPTURE_P16V_SOURCE     0x16            /* P16V source select. Set to 0x0700E4E5 for AC97 CAPTURE */
+						/* [0:1] Capture input 0 channel select. 0 = Capture output 0.
+						 *                                       1 = Capture output 1.
+						 *                                       2 = Capture output 2.
+						 *                                       3 = Capture output 3.
+						 * [3:2] Capture input 1 channel select. 0 = Capture output 0.
+						 *                                       1 = Capture output 1.
+						 *                                       2 = Capture output 2.
+						 *                                       3 = Capture output 3.
+						 * [5:4] Capture input 2 channel select. 0 = Capture output 0.
+						 *                                       1 = Capture output 1.
+						 *                                       2 = Capture output 2.
+						 *                                       3 = Capture output 3.
+						 * [7:6] Capture input 3 channel select. 0 = Capture output 0.
+						 *                                       1 = Capture output 1.
+						 *                                       2 = Capture output 2.
+						 *                                       3 = Capture output 3.
+						 * [9:8] Playback input 0 channel select. 0 = Play output 0.
+						 *                                        1 = Play output 1.
+						 *                                        2 = Play output 2.
+						 *                                        3 = Play output 3.
+						 * [11:10] Playback input 1 channel select. 0 = Play output 0.
+						 *                                          1 = Play output 1.
+						 *                                          2 = Play output 2.
+						 *                                          3 = Play output 3.
+						 * [13:12] Playback input 2 channel select. 0 = Play output 0.
+						 *                                          1 = Play output 1.
+						 *                                          2 = Play output 2.
+						 *                                          3 = Play output 3.
+						 * [15:14] Playback input 3 channel select. 0 = Play output 0.
+						 *                                          1 = Play output 1.
+						 *                                          2 = Play output 2.
+						 *                                          3 = Play output 3.
+						 * [19:16] Playback mixer output enable. 1 bit per channel.
+						 * [23:20] Capture mixer output enable. 1 bit per channel.
+						 * [26:24] FX engine channel capture 0 = 0x60-0x67.
+						 *                                   1 = 0x68-0x6f.
+						 *                                   2 = 0x70-0x77.
+						 *                                   3 = 0x78-0x7f.
+						 *                                   4 = 0x80-0x87.
+						 *                                   5 = 0x88-0x8f.
+						 *                                   6 = 0x90-0x97.
+						 *                                   7 = 0x98-0x9f.
+						 * [31:27] Not used.
+						 */
+
+						/* 0x1 = capture on.
+						 * 0x100 = capture off.
+						 * 0x200 = capture off.
+						 * 0x1000 = capture off.
+						 */
+#define CAPTURE_RATE_STATUS		0x17		/* Capture sample rate. Read only */
+						/* [15:0] Not used.
+						 * [18:16] Channel 0 Detected sample rate. 0 - 44.1khz
+						 *                               1 - 48 khz
+						 *                               2 - 96 khz
+						 *                               3 - 192 khz
+						 *                               7 - undefined rate.
+						 * [19] Channel 0. 1 - Valid, 0 - Not Valid.
+						 * [22:20] Channel 1 Detected sample rate. 
+						 * [23] Channel 1. 1 - Valid, 0 - Not Valid.
+						 * [26:24] Channel 2 Detected sample rate. 
+						 * [27] Channel 2. 1 - Valid, 0 - Not Valid.
+						 * [30:28] Channel 3 Detected sample rate. 
+						 * [31] Channel 3. 1 - Valid, 0 - Not Valid.
+						 */
+/* 0x18 - 0x1f unused */
+#define PLAYBACK_LAST_SAMPLE    0x20		/* The sample currently being played. Read only */
+/* 0x21 - 0x3f unused */
+#define BASIC_INTERRUPT         0x40		/* Used by both playback and capture interrupt handler */
+						/* Playback (0x1<<channel_id) Don't touch high 16bits. */
+						/* Capture  (0x100<<channel_id). not tested */
+						/* Start Playback [3:0] (one bit per channel)
+						 * Start Capture [11:8] (one bit per channel)
+						 * Record source select for channel 0 [18:16]
+						 * Record source select for channel 1 [22:20]
+						 * Record source select for channel 2 [26:24]
+						 * Record source select for channel 3 [30:28]
+						 * 0 - SPDIF channel.
+						 * 1 - I2S channel.
+						 * 2 - SRC48 channel.
+						 * 3 - SRCMulti_SPDIF channel.
+						 * 4 - SRCMulti_I2S channel.
+						 * 5 - SPDIF channel.
+						 * 6 - fxengine capture.
+						 * 7 - AC97 capture.
+						 */
+						/* Default 41110000.
+						 * Writing 0xffffffff hangs the PC.
+						 * Writing 0xffff0000 -> 77770000 so it must be some sort of route.
+						 * bit 0x1 starts DMA playback on channel_id 0
+						 */
+/* 0x41,42 take values from 0 - 0xffffffff, but have no effect on playback */
+/* 0x43,0x48 do not remember settings */
+/* 0x41-45 unused */
+#define WATERMARK            0x46		/* Test bit to indicate cache level usage */
+						/* Values it can have while playing on channel 0. 
+						 * 0000f000, 0000f004, 0000f008, 0000f00c.
+						 * Readonly.
+						 */
+/* 0x47-0x4f unused */
+/* 0x50-0x5f Capture cache data */
+#define SRCSel			0x60            /* SRCSel. Default 0x4. Bypass P16V 0x14 */
+						/* [0] 0 = 10K2 audio, 1 = SRC48 mixer output.
+						 * [2] 0 = 10K2 audio, 1 = SRCMulti SPDIF mixer output.
+						 * [4] 0 = 10K2 audio, 1 = SRCMulti I2S mixer output.
+						 */
+						/* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
+						/* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
+						/* SRC48 and SRCMULTI sample rate select and output select. */
+						/* 0xffffffff -> 0xC0000015
+						 * 0xXXXXXXX4 = Enable Front Left/Right
+						 * Enable PCMs
+						 */
+
+/* 0x61 -> 0x6c are Volume controls */
+#define PLAYBACK_VOLUME_MIXER1  0x61		/* SRC48 Low to mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER2  0x62		/* SRC48 High to mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER3  0x63		/* SRCMULTI SPDIF Low to mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER4  0x64		/* SRCMULTI SPDIF High to mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER5  0x65		/* SRCMULTI I2S Low to mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER6  0x66		/* SRCMULTI I2S High to mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER7  0x67		/* P16V Low to SRCMULTI SPDIF mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER8  0x68		/* P16V High to SRCMULTI SPDIF mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER9  0x69		/* P16V Low to SRCMULTI I2S mixer input volume control. */
+						/* 0xXXXX3030 = PCM0 Volume (Front).
+						 * 0x3030XXXX = PCM1 Volume (Center)
+						 */
+#define PLAYBACK_VOLUME_MIXER10  0x6a		/* P16V High to SRCMULTI I2S mixer input volume control. */
+						/* 0x3030XXXX = PCM3 Volume (Rear). */
+#define PLAYBACK_VOLUME_MIXER11  0x6b		/* E10K2 Low to SRC48 mixer input volume control. */
+#define PLAYBACK_VOLUME_MIXER12 0x6c		/* E10K2 High to SRC48 mixer input volume control. */
+
+#define SRC48_ENABLE            0x6d            /* SRC48 input audio enable */
+						/* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
+						/* [23:16] The corresponding P16V channel to SRC48 enabled if == 1.
+						 * [31:24] The corresponding E10K2 channel to SRC48 enabled.
+						 */
+#define SRCMULTI_ENABLE         0x6e            /* SRCMulti input audio enable. Default 0xffffffff */
+						/* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
+						/* [7:0] The corresponding P16V channel to SRCMulti_I2S enabled if == 1.
+						 * [15:8] The corresponding E10K2 channel to SRCMulti I2S enabled.
+						 * [23:16] The corresponding P16V channel to SRCMulti SPDIF enabled.
+						 * [31:24] The corresponding E10K2 channel to SRCMulti SPDIF enabled.
+						 */
+						/* Bypass P16V 0xff00ff00 
+						 * Bitmap. 0 = Off, 1 = On.
+						 * P16V playback outputs:
+						 * 0xXXXXXXX1 = PCM0 Left. (Front)
+						 * 0xXXXXXXX2 = PCM0 Right.
+						 * 0xXXXXXXX4 = PCM1 Left. (Center/LFE)
+						 * 0xXXXXXXX8 = PCM1 Right.
+						 * 0xXXXXXX1X = PCM2 Left. (Unknown)
+						 * 0xXXXXXX2X = PCM2 Right.
+						 * 0xXXXXXX4X = PCM3 Left. (Rear)
+						 * 0xXXXXXX8X = PCM3 Right.
+						 */
+#define AUDIO_OUT_ENABLE        0x6f            /* Default: 000100FF */
+						/* [3:0] Does something, but not documented. Probably capture enable.
+						 * [7:4] Playback channels enable. not documented.
+						 * [16] AC97 output enable if == 1
+						 * [30] 0 = SRCMulti_I2S input from fxengine 0x68-0x6f.
+						 *      1 = SRCMulti_I2S input from SRC48 output.
+						 * [31] 0 = SRCMulti_SPDIF input from fxengine 0x60-0x67.
+						 *      1 = SRCMulti_SPDIF input from SRC48 output.
+						 */
+						/* 0xffffffff -> C00100FF */
+						/* 0 -> Not playback sound, irq still running */
+						/* 0xXXXXXX10 = PCM0 Left/Right On. (Front)
+						 * 0xXXXXXX20 = PCM1 Left/Right On. (Center/LFE)
+						 * 0xXXXXXX40 = PCM2 Left/Right On. (Unknown)
+						 * 0xXXXXXX80 = PCM3 Left/Right On. (Rear)
+						 */
+#define PLAYBACK_SPDIF_SELECT     0x70          /* Default: 12030F00 */
+						/* 0xffffffff -> 3FF30FFF */
+						/* 0x00000001 pauses stream/irq fail. */
+						/* All other bits do not effect playback */
+#define PLAYBACK_SPDIF_SRC_SELECT 0x71          /* Default: 0000E4E4 */
+						/* 0xffffffff -> F33FFFFF */
+						/* All bits do not effect playback */
+#define PLAYBACK_SPDIF_USER_DATA0 0x72		/* SPDIF out user data 0 */
+#define PLAYBACK_SPDIF_USER_DATA1 0x73		/* SPDIF out user data 1 */
+/* 0x74-0x75 unknown */
+#define CAPTURE_SPDIF_CONTROL	0x76		/* SPDIF in control setting */
+#define CAPTURE_SPDIF_STATUS	0x77		/* SPDIF in status */
+#define CAPURE_SPDIF_USER_DATA0 0x78		/* SPDIF in user data 0 */
+#define CAPURE_SPDIF_USER_DATA1 0x79		/* SPDIF in user data 1 */
+#define CAPURE_SPDIF_USER_DATA2 0x7a		/* SPDIF in user data 2 */
+
diff -Nru a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
--- a/sound/pci/emu10k1/timer.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/timer.c	2005-03-23 19:29:42 -08:00
@@ -1,10 +1,8 @@
 /*
  *  Copyright (c) by Lee Revell <rlrevell@joe-job.com>
- *  
+ *                   Clemens Ladisch <clemens@ladisch.de>
  *  Routines for control of EMU10K1 chips
  *
- *  Copied from similar code by Clemens Ladisch in the ymfpci driver
- * 
  *  BUGS:
  *    --
  *
diff -Nru a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
--- a/sound/pci/emu10k1/voice.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/emu10k1/voice.c	2005-03-23 19:29:42 -08:00
@@ -81,12 +81,8 @@
 		}
 	}
 	
-	if (first_voice == last_voice) {
-		printk("BUG (or not enough voices), number %d, next free %d!\n",
-				number,
-				emu->next_free_voice);
+	if (first_voice == last_voice)
 		return -ENOMEM;
-	}	
 	
 	for (i=0; i < number; i++) {
 		voice = &emu->voices[(first_voice + i) % NUM_G];
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/ens1370.c	2005-03-23 19:29:42 -08:00
@@ -754,8 +754,6 @@
 
 static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
 {
-	unsigned long flags;
-
 	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -775,13 +773,13 @@
 			} else if (s == ensoniq->capture_substream)
 				return -EINVAL;
 		}
-		spin_lock_irqsave(&ensoniq->reg_lock, flags);
+		spin_lock(&ensoniq->reg_lock);
 		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
 			ensoniq->sctrl |= what;
 		else
 			ensoniq->sctrl &= ~what;
 		outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
-		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+		spin_unlock(&ensoniq->reg_lock);
 		break;
 	}
 	case SNDRV_PCM_TRIGGER_START:
@@ -803,13 +801,13 @@
 				snd_pcm_trigger_done(s, substream);
 			}
 		}
-		spin_lock_irqsave(&ensoniq->reg_lock, flags);
+		spin_lock(&ensoniq->reg_lock);
 		if (cmd == SNDRV_PCM_TRIGGER_START)
 			ensoniq->ctrl |= what;
 		else
 			ensoniq->ctrl &= ~what;
 		outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
-		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+		spin_unlock(&ensoniq->reg_lock);
 		break;
 	}
 	default:
@@ -958,11 +956,10 @@
 
 static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(snd_pcm_substream_t * substream)
 {
-	unsigned long flags;
 	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
-	spin_lock_irqsave(&ensoniq->reg_lock, flags);
+	spin_lock(&ensoniq->reg_lock);
 	if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC1_EN) {
 		outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
 		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC1_SIZE)));
@@ -970,17 +967,16 @@
 	} else {
 		ptr = 0;
 	}
-	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+	spin_unlock(&ensoniq->reg_lock);
 	return ptr;
 }
 
 static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(snd_pcm_substream_t * substream)
 {
-	unsigned long flags;
 	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
-	spin_lock_irqsave(&ensoniq->reg_lock, flags);
+	spin_lock(&ensoniq->reg_lock);
 	if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC2_EN) {
 		outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
 		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC2_SIZE)));
@@ -988,17 +984,16 @@
 	} else {
 		ptr = 0;
 	}
-	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+	spin_unlock(&ensoniq->reg_lock);
 	return ptr;
 }
 
 static snd_pcm_uframes_t snd_ensoniq_capture_pointer(snd_pcm_substream_t * substream)
 {
-	unsigned long flags;
 	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
-	spin_lock_irqsave(&ensoniq->reg_lock, flags);
+	spin_lock(&ensoniq->reg_lock);
 	if (inl(ES_REG(ensoniq, CONTROL)) & ES_ADC_EN) {
 		outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
 		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, ADC_SIZE)));
@@ -1006,7 +1001,7 @@
 	} else {
 		ptr = 0;
 	}
-	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+	spin_unlock(&ensoniq->reg_lock);
 	return ptr;
 }
 
@@ -2088,14 +2083,13 @@
 
 static void snd_ensoniq_midi_interrupt(ensoniq_t * ensoniq)
 {
-	unsigned long flags;
 	snd_rawmidi_t * rmidi = ensoniq->rmidi;
 	unsigned char status, mask, byte;
 
 	if (rmidi == NULL)
 		return;
 	/* do Rx at first */
-	spin_lock_irqsave(&ensoniq->reg_lock, flags);
+	spin_lock(&ensoniq->reg_lock);
 	mask = ensoniq->uartm & ES_MODE_INPUT ? ES_RXRDY : 0;
 	while (mask) {
 		status = inb(ES_REG(ensoniq, UART_STATUS));
@@ -2104,10 +2098,10 @@
 		byte = inb(ES_REG(ensoniq, UART_DATA));
 		snd_rawmidi_receive(ensoniq->midi_input, &byte, 1);
 	}
-	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+	spin_unlock(&ensoniq->reg_lock);
 
 	/* do Tx at second */
-	spin_lock_irqsave(&ensoniq->reg_lock, flags);
+	spin_lock(&ensoniq->reg_lock);
 	mask = ensoniq->uartm & ES_MODE_OUTPUT ? ES_TXRDY : 0;
 	while (mask) {
 		status = inb(ES_REG(ensoniq, UART_STATUS));
@@ -2121,7 +2115,7 @@
 			outb(byte, ES_REG(ensoniq, UART_DATA));
 		}
 	}
-	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+	spin_unlock(&ensoniq->reg_lock);
 }
 
 static int snd_ensoniq_midi_input_open(snd_rawmidi_substream_t * substream)
@@ -2288,7 +2282,6 @@
 
 static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	unsigned long flags;
 	ensoniq_t *ensoniq = dev_id;
 	unsigned int status, sctrl;
 
@@ -2299,7 +2292,7 @@
 	if (!(status & ES_INTR))
 		return IRQ_NONE;
 
-	spin_lock_irqsave(&ensoniq->reg_lock, flags);
+	spin_lock(&ensoniq->reg_lock);
 	sctrl = ensoniq->sctrl;
 	if (status & ES_DAC1)
 		sctrl &= ~ES_P1_INT_EN;
@@ -2309,7 +2302,7 @@
 		sctrl &= ~ES_R1_INT_EN;
 	outl(sctrl, ES_REG(ensoniq, SERIAL));
 	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
-	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
+	spin_unlock(&ensoniq->reg_lock);
 
 	if (status & ES_UART)
 		snd_ensoniq_midi_interrupt(ensoniq);
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/es1968.c	2005-03-23 19:29:42 -08:00
@@ -586,6 +586,7 @@
 	spinlock_t reg_lock;
 	spinlock_t ac97_lock;
 	struct tasklet_struct hwvol_tq;
+	unsigned int in_suspend;
 
 	/* Maestro Stuff */
 	u16 maestro_map[32];
@@ -1937,6 +1938,9 @@
 	outb(0x88, chip->io_port + 0x1e);
 	outb(0x88, chip->io_port + 0x1f);
 
+	if (chip->in_suspend)
+		return;
+
 	if (! chip->master_switch || ! chip->master_volume)
 		return;
 
@@ -2410,6 +2414,7 @@
 	if (! chip->do_pm)
 		return 0;
 
+	chip->in_suspend = 1;
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 	snd_es1968_bob_stop(chip);
@@ -2421,6 +2426,7 @@
 static int es1968_resume(snd_card_t *card)
 {
 	es1968_t *chip = card->pm_private_data;
+	struct list_head *p;
 
 	if (! chip->do_pm)
 		return 0;
@@ -2441,10 +2447,23 @@
 	/* restore ac97 state */
 	snd_ac97_resume(chip->ac97);
 
+	list_for_each(p, &chip->substream_list) {
+		esschan_t *es = list_entry(p, esschan_t, list);
+		switch (es->mode) {
+		case ESM_MODE_PLAY:
+			snd_es1968_playback_setup(chip, es, es->substream->runtime);
+			break;
+		case ESM_MODE_CAPTURE:
+			snd_es1968_capture_setup(chip, es, es->substream->runtime);
+			break;
+		}
+	}
+
 	/* start timer again */
 	if (chip->bobclient)
 		snd_es1968_bob_start(chip);
 
+	chip->in_suspend = 0;
 	return 0;
 }
 #endif /* CONFIG_PM */
diff -Nru a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
--- a/sound/pci/hda/hda_codec.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/hda/hda_codec.c	2005-03-23 19:29:42 -08:00
@@ -49,6 +49,7 @@
 /* codec vendor labels */
 static struct hda_vendor_id hda_vendor_ids[] = {
 	{ 0x10ec, "Realtek" },
+	{ 0x13f6, "C-Media" },
 	{ 0x434d, "C-Media" },
 	{} /* terminator */
 };
@@ -610,6 +611,8 @@
 	if (! info)
 		return 0;
 	if (! (info->status & INFO_AMP_CAPS)) {
+		if (!(snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_AMP_OVRD))
+			nid = codec->afg;
 		info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?
 						    AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
 		info->status |= INFO_AMP_CAPS;
@@ -954,6 +957,9 @@
 	if (change || codec->in_resume) {
 		codec->spdif_ctls = val;
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+				    AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
+				    AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
 	}
 	up(&codec->spdif_mutex);
 	return change;
diff -Nru a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
--- a/sound/pci/hda/patch_cmedia.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/hda/patch_cmedia.c	2005-03-23 19:29:42 -08:00
@@ -565,7 +565,7 @@
 	spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl);
 	if (spec->board_config < 0) {
 		snd_printd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
-		spec->board_config = CMI_MINIMAL;
+		spec->board_config = CMI_FULL_DIG; /* try everything */
 	}
 
 	switch (spec->board_config) {
@@ -615,6 +615,7 @@
  * patch entries
  */
 struct hda_codec_preset snd_hda_preset_cmedia[] = {
+	{ .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
  	{ .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
 	{} /* terminator */
 };
diff -Nru a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
--- a/sound/pci/mixart/mixart.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/mixart/mixart.c	2005-03-23 19:29:42 -08:00
@@ -1062,7 +1062,7 @@
 		free_irq(mgr->irq, (void *)mgr);
 
 	/* reset board if some firmware was loaded */
-	if(mgr->hwdep->dsp_loaded) {
+	if(mgr->dsp_loaded) {
 		snd_mixart_reset_board(mgr);
 		snd_printdd("reset miXart !\n");
 	}
@@ -1203,7 +1203,7 @@
 	snd_iprintf(buffer, "Digigram miXart (alsa card %d)\n\n", chip->chip_idx);
 
 	/* stats available when embedded OS is running */
-	if (chip->mgr->hwdep->dsp_loaded & ( 1 << MIXART_MOTHERBOARD_ELF_INDEX)) {
+	if (chip->mgr->dsp_loaded & ( 1 << MIXART_MOTHERBOARD_ELF_INDEX)) {
 		snd_iprintf(buffer, "- hardware -\n");
 		switch (chip->mgr->board_type ) {
 		case MIXART_DAUGHTER_TYPE_NONE     : snd_iprintf(buffer, "\tmiXart8 (no daughter board)\n\n"); break;
@@ -1381,7 +1381,7 @@
 		}
 	}
 
-	/* init firmware status (mgr->hwdep->dsp_loaded reset in hwdep_new) */
+	/* init firmware status (mgr->dsp_loaded reset in hwdep_new) */
 	mgr->board_type = MIXART_DAUGHTER_TYPE_NONE;
 
 	/* create array of streaminfo */
diff -Nru a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h
--- a/sound/pci/mixart/mixart.h	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/mixart/mixart.h	2005-03-23 19:29:42 -08:00
@@ -112,7 +112,7 @@
 	struct semaphore setup_mutex; /* mutex used in hw_params, open and close */
 
 	/* hardware interface */
-	snd_hwdep_t *hwdep;
+	unsigned int dsp_loaded;      /* bit flags of loaded dsp indices */
 	unsigned int board_type;      /* read from embedded once elf file is loaded, 250 = miXart8, 251 = with AES, 252 = with Cobranet */
 
 	struct snd_dma_buffer flowinfo;
diff -Nru a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
--- a/sound/pci/mixart/mixart_hwdep.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/mixart/mixart_hwdep.c	2005-03-23 19:29:42 -08:00
@@ -546,6 +546,7 @@
 		release_firmware(fw_entry);
 		if (err < 0)
 			return err;
+		mgr->dsp_loaded |= 1 << i;
 	}
 	return 0;
 }
@@ -573,7 +574,7 @@
 	strcpy(info->id, "miXart");
         info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
 
-	if (mgr->hwdep->dsp_loaded & (1 <<  MIXART_MOTHERBOARD_ELF_INDEX))
+	if (mgr->dsp_loaded & (1 <<  MIXART_MOTHERBOARD_ELF_INDEX))
 		info->chip_ready = 1;
 
 	info->version = MIXART_DRIVER_VERSION;
@@ -599,6 +600,9 @@
 	}
 	err = mixart_dsp_load(mgr, dsp->index, &fw);
 	vfree(fw.data);
+	if (err < 0)
+		return err;
+	mgr->dsp_loaded |= 1 << dsp->index;
 	return err;
 }
 
@@ -619,8 +623,7 @@
 	hw->ops.dsp_load = mixart_hwdep_dsp_load;
 	hw->exclusive = 1;
 	sprintf(hw->name,  SND_MIXART_HWDEP_ID);
-	mgr->hwdep = hw;
-	mgr->hwdep->dsp_loaded = 0;
+	mgr->dsp_loaded = 0;
 
 	return snd_card_register(mgr->chip[0]->card);
 }
diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/rme32.c	2005-03-23 19:29:42 -08:00
@@ -1183,15 +1183,14 @@
 {
 	rme32_t *rme32 = snd_pcm_substream_chip(substream);
 	snd_pcm_indirect_t *rec, *cprec;
-	unsigned long flags;
 
 	rec = &rme32->playback_pcm;
 	cprec = &rme32->capture_pcm;
-	spin_lock_irqsave(&rme32->lock, flags);
+	spin_lock(&rme32->lock);
 	rec->hw_queue_size = RME32_BUFFER_SIZE;
 	if (rme32->running & (1 << SNDRV_PCM_STREAM_CAPTURE))
 		rec->hw_queue_size -= cprec->hw_ready;
-	spin_unlock_irqrestore(&rme32->lock, flags);
+	spin_unlock(&rme32->lock);
 	snd_pcm_indirect_playback_transfer(substream, rec,
 					   snd_rme32_pb_trans_copy);
 	return 0;
diff -Nru a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/rme9652/hdsp.c	2005-03-23 19:29:42 -08:00
@@ -3905,7 +3905,6 @@
 
 static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd)
 {
-	unsigned long flags;
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	snd_pcm_substream_t *other;
 	int running;
@@ -3925,7 +3924,7 @@
 		return -EIO;
 	}
 
-	spin_lock_irqsave(&hdsp->lock, flags);
+	spin_lock(&hdsp->lock);
 	running = hdsp->running;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -3936,7 +3935,7 @@
 		break;
 	default:
 		snd_BUG();
-		spin_unlock_irqrestore(&hdsp->lock, flags);
+		spin_unlock(&hdsp->lock);
 		return -EINVAL;
 	}
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -3978,7 +3977,7 @@
 	else if (hdsp->running && !running)
 		hdsp_stop_audio(hdsp);
 	hdsp->running = running;
-	spin_unlock_irqrestore(&hdsp->lock, flags);
+	spin_unlock(&hdsp->lock);
 
 	return 0;
 }
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	2005-03-23 19:29:42 -08:00
+++ b/sound/pci/via82xx.c	2005-03-23 19:29:42 -08:00
@@ -2168,6 +2168,7 @@
 		{ .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
 		{ .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
 		{ .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
+		{ .vendor = 0x1462, .device = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
 		{ .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
 		{ .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
 		{ .vendor = 0x147b, .device = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */
