http://linux-sound.bkbits.net/linux-sound
perex@suse.cz|ChangeSet|20050324111342|58895 perex

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/24 14:02:03-08:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/via82xx.c
#   2005/03/24 14:01:58-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/trident/trident_main.c
#   2005/03/24 14:01:58-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1968.c
#   2005/03/24 14:01:58-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/24 14:01:58-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1938.c
#   2005/03/24 14:01:57-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ens1370.c
#   2005/03/24 14:01:57-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2005/03/24 14:01:57-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cmipci.c
#   2005/03/24 14:01:57-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/24 12:13:42+01:00 perex@suse.cz 
#   ALSA 1.0.9rc2
# 
# include/sound/version.h
#   2005/03/24 12:13:12+01:00 perex@suse.cz +1 -1
#   ALSA 1.0.9rc2
# 
# ChangeSet
#   2005/03/24 12:00:49+01:00 perex@suse.cz 
#   ALSA CVS update
#   ALSA Version
#   release: 1.0.9rc2
#   
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# include/sound/version.h
#   2005/03/24 02:49:11+01:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2005/03/24 09:49:11
#   C:ALSA Version
#   F:include/version.h:1.55->1.56 
#   L:release: 1.0.9rc2
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2005/03/24 12:00:05+01:00 perex@suse.cz 
#   [ALSA] seq - fix local variable initialization
#   
#   ALSA sequencer
#   This patch re-adds the initialization of callbacks and pcallbacks
#   that was accidentally removed in the last revision.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/core/seq/seq_system.c
#   2005/03/24 00:32:08+01:00 perex@suse.cz +2 -0
#   [ALSA] seq - fix local variable initialization
#   
#   D:2005/03/24 07:32:08
#   C:ALSA sequencer
#   F:core/seq/seq_system.c:1.7->1.8 
#   L:This patch re-adds the initialization of callbacks and pcallbacks
#   L:that was accidentally removed in the last revision.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/24 11:59:21+01:00 perex@suse.cz 
#   [ALSA] usb - change timeout of USB control/bulk msg functions to msecs
#   
#   USB generic driver
#   This changes the timeout in the remaining (indirect) calls to
#   usb_control/bulk_msg from jiffies to msecs.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbmidi.c
#   2005/03/24 00:17:17+01:00 perex@suse.cz +1 -1
#   [ALSA] usb - change timeout of USB control/bulk msg functions to msecs
#   
#   D:2005/03/24 07:17:17
#   C:USB generic driver
#   F:usb/usbaudio.c:1.118->1.119 
#   F:usb/usbmidi.c:1.44->1.45 
#   L:This changes the timeout in the remaining (indirect) calls to
#   L:usb_control/bulk_msg from jiffies to msecs.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbaudio.c
#   2005/03/24 00:17:17+01:00 perex@suse.cz +4 -4
#   [ALSA] usb - change timeout of USB control/bulk msg functions to msecs
#   
#   D:2005/03/24 07:17:17
#   C:USB generic driver
#   F:usb/usbaudio.c:1.118->1.119 
#   F:usb/usbmidi.c:1.44->1.45 
#   L:This changes the timeout in the remaining (indirect) calls to
#   L:usb_control/bulk_msg from jiffies to msecs.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/24 11:58:40+01:00 perex@suse.cz 
#   [ALSA] cs4281 - fix typos in the case gameport is disabled
#   
#   CS4281 driver
#   This patch fixes the wrong names of the dummy gameport functions
#   used when CONFIG_GAMEPORT isn't set.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/cs4281.c
#   2005/03/24 00:11:42+01:00 perex@suse.cz +2 -2
#   [ALSA] cs4281 - fix typos in the case gameport is disabled
#   
#   D:2005/03/24 07:11:42
#   C:CS4281 driver
#   F:pci/cs4281.c:1.75->1.76 
#   L:This patch fixes the wrong names of the dummy gameport functions
#   L:used when CONFIG_GAMEPORT isn't set.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/03/24 11:57:55+01:00 perex@suse.cz 
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   controls on ac97 codec.  This flag is used when the sound chip has its
#   native SPDIF support and it conflicts with the one of AC97 codec.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emumixer.c
#   2005/03/23 10:04:17+01:00 perex@suse.cz +1 -5
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   D:2005/03/23 17:03:57
#   C:AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   F:include/ac97_codec.h:1.64->1.65 
#   F:pci/atiixp.c:1.33->1.34 
#   F:pci/ac97/ac97_codec.c:1.178->1.179 
#   F:pci/au88x0/au88x0_mixer.c:1.4->1.5 
#   F:pci/emu10k1/emu10k1x.c:1.7->1.8 
#   F:pci/emu10k1/emumixer.c:1.33->1.34 
#   L:Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   L:controls on ac97 codec.  This flag is used when the sound chip has its
#   L:native SPDIF support and it conflicts with the one of AC97 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1x.c
#   2005/03/23 10:04:17+01:00 perex@suse.cz +1 -0
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   D:2005/03/23 17:03:57
#   C:AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   F:include/ac97_codec.h:1.64->1.65 
#   F:pci/atiixp.c:1.33->1.34 
#   F:pci/ac97/ac97_codec.c:1.178->1.179 
#   F:pci/au88x0/au88x0_mixer.c:1.4->1.5 
#   F:pci/emu10k1/emu10k1x.c:1.7->1.8 
#   F:pci/emu10k1/emumixer.c:1.33->1.34 
#   L:Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   L:controls on ac97 codec.  This flag is used when the sound chip has its
#   L:native SPDIF support and it conflicts with the one of AC97 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/au88x0/au88x0_mixer.c
#   2005/03/23 10:04:16+01:00 perex@suse.cz +1 -0
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   D:2005/03/23 17:03:57
#   C:AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   F:include/ac97_codec.h:1.64->1.65 
#   F:pci/atiixp.c:1.33->1.34 
#   F:pci/ac97/ac97_codec.c:1.178->1.179 
#   F:pci/au88x0/au88x0_mixer.c:1.4->1.5 
#   F:pci/emu10k1/emu10k1x.c:1.7->1.8 
#   F:pci/emu10k1/emumixer.c:1.33->1.34 
#   L:Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   L:controls on ac97 codec.  This flag is used when the sound chip has its
#   L:native SPDIF support and it conflicts with the one of AC97 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/atiixp.c
#   2005/03/23 10:04:15+01:00 perex@suse.cz +2 -0
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   D:2005/03/23 17:03:57
#   C:AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   F:include/ac97_codec.h:1.64->1.65 
#   F:pci/atiixp.c:1.33->1.34 
#   F:pci/ac97/ac97_codec.c:1.178->1.179 
#   F:pci/au88x0/au88x0_mixer.c:1.4->1.5 
#   F:pci/emu10k1/emu10k1x.c:1.7->1.8 
#   F:pci/emu10k1/emumixer.c:1.33->1.34 
#   L:Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   L:controls on ac97 codec.  This flag is used when the sound chip has its
#   L:native SPDIF support and it conflicts with the one of AC97 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2005/03/23 10:04:16+01:00 perex@suse.cz +1 -1
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   D:2005/03/23 17:03:57
#   C:AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   F:include/ac97_codec.h:1.64->1.65 
#   F:pci/atiixp.c:1.33->1.34 
#   F:pci/ac97/ac97_codec.c:1.178->1.179 
#   F:pci/au88x0/au88x0_mixer.c:1.4->1.5 
#   F:pci/emu10k1/emu10k1x.c:1.7->1.8 
#   F:pci/emu10k1/emumixer.c:1.33->1.34 
#   L:Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   L:controls on ac97 codec.  This flag is used when the sound chip has its
#   L:native SPDIF support and it conflicts with the one of AC97 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/ac97_codec.h
#   2005/03/23 10:03:57+01:00 perex@suse.cz +1 -0
#   [ALSA] Add AC97_SCAP_NO_SPDIF flag
#   
#   D:2005/03/23 17:03:57
#   C:AC97 Codec,ATIIXP driver,au88x0 driver,EMU10K1/EMU10K2 driver
#   F:include/ac97_codec.h:1.64->1.65 
#   F:pci/atiixp.c:1.33->1.34 
#   F:pci/ac97/ac97_codec.c:1.178->1.179 
#   F:pci/au88x0/au88x0_mixer.c:1.4->1.5 
#   F:pci/emu10k1/emu10k1x.c:1.7->1.8 
#   F:pci/emu10k1/emumixer.c:1.33->1.34 
#   L:Added a new flag, AC97_SCAP_NO_SPDIF, to prevent to build the SPDIF-related
#   L:controls on ac97 codec.  This flag is used when the sound chip has its
#   L:native SPDIF support and it conflicts with the one of AC97 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:57:09+01:00 perex@suse.cz 
#   [ALSA] Fix EFX voice allocation/preparation
#   
#   EMU10K1/EMU10K2 driver
#   Fixed a bug (possibly Oops) in allocation/preparation of EFX voices
#   The invalid voice pointer was accessed when voices are allocated over
#   the voice table boundary.
#   
#   The patch includes a small clean-up & optimization.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/voice.c
#   2005/03/23 10:01:31+01:00 perex@suse.cz +3 -5
#   [ALSA] Fix EFX voice allocation/preparation
#   
#   D:2005/03/23 17:01:31
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emupcm.c:1.45->1.46 
#   F:pci/emu10k1/voice.c:1.8->1.9 
#   L:Fixed a bug (possibly Oops) in allocation/preparation of EFX voices
#   L:The invalid voice pointer was accessed when voices are allocated over
#   L:the voice table boundary.
#   L:
#   L:The patch includes a small clean-up & optimization.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emupcm.c
#   2005/03/23 10:01:31+01:00 perex@suse.cz +33 -33
#   [ALSA] Fix EFX voice allocation/preparation
#   
#   D:2005/03/23 17:01:31
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emupcm.c:1.45->1.46 
#   F:pci/emu10k1/voice.c:1.8->1.9 
#   L:Fixed a bug (possibly Oops) in allocation/preparation of EFX voices
#   L:The invalid voice pointer was accessed when voices are allocated over
#   L:the voice table boundary.
#   L:
#   L:The patch includes a small clean-up & optimization.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:56:28+01:00 perex@suse.cz 
#   [ALSA] Fix Oops in snd_emu10k1_add_controls
#   
#   EMU10K1/EMU10K2 driver
#   Fixed Oops in snd_emu101k_add_controls (introduced in the last patch
#   for stack usage reduction).
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emufx.c
#   2005/03/23 09:58:41+01:00 perex@suse.cz +8 -6
#   [ALSA] Fix Oops in snd_emu10k1_add_controls
#   
#   D:2005/03/23 16:58:41
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emufx.c:1.72->1.73 
#   L:Fixed Oops in snd_emu101k_add_controls (introduced in the last patch
#   L:for stack usage reduction).
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:55:42+01:00 perex@suse.cz 
#   [ALSA] Clean up the chip detection
#   
#   EMU10K1/EMU10K2 driver
#   Minor clean-ups of the chip detectoin code.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1_main.c
#   2005/03/23 09:56:03+01:00 perex@suse.cz +25 -33
#   [ALSA] Clean up the chip detection
#   
#   D:2005/03/23 16:56:02
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.60->1.61 
#   F:pci/emu10k1/emu10k1.c:1.34->1.35 
#   F:pci/emu10k1/emu10k1_main.c:1.46->1.47 
#   L:Minor clean-ups of the chip detectoin code.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1.c
#   2005/03/23 09:56:03+01:00 perex@suse.cz +3 -1
#   [ALSA] Clean up the chip detection
#   
#   D:2005/03/23 16:56:02
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.60->1.61 
#   F:pci/emu10k1/emu10k1.c:1.34->1.35 
#   F:pci/emu10k1/emu10k1_main.c:1.46->1.47 
#   L:Minor clean-ups of the chip detectoin code.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/emu10k1.h
#   2005/03/23 09:56:02+01:00 perex@suse.cz +10 -10
#   [ALSA] Clean up the chip detection
#   
#   D:2005/03/23 16:56:02
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.60->1.61 
#   F:pci/emu10k1/emu10k1.c:1.34->1.35 
#   F:pci/emu10k1/emu10k1_main.c:1.46->1.47 
#   L:Minor clean-ups of the chip detectoin code.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:54:58+01:00 perex@suse.cz 
#   [ALSA] Add Mono volume controls for ALC260
#   
#   HDA Codec driver
#   Added Mono volume controls for ALC260 codec.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/patch_realtek.c
#   2005/03/22 14:02:44+01:00 perex@suse.cz +11 -0
#   [ALSA] Add Mono volume controls for ALC260
#   
#   D:2005/03/22 21:02:44
#   C:HDA Codec driver
#   F:pci/hda/patch_realtek.c:1.6->1.7 
#   L:Added Mono volume controls for ALC260 codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:54:18+01:00 perex@suse.cz 
#   [ALSA] Add AD1986A support
#   
#   HDA generic driver,HDA Codec driver
#   Added the patch for Analog Device AD1986A codec.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/hda_patch.h
#   2005/03/22 14:02:04+01:00 perex@suse.cz +3 -0
#   [ALSA] Add AD1986A support
#   
#   D:2005/03/22 21:02:04
#   C:HDA generic driver,HDA Codec driver
#   F:pci/hda/Makefile:1.1->1.2 
#   F:pci/hda/hda_patch.h:1.1->1.2 
#   F:pci/hda/patch_analog.c:INITIAL->1.1 
#   L:Added the patch for Analog Device AD1986A codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/Makefile
#   2005/03/22 14:02:04+01:00 perex@suse.cz +1 -1
#   [ALSA] Add AD1986A support
#   
#   D:2005/03/22 21:02:04
#   C:HDA generic driver,HDA Codec driver
#   F:pci/hda/Makefile:1.1->1.2 
#   F:pci/hda/hda_patch.h:1.1->1.2 
#   F:pci/hda/patch_analog.c:INITIAL->1.1 
#   L:Added the patch for Analog Device AD1986A codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/patch_analog.c
#   2005/03/24 11:41:29+01:00 perex@suse.cz +445 -0
#   [ALSA] Add AD1986A support
#   
#   D:2005/03/22 21:02:04
#   C:HDA generic driver,HDA Codec driver
#   F:pci/hda/Makefile:1.1->1.2 
#   F:pci/hda/hda_patch.h:1.1->1.2 
#   F:pci/hda/patch_analog.c:INITIAL->1.1 
#   L:Added the patch for Analog Device AD1986A codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/patch_analog.c
#   2005/03/24 11:41:29+01:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/hda/patch_analog.c
# 
# ChangeSet
#   2005/03/24 11:53:32+01:00 perex@suse.cz 
#   [ALSA] correct comment for setting widget output
#   
#   HDA Codec driver
#   This patch has no real logical change, it simply correct the comment.
#   
#   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/22 14:00:37+01:00 perex@suse.cz +4 -4
#   [ALSA] correct comment for setting widget output
#   
#   D:2005/03/22 21:00:37
#   C:HDA Codec driver
#   F:pci/hda/patch_cmedia.c:1.5->1.6 
#   L:This patch has no real logical change, it simply correct the comment.
#   Signed-off-by: ChenLi Tien<cltien@cmedia.com.tw>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:52:53+01:00 perex@suse.cz 
#   [ALSA] Fixes AC3 output on Audigy2 sound cards
#   
#   EMU10K1/EMU10K2 driver
#   This patch adds a DSP patch to fix an spdif_bug on some Audigy2 cards.
#   
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emufx.c
#   2005/03/22 13:58:45+01:00 perex@suse.cz +9 -1
#   [ALSA] Fixes AC3 output on Audigy2 sound cards
#   
#   D:2005/03/22 20:58:45
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emufx.c:1.71->1.72 
#   L:This patch adds a DSP patch to fix an spdif_bug on some Audigy2 cards.
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:52:11+01:00 perex@suse.cz 
#   [ALSA] Add framework for better audigy sound card capabilities selection
#   
#   EMU10K1/EMU10K2 driver
#   This patch adds more options to help identify all the many different
#   creative sound cards. It will eventually be used to control features
#   more finely.
#   
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1_main.c
#   2005/03/22 13:56:33+01:00 perex@suse.cz +114 -17
#   [ALSA] Add framework for better audigy sound card capabilities selection
#   
#   D:2005/03/22 20:56:17
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.59->1.60 
#   F:pci/emu10k1/emu10k1.c:1.33->1.34 
#   F:pci/emu10k1/emu10k1_main.c:1.45->1.46 
#   L:This patch adds more options to help identify all the many different
#   L:creative sound cards. It will eventually be used to control features
#   L:more finely.
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emu10k1.c
#   2005/03/22 13:56:33+01:00 perex@suse.cz +2 -16
#   [ALSA] Add framework for better audigy sound card capabilities selection
#   
#   D:2005/03/22 20:56:17
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.59->1.60 
#   F:pci/emu10k1/emu10k1.c:1.33->1.34 
#   F:pci/emu10k1/emu10k1_main.c:1.45->1.46 
#   L:This patch adds more options to help identify all the many different
#   L:creative sound cards. It will eventually be used to control features
#   L:more finely.
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/emu10k1.h
#   2005/03/22 13:56:17+01:00 perex@suse.cz +18 -0
#   [ALSA] Add framework for better audigy sound card capabilities selection
#   
#   D:2005/03/22 20:56:17
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.59->1.60 
#   F:pci/emu10k1/emu10k1.c:1.33->1.34 
#   F:pci/emu10k1/emu10k1_main.c:1.45->1.46 
#   L:This patch adds more options to help identify all the many different
#   L:creative sound cards. It will eventually be used to control features
#   L:more finely.
#   Signed-off-by: James Courtier-Dutton
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:51:23+01:00 perex@suse.cz 
#   [ALSA] Replace with macros for gameport initialization
#   
#   ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   Use some macros for gameport initialization.  This makes much easier
#   to write the compatible layer for the old gameport API in alsa-driver
#   tree.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ymfpci/ymfpci.c
#   2005/03/22 11:09:38+01:00 perex@suse.cz +3 -3
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2005/03/22 11:09:36+01:00 perex@suse.cz +3 -3
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/trident/trident_main.c
#   2005/03/22 11:09:37+01:00 perex@suse.cz +6 -6
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/sonicvibes.c
#   2005/03/22 11:09:35+01:00 perex@suse.cz +1 -1
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/es1968.c
#   2005/03/22 11:09:35+01:00 perex@suse.cz +3 -3
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/es1938.c
#   2005/03/22 11:09:35+01:00 perex@suse.cz +1 -1
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ens1370.c
#   2005/03/22 11:09:35+01:00 perex@suse.cz +1 -1
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2005/03/22 11:09:37+01:00 perex@suse.cz +5 -5
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs4281.c
#   2005/03/22 11:09:34+01:00 perex@suse.cz +5 -5
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cmipci.c
#   2005/03/22 11:09:34+01:00 perex@suse.cz +3 -3
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/azt3328.c
#   2005/03/22 11:09:33+01:00 perex@suse.cz +3 -3
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/au88x0/au88x0_game.c
#   2005/03/22 11:09:37+01:00 perex@suse.cz +6 -6
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/als4000.c
#   2005/03/22 11:09:33+01:00 perex@suse.cz +3 -3
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/core.h
#   2005/03/22 11:09:32+01:00 perex@suse.cz +9 -0
#   [ALSA] Replace with macros for gameport initialization
#   
#   D:2005/03/22 18:09:32
#   C:ALSA Core,ALS4000 driver,AZT3328 driver,CMIPCI driver,CS4281 driver
#   C:ENS1370/1+ driver,ES1938 driver,ES1968 driver,SonicVibes driver
#   C:VIA82xx driver,au88x0 driver,CS46xx driver,Trident driver,YMFPCI driver
#   F:include/core.h:1.67->1.68 
#   F:pci/als4000.c:1.40->1.41 
#   F:pci/azt3328.c:1.25->1.26 
#   F:pci/cmipci.c:1.81->1.82 
#   F:pci/cs4281.c:1.74->1.75 
#   F:pci/ens1370.c:1.78->1.79 
#   F:pci/es1938.c:1.47->1.48 
#   F:pci/es1968.c:1.86->1.87 
#   F:pci/sonicvibes.c:1.46->1.47 
#   F:pci/via82xx.c:1.140->1.141 
#   F:pci/au88x0/au88x0_game.c:1.6->1.7 
#   F:pci/cs46xx/cs46xx_lib.c:1.98->1.99 
#   F:pci/trident/trident_main.c:1.71->1.72 
#   F:pci/ymfpci/ymfpci.c:1.40->1.41 
#   L:Use some macros for gameport initialization.  This makes much easier
#   L:to write the compatible layer for the old gameport API in alsa-driver
#   L:tree.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:50:38+01:00 perex@suse.cz 
#   [ALSA] Fix Oops with joystick support
#   
#   YMFPCI driver
#   Fix Oops when joystick is enabled.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ymfpci/ymfpci.c
#   2005/03/22 10:56:38+01:00 perex@suse.cz +1 -0
#   [ALSA] Fix Oops with joystick support
#   
#   D:2005/03/22 17:56:38
#   C:YMFPCI driver
#   F:pci/ymfpci/ymfpci.c:1.39->1.40 
#   L:Fix Oops when joystick is enabled.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:49:58+01:00 perex@suse.cz 
#   [ALSA] Fix Oops with joystick support
#   
#   ES1968 driver
#   Fix Oops when joystick is enabled.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/es1968.c
#   2005/03/22 10:46:32+01:00 perex@suse.cz +1 -0
#   [ALSA] Fix Oops with joystick support
#   
#   D:2005/03/22 17:46:32
#   C:ES1968 driver
#   F:pci/es1968.c:1.85->1.86 
#   L:Fix Oops when joystick is enabled.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:48:53+01:00 perex@suse.cz 
#   [ALSA] Use vprintk()
#   
#   ALSA Core
#   Use vprintk() instead of printk with a temporary line buffer.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/misc.c
#   2005/03/22 08:32:43+01:00 perex@suse.cz +2 -6
#   [ALSA] Use vprintk()
#   
#   D:2005/03/22 15:32:43
#   C:ALSA Core
#   F:core/misc.c:1.18->1.19 
#   L:Use vprintk() instead of printk with a temporary line buffer.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:46:07+01:00 perex@suse.cz 
#   [ALSA] Reduce stack usage
#   
#   Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   PDAudioCF driver,USB generic driver
#   Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   instances.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/usb/usbaudio.c
#   2005/03/22 08:34:38+01:00 perex@suse.cz +23 -15
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pcmcia/pdaudiocf/pdaudiocf.c
#   2005/03/22 08:34:38+01:00 perex@suse.cz +9 -3
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart_hwdep.c
#   2005/03/22 08:34:38+01:00 perex@suse.cz +50 -34
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/hda/hda_generic.c
#   2005/03/22 08:34:38+01:00 perex@suse.cz +5 -8
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emufx.c
#   2005/03/22 08:34:37+01:00 perex@suse.cz +81 -53
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/isa/wavefront/wavefront_synth.c
#   2005/03/22 08:34:27+01:00 perex@suse.cz +84 -47
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/isa/gus/gus_synth.c
#   2005/03/22 08:34:27+01:00 perex@suse.cz +14 -7
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/i2c/other/ak4xxx-adda.c
#   2005/03/22 08:34:25+01:00 perex@suse.cz +71 -63
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/timer.c
#   2005/03/22 08:31:21+01:00 perex@suse.cz +35 -24
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_virmidi.c
#   2005/03/22 08:31:22+01:00 perex@suse.cz +34 -20
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_system.c
#   2005/03/22 08:31:22+01:00 perex@suse.cz +34 -28
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_midi.c
#   2005/03/22 08:31:22+01:00 perex@suse.cz +53 -43
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/oss/seq_oss_midi.c
#   2005/03/22 08:31:22+01:00 perex@suse.cz +18 -17
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/oss/seq_oss_init.c
#   2005/03/22 08:31:22+01:00 perex@suse.cz +28 -18
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm_native.c
#   2005/03/22 08:31:21+01:00 perex@suse.cz +12 -4
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm.c
#   2005/03/22 08:31:21+01:00 perex@suse.cz +23 -13
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/oss/pcm_oss.c
#   2005/03/22 08:31:21+01:00 perex@suse.cz +1 -1
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/oss/mixer_oss.c
#   2005/03/22 08:31:21+01:00 perex@suse.cz +26 -12
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/info.c
#   2005/03/22 08:31:21+01:00 perex@suse.cz +4 -5
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/control.c
#   2005/03/22 08:31:20+01:00 perex@suse.cz +15 -10
#   [ALSA] Reduce stack usage
#   
#   D:2005/03/22 15:31:20
#   C:Control Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel
#   C:ALSA<-OSS emulation,ALSA sequencer,ALSA<-OSS sequencer
#   C:AK4XXX AD/DA converters,GUS Library,Wavefront drivers
#   C:EMU10K1/EMU10K2 driver,HDA generic driver,MIXART driver
#   C:PDAudioCF driver,USB generic driver
#   F:core/control.c:1.59->1.60 
#   F:core/info.c:1.51->1.52 
#   F:core/pcm.c:1.50->1.51 
#   F:core/pcm_native.c:1.116->1.117 
#   F:core/timer.c:1.68->1.69 
#   F:core/oss/mixer_oss.c:1.39->1.40 
#   F:core/oss/pcm_oss.c:1.85->1.86 
#   F:core/seq/seq_midi.c:1.25->1.26 
#   F:core/seq/seq_system.c:1.6->1.7 
#   F:core/seq/seq_virmidi.c:1.12->1.13 
#   F:core/seq/oss/seq_oss_init.c:1.15->1.16 
#   F:core/seq/oss/seq_oss_midi.c:1.17->1.18 
#   F:i2c/other/ak4xxx-adda.c:1.9->1.10 
#   F:isa/gus/gus_synth.c:1.12->1.13 
#   F:isa/wavefront/wavefront_synth.c:1.25->1.26 
#   F:pci/emu10k1/emufx.c:1.70->1.71 
#   F:pci/hda/hda_generic.c:1.2->1.3 
#   F:pci/mixart/mixart_hwdep.c:1.9->1.10 
#   F:pcmcia/pdaudiocf/pdaudiocf.c:1.12->1.13 
#   F:usb/usbaudio.c:1.117->1.118 
#   L:Reduce the stack usage, mostly by replacing large structs with kmalloc'ed
#   L:instances.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/03/24 11:44:51+01:00 perex@suse.cz 
#   [ALSA] Remove unnecessary ac97 init code
#   
#   VIA82xx driver,VIA82xx-modem driver
#   Removed unnecessary ac97 init code in snd_via82xx_chip_init().
#   This reduces eventually the big stack usage, too.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx_modem.c
#   2005/03/22 08:29:30+01:00 perex@suse.cz +0 -11
#   [ALSA] Remove unnecessary ac97 init code
#   
#   D:2005/03/22 15:29:30
#   C:VIA82xx driver,VIA82xx-modem driver
#   F:pci/via82xx.c:1.139->1.140 
#   F:pci/via82xx_modem.c:1.5->1.6 
#   L:Removed unnecessary ac97 init code in snd_via82xx_chip_init().
#   L:This reduces eventually the big stack usage, too.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2005/03/22 08:29:30+01:00 perex@suse.cz +0 -9
#   [ALSA] Remove unnecessary ac97 init code
#   
#   D:2005/03/22 15:29:30
#   C:VIA82xx driver,VIA82xx-modem driver
#   F:pci/via82xx.c:1.139->1.140 
#   F:pci/via82xx_modem.c:1.5->1.6 
#   L:Removed unnecessary ac97 init code in snd_via82xx_chip_init().
#   L:This reduces eventually the big stack usage, too.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# 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-24 18:13:28 -08:00
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2005-03-24 18:13:28 -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/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	2005-03-24 18:13:28 -08:00
+++ b/include/sound/ac97_codec.h	2005-03-24 18:13:28 -08:00
@@ -356,6 +356,7 @@
 #define AC97_SCAP_INDEP_SDIN	(1<<6)	/* independent SDIN */
 #define AC97_SCAP_INV_EAPD	(1<<7)	/* inverted EAPD */
 #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */
+#define AC97_SCAP_NO_SPDIF	(1<<9)	/* don't build SPDIF controls */
 
 /* ac97->flags */
 #define AC97_HAS_PC_BEEP	(1<<0)	/* force PC Speaker usage */
diff -Nru a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h	2005-03-24 18:13:29 -08:00
+++ b/include/sound/asound.h	2005-03-24 18:13:29 -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-24 18:13:28 -08:00
+++ b/include/sound/asoundef.h	2005-03-24 18:13:28 -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/core.h b/include/sound/core.h
--- a/include/sound/core.h	2005-03-24 18:13:29 -08:00
+++ b/include/sound/core.h	2005-03-24 18:13:29 -08:00
@@ -490,4 +490,13 @@
 
 #define SNDRV_OSS_VERSION         ((3<<16)|(8<<8)|(1<<4)|(0))	/* 3.8.1a */
 
+/* for easier backward-porting */
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
+#ifndef gameport_set_dev_parent
+#define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev))
+#define gameport_set_port_data(gp,r) ((gp)->port_data = (r))
+#define gameport_get_port_data(gp) (gp)->port_data
+#endif
+#endif
+
 #endif /* __SOUND_CORE_H */
diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	2005-03-24 18:13:28 -08:00
+++ b/include/sound/emu10k1.h	2005-03-24 18:13:28 -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						*/
 /************************************************************************************************/
@@ -995,6 +1035,23 @@
 	void (*interrupt)(emu10k1_t *emu, unsigned int status);
 } emu10k1_midi_t;
 
+typedef struct {
+	u32 vendor;
+	u32 device;
+	u32 subsystem;
+	unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */
+	unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
+	unsigned char ca0102_chip;  /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
+	unsigned char ca0108_chip;  /* Audigy 2 Value */
+	unsigned char ca0151_chip;  /* P16V */
+	unsigned char spk71;        /* Has 7.1 speakers */
+	unsigned char spdif_bug;    /* Has Spdif phasing bug */
+	unsigned char ac97_chip;    /* Has an AC97 chip */
+	unsigned char ecard;        /* APS EEPROM */
+	char * driver;
+	char * name;
+} emu_chip_details_t;
+
 struct _snd_emu10k1 {
 	int irq;
 
@@ -1004,6 +1061,7 @@
 	    tos_link: 1,			/* tos link detected */
 	    rear_ac97: 1,			/* rear channels are on AC'97 */
 	    spk71:1;				/* 7.1 configuration (Audigy 2 ZS) */
+	const emu_chip_details_t *card_capabilities;	/* Contains profile of card capabilities */
 	unsigned int audigy;			/* is Audigy? */
 	unsigned int revision;			/* chip revision */
 	unsigned int serial;			/* serial number */
@@ -1014,6 +1072,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 +1096,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 +1108,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 +1151,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 +1171,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-24 18:13:28 -08:00
+++ b/include/sound/rawmidi.h	2005-03-24 18:13:28 -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-24 18:13:29 -08:00
+++ b/include/sound/seq_midi_emul.h	2005-03-24 18:13:29 -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/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	2005-03-24 18:13:29 -08:00
+++ b/include/sound/version.h	2005-03-24 18:13:29 -08:00
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.8"
-#define CONFIG_SND_DATE " (Thu Jan 13 09:39:32 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.9rc2"
+#define CONFIG_SND_DATE "  (Thu Mar 24 10:33:39 2005 UTC)"
diff -Nru a/sound/core/control.c b/sound/core/control.c
--- a/sound/core/control.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/control.c	2005-03-24 18:13:28 -08:00
@@ -519,20 +519,25 @@
 static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
 			     unsigned int cmd, void __user *arg)
 {
-	snd_ctl_card_info_t info;
+	snd_ctl_card_info_t *info;
 
-	memset(&info, 0, sizeof(info));
+	info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+	if (! info)
+		return -ENOMEM;
 	down_read(&snd_ioctl_rwsem);
-	info.card = card->number;
-	strlcpy(info.id, card->id, sizeof(info.id));
-	strlcpy(info.driver, card->driver, sizeof(info.driver));
-	strlcpy(info.name, card->shortname, sizeof(info.name));
-	strlcpy(info.longname, card->longname, sizeof(info.longname));
-	strlcpy(info.mixername, card->mixername, sizeof(info.mixername));
-	strlcpy(info.components, card->components, sizeof(info.components));
+	info->card = card->number;
+	strlcpy(info->id, card->id, sizeof(info->id));
+	strlcpy(info->driver, card->driver, sizeof(info->driver));
+	strlcpy(info->name, card->shortname, sizeof(info->name));
+	strlcpy(info->longname, card->longname, sizeof(info->longname));
+	strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
+	strlcpy(info->components, card->components, sizeof(info->components));
 	up_read(&snd_ioctl_rwsem);
-	if (copy_to_user(arg, &info, sizeof(snd_ctl_card_info_t)))
+	if (copy_to_user(arg, info, sizeof(snd_ctl_card_info_t))) {
+		kfree(info);
 		return -EFAULT;
+	}
+	kfree(info);
 	return 0;
 }
 
diff -Nru a/sound/core/info.c b/sound/core/info.c
--- a/sound/core/info.c	2005-03-24 18:13:29 -08:00
+++ b/sound/core/info.c	2005-03-24 18:13:29 -08:00
@@ -92,19 +92,18 @@
 int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
 {
 	va_list args;
-	int res;
-	char sbuffer[512];
+	int len, res;
 
 	if (buffer->stop || buffer->error)
 		return 0;
+	len = buffer->len - buffer->size;
 	va_start(args, fmt);
-	res = vscnprintf(sbuffer, sizeof(sbuffer), fmt, args);
+	res = vsnprintf(buffer->curr, len, fmt, args);
 	va_end(args);
-	if (buffer->size + res >= buffer->len) {
+	if (res >= len) {
 		buffer->stop = 1;
 		return 0;
 	}
-	strcpy(buffer->curr, sbuffer);
 	buffer->curr += res;
 	buffer->size += res;
 	return res;
diff -Nru a/sound/core/misc.c b/sound/core/misc.c
--- a/sound/core/misc.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/misc.c	2005-03-24 18:13:28 -08:00
@@ -40,7 +40,6 @@
 void snd_verbose_printk(const char *file, int line, const char *format, ...)
 {
 	va_list args;
-	char tmpbuf[512];
 	
 	if (format[0] == '<' && format[1] >= '0' && format[1] <= '9' && format[2] == '>') {
 		char tmp[] = "<0>";
@@ -51,9 +50,8 @@
 		printk("ALSA %s:%d: ", file, line);
 	}
 	va_start(args, format);
-	vsnprintf(tmpbuf, sizeof(tmpbuf), format, args);
+	vprintk(format, args);
 	va_end(args);
-	printk(tmpbuf);
 }
 #endif
 
@@ -61,7 +59,6 @@
 void snd_verbose_printd(const char *file, int line, const char *format, ...)
 {
 	va_list args;
-	char tmpbuf[512];
 	
 	if (format[0] == '<' && format[1] >= '0' && format[1] <= '9' && format[2] == '>') {
 		char tmp[] = "<0>";
@@ -72,9 +69,8 @@
 		printk(KERN_DEBUG "ALSA %s:%d: ", file, line);
 	}
 	va_start(args, format);
-	vsnprintf(tmpbuf, sizeof(tmpbuf), format, args);
+	vprintk(format, args);
 	va_end(args);
-	printk(tmpbuf);
 
 }
 #endif
diff -Nru a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
--- a/sound/core/oss/mixer_oss.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/oss/mixer_oss.c	2005-03-24 18:13:28 -08:00
@@ -857,7 +857,7 @@
 
 static int snd_mixer_oss_build_test(snd_mixer_oss_t *mixer, struct slot *slot, const char *name, int index, int item)
 {
-	snd_ctl_elem_info_t info;
+	snd_ctl_elem_info_t *info;
 	snd_kcontrol_t *kcontrol;
 	snd_card_t *card = mixer->card;
 	int err;
@@ -868,15 +868,22 @@
 		up_read(&card->controls_rwsem);
 		return 0;
 	}
-	if ((err = kcontrol->info(kcontrol, &info)) < 0) {
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (! info) {
 		up_read(&card->controls_rwsem);
+		return -ENOMEM;
+	}
+	if ((err = kcontrol->info(kcontrol, info)) < 0) {
+		up_read(&card->controls_rwsem);
+		kfree(info);
 		return err;
 	}
 	slot->numid[item] = kcontrol->id.numid;
 	up_read(&card->controls_rwsem);
-	if (info.count > slot->channels)
-		slot->channels = info.count;
+	if (info->count > slot->channels)
+		slot->channels = info->count;
 	slot->present |= 1 << item;
+	kfree(info);
 	return 0;
 }
 
@@ -961,10 +968,16 @@
 		return 0;
 	down_read(&mixer->card->controls_rwsem);
 	if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) {
-		snd_ctl_elem_info_t uinfo;
+		snd_ctl_elem_info_t *uinfo;
 
-		memset(&uinfo, 0, sizeof(uinfo));
-		if (kctl->info(kctl, &uinfo)) {
+		uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL);
+		if (! uinfo) {
+			up_read(&mixer->card->controls_rwsem);
+			return -ENOMEM;
+		}
+			
+		memset(uinfo, 0, sizeof(*uinfo));
+		if (kctl->info(kctl, uinfo)) {
 			up_read(&mixer->card->controls_rwsem);
 			return 0;
 		}
@@ -974,21 +987,22 @@
 		if (!strcmp(str, "Master Mono"))
 			strcpy(str, "Mix Mono");
 		slot.capture_item = 0;
-		if (!strcmp(uinfo.value.enumerated.name, str)) {
+		if (!strcmp(uinfo->value.enumerated.name, str)) {
 			slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;
 		} else {
-			for (slot.capture_item = 1; slot.capture_item < uinfo.value.enumerated.items; slot.capture_item++) {
-				uinfo.value.enumerated.item = slot.capture_item;
-				if (kctl->info(kctl, &uinfo)) {
+			for (slot.capture_item = 1; slot.capture_item < uinfo->value.enumerated.items; slot.capture_item++) {
+				uinfo->value.enumerated.item = slot.capture_item;
+				if (kctl->info(kctl, uinfo)) {
 					up_read(&mixer->card->controls_rwsem);
 					return 0;
 				}
-				if (!strcmp(uinfo.value.enumerated.name, str)) {
+				if (!strcmp(uinfo->value.enumerated.name, str)) {
 					slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;
 					break;
 				}
 			}
 		}
+		kfree(uinfo);
 	}
 	up_read(&mixer->card->controls_rwsem);
 	if (slot.present != 0) {
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/oss/pcm_oss.c	2005-03-24 18:13:28 -08:00
@@ -2294,7 +2294,7 @@
 				   snd_info_buffer_t * buffer)
 {
 	snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
-	char line[256], str[32], task_name[32], *ptr;
+	char line[128], str[32], task_name[32], *ptr;
 	int idx1;
 	snd_pcm_oss_setup_t *setup, *setup1, template;
 
diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c	2005-03-24 18:13:29 -08:00
+++ b/sound/core/pcm.c	2005-03-24 18:13:29 -08:00
@@ -270,25 +270,35 @@
 #ifdef CONFIG_PROC_FS
 static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buffer_t *buffer)
 {
-	snd_pcm_info_t info;
+	snd_pcm_info_t *info;
 	int err;
+
 	snd_runtime_check(substream, return);
-	err = snd_pcm_info(substream, &info);
+
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (! info) {
+		printk(KERN_DEBUG "snd_pcm_proc_info_read: cannot malloc\n");
+		return;
+	}
+
+	err = snd_pcm_info(substream, info);
 	if (err < 0) {
 		snd_iprintf(buffer, "error %d\n", err);
+		kfree(info);
 		return;
 	}
-	snd_iprintf(buffer, "card: %d\n", info.card);
-	snd_iprintf(buffer, "device: %d\n", info.device);
-	snd_iprintf(buffer, "subdevice: %d\n", info.subdevice);
-	snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info.stream));
-	snd_iprintf(buffer, "id: %s\n", info.id);
-	snd_iprintf(buffer, "name: %s\n", info.name);
-	snd_iprintf(buffer, "subname: %s\n", info.subname);
-	snd_iprintf(buffer, "class: %d\n", info.dev_class);
-	snd_iprintf(buffer, "subclass: %d\n", info.dev_subclass);
-	snd_iprintf(buffer, "subdevices_count: %d\n", info.subdevices_count);
-	snd_iprintf(buffer, "subdevices_avail: %d\n", info.subdevices_avail);
+	snd_iprintf(buffer, "card: %d\n", info->card);
+	snd_iprintf(buffer, "device: %d\n", info->device);
+	snd_iprintf(buffer, "subdevice: %d\n", info->subdevice);
+	snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info->stream));
+	snd_iprintf(buffer, "id: %s\n", info->id);
+	snd_iprintf(buffer, "name: %s\n", info->name);
+	snd_iprintf(buffer, "subname: %s\n", info->subname);
+	snd_iprintf(buffer, "class: %d\n", info->dev_class);
+	snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass);
+	snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count);
+	snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail);
+	kfree(info);
 }
 
 static void snd_pcm_stream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/pcm_native.c	2005-03-24 18:13:28 -08:00
@@ -113,10 +113,18 @@
 
 int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user * _info)
 {
-	snd_pcm_info_t info;
-	int err = snd_pcm_info(substream, &info);
-	if (copy_to_user(_info, &info, sizeof(info)))
-		return -EFAULT;
+	snd_pcm_info_t *info;
+	int err;
+
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (! info)
+		return -ENOMEM;
+	err = snd_pcm_info(substream, info);
+	if (err >= 0) {
+		if (copy_to_user(_info, info, sizeof(*info)))
+			err = -EFAULT;
+	}
+	kfree(info);
 	return err;
 }
 
@@ -1038,7 +1046,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 +1071,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-24 18:13:28 -08:00
+++ b/sound/core/rawmidi.c	2005-03-24 18:13:28 -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/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
--- a/sound/core/seq/oss/seq_oss_init.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/seq/oss/seq_oss_init.c	2005-03-24 18:13:28 -08:00
@@ -66,10 +66,17 @@
 {
 	int rc;
 	snd_seq_client_callback_t callback;
-	snd_seq_client_info_t info;
-	snd_seq_port_info_t port;
+	snd_seq_client_info_t *info;
+	snd_seq_port_info_t *port;
 	snd_seq_port_callback_t port_callback;
 
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	port = kmalloc(sizeof(*port), GFP_KERNEL);
+	if (!info || !port) {
+		rc = -ENOMEM;
+		goto __error;
+	}
+
 	/* create ALSA client */
 	memset(&callback, 0, sizeof(callback));
 
@@ -79,38 +86,38 @@
 
 	rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS, &callback);
 	if (rc < 0)
-		return rc;
+		goto __error;
 
 	system_client = rc;
 	debug_printk(("new client = %d\n", rc));
 
 	/* set client information */
-	memset(&info, 0, sizeof(info));
-	info.client = system_client;
-	info.type = KERNEL_CLIENT;
-	strcpy(info.name, "OSS sequencer");
+	memset(info, 0, sizeof(*info));
+	info->client = system_client;
+	info->type = KERNEL_CLIENT;
+	strcpy(info->name, "OSS sequencer");
 
-	rc = call_ctl(SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &info);
+	rc = call_ctl(SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, info);
 
 	/* look up midi devices */
 	snd_seq_oss_midi_lookup_ports(system_client);
 
 	/* create annoucement receiver port */
-	memset(&port, 0, sizeof(port));
-	strcpy(port.name, "Receiver");
-	port.addr.client = system_client;
-	port.capability = SNDRV_SEQ_PORT_CAP_WRITE; /* receive only */
-	port.type = 0;
+	memset(port, 0, sizeof(*port));
+	strcpy(port->name, "Receiver");
+	port->addr.client = system_client;
+	port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* receive only */
+	port->type = 0;
 
 	memset(&port_callback, 0, sizeof(port_callback));
 	/* don't set port_callback.owner here. otherwise the module counter
 	 * is incremented and we can no longer release the module..
 	 */
 	port_callback.event_input = receive_announce;
-	port.kernel = &port_callback;
+	port->kernel = &port_callback;
 	
-	call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, &port);
-	if ((system_port = port.addr.port) >= 0) {
+	call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, port);
+	if ((system_port = port->addr.port) >= 0) {
 		snd_seq_port_subscribe_t subs;
 
 		memset(&subs, 0, sizeof(subs));
@@ -120,9 +127,12 @@
 		subs.dest.port = system_port;
 		call_ctl(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs);
 	}
+	rc = 0;
 
-
-	return 0;
+ __error:
+	kfree(port);
+	kfree(info);
+	return rc;
 }
 
 
diff -Nru a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
--- a/sound/core/seq/oss/seq_oss_midi.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/seq/oss/seq_oss_midi.c	2005-03-24 18:13:28 -08:00
@@ -73,26 +73,27 @@
 int __init
 snd_seq_oss_midi_lookup_ports(int client)
 {
-	snd_seq_system_info_t sysinfo;
-	snd_seq_client_info_t clinfo;
-	snd_seq_port_info_t pinfo;
-	int rc;
+	snd_seq_client_info_t *clinfo;
+	snd_seq_port_info_t *pinfo;
 
-	rc = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SYSTEM_INFO, &sysinfo);
-	if (rc < 0)
-		return rc;
-	
-	memset(&clinfo, 0, sizeof(clinfo));
-	memset(&pinfo, 0, sizeof(pinfo));
-	clinfo.client = -1;
-	while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, &clinfo) == 0) {
-		if (clinfo.client == client)
+	clinfo = kcalloc(1, sizeof(*clinfo), GFP_KERNEL);
+	pinfo = kcalloc(1, sizeof(*pinfo), GFP_KERNEL);
+	if (! clinfo || ! pinfo) {
+		kfree(clinfo);
+		kfree(pinfo);
+		return -ENOMEM;
+	}
+	clinfo->client = -1;
+	while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) {
+		if (clinfo->client == client)
 			continue; /* ignore myself */
-		pinfo.addr.client = clinfo.client;
-		pinfo.addr.port = -1;
-		while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, &pinfo) == 0)
-			snd_seq_oss_midi_check_new_port(&pinfo);
+		pinfo->addr.client = clinfo->client;
+		pinfo->addr.port = -1;
+		while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0)
+			snd_seq_oss_midi_check_new_port(pinfo);
 	}
+	kfree(clinfo);
+	kfree(pinfo);
 	return 0;
 }
 
diff -Nru a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
--- a/sound/core/seq/seq_midi.c	2005-03-24 18:13:29 -08:00
+++ b/sound/core/seq/seq_midi.c	2005-03-24 18:13:29 -08:00
@@ -289,8 +289,8 @@
 {
 	seq_midisynth_client_t *client;
 	seq_midisynth_t *msynth, *ms;
-	snd_seq_port_info_t port;
-	snd_rawmidi_info_t info;
+	snd_seq_port_info_t *port;
+	snd_rawmidi_info_t *info;
 	int newclient = 0;
 	unsigned int p, ports;
 	snd_seq_client_callback_t callbacks;
@@ -300,20 +300,25 @@
 	unsigned int input_count = 0, output_count = 0;
 
 	snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL);
-	info.device = device;
-	info.stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
-	info.subdevice = 0;
-	if (snd_rawmidi_info_select(card, &info) >= 0)
-		output_count = info.subdevices_count;
-	info.stream = SNDRV_RAWMIDI_STREAM_INPUT;
-	if (snd_rawmidi_info_select(card, &info) >= 0) {
-		input_count = info.subdevices_count;
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (! info)
+		return -ENOMEM;
+	info->device = device;
+	info->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
+	info->subdevice = 0;
+	if (snd_rawmidi_info_select(card, info) >= 0)
+		output_count = info->subdevices_count;
+	info->stream = SNDRV_RAWMIDI_STREAM_INPUT;
+	if (snd_rawmidi_info_select(card, info) >= 0) {
+		input_count = info->subdevices_count;
 	}
 	ports = output_count;
 	if (ports < input_count)
 		ports = input_count;
-	if (ports == 0)
+	if (ports == 0) {
+		kfree(info);
 		return -ENODEV;
+	}
 	if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
 		ports = 256 / SNDRV_RAWMIDI_DEVICES;
 
@@ -324,6 +329,7 @@
 		client = kcalloc(1, sizeof(*client), GFP_KERNEL);
 		if (client == NULL) {
 			up(&register_mutex);
+			kfree(info);
 			return -ENOMEM;
 		}
 		memset(&callbacks, 0, sizeof(callbacks));
@@ -333,14 +339,16 @@
 		if (client->seq_client < 0) {
 			kfree(client);
 			up(&register_mutex);
+			kfree(info);
 			return -ENOMEM;
 		}
-		set_client_name(client, card, &info);
+		set_client_name(client, card, info);
 	} else if (device == 0)
-		set_client_name(client, card, &info); /* use the first device's name */
+		set_client_name(client, card, info); /* use the first device's name */
 
 	msynth = kcalloc(ports, sizeof(seq_midisynth_t), GFP_KERNEL);
-	if (msynth == NULL)
+	port = kmalloc(sizeof(*port), GFP_KERNEL);
+	if (msynth == NULL || port == NULL)
 		goto __nomem;
 
 	for (p = 0; p < ports; p++) {
@@ -350,42 +358,42 @@
 			goto __nomem;
 
 		/* declare port */
-		memset(&port, 0, sizeof(port));
-		port.addr.client = client->seq_client;
-		port.addr.port = device * (256 / SNDRV_RAWMIDI_DEVICES) + p;
-		port.flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
-		memset(&info, 0, sizeof(info));
-		info.device = device;
+		memset(port, 0, sizeof(*port));
+		port->addr.client = client->seq_client;
+		port->addr.port = device * (256 / SNDRV_RAWMIDI_DEVICES) + p;
+		port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
+		memset(info, 0, sizeof(*info));
+		info->device = device;
 		if (p < output_count)
-			info.stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
+			info->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
 		else
-			info.stream = SNDRV_RAWMIDI_STREAM_INPUT;
-		info.subdevice = p;
-		if (snd_rawmidi_info_select(card, &info) >= 0)
-			strcpy(port.name, info.subname);
-		if (! port.name[0]) {
-			if (info.name[0]) {
+			info->stream = SNDRV_RAWMIDI_STREAM_INPUT;
+		info->subdevice = p;
+		if (snd_rawmidi_info_select(card, info) >= 0)
+			strcpy(port->name, info->subname);
+		if (! port->name[0]) {
+			if (info->name[0]) {
 				if (ports > 1)
-					snprintf(port.name, sizeof(port.name), "%s-%d", info.name, p);
+					snprintf(port->name, sizeof(port->name), "%s-%d", info->name, p);
 				else
-					snprintf(port.name, sizeof(port.name), "%s", info.name);
+					snprintf(port->name, sizeof(port->name), "%s", info->name);
 			} else {
 				/* last resort */
 				if (ports > 1)
-					sprintf(port.name, "MIDI %d-%d-%d", card->number, device, p);
+					sprintf(port->name, "MIDI %d-%d-%d", card->number, device, p);
 				else
-					sprintf(port.name, "MIDI %d-%d", card->number, device);
+					sprintf(port->name, "MIDI %d-%d", card->number, device);
 			}
 		}
-		if ((info.flags & SNDRV_RAWMIDI_INFO_OUTPUT) && p < output_count)
-			port.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
-		if ((info.flags & SNDRV_RAWMIDI_INFO_INPUT) && p < input_count)
-			port.capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
-		if ((port.capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
-		    info.flags & SNDRV_RAWMIDI_INFO_DUPLEX)
-			port.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
-		port.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
-		port.midi_channels = 16;
+		if ((info->flags & SNDRV_RAWMIDI_INFO_OUTPUT) && p < output_count)
+			port->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
+		if ((info->flags & SNDRV_RAWMIDI_INFO_INPUT) && p < input_count)
+			port->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
+		if ((port->capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
+		    info->flags & SNDRV_RAWMIDI_INFO_DUPLEX)
+			port->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
+		port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
+		port->midi_channels = 16;
 		memset(&pcallbacks, 0, sizeof(pcallbacks));
 		pcallbacks.owner = THIS_MODULE;
 		pcallbacks.private_data = ms;
@@ -394,11 +402,11 @@
 		pcallbacks.use = midisynth_use;
 		pcallbacks.unuse = midisynth_unuse;
 		pcallbacks.event_input = event_process_midi;
-		port.kernel = &pcallbacks;
-		if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, &port)<0)
+		port->kernel = &pcallbacks;
+		if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, port)<0)
 			goto __nomem;
 		ms->seq_client = client->seq_client;
-		ms->seq_port = port.addr.port;
+		ms->seq_port = port->addr.port;
 	}
 	client->ports_per_device[device] = ports;
 	client->ports[device] = msynth;
@@ -418,6 +426,8 @@
 		snd_seq_delete_kernel_client(client->seq_client);
 		kfree(client);
 	}
+	kfree(info);
+	kfree(port);
 	up(&register_mutex);
 	return -ENOMEM;
 }
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-24 18:13:29 -08:00
+++ b/sound/core/seq/seq_midi_emul.c	2005-03-24 18:13:29 -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/seq/seq_system.c b/sound/core/seq/seq_system.c
--- a/sound/core/seq/seq_system.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/seq/seq_system.c	2005-03-24 18:13:28 -08:00
@@ -123,13 +123,19 @@
 
 	snd_seq_client_callback_t callbacks;
 	snd_seq_port_callback_t pcallbacks;
-	snd_seq_client_info_t inf;
-	snd_seq_port_info_t port;
+	snd_seq_client_info_t *inf;
+	snd_seq_port_info_t *port;
+
+	inf = kcalloc(1, sizeof(*inf), GFP_KERNEL);
+	port = kcalloc(1, sizeof(*port), GFP_KERNEL);
+	if (! inf || ! port) {
+		kfree(inf);
+		kfree(port);
+		return -ENOMEM;
+	}
 
 	memset(&callbacks, 0, sizeof(callbacks));
 	memset(&pcallbacks, 0, sizeof(pcallbacks));
-	memset(&inf, 0, sizeof(inf));
-	memset(&port, 0, sizeof(port));
 	pcallbacks.owner = THIS_MODULE;
 	pcallbacks.event_input = event_input_timer;
 
@@ -138,33 +144,35 @@
 	sysclient = snd_seq_create_kernel_client(NULL, 0, &callbacks);
 
 	/* set our name */
-	inf.client = 0;
-	inf.type = KERNEL_CLIENT;
-	strcpy(inf.name, "System");
-	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &inf);
+	inf->client = 0;
+	inf->type = KERNEL_CLIENT;
+	strcpy(inf->name, "System");
+	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, inf);
 
 	/* register timer */
-	strcpy(port.name, "Timer");
-	port.capability = SNDRV_SEQ_PORT_CAP_WRITE; /* accept queue control */
-	port.capability |= SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast */
-	port.kernel = &pcallbacks;
-	port.type = 0;
-	port.flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
-	port.addr.client = sysclient;
-	port.addr.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
-	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, &port);
+	strcpy(port->name, "Timer");
+	port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* accept queue control */
+	port->capability |= SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast */
+	port->kernel = &pcallbacks;
+	port->type = 0;
+	port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
+	port->addr.client = sysclient;
+	port->addr.port = SNDRV_SEQ_PORT_SYSTEM_TIMER;
+	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
 
 	/* register announcement port */
-	strcpy(port.name, "Announce");
-	port.capability = SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast only */
-	port.kernel = NULL;
-	port.type = 0;
-	port.flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
-	port.addr.client = sysclient;
-	port.addr.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
-	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, &port);
-	announce_port = port.addr.port;
+	strcpy(port->name, "Announce");
+	port->capability = SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast only */
+	port->kernel = NULL;
+	port->type = 0;
+	port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
+	port->addr.client = sysclient;
+	port->addr.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
+	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
+	announce_port = port->addr.port;
 
+	kfree(inf);
+	kfree(port);
 	return 0;
 }
 
diff -Nru a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
--- a/sound/core/seq/seq_virmidi.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/seq/seq_virmidi.c	2005-03-24 18:13:28 -08:00
@@ -354,39 +354,48 @@
 	int client;
 	snd_seq_client_callback_t callbacks;
 	snd_seq_port_callback_t pcallbacks;
-	snd_seq_client_info_t info;
-	snd_seq_port_info_t pinfo;
+	snd_seq_client_info_t *info;
+	snd_seq_port_info_t *pinfo;
 	int err;
 
 	if (rdev->client >= 0)
 		return 0;
 
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL);
+	if (! info || ! pinfo) {
+		err = -ENOMEM;
+		goto __error;
+	}
+
 	memset(&callbacks, 0, sizeof(callbacks));
 	callbacks.private_data = rdev;
 	callbacks.allow_input = 1;
 	callbacks.allow_output = 1;
 	client = snd_seq_create_kernel_client(rdev->card, rdev->device, &callbacks);
-	if (client < 0)
-		return client;
+	if (client < 0) {
+		err = client;
+		goto __error;
+	}
 	rdev->client = client;
 
 	/* set client name */
-	memset(&info, 0, sizeof(info));
-	info.client = client;
-	info.type = KERNEL_CLIENT;
-	sprintf(info.name, "%s %d-%d", rdev->rmidi->name, rdev->card->number, rdev->device);
+	memset(info, 0, sizeof(*info));
+	info->client = client;
+	info->type = KERNEL_CLIENT;
+	sprintf(info->name, "%s %d-%d", rdev->rmidi->name, rdev->card->number, rdev->device);
 	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &info);
 
 	/* create a port */
-	memset(&pinfo, 0, sizeof(pinfo));
-	pinfo.addr.client = client;
-	sprintf(pinfo.name, "VirMIDI %d-%d", rdev->card->number, rdev->device);
+	memset(pinfo, 0, sizeof(*pinfo));
+	pinfo->addr.client = client;
+	sprintf(pinfo->name, "VirMIDI %d-%d", rdev->card->number, rdev->device);
 	/* set all capabilities */
-	pinfo.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
-	pinfo.capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
-	pinfo.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
-	pinfo.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
-	pinfo.midi_channels = 16;
+	pinfo->capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
+	pinfo->capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
+	pinfo->capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
+	pinfo->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
+	pinfo->midi_channels = 16;
 	memset(&pcallbacks, 0, sizeof(pcallbacks));
 	pcallbacks.owner = THIS_MODULE;
 	pcallbacks.private_data = rdev;
@@ -395,16 +404,21 @@
 	pcallbacks.use = snd_virmidi_use;
 	pcallbacks.unuse = snd_virmidi_unuse;
 	pcallbacks.event_input = snd_virmidi_event_input;
-	pinfo.kernel = &pcallbacks;
+	pinfo->kernel = &pcallbacks;
 	err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, &pinfo);
 	if (err < 0) {
 		snd_seq_delete_kernel_client(client);
 		rdev->client = -1;
-		return err;
+		goto __error;
 	}
 
-	rdev->port = pinfo.addr.port;
-	return 0;	/* success */
+	rdev->port = pinfo->addr.port;
+	err = 0; /* success */
+
+ __error:
+	kfree(info);
+	kfree(pinfo);
+	return err;
 }
 
 
diff -Nru a/sound/core/timer.c b/sound/core/timer.c
--- a/sound/core/timer.c	2005-03-24 18:13:28 -08:00
+++ b/sound/core/timer.c	2005-03-24 18:13:28 -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,
@@ -1342,39 +1347,45 @@
 
 static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
 {
-	snd_timer_ginfo_t ginfo;
+	snd_timer_ginfo_t *ginfo;
 	snd_timer_id_t tid;
 	snd_timer_t *t;
 	struct list_head *p;
 	int err = 0;
 
-	if (copy_from_user(&ginfo, _ginfo, sizeof(ginfo)))
+	ginfo = kmalloc(sizeof(*ginfo), GFP_KERNEL);
+	if (! ginfo)
+		return -ENOMEM;
+	if (copy_from_user(ginfo, _ginfo, sizeof(*ginfo))) {
+		kfree(ginfo);
 		return -EFAULT;
-	tid = ginfo.tid;
-	memset(&ginfo, 0, sizeof(ginfo));
-	ginfo.tid = tid;
+	}
+	tid = ginfo->tid;
+	memset(ginfo, 0, sizeof(*ginfo));
+	ginfo->tid = tid;
 	down(&register_mutex);
 	t = snd_timer_find(&tid);
 	if (t != NULL) {
-		ginfo.card = t->card ? t->card->number : -1;
+		ginfo->card = t->card ? t->card->number : -1;
 		if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
-			ginfo.flags |= SNDRV_TIMER_FLG_SLAVE;
-		strlcpy(ginfo.id, t->id, sizeof(ginfo.id));
-		strlcpy(ginfo.name, t->name, sizeof(ginfo.name));
-		ginfo.resolution = t->hw.resolution;
+			ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
+		strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
+		strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
+		ginfo->resolution = t->hw.resolution;
 		if (t->hw.resolution_min > 0) {
-			ginfo.resolution_min = t->hw.resolution_min;
-			ginfo.resolution_max = t->hw.resolution_max;
+			ginfo->resolution_min = t->hw.resolution_min;
+			ginfo->resolution_max = t->hw.resolution_max;
 		}
 		list_for_each(p, &t->open_list_head) {
-			ginfo.clients++;
+			ginfo->clients++;
 		}
 	} else {
 		err = -ENODEV;
 	}
 	up(&register_mutex);
-	if (err >= 0 && copy_to_user(_ginfo, &ginfo, sizeof(ginfo)))
+	if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
 		err = -EFAULT;
+	kfree(ginfo);
 	return err;
 }
 
@@ -1488,23 +1499,28 @@
 static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
 {
 	snd_timer_user_t *tu;
-	snd_timer_info_t info;
+	snd_timer_info_t *info;
 	snd_timer_t *t;
+	int err = 0;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	t = tu->timeri->timer;
 	snd_assert(t != NULL, return -ENXIO);
-	memset(&info, 0, sizeof(info));
-	info.card = t->card ? t->card->number : -1;
+
+	info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+	if (! info)
+		return -ENOMEM;
+	info->card = t->card ? t->card->number : -1;
 	if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
-		info.flags |= SNDRV_TIMER_FLG_SLAVE;
-	strlcpy(info.id, t->id, sizeof(info.id));
-	strlcpy(info.name, t->name, sizeof(info.name));
-	info.resolution = t->hw.resolution;
-	if (copy_to_user(_info, &info, sizeof(*_info)))
-		return -EFAULT;
-	return 0;
+		info->flags |= SNDRV_TIMER_FLG_SLAVE;
+	strlcpy(info->id, t->id, sizeof(info->id));
+	strlcpy(info->name, t->name, sizeof(info->name));
+	info->resolution = t->hw.resolution;
+	if (copy_to_user(_info, info, sizeof(*_info)))
+		err = -EFAULT;
+	kfree(info);
+	return err;
 }
 
 static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
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-24 18:13:28 -08:00
+++ b/sound/drivers/mpu401/mpu401_uart.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/drivers/mtpav.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/drivers/serial-u16550.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/i2c/other/ak4114.c	2005-03-24 18:13:28 -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/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
--- a/sound/i2c/other/ak4xxx-adda.c	2005-03-24 18:13:29 -08:00
+++ b/sound/i2c/other/ak4xxx-adda.c	2005-03-24 18:13:29 -08:00
@@ -366,113 +366,121 @@
 int snd_akm4xxx_build_controls(akm4xxx_t *ak)
 {
 	unsigned int idx, num_emphs;
+	snd_kcontrol_t *ctl;
 	int err;
 
+	ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
+	if (! ctl)
+		return -ENOMEM;
+
 	for (idx = 0; idx < ak->num_dacs; ++idx) {
-		snd_kcontrol_t ctl;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "DAC Volume");
-		ctl.id.index = idx + ak->idx_offset * 2;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.count = 1;
-		ctl.info = snd_akm4xxx_volume_info;
-		ctl.get = snd_akm4xxx_volume_get;
-		ctl.put = snd_akm4xxx_volume_put;
+		memset(ctl, 0, sizeof(*ctl));
+		strcpy(ctl->id.name, "DAC Volume");
+		ctl->id.index = idx + ak->idx_offset * 2;
+		ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+		ctl->count = 1;
+		ctl->info = snd_akm4xxx_volume_info;
+		ctl->get = snd_akm4xxx_volume_get;
+		ctl->put = snd_akm4xxx_volume_put;
 		switch (ak->type) {
 		case SND_AK4524:
-			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */
+			ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0, 127); /* register 6 & 7 */
 			break;
 		case SND_AK4528:
-			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
+			ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
 			break;
 		case SND_AK4529: {
 			int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */
-			ctl.private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
+			ctl->private_value = AK_COMPOSE(0, val, 0, 255) | AK_INVERT;
 			break;
 		}
 		case SND_AK4355:
-			ctl.private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */
+			ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */
 			break;
 		case SND_AK4358:
 			if (idx >= 6)
-				ctl.private_value = AK_COMPOSE(0, idx + 5, 0, 255); /* register 4-9, chip #0 only */
+				ctl->private_value = AK_COMPOSE(0, idx + 5, 0, 255); /* register 4-9, chip #0 only */
 			else
-				ctl.private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */
+				ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); /* register 4-9, chip #0 only */
 			break;
 		case SND_AK4381:
-			ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */
+			ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 3, 0, 255); /* register 3 & 4 */
 			break;
 		default:
-			return -EINVAL;
-			}
-		ctl.private_data = ak;
-		if ((err = snd_ctl_add(ak->card, snd_ctl_new(&ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
-			return err;
+			err = -EINVAL;
+			goto __error;
+		}
+		ctl->private_data = ak;
+		if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
+			goto __error;
 	}
 	for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) {
-		snd_kcontrol_t ctl;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "ADC Volume");
-		ctl.id.index = idx + ak->idx_offset * 2;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.count = 1;
-		ctl.info = snd_akm4xxx_volume_info;
-		ctl.get = snd_akm4xxx_volume_get;
-		ctl.put = snd_akm4xxx_volume_put;
-		ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
-		ctl.private_data = ak;
-		if ((err = snd_ctl_add(ak->card, snd_ctl_new(&ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
-			return err;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "IPGA Analog Capture Volume");
-		ctl.id.index = idx + ak->idx_offset * 2;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.count = 1;
-		ctl.info = snd_akm4xxx_ipga_gain_info;
-		ctl.get = snd_akm4xxx_ipga_gain_get;
-		ctl.put = snd_akm4xxx_ipga_gain_put;
-		ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */
-		ctl.private_data = ak;
-		if ((err = snd_ctl_add(ak->card, snd_ctl_new(&ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
-			return err;
+		memset(ctl, 0, sizeof(*ctl));
+		strcpy(ctl->id.name, "ADC Volume");
+		ctl->id.index = idx + ak->idx_offset * 2;
+		ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+		ctl->count = 1;
+		ctl->info = snd_akm4xxx_volume_info;
+		ctl->get = snd_akm4xxx_volume_get;
+		ctl->put = snd_akm4xxx_volume_put;
+		ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 127); /* register 4 & 5 */
+		ctl->private_data = ak;
+		if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
+			goto __error;
+
+		memset(ctl, 0, sizeof(*ctl));
+		strcpy(ctl->id.name, "IPGA Analog Capture Volume");
+		ctl->id.index = idx + ak->idx_offset * 2;
+		ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+		ctl->count = 1;
+		ctl->info = snd_akm4xxx_ipga_gain_info;
+		ctl->get = snd_akm4xxx_ipga_gain_get;
+		ctl->put = snd_akm4xxx_ipga_gain_put;
+		ctl->private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0, 0); /* register 4 & 5 */
+		ctl->private_data = ak;
+		if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
+			goto __error;
 	}
 	if (ak->type == SND_AK4355 || ak->type == SND_AK4358)
 		num_emphs = 1;
 	else
 		num_emphs = ak->num_dacs / 2;
 	for (idx = 0; idx < num_emphs; idx++) {
-		snd_kcontrol_t ctl;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "Deemphasis");
-		ctl.id.index = idx + ak->idx_offset;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.count = 1;
-		ctl.info = snd_akm4xxx_deemphasis_info;
-		ctl.get = snd_akm4xxx_deemphasis_get;
-		ctl.put = snd_akm4xxx_deemphasis_put;
+		memset(ctl, 0, sizeof(*ctl));
+		strcpy(ctl->id.name, "Deemphasis");
+		ctl->id.index = idx + ak->idx_offset;
+		ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+		ctl->count = 1;
+		ctl->info = snd_akm4xxx_deemphasis_info;
+		ctl->get = snd_akm4xxx_deemphasis_get;
+		ctl->put = snd_akm4xxx_deemphasis_put;
 		switch (ak->type) {
 		case SND_AK4524:
 		case SND_AK4528:
-			ctl.private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */
+			ctl->private_value = AK_COMPOSE(idx, 3, 0, 0); /* register 3 */
 			break;
 		case SND_AK4529: {
 			int shift = idx == 3 ? 6 : (2 - idx) * 2;
-			ctl.private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */
+			ctl->private_value = AK_COMPOSE(0, 8, shift, 0); /* register 8 with shift */
 			break;
 		}
 		case SND_AK4355:
 		case SND_AK4358:
-			ctl.private_value = AK_COMPOSE(idx, 3, 0, 0);
+			ctl->private_value = AK_COMPOSE(idx, 3, 0, 0);
 			break;
 		case SND_AK4381:
-			ctl.private_value = AK_COMPOSE(idx, 1, 1, 0);
+			ctl->private_value = AK_COMPOSE(idx, 1, 1, 0);
 			break;
 		}
-		ctl.private_data = ak;
-		if ((err = snd_ctl_add(ak->card, snd_ctl_new(&ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
-			return err;
+		ctl->private_data = ak;
+		if ((err = snd_ctl_add(ak->card, snd_ctl_new(ctl, SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE))) < 0)
+			goto __error;
 	}
-	return 0;
+	err = 0;
+
+ __error:
+	kfree(ctl);
+	return err;
 }
 
 static int __init alsa_akm4xxx_module_init(void)
diff -Nru a/sound/isa/Kconfig b/sound/isa/Kconfig
--- a/sound/isa/Kconfig	2005-03-24 18:13:28 -08:00
+++ b/sound/isa/Kconfig	2005-03-24 18:13:28 -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/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
--- a/sound/isa/gus/gus_synth.c	2005-03-24 18:13:28 -08:00
+++ b/sound/isa/gus/gus_synth.c	2005-03-24 18:13:28 -08:00
@@ -214,7 +214,7 @@
 	snd_gus_card_t *gus;
 	int client, i;
 	snd_seq_client_callback_t callbacks;
-	snd_seq_client_info_t cinfo;
+	snd_seq_client_info_t *cinfo;
 	snd_seq_port_subscribe_t sub;
 	snd_iwffff_ops_t *iwops;
 	snd_gf1_ops_t *gf1ops;
@@ -227,21 +227,28 @@
 	init_MUTEX(&gus->register_mutex);
 	gus->gf1.seq_client = -1;
 	
+	cinfo = kmalloc(sizeof(*cinfo), GFP_KERNEL);
+	if (! cinfo)
+		return -ENOMEM;
+
 	/* allocate new client */
 	memset(&callbacks, 0, sizeof(callbacks));
 	callbacks.private_data = gus;
 	callbacks.allow_output = callbacks.allow_input = 1;
 	client = gus->gf1.seq_client =
 			snd_seq_create_kernel_client(gus->card, 1, &callbacks);
-	if (client < 0)
+	if (client < 0) {
+		kfree(cinfo);
 		return client;
+	}
 
 	/* change name of client */
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = client;
-	cinfo.type = KERNEL_CLIENT;
-	sprintf(cinfo.name, gus->interwave ? "AMD InterWave" : "GF1");
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
+	memset(cinfo, 0, sizeof(*cinfo));
+	cinfo->client = client;
+	cinfo->type = KERNEL_CLIENT;
+	sprintf(cinfo->name, gus->interwave ? "AMD InterWave" : "GF1");
+	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, cinfo);
+	kfree(cinfo);
 
 	for (i = 0; i < 4; i++)
 		snd_gus_synth_create_port(gus, i);
diff -Nru a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
--- a/sound/isa/wavefront/wavefront_synth.c	2005-03-24 18:13:29 -08:00
+++ b/sound/isa/wavefront/wavefront_synth.c	2005-03-24 18:13:29 -08:00
@@ -1201,7 +1201,11 @@
 {
 	int i;
 	int num_samples;
-	unsigned char msample_hdr[WF_MSAMPLE_BYTES];
+	unsigned char *msample_hdr;
+
+	msample_hdr = kmalloc(sizeof(WF_MSAMPLE_BYTES), GFP_KERNEL);
+	if (! msample_hdr)
+		return -ENOMEM;
 
 	munge_int32 (header->number, &msample_hdr[0], 2);
 
@@ -1234,11 +1238,13 @@
 			   (unsigned char *) (long) ((num_samples*2)+3),
 			   msample_hdr)) {
 		snd_printk ("download of multisample failed.\n");
+		kfree(msample_hdr);
 		return -(EIO);
 	}
 
 	dev->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
 
+	kfree(msample_hdr);
 	return (0);
 }
 
@@ -1356,78 +1362,103 @@
 
 static int
 wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr)
-
 {
-	wavefront_patch_info header;
+	wavefront_patch_info *header;
+	int err;
 	
-	if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
+	header = kmalloc(sizeof(*header), GFP_KERNEL);
+	if (! header)
+		return -ENOMEM;
+
+	if (copy_from_user (header, addr, sizeof(wavefront_patch_info) -
 			    sizeof(wavefront_any))) {
 		snd_printk ("bad address for load patch.\n");
-		return -(EFAULT);
+		err = -EFAULT;
+		goto __error;
 	}
 
 	DPRINT (WF_DEBUG_LOAD_PATCH, "download "
 				      "Sample type: %d "
 				      "Sample number: %d "
 				      "Sample size: %d\n",
-				      header.subkey,
-				      header.number,
-				      header.size);
+				      header->subkey,
+				      header->number,
+				      header->size);
 
-	switch (header.subkey) {
+	switch (header->subkey) {
 	case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */
 
-		if (copy_from_user (&header.hdr.s, header.hdrptr,
-				    sizeof (wavefront_sample)))
-			return -EFAULT;
+		if (copy_from_user (&header->hdr.s, header->hdrptr,
+				    sizeof (wavefront_sample))) {
+			err = -EFAULT;
+			break;
+		}
 
-		return wavefront_send_sample (dev, &header, header.dataptr, 0);
+		err = wavefront_send_sample (dev, header, header->dataptr, 0);
+		break;
 
 	case WF_ST_MULTISAMPLE:
 
-		if (copy_from_user (&header.hdr.s, header.hdrptr,
-				    sizeof (wavefront_multisample)))
-			return -EFAULT;
-
-		return wavefront_send_multisample (dev, &header);
+		if (copy_from_user (&header->hdr.s, header->hdrptr,
+				    sizeof (wavefront_multisample))) {
+			err = -EFAULT;
+			break;
+		}
 
+		err = wavefront_send_multisample (dev, header);
+		break;
 
 	case WF_ST_ALIAS:
 
-		if (copy_from_user (&header.hdr.a, header.hdrptr,
-				    sizeof (wavefront_alias)))
-			return -EFAULT;
+		if (copy_from_user (&header->hdr.a, header->hdrptr,
+				    sizeof (wavefront_alias))) {
+			err = -EFAULT;
+			break;
+		}
 
-		return wavefront_send_alias (dev, &header);
+		err = wavefront_send_alias (dev, header);
+		break;
 
 	case WF_ST_DRUM:
-		if (copy_from_user (&header.hdr.d, header.hdrptr,
-				    sizeof (wavefront_drum)))
-			return -EFAULT;
+		if (copy_from_user (&header->hdr.d, header->hdrptr,
+				    sizeof (wavefront_drum))) {
+			err = -EFAULT;
+			break;
+		}
 
-		return wavefront_send_drum (dev, &header);
+		err = wavefront_send_drum (dev, header);
+		break;
 
 	case WF_ST_PATCH:
-		if (copy_from_user (&header.hdr.p, header.hdrptr,
-				    sizeof (wavefront_patch)))
-			return -EFAULT;
-
-		return wavefront_send_patch (dev, &header);
+		if (copy_from_user (&header->hdr.p, header->hdrptr,
+				    sizeof (wavefront_patch))) {
+			err = -EFAULT;
+			break;
+		}
+		
+		err = wavefront_send_patch (dev, header);
+		break;
 
 	case WF_ST_PROGRAM:
-		if (copy_from_user (&header.hdr.pr, header.hdrptr,
-				    sizeof (wavefront_program)))
-			return -EFAULT;
+		if (copy_from_user (&header->hdr.pr, header->hdrptr,
+				    sizeof (wavefront_program))) {
+			err = -EFAULT;
+			break;
+		}
 
-		return wavefront_send_program (dev, &header);
+		err = wavefront_send_program (dev, header);
+		break;
 
 	default:
 		snd_printk ("unknown patch type %d.\n",
-			    header.subkey);
-		return -(EINVAL);
+			    header->subkey);
+		err = -EINVAL;
+		break;
 	}
 
-	return 0;
+ __error:
+	kfree(header);
+	return err;
 }
 
 /***********************************************************************
@@ -1620,8 +1651,9 @@
 	snd_card_t *card;
 	snd_wavefront_t *dev;
 	snd_wavefront_card_t *acard;
-	wavefront_control wc;
+	wavefront_control *wc;
 	void __user *argp = (void __user *)arg;
+	int err;
 
 	card = (snd_card_t *) hw->card;
 
@@ -1640,14 +1672,19 @@
 		break;
 
 	case WFCTL_WFCMD:
-		if (copy_from_user (&wc, argp, sizeof (wc)))
-			return -EFAULT;
-		if (wavefront_synth_control (acard, &wc) < 0) {
-			return -EIO;
-		}
-		if (copy_to_user (argp, &wc, sizeof (wc)))
-			return -EFAULT;
-		break;
+		wc = kmalloc(sizeof(*wc), GFP_KERNEL);
+		if (! wc)
+			return -ENOMEM;
+		if (copy_from_user (wc, argp, sizeof (*wc)))
+			err = -EFAULT;
+		else if (wavefront_synth_control (acard, wc) < 0)
+			err = -EIO;
+		else if (copy_to_user (argp, wc, sizeof (*wc)))
+			err = -EFAULT;
+		else
+			err = 0;
+		kfree(wc);
+		return err;
 
 	default:
 		return -EINVAL;
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-24 18:13:29 -08:00
+++ b/sound/pci/ac97/ac97_codec.c	2005-03-24 18:13:29 -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 }
 };
 
@@ -1486,7 +1486,7 @@
 	}
 
 	/* build S/PDIF controls */
-	if (ac97->ext_id & AC97_EI_SPDIF) {
+	if ((ac97->ext_id & AC97_EI_SPDIF) && !(ac97->scaps & AC97_SCAP_NO_SPDIF)) {
 		if (ac97->build_ops->build_spdif) {
 			if ((err = ac97->build_ops->build_spdif(ac97)) < 0)
 				return err;
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-24 18:13:28 -08:00
+++ b/sound/pci/ac97/ac97_patch.c	2005-03-24 18:13:29 -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/als4000.c b/sound/pci/als4000.c
--- a/sound/pci/als4000.c	2005-03-24 18:13:29 -08:00
+++ b/sound/pci/als4000.c	2005-03-24 18:13:29 -08:00
@@ -601,9 +601,9 @@
 
 	gameport_set_name(gp, "ALS4000 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci));
-	gp->dev.parent = &acard->pci->dev;
+	gameport_set_dev_parent(gp, &acard->pci->dev);
 	gp->io = io_port;
-	gp->port_data = r;
+	gameport_set_port_data(gp, r);
 
 	/* Enable legacy joystick port */
 	snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);
@@ -616,7 +616,7 @@
 static void snd_als4000_free_gameport(snd_card_als4000_t *acard)
 {
 	if (acard->gameport) {
-		struct resource *r = acard->gameport->port_data;
+		struct resource *r = gameport_get_port_data(acard->gameport);
 
 		gameport_unregister_port(acard->gameport);
 		acard->gameport = NULL;
diff -Nru a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/atiixp.c	2005-03-24 18:13:28 -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;
 };
 
 /*
@@ -1375,6 +1376,8 @@
 		ac97.pci = chip->pci;
 		ac97.num = i;
 		ac97.scaps = AC97_SCAP_SKIP_MODEM;
+		if (! chip->spdif_over_aclink)
+			ac97.scaps |= AC97_SCAP_NO_SPDIF;
 		if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
 			chip->ac97[i] = NULL; /* to be sure */
 			snd_printdd("atiixp: codec %d not available for audio\n", i);
@@ -1404,8 +1407,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 +1439,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/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
--- a/sound/pci/au88x0/au88x0_game.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/au88x0/au88x0_game.c	2005-03-24 18:13:28 -08:00
@@ -44,20 +44,20 @@
 
 static unsigned char vortex_game_read(struct gameport *gameport)
 {
-	vortex_t *vortex = gameport->port_data;
+	vortex_t *vortex = gameport_get_port_data(gameport);
 	return hwread(vortex->mmio, VORTEX_GAME_LEGACY);
 }
 
 static void vortex_game_trigger(struct gameport *gameport)
 {
-	vortex_t *vortex = gameport->port_data;
+	vortex_t *vortex = gameport_get_port_data(gameport);
 	hwwrite(vortex->mmio, VORTEX_GAME_LEGACY, 0xff);
 }
 
 static int
 vortex_game_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	vortex_t *vortex = gameport->port_data;
+	vortex_t *vortex = gameport_get_port_data(gameport);
 	int i;
 
 	*buttons = (~hwread(vortex->mmio, VORTEX_GAME_LEGACY) >> 4) & 0xf;
@@ -73,7 +73,7 @@
 
 static int vortex_game_open(struct gameport *gameport, int mode)
 {
-	vortex_t *vortex = gameport->port_data;
+	vortex_t *vortex = gameport_get_port_data(gameport);
 
 	switch (mode) {
 	case GAMEPORT_MODE_COOKED:
@@ -106,14 +106,14 @@
 
 	gameport_set_name(gp, "AU88x0 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev));
-	gp->dev.parent = &vortex->pci_dev->dev;
+	gameport_set_dev_parent(gp, &vortex->pci_dev->dev);
 
 	gp->read = vortex_game_read;
 	gp->trigger = vortex_game_trigger;
 	gp->cooked_read = vortex_game_cooked_read;
 	gp->open = vortex_game_open;
 
-	gp->port_data = vortex;
+	gameport_set_port_data(gp, vortex);
 	gp->fuzz = 64;
 
 	gameport_register_port(gp);
diff -Nru a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
--- a/sound/pci/au88x0/au88x0_mixer.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/au88x0/au88x0_mixer.c	2005-03-24 18:13:28 -08:00
@@ -26,6 +26,7 @@
 	memset(&ac97, 0, sizeof(ac97));
 	// Intialize AC97 codec stuff.
 	ac97.private_data = vortex;
+	ac97.scaps = AC97_SCAP_NO_SPDIF;
 	err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
 	vortex->isquad = ((vortex->codec == NULL) ?  0 : (vortex->codec->ext_id&0x80));
 	return err;
diff -Nru a/sound/pci/azt3328.c b/sound/pci/azt3328.c
--- a/sound/pci/azt3328.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/azt3328.c	2005-03-24 18:13:28 -08:00
@@ -1245,9 +1245,9 @@
 
 	gameport_set_name(gp, "AZF3328 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 	gp->io = 0x200;
-	gp->port_data = r;
+	gameport_set_port_data(gp, r);
 
 	snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
 			      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
@@ -1260,7 +1260,7 @@
 static void snd_azf3328_free_joystick(azf3328_t *chip)
 {
 	if (chip->gameport) {
-		struct resource *r = chip->gameport->port_data;
+		struct resource *r = gameport_get_port_data(chip->gameport);
 
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
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-24 18:13:29 -08:00
+++ b/sound/pci/ca0106/ca0106_main.c	2005-03-24 18:13:29 -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/cmipci.c b/sound/pci/cmipci.c
--- a/sound/pci/cmipci.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/cmipci.c	2005-03-24 18:13:28 -08:00
@@ -2592,9 +2592,9 @@
 	}
 	gameport_set_name(gp, "C-Media Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(cm->pci));
-	gp->dev.parent = &cm->pci->dev;
+	gameport_set_dev_parent(gp, &cm->pci->dev);
 	gp->io = io_port;
-	gp->port_data = r;
+	gameport_set_port_data(gp, r);
 
 	snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
 
@@ -2606,7 +2606,7 @@
 static void snd_cmipci_free_gameport(cmipci_t *cm)
 {
 	if (cm->gameport) {
-		struct resource *r = cm->gameport->port_data;
+		struct resource *r = gameport_get_port_data(cm->gameport);
 
 		gameport_unregister_port(cm->gameport);
 		cm->gameport = NULL;
diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c
--- a/sound/pci/cs4281.c	2005-03-24 18:13:29 -08:00
+++ b/sound/pci/cs4281.c	2005-03-24 18:13:29 -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;
 }
 
@@ -1241,7 +1240,7 @@
 
 static void snd_cs4281_gameport_trigger(struct gameport *gameport)
 {
-	cs4281_t *chip = gameport->port_data;
+	cs4281_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return);
 	snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
@@ -1249,7 +1248,7 @@
 
 static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
 {
-	cs4281_t *chip = gameport->port_data;
+	cs4281_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 	return snd_cs4281_peekBA0(chip, BA0_JSPT);
@@ -1258,7 +1257,7 @@
 #ifdef COOKED_MODE
 static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	cs4281_t *chip = gameport->port_data;
+	cs4281_t *chip = gameport_get_port_data(gameport);
 	unsigned js1, js2, jst;
 	
 	snd_assert(chip, return 0);
@@ -1309,12 +1308,12 @@
 
 	gameport_set_name(gp, "CS4281 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 	gp->open = snd_cs4281_gameport_open;
 	gp->read = snd_cs4281_gameport_read;
 	gp->trigger = snd_cs4281_gameport_trigger;
 	gp->cooked_read = snd_cs4281_gameport_cooked_read;
-	gp->port_data = chip;
+	gameport_set_port_data(gp, chip);
 
 	snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ?
 	snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
@@ -1332,8 +1331,8 @@
 	}
 }
 #else
-static inline int snd_cs4281_gameport(cs4281_t *chip) { return -ENOSYS; }
-static inline void snd_cs4281_gameport_free(cs4281_t *chip) { }
+static inline int snd_cs4281_create_gameport(cs4281_t *chip) { return -ENOSYS; }
+static inline void snd_cs4281_free_gameport(cs4281_t *chip) { }
 #endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */
 
 
@@ -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-24 18:13:28 -08:00
+++ b/sound/pci/cs46xx/cs46xx_lib.c	2005-03-24 18:13:28 -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
@@ -2695,7 +2690,7 @@
 
 static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
 {
-	cs46xx_t *chip = gameport->port_data;
+	cs46xx_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return);
 	snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
@@ -2703,7 +2698,7 @@
 
 static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
 {
-	cs46xx_t *chip = gameport->port_data;
+	cs46xx_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 	return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
@@ -2711,7 +2706,7 @@
 
 static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	cs46xx_t *chip = gameport->port_data;
+	cs46xx_t *chip = gameport_get_port_data(gameport);
 	unsigned js1, js2, jst;
 
 	snd_assert(chip, return 0);
@@ -2757,8 +2752,8 @@
 
 	gameport_set_name(gp, "CS46xx Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
-	gp->port_data = chip;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
+	gameport_set_port_data(gp, chip);
 
 	gp->open = snd_cs46xx_gameport_open;
 	gp->read = snd_cs46xx_gameport_read;
diff -Nru a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
--- a/sound/pci/emu10k1/Makefile	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/Makefile	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emu10k1.c	2005-03-24 18:13:28 -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);
@@ -185,23 +198,11 @@
 	}
 #endif
  
-	if (emu->audigy && (emu->serial == 0x10011102) ) {
-		strcpy(card->driver, "Audigy2");
-		strcpy(card->shortname, "Sound Blaster Audigy2_Value");
-	} else if (emu->audigy && (emu->revision == 4) ) {
-		strcpy(card->driver, "Audigy2");
-		strcpy(card->shortname, "Sound Blaster Audigy2");
-	} else if (emu->audigy) {
-		strcpy(card->driver, "Audigy");
-		strcpy(card->shortname, "Sound Blaster Audigy");
-	} else if (emu->APS) {
-		strcpy(card->driver, "E-mu APS");
-		strcpy(card->shortname, "E-mu APS");
-	} else {
-		strcpy(card->driver, "EMU10K1");
-		strcpy(card->shortname, "Sound Blaster Live!");
-	}
-	sprintf(card->longname, "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
+	strcpy(card->driver, emu->card_capabilities->driver);
+	strcpy(card->shortname, emu->card_capabilities->name);
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
+		 card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
 
 	if ((err = snd_card_register(card)) < 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-24 18:13:29 -08:00
+++ b/sound/pci/emu10k1/emu10k1_main.c	2005-03-24 18:13:29 -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;
 }
@@ -606,6 +612,85 @@
 	return snd_emu10k1_free(emu);
 }
 
+/* vendor, device, subsystem, emu10k1_chip, emu10k2_chip, ca0102_chip, ca0108_chip, ca0151_chip, spk71, spdif_bug, ac97_chip, ecard, driver, name */
+
+static emu_chip_details_t emu_chip_details[] = {
+	/* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
+	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
+	 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", 
+	 .emu10k2_chip = 1,
+	 .ca0108_chip = 1,
+	 .spk71 = 1} ,
+	{.vendor = 0x1102, .device = 0x0008, 
+	 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
+	 .emu10k2_chip = 1,
+	 .ca0108_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
+	 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spk71 = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
+	 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spk71 = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
+	 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spk71 = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
+	 .driver = "Audigy2", .name = "Audigy 2 [SB0240]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spk71 = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
+	 .driver = "Audigy2", .name = "Audigy 2 EX [1005]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spdif_bug = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
+	 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spk71 = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004,
+	 .driver = "Audigy", .name = "Audigy 1 or 2 [Unknown]", 
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .spdif_bug = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
+	 .driver = "EMU10K1", .name = "E-mu APS [4001]", 
+	 .emu10k1_chip = 1,
+	 .ecard = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
+	 .driver = "EMU10K1", .name = "SB Live 5.1", 
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0002,
+	 .driver = "EMU10K1", .name = "SB Live [Unknown]", 
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1} ,
+	{ } /* terminator */
+};
+
 int __devinit snd_emu10k1_create(snd_card_t * card,
 		       struct pci_dev * pci,
 		       unsigned short extin_mask,
@@ -617,15 +702,14 @@
 	emu10k1_t *emu;
 	int err;
 	int is_audigy;
+	unsigned char revision;
+	const emu_chip_details_t *c;
 	static snd_device_ops_t ops = {
 		.dev_free =	snd_emu10k1_dev_free,
 	};
 	
 	*remu = NULL;
 
-	// is_audigy = (int)pci->driver_data;
-	is_audigy = (pci->device == 0x0004) || ( (pci->device == 0x0008) );
-
 	/* enable PCI device */
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
@@ -635,15 +719,6 @@
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
-	/* set the DMA transfer mask */
-	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
-	if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
-	    pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
-		snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
-		kfree(emu);
-		pci_disable_device(pci);
-		return -ENXIO;
-	}
 	emu->card = card;
 	spin_lock_init(&emu->reg_lock);
 	spin_lock_init(&emu->emu_lock);
@@ -658,8 +733,43 @@
 	emu->irq = -1;
 	emu->synth = NULL;
 	emu->get_synth_voice = NULL;
+	/* read revision & serial */
+	pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
+	emu->revision = revision;
+	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
+	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
+	emu->card_type = EMU10K1_CARD_CREATIVE;
+	snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model);
+
+	for (c = emu_chip_details; c->vendor; c++) {
+		if (c->vendor == pci->vendor && c->device == pci->device) {
+			if (c->subsystem == emu->serial) break;
+			if (c->subsystem == 0) break;
+		}
+	}
+	if (c->vendor == 0) {
+		snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
+		kfree(emu);
+		pci_disable_device(pci);
+		return -ENOENT;
+	}
+	emu->card_capabilities = c;
+	if (c->subsystem != 0)
+		snd_printdd("Sound card name=%s\n", c->name);
+	else
+		snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial);
+	
+	is_audigy = emu->audigy = c->emu10k2_chip;
 
-	emu->audigy = is_audigy;
+	/* set the DMA transfer mask */
+	emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
+	if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
+	    pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
+		snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
+		kfree(emu);
+		pci_disable_device(pci);
+		return -ENXIO;
+	}
 	if (is_audigy)
 		emu->gpr_base = A_FXGPREGBASE;
 	else
@@ -705,30 +815,15 @@
 	emu->memhdr->block_extra_size = sizeof(emu10k1_memblk_t) - sizeof(snd_util_memblk_t);
 
 	pci_set_master(pci);
-	/* read revision & serial */
-	pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&emu->revision);
-	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
-	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
-	emu->card_type = EMU10K1_CARD_CREATIVE;
-	if (emu->serial == 0x40011102) {
+
+	if (c->ecard) {
 		emu->card_type = EMU10K1_CARD_EMUAPS;
 		emu->APS = 1;
-		emu->no_ac97 = 1; /* APS has no AC97 chip */
-	}
-	else if (emu->revision == 4 && emu->serial == 0x10051102) {
-		/* Audigy 2 EX has apparently no effective AC97 controls
-		 * (for both input and output), so we skip the AC97 detections
-		 */
-		snd_printdd(KERN_INFO "Audigy2 EX is detected. skipping ac97.\n");
-		emu->no_ac97 = 1;	
-	}
-	
-	if (emu->revision == 4 && (emu->model == 0x2001 || emu->model == 0x2002)) {
-		/* Audigy 2 ZS */
-		snd_printdd(KERN_INFO "Audigy2 ZS is detected. setting 7.1 mode.\n");
-		emu->spk71 = 1;
 	}
+	if (! c->ac97_chip)
+		emu->no_ac97 = 1;
 	
+	emu->spk71 = c->spk71;
 	
 	emu->fx8010.fxbus_mask = 0x303f;
 	if (extin_mask == 0)
diff -Nru a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
--- a/sound/pci/emu10k1/emu10k1x.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emu10k1x.c	2005-03-24 18:13:28 -08:00
@@ -749,6 +749,7 @@
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
+	ac97.scaps = AC97_SCAP_NO_SPDIF;
 	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
 }
 
@@ -1265,7 +1266,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 +1285,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 +1294,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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emufx.c	2005-03-24 18:13:28 -08:00
@@ -634,7 +634,8 @@
 	snd_ctl_elem_id_t __user *_id;
 	snd_ctl_elem_id_t id;
 	emu10k1_fx8010_control_gpr_t __user *_gctl;
-	emu10k1_fx8010_control_gpr_t gctl;
+	emu10k1_fx8010_control_gpr_t *gctl;
+	int err;
 	
 	for (i = 0, _id = icode->gpr_del_controls;
 	     i < icode->gpr_del_control_count; i++, _id++) {
@@ -643,29 +644,42 @@
 		if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
 			return -ENOENT;
 	}
+	gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
+	if (! gctl)
+		return -ENOMEM;
+	err = 0;
 	for (i = 0, _gctl = icode->gpr_add_controls;
 	     i < icode->gpr_add_control_count; i++, _gctl++) {
-		if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
-			return -EFAULT;
-		if (snd_emu10k1_look_for_ctl(emu, &gctl.id))
+		if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
+			err = -EFAULT;
+			goto __error;
+		}
+		if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
 			continue;
 		down_read(&emu->card->controls_rwsem);
-		if (snd_ctl_find_id(emu->card, &gctl.id) != NULL) {
+		if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
 			up_read(&emu->card->controls_rwsem);
-			return -EEXIST;
+			err = -EEXIST;
+			goto __error;
 		}
 		up_read(&emu->card->controls_rwsem);
-		if (gctl.id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
-		    gctl.id.iface != SNDRV_CTL_ELEM_IFACE_PCM)
-			return -EINVAL;
+		if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+		    gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+			err = -EINVAL;
+			goto __error;
+		}
 	}
 	for (i = 0, _gctl = icode->gpr_list_controls;
 	     i < icode->gpr_list_control_count; i++, _gctl++) {
 	     	/* FIXME: we need to check the WRITE access */
-		if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
-			return -EFAULT;
+		if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
+			err = -EFAULT;
+			goto __error;
+		}
 	}
-	return 0;
+ __error:
+	kfree(gctl);
+	return err;
 }
 
 static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
@@ -682,52 +696,59 @@
 {
 	unsigned int i, j;
 	emu10k1_fx8010_control_gpr_t __user *_gctl;
-	emu10k1_fx8010_control_gpr_t gctl;
-	snd_emu10k1_fx8010_ctl_t *ctl, nctl;
+	emu10k1_fx8010_control_gpr_t *gctl;
+	snd_emu10k1_fx8010_ctl_t *ctl, *nctl;
 	snd_kcontrol_new_t knew;
 	snd_kcontrol_t *kctl;
 	snd_ctl_elem_value_t *val;
 	int err = 0;
 
 	val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
-	if (!val)
-		return -ENOMEM;
+	gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
+	nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
+	if (!val || !gctl || !nctl) {
+		err = -ENOMEM;
+		goto __error;
+	}
+
 	for (i = 0, _gctl = icode->gpr_add_controls;
 	     i < icode->gpr_add_control_count; i++, _gctl++) {
-		if (copy_from_user(&gctl, _gctl, sizeof(gctl))) {
+		if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
 			err = -EFAULT;
 			goto __error;
 		}
-		snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
-		                  gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
-		snd_runtime_check(gctl.id.name[0] != '\0', err = -EINVAL; goto __error);
-		ctl = snd_emu10k1_look_for_ctl(emu, &gctl.id);
+		snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
+		                  gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
+		snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
+		ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
 		memset(&knew, 0, sizeof(knew));
-		knew.iface = gctl.id.iface;
-		knew.name = gctl.id.name;
-		knew.index = gctl.id.index;
-		knew.device = gctl.id.device;
-		knew.subdevice = gctl.id.subdevice;
+		knew.iface = gctl->id.iface;
+		knew.name = gctl->id.name;
+		knew.index = gctl->id.index;
+		knew.device = gctl->id.device;
+		knew.subdevice = gctl->id.subdevice;
 		knew.info = snd_emu10k1_gpr_ctl_info;
 		knew.get = snd_emu10k1_gpr_ctl_get;
 		knew.put = snd_emu10k1_gpr_ctl_put;
-		memset(&nctl, 0, sizeof(nctl));
-		nctl.vcount = gctl.vcount;
-		nctl.count = gctl.count;
+		memset(nctl, 0, sizeof(*nctl));
+		nctl->vcount = gctl->vcount;
+		nctl->count = gctl->count;
 		for (j = 0; j < 32; j++) {
-			nctl.gpr[j] = gctl.gpr[j];
-			nctl.value[j] = ~gctl.value[j];	/* inverted, we want to write new value in gpr_ctl_put() */
-			val->value.integer.value[j] = gctl.value[j];
-		}
-		nctl.min = gctl.min;
-		nctl.max = gctl.max;
-		nctl.translation = gctl.translation;
+			nctl->gpr[j] = gctl->gpr[j];
+			nctl->value[j] = ~gctl->value[j];	/* inverted, we want to write new value in gpr_ctl_put() */
+			val->value.integer.value[j] = gctl->value[j];
+		}
+		nctl->min = gctl->min;
+		nctl->max = gctl->max;
+		nctl->translation = gctl->translation;
 		if (ctl == NULL) {
 			ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
-			if (ctl == NULL)
-				continue;
+			if (ctl == NULL) {
+				err = -ENOMEM;
+				goto __error;
+			}
 			knew.private_value = (unsigned long)ctl;
-			memcpy(ctl, &nctl, sizeof(nctl));
+			*ctl = *nctl;
 			if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
 				kfree(ctl);
 				goto __error;
@@ -737,15 +758,17 @@
 			list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
 		} else {
 			/* overwrite */
-			nctl.list = ctl->list;
-			nctl.kcontrol = ctl->kcontrol;
-			memcpy(ctl, &nctl, sizeof(nctl));
+			nctl->list = ctl->list;
+			nctl->kcontrol = ctl->kcontrol;
+			*ctl = *nctl;
 			snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
 			                          SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
 		}
 		snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
 	}
       __error:
+	kfree(nctl);
+	kfree(gctl);
 	kfree(val);
 	return err;
 }
@@ -774,40 +797,47 @@
 {
 	unsigned int i = 0, j;
 	unsigned int total = 0;
-	emu10k1_fx8010_control_gpr_t gctl;
+	emu10k1_fx8010_control_gpr_t *gctl;
 	emu10k1_fx8010_control_gpr_t __user *_gctl;
 	snd_emu10k1_fx8010_ctl_t *ctl;
 	snd_ctl_elem_id_t *id;
 	struct list_head *list;
 
+	gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
+	if (! gctl)
+		return -ENOMEM;
+
 	_gctl = icode->gpr_list_controls;	
 	list_for_each(list, &emu->fx8010.gpr_ctl) {
 		ctl = emu10k1_gpr_ctl(list);
 		total++;
 		if (_gctl && i < icode->gpr_list_control_count) {
-			memset(&gctl, 0, sizeof(gctl));
+			memset(gctl, 0, sizeof(*gctl));
 			id = &ctl->kcontrol->id;
-			gctl.id.iface = id->iface;
-			strlcpy(gctl.id.name, id->name, sizeof(gctl.id.name));
-			gctl.id.index = id->index;
-			gctl.id.device = id->device;
-			gctl.id.subdevice = id->subdevice;
-			gctl.vcount = ctl->vcount;
-			gctl.count = ctl->count;
+			gctl->id.iface = id->iface;
+			strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
+			gctl->id.index = id->index;
+			gctl->id.device = id->device;
+			gctl->id.subdevice = id->subdevice;
+			gctl->vcount = ctl->vcount;
+			gctl->count = ctl->count;
 			for (j = 0; j < 32; j++) {
-				gctl.gpr[j] = ctl->gpr[j];
-				gctl.value[j] = ctl->value[j];
+				gctl->gpr[j] = ctl->gpr[j];
+				gctl->value[j] = ctl->value[j];
 			}
-			gctl.min = ctl->min;
-			gctl.max = ctl->max;
-			gctl.translation = ctl->translation;
-			if (copy_to_user(_gctl, &gctl, sizeof(gctl)))
+			gctl->min = ctl->min;
+			gctl->max = ctl->max;
+			gctl->translation = ctl->translation;
+			if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
+				kfree(gctl);
 				return -EFAULT;
+			}
 			_gctl++;
 			i++;
 		}
 	}
 	icode->gpr_list_control_total = total;
+	kfree(gctl);
 	return 0;
 }
 
@@ -1339,6 +1369,7 @@
 	/* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
 
 	/* IEC958 Optical Raw Playback Switch */ 
+	gpr_map[gpr++] = 0;
 	gpr_map[gpr++] = 0x1008;
 	gpr_map[gpr++] = 0xffff0000;
 	for (z = 0; z < 2; z++) {
@@ -1349,7 +1380,14 @@
 		A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
 		A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
 		A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
-		A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
+		if ((z==1) && (emu->card_capabilities->spdif_bug)) {
+			/* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
+			snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
+			A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
+			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
+		} else {
+			A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
+		}
 	}
 	snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
 	gpr += 2;
@@ -2092,7 +2130,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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emumixer.c	2005-03-24 18:13:28 -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;
 }
@@ -795,6 +806,7 @@
 		memset(&ac97, 0, sizeof(ac97));
 		ac97.private_data = emu;
 		ac97.private_free = snd_emu10k1_mixer_free_ac97;
+		ac97.scaps = AC97_SCAP_NO_SPDIF;
 		if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
 			return err;
 		if (emu->audigy) {
@@ -912,11 +924,6 @@
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
 			return err;
-		if ((kctl = ctl_find(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT))) != NULL) {
-			/* already defined by ac97, remove it */
-			/* FIXME: or do we need both controls? */
-			remove_ctl(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT));
-		}
 		if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
@@ -939,6 +946,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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emumpu401.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emupcm.c	2005-03-24 18:13:28 -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,
@@ -271,11 +275,11 @@
 				       int master, int extra,
 				       emu10k1_voice_t *evoice,
 				       unsigned int start_addr,
-				       unsigned int end_addr)
+				       unsigned int end_addr,
+				       emu10k1_pcm_mixer_t *mix)
 {
 	snd_pcm_substream_t *substream = evoice->epcm->substream;
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_mixer_t *mix;
 	unsigned int silent_page, tmp;
 	int voice, stereo, w_16;
 	unsigned char attn, send_amount[8];
@@ -285,11 +289,6 @@
 	unsigned int ccis;
 
 	voice = evoice->number;
-	if (evoice->epcm->type == PLAYBACK_EFX) 
-		mix = &emu->efx_pcm_mixer[voice - evoice->epcm->voices[0]->number];
-	else
-		mix = &emu->pcm_mixer[substream->number];
-
 	stereo = runtime->channels == 2;
 	w_16 = snd_pcm_format_width(runtime->format) == 16;
 
@@ -493,14 +492,16 @@
 	}
 	end_addr += start_addr;
 	snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
-				   start_addr, end_addr);
+				   start_addr, end_addr, NULL);
 	start_addr = epcm->start_addr;
 	end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
 	snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
-				   start_addr, end_addr);
+				   start_addr, end_addr,
+				   &emu->pcm_mixer[substream->number]);
 	if (epcm->voices[1])
 		snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1],
-					   start_addr, end_addr);
+					   start_addr, end_addr,
+					   &emu->pcm_mixer[substream->number]);
 	return 0;
 }
 
@@ -522,16 +523,18 @@
 	channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
 
 	snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
-				   start_addr, start_addr + (channel_size / 2));
+				   start_addr, start_addr + (channel_size / 2), NULL);
 
 	/* only difference with the master voice is we use it for the pointer */
 	snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
-				   start_addr, start_addr + channel_size);
+				   start_addr, start_addr + channel_size,
+				   &emu->efx_pcm_mixer[0]);
 
 	start_addr += channel_size;
 	for (i = 1; i < NUM_EFX_PLAYBACK; i++) {
 		snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i],
-					   start_addr, start_addr+channel_size);
+					   start_addr, start_addr + channel_size,
+					   &emu->efx_pcm_mixer[i]);
 		start_addr += channel_size;
 	}
 
@@ -650,12 +653,13 @@
 	}
 }
 
-static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra)
+static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice,
+					       int master, int extra,
+					       emu10k1_pcm_mixer_t *mix)
 {
 	snd_pcm_substream_t *substream;
 	snd_pcm_runtime_t *runtime;
-	emu10k1_pcm_mixer_t *mix;
-	unsigned int attn;
+	unsigned int attn, vattn;
 	unsigned int voice, tmp;
 
 	if (evoice == NULL)	/* skip second voice for mono */
@@ -664,15 +668,12 @@
 	runtime = substream->runtime;
 	voice = evoice->number;
 
-	mix = evoice->epcm->type == PLAYBACK_EFX
-		? &emu->efx_pcm_mixer[voice - evoice->epcm->voices[0]->number]
-		: &emu->pcm_mixer[substream->number];
-
 	attn = extra ? 0 : 0x00ff;
 	tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
+	vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
 	snd_emu10k1_ptr_write(emu, IFATN, voice, attn);
-	snd_emu10k1_ptr_write(emu, VTFT, voice, (mix->attn[tmp] << 16) | 0xffff);
-	snd_emu10k1_ptr_write(emu, CVCF, voice, (mix->attn[tmp] << 16) | 0xffff);
+	snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | 0xffff);
+	snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | 0xffff);
 	snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f);
 	snd_emu10k1_voice_clear_loop_stop(emu, voice);
 }	
@@ -721,7 +722,9 @@
 	emu10k1_t *emu = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	emu10k1_pcm_t *epcm = runtime->private_data;
+	emu10k1_pcm_mixer_t *mix;
 	int result = 0;
+
 	// printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream));
 	spin_lock(&emu->reg_lock);
 	switch (cmd) {
@@ -730,9 +733,10 @@
 		snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0);
-		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0);
-		snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1);
+		mix = &emu->pcm_mixer[substream->number];
+		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
+		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
+		snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
 		snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0);
 		snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0);
 		snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
@@ -847,7 +851,7 @@
 	emu10k1_t *emu = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	emu10k1_pcm_t *epcm = runtime->private_data;
-	int i = 0;
+	int i;
 	int result = 0;
 
 	spin_lock(&emu->reg_lock);
@@ -861,16 +865,16 @@
 
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0);
-		snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1);
-		for (i = 1; i < NUM_EFX_PLAYBACK; i++) {	
-			snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0);
-		}
+		snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
+		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,
+						   &emu->efx_pcm_mixer[0]);
+		for (i = 1; i < NUM_EFX_PLAYBACK; i++)
+			snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0,
+							   &emu->efx_pcm_mixer[i]);
 		snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);
 		snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
-		for (i = 1; i < NUM_EFX_PLAYBACK; i++) {	
+		for (i = 1; i < NUM_EFX_PLAYBACK; i++)
 			snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);
-		}
 		epcm->running = 1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/emuproc.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/io.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/irq.c	2005-03-24 18:13:28 -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-24 18:13:29 -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-24 18:13:29 -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/timer.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/pci/emu10k1/voice.c	2005-03-24 18:13:28 -08:00
@@ -62,15 +62,13 @@
 			continue;
 		}
 			
-		/* make sure the block of voices does not cross the 32 voice boundary */
-		//if (((i % 32) + number) > 32)
-		//	continue;
-
 		skip = 0;
 		for (k = 0; k < number; k++) {
 			voice = &emu->voices[(i+k) % NUM_G];
-			if (voice->use)
+			if (voice->use) {
 				skip = 1;
+				break;
+			}
 		}
 		if (!skip) {
 			// printk("allocated voice %d\n", i);
@@ -81,12 +79,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-24 18:13:28 -08:00
+++ b/sound/pci/ens1370.c	2005-03-24 18:13:28 -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;
 }
 
@@ -1802,7 +1797,7 @@
 
 	gameport_set_name(gp, "ES137x");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(ensoniq->pci));
-	gp->dev.parent = &ensoniq->pci->dev;
+	gameport_set_dev_parent(gp, &ensoniq->pci->dev);
 	gp->io = io_port;
 
 	ensoniq->ctrl |= ES_JYSTK_EN;
@@ -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/es1938.c b/sound/pci/es1938.c
--- a/sound/pci/es1938.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/es1938.c	2005-03-24 18:13:28 -08:00
@@ -1435,7 +1435,7 @@
 
 	gameport_set_name(gp, "ES1938");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 	gp->io = chip->game_port;
 
 	gameport_register_port(gp);
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	2005-03-24 18:13:29 -08:00
+++ b/sound/pci/es1968.c	2005-03-24 18:13:29 -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 */
@@ -2477,8 +2496,9 @@
 
 	gameport_set_name(gp, "ES1968 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 	gp->io = JOYSTICK_ADDR;
+	gameport_set_port_data(gp, r);
 
 	gameport_register_port(gp);
 
@@ -2488,7 +2508,7 @@
 static void snd_es1968_free_gameport(es1968_t *chip)
 {
 	if (chip->gameport) {
-		struct resource *r = chip->gameport->port_data;
+		struct resource *r = gameport_get_port_data(chip->gameport);
 
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
diff -Nru a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
--- a/sound/pci/hda/Makefile	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/hda/Makefile	2005-03-24 18:13:28 -08:00
@@ -1,5 +1,5 @@
 snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o
+snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o
 ifdef CONFIG_PROC_FS
 snd-hda-codec-objs += hda_proc.o
 endif
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-24 18:13:29 -08:00
+++ b/sound/pci/hda/hda_codec.c	2005-03-24 18:13:29 -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/hda_generic.c b/sound/pci/hda/hda_generic.c
--- a/sound/pci/hda/hda_generic.c	2005-03-24 18:13:29 -08:00
+++ b/sound/pci/hda/hda_generic.c	2005-03-24 18:13:29 -08:00
@@ -617,6 +617,7 @@
 	char name[32];
 	int err;
 	int created = 0;
+	snd_kcontrol_new_t knew;
 
 	if (type)
 		sprintf(name, "%s %s Switch", type, dir_sfx);
@@ -624,16 +625,14 @@
 		sprintf(name, "%s Switch", dir_sfx);
 	if ((node->wid_caps & AC_WCAP_IN_AMP) &&
 	    (node->amp_in_caps & AC_AMPCAP_MUTE)) {
-		snd_kcontrol_new_t knew =
-			HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
+		knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
 		created = 1;
 	} else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
 		   (node->amp_out_caps & AC_AMPCAP_MUTE)) {
-		snd_kcontrol_new_t knew =
-			HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
+		knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
@@ -646,16 +645,14 @@
 		sprintf(name, "%s Volume", dir_sfx);
 	if ((node->wid_caps & AC_WCAP_IN_AMP) &&
 	    (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
-		snd_kcontrol_new_t knew =
-			HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
+		knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
 		created = 1;
 	} else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
 		   (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
-		snd_kcontrol_new_t knew =
-			HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
+		knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
diff -Nru a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
--- a/sound/pci/hda/hda_patch.h	2005-03-24 18:13:29 -08:00
+++ b/sound/pci/hda/hda_patch.h	2005-03-24 18:13:29 -08:00
@@ -6,9 +6,12 @@
 extern struct hda_codec_preset snd_hda_preset_realtek[];
 /* C-Media codecs */
 extern struct hda_codec_preset snd_hda_preset_cmedia[];
+/* Analog Devices codecs */
+extern struct hda_codec_preset snd_hda_preset_analog[];
 
 static const struct hda_codec_preset *hda_preset_tables[] = {
 	snd_hda_preset_realtek,
 	snd_hda_preset_cmedia,
+	snd_hda_preset_analog,
 	NULL
 };
diff -Nru a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/hda/patch_analog.c	2005-03-24 18:13:29 -08:00
@@ -0,0 +1,445 @@
+/*
+ * HD audio interface patch for AD1986A
+ *
+ * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
+ *
+ *  This driver 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 driver 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/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+struct ad1986a_spec {
+	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
+	struct hda_multi_out multiout;	/* playback */
+	unsigned int cur_mux;		/* capture source */
+	struct hda_pcm pcm_rec[2];	/* PCM information */
+};
+
+#define AD1986A_SPDIF_OUT	0x02
+#define AD1986A_FRONT_DAC	0x03
+#define AD1986A_SURR_DAC	0x04
+#define AD1986A_CLFE_DAC	0x05
+#define AD1986A_ADC		0x06
+
+static hda_nid_t ad1986a_dac_nids[3] = {
+	AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
+};
+
+static struct hda_input_mux ad1986a_capture_source = {
+	.num_items = 7,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "CD", 0x1 },
+		{ "Aux", 0x3 },
+		{ "Line", 0x4 },
+		{ "Mix", 0x5 },
+		{ "Mono", 0x6 },
+		{ "Phone", 0x7 },
+	},
+};
+
+/*
+ * PCM control
+ *
+ * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
+ */
+
+#define ad1986a_pcm_amp_vol_info	snd_hda_mixer_amp_volume_info
+
+static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad1986a_spec *ad = codec->spec;
+
+	down(&ad->amp_mutex);
+	snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
+	up(&ad->amp_mutex);
+	return 0;
+}
+
+static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad1986a_spec *ad = codec->spec;
+	int i, change = 0;
+
+	down(&ad->amp_mutex);
+	for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
+		kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
+		change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
+	}
+	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
+	up(&ad->amp_mutex);
+	return change;
+}
+
+#define ad1986a_pcm_amp_sw_info		snd_hda_mixer_amp_volume_info
+
+static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad1986a_spec *ad = codec->spec;
+
+	down(&ad->amp_mutex);
+	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
+	up(&ad->amp_mutex);
+	return 0;
+}
+
+static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad1986a_spec *ad = codec->spec;
+	int i, change = 0;
+
+	down(&ad->amp_mutex);
+	for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
+		kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
+		change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+	}
+	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
+	up(&ad->amp_mutex);
+	return change;
+}
+
+/*
+ * input MUX handling
+ */
+static int ad1986a_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	return snd_hda_input_mux_info(&ad1986a_capture_source, uinfo);
+}
+
+static int ad1986a_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad1986a_spec *spec = codec->spec;
+
+	ucontrol->value.enumerated.item[0] = spec->cur_mux;
+	return 0;
+}
+
+static int ad1986a_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad1986a_spec *spec = codec->spec;
+
+	return snd_hda_input_mux_put(codec, &ad1986a_capture_source, ucontrol,
+				     AD1986A_ADC, &spec->cur_mux);
+}
+
+/*
+ * mixers
+ */
+static snd_kcontrol_new_t ad1986a_mixers[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "PCM Playback Volume",
+		.info = ad1986a_pcm_amp_vol_info,
+		.get = ad1986a_pcm_amp_vol_get,
+		.put = ad1986a_pcm_amp_vol_put,
+		.private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "PCM Playback Switch",
+		.info = ad1986a_pcm_amp_sw_info,
+		.get = ad1986a_pcm_amp_sw_get,
+		.put = ad1986a_pcm_amp_sw_put,
+		.private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
+	},
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = ad1986a_mux_enum_info,
+		.get = ad1986a_mux_enum_get,
+		.put = ad1986a_mux_enum_put,
+	},
+	HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
+	{ } /* end */
+};
+
+/*
+ * initialization verbs
+ */
+static struct hda_verb ad1986a_init_verbs[] = {
+	/* Front, Surround, CLFE DAC; mute as default */
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* Downmix - off */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* HP, Line-Out, Surround, CLFE selectors */
+	{0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
+	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
+	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Mono selector */
+	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Mic selector: Mic 1/2 pin */
+	{0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Line-in selector: Line-in */
+	{0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Mic 1/2 swap */
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Record selector: mic */
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Mic, Phone, CD, Aux, Line-In amp; mute as default */
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* PC beep */
+	{0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{ } /* end */
+};
+
+
+static int ad1986a_init(struct hda_codec *codec)
+{
+	snd_hda_sequence_write(codec, ad1986a_init_verbs);
+	return 0;
+}
+
+static int ad1986a_build_controls(struct hda_codec *codec)
+{
+	int err;
+
+	err = snd_hda_add_new_ctls(codec, ad1986a_mixers);
+	if (err < 0)
+		return err;
+	err = snd_hda_create_spdif_out_ctls(codec, AD1986A_SPDIF_OUT);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+/*
+ * Analog playback callbacks
+ */
+static int ad1986a_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				     struct hda_codec *codec,
+				     snd_pcm_substream_t *substream)
+{
+	struct ad1986a_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
+}
+
+static int ad1986a_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					unsigned int stream_tag,
+					unsigned int format,
+					snd_pcm_substream_t *substream)
+{
+	struct ad1986a_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
+						format, substream);
+}
+
+static int ad1986a_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					snd_pcm_substream_t *substream)
+{
+	struct ad1986a_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
+}
+
+/*
+ * Digital out
+ */
+static int ad1986a_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 snd_pcm_substream_t *substream)
+{
+	struct ad1986a_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int ad1986a_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+					  struct hda_codec *codec,
+					  snd_pcm_substream_t *substream)
+{
+	struct ad1986a_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+/*
+ * Analog capture
+ */
+static int ad1986a_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       unsigned int stream_tag,
+				       unsigned int format,
+				       snd_pcm_substream_t *substream)
+{
+	snd_hda_codec_setup_stream(codec, AD1986A_ADC, stream_tag, 0, format);
+	return 0;
+}
+
+static int ad1986a_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       snd_pcm_substream_t *substream)
+{
+	snd_hda_codec_setup_stream(codec, AD1986A_ADC, 0, 0, 0);
+	return 0;
+}
+
+
+/*
+ */
+static struct hda_pcm_stream ad1986a_pcm_analog_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 6,
+	.nid = AD1986A_FRONT_DAC, /* NID to query formats and rates */
+	.ops = {
+		.open = ad1986a_playback_pcm_open,
+		.prepare = ad1986a_playback_pcm_prepare,
+		.cleanup = ad1986a_playback_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream ad1986a_pcm_analog_capture = {
+	.substreams = 2,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = AD1986A_ADC, /* NID to query formats and rates */
+	.ops = {
+		.prepare = ad1986a_capture_pcm_prepare,
+		.cleanup = ad1986a_capture_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream ad1986a_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = AD1986A_SPDIF_OUT, 
+	.ops = {
+		.open = ad1986a_dig_playback_pcm_open,
+		.close = ad1986a_dig_playback_pcm_close
+	},
+};
+
+static int ad1986a_build_pcms(struct hda_codec *codec)
+{
+	struct ad1986a_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+
+	codec->num_pcms = 2;
+	codec->pcm_info = info;
+
+	info->name = "AD1986A Analog";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_analog_playback;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1986a_pcm_analog_capture;
+	info++;
+
+	info->name = "AD1986A Digital";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_digital_playback;
+
+	return 0;
+}
+
+static void ad1986a_free(struct hda_codec *codec)
+{
+	kfree(codec->spec);
+}
+
+#ifdef CONFIG_PM
+static int ad1986a_resume(struct hda_codec *codec)
+{
+	ad1986a_init(codec);
+	snd_hda_resume_ctls(codec, ad1986a_mixers);
+	snd_hda_resume_spdif_out(codec);
+	return 0;
+}
+#endif
+
+static struct hda_codec_ops ad1986a_patch_ops = {
+	.build_controls = ad1986a_build_controls,
+	.build_pcms = ad1986a_build_pcms,
+	.init = ad1986a_init,
+	.free = ad1986a_free,
+#ifdef CONFIG_PM
+	.resume = ad1986a_resume,
+#endif
+};
+
+static int patch_ad1986a(struct hda_codec *codec)
+{
+	struct ad1986a_spec *spec;
+
+	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	init_MUTEX(&spec->amp_mutex);
+	codec->spec = spec;
+
+	spec->multiout.max_channels = 6;
+	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
+	spec->multiout.dac_nids = ad1986a_dac_nids;
+	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
+
+	codec->patch_ops = ad1986a_patch_ops;
+
+	return 0;
+}
+
+/*
+ * patch entries
+ */
+struct hda_codec_preset snd_hda_preset_analog[] = {
+	{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
+	{} /* terminator */
+};
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-24 18:13:28 -08:00
+++ b/sound/pci/hda/patch_cmedia.c	2005-03-24 18:13:28 -08:00
@@ -112,9 +112,9 @@
 
 /* 3-stack / 6 channel */
 static struct hda_verb cmi9880_ch6_init[] = {
-	/* set line-in PIN for input */
+	/* set line-in PIN for output */
 	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	/* set mic PIN for input, also enable vref */
+	/* set mic PIN for output */
 	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 	/* route front PCM (DAC1) to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
@@ -123,9 +123,9 @@
 
 /* 3-stack+front / 8 channel */
 static struct hda_verb cmi9880_ch8_init[] = {
-	/* set line-in PIN for input */
+	/* set line-in PIN for output */
 	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	/* set mic PIN for input, also enable vref */
+	/* set mic PIN for output */
 	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 	/* route rear-surround PCM (DAC4) to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 },
@@ -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/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
--- a/sound/pci/hda/patch_realtek.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/hda/patch_realtek.c	2005-03-24 18:13:28 -08:00
@@ -1133,6 +1133,8 @@
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
 	{
@@ -1162,6 +1164,8 @@
 	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 	/* enable HP */
 	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	/* enable Mono */
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 	/* unmute amp left and right */
 	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
 	/* set connection select to line in (default select for this ADC) */
@@ -1174,6 +1178,10 @@
 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 	/* mute pin widget amp left and right (no gain on this amp) */
 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* unmute Mono mixer amp left and right (volume = 0) */
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* mute pin widget amp left and right (no gain on this amp) */
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 	/* mute LINE-2 out */
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
@@ -1190,6 +1198,9 @@
 	/* Unmute Headphone out path */
 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* Unmute Mono out path */
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 	{ }
 };
 
diff -Nru a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
--- a/sound/pci/mixart/mixart.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/mixart/mixart.c	2005-03-24 18:13:28 -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-24 18:13:28 -08:00
+++ b/sound/pci/mixart/mixart.h	2005-03-24 18:13:28 -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-24 18:13:29 -08:00
+++ b/sound/pci/mixart/mixart_hwdep.c	2005-03-24 18:13:29 -08:00
@@ -142,26 +142,35 @@
 	u32 k;
 	int err;
 	mixart_msg_t request;
-	mixart_enum_connector_resp_t connector;
-	mixart_audio_info_req_t  audio_info_req;
-	mixart_audio_info_resp_t audio_info;
-
-	audio_info_req.line_max_level = MIXART_FLOAT_P_22_0_TO_HEX;
-	audio_info_req.micro_max_level = MIXART_FLOAT_M_20_0_TO_HEX;
-	audio_info_req.cd_max_level = MIXART_FLOAT____0_0_TO_HEX;
+	mixart_enum_connector_resp_t *connector;
+	mixart_audio_info_req_t  *audio_info_req;
+	mixart_audio_info_resp_t *audio_info;
+
+	connector = kmalloc(sizeof(*connector), GFP_KERNEL);
+	audio_info_req = kmalloc(sizeof(*audio_info_req), GFP_KERNEL);
+	audio_info = kmalloc(sizeof(*audio_info), GFP_KERNEL);
+	if (! connector || ! audio_info_req || ! audio_info) {
+		err = -ENOMEM;
+		goto __error;
+	}
+
+	audio_info_req->line_max_level = MIXART_FLOAT_P_22_0_TO_HEX;
+	audio_info_req->micro_max_level = MIXART_FLOAT_M_20_0_TO_HEX;
+	audio_info_req->cd_max_level = MIXART_FLOAT____0_0_TO_HEX;
 
 	request.message_id = MSG_SYSTEM_ENUM_PLAY_CONNECTOR;
 	request.uid = (mixart_uid_t){0,0};  /* board num = 0 */
 	request.data = NULL;
 	request.size = 0;
 
-	err = snd_mixart_send_msg(mgr, &request, sizeof(connector), &connector);
-	if((err < 0) || (connector.error_code) || (connector.uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
+	err = snd_mixart_send_msg(mgr, &request, sizeof(*connector), connector);
+	if((err < 0) || (connector->error_code) || (connector->uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
 		snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_PLAY_CONNECTOR\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto __error;
 	}
 
-	for(k=0; k < connector.uid_count; k++) {
+	for(k=0; k < connector->uid_count; k++) {
 		mixart_pipe_t* pipe;
 
 		if(k < MIXART_FIRST_DIG_AUDIO_ID) {
@@ -170,25 +179,25 @@
 			pipe = &mgr->chip[(k-MIXART_FIRST_DIG_AUDIO_ID)/2]->pipe_out_dig;
 		}
 		if(k & 1) {
-			pipe->uid_right_connector = connector.uid[k];   /* odd */
+			pipe->uid_right_connector = connector->uid[k];   /* odd */
 		} else {
-			pipe->uid_left_connector = connector.uid[k];    /* even */
+			pipe->uid_left_connector = connector->uid[k];    /* even */
 		}
 
-		/* snd_printk(KERN_DEBUG "playback connector[%d].object_id = %x\n", k, connector.uid[k].object_id); */
+		/* snd_printk(KERN_DEBUG "playback connector[%d].object_id = %x\n", k, connector->uid[k].object_id); */
 
 		/* TODO: really need send_msg MSG_CONNECTOR_GET_AUDIO_INFO for each connector ? perhaps for analog level caps ? */
 		request.message_id = MSG_CONNECTOR_GET_AUDIO_INFO;
-		request.uid = connector.uid[k];
-		request.data = &audio_info_req;
-		request.size = sizeof(audio_info_req);
+		request.uid = connector->uid[k];
+		request.data = audio_info_req;
+		request.size = sizeof(*audio_info_req);
 
-		err = snd_mixart_send_msg(mgr, &request, sizeof(audio_info), &audio_info);
+		err = snd_mixart_send_msg(mgr, &request, sizeof(*audio_info), audio_info);
 		if( err < 0 ) {
 			snd_printk(KERN_ERR "error MSG_CONNECTOR_GET_AUDIO_INFO\n");
-			return err;
+			goto __error;
 		}
-		/*snd_printk(KERN_DEBUG "play  analog_info.analog_level_present = %x\n", audio_info.info.analog_info.analog_level_present);*/
+		/*snd_printk(KERN_DEBUG "play  analog_info.analog_level_present = %x\n", audio_info->info.analog_info.analog_level_present);*/
 	}
 
 	request.message_id = MSG_SYSTEM_ENUM_RECORD_CONNECTOR;
@@ -196,13 +205,14 @@
 	request.data = NULL;
 	request.size = 0;
 
-	err = snd_mixart_send_msg(mgr, &request, sizeof(connector), &connector);
-	if((err < 0) || (connector.error_code) || (connector.uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
+	err = snd_mixart_send_msg(mgr, &request, sizeof(*connector), connector);
+	if((err < 0) || (connector->error_code) || (connector->uid_count > MIXART_MAX_PHYS_CONNECTORS)) {
 		snd_printk(KERN_ERR "error MSG_SYSTEM_ENUM_RECORD_CONNECTOR\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto __error;
 	}
 
-	for(k=0; k < connector.uid_count; k++) {
+	for(k=0; k < connector->uid_count; k++) {
 		mixart_pipe_t* pipe;
 
 		if(k < MIXART_FIRST_DIG_AUDIO_ID) {
@@ -211,28 +221,34 @@
 			pipe = &mgr->chip[(k-MIXART_FIRST_DIG_AUDIO_ID)/2]->pipe_in_dig;
 		}
 		if(k & 1) {
-			pipe->uid_right_connector = connector.uid[k];   /* odd */
+			pipe->uid_right_connector = connector->uid[k];   /* odd */
 		} else {
-			pipe->uid_left_connector = connector.uid[k];    /* even */
+			pipe->uid_left_connector = connector->uid[k];    /* even */
 		}
 
-		/* snd_printk(KERN_DEBUG "capture connector[%d].object_id = %x\n", k, connector.uid[k].object_id); */
+		/* snd_printk(KERN_DEBUG "capture connector[%d].object_id = %x\n", k, connector->uid[k].object_id); */
 
 		/* TODO: really need send_msg MSG_CONNECTOR_GET_AUDIO_INFO for each connector ? perhaps for analog level caps ? */
 		request.message_id = MSG_CONNECTOR_GET_AUDIO_INFO;
-		request.uid = connector.uid[k];
-		request.data = &audio_info_req;
-		request.size = sizeof(audio_info_req);
+		request.uid = connector->uid[k];
+		request.data = audio_info_req;
+		request.size = sizeof(*audio_info_req);
 
-		err = snd_mixart_send_msg(mgr, &request, sizeof(audio_info), &audio_info);
+		err = snd_mixart_send_msg(mgr, &request, sizeof(*audio_info), audio_info);
 		if( err < 0 ) {
 			snd_printk(KERN_ERR "error MSG_CONNECTOR_GET_AUDIO_INFO\n");
-			return err;
+			goto __error;
 		}
-		/*snd_printk(KERN_DEBUG "rec  analog_info.analog_level_present = %x\n", audio_info.info.analog_info.analog_level_present);*/
+		/*snd_printk(KERN_DEBUG "rec  analog_info.analog_level_present = %x\n", audio_info->info.analog_info.analog_level_present);*/
 	}
+	err = 0;
 
-	return 0;
+ __error:
+	kfree(connector);
+	kfree(audio_info_req);
+	kfree(audio_info);
+
+	return err;
 }
 
 static int mixart_enum_physio(mixart_mgr_t *mgr)
@@ -546,6 +562,7 @@
 		release_firmware(fw_entry);
 		if (err < 0)
 			return err;
+		mgr->dsp_loaded |= 1 << i;
 	}
 	return 0;
 }
@@ -573,7 +590,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 +616,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 +639,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-24 18:13:29 -08:00
+++ b/sound/pci/rme32.c	2005-03-24 18:13:29 -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-24 18:13:28 -08:00
+++ b/sound/pci/rme9652/hdsp.c	2005-03-24 18:13:28 -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/sonicvibes.c b/sound/pci/sonicvibes.c
--- a/sound/pci/sonicvibes.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/sonicvibes.c	2005-03-24 18:13:28 -08:00
@@ -1183,7 +1183,7 @@
 
 	gameport_set_name(gp, "SonicVibes Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci));
-	gp->dev.parent = &sonic->pci->dev;
+	gameport_set_dev_parent(gp, &sonic->pci->dev);
 	gp->io = sonic->game_port;
 
 	gameport_register_port(gp);
diff -Nru a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
--- a/sound/pci/trident/trident_main.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/trident/trident_main.c	2005-03-24 18:13:28 -08:00
@@ -3112,7 +3112,7 @@
 
 static unsigned char snd_trident_gameport_read(struct gameport *gameport)
 {
-	trident_t *chip = gameport->port_data;
+	trident_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 	return inb(TRID_REG(chip, GAMEPORT_LEGACY));
@@ -3120,7 +3120,7 @@
 
 static void snd_trident_gameport_trigger(struct gameport *gameport)
 {
-	trident_t *chip = gameport->port_data;
+	trident_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return);
 	outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
@@ -3128,7 +3128,7 @@
 
 static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	trident_t *chip = gameport->port_data;
+	trident_t *chip = gameport_get_port_data(gameport);
 	int i;
 
 	snd_assert(chip, return 0);
@@ -3145,7 +3145,7 @@
 
 static int snd_trident_gameport_open(struct gameport *gameport, int mode)
 {
-	trident_t *chip = gameport->port_data;
+	trident_t *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 
@@ -3175,9 +3175,9 @@
 
 	gameport_set_name(gp, "Trident 4DWave");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 
-	gp->port_data = chip;
+	gameport_set_port_data(gp, chip);
 	gp->fuzz = 64;
 	gp->read = snd_trident_gameport_read;
 	gp->trigger = snd_trident_gameport_trigger;
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/via82xx.c	2005-03-24 18:13:28 -08:00
@@ -1660,9 +1660,9 @@
 
 	gameport_set_name(gp, "VIA686 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 	gp->io = JOYSTICK_ADDR;
-	gp->port_data = r;
+	gameport_set_port_data(gp, r);
 
 	/* Enable legacy joystick port */
 	*legacy |= VIA_FUNC_ENABLE_GAME;
@@ -1676,7 +1676,7 @@
 static void snd_via686_free_gameport(via82xx_t *chip)
 {
 	if (chip->gameport) {
-		struct resource *r = chip->gameport->port_data;
+		struct resource *r = gameport_get_port_data(chip->gameport);
 
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
@@ -1838,14 +1838,10 @@
 
 static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
 {
-	ac97_t ac97;
 	unsigned int val;
 	int max_count;
 	unsigned char pval;
 
-	memset(&ac97, 0, sizeof(ac97));
-	ac97.private_data = chip;
-
 #if 0 /* broken on K7M? */
 	if (chip->chip_type == TYPE_VIA686)
 		/* disable all legacy ports */
@@ -1897,11 +1893,6 @@
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
 		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
 
-	/* and then reset codec.. */
-	snd_via82xx_codec_ready(chip, 0);
-	snd_via82xx_codec_write(&ac97, AC97_RESET, 0x0000);
-	snd_via82xx_codec_read(&ac97, 0);
-
 #if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
@@ -2168,6 +2159,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 */
diff -Nru a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
--- a/sound/pci/via82xx_modem.c	2005-03-24 18:13:29 -08:00
+++ b/sound/pci/via82xx_modem.c	2005-03-24 18:13:29 -08:00
@@ -940,14 +940,10 @@
 
 static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
 {
-	ac97_t ac97;
 	unsigned int val;
 	int max_count;
 	unsigned char pval;
 
-	memset(&ac97, 0, sizeof(ac97));
-	ac97.private_data = chip;
-
 	pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
 	if((pval & VIA_MC97_CTRL_INIT) != VIA_MC97_CTRL_INIT) {
 		pci_write_config_byte(chip->pci, 0x44, pval|VIA_MC97_CTRL_INIT);
@@ -995,13 +991,6 @@
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
 		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
-
-	/* and then reset codec.. */
-#if 0 /* do we need it? when? */
-	snd_via82xx_codec_ready(chip, 0);
-	snd_via82xx_codec_write(&ac97, AC97_RESET, 0x0000);
-	snd_via82xx_codec_read(&ac97, 0);
-#endif
 
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
diff -Nru a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
--- a/sound/pci/ymfpci/ymfpci.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pci/ymfpci/ymfpci.c	2005-03-24 18:13:28 -08:00
@@ -138,8 +138,9 @@
 
 	gameport_set_name(gp, "Yamaha YMF Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
-	gp->dev.parent = &chip->pci->dev;
+	gameport_set_dev_parent(gp, &chip->pci->dev);
 	gp->io = io_port;
+	gameport_set_port_data(gp, r);
 
 	if (chip->pci->device >= 0x0010) /* YMF 744/754 */
 		pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, io_port);
@@ -155,7 +156,7 @@
 void snd_ymfpci_free_gameport(ymfpci_t *chip)
 {
 	if (chip->gameport) {
-		struct resource *r = chip->gameport->port_data;
+		struct resource *r = gameport_get_port_data(chip->gameport);
 
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
diff -Nru a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-03-24 18:13:28 -08:00
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-03-24 18:13:28 -08:00
@@ -272,12 +272,17 @@
 	client_handle_t handle = link->handle;
 	pdacf_t *pdacf = link->priv;
 	tuple_t tuple;
-	cisparse_t parse;
+	cisparse_t *parse = NULL;
 	config_info_t conf;
 	u_short buf[32];
 	int last_fn, last_ret;
 
 	snd_printdd(KERN_DEBUG "pdacf_config called\n");
+	parse = kmalloc(sizeof(*parse), GFP_KERNEL);
+	if (! parse) {
+		snd_printk(KERN_ERR "pdacf_config: cannot allocate\n");
+		return;
+	}
 	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 	tuple.Attributes = 0;
 	tuple.TupleData = (cisdata_t *)buf;
@@ -286,9 +291,10 @@
 	tuple.DesiredTuple = CISTPL_CONFIG;
 	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
 	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
-	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
-	link->conf.ConfigBase = parse.config.base;
+	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse));
+	link->conf.ConfigBase = parse->config.base;
 	link->conf.ConfigIndex = 0x5;
+	kfree(parse);
 
 	CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
 	link->conf.Vcc = conf.Vcc;
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	2005-03-24 18:13:28 -08:00
+++ b/sound/usb/usbaudio.c	2005-03-24 18:13:28 -08:00
@@ -1141,7 +1141,7 @@
 		data[0] = 1;
 		if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
 					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
-					   PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) {
+					   PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
 			snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
 				   dev->devnum, iface, ep);
 			return err;
@@ -1167,14 +1167,14 @@
 		data[2] = rate >> 16;
 		if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR,
 					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
-					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) {
 			snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n",
 				   dev->devnum, iface, fmt->altsetting, rate, ep);
 			return err;
 		}
 		if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR,
 					   USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
-					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) {
+					   SAMPLING_FREQ_CONTROL << 8, ep, data, 3, 1000)) < 0) {
 			snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep 0x%x\n",
 				   dev->devnum, iface, fmt->altsetting, ep);
 			return 0; /* some devices don't support reading */
@@ -1606,62 +1606,65 @@
 	return changed;
 }
 
+#define MAX_MASK	64
+
 /*
  * check whether the registered audio formats need special hw-constraints
  */
 static int check_hw_params_convention(snd_usb_substream_t *subs)
 {
 	int i;
-	u32 channels[64];
-	u32 rates[64];
+	u32 *channels;
+	u32 *rates;
 	u32 cmaster, rmaster;
 	u32 rate_min = 0, rate_max = 0;
 	struct list_head *p;
+	int err = 1;
 
-	memset(channels, 0, sizeof(channels));
-	memset(rates, 0, sizeof(rates));
+	channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
+	rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
 
 	list_for_each(p, &subs->fmt_list) {
 		struct audioformat *f;
 		f = list_entry(p, struct audioformat, list);
 		/* unconventional channels? */
 		if (f->channels > 32)
-			return 1;
+			goto __out;
 		/* continuous rate min/max matches? */
 		if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
 			if (rate_min && f->rate_min != rate_min)
-				return 1;
+				goto __out;
 			if (rate_max && f->rate_max != rate_max)
-				return 1;
+				goto __out;
 			rate_min = f->rate_min;
 			rate_max = f->rate_max;
 		}
 		/* combination of continuous rates and fixed rates? */
 		if (rates[f->format] & SNDRV_PCM_RATE_CONTINUOUS) {
 			if (f->rates != rates[f->format])
-				return 1;
+				goto __out;
 		}
 		if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) {
 			if (rates[f->format] && rates[f->format] != f->rates)
-				return 1;
+				goto __out;
 		}
 		channels[f->format] |= (1 << f->channels);
 		rates[f->format] |= f->rates;
 	}
 	/* check whether channels and rates match for all formats */
 	cmaster = rmaster = 0;
-	for (i = 0; i < 64; i++) {
+	for (i = 0; i < MAX_MASK; i++) {
 		if (cmaster != channels[i] && cmaster && channels[i])
-			return 1;
+			goto __out;
 		if (rmaster != rates[i] && rmaster && rates[i])
-			return 1;
+			goto __out;
 		if (channels[i])
 			cmaster = channels[i];
 		if (rates[i])
 			rmaster = rates[i];
 	}
 	/* check whether channels match for all distinct rates */
-	memset(channels, 0, sizeof(channels));
+	memset(channels, 0, MAX_MASK * sizeof(u32));
 	list_for_each(p, &subs->fmt_list) {
 		struct audioformat *f;
 		f = list_entry(p, struct audioformat, list);
@@ -1675,11 +1678,16 @@
 	cmaster = 0;
 	for (i = 0; i < 32; i++) {
 		if (cmaster != channels[i] && cmaster && channels[i])
-			return 1;
+			goto __out;
 		if (channels[i])
 			cmaster = channels[i];
 	}
-	return 0;
+	err = 0;
+
+ __out:
+	kfree(channels);
+	kfree(rates);
+	return err;
 }
 
 
@@ -2936,7 +2944,7 @@
 		snd_printdd("sending Extigy boot sequence...\n");
 		/* Send message to force it to reconnect with full interface. */
 		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
-				      0x10, 0x43, 0x0001, 0x000a, NULL, 0, HZ);
+				      0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
 		if (err < 0) snd_printdd("error sending boot message: %d\n", err);
 		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
 				&dev->descriptor, sizeof(dev->descriptor));
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c	2005-03-24 18:13:28 -08:00
+++ b/sound/usb/usbmidi.c	2005-03-24 18:13:28 -08:00
@@ -287,7 +287,7 @@
 	memcpy(buf, data, len);
 	dump_urb("sending", buf, len);
 	err = usb_bulk_msg(ep->umidi->chip->dev, ep->urb->pipe, buf, len,
-			   NULL, HZ / 4);
+			   NULL, 1000);
 	kfree(buf);
 	return err;
 }