http://linux-sound.bkbits.net/linux-sound
perex@suse.cz|ChangeSet|20041020185133|25979 perex

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/10/21 00:10:35-07:00 akpm@bix.(none) 
#   dd
# 
# sound/pci/nm256/nm256.c
#   2004/10/21 00:10:27-07:00 akpm@bix.(none) +1 -0
#   ffff
# 
# ChangeSet
#   2004/10/21 00:09:39-07:00 akpm@bix.(none) 
#   bar
# 
# sound/pci/intel8x0.c
#   2004/10/21 00:09:30-07:00 akpm@bix.(none) +6 -2
#   foo
# 
# sound/usb/usx2y/usbusx2y.c
#   2004/10/21 00:08:05-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/usb/usbaudio.c
#   2004/10/21 00:08:05-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/via82xx.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/rme9652/rme9652.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/rme9652/hdsp.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/rme96.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/mixart/mixart.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/korg1212/korg1212.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ice1712/ice1724.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ice1712/ice1712.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/au88x0/au88x0.c
#   2004/10/21 00:08:04-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/rme32.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/intel8x0m.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/es1968.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/ens1370.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/bt87x.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/atiixp_modem.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/atiixp.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/parisc/harmony.c
#   2004/10/21 00:08:03-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/es18xx.c
#   2004/10/21 00:08:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/drivers/dummy.c
#   2004/10/21 00:08:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/core/seq/seq.c
#   2004/10/21 00:08:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/core/oss/pcm_oss.c
#   2004/10/21 00:08:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/core/memalloc.c
#   2004/10/21 00:08:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/20 20:33:06+02:00 perex@suse.cz 
#   Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5
#   into suse.cz:/home/perex/bk/linux-sound/linux-sound
# 
# sound/core/init.c
#   2004/10/20 20:32:42+02:00 perex@suse.cz +0 -1
#   Auto merged
# 
# ChangeSet
#   2004/10/20 14:14:29+02:00 perex@suse.cz 
#   [ALSA]  Fix non-blocking write in ALSA OSS emulation
#   
#   ALSA<-OSS emulation
#   write() calls in non-blocking mode eat the written data and never
#   return -EAGAIN.  The attached patch fixes the problem.
#   
#   Signed-off-by: Benjamin Otte <otte@gnome.org>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/oss/pcm_oss.c
#   2004/10/18 10:42:06+02:00 perex@suse.cz +6 -6
#   [ALSA]  Fix non-blocking write in ALSA OSS emulation
#   
#   D:2004/10/18 16:42:06
#   C:ALSA<-OSS emulation
#   F:core/oss/pcm_oss.c:1.78->1.79 
#   L:write() calls in non-blocking mode eat the written data and never
#   L:return -EAGAIN.  The attached patch fixes the problem.
#   Signed-off-by: Benjamin Otte <otte@gnome.org>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:13:41+02:00 perex@suse.cz 
#   [ALSA]  PCM boundary fix in 32bit compat layer
#   
#   IOCTL32 emulation
#   PCM boundary size is fixed within the 32bit value range when HW_PARAMS
#   ioctl is called in 32bit mode.
#   Also, with this patch, the conversion functions are inlined.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/pcm32.c
#   2004/10/18 09:55:51+02:00 perex@suse.cz +64 -4
#   [ALSA]  PCM boundary fix in 32bit compat layer
#   
#   D:2004/10/18 15:55:51
#   C:IOCTL32 emulation
#   F:core/ioctl32/hwdep32.c:1.8->1.9 
#   F:core/ioctl32/ioctl32.c:1.22->1.23 
#   F:core/ioctl32/ioctl32.h:1.15->1.16 
#   F:core/ioctl32/pcm32.c:1.21->1.22 
#   L:PCM boundary size is fixed within the 32bit value range when HW_PARAMS
#   L:ioctl is called in 32bit mode.
#   L:Also, with this patch, the conversion functions are inlined.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/ioctl32.h
#   2004/10/18 09:55:51+02:00 perex@suse.cz +2 -2
#   [ALSA]  PCM boundary fix in 32bit compat layer
#   
#   D:2004/10/18 15:55:51
#   C:IOCTL32 emulation
#   F:core/ioctl32/hwdep32.c:1.8->1.9 
#   F:core/ioctl32/ioctl32.c:1.22->1.23 
#   F:core/ioctl32/ioctl32.h:1.15->1.16 
#   F:core/ioctl32/pcm32.c:1.21->1.22 
#   L:PCM boundary size is fixed within the 32bit value range when HW_PARAMS
#   L:ioctl is called in 32bit mode.
#   L:Also, with this patch, the conversion functions are inlined.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/ioctl32.c
#   2004/10/18 09:55:51+02:00 perex@suse.cz +3 -3
#   [ALSA]  PCM boundary fix in 32bit compat layer
#   
#   D:2004/10/18 15:55:51
#   C:IOCTL32 emulation
#   F:core/ioctl32/hwdep32.c:1.8->1.9 
#   F:core/ioctl32/ioctl32.c:1.22->1.23 
#   F:core/ioctl32/ioctl32.h:1.15->1.16 
#   F:core/ioctl32/pcm32.c:1.21->1.22 
#   L:PCM boundary size is fixed within the 32bit value range when HW_PARAMS
#   L:ioctl is called in 32bit mode.
#   L:Also, with this patch, the conversion functions are inlined.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/hwdep32.c
#   2004/10/18 09:55:51+02:00 perex@suse.cz +1 -1
#   [ALSA]  PCM boundary fix in 32bit compat layer
#   
#   D:2004/10/18 15:55:51
#   C:IOCTL32 emulation
#   F:core/ioctl32/hwdep32.c:1.8->1.9 
#   F:core/ioctl32/ioctl32.c:1.22->1.23 
#   F:core/ioctl32/ioctl32.h:1.15->1.16 
#   F:core/ioctl32/pcm32.c:1.21->1.22 
#   L:PCM boundary size is fixed within the 32bit value range when HW_PARAMS
#   L:ioctl is called in 32bit mode.
#   L:Also, with this patch, the conversion functions are inlined.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:12:54+02:00 perex@suse.cz 
#   [ALSA]  Add VIA8237 driver type
#   
#   VIA82xx driver
#   VIA8237 and later chips are handled as a different type from VIA8233,
#   since they don't support the AC97 slot mapping any more.
#   The alsa-lib will resolve the 5.1 remapping for them.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2004/10/18 09:54:00+02:00 perex@suse.cz +4 -0
#   [ALSA]  Add VIA8237 driver type
#   
#   D:2004/10/18 15:54:00
#   C:VIA82xx driver
#   F:pci/via82xx.c:1.124->1.125 
#   L:VIA8237 and later chips are handled as a different type from VIA8233,
#   L:since they don't support the AC97 slot mapping any more.
#   L:The alsa-lib will resolve the 5.1 remapping for them.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:12:07+02:00 perex@suse.cz 
#   [ALSA]  Exclude uneeded code when ! CONFIG_PROC_FS
#   
#   PCM Midlevel,AC97 Codec Core
#   From Michal Rokos <michal@rokos.info>
#   
#   I tried to compile without procfs support and I got few 'unused code'
#   warnings.
#   
#   This patch fixes it.
#   
#   Tested by compilation only. (With CONFIG_PROC_FS on and off)
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_local.h
#   2004/10/18 08:01:40+02:00 perex@suse.cz +7 -0
#   [ALSA]  Exclude uneeded code when ! CONFIG_PROC_FS
#   
#   D:2004/10/18 14:01:40
#   C:PCM Midlevel,AC97 Codec Core
#   F:core/pcm.c:1.46->1.47 
#   F:pci/ac97/Makefile:1.14->1.15 
#   F:pci/ac97/ac97_local.h:1.7->1.8 
#   L:From Michal Rokos <michal@rokos.info>
#   L:
#   L:I tried to compile without procfs support and I got few 'unused code'
#   L:warnings.
#   L:
#   L:This patch fixes it.
#   L:
#   L:Tested by compilation only. (With CONFIG_PROC_FS on and off)
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/Makefile
#   2004/10/18 08:01:40+02:00 perex@suse.cz +6 -1
#   [ALSA]  Exclude uneeded code when ! CONFIG_PROC_FS
#   
#   D:2004/10/18 14:01:40
#   C:PCM Midlevel,AC97 Codec Core
#   F:core/pcm.c:1.46->1.47 
#   F:pci/ac97/Makefile:1.14->1.15 
#   F:pci/ac97/ac97_local.h:1.7->1.8 
#   L:From Michal Rokos <michal@rokos.info>
#   L:
#   L:I tried to compile without procfs support and I got few 'unused code'
#   L:warnings.
#   L:
#   L:This patch fixes it.
#   L:
#   L:Tested by compilation only. (With CONFIG_PROC_FS on and off)
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm.c
#   2004/10/18 08:01:40+02:00 perex@suse.cz +2 -1
#   [ALSA]  Exclude uneeded code when ! CONFIG_PROC_FS
#   
#   D:2004/10/18 14:01:40
#   C:PCM Midlevel,AC97 Codec Core
#   F:core/pcm.c:1.46->1.47 
#   F:pci/ac97/Makefile:1.14->1.15 
#   F:pci/ac97/ac97_local.h:1.7->1.8 
#   L:From Michal Rokos <michal@rokos.info>
#   L:
#   L:I tried to compile without procfs support and I got few 'unused code'
#   L:warnings.
#   L:
#   L:This patch fixes it.
#   L:
#   L:Tested by compilation only. (With CONFIG_PROC_FS on and off)
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:11:20+02:00 perex@suse.cz 
#   [ALSA]  Fix AC97_EXTENDED_STATUS initialial value
#   
#   AC97 Codec Core
#   Fixed a bug to write an invalid initial value of AC97_EXTENDED_STATUS.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/10/13 04:26:12+02:00 perex@suse.cz +5 -2
#   [ALSA]  Fix AC97_EXTENDED_STATUS initialial value
#   
#   D:2004/10/13 10:26:12
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.151->1.152 
#   L:Fixed a bug to write an invalid initial value of AC97_EXTENDED_STATUS.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:10:33+02:00 perex@suse.cz 
#   [ALSA]  Fixed SPDIF on CS4298
#   
#   AC97 Codec Core
#   Fixed SPDIF support on CS4298 AC97 chip.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/10/13 04:22:48+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fixed SPDIF on CS4298
#   
#   D:2004/10/13 10:22:48
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.150->1.151 
#   L:Fixed SPDIF support on CS4298 AC97 chip.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:09:47+02:00 perex@suse.cz 
#   [ALSA]  fix build in !KMOD case (sequencer)
#   
#   ALSA sequencer
#   seq_device.c needs to pull in the snd_seq_autoload_lock()/unlock()
#   defines from seq_kernel.h in the !KMOD case.
#   
#   Signed-off-by: Ingo Molnar <mingo@elte.hu>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/core/seq/seq_device.c
#   2004/10/12 01:17:43+02:00 perex@suse.cz +1 -0
#   [ALSA]  fix build in !KMOD case (sequencer)
#   
#   D:2004/10/12 07:17:43
#   C:ALSA sequencer
#   F:core/seq/seq_device.c:1.17->1.18 
#   L:seq_device.c needs to pull in the snd_seq_autoload_lock()/unlock()
#   L:defines from seq_kernel.h in the !KMOD case.
#   Signed-off-by: Ingo Molnar <mingo@elte.hu>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2004/10/20 14:09:00+02:00 perex@suse.cz 
#   [ALSA]  RME9632 precise_ptr fix
#   
#   RME HDSP driver
#   Correct hardware position mask to mask correctly when buffer is not
#   maximum size.
#   
#   Signed-off-by:  Ed Wildgoose <lists@wildgooses.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme9652/hdsp.c
#   2004/10/11 05:28:09+02:00 perex@suse.cz +1 -3
#   [ALSA]  RME9632 precise_ptr fix
#   
#   D:2004/10/11 11:28:09
#   C:RME HDSP driver
#   F:pci/rme9652/hdsp.c:1.71->1.72 
#   L:Correct hardware position mask to mask correctly when buffer is not
#   L:maximum size.
#   Signed-off-by:  Ed Wildgoose <lists@wildgooses.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:08:13+02:00 perex@suse.cz 
#   [ALSA]  Misc. volume fixes
#   
#   ICE1712 driver
#    - Added mute function to Master/Front/Rear/Side/LFE/CEnter
#    - Master volume is artificially made in software
#    - Added PCM volume control (basically what was the master volume)
#    - Front/Read/Side/LFE/Center is now logarithmic (and computed as <volume> * <master volume> / <maximum volume>)
#   
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/ice1712.h
#   2004/10/11 05:15:49+02:00 perex@suse.cz +5 -1
#   [ALSA]  Misc. volume fixes
#   
#   D:2004/10/11 11:15:49
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.21->1.22 
#   F:pci/ice1712/ice1712.h:1.25->1.26 
#   L: - Added mute function to Master/Front/Rear/Side/LFE/CEnter
#   L: - Master volume is artificially made in software
#   L: - Added PCM volume control (basically what was the master volume)
#   L: - Front/Read/Side/LFE/Center is now logarithmic (and computed as <volume> * <master volume> / <maximum volume>)
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.c
#   2004/10/11 05:15:49+02:00 perex@suse.cz +295 -77
#   [ALSA]  Misc. volume fixes
#   
#   D:2004/10/11 11:15:49
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.21->1.22 
#   F:pci/ice1712/ice1712.h:1.25->1.26 
#   L: - Added mute function to Master/Front/Rear/Side/LFE/CEnter
#   L: - Master volume is artificially made in software
#   L: - Added PCM volume control (basically what was the master volume)
#   L: - Front/Read/Side/LFE/Center is now logarithmic (and computed as <volume> * <master volume> / <maximum volume>)
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:07:27+02:00 perex@suse.cz 
#   [ALSA]  Add routing/volume of ADAT I/O on EWS88D
#   
#   ICE1712 driver
#   The routing/volume control of ADAT I/O on EWS88D is added.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/ews.c
#   2004/10/11 05:08:07+02:00 perex@suse.cz +4 -1
#   [ALSA]  Add routing/volume of ADAT I/O on EWS88D
#   
#   D:2004/10/11 11:08:07
#   C:ICE1712 driver
#   F:pci/ice1712/ews.c:1.20->1.21 
#   L:The routing/volume control of ADAT I/O on EWS88D is added.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/20 14:04:46+02:00 perex@suse.cz 
#   [ALSA]  fixing a two-rme32-in-one-machine bug
#       
#   RME32 driver
#       - fixing the dev counter in snd_rme32_probe(). The patch can enable a second
#         rme32 card
#   
#   Signed-off-by: Martin Langer <martin-langer@gmx.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme32.c
#   2004/10/07 07:58:41+02:00 perex@suse.cz +5 -7
#   [ALSA]  fixing a two-rme32-in-one-machine bug
#   
#   RME32 driver
#   - fixing the dev counter in snd_rme32_probe(). The patch can enable a second
#     rme32 card now.
#   
#   Signed-off-by: Martin Langer <martin-langer@gmx.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 14:06:21+02:00 perex@suse.cz 
#   Merge suse.cz:/home/perex/bk/linux-sound/linux-sound
#   into suse.cz:/home/perex/bk/linux-sound/work
# 
# sound/pci/intel8x0.c
#   2004/10/07 14:06:00+02:00 perex@suse.cz +0 -0
#   Auto merged
# 
# include/sound/seq_kernel.h
#   2004/10/07 14:05:59+02:00 perex@suse.cz +0 -0
#   Auto merged
# 
# include/sound/pcm.h
#   2004/10/07 14:05:59+02:00 perex@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/07 13:16:37+02:00 perex@suse.cz 
#   Merge
# 
# sound/pci/intel8x0.c
#   2004/10/07 13:16:21+02:00 perex@suse.cz +9 -7
#   SCCS merged
# 
# include/sound/pcm.h
#   2004/10/07 13:06:21+02:00 perex@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/07 12:34:36+02:00 perex@suse.cz 
#   [ALSA]  Fix the detection of secondary codec
#   
#   CS46xx driver
#   Fixed the detection of secondary codec.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/10/06 05:25:53+02:00 perex@suse.cz +1 -2
#   [ALSA]  Fix the detection of secondary codec
#   
#   D:2004/10/06 11:25:53
#   C:CS46xx driver
#   F:pci/cs46xx/cs46xx_lib.c:1.86->1.87 
#   L:Fixed the detection of secondary codec.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:33:47+02:00 perex@suse.cz 
#   [ALSA]  Fix Aureon CCS init sequence
#   
#   ICE1712 driver
#   - Fix Aureon 5.1 Sky GPIO write mask bits
#   - Fix 192kHz bit
#   
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.c
#   2004/10/06 05:19:28+02:00 perex@suse.cz +6 -6
#   [ALSA]  Fix Aureon CCS init sequence
#   
#   D:2004/10/06 11:19:28
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.20->1.21 
#   L:- Fix Aureon 5.1 Sky GPIO write mask bits
#   L:- Fix 192kHz bit
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:32:59+02:00 perex@suse.cz 
#   [ALSA]  Fix compilation (sync with parisc tree)
#   
#   PARISC Harmony driver
#   Sync with parisc tree - fix compilations, module description fixes.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/parisc/harmony.c
#   2004/10/06 05:12:12+02:00 perex@suse.cz +9 -6
#   [ALSA]  Fix compilation (sync with parisc tree)
#   
#   D:2004/10/06 11:12:12
#   C:PARISC Harmony driver
#   F:parisc/harmony.c:1.17->1.18 
#   L:Sync with parisc tree - fix compilations, module description fixes.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:32:11+02:00 perex@suse.cz 
#   [ALSA]  Fix ac97 codec reset and clean up
#   
#   CS46xx driver
#   - Fixed AC97 codec RESET for duel codecs (only for CONFIG_SND_CS46XX_NEW_DSP)
#   - Clean up the codec detection routine
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/10/06 04:55:22+02:00 perex@suse.cz +49 -74
#   [ALSA]  Fix ac97 codec reset and clean up
#   
#   D:2004/10/06 10:55:22
#   C:CS46xx driver
#   F:pci/cs46xx/cs46xx_lib.c:1.85->1.86 
#   L:- Fixed AC97 codec RESET for duel codecs (only for CONFIG_SND_CS46XX_NEW_DSP)
#   L:- Clean up the codec detection routine
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:31:18+02:00 perex@suse.cz 
#   [ALSA]  Added dxs quirk for QDI Kudoz 7X/600-6AL
#   
#   VIA82xx driver
#   Added the default dxs_support entry for QDI Kudoz 7X/600-6AL.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2004/10/05 12:19:28+02:00 perex@suse.cz +1 -0
#   [ALSA]  Added dxs quirk for QDI Kudoz 7X/600-6AL
#   
#   D:2004/10/05 18:19:28
#   C:VIA82xx driver
#   F:pci/via82xx.c:1.123->1.124 
#   L:Added the default dxs_support entry for QDI Kudoz 7X/600-6AL.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:30:20+02:00 perex@suse.cz 
#   [ALSA]  Fix typo
#   
#   ALSA sequencer
#   Fixed a typo for snd_seq_autoload_lock() in the last change
#   (only for the case without CONFIG_KMOD).
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/seq_kernel.h
#   2004/10/05 05:07:41+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix typo
#   
#   D:2004/10/05 11:07:41
#   C:ALSA sequencer
#   F:include/seq_kernel.h:1.12->1.13 
#   L:Fixed a typo for snd_seq_autoload_lock() in the last change
#   L:(only for the case without CONFIG_KMOD).
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:29:22+02:00 perex@suse.cz 
#   [ALSA]  Add KERN_ERR to error messages
#   
#   ALSA Core
#   Added KERN_ERR prefix to error messages in snd_assert() and
#   snd_runtime_check() macros.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/core.h
#   2004/10/04 10:41:01+02:00 perex@suse.cz +2 -2
#   [ALSA]  Add KERN_ERR to error messages
#   
#   D:2004/10/04 16:41:01
#   C:ALSA Core
#   F:include/core.h:1.58->1.59 
#   L:Added KERN_ERR prefix to error messages in snd_assert() and
#   L:snd_runtime_check() macros.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:28:22+02:00 perex@suse.cz 
#   [ALSA]  Fix pci_restore_state()
#   
#   ALSA Core
#   Fixed pci_save_state() call with the new API.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/init.c
#   2004/10/04 10:40:12+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix pci_restore_state()
#   
#   D:2004/10/04 16:40:12
#   C:ALSA Core
#   F:core/init.c:1.48->1.49 
#   L:Fixed pci_save_state() call with the new API.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:27:21+02:00 perex@suse.cz 
#   [ALSA]  Fix dead blocking during module_init()
#   
#   ALSA sequencer,ALSA<-OSS sequencer
#   Fixed the auto-loading of modules during module_init().
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_midi.c
#   2004/10/04 05:33:23+02:00 perex@suse.cz +2 -0
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_dummy.c
#   2004/10/04 05:33:23+02:00 perex@suse.cz +5 -1
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_device.c
#   2004/10/04 05:33:23+02:00 perex@suse.cz +30 -1
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_clientmgr.c
#   2004/10/04 05:33:23+02:00 perex@suse.cz +1 -6
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq.c
#   2004/10/04 05:33:23+02:00 perex@suse.cz +10 -12
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/oss/seq_oss.c
#   2004/10/04 05:33:24+02:00 perex@suse.cz +9 -5
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/seq_kernel.h
#   2004/10/04 05:33:24+02:00 perex@suse.cz +8 -0
#   [ALSA]  Fix dead blocking during module_init()
#   
#   D:2004/10/04 11:33:23
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   F:core/seq/seq.c:1.15->1.16 
#   F:core/seq/seq_clientmgr.c:1.37->1.38 
#   F:core/seq/seq_device.c:1.16->1.17 
#   F:core/seq/seq_dummy.c:1.14->1.15 
#   F:core/seq/seq_midi.c:1.23->1.24 
#   F:core/seq/oss/seq_oss.c:1.16->1.17 
#   F:include/seq_kernel.h:1.11->1.12 
#   L:Fixed the auto-loading of modules during module_init().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:26:16+02:00 perex@suse.cz 
#   [ALSA]  Clean up bitmap
#   
#   EMU10K1/EMU10K2 driver
#   Clean up the declaration of bitmap with DECLARE_BITMAP().
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/emu10k1.h
#   2004/10/01 10:16:50+02:00 perex@suse.cz +3 -3
#   [ALSA]  Clean up bitmap
#   
#   D:2004/10/01 16:16:50
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.46->1.47 
#   L:Clean up the declaration of bitmap with DECLARE_BITMAP().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:25:41+02:00 perex@suse.cz 
#   [ALSA]  fix snd_opl3_init documentation
#   
#   Documentation
#   
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/10/01 08:43:42+02:00 perex@suse.cz +1 -1
#   [ALSA]  fix snd_opl3_init documentation
#   
#   D:2004/10/01 14:43:42
#   C:Documentation
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.41->1.42 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/10/07 12:25:09+02:00 perex@suse.cz 
#   [ALSA]  fix description of SPSA=3 in the proc file
#   
#   AC97 Codec Core
#   
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ac97/ac97_proc.c
#   2004/10/01 08:42:22+02:00 perex@suse.cz +1 -1
#   [ALSA]  fix description of SPSA=3 in the proc file
#   
#   D:2004/10/01 14:42:22
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_proc.c:1.11->1.12 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/10/07 12:24:37+02:00 perex@suse.cz 
#   [ALSA]  fix DAC slot assignment
#   
#   AC97 Codec Core
#   write the DAC slot assignment bits to the extended ID register
#   where they belong instead of overwriting the SPSA bits in the
#   extended status register
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ac97/ac97_pcm.c
#   2004/10/01 08:41:04+02:00 perex@suse.cz +2 -2
#   [ALSA]  fix DAC slot assignment
#   
#   D:2004/10/01 14:41:04
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_pcm.c:1.17->1.18 
#   L:write the DAC slot assignment bits to the extended ID register
#   L:where they belong instead of overwriting the SPSA bits in the
#   L:extended status register
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/10/07 12:24:06+02:00 perex@suse.cz 
#   [ALSA]  Fix / clean up OPL3 for CS4281
#   
#   Documentation,OPL3,CS4281 driver
#   Moved cs4281-specific code into cs4281 driver from opl3.
#   The ugly type-casting is removed now.
#   
#   The opl3 instance can be created via snd_opl3_new() (followed by
#   snd_opl3_init()) to allow the driver to set its own command and
#   private_data/private_free.
#   
#   snd_opl3_create() is kept for compatibility as it was.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs4281.c
#   2004/09/30 11:48:43+02:00 perex@suse.cz +29 -4
#   [ALSA]  Fix / clean up OPL3 for CS4281
#   
#   D:2004/09/30 17:48:43
#   C:Documentation,OPL3,CS4281 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.40->1.41 
#   F:drivers/opl3/opl3_lib.c:1.22->1.23 
#   F:include/opl3.h:1.11->1.12 
#   F:pci/cs4281.c:1.64->1.65 
#   L:Moved cs4281-specific code into cs4281 driver from opl3.
#   L:The ugly type-casting is removed now.
#   L:
#   L:The opl3 instance can be created via snd_opl3_new() (followed by
#   L:snd_opl3_init()) to allow the driver to set its own command and
#   L:private_data/private_free.
#   L:
#   L:snd_opl3_create() is kept for compatibility as it was.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/drivers/opl3/opl3_lib.c
#   2004/09/30 11:48:43+02:00 perex@suse.cz +70 -68
#   [ALSA]  Fix / clean up OPL3 for CS4281
#   
#   D:2004/09/30 17:48:43
#   C:Documentation,OPL3,CS4281 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.40->1.41 
#   F:drivers/opl3/opl3_lib.c:1.22->1.23 
#   F:include/opl3.h:1.11->1.12 
#   F:pci/cs4281.c:1.64->1.65 
#   L:Moved cs4281-specific code into cs4281 driver from opl3.
#   L:The ugly type-casting is removed now.
#   L:
#   L:The opl3 instance can be created via snd_opl3_new() (followed by
#   L:snd_opl3_init()) to allow the driver to set its own command and
#   L:private_data/private_free.
#   L:
#   L:snd_opl3_create() is kept for compatibility as it was.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/opl3.h
#   2004/09/30 11:48:43+02:00 perex@suse.cz +5 -0
#   [ALSA]  Fix / clean up OPL3 for CS4281
#   
#   D:2004/09/30 17:48:43
#   C:Documentation,OPL3,CS4281 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.40->1.41 
#   F:drivers/opl3/opl3_lib.c:1.22->1.23 
#   F:include/opl3.h:1.11->1.12 
#   F:pci/cs4281.c:1.64->1.65 
#   L:Moved cs4281-specific code into cs4281 driver from opl3.
#   L:The ugly type-casting is removed now.
#   L:
#   L:The opl3 instance can be created via snd_opl3_new() (followed by
#   L:snd_opl3_init()) to allow the driver to set its own command and
#   L:private_data/private_free.
#   L:
#   L:snd_opl3_create() is kept for compatibility as it was.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/09/30 11:48:43+02:00 perex@suse.cz +33 -1
#   [ALSA]  Fix / clean up OPL3 for CS4281
#   
#   D:2004/09/30 17:48:43
#   C:Documentation,OPL3,CS4281 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.40->1.41 
#   F:drivers/opl3/opl3_lib.c:1.22->1.23 
#   F:include/opl3.h:1.11->1.12 
#   F:pci/cs4281.c:1.64->1.65 
#   L:Moved cs4281-specific code into cs4281 driver from opl3.
#   L:The ugly type-casting is removed now.
#   L:
#   L:The opl3 instance can be created via snd_opl3_new() (followed by
#   L:snd_opl3_init()) to allow the driver to set its own command and
#   L:private_data/private_free.
#   L:
#   L:snd_opl3_create() is kept for compatibility as it was.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:23:34+02:00 perex@suse.cz 
#   ALSA CVS update
#   USB generic driver
#   add Edirol UA-25 support
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbquirks.h
#   2004/09/30 05:11:25+02:00 perex@suse.cz +34 -3
#   ALSA CVS update
#   D:2004/09/30 11:11:25
#   C:USB generic driver
#   F:usb/usbaudio.c:1.109->1.110 
#   F:usb/usbaudio.h:1.34->1.35 
#   F:usb/usbquirks.h:1.37->1.38 
#   L:add Edirol UA-25 support
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbaudio.h
#   2004/09/30 05:11:25+02:00 perex@suse.cz +2 -2
#   ALSA CVS update
#   D:2004/09/30 11:11:25
#   C:USB generic driver
#   F:usb/usbaudio.c:1.109->1.110 
#   F:usb/usbaudio.h:1.34->1.35 
#   F:usb/usbquirks.h:1.37->1.38 
#   L:add Edirol UA-25 support
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbaudio.c
#   2004/09/30 05:11:25+02:00 perex@suse.cz +26 -10
#   ALSA CVS update
#   D:2004/09/30 11:11:25
#   C:USB generic driver
#   F:usb/usbaudio.c:1.109->1.110 
#   F:usb/usbaudio.h:1.34->1.35 
#   F:usb/usbquirks.h:1.37->1.38 
#   L:add Edirol UA-25 support
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/10/07 12:23:01+02:00 perex@suse.cz 
#   [ALSA]  Fix AC3 playback on SB Live
#   
#   EMU10K1/EMU10K2 driver
#   Fix the AC3 playback on SB Live!
#   (Audigy has been working fine.)
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emupcm.c
#   2004/09/30 05:06:53+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix AC3 playback on SB Live
#   
#   D:2004/09/30 11:06:53
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emupcm.c:1.32->1.33 
#   L:Fix the AC3 playback on SB Live!
#   L:(Audigy has been working fine.)
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:22:30+02:00 perex@suse.cz 
#   [ALSA]  Fix AC97 master mute
#   
#   ICE1712 driver
#   Instead of muting the AC97 chip and thus eliminating the possibility of recording,
#   muting is done by setting front playback to DAC only instead of DAC+AUX.
#   
#   Signed-off-by: Peter Christensen <ungod@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.c
#   2004/09/29 10:55:44+02:00 perex@suse.cz +39 -3
#   [ALSA]  Fix AC97 master mute
#   
#   D:2004/09/29 16:55:44
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.19->1.20 
#   L:Instead of muting the AC97 chip and thus eliminating the possibility of recording,
#   L:muting is done by setting front playback to DAC only instead of DAC+AUX.
#   Signed-off-by: Peter Christensen <ungod@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:21:33+02:00 perex@suse.cz 
#   [ALSA]  Fix SPDIF support on ICH4/5/6
#   
#   Intel8x0 driver
#   Fixed SPDIF support on ICH4/5/6.  The driver name of these chipsets
#   is set as 'ICH4' to tell from the older ICHs.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2004/09/29 10:46:41+02:00 perex@suse.cz +11 -0
#   [ALSA]  Fix SPDIF support on ICH4/5/6
#   
#   D:2004/09/29 16:46:41
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.171->1.172 
#   L:Fixed SPDIF support on ICH4/5/6.  The driver name of these chipsets
#   L:is set as 'ICH4' to tell from the older ICHs.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:20:47+02:00 perex@suse.cz 
#   [ALSA]  Add (experimental) CM9761 support
#   
#   AC97 Codec Core
#   CM9761 support patch is added.
#   At least, SPDIF and 4.0 output seems working.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_patch.h
#   2004/09/29 10:45:52+02:00 perex@suse.cz +1 -0
#   [ALSA]  Add (experimental) CM9761 support
#   
#   D:2004/09/29 16:45:52
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.149->1.150 
#   F:pci/ac97/ac97_id.h:1.9->1.10 
#   F:pci/ac97/ac97_patch.c:1.57->1.58 
#   F:pci/ac97/ac97_patch.h:1.16->1.17 
#   L:CM9761 support patch is added.
#   L:At least, SPDIF and 4.0 output seems working.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_patch.c
#   2004/09/29 10:45:52+02:00 perex@suse.cz +134 -0
#   [ALSA]  Add (experimental) CM9761 support
#   
#   D:2004/09/29 16:45:52
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.149->1.150 
#   F:pci/ac97/ac97_id.h:1.9->1.10 
#   F:pci/ac97/ac97_patch.c:1.57->1.58 
#   F:pci/ac97/ac97_patch.h:1.16->1.17 
#   L:CM9761 support patch is added.
#   L:At least, SPDIF and 4.0 output seems working.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_id.h
#   2004/09/29 10:45:52+02:00 perex@suse.cz +3 -0
#   [ALSA]  Add (experimental) CM9761 support
#   
#   D:2004/09/29 16:45:52
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.149->1.150 
#   F:pci/ac97/ac97_id.h:1.9->1.10 
#   F:pci/ac97/ac97_patch.c:1.57->1.58 
#   F:pci/ac97/ac97_patch.h:1.16->1.17 
#   L:CM9761 support patch is added.
#   L:At least, SPDIF and 4.0 output seems working.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/09/29 10:45:52+02:00 perex@suse.cz +3 -0
#   [ALSA]  Add (experimental) CM9761 support
#   
#   D:2004/09/29 16:45:52
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.149->1.150 
#   F:pci/ac97/ac97_id.h:1.9->1.10 
#   F:pci/ac97/ac97_patch.c:1.57->1.58 
#   F:pci/ac97/ac97_patch.h:1.16->1.17 
#   L:CM9761 support patch is added.
#   L:At least, SPDIF and 4.0 output seems working.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:19:58+02:00 perex@suse.cz 
#   [ALSA]  add overclocking option for the analog input
#   
#   PCI drivers,BT87x driver
#   adds CONFIG_SND_BT87X_OVERCLOCK to enable sample rates
#   up to 1792000 Hz when recording from the analog input
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/bt87x.c
#   2004/09/29 08:33:18+02:00 perex@suse.cz +14 -6
#   [ALSA]  add overclocking option for the analog input
#   
#   D:2004/09/29 14:33:18
#   C:PCI drivers,BT87x driver
#   F:pci/Kconfig:1.34->1.35 
#   F:pci/bt87x.c:1.13->1.14 
#   L:adds CONFIG_SND_BT87X_OVERCLOCK to enable sample rates
#   L:up to 1792000 Hz when recording from the analog input
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/Kconfig
#   2004/09/29 08:33:18+02:00 perex@suse.cz +10 -0
#   [ALSA]  add overclocking option for the analog input
#   
#   D:2004/09/29 14:33:18
#   C:PCI drivers,BT87x driver
#   F:pci/Kconfig:1.34->1.35 
#   F:pci/bt87x.c:1.13->1.14 
#   L:adds CONFIG_SND_BT87X_OVERCLOCK to enable sample rates
#   L:up to 1792000 Hz when recording from the analog input
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/10/07 12:19:13+02:00 perex@suse.cz 
#   [ALSA]  Add reset_workaround module option
#   
#   Documentation,NM256 driver
#   - The workaround for some laptops like Dell Latitude LS can be
#     specified via reset_workaround module option, too.
#   - The check of reset_workaround is merged into the quirk table.
#   - The spinlock in AC97 reset callback is removed.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/nm256/nm256.c
#   2004/09/28 11:44:03+02:00 perex@suse.cz +20 -20
#   [ALSA]  Add reset_workaround module option
#   
#   D:2004/09/28 17:44:02
#   C:Documentation,NM256 driver
#   F:Documentation/ALSA-Configuration.txt:1.52->1.53 
#   F:pci/nm256/nm256.c:1.51->1.52 
#   L:- The workaround for some laptops like Dell Latitude LS can be
#   L:  specified via reset_workaround module option, too.
#   L:- The check of reset_workaround is merged into the quirk table.
#   L:- The spinlock in AC97 reset callback is removed.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2004/09/28 11:44:02+02:00 perex@suse.cz +6 -0
#   [ALSA]  Add reset_workaround module option
#   
#   D:2004/09/28 17:44:02
#   C:Documentation,NM256 driver
#   F:Documentation/ALSA-Configuration.txt:1.52->1.53 
#   F:pci/nm256/nm256.c:1.51->1.52 
#   L:- The workaround for some laptops like Dell Latitude LS can be
#   L:  specified via reset_workaround module option, too.
#   L:- The check of reset_workaround is merged into the quirk table.
#   L:- The spinlock in AC97 reset callback is removed.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:18:24+02:00 perex@suse.cz 
#   [ALSA]  Adds AC'97 support to Aureon cards.
#   
#   ICE1712 driver
#   This patch adds support of the STAC9744 chip located on Aureon cards,
#   enabling volume control for analogue input channels.
#   It also adds the posibility of listening to both the analogue inputs
#   and the digital audio.
#   
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/ice1712.h
#   2004/09/27 09:45:22+02:00 perex@suse.cz +2 -0
#   [ALSA]  Adds AC'97 support to Aureon cards.
#   
#   D:2004/09/27 15:45:22
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.18->1.19 
#   F:pci/ice1712/aureon.h:1.4->1.5 
#   F:pci/ice1712/ice1712.h:1.24->1.25 
#   L:This patch adds support of the STAC9744 chip located on Aureon cards,
#   L:enabling volume control for analogue input channels.
#   L:It also adds the posibility of listening to both the analogue inputs
#   L:and the digital audio.
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.h
#   2004/09/27 09:45:22+02:00 perex@suse.cz +5 -0
#   [ALSA]  Adds AC'97 support to Aureon cards.
#   
#   D:2004/09/27 15:45:22
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.18->1.19 
#   F:pci/ice1712/aureon.h:1.4->1.5 
#   F:pci/ice1712/ice1712.h:1.24->1.25 
#   L:This patch adds support of the STAC9744 chip located on Aureon cards,
#   L:enabling volume control for analogue input channels.
#   L:It also adds the posibility of listening to both the analogue inputs
#   L:and the digital audio.
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.c
#   2004/09/27 09:45:22+02:00 perex@suse.cz +333 -5
#   [ALSA]  Adds AC'97 support to Aureon cards.
#   
#   D:2004/09/27 15:45:22
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.18->1.19 
#   F:pci/ice1712/aureon.h:1.4->1.5 
#   F:pci/ice1712/ice1712.h:1.24->1.25 
#   L:This patch adds support of the STAC9744 chip located on Aureon cards,
#   L:enabling volume control for analogue input channels.
#   L:It also adds the posibility of listening to both the analogue inputs
#   L:and the digital audio.
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:17:32+02:00 perex@suse.cz 
#   [ALSA]  Clean up ice1712 chip struct
#   
#   ICE1712 driver
#   Clean up of ice1712 chip struct.  The board-specific data are moved
#   to spec union.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/ice1712.h
#   2004/09/27 09:44:14+02:00 perex@suse.cz +13 -5
#   [ALSA]  Clean up ice1712 chip struct
#   
#   D:2004/09/27 15:44:14
#   C:ICE1712 driver
#   F:pci/ice1712/ews.c:1.19->1.20 
#   F:pci/ice1712/hoontech.c:1.7->1.8 
#   F:pci/ice1712/ice1712.h:1.23->1.24 
#   L:Clean up of ice1712 chip struct.  The board-specific data are moved
#   L:to spec union.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/hoontech.c
#   2004/09/27 09:44:14+02:00 perex@suse.cz +82 -82
#   [ALSA]  Clean up ice1712 chip struct
#   
#   D:2004/09/27 15:44:14
#   C:ICE1712 driver
#   F:pci/ice1712/ews.c:1.19->1.20 
#   F:pci/ice1712/hoontech.c:1.7->1.8 
#   F:pci/ice1712/ice1712.h:1.23->1.24 
#   L:Clean up of ice1712 chip struct.  The board-specific data are moved
#   L:to spec union.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/ews.c
#   2004/09/27 09:44:14+02:00 perex@suse.cz +32 -22
#   [ALSA]  Clean up ice1712 chip struct
#   
#   D:2004/09/27 15:44:14
#   C:ICE1712 driver
#   F:pci/ice1712/ews.c:1.19->1.20 
#   F:pci/ice1712/hoontech.c:1.7->1.8 
#   F:pci/ice1712/ice1712.h:1.23->1.24 
#   L:Clean up of ice1712 chip struct.  The board-specific data are moved
#   L:to spec union.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:16:41+02:00 perex@suse.cz 
#   [ALSA]  Fix peakmeter ioctl on big-endian
#   
#   RME HDSP driver
#   Fixed the data transfer of peakmeter ioctl on big-endian architectures.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme9652/hdsp.c
#   2004/09/27 08:00:11+02:00 perex@suse.cz +66 -53
#   [ALSA]  Fix peakmeter ioctl on big-endian
#   
#   D:2004/09/27 14:00:11
#   C:RME HDSP driver
#   F:pci/rme9652/hdsp.c:1.70->1.71 
#   L:Fixed the data transfer of peakmeter ioctl on big-endian architectures.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:15:56+02:00 perex@suse.cz 
#   [ALSA]  Replace with usb_kill_urb()
#   
#   USB generic driver
#   Use usb_kill_urb() instead of deprecated usb_unlink_urb() for sync'ed URBs.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/usb/usbaudio.c
#   2004/09/24 10:50:48+02:00 perex@suse.cz +8 -8
#   [ALSA]  Replace with usb_kill_urb()
#   
#   D:2004/09/24 16:50:48
#   C:USB generic driver
#   F:usb/usbaudio.c:1.108->1.109 
#   L:Use usb_kill_urb() instead of deprecated usb_unlink_urb() for sync'ed URBs.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 12:15:03+02:00 perex@suse.cz 
#   [ALSA]  snd-usb-usx2y 0.7.3
#   
#   USB generic driver,USB USX2Y
#   Use usb_kill_urb() instead of deprecated usb_unlink_urb()
#   
#   Signed-off-by: Karsten Wiese <annabellesgarden@yahoo.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/usb/usx2y/usbusx2yaudio.c
#   2004/09/24 10:50:04+02:00 perex@suse.cz +17 -19
#   [ALSA]  snd-usb-usx2y 0.7.3
#   
#   D:2004/09/24 16:50:04
#   C:USB generic driver,USB USX2Y
#   F:usb/usbmidi.c:1.33->1.34 
#   F:usb/usx2y/usbusx2y.c:1.2->1.3 
#   F:usb/usx2y/usbusx2yaudio.c:1.3->1.4 
#   L:Use usb_kill_urb() instead of deprecated usb_unlink_urb()
#   Signed-off-by: Karsten Wiese <annabellesgarden@yahoo.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/usb/usx2y/usbusx2y.c
#   2004/09/24 10:50:04+02:00 perex@suse.cz +7 -3
#   [ALSA]  snd-usb-usx2y 0.7.3
#   
#   D:2004/09/24 16:50:04
#   C:USB generic driver,USB USX2Y
#   F:usb/usbmidi.c:1.33->1.34 
#   F:usb/usx2y/usbusx2y.c:1.2->1.3 
#   F:usb/usx2y/usbusx2yaudio.c:1.3->1.4 
#   L:Use usb_kill_urb() instead of deprecated usb_unlink_urb()
#   Signed-off-by: Karsten Wiese <annabellesgarden@yahoo.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/usb/usbmidi.c
#   2004/09/24 10:50:04+02:00 perex@suse.cz +3 -3
#   [ALSA]  snd-usb-usx2y 0.7.3
#   
#   D:2004/09/24 16:50:04
#   C:USB generic driver,USB USX2Y
#   F:usb/usbmidi.c:1.33->1.34 
#   F:usb/usx2y/usbusx2y.c:1.2->1.3 
#   F:usb/usx2y/usbusx2yaudio.c:1.3->1.4 
#   L:Use usb_kill_urb() instead of deprecated usb_unlink_urb()
#   Signed-off-by: Karsten Wiese <annabellesgarden@yahoo.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:56:30+02:00 perex@suse.cz 
#   [ALSA]  Fix drain/drop of linked PCM streams
#   
#   PCM Midlevel
#   This patch fixes the dead-locking of linked PCM streams when
#   drain/drop is called.  The counter field is added to pcm group
#   struct to handle link/unlink more easily.
#   
#   When the PCM streams are linked, start/drain/drop are operated
#   to all linked streams.  The drain will wait until draining of all
#   linked streams are finished.
#   
#   The XRUN triggers stopping of all linked streams and changes the
#   state of all of them to XRUN even if only one of them is actually
#   in XRUN.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm_native.c
#   2004/09/24 09:25:02+02:00 perex@suse.cz +320 -314
#   [ALSA]  Fix drain/drop of linked PCM streams
#   
#   D:2004/09/24 15:25:02
#   C:PCM Midlevel
#   F:core/pcm_lib.c:1.57->1.58 
#   F:core/pcm_native.c:1.106->1.107 
#   F:include/pcm.h:1.48->1.49 
#   L:This patch fixes the dead-locking of linked PCM streams when
#   L:drain/drop is called.  The counter field is added to pcm group
#   L:struct to handle link/unlink more easily.
#   L:
#   L:When the PCM streams are linked, start/drain/drop are operated
#   L:to all linked streams.  The drain will wait until draining of all
#   L:linked streams are finished.
#   L:
#   L:The XRUN triggers stopping of all linked streams and changes the
#   L:state of all of them to XRUN even if only one of them is actually
#   L:in XRUN.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm_lib.c
#   2004/09/24 09:25:02+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix drain/drop of linked PCM streams
#   
#   D:2004/09/24 15:25:02
#   C:PCM Midlevel
#   F:core/pcm_lib.c:1.57->1.58 
#   F:core/pcm_native.c:1.106->1.107 
#   F:include/pcm.h:1.48->1.49 
#   L:This patch fixes the dead-locking of linked PCM streams when
#   L:drain/drop is called.  The counter field is added to pcm group
#   L:struct to handle link/unlink more easily.
#   L:
#   L:When the PCM streams are linked, start/drain/drop are operated
#   L:to all linked streams.  The drain will wait until draining of all
#   L:linked streams are finished.
#   L:
#   L:The XRUN triggers stopping of all linked streams and changes the
#   L:state of all of them to XRUN even if only one of them is actually
#   L:in XRUN.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/pcm.h
#   2004/09/24 09:25:03+02:00 perex@suse.cz +2 -0
#   [ALSA]  Fix drain/drop of linked PCM streams
#   
#   D:2004/09/24 15:25:02
#   C:PCM Midlevel
#   F:core/pcm_lib.c:1.57->1.58 
#   F:core/pcm_native.c:1.106->1.107 
#   F:include/pcm.h:1.48->1.49 
#   L:This patch fixes the dead-locking of linked PCM streams when
#   L:drain/drop is called.  The counter field is added to pcm group
#   L:struct to handle link/unlink more easily.
#   L:
#   L:When the PCM streams are linked, start/drain/drop are operated
#   L:to all linked streams.  The drain will wait until draining of all
#   L:linked streams are finished.
#   L:
#   L:The XRUN triggers stopping of all linked streams and changes the
#   L:state of all of them to XRUN even if only one of them is actually
#   L:in XRUN.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:55:58+02:00 perex@suse.cz 
#   [ALSA]  Aureon S/PDIF input fixes
#   
#   ICE1712 driver
#   GPIO directions changed
#      * GPIO>22 not configured as they do not exist
#      * GPIO22 set to output (CS8415A CS pin)
#      * GPIO21 set to input. (SPI MISO pin)
#   
#   Init sequence of CS8415A changed:
#     * SWCLK is set to 1 (OMCK output to RMCK pin)
#     * MUX2:0 is set to 001 (S/PDIF input on RXP1)
#     * SODEL is set to 1 (MSB of SDOUT data occurs if the second OSCLK period after the OLRCK edge)
#     * SOLRPOL is set to 1 (SDOUT data is for the right channel with OLRCK is high)
#   
#   Signed-off-by: Peter Christensen <peter@christensen>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.c
#   2004/09/24 07:42:05+02:00 perex@suse.cz +2 -2
#   [ALSA]  Aureon S/PDIF input fixes
#   
#   D:2004/09/24 13:42:05
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.17->1.18 
#   L:GPIO directions changed
#   L:   * GPIO>22 not configured as they do not exist
#   L:   * GPIO22 set to output (CS8415A CS pin)
#   L:   * GPIO21 set to input. (SPI MISO pin)
#   L:
#   L:Init sequence of CS8415A changed:
#   L:  * SWCLK is set to 1 (OMCK output to RMCK pin)
#   L:  * MUX2:0 is set to 001 (S/PDIF input on RXP1)
#   L:  * SODEL is set to 1 (MSB of SDOUT data occurs if the second OSCLK period after the OLRCK edge)
#   L:  * SOLRPOL is set to 1 (SDOUT data is for the right channel with OLRCK is high)
#   Signed-off-by: Peter Christensen <peter@christensen>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:55:16+02:00 perex@suse.cz 
#   [ALSA]  Aureon S/PDIF input fixes
#   
#   ICE1712 driver
#   Fix GPIO pin directions and use RXP1 instead of RXP0 as S/PDIF source on CS8415A
#   
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/aureon.c
#   2004/09/24 07:28:44+02:00 perex@suse.cz +5 -5
#   [ALSA]  Aureon S/PDIF input fixes
#   
#   D:2004/09/24 13:28:44
#   C:ICE1712 driver
#   F:pci/ice1712/aureon.c:1.16->1.17 
#   L:Fix GPIO pin directions and use RXP1 instead of RXP0 as S/PDIF source on CS8415A
#   Signed-off-by: Peter Christensen <peter@developers.dk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:54:31+02:00 perex@suse.cz 
#   [ALSA]  Fix DXS entry for GA-7VAX
#   
#   VIA82xx driver
#   From: 1 1 <anoy@mail.ru>
#   
#   I have tested my MB GA-7VAX and want to say you that you should use
#   VIA_DXS_ENABLE instead VIA_DXS_NO_VRA.  On the maximum volume output level
#   with VIA_DXS_NO_VRA there is abnormal loud noise, and with VIA_DXS_ENABLE
#   there are much less noises.  And I have detected unused code section.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2004/09/24 05:08:02+02:00 perex@suse.cz +1 -7
#   [ALSA]  Fix DXS entry for GA-7VAX
#   
#   D:2004/09/24 11:08:02
#   C:VIA82xx driver
#   F:pci/via82xx.c:1.122->1.123 
#   L:From: 1 1 <anoy@mail.ru>
#   L:
#   L:I have tested my MB GA-7VAX and want to say you that you should use
#   L:VIA_DXS_ENABLE instead VIA_DXS_NO_VRA.  On the maximum volume output level
#   L:with VIA_DXS_NO_VRA there is abnormal loud noise, and with VIA_DXS_ENABLE
#   L:there are much less noises.  And I have detected unused code section.
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:53:30+02:00 perex@suse.cz 
#   [ALSA]  Fix HDSP meter ioctl
#   
#   RME HDSP driver
#   Fixes and clean up of GET_PEAK_RMS ioctl.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme9652/hdsp.c
#   2004/09/23 05:05:29+02:00 perex@suse.cz +122 -98
#   [ALSA]  Fix HDSP meter ioctl
#   
#   D:2004/09/23 11:05:29
#   C:RME HDSP driver
#   F:pci/rme9652/hdsp.c:1.69->1.70 
#   L:Fixes and clean up of GET_PEAK_RMS ioctl.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:52:15+02:00 perex@suse.cz 
#   [ALSA]  more au88x0 eq cleanups
#   
#   au88x0 driver
#   cleanup au88x0 equalizer code by factoring out a sign_invert function
#   that ensures all negative integers become positive.
#   
#   Signed-off-by: Jeff Muizelaar <muizelaar@rogers.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/au88x0/au88x0_eq.c
#   2004/09/22 11:11:17+02:00 perex@suse.cz +25 -51
#   [ALSA]  more au88x0 eq cleanups
#   
#   D:2004/09/22 17:11:17
#   C:au88x0 driver
#   F:pci/au88x0/au88x0_eq.c:1.4->1.5 
#   L:cleanup au88x0 equalizer code by factoring out a sign_invert function
#   L:that ensures all negative integers become positive.
#   Signed-off-by: Jeff Muizelaar <muizelaar@rogers.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/10/07 11:51:16+02:00 perex@suse.cz 
#   [ALSA]  Fix the variable types in struct
#   
#   RME HDSP driver
#   The variable types are declared explicitly like u32 and u64
#   to avoid ambiguity.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/hdsp.h
#   2004/09/22 10:20:44+02:00 perex@suse.cz +6 -6
#   [ALSA]  Fix the variable types in struct
#   
#   D:2004/09/22 16:20:44
#   C:RME HDSP driver
#   F:include/hdsp.h:1.6->1.7 
#   L:The variable types are declared explicitly like u32 and u64
#   L:to avoid ambiguity.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 12:28:46+02:00 perex@suse.cz 
#   [ALSA]  don't stop capture on errors
#   
#   BT87x driver
#   don't stop capture on errors because there's too much broken hardware out there
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 12:28:15+02:00 perex@suse.cz 
#   [ALSA]  remove 'Rawmidi' part from sequencer port names
#   
#   ALSA sequencer
#   
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 11:25:08+02:00 perex@suse.cz 
#   Merge
# 
# ChangeSet
#   2004/09/22 10:06:58+02:00 perex@suse.cz 
#   Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5
#   into suse.cz:/home/perex/bk/linux-sound/linux-sound
# 
# sound/pci/bt87x.c
#   2004/09/22 03:53:26+02:00 perex@suse.cz +2 -3
#   [ALSA]  don't stop capture on errors
#   
#   D:2004/09/22 09:53:26
#   C:BT87x driver
#   F:pci/bt87x.c:1.12->1.13 
#   L:don't stop capture on errors because there's too much broken hardware out there
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/core/seq/seq_midi.c
#   2004/09/22 02:16:27+02:00 perex@suse.cz +1 -1
#   [ALSA]  remove 'Rawmidi' part from sequencer port names
#   
#   D:2004/09/22 08:16:27
#   C:ALSA sequencer
#   F:core/seq/seq_midi.c:1.22->1.23 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/intel8x0.c
#   2004/09/22 11:24:55+02:00 perex@suse.cz +0 -8
#   SCCS merged
# 
# sound/pci/atiixp_modem.c
#   2004/09/22 11:23:23+02:00 perex@suse.cz +0 -3
#   SCCS merged
# 
# sound/pci/atiixp.c
#   2004/09/22 11:23:14+02:00 perex@suse.cz +0 -3
#   SCCS merged
# 
# sound/pci/intel8x0.c
#   2004/09/22 10:06:47+02:00 perex@suse.cz +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/22 09:55:28+02:00 perex@suse.cz 
#   [ALSA]  use card-specific driver name
#   
#   au88x0 driver
#   use CARD_NAME_SHORT as driver name to allow different configuration file aliases in alsa-lib
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/au88x0/au88x0.c
#   2004/09/22 02:11:15+02:00 perex@suse.cz +1 -1
#   [ALSA]  use card-specific driver name
#   
#   D:2004/09/22 08:11:15
#   C:au88x0 driver
#   F:pci/au88x0/au88x0.c:1.12->1.13 
#   L:use CARD_NAME_SHORT as driver name to allow different configuration file aliases in alsa-lib
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:55:06+02:00 perex@suse.cz 
#   [ALSA]  Fix SPDIF rate setting for old ICHs
#   
#   Intel8x0 driver
#   Force to set SPDIF rate when PCMOUT is used on ICH[1-3].
#   ICH4, NFORCE and ALI uses a separate DMA for SPDIF.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2004/09/21 08:15:27+02:00 perex@suse.cz +12 -12
#   [ALSA]  Fix SPDIF rate setting for old ICHs
#   
#   D:2004/09/21 14:15:27
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.170->1.171 
#   L:Force to set SPDIF rate when PCMOUT is used on ICH[1-3].
#   L:ICH4, NFORCE and ALI uses a separate DMA for SPDIF.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:54:42+02:00 perex@suse.cz 
#   [ALSA]  [hdsp] Fix for 64bit architectures
#   
#   RME HDSP driver
#   Fixed the loading of firmware data and the handling of meter mmap
#   on 64bit architectures.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme9652/hdsp.c
#   2004/09/21 05:32:27+02:00 perex@suse.cz +3 -3
#   [ALSA]  [hdsp] Fix for 64bit architectures
#   
#   D:2004/09/21 11:32:27
#   C:RME HDSP driver
#   F:include/hdsp.h:1.5->1.6 
#   F:pci/rme9652/hdsp.c:1.68->1.69 
#   L:Fixed the loading of firmware data and the handling of meter mmap
#   L:on 64bit architectures.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/hdsp.h
#   2004/09/21 05:32:27+02:00 perex@suse.cz +1 -1
#   [ALSA]  [hdsp] Fix for 64bit architectures
#   
#   D:2004/09/21 11:32:27
#   C:RME HDSP driver
#   F:include/hdsp.h:1.5->1.6 
#   F:pci/rme9652/hdsp.c:1.68->1.69 
#   L:Fixed the loading of firmware data and the handling of meter mmap
#   L:on 64bit architectures.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:54:19+02:00 perex@suse.cz 
#   [ALSA]  rme32 segfault fix
#   
#   RME32 driver
#   - disables buffer prefill in halfduplex mode, which fixes segmentation fault
#     of rme32 for playback in halfduplex mode
#   
#   Signed-Off-By: Martin Langer <martin-langer@gmx.de>
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme32.c
#   2004/09/20 05:10:47+02:00 perex@suse.cz +1 -1
#   [ALSA]  rme32 segfault fix
#   
#   D:2004/09/20 11:10:47
#   C:RME32 driver
#   F:pci/rme32.c:1.46->1.47 
#   L:- disables buffer prefill in halfduplex mode, which fixes segmentation fault
#   L:  of rme32 for playback in halfduplex mode
#   L:
#   L:Signed-Off-By: Martin Langer <martin-langer@gmx.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:53:57+02:00 perex@suse.cz 
#   [ALSA]  Added support of Mediastation
#   
#   ICE1712 driver
#   The support for Lionstracs Mediastation is added.
#   The model name is 'mediastation'.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/delta.h
#   2004/09/17 12:38:26+02:00 perex@suse.cz +3 -1
#   [ALSA]  Added support of Mediastation
#   
#   D:2004/09/17 18:38:26
#   C:ICE1712 driver
#   F:pci/ice1712/delta.c:1.18->1.19 
#   F:pci/ice1712/delta.h:1.6->1.7 
#   L:The support for Lionstracs Mediastation is added.
#   L:The model name is 'mediastation'.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/delta.c
#   2004/09/17 12:38:26+02:00 perex@suse.cz +13 -0
#   [ALSA]  Added support of Mediastation
#   
#   D:2004/09/17 18:38:26
#   C:ICE1712 driver
#   F:pci/ice1712/delta.c:1.18->1.19 
#   F:pci/ice1712/delta.h:1.6->1.7 
#   L:The support for Lionstracs Mediastation is added.
#   L:The model name is 'mediastation'.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:53:32+02:00 perex@suse.cz 
#   [ALSA]  Fix iomem variable type
#   
#   Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   RME9652 driver,PPC Tumbler driver
#   The type of iomem variables is changed to void __iomem *.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/ppc/tumbler.c
#   2004/09/16 13:40:26+02:00 perex@suse.cz +3 -3
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ymfpci/ymfpci_main.c
#   2004/09/16 13:40:26+02:00 perex@suse.cz +2 -2
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme9652/rme9652.c
#   2004/09/16 13:40:26+02:00 perex@suse.cz +5 -5
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme9652/hdsp.c
#   2004/09/16 13:40:26+02:00 perex@suse.cz +29 -29
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme96.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +8 -6
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/rme32.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +10 -10
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/nm256/nm256.c
#   2004/09/16 13:40:26+02:00 perex@suse.cz +17 -17
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart.h
#   2004/09/16 13:40:25+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart.c
#   2004/09/16 13:40:25+02:00 perex@suse.cz +3 -3
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/korg1212/korg1212.c
#   2004/09/16 13:40:25+02:00 perex@suse.cz +34 -33
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0m.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +10 -10
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +10 -10
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/dsp_spos_scb_lib.c
#   2004/09/16 13:40:25+02:00 perex@suse.cz +2 -2
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/dsp_spos.c
#   2004/09/16 13:40:25+02:00 perex@suse.cz +5 -5
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/09/16 13:40:25+02:00 perex@suse.cz +5 -5
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs4281.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +8 -8
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/au88x0/au88x0.h
#   2004/09/16 13:40:24+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/au88x0/au88x0.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/atiixp_modem.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +5 -5
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/atiixp.c
#   2004/09/16 13:40:24+02:00 perex@suse.cz +5 -5
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/drivers/opl3/opl3_lib.c
#   2004/09/16 13:40:23+02:00 perex@suse.cz +4 -4
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/drivers/mpu401/mpu401_uart.c
#   2004/09/16 13:40:23+02:00 perex@suse.cz +2 -2
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/memory.c
#   2004/09/16 13:40:23+02:00 perex@suse.cz +4 -4
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/ymfpci.h
#   2004/09/16 13:40:24+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/cs46xx.h
#   2004/09/16 13:40:24+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/core.h
#   2004/09/16 13:40:24+02:00 perex@suse.cz +2 -2
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/09/16 13:40:23+02:00 perex@suse.cz +3 -4
#   [ALSA]  Fix iomem variable type
#   
#   D:2004/09/16 19:40:23
#   C:Documentation,ALSA Core,MPU401 UART,OPL3,CS46xx driver,YMFPCI driver
#   C:ATIIXP driver,ATIIXP-modem driver,CS4281 driver,Intel8x0 driver
#   C:Intel8x0-modem driver,RME32 driver,RME96 driver,au88x0 driver
#   C:KORG1212 driver,MIXART driver,NM256 driver,RME HDSP driver
#   C:RME9652 driver,PPC Tumbler driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.39->1.40 
#   F:core/memory.c:1.31->1.32 
#   F:drivers/mpu401/mpu401_uart.c:1.31->1.32 
#   F:drivers/opl3/opl3_lib.c:1.21->1.22 
#   F:include/core.h:1.57->1.58 
#   F:include/cs46xx.h:1.21->1.22 
#   F:include/ymfpci.h:1.16->1.17 
#   F:pci/atiixp.c:1.23->1.24 
#   F:pci/atiixp_modem.c:1.7->1.8 
#   F:pci/cs4281.c:1.63->1.64 
#   F:pci/intel8x0.c:1.169->1.170 
#   F:pci/intel8x0m.c:1.20->1.21 
#   F:pci/rme32.c:1.45->1.46 
#   F:pci/rme96.c:1.43->1.44 
#   F:pci/au88x0/au88x0.c:1.11->1.12 
#   F:pci/au88x0/au88x0.h:1.7->1.8 
#   F:pci/cs46xx/cs46xx_lib.c:1.84->1.85 
#   F:pci/cs46xx/dsp_spos.c:1.26->1.27 
#   F:pci/cs46xx/dsp_spos_scb_lib.c:1.24->1.25 
#   F:pci/korg1212/korg1212.c:1.48->1.49 
#   F:pci/mixart/mixart.c:1.17->1.18 
#   F:pci/mixart/mixart.h:1.5->1.6 
#   F:pci/nm256/nm256.c:1.50->1.51 
#   F:pci/rme9652/hdsp.c:1.67->1.68 
#   F:pci/rme9652/rme9652.c:1.52->1.53 
#   F:pci/ymfpci/ymfpci_main.c:1.57->1.58 
#   F:ppc/tumbler.c:1.33->1.34 
#   L:The type of iomem variables is changed to void __iomem *.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:53:03+02:00 perex@suse.cz 
#   [ALSA]  Fix auto-loading of sequencer modules
#   
#   ALSA sequencer
#   Allow auto-loading of sequencer modules except for module init time
#   (which may cause blocking).
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_clientmgr.c
#   2004/09/16 13:35:29+02:00 perex@suse.cz +5 -3
#   [ALSA]  Fix auto-loading of sequencer modules
#   
#   D:2004/09/16 19:35:29
#   C:ALSA sequencer
#   F:core/seq/seq.c:1.14->1.15 
#   F:core/seq/seq_clientmgr.c:1.36->1.37 
#   L:Allow auto-loading of sequencer modules except for module init time
#   L:(which may cause blocking).
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq.c
#   2004/09/16 13:35:29+02:00 perex@suse.cz +4 -0
#   [ALSA]  Fix auto-loading of sequencer modules
#   
#   D:2004/09/16 19:35:29
#   C:ALSA sequencer
#   F:core/seq/seq.c:1.14->1.15 
#   F:core/seq/seq_clientmgr.c:1.36->1.37 
#   L:Allow auto-loading of sequencer modules except for module init time
#   L:(which may cause blocking).
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:52:41+02:00 perex@suse.cz 
#   [ALSA]  Fixed the obsolete description in comments
#   
#   IOCTL32 emulation
#   
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/ioctl32.h
#   2004/09/16 07:27:18+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fixed the obsolete description in comments
#   
#   D:2004/09/16 13:27:18
#   C:IOCTL32 emulation
#   F:core/ioctl32/ioctl32.h:1.14->1.15 
#   L:
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:52:19+02:00 perex@suse.cz 
#   [ALSA]  Improved clock measurement
#   
#   Intel8x0 driver
#   Improved the clock measurement routine to allow the longer sleep time.
#   Now it invokes schedule_timeout() instead of a long mdelay().
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2004/09/16 07:26:16+02:00 perex@suse.cz +5 -6
#   [ALSA]  Improved clock measurement
#   
#   D:2004/09/16 13:26:16
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.168->1.169 
#   L:Improved the clock measurement routine to allow the longer sleep time.
#   L:Now it invokes schedule_timeout() instead of a long mdelay().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:51:57+02:00 perex@suse.cz 
#   [ALSA]  Remove delay() to improve latency
#   
#   ES1968 driver
#   - Removed mdelay() in ac97 codec handling.
#   - Improved the clock measurement routine to allow the longer sleep time.
#     Now it invokes schedule_timeout() instead of a long mdelay().
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/es1968.c
#   2004/09/16 07:25:25+02:00 perex@suse.cz +28 -20
#   [ALSA]  Remove delay() to improve latency
#   
#   D:2004/09/16 13:25:25
#   C:ES1968 driver
#   F:pci/es1968.c:1.75->1.76 
#   L:- Removed mdelay() in ac97 codec handling.
#   L:- Improved the clock measurement routine to allow the longer sleep time.
#   L:  Now it invokes schedule_timeout() instead of a long mdelay().
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:51:34+02:00 perex@suse.cz 
#   [ALSA]  Support for capture of 16,32,64 channels on emu10k1 device 2
#   
#   EMU10K1/EMU10K2 driver
#   This patch changes default constraint on 'EFX voices mask' control and
#   allow capture of 1, 2, 4, 8, 16, 32, 64 channels instead of 1, 2, 4, 8.
#   
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emupcm.c
#   2004/09/16 05:36:44+02:00 perex@suse.cz +8 -1
#   [ALSA]  Support for capture of 16,32,64 channels on emu10k1 device 2
#   
#   D:2004/09/16 11:36:44
#   C:EMU10K1/EMU10K2 driver
#   F:pci/emu10k1/emupcm.c:1.31->1.32 
#   L:This patch changes default constraint on 'EFX voices mask' control and
#   L:allow capture of 1, 2, 4, 8, 16, 32, 64 channels instead of 1, 2, 4, 8.
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:35:51+02:00 perex@suse.cz 
#   [ALSA]  Fixes for PCM/control 32bit emulation
#   
#   PCM Midlevel,IOCTL32 emulation
#   - Size mismatch of control element struct due to packed attribute
#     is removed.
#   - A typo in PCM syncptr definition is fixed.
#   - Suppress the mmap of PCM status/control records on 32bit emulation
#     mode since the record size doesn't match.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/pcm_native.c
#   2004/09/15 04:30:08+02:00 perex@suse.cz +5 -0
#   [ALSA]  Fixes for PCM/control 32bit emulation
#   
#   D:2004/09/15 10:30:08
#   C:PCM Midlevel,IOCTL32 emulation
#   F:core/pcm_native.c:1.105->1.106 
#   F:core/ioctl32/ioctl32.c:1.21->1.22 
#   F:core/ioctl32/pcm32.c:1.20->1.21 
#   F:include/pcm.h:1.47->1.48 
#   L:- Size mismatch of control element struct due to packed attribute
#   L:  is removed.
#   L:- A typo in PCM syncptr definition is fixed.
#   L:- Suppress the mmap of PCM status/control records on 32bit emulation
#   L:  mode since the record size doesn't match.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/pcm32.c
#   2004/09/15 04:30:08+02:00 perex@suse.cz +27 -2
#   [ALSA]  Fixes for PCM/control 32bit emulation
#   
#   D:2004/09/15 10:30:08
#   C:PCM Midlevel,IOCTL32 emulation
#   F:core/pcm_native.c:1.105->1.106 
#   F:core/ioctl32/ioctl32.c:1.21->1.22 
#   F:core/ioctl32/pcm32.c:1.20->1.21 
#   F:include/pcm.h:1.47->1.48 
#   L:- Size mismatch of control element struct due to packed attribute
#   L:  is removed.
#   L:- A typo in PCM syncptr definition is fixed.
#   L:- Suppress the mmap of PCM status/control records on 32bit emulation
#   L:  mode since the record size doesn't match.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/ioctl32.c
#   2004/09/15 04:30:08+02:00 perex@suse.cz +1 -1
#   [ALSA]  Fixes for PCM/control 32bit emulation
#   
#   D:2004/09/15 10:30:08
#   C:PCM Midlevel,IOCTL32 emulation
#   F:core/pcm_native.c:1.105->1.106 
#   F:core/ioctl32/ioctl32.c:1.21->1.22 
#   F:core/ioctl32/pcm32.c:1.20->1.21 
#   F:include/pcm.h:1.47->1.48 
#   L:- Size mismatch of control element struct due to packed attribute
#   L:  is removed.
#   L:- A typo in PCM syncptr definition is fixed.
#   L:- Suppress the mmap of PCM status/control records on 32bit emulation
#   L:  mode since the record size doesn't match.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/pcm.h
#   2004/09/15 04:30:08+02:00 perex@suse.cz +2 -0
#   [ALSA]  Fixes for PCM/control 32bit emulation
#   
#   D:2004/09/15 10:30:08
#   C:PCM Midlevel,IOCTL32 emulation
#   F:core/pcm_native.c:1.105->1.106 
#   F:core/ioctl32/ioctl32.c:1.21->1.22 
#   F:core/ioctl32/pcm32.c:1.20->1.21 
#   F:include/pcm.h:1.47->1.48 
#   L:- Size mismatch of control element struct due to packed attribute
#   L:  is removed.
#   L:- A typo in PCM syncptr definition is fixed.
#   L:- Suppress the mmap of PCM status/control records on 32bit emulation
#   L:  mode since the record size doesn't match.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:35:27+02:00 perex@suse.cz 
#   [ALSA]  fix ALI M5451 description
#   
#   PCI drivers
#   modify ali5451 and intel8x0 help texts to better distinguish
#   between M5451 and M5455 AC97 controllers
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/Kconfig
#   2004/09/13 07:53:25+02:00 perex@suse.cz +8 -4
#   [ALSA]  fix ALI M5451 description
#   
#   D:2004/09/13 13:53:25
#   C:PCI drivers
#   F:pci/Kconfig:1.33->1.34 
#   L:modify ali5451 and intel8x0 help texts to better distinguish
#   L:between M5451 and M5455 AC97 controllers
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:35:05+02:00 perex@suse.cz 
#   [ALSA]  remove 'ALSA' from Kconfig USB menu name
#   
#   USB
#   make ISA, PCI and USB device look the same in {q,x,menu}config
#   
#   Signed-off-by: Thierry Vignaud <tvignaud@mandrakesoft.com>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/Kconfig
#   2004/09/13 05:53:20+02:00 perex@suse.cz +1 -1
#   [ALSA]  remove 'ALSA' from Kconfig USB menu name
#   
#   D:2004/09/13 11:53:20
#   C:USB
#   F:usb/Kconfig:1.6->1.7 
#   L:make ISA, PCI and USB device look the same in {q,x,menu}config
#   Signed-off-by: Thierry Vignaud <tvignaud@mandrakesoft.com>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:34:41+02:00 perex@suse.cz 
#   [ALSA]  enhance Kconfig help texts
#   
#   ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   USB
#   add module names and references to other documentation files
#   add more help for generic options
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/Kconfig
#   2004/09/13 02:15:00+02:00 perex@suse.cz +9 -2
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/ppc/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +5 -0
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pcmcia/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +15 -3
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +200 -63
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/parisc/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +4 -1
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/isa/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +141 -48
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/drivers/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +38 -10
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/core/Kconfig
#   2004/09/13 02:14:59+02:00 perex@suse.cz +57 -18
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/arm/Kconfig
#   2004/09/13 02:14:58+02:00 perex@suse.cz +6 -3
#   [ALSA]  enhance Kconfig help texts
#   
#   D:2004/09/13 08:14:58
#   C:ARM,ALSA Core,Generic drivers,ISA,PARISC,PCI drivers,PCMCIA Kconfig,PPC
#   C:USB
#   F:arm/Kconfig:1.2->1.3 
#   F:core/Kconfig:1.5->1.6 
#   F:drivers/Kconfig:1.6->1.7 
#   F:isa/Kconfig:1.13->1.14 
#   F:parisc/Kconfig:1.2->1.3 
#   F:pci/Kconfig:1.32->1.33 
#   F:pcmcia/Kconfig:1.7->1.8 
#   F:ppc/Kconfig:1.4->1.5 
#   F:usb/Kconfig:1.5->1.6 
#   L:add module names and references to other documentation files
#   L:add more help for generic options
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:34:18+02:00 perex@suse.cz 
#   [ALSA]  adjust intel8x0 joystick documentation
#   
#   Documentation
#   
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# Documentation/sound/alsa/Joystick.txt
#   2004/09/13 01:56:22+02:00 perex@suse.cz +4 -6
#   [ALSA]  adjust intel8x0 joystick documentation
#   
#   D:2004/09/13 07:56:22
#   C:Documentation
#   F:Documentation/Joystick.txt:1.3->1.4 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:33:57+02:00 perex@suse.cz 
#   [ALSA]  show codec name in card description
#   
#   AC97 Codec Core,ATIIXP driver,Intel8x0 driver,VIA82xx driver
#   Include the AC97 codec name in the card longname of
#   motherboard controllers.
#   (to enhance the chance of getting useful bug reports :)
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/via82xx.c
#   2004/09/10 09:19:29+02:00 perex@suse.cz +3 -2
#   [ALSA]  show codec name in card description
#   
#   D:2004/09/10 15:19:28
#   C:AC97 Codec Core,ATIIXP driver,Intel8x0 driver,VIA82xx driver
#   F:include/ac97_codec.h:1.55->1.56 
#   F:pci/atiixp.c:1.22->1.23 
#   F:pci/intel8x0.c:1.167->1.168 
#   F:pci/via82xx.c:1.121->1.122 
#   F:pci/ac97/ac97_codec.c:1.148->1.149 
#   L:Include the AC97 codec name in the card longname of
#   L:motherboard controllers.
#   L:(to enhance the chance of getting useful bug reports :)
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/intel8x0.c
#   2004/09/10 09:19:29+02:00 perex@suse.cz +3 -2
#   [ALSA]  show codec name in card description
#   
#   D:2004/09/10 15:19:28
#   C:AC97 Codec Core,ATIIXP driver,Intel8x0 driver,VIA82xx driver
#   F:include/ac97_codec.h:1.55->1.56 
#   F:pci/atiixp.c:1.22->1.23 
#   F:pci/intel8x0.c:1.167->1.168 
#   F:pci/via82xx.c:1.121->1.122 
#   F:pci/ac97/ac97_codec.c:1.148->1.149 
#   L:Include the AC97 codec name in the card longname of
#   L:motherboard controllers.
#   L:(to enhance the chance of getting useful bug reports :)
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/atiixp.c
#   2004/09/10 09:19:29+02:00 perex@suse.cz +4 -2
#   [ALSA]  show codec name in card description
#   
#   D:2004/09/10 15:19:28
#   C:AC97 Codec Core,ATIIXP driver,Intel8x0 driver,VIA82xx driver
#   F:include/ac97_codec.h:1.55->1.56 
#   F:pci/atiixp.c:1.22->1.23 
#   F:pci/intel8x0.c:1.167->1.168 
#   F:pci/via82xx.c:1.121->1.122 
#   F:pci/ac97/ac97_codec.c:1.148->1.149 
#   L:Include the AC97 codec name in the card longname of
#   L:motherboard controllers.
#   L:(to enhance the chance of getting useful bug reports :)
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/09/10 09:19:29+02:00 perex@suse.cz +17 -0
#   [ALSA]  show codec name in card description
#   
#   D:2004/09/10 15:19:28
#   C:AC97 Codec Core,ATIIXP driver,Intel8x0 driver,VIA82xx driver
#   F:include/ac97_codec.h:1.55->1.56 
#   F:pci/atiixp.c:1.22->1.23 
#   F:pci/intel8x0.c:1.167->1.168 
#   F:pci/via82xx.c:1.121->1.122 
#   F:pci/ac97/ac97_codec.c:1.148->1.149 
#   L:Include the AC97 codec name in the card longname of
#   L:motherboard controllers.
#   L:(to enhance the chance of getting useful bug reports :)
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# include/sound/ac97_codec.h
#   2004/09/10 09:19:28+02:00 perex@suse.cz +1 -0
#   [ALSA]  show codec name in card description
#   
#   D:2004/09/10 15:19:28
#   C:AC97 Codec Core,ATIIXP driver,Intel8x0 driver,VIA82xx driver
#   F:include/ac97_codec.h:1.55->1.56 
#   F:pci/atiixp.c:1.22->1.23 
#   F:pci/intel8x0.c:1.167->1.168 
#   F:pci/via82xx.c:1.121->1.122 
#   F:pci/ac97/ac97_codec.c:1.148->1.149 
#   L:Include the AC97 codec name in the card longname of
#   L:motherboard controllers.
#   L:(to enhance the chance of getting useful bug reports :)
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:33:34+02:00 perex@suse.cz 
#   [ALSA]  Fix driver name for nforce and clean-up
#   
#   Intel8x0-modem driver
#   Driver name is always ICH-MODEM as defined in alsa-lib config.
#   Cosmetic cleanups: unused include files, MODULE_DEVICE update.
#   
#   Signed-off-by: Sasha Khapyorsky <sashak@smlink.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0m.c
#   2004/09/08 10:23:50+02:00 perex@suse.cz +8 -13
#   [ALSA]  Fix driver name for nforce and clean-up
#   
#   D:2004/09/08 16:23:50
#   C:Intel8x0-modem driver
#   F:pci/intel8x0m.c:1.19->1.20 
#   L:Driver name is always ICH-MODEM as defined in alsa-lib config.
#   L:Cosmetic cleanups: unused include files, MODULE_DEVICE update.
#   Signed-off-by: Sasha Khapyorsky <sashak@smlink.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/22 09:33:11+02:00 perex@suse.cz 
#   [ALSA]  Added missing header file for AudioTrak Prodigy 192 cards
#   
#   ICE1712 driver
#   
#   
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/stac946x.h
#   2004/09/22 09:09:18+02:00 perex@suse.cz +25 -0
#   [ALSA]  Added missing header file for AudioTrak Prodigy 192 cards
#   
#   D:2004/09/08 12:28:25
#   C:ICE1712 driver
#   F:pci/ice1712/stac946x.h:INITIAL->1.1 
#   L:
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/stac946x.h
#   2004/09/22 09:09:18+02:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/ice1712/stac946x.h
# 
# ChangeSet
#   2004/09/22 09:32:47+02:00 perex@suse.cz 
#   [ALSA]  copy_to_user() return value checking in snd_seq_read()
#   
#   ALSA sequencer
#   Here's a patch that ensures the copy_to_user() return value gets checked
#   and acted upon if it is != 0 (that is, if we failed to copy all data) in
#   snd_seq_read().
#   
#   Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/core/seq/seq_clientmgr.c
#   2004/09/07 14:22:28+02:00 perex@suse.cz +4 -1
#   [ALSA]  copy_to_user() return value checking in snd_seq_read()
#   
#   D:2004/09/07 20:22:28
#   C:ALSA sequencer
#   F:core/seq/seq_clientmgr.c:1.35->1.36 
#   L:Here's a patch that ensures the copy_to_user() return value gets checked
#   L:and acted upon if it is != 0 (that is, if we failed to copy all data) in
#   L:snd_seq_read().
#   Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2004/09/22 09:32:20+02:00 perex@suse.cz 
#   [ALSA]  [ac97 core] added AC97_SCAP_DETECT_BY_VENDOR flag
#   
#   AC97 Codec Core,Intel8x0 driver
#   This patch adds a AC97_SCAP_DETECT_BY_VENDOR flag for Xbox. If the flag
#   is set, the AC97 codec is detected only by reading of a reasonable
#   vendor ID. It seems that Xbox has accessible only vendor/device ID
#   registers for reading. Also, a new xbox parameter for snd-intel8x0
#   has been introduced to let user force this behaviour.
#   
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/intel8x0.c
#   2004/09/07 10:58:24+02:00 perex@suse.cz +8 -0
#   [ALSA]  [ac97 core] added AC97_SCAP_DETECT_BY_VENDOR flag
#   
#   D:2004/09/07 16:58:24
#   C:AC97 Codec Core,Intel8x0 driver
#   F:include/ac97_codec.h:1.54->1.55 
#   F:pci/intel8x0.c:1.166->1.167 
#   F:pci/ac97/ac97_codec.c:1.147->1.148 
#   L:This patch adds a AC97_SCAP_DETECT_BY_VENDOR flag for Xbox. If the flag
#   L:is set, the AC97 codec is detected only by reading of a reasonable
#   L:vendor ID. It seems that Xbox has accessible only vendor/device ID
#   L:registers for reading. Also, a new xbox parameter for snd-intel8x0
#   L:has been introduced to let user force this behaviour.
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/09/07 10:58:24+02:00 perex@suse.cz +18 -10
#   [ALSA]  [ac97 core] added AC97_SCAP_DETECT_BY_VENDOR flag
#   
#   D:2004/09/07 16:58:24
#   C:AC97 Codec Core,Intel8x0 driver
#   F:include/ac97_codec.h:1.54->1.55 
#   F:pci/intel8x0.c:1.166->1.167 
#   F:pci/ac97/ac97_codec.c:1.147->1.148 
#   L:This patch adds a AC97_SCAP_DETECT_BY_VENDOR flag for Xbox. If the flag
#   L:is set, the AC97 codec is detected only by reading of a reasonable
#   L:vendor ID. It seems that Xbox has accessible only vendor/device ID
#   L:registers for reading. Also, a new xbox parameter for snd-intel8x0
#   L:has been introduced to let user force this behaviour.
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# include/sound/ac97_codec.h
#   2004/09/07 10:58:24+02:00 perex@suse.cz +1 -0
#   [ALSA]  [ac97 core] added AC97_SCAP_DETECT_BY_VENDOR flag
#   
#   D:2004/09/07 16:58:24
#   C:AC97 Codec Core,Intel8x0 driver
#   F:include/ac97_codec.h:1.54->1.55 
#   F:pci/intel8x0.c:1.166->1.167 
#   F:pci/ac97/ac97_codec.c:1.147->1.148 
#   L:This patch adds a AC97_SCAP_DETECT_BY_VENDOR flag for Xbox. If the flag
#   L:is set, the AC97 codec is detected only by reading of a reasonable
#   L:vendor ID. It seems that Xbox has accessible only vendor/device ID
#   L:registers for reading. Also, a new xbox parameter for snd-intel8x0
#   L:has been introduced to let user force this behaviour.
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2004/09/22 09:30:18+02:00 perex@suse.cz 
#   [ALSA]  mark snd_card_dummy_new_mixer() as static
#   
#   Generic drivers
#   
#   
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/drivers/dummy.c
#   2004/09/07 10:52:40+02:00 perex@suse.cz +1 -1
#   [ALSA]  mark snd_card_dummy_new_mixer() as static
#   
#   D:2004/09/07 16:52:40
#   C:Generic drivers
#   F:drivers/dummy.c:1.32->1.33 
#   L:
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2004/09/22 09:29:41+02:00 perex@suse.cz 
#   [ALSA]  add UA-1000 sample rate detection
#   
#   USB generic driver
#   Instead of assuming 48 kHz, the driver now detects
#   the current sample rate setting.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbquirks.h
#   2004/09/07 10:09:08+02:00 perex@suse.cz +2 -28
#   [ALSA]  add UA-1000 sample rate detection
#   
#   D:2004/09/07 16:09:08
#   C:USB generic driver
#   F:usb/usbaudio.c:1.107->1.108 
#   F:usb/usbaudio.h:1.33->1.34 
#   F:usb/usbquirks.h:1.36->1.37 
#   L:Instead of assuming 48 kHz, the driver now detects
#   L:the current sample rate setting.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbaudio.h
#   2004/09/07 10:09:08+02:00 perex@suse.cz +2 -1
#   [ALSA]  add UA-1000 sample rate detection
#   
#   D:2004/09/07 16:09:08
#   C:USB generic driver
#   F:usb/usbaudio.c:1.107->1.108 
#   F:usb/usbaudio.h:1.33->1.34 
#   F:usb/usbquirks.h:1.36->1.37 
#   L:Instead of assuming 48 kHz, the driver now detects
#   L:the current sample rate setting.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbaudio.c
#   2004/09/07 10:09:08+02:00 perex@suse.cz +52 -0
#   [ALSA]  add UA-1000 sample rate detection
#   
#   D:2004/09/07 16:09:08
#   C:USB generic driver
#   F:usb/usbaudio.c:1.107->1.108 
#   F:usb/usbaudio.h:1.33->1.34 
#   F:usb/usbquirks.h:1.36->1.37 
#   L:Instead of assuming 48 kHz, the driver now detects
#   L:the current sample rate setting.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/22 09:29:10+02:00 perex@suse.cz 
#   [ALSA]  Added support for AudioTrak Prodigy 192 cards
#   
#   ICE1712 driver,ICE1724 driver
#   
#   
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/prodigy192.h
#   2004/09/22 09:08:13+02:00 perex@suse.cz +11 -0
#   [ALSA]  Added support for AudioTrak Prodigy 192 cards
#   
#   D:2004/09/07 16:02:49
#   C:ICE1712 driver,ICE1724 driver
#   F:pci/ice1712/Makefile:1.13->1.14 
#   F:pci/ice1712/ice1724.c:1.44->1.45 
#   F:pci/ice1712/prodigy192.c:INITIAL->1.1 
#   F:pci/ice1712/prodigy192.h:INITIAL->1.1 
#   L:
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/prodigy192.h
#   2004/09/22 09:08:13+02:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/ice1712/prodigy192.h
# 
# sound/pci/ice1712/ice1724.c
#   2004/09/07 10:02:49+02:00 perex@suse.cz +3 -0
#   [ALSA]  Added support for AudioTrak Prodigy 192 cards
#   
#   D:2004/09/07 16:02:49
#   C:ICE1712 driver,ICE1724 driver
#   F:pci/ice1712/Makefile:1.13->1.14 
#   F:pci/ice1712/ice1724.c:1.44->1.45 
#   F:pci/ice1712/prodigy192.c:INITIAL->1.1 
#   F:pci/ice1712/prodigy192.h:INITIAL->1.1 
#   L:
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/Makefile
#   2004/09/07 10:02:49+02:00 perex@suse.cz +1 -1
#   [ALSA]  Added support for AudioTrak Prodigy 192 cards
#   
#   D:2004/09/07 16:02:49
#   C:ICE1712 driver,ICE1724 driver
#   F:pci/ice1712/Makefile:1.13->1.14 
#   F:pci/ice1712/ice1724.c:1.44->1.45 
#   F:pci/ice1712/prodigy192.c:INITIAL->1.1 
#   F:pci/ice1712/prodigy192.h:INITIAL->1.1 
#   L:
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/prodigy192.c
#   2004/09/22 09:08:08+02:00 perex@suse.cz +524 -0
#   [ALSA]  Added support for AudioTrak Prodigy 192 cards
#   
#   D:2004/09/07 16:02:49
#   C:ICE1712 driver,ICE1724 driver
#   F:pci/ice1712/Makefile:1.13->1.14 
#   F:pci/ice1712/ice1724.c:1.44->1.45 
#   F:pci/ice1712/prodigy192.c:INITIAL->1.1 
#   F:pci/ice1712/prodigy192.h:INITIAL->1.1 
#   L:
#   Signed-off-by: Kouichi ONO <co2b@ceres.dti.ne.jp>
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/pci/ice1712/prodigy192.c
#   2004/09/22 09:08:08+02:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/ice1712/prodigy192.c
# 
# ChangeSet
#   2004/09/22 09:28:40+02:00 perex@suse.cz 
#   [ALSA]  Fix the OSS PCM emulation - O_NONBLOCK write
#   
#   ALSA<-OSS emulation
#   This patch fixes the OSS PCM write() in O_NONBLOCK mode.
#   The previous code had not returned partial written bytes.
#   
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# sound/core/oss/pcm_oss.c
#   2004/09/07 09:17:48+02:00 perex@suse.cz +9 -1
#   [ALSA]  Fix the OSS PCM emulation - O_NONBLOCK write
#   
#   D:2004/09/07 15:17:48
#   C:ALSA<-OSS emulation
#   F:core/oss/pcm_oss.c:1.77->1.78 
#   L:This patch fixes the OSS PCM write() in O_NONBLOCK mode.
#   L:The previous code had not returned partial written bytes.
#   Signed-off-by: Jaroslav Kysela <perex@suse.cz>
# 
# ChangeSet
#   2004/09/06 20:33:07+02:00 perex@suse.cz 
#   [ALSA]  [emu10k1] Audigy DSP support
#   
#   EMU10K1/EMU10K2 driver
#   This patch will add better support for Audigy DSP.  More gpr,
#   instruction and tram.  It will break binary compatibility for app
#   which use emu10k1 hwdep.
#   
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emuproc.c
#   2004/09/06 10:05:19+02:00 perex@suse.cz +19 -11
#   [ALSA]  [emu10k1] Audigy DSP support
#   
#   D:2004/09/06 16:05:18
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.45->1.46 
#   F:pci/emu10k1/emufx.c:1.58->1.59 
#   F:pci/emu10k1/emuproc.c:1.20->1.21 
#   L:This patch will add better support for Audigy DSP.  More gpr,
#   L:instruction and tram.  It will break binary compatibility for app
#   L:which use emu10k1 hwdep.
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/emu10k1/emufx.c
#   2004/09/06 10:05:18+02:00 perex@suse.cz +25 -17
#   [ALSA]  [emu10k1] Audigy DSP support
#   
#   D:2004/09/06 16:05:18
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.45->1.46 
#   F:pci/emu10k1/emufx.c:1.58->1.59 
#   F:pci/emu10k1/emuproc.c:1.20->1.21 
#   L:This patch will add better support for Audigy DSP.  More gpr,
#   L:instruction and tram.  It will break binary compatibility for app
#   L:which use emu10k1 hwdep.
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/emu10k1.h
#   2004/09/06 10:05:18+02:00 perex@suse.cz +37 -24
#   [ALSA]  [emu10k1] Audigy DSP support
#   
#   D:2004/09/06 16:05:18
#   C:EMU10K1/EMU10K2 driver
#   F:include/emu10k1.h:1.45->1.46 
#   F:pci/emu10k1/emufx.c:1.58->1.59 
#   F:pci/emu10k1/emuproc.c:1.20->1.21 
#   L:This patch will add better support for Audigy DSP.  More gpr,
#   L:instruction and tram.  It will break binary compatibility for app
#   L:which use emu10k1 hwdep.
#   Signed-off-by: Peter Zubaj <pzad@pobox.sk>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:25:33+02:00 perex@suse.cz 
#   [ALSA]  Added Compaq Evo W4000 quirk
#   
#   Intel8x0 driver
#   Added an AC97 quirk entry for Compaq Evo W4000.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2004/09/06 07:51:11+02:00 perex@suse.cz +6 -0
#   [ALSA]  Added Compaq Evo W4000 quirk
#   
#   D:2004/09/06 13:51:11
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.165->1.166 
#   L:Added an AC97 quirk entry for Compaq Evo W4000.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:24:49+02:00 perex@suse.cz 
#   [ALSA]  detect errors reported by the hardware
#   
#   BT87x driver
#   stop the PCM if the hardware reports FIFO/PCI errors
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/bt87x.c
#   2004/09/06 03:10:32+02:00 perex@suse.cz +3 -2
#   [ALSA]  detect errors reported by the hardware
#   
#   D:2004/09/06 09:10:32
#   C:BT87x driver
#   F:pci/bt87x.c:1.11->1.12 
#   L:stop the PCM if the hardware reports FIFO/PCI errors
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/06 20:24:04+02:00 perex@suse.cz 
#   [ALSA]  inverted EAPD support
#   
#   Documentation,AC97 Codec Core,Intel8x0 driver,CS46xx driver
#   Since there are more than one (broken) implementation of EAPD bit
#   on ac97 chips, the new scaps bit is added for the inverted EAPD.
#   Also, AC97_TUNE_INV_EAPD is used to tune this behavior later by
#   snd_ac97_tune_hardware().
#   
#   The ac97 quirk entry for Sony S1XP is added to turn this on.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2004/09/03 09:21:14+02:00 perex@suse.cz +6 -0
#   [ALSA]  inverted EAPD support
#   
#   D:2004/09/03 15:21:13
#   C:Documentation,AC97 Codec Core,Intel8x0 driver,CS46xx driver
#   F:Documentation/ALSA-Configuration.txt:1.51->1.52 
#   F:include/ac97_codec.h:1.53->1.54 
#   F:pci/intel8x0.c:1.164->1.165 
#   F:pci/ac97/ac97_codec.c:1.146->1.147 
#   F:pci/cs46xx/cs46xx_lib.c:1.83->1.84 
#   L:Since there are more than one (broken) implementation of EAPD bit
#   L:on ac97 chips, the new scaps bit is added for the inverted EAPD.
#   L:Also, AC97_TUNE_INV_EAPD is used to tune this behavior later by
#   L:snd_ac97_tune_hardware().
#   L:
#   L:The ac97 quirk entry for Sony S1XP is added to turn this on.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/09/03 09:21:24+02:00 perex@suse.cz +2 -12
#   [ALSA]  inverted EAPD support
#   
#   D:2004/09/03 15:21:13
#   C:Documentation,AC97 Codec Core,Intel8x0 driver,CS46xx driver
#   F:Documentation/ALSA-Configuration.txt:1.51->1.52 
#   F:include/ac97_codec.h:1.53->1.54 
#   F:pci/intel8x0.c:1.164->1.165 
#   F:pci/ac97/ac97_codec.c:1.146->1.147 
#   F:pci/cs46xx/cs46xx_lib.c:1.83->1.84 
#   L:Since there are more than one (broken) implementation of EAPD bit
#   L:on ac97 chips, the new scaps bit is added for the inverted EAPD.
#   L:Also, AC97_TUNE_INV_EAPD is used to tune this behavior later by
#   L:snd_ac97_tune_hardware().
#   L:
#   L:The ac97 quirk entry for Sony S1XP is added to turn this on.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/09/03 09:21:14+02:00 perex@suse.cz +30 -6
#   [ALSA]  inverted EAPD support
#   
#   D:2004/09/03 15:21:13
#   C:Documentation,AC97 Codec Core,Intel8x0 driver,CS46xx driver
#   F:Documentation/ALSA-Configuration.txt:1.51->1.52 
#   F:include/ac97_codec.h:1.53->1.54 
#   F:pci/intel8x0.c:1.164->1.165 
#   F:pci/ac97/ac97_codec.c:1.146->1.147 
#   F:pci/cs46xx/cs46xx_lib.c:1.83->1.84 
#   L:Since there are more than one (broken) implementation of EAPD bit
#   L:on ac97 chips, the new scaps bit is added for the inverted EAPD.
#   L:Also, AC97_TUNE_INV_EAPD is used to tune this behavior later by
#   L:snd_ac97_tune_hardware().
#   L:
#   L:The ac97 quirk entry for Sony S1XP is added to turn this on.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/ac97_codec.h
#   2004/09/03 09:21:14+02:00 perex@suse.cz +2 -0
#   [ALSA]  inverted EAPD support
#   
#   D:2004/09/03 15:21:13
#   C:Documentation,AC97 Codec Core,Intel8x0 driver,CS46xx driver
#   F:Documentation/ALSA-Configuration.txt:1.51->1.52 
#   F:include/ac97_codec.h:1.53->1.54 
#   F:pci/intel8x0.c:1.164->1.165 
#   F:pci/ac97/ac97_codec.c:1.146->1.147 
#   F:pci/cs46xx/cs46xx_lib.c:1.83->1.84 
#   L:Since there are more than one (broken) implementation of EAPD bit
#   L:on ac97 chips, the new scaps bit is added for the inverted EAPD.
#   L:Also, AC97_TUNE_INV_EAPD is used to tune this behavior later by
#   L:snd_ac97_tune_hardware().
#   L:
#   L:The ac97 quirk entry for Sony S1XP is added to turn this on.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2004/09/03 09:21:13+02:00 perex@suse.cz +1 -0
#   [ALSA]  inverted EAPD support
#   
#   D:2004/09/03 15:21:13
#   C:Documentation,AC97 Codec Core,Intel8x0 driver,CS46xx driver
#   F:Documentation/ALSA-Configuration.txt:1.51->1.52 
#   F:include/ac97_codec.h:1.53->1.54 
#   F:pci/intel8x0.c:1.164->1.165 
#   F:pci/ac97/ac97_codec.c:1.146->1.147 
#   F:pci/cs46xx/cs46xx_lib.c:1.83->1.84 
#   L:Since there are more than one (broken) implementation of EAPD bit
#   L:on ac97 chips, the new scaps bit is added for the inverted EAPD.
#   L:Also, AC97_TUNE_INV_EAPD is used to tune this behavior later by
#   L:snd_ac97_tune_hardware().
#   L:
#   L:The ac97 quirk entry for Sony S1XP is added to turn this on.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:23:17+02:00 perex@suse.cz 
#   [ALSA]  ac97 quirk entry for Soltek SL-75DRV5
#   
#   VIA82xx driver
#   Added an ac97 quirk entry for Soltek SL-75DRV5.
#   Since the PCI subsystem id is identical with ASRock K7VT2, codec_id is
#   used additionally to tell between them.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2004/09/03 09:17:29+02:00 perex@suse.cz +7 -0
#   [ALSA]  ac97 quirk entry for Soltek SL-75DRV5
#   
#   D:2004/09/03 15:17:29
#   C:VIA82xx driver
#   F:pci/via82xx.c:1.120->1.121 
#   L:Added an ac97 quirk entry for Soltek SL-75DRV5.
#   L:Since the PCI subsystem id is identical with ASRock K7VT2, codec_id is
#   L:used additionally to tell between them.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:22:32+02:00 perex@suse.cz 
#   [ALSA]  [ac97] Check ac97 codec id in quirk table
#   
#   AC97 Codec Core
#   Added codec_id field to ac97_quirk struct so that the devices with
#   the same PCI subsystem IDs but with different AC97 chips can be
#   distinguished properly.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/09/03 09:15:35+02:00 perex@suse.cz +2 -0
#   [ALSA]  [ac97] Check ac97 codec id in quirk table
#   
#   D:2004/09/03 15:15:35
#   C:AC97 Codec Core
#   F:include/ac97_codec.h:1.52->1.53 
#   F:pci/ac97/ac97_codec.c:1.145->1.146 
#   L:Added codec_id field to ac97_quirk struct so that the devices with
#   L:the same PCI subsystem IDs but with different AC97 chips can be
#   L:distinguished properly.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/ac97_codec.h
#   2004/09/03 09:15:35+02:00 perex@suse.cz +1 -0
#   [ALSA]  [ac97] Check ac97 codec id in quirk table
#   
#   D:2004/09/03 15:15:35
#   C:AC97 Codec Core
#   F:include/ac97_codec.h:1.52->1.53 
#   F:pci/ac97/ac97_codec.c:1.145->1.146 
#   L:Added codec_id field to ac97_quirk struct so that the devices with
#   L:the same PCI subsystem IDs but with different AC97 chips can be
#   L:distinguished properly.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:21:46+02:00 perex@suse.cz 
#   [ALSA]  [ac97] Added VIA shared type.
#   
#   AC97 Codec Core,VIA82xx driver
#   Added a new shared type AC97_SHARED_TYPE_VIA for via82xx southbridge
#   to share codecs between audio and modem drivers.
#   
#   Signed-off-by: Sasha Khapyorsky <sashak@smlink.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/via82xx.c
#   2004/09/03 08:50:25+02:00 perex@suse.cz +1 -0
#   [ALSA]  [ac97] Added VIA shared type.
#   
#   D:2004/09/03 14:50:25
#   C:AC97 Codec Core,VIA82xx driver
#   F:include/ac97_codec.h:1.51->1.52 
#   F:pci/via82xx.c:1.119->1.120 
#   L:Added a new shared type AC97_SHARED_TYPE_VIA for via82xx southbridge
#   L:to share codecs between audio and modem drivers.
#   Signed-off-by: Sasha Khapyorsky <sashak@smlink.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/ac97_codec.h
#   2004/09/03 08:50:25+02:00 perex@suse.cz +1 -0
#   [ALSA]  [ac97] Added VIA shared type.
#   
#   D:2004/09/03 14:50:25
#   C:AC97 Codec Core,VIA82xx driver
#   F:include/ac97_codec.h:1.51->1.52 
#   F:pci/via82xx.c:1.119->1.120 
#   L:Added a new shared type AC97_SHARED_TYPE_VIA for via82xx southbridge
#   L:to share codecs between audio and modem drivers.
#   Signed-off-by: Sasha Khapyorsky <sashak@smlink.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:21:03+02:00 perex@suse.cz 
#   [ALSA]  add mixer quirk for LineX FM Transmitter
#   
#   USB generic driver
#   The LineX FM Transmitter needs a mixer quirk entry
#   to ignore control errors.
#   
#   Signed-off-by: Lonnie Mendez <dignome@gmail.com>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/usb/usbmixer_maps.c
#   2004/09/03 07:33:11+02:00 perex@suse.cz +9 -0
#   [ALSA]  add mixer quirk for LineX FM Transmitter
#   
#   D:2004/09/03 13:33:11
#   C:USB generic driver
#   F:usb/usbmixer_maps.c:1.7->1.8 
#   L:The LineX FM Transmitter needs a mixer quirk entry
#   L:to ignore control errors.
#   Signed-off-by: Lonnie Mendez <dignome@gmail.com>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/06 20:20:18+02:00 perex@suse.cz 
#   [ALSA]  remove gameport/MIDI support
#   
#   Documentation,PCI drivers,Intel8x0 driver
#   snd-intel8x0's gameport/MIDI code has quite a few problems:  the port
#   addresses cannot be detected reliably (or not at all with newer LPC
#   bridge devices), joystick port address 0x208 isn't supported, the MIDI
#   interrupt isn't detected, PnP isn't supported, changing the port
#   addresses in the LPC bridge configuration doesn't affect the devices
#   in the Super-I/O chip connected to the LPC bus, and registering this
#   driver for the LPC bridge PCI device prevents other drivers using the
#   LPC's PCI id from loading later.
#   
#   All these problems can be cured by removing the offending code and
#   using the proper modules for these devices (ns558/snd-mpu401) instead.
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/intel8x0.c
#   2004/09/03 05:32:02+02:00 perex@suse.cz +0 -146
#   [ALSA]  remove gameport/MIDI support
#   
#   D:2004/09/03 11:32:02
#   C:Documentation,PCI drivers,Intel8x0 driver
#   F:Documentation/ALSA-Configuration.txt:1.50->1.51 
#   F:pci/Kconfig:1.31->1.32 
#   F:pci/intel8x0.c:1.163->1.164 
#   L:snd-intel8x0's gameport/MIDI code has quite a few problems:  the port
#   L:addresses cannot be detected reliably (or not at all with newer LPC
#   L:bridge devices), joystick port address 0x208 isn't supported, the MIDI
#   L:interrupt isn't detected, PnP isn't supported, changing the port
#   L:addresses in the LPC bridge configuration doesn't affect the devices
#   L:in the Super-I/O chip connected to the LPC bus, and registering this
#   L:driver for the LPC bridge PCI device prevents other drivers using the
#   L:LPC's PCI id from loading later.
#   L:
#   L:All these problems can be cured by removing the offending code and
#   L:using the proper modules for these devices (ns558/snd-mpu401) instead.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/Kconfig
#   2004/09/03 05:32:02+02:00 perex@suse.cz +0 -1
#   [ALSA]  remove gameport/MIDI support
#   
#   D:2004/09/03 11:32:02
#   C:Documentation,PCI drivers,Intel8x0 driver
#   F:Documentation/ALSA-Configuration.txt:1.50->1.51 
#   F:pci/Kconfig:1.31->1.32 
#   F:pci/intel8x0.c:1.163->1.164 
#   L:snd-intel8x0's gameport/MIDI code has quite a few problems:  the port
#   L:addresses cannot be detected reliably (or not at all with newer LPC
#   L:bridge devices), joystick port address 0x208 isn't supported, the MIDI
#   L:interrupt isn't detected, PnP isn't supported, changing the port
#   L:addresses in the LPC bridge configuration doesn't affect the devices
#   L:in the Super-I/O chip connected to the LPC bus, and registering this
#   L:driver for the LPC bridge PCI device prevents other drivers using the
#   L:LPC's PCI id from loading later.
#   L:
#   L:All these problems can be cured by removing the offending code and
#   L:using the proper modules for these devices (ns558/snd-mpu401) instead.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2004/09/03 05:32:02+02:00 perex@suse.cz +3 -4
#   [ALSA]  remove gameport/MIDI support
#   
#   D:2004/09/03 11:32:02
#   C:Documentation,PCI drivers,Intel8x0 driver
#   F:Documentation/ALSA-Configuration.txt:1.50->1.51 
#   F:pci/Kconfig:1.31->1.32 
#   F:pci/intel8x0.c:1.163->1.164 
#   L:snd-intel8x0's gameport/MIDI code has quite a few problems:  the port
#   L:addresses cannot be detected reliably (or not at all with newer LPC
#   L:bridge devices), joystick port address 0x208 isn't supported, the MIDI
#   L:interrupt isn't detected, PnP isn't supported, changing the port
#   L:addresses in the LPC bridge configuration doesn't affect the devices
#   L:in the Super-I/O chip connected to the LPC bus, and registering this
#   L:driver for the LPC bridge PCI device prevents other drivers using the
#   L:LPC's PCI id from loading later.
#   L:
#   L:All these problems can be cured by removing the offending code and
#   L:using the proper modules for these devices (ns558/snd-mpu401) instead.
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/06 20:19:32+02:00 perex@suse.cz 
#   [ALSA]  add AC97 quirk for Fujitsu-Siemens E4010
#   
#   Intel8x0 driver
#   
#   
#   Signed-off-by: <castet.matthieu@free.fr>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/intel8x0.c
#   2004/09/02 06:59:21+02:00 perex@suse.cz +6 -0
#   [ALSA]  add AC97 quirk for Fujitsu-Siemens E4010
#   
#   D:2004/09/02 12:59:21
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.162->1.163 
#   L:
#   Signed-off-by: <castet.matthieu@free.fr>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/06 20:18:46+02:00 perex@suse.cz 
#   [ALSA]  Fix latency in ens1371 driver
#   
#   ENS1370/1+ driver
#   The high latency in prepare callback of ens1371 driver is fixed.
#   The *_rate_set() functions are moved outside of spinlock, and
#   cond_resched() is inserted in the busy probing loop.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ens1370.c
#   2004/09/01 14:27:33+02:00 perex@suse.cz +18 -6
#   [ALSA]  Fix latency in ens1371 driver
#   
#   D:2004/09/01 20:27:33
#   C:ENS1370/1+ driver
#   F:pci/ens1370.c:1.68->1.69 
#   L:The high latency in prepare callback of ens1371 driver is fixed.
#   L:The *_rate_set() functions are moved outside of spinlock, and
#   L:cond_resched() is inserted in the busy probing loop.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:18:03+02:00 perex@suse.cz 
#   [ALSA]  suppress auto-loading of modules in module_init().
#   
#   ALSA sequencer
#   The auto-loading of sequencer modules is suppressed in module_init().
#   The recent module-init-tools may cause blocking.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/seq/seq_clientmgr.c
#   2004/09/01 14:25:27+02:00 perex@suse.cz +4 -1
#   [ALSA]  suppress auto-loading of modules in module_init().
#   
#   D:2004/09/01 20:25:27
#   C:ALSA sequencer
#   F:core/seq/seq_clientmgr.c:1.34->1.35 
#   L:The auto-loading of sequencer modules is suppressed in module_init().
#   L:The recent module-init-tools may cause blocking.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:17:20+02:00 perex@suse.cz 
#   [ALSA]  add missing ifdef for disabling MIDI
#   
#   Intel8x0 driver
#   
#   
#   Signed-off-by: <castet.matthieu@free.fr>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/intel8x0.c
#   2004/09/01 02:41:19+02:00 perex@suse.cz +2 -0
#   [ALSA]  add missing ifdef for disabling MIDI
#   
#   D:2004/09/01 08:41:19
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.161->1.162 
#   L:
#   Signed-off-by: <castet.matthieu@free.fr>
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/06 20:16:34+02:00 perex@suse.cz 
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   Documentation,AC97 Codec Core,Intel8x0 driver
#   
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/intel8x0.c
#   2004/09/01 02:30:56+02:00 perex@suse.cz +26 -11
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   D:2004/09/01 08:30:56
#   C:Documentation,AC97 Codec Core,Intel8x0 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.38->1.39 
#   F:include/ac97_codec.h:1.50->1.51 
#   F:pci/intel8x0.c:1.160->1.161 
#   F:pci/ac97/ac97_codec.c:1.144->1.145 
#   F:pci/ac97/ac97_pcm.c:1.16->1.17 
#   F:pci/ac97/ac97_proc.c:1.10->1.11 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ac97/ac97_proc.c
#   2004/09/01 02:30:57+02:00 perex@suse.cz +4 -0
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   D:2004/09/01 08:30:56
#   C:Documentation,AC97 Codec Core,Intel8x0 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.38->1.39 
#   F:include/ac97_codec.h:1.50->1.51 
#   F:pci/intel8x0.c:1.160->1.161 
#   F:pci/ac97/ac97_codec.c:1.144->1.145 
#   F:pci/ac97/ac97_pcm.c:1.16->1.17 
#   F:pci/ac97/ac97_proc.c:1.10->1.11 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ac97/ac97_pcm.c
#   2004/09/01 02:30:57+02:00 perex@suse.cz +120 -34
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   D:2004/09/01 08:30:56
#   C:Documentation,AC97 Codec Core,Intel8x0 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.38->1.39 
#   F:include/ac97_codec.h:1.50->1.51 
#   F:pci/intel8x0.c:1.160->1.161 
#   F:pci/ac97/ac97_codec.c:1.144->1.145 
#   F:pci/ac97/ac97_pcm.c:1.16->1.17 
#   F:pci/ac97/ac97_proc.c:1.10->1.11 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2004/09/01 02:30:57+02:00 perex@suse.cz +31 -1
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   D:2004/09/01 08:30:56
#   C:Documentation,AC97 Codec Core,Intel8x0 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.38->1.39 
#   F:include/ac97_codec.h:1.50->1.51 
#   F:pci/intel8x0.c:1.160->1.161 
#   F:pci/ac97/ac97_codec.c:1.144->1.145 
#   F:pci/ac97/ac97_pcm.c:1.16->1.17 
#   F:pci/ac97/ac97_proc.c:1.10->1.11 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# include/sound/ac97_codec.h
#   2004/09/01 02:30:56+02:00 perex@suse.cz +10 -1
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   D:2004/09/01 08:30:56
#   C:Documentation,AC97 Codec Core,Intel8x0 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.38->1.39 
#   F:include/ac97_codec.h:1.50->1.51 
#   F:pci/intel8x0.c:1.160->1.161 
#   F:pci/ac97/ac97_codec.c:1.144->1.145 
#   F:pci/ac97/ac97_pcm.c:1.16->1.17 
#   F:pci/ac97/ac97_proc.c:1.10->1.11 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/09/01 02:30:56+02:00 perex@suse.cz +2 -2
#   [ALSA]  AC97 96 kHz sample rate support
#   
#   D:2004/09/01 08:30:56
#   C:Documentation,AC97 Codec Core,Intel8x0 driver
#   F:Documentation/DocBook/writing-an-alsa-driver.tmpl:1.38->1.39 
#   F:include/ac97_codec.h:1.50->1.51 
#   F:pci/intel8x0.c:1.160->1.161 
#   F:pci/ac97/ac97_codec.c:1.144->1.145 
#   F:pci/ac97/ac97_pcm.c:1.16->1.17 
#   F:pci/ac97/ac97_proc.c:1.10->1.11 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2004/09/06 20:15:40+02:00 perex@suse.cz 
#   [ALSA]  Korg1212 misc fixes
#   
#   KORG1212 driver
#   The DSP firmware download timeout has been increased;
#   Some concurrent device settings has been fixed (I have shameless copied
#   some code from RME9652); and
#   One debug message was fixed.
#   
#   Signed-off-by: Haroldo Gamal <gamal@alternex.com.br>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/korg1212/korg1212.c
#   2004/08/31 04:50:15+02:00 perex@suse.cz +59 -9
#   [ALSA]  Korg1212 misc fixes
#   
#   D:2004/08/31 10:50:15
#   C:KORG1212 driver
#   F:pci/korg1212/korg1212.c:1.47->1.48 
#   L:The DSP firmware download timeout has been increased;
#   L:Some concurrent device settings has been fixed (I have shameless copied
#   L:some code from RME9652); and
#   L:One debug message was fixed.
#   Signed-off-by: Haroldo Gamal <gamal@alternex.com.br>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:14:51+02:00 perex@suse.cz 
#   [ALSA]  Enable __GFP_NOWARN as default for buffer allocation
#   
#   Memalloc module
#   __GFP_NOWARN is enabled for DMA buffer allocation regardless of
#   its size.  The DMA buffer allocation is not a critical task.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/memalloc.c
#   2004/08/31 04:49:23+02:00 perex@suse.cz +3 -4
#   [ALSA]  Enable __GFP_NOWARN as default for buffer allocation
#   
#   D:2004/08/31 10:49:23
#   C:Memalloc module
#   F:core/memalloc.c:1.37->1.38 
#   L:__GFP_NOWARN is enabled for DMA buffer allocation regardless of
#   L:its size.  The DMA buffer allocation is not a critical task.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:14:05+02:00 perex@suse.cz 
#   [ALSA]  Added __GFP_NORETRY to avoid OOM-killer
#   
#   Memalloc module
#   __GFP_NORETRY is added to the DMA buffer allocator to avoid triggering
#   OOM-killer.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/memalloc.c
#   2004/08/30 12:39:22+02:00 perex@suse.cz +1 -0
#   [ALSA]  Added __GFP_NORETRY to avoid OOM-killer
#   
#   D:2004/08/30 18:39:22
#   C:Memalloc module
#   F:core/memalloc.c:1.36->1.37 
#   L:__GFP_NORETRY is added to the DMA buffer allocator to avoid triggering
#   L:OOM-killer.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:13:09+02:00 perex@suse.cz 
#   ALSA CVS update
#   ES18xx driver
#   Fixed a bug in setting the filter register.
#   
#   A fix from the kernel OSS driver.  The original report/patch is from
#   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=204147
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/isa/es18xx.c
#   2004/08/26 10:57:47+02:00 perex@suse.cz +5 -0
#   ALSA CVS update
#   D:2004/08/26 16:57:47
#   C:ES18xx driver
#   F:isa/es18xx.c:1.48->1.49 
#   L:Fixed a bug in setting the filter register.
#   L:
#   L:A fix from the kernel OSS driver.  The original report/patch is from
#   L:http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=204147
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:12:22+02:00 perex@suse.cz 
#   ALSA CVS update
#   ICE1712 driver
#   Allow the private EEPROM image for evaluation boards
#   
#   The driver may have a private EEPROM image instead of reading
#   from the board (as well as ice1724 does).  It'll be helpful for
#   test boards.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ice1712/ice1712.c
#   2004/08/26 10:55:43+02:00 perex@suse.cz +39 -19
#   ALSA CVS update
#   D:2004/08/26 16:55:43
#   C:ICE1712 driver
#   F:pci/ice1712/ice1712.c:1.61->1.62 
#   L:Allow the private EEPROM image for evaluation boards
#   L:
#   L:The driver may have a private EEPROM image instead of reading
#   L:from the board (as well as ice1724 does).  It'll be helpful for
#   L:test boards.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2004/09/06 20:11:34+02:00 perex@suse.cz 
#   ALSA CVS update
#   ENS1370/1+ driver
#   Fixed AC3-passthru on ens1371/1373 boards.
#   
#   SRC is bypassed when the sample rate is 48k, so that the non-audio
#   signal won't be broken.  The other sample rates still need SRC.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ens1370.c
#   2004/08/26 10:53:55+02:00 perex@suse.cz +7 -0
#   ALSA CVS update
#   D:2004/08/26 16:53:55
#   C:ENS1370/1+ driver
#   F:pci/ens1370.c:1.67->1.68 
#   L:Fixed AC3-passthru on ens1371/1373 boards.
#   L:
#   L:SRC is bypassed when the sample rate is 48k, so that the non-audio
#   L:signal won't be broken.  The other sample rates still need SRC.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	2004-10-21 14:13:16 -07:00
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	2004-10-21 14:13:16 -07:00
@@ -661,8 +661,6 @@
 			* ALi m5455
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
-    joystick      - Enable joystick (default off)
-    mpu_port      - MPU401 port # (0 = disabled, 0x330,0x300)
     ac97_quirk    - AC'97 workaround for strange hardware (-1 = default)
                     -1 = default, don't override
                      0 = disable
@@ -670,6 +668,7 @@
                      2 = swap headphone and master controls
                      3 = for AD1985, turn on OMS bit and use headphone
                      4 = for ALC65x, turn on the jack sense mode
+                     5 = inverted EAPD implementation
     buggy_irq      - Enable workaround for buggy interrupts on some
                      motherboards (default off)
 
@@ -679,8 +678,9 @@
     if you still encounter too fast playback, specify the clock
     explicitly via the module option "ac97_clock=41194".
 
-    The joystick and MPU-401 are supported only certain hardwares.
-    MPU401 is experimental,  It doesn't work perfectly.
+    Joystick/MIDI ports are not supported by this driver.  If your
+    motherboard has these devices, use the ns558 or snd-mpu401
+    modules, respectively.
 
     The ac97_quirk option is used to enable/override the workaround
     for specific devices.  Some hardware have swapped output pins
@@ -809,6 +809,7 @@
     buffer_top       - specify buffer top address
     use_cache        - 0 or 1 (disabled by default)
     vaio_hack        - alias buffer_top=0x25a800
+    reset_workaround - enable AC97 RESET workaround for some laptops
 
     Module supports autoprobe and multiple chips (max 8).
 
@@ -833,6 +834,11 @@
     other drivers, e.g. snd-cs4232 or snd-opl3sa2.  Some has ISA-PnP
     but some doesn't have ISA PnP.  You'll need to speicfy isapnp=0
     and proper hardware parameters in the case without ISA PnP.
+
+    Note: some laptops need a workaround for AC97 RESET.  For the
+    known hardware like Dell Latitude LS and Sony PCG-F305, this
+    workaround is enabled automatically.  For other laptops with a
+    hard freeze, you can try reset_workaround=1 option.
 
     Note: This driver is really crappy.  It's a porting from the
     OSS driver, which is a result of black-magic reverse engineering.
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	2004-10-21 14:13:16 -07:00
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2004-10-21 14:13:16 -07:00
@@ -1479,7 +1479,7 @@
   struct snd_mychip {
           ....
           unsigned long iobase_phys;
-          unsigned long iobase_virt;
+          void __iomem *iobase_virt;
   };
 ]]>
           </programlisting>
@@ -1495,8 +1495,7 @@
           return err;
   }
   chip->iobase_phys = pci_resource_start(pci, 0);
-  chip->iobase_virt = (unsigned long)
-                      ioremap_nocache(chip->iobase_phys,
+  chip->iobase_virt = ioremap_nocache(chip->iobase_phys,
                                       pci_resource_len(pci, 0));
 ]]>
           </programlisting>
@@ -1511,7 +1510,7 @@
   {
           ....
           if (chip->iobase_virt)
-                  iounmap((void *)chip->iobase_virt);
+                  iounmap(chip->iobase_virt);
           ....
           pci_release_regions(chip->pci);
           ....
@@ -4060,8 +4059,8 @@
       <para>
         Also, there is a function to change the sample rate (of a
         certain register such as
-        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA is
-        supported by the codec:
+        <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA or
+        DRA is supported by the codec:
         <function>snd_ac97_set_rate()</function>. 
 
         <informalexample>
@@ -4341,7 +4340,39 @@
       </para>
 
       <para>
-        If this function returns successfully with 0, then create a
+        When the accessing to the hardware requires special method
+        instead of the standard I/O access, you can create opl3 instance
+        separately with <function>snd_opl3_new()</function>.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  opl3_t *opl3;
+  snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+	Then set <structfield>command</structfield>,
+	<structfield>private_data</structfield> and
+	<structfield>private_free</structfield> for the private
+	access function, the private data and the destructor.
+	The l_port and r_port are not necessarily set.  Only the
+	command must be set properly.  You can retrieve the data
+	from opl3-&gt;private_data field.
+      </para>
+
+      <para>
+	After creating the opl3 instance via <function>snd_opl3_new()</function>,
+	call <function>snd_opl3_init()</function> to initialize the chip to the
+	proper state.  Note that <function>snd_opl3_create()</function> always
+	calls it internally.
+      </para>
+
+      <para>
+        If the opl3 instance is created successfully, then create a
         hwdep device for this opl3. 
 
         <informalexample>
diff -Nru a/Documentation/sound/alsa/Joystick.txt b/Documentation/sound/alsa/Joystick.txt
--- a/Documentation/sound/alsa/Joystick.txt	2004-10-21 14:13:16 -07:00
+++ b/Documentation/sound/alsa/Joystick.txt	2004-10-21 14:13:16 -07:00
@@ -49,17 +49,15 @@
     cs46xx	N/A		N/A
     es1938	N/A		N/A
     es1968	joystick	0 = disable (default), 1 = enable
-    intel8x0(*1)joystick	0 = disable (default), 1 = enable
     sonicvibes	N/A		N/A
     trident	N/A		N/A
-    via82xx(*2)	joystick	0 = disable (default), 1 = enable
+    via82xx(*1)	joystick	0 = disable (default), 1 = enable
     ymfpci	joystick_port	0 = disable (default), 1 = auto-detect,
-                                manual: 0x201, 0x202, 0x204, 0x205(*3)
+                                manual: 0x201, 0x202, 0x204, 0x205(*2)
     ---------------------------------------------------------------------------
 
-    *1)  not all chips support joystick
-    *2)  VIA686A/B only
-    *3)  With YMF744/754 chips, the port address can be chosen arbitrarily
+    *1)  VIA686A/B only
+    *2)  With YMF744/754 chips, the port address can be chosen arbitrarily
 
 The following drivers don't support gameport natively, but there are
 additional modules.  Load the corresponding module to add the gameport
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/ac97_codec.h	2004-10-21 14:13:16 -07:00
@@ -26,6 +26,7 @@
  */
 
 #include <linux/bitops.h>
+#include "pcm.h"
 #include "control.h"
 #include "info.h"
 
@@ -133,6 +134,11 @@
 #define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
 #define AC97_BC_ADC_MASK	0x0300
 
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
 /* extended audio ID bit defines */
 #define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
 #define AC97_EI_DRA		0x0002	/* Double rate supported */
@@ -348,6 +354,8 @@
 #define AC97_SCAP_SKIP_AUDIO	(1<<4)	/* skip audio part of codec */
 #define AC97_SCAP_SKIP_MODEM	(1<<5)	/* skip modem part of codec */
 #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 */
 
 /* ac97->flags */
 #define AC97_HAS_PC_BEEP	(1<<0)	/* force PC Speaker usage */
@@ -355,6 +363,7 @@
 #define AC97_CS_SPDIF		(1<<2)	/* Cirrus Logic uses funky SPDIF */
 #define AC97_CX_SPDIF		(1<<3)	/* Conexant's spdif interface */
 #define AC97_STEREO_MUTES	(1<<4)	/* has stereo mute bits */
+#define AC97_DOUBLE_RATE	(1<<5)	/* supports double rate playback */
 
 /* rates indexes */
 #define AC97_RATES_FRONT_DAC	0
@@ -369,6 +378,7 @@
 	AC97_SHARED_TYPE_NONE,
 	AC97_SHARED_TYPE_ICH,
 	AC97_SHARED_TYPE_ATIIXP,
+	AC97_SHARED_TYPE_VIA,
 	AC97_SHARED_TYPES
 };
 
@@ -432,6 +442,7 @@
 	snd_card_t *card;
 	unsigned short num;	/* bus number */
 	unsigned short no_vra: 1, /* bridge doesn't support VRA */
+		       dra: 1,	/* bridge supports double rate */
 		       isdin: 1;/* independent SDIN */
 	unsigned int clock;	/* AC'97 base clock (usually 48000Hz) */
 	spinlock_t bus_lock;	/* used mainly for slot allocation */
@@ -518,6 +529,7 @@
 /* functions */
 int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, void *private_data, ac97_bus_t **rbus); /* create new AC97 bus */
 int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97);	/* create mixer controls */
+const char *snd_ac97_get_short_name(ac97_t *ac97);
 
 void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value);
 unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg);
@@ -538,18 +550,20 @@
 	AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */
 	AC97_TUNE_AD_SHARING,	/* for AD1985, turn on OMS bit and use headphone */
 	AC97_TUNE_ALC_JACK,	/* for Realtek, enable JACK detection */
+	AC97_TUNE_INV_EAPD,	/* inverted EAPD implementation */
 };
 
 struct ac97_quirk {
 	unsigned short vendor;	/* PCI vendor id */
 	unsigned short device;	/* PCI device id */
 	unsigned short mask;	/* device id bit mask, 0 = accept all */
+	unsigned int codec_id;	/* codec id (if any), 0 = accept all */
 	const char *name;	/* name shown as info */
 	int type;		/* quirk type above */
 };
 
 int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, int override);
-int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate);
+int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate);
 
 int snd_ac97_pcm_assign(ac97_bus_t *ac97,
 			unsigned short pcms_count,
@@ -557,5 +571,6 @@
 int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
 		      enum ac97_pcm_cfg cfg, unsigned short slots);
 int snd_ac97_pcm_close(struct ac97_pcm *pcm);
+int snd_ac97_pcm_double_rate_rules(snd_pcm_runtime_t *runtime);
 
 #endif /* __SOUND_AC97_CODEC_H */
diff -Nru a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/core.h	2004-10-21 14:13:16 -07:00
@@ -307,8 +307,8 @@
 #define vfree_nocheck(obj) vfree(obj)
 #endif
 char *snd_kmalloc_strdup(const char *string, int flags);
-int copy_to_user_fromio(void __user *dst, unsigned long src, size_t count);
-int copy_from_user_toio(unsigned long dst, const void __user *src, size_t count);
+int copy_to_user_fromio(void __user *dst, const void __iomem *src, size_t count);
+int copy_from_user_toio(void __iomem *dst, const void __user *src, size_t count);
 
 /* init.c */
 
@@ -417,7 +417,7 @@
  */
 #define snd_assert(expr, args...) do {\
 	if (unlikely(!(expr))) {				\
-		snd_printk("BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
+		snd_printk(KERN_ERR "BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
 		args;\
 	}\
 } while (0)
@@ -433,7 +433,7 @@
  */
 #define snd_runtime_check(expr, args...) do {\
 	if (unlikely(!(expr))) {				\
-		snd_printk("ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
+		snd_printk(KERN_ERR "ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
 		args;\
 	}\
 } while (0)
diff -Nru a/include/sound/cs46xx.h b/include/sound/cs46xx.h
--- a/include/sound/cs46xx.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/cs46xx.h	2004-10-21 14:13:16 -07:00
@@ -1662,7 +1662,7 @@
 typedef struct {
 	char name[24];
 	unsigned long base;
-	unsigned long remap_addr;
+	void __iomem *remap_addr;
 	unsigned long size;
 	struct resource *resource;
 } snd_cs46xx_region_t;
diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/emu10k1.h	2004-10-21 14:13:16 -07:00
@@ -737,6 +737,9 @@
 #define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
 #define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
 
+#define A_TANKMEMCTLREGBASE	0x100		/* Tank memory control registers base - only for Audigy */
+#define A_TANKMEMCTLREG_MASK	0x1f		/* only 5 bits used - only for Audigy */
+
 /* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
 /* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
 /* locations are for external TRAM. 								*/
@@ -857,7 +860,7 @@
 	struct list_head list;		/* list link container */
 	unsigned int vcount;
 	unsigned int count;		/* count of GPR (1..16) */
-	unsigned char gpr[32];		/* GPR number(s) */
+	unsigned short gpr[32];		/* GPR number(s) */
 	unsigned int value[32];
 	unsigned int min;		/* minimum range */
 	unsigned int max;		/* maximum range */
@@ -870,7 +873,7 @@
 typedef struct _snd_emu10k1_fx8010_irq {
 	struct _snd_emu10k1_fx8010_irq *next;
 	snd_fx8010_irq_handler_t *handler;
-	unsigned char gpr_running;
+	unsigned short gpr_running;
 	void *private_data;
 } snd_emu10k1_fx8010_irq_t;
 
@@ -881,12 +884,12 @@
 	unsigned int channels;		/* 16-bit channels count */
 	unsigned int tram_start;	/* initial ring buffer position in TRAM (in samples) */
 	unsigned int buffer_size;	/* count of buffered samples */
-	unsigned char gpr_size;		/* GPR containing size of ring buffer in samples (host) */
-	unsigned char gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
-	unsigned char gpr_count;	/* GPR containing count of samples between two interrupts (host) */
-	unsigned char gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
-	unsigned char gpr_trigger;	/* GPR containing trigger (activate) information (host) */
-	unsigned char gpr_running;	/* GPR containing info if PCM is running (FX8010) */
+	unsigned short gpr_size;		/* GPR containing size of ring buffer in samples (host) */
+	unsigned short gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+	unsigned short gpr_count;	/* GPR containing count of samples between two interrupts (host) */
+	unsigned short gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
+	unsigned short gpr_trigger;	/* GPR containing trigger (activate) information (host) */
+	unsigned short gpr_running;	/* GPR containing info if PCM is running (FX8010) */
 	unsigned char etram[32];	/* external TRAM address & data */
 	snd_pcm_indirect_t pcm_rec;
 	unsigned int tram_pos;
@@ -1141,6 +1144,13 @@
 #define ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
 #define ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
 
+#define A_ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+#define A_ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+#define A_ITRAM_CTL(x)	(A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_CTL(x)	(A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+
 #define A_FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x3f? */
 #define A_EXTIN(x)	(0x40 + (x))	/* x = 0x00 - 0x1f? */
 #define A_EXTOUT(x)	(0x60 + (x))	/* x = 0x00 - 0x1f? */
@@ -1269,8 +1279,11 @@
 #define A_C_00100000	0xd5
 #define A_GPR_ACCU	0xd6		/* ACCUM, accumulator */
 #define A_GPR_COND	0xd7		/* CCR, condition register */
-/* 0xd8 = noise1 */
-/* 0xd9 = noise2 */
+#define A_GPR_NOISE0	0xd8		/* noise source */
+#define A_GPR_NOISE1	0xd9		/* noise source */
+#define A_GPR_IRQ	0xda		/* IRQ register */
+#define A_GPR_DBAC	0xdb		/* TRAM Delay Base Address Counter - internal */
+#define A_GPR_DBACE	0xde		/* TRAM Delay Base Address Counter - external */
 
 /* definitions for debug register */
 #define EMU10K1_DBG_ZC			0x80000000	/* zero tram counter */
@@ -1310,7 +1323,7 @@
 	snd_ctl_elem_id_t id;		/* full control ID definition */
 	unsigned int vcount;		/* visible count */
 	unsigned int count;		/* count of GPR (1..16) */
-	unsigned char gpr[32];		/* GPR number(s) */
+	unsigned short gpr[32];		/* GPR number(s) */
 	unsigned int value[32];		/* initial values */
 	unsigned int min;		/* minimum range */
 	unsigned int max;		/* maximum range */
@@ -1320,8 +1333,8 @@
 typedef struct {
 	char name[128];
 
-	unsigned long gpr_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
-	unsigned int gpr_map[0x100];	  /* initializers */
+	DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
+	unsigned int gpr_map[0x200];	  /* initializers */
 
 	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
 	emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */
@@ -1333,12 +1346,12 @@
 	unsigned int gpr_list_control_total; /* total count of GPR controls */
 	emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */
 
-	unsigned long tram_valid[0xa0/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
-	unsigned int tram_data_map[0xa0]; /* data initializers */
-	unsigned int tram_addr_map[0xa0]; /* map initializers */
+	DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
+	unsigned int tram_data_map[0x100]; /* data initializers */
+	unsigned int tram_addr_map[0x100]; /* map initializers */
 
-	unsigned long code_valid[512/(sizeof(unsigned long)*8)];  /* bitmask of valid instructions */
-	unsigned int code[512][2];	  /* one instruction - 64 bits */
+	DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
+	unsigned int code[1024][2];	  /* one instruction - 64 bits */
 } emu10k1_fx8010_code_t;
 
 typedef struct {
@@ -1354,12 +1367,12 @@
 	unsigned int channels;		/* 16-bit channels count, zero = remove this substream */
 	unsigned int tram_start;	/* ring buffer position in TRAM (in samples) */
 	unsigned int buffer_size;	/* count of buffered samples */
-	unsigned char gpr_size;		/* GPR containing size of ringbuffer in samples (host) */
-	unsigned char gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
-	unsigned char gpr_count;	/* GPR containing count of samples between two interrupts (host) */
-	unsigned char gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
-	unsigned char gpr_trigger;	/* GPR containing trigger (activate) information (host) */
-	unsigned char gpr_running;	/* GPR containing info if PCM is running (FX8010) */
+	unsigned short gpr_size;		/* GPR containing size of ringbuffer in samples (host) */
+	unsigned short gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+	unsigned short gpr_count;	/* GPR containing count of samples between two interrupts (host) */
+	unsigned short gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
+	unsigned short gpr_trigger;	/* GPR containing trigger (activate) information (host) */
+	unsigned short gpr_running;	/* GPR containing info if PCM is running (FX8010) */
 	unsigned char pad;		/* reserved */
 	unsigned char etram[32];	/* external TRAM address & data (one per channel) */
 	unsigned int res2;		/* reserved */
diff -Nru a/include/sound/hdsp.h b/include/sound/hdsp.h
--- a/include/sound/hdsp.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/hdsp.h	2004-10-21 14:13:16 -07:00
@@ -32,13 +32,13 @@
 typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t;
 
 struct _snd_hdsp_peak_rms {
-	unsigned int input_peaks[26];
-	unsigned int playback_peaks[26];
-	unsigned int output_peaks[28];
-	unsigned long long input_rms[26];
-	unsigned long long playback_rms[26];
+	u32 input_peaks[26];
+	u32 playback_peaks[26];
+	u32 output_peaks[28];
+	u64 input_rms[26];
+	u64 playback_rms[26];
 	/* These are only used for H96xx cards */
-	unsigned long long output_rms[26];
+	u64 output_rms[26];
 };
 
 #define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
@@ -76,7 +76,7 @@
 typedef struct _snd_hdsp_firmware hdsp_firmware_t;
 
 struct _snd_hdsp_firmware {
-	unsigned long __user *firmware_data;	/* 24413 long words */
+	void __user *firmware_data;	/* 24413 x 4 bytes */
 };
 
 #define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
diff -Nru a/include/sound/opl3.h b/include/sound/opl3.h
--- a/include/sound/opl3.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/opl3.h	2004-10-21 14:13:16 -07:00
@@ -274,6 +274,9 @@
 	snd_timer_t *timer2;
 	spinlock_t timer_lock;
 
+	void *private_data;
+	void (*private_free)(opl3_t *);
+
 	spinlock_t reg_lock;
 	snd_card_t *card;		/* The card that this belongs to */
 	int used;			/* usage flag - exclusive */
@@ -314,6 +317,8 @@
 
 /* opl3.c */
 void snd_opl3_interrupt(snd_hwdep_t * hw);
+int snd_opl3_new(snd_card_t *card, unsigned short hardware, opl3_t **ropl3);
+int snd_opl3_init(opl3_t *opl3);
 int snd_opl3_create(snd_card_t * card,
 		    unsigned long l_port, unsigned long r_port,
 		    unsigned short hardware,
diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h
--- a/include/sound/pcm.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/pcm.h	2004-10-21 14:13:16 -07:00
@@ -364,6 +364,7 @@
 typedef struct _snd_pcm_group {		/* keep linked substreams */
 	spinlock_t lock;
 	struct list_head substreams;
+	int count;
 } snd_pcm_group_t;
 
 struct _snd_pcm_substream {
@@ -405,6 +406,8 @@
 	snd_info_entry_t *proc_sw_params_entry;
 	snd_info_entry_t *proc_status_entry;
 	snd_info_entry_t *proc_prealloc_entry;
+	/* misc flags */
+	unsigned int no_mmap_ctrl: 1;
 };
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
@@ -486,6 +489,7 @@
 int snd_pcm_prepare(snd_pcm_substream_t *substream);
 int snd_pcm_start(snd_pcm_substream_t *substream);
 int snd_pcm_stop(snd_pcm_substream_t *substream, int status);
+int snd_pcm_drain_done(snd_pcm_substream_t *substream);
 #ifdef CONFIG_PM
 int snd_pcm_suspend(snd_pcm_substream_t *substream);
 int snd_pcm_suspend_all(snd_pcm_t *pcm);
diff -Nru a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
--- a/include/sound/seq_kernel.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/seq_kernel.h	2004-10-21 14:13:16 -07:00
@@ -180,4 +180,12 @@
 			      int cap, int type, int midi_channels, int midi_voices, char *portname);
 int snd_seq_event_port_detach(int client, int port);
 
+#ifdef CONFIG_KMOD
+void snd_seq_autoload_lock(void);
+void snd_seq_autoload_unlock(void);
+#else
+#define snd_seq_autoload_lock()
+#define snd_seq_autoload_unlock()
+#endif
+
 #endif /* __SOUND_SEQ_KERNEL_H */
diff -Nru a/include/sound/ymfpci.h b/include/sound/ymfpci.h
--- a/include/sound/ymfpci.h	2004-10-21 14:13:16 -07:00
+++ b/include/sound/ymfpci.h	2004-10-21 14:13:16 -07:00
@@ -305,7 +305,7 @@
 	unsigned int device_id;	/* PCI device ID */
 	unsigned int rev;	/* PCI revision */
 	unsigned long reg_area_phys;
-	unsigned long reg_area_virt;
+	void __iomem *reg_area_virt;
 	struct resource *res_reg_area;
 	struct resource *fm_res;
 	struct resource *mpu_res;
diff -Nru a/sound/arm/Kconfig b/sound/arm/Kconfig
--- a/sound/arm/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/arm/Kconfig	2004-10-21 14:13:16 -07:00
@@ -4,12 +4,15 @@
 	depends on SND!=n && ARM
 
 config SND_SA11XX_UDA1341
-	tristate "SA11xx UDA1341TS driver (H3600)"
+	tristate "SA11xx UDA1341TS driver (iPaq H3600)"
 	depends on ARCH_SA1100 && SND && L3
 	select SND_PCM
 	help
-	  Say Y or M if you have a Compaq iPaq H3x00 handheld computer and want
-	  to use its Philips UDA 1341 audio chip.
+	  Say Y here if you have a Compaq iPaq H3x00 handheld computer
+	  and want to use its Philips UDA 1341 audio chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sa11xx-uda1341.
 
 endmenu
 
diff -Nru a/sound/core/Kconfig b/sound/core/Kconfig
--- a/sound/core/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/core/Kconfig	2004-10-21 14:13:16 -07:00
@@ -17,17 +17,26 @@
 	depends on SND
 	select SND_TIMER
 	help
-	  Say 'Y' or 'M' to enable MIDI sequencer and router support. This feature
-	  allows routing and enqueing MIDI events. Events can be processed at given
-	  time.
+	  Say Y or M to enable MIDI sequencer and router support.  This
+	  feature allows routing and enqueueing of MIDI events.  Events
+	  can be processed at a given time.
+
+	  Many programs require this feature, so you should enable it
+	  unless you know what you're doing.
 
 config SND_SEQ_DUMMY
 	tristate "Sequencer dummy client"
 	depends on SND_SEQUENCER
 	help
-	  Say 'Y' or 'M' to enable dummy sequencer client. This client is a simple
-	  midi-through client. All normal input events are redirected to output port
-	  immediately.
+	  Say Y here to enable the dummy sequencer client.  This client
+	  is a simple MIDI-through client: all normal input events are
+	  redirected to the output port immediately.
+
+	  You don't need this unless you want to connect many MIDI
+	  devices or applications together.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-seq-dummy.
 
 config SND_OSSEMUL
 	bool
@@ -37,7 +46,13 @@
 	depends on SND
 	select SND_OSSEMUL
 	help
-	  Say 'Y' or 'M' to enable mixer OSS API emulation (/dev/mixer*).
+	  To enable OSS mixer API emulation (/dev/mixer*), say Y here
+	  and read <file:Documentation/sound/alsa/OSS-Emulation.txt>.
+
+	  Many programs still use the OSS API, so say Y.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-mixer-oss.
 
 config SND_PCM_OSS
 	tristate "OSS PCM (digital audio) API"
@@ -45,15 +60,26 @@
 	select SND_OSSEMUL
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to enable digital audio (PCM) OSS API emulation (/dev/dsp*).
+	  To enable OSS digital audio (PCM) emulation (/dev/dsp*), say Y
+	  here and read <file:Documentation/sound/alsa/OSS-Emulation.txt>.
+
+	  Many programs still use the OSS API, so say Y.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-pcm-oss.
 
 config SND_SEQUENCER_OSS
 	bool "OSS Sequencer API"
 	depends on SND_SEQUENCER
 	select SND_OSSEMUL
 	help
-	  Say 'Y' to enable OSS sequencer emulation (both /dev/sequencer and
-	  /dev/music interfaces).
+	  Say Y here to enable OSS sequencer emulation (both
+	  /dev/sequencer and /dev/music interfaces).
+
+	  Many programs still use the OSS API, so say Y.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-seq-oss.
 
 config SND_BIT32_EMUL
 	tristate "Emulation for 32-bit applications"
@@ -63,38 +89,51 @@
 	select SND_TIMER
 	select SND_HWDEP
 	help
-	  Say 'Y' or 'M' to enable the emulation for 32-bit ALSA-native
+	  Say Y here to enable the emulation for 32-bit ALSA-native
 	  applications.
 
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ioctl32.
+
 config SND_RTCTIMER
 	tristate "RTC Timer support"
 	depends on SND && RTC
 	select SND_TIMER
 	help
-	  Say 'Y' or 'M' to enable RTC timer support for ALSA. ALSA code uses RTC
-	  timer as precise timing source and maps the RTC timer to the ALSA's timer
-	  interface. ALSA sequencer code can also use this timing source.
+	  Say Y here to enable RTC timer support for ALSA.  ALSA uses
+	  the RTC timer as a precise timing source and maps the RTC
+	  timer to ALSA's timer interface.  The ALSA sequencer code also
+	  can use this timing source.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rtctimer.
 
 config SND_VERBOSE_PRINTK
 	bool "Verbose printk"
 	depends on SND
 	help
-	  Say 'Y' to enable verbose log messages. These messages will help to
-	  identify source file and position containing printed messages.
+	  Say Y here to enable verbose log messages.  These messages
+	  will help to identify source file and position containing
+	  printed messages.
+
+	  You don't need this unless you're debugging ALSA.
 
 config SND_DEBUG
 	bool "Debug"
 	depends on SND
 	help
-	  Say 'Y' to enable ALSA debug code.
+	  Say Y here to enable ALSA debug code.
 
 config SND_DEBUG_MEMORY
 	bool "Debug memory"
 	depends on SND_DEBUG
 	help
-	  Say 'Y' to enable debugging of memory allocation.
+	  Say Y here to enable debugging of memory allocations.
 
 config SND_DEBUG_DETECT
 	bool "Debug detection"
 	depends on SND_DEBUG
+	help
+	  Say Y here to enable extra-verbose log messages printed when
+	  detecting devices.
 
diff -Nru a/sound/core/ioctl32/hwdep32.c b/sound/core/ioctl32/hwdep32.c
--- a/sound/core/ioctl32/hwdep32.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/ioctl32/hwdep32.c	2004-10-21 14:13:16 -07:00
@@ -34,7 +34,7 @@
 	u32 driver_data;
 } /* don't set packed attribute here */;
 
-static int _snd_ioctl32_hwdep_dsp_image(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_hwdep_dsp_image(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_hwdep_dsp_image data;
 	struct sndrv_hwdep_dsp_image32 data32;
diff -Nru a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c
--- a/sound/core/ioctl32/ioctl32.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/ioctl32/ioctl32.c	2004-10-21 14:13:16 -07:00
@@ -102,7 +102,7 @@
 	CPTR(pids);\
 }
 
-static int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_ctl_elem_list(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_ctl_elem_list32 data32;
 	struct sndrv_ctl_elem_list data;
@@ -168,7 +168,7 @@
 	unsigned char reserved[64];
 } __attribute__((packed));
 
-static int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_ctl_elem_info data;
 	struct sndrv_ctl_elem_info32 data32;
@@ -246,7 +246,7 @@
 		struct sndrv_aes_iec958 iec958;
         } value;
         unsigned char reserved[128];
-} __attribute__((packed));
+};
 
 
 /* hmm, it's so hard to retrieve the value type from the control id.. */
@@ -274,7 +274,7 @@
 }
 
 
-static int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_ctl_elem_value *data;
 	struct sndrv_ctl_elem_value32 *data32;
diff -Nru a/sound/core/ioctl32/ioctl32.h b/sound/core/ioctl32/ioctl32.h
--- a/sound/core/ioctl32/ioctl32.h	2004-10-21 14:13:16 -07:00
+++ b/sound/core/ioctl32/ioctl32.h	2004-10-21 14:13:16 -07:00
@@ -18,7 +18,7 @@
  *
  *
  * This file registers the converters from 32-bit ioctls to 64-bit ones.
- * The converter assumes that a 32-bit user-pointer can be casted by A(x)
+ * The converter assumes that a 32-bit user-pointer can be casted by compat_ptr(x)
  * macro to a valid 64-bit pointer which is accessible via copy_from/to_user.
  *
  */
@@ -47,7 +47,7 @@
 
 
 #define DEFINE_ALSA_IOCTL(type) \
-static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
+static inline int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
 {\
 	struct sndrv_##type##32 data32;\
 	struct sndrv_##type data;\
@@ -72,7 +72,7 @@
 }
 
 #define DEFINE_ALSA_IOCTL_BIG(type) \
-static int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
+static inline int _snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)\
 {\
 	struct sndrv_##type##32 *data32;\
 	struct sndrv_##type *data;\
diff -Nru a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c
--- a/sound/core/ioctl32/pcm32.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/ioctl32/pcm32.c	2004-10-21 14:13:16 -07:00
@@ -169,11 +169,69 @@
 
 DEFINE_ALSA_IOCTL(pcm_uframes_str);
 DEFINE_ALSA_IOCTL(pcm_sframes_str);
-DEFINE_ALSA_IOCTL_BIG(pcm_hw_params);
 DEFINE_ALSA_IOCTL(pcm_sw_params);
 DEFINE_ALSA_IOCTL(pcm_channel_info);
 DEFINE_ALSA_IOCTL(pcm_status);
 
+/* recalcuate the boundary within 32bit */
+static void recalculate_boundary(struct file *file)
+{
+	snd_pcm_file_t *pcm_file;
+	snd_pcm_substream_t *substream;
+	snd_pcm_runtime_t *runtime;
+
+	/* FIXME: need to check whether fop->ioctl is sane */
+	if (! (pcm_file = file->private_data))
+		return;
+	if (! (substream = pcm_file->substream))
+		return;
+	if (! (runtime = substream->runtime))
+		return;
+	runtime->boundary = runtime->buffer_size;
+	while (runtime->boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
+		runtime->boundary *= 2;
+}
+
+static inline int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+{
+	struct sndrv_pcm_hw_params32 *data32;
+	struct sndrv_pcm_hw_params *data;
+	mm_segment_t oldseg;
+	int err;
+
+	data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	if (data32 == NULL || data == NULL) {
+		err = -ENOMEM;
+		goto __end;
+	}
+	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) {
+		err = -EFAULT;
+		goto __end;
+	}
+	memset(data, 0, sizeof(*data));
+	convert_from_32(pcm_hw_params, data, data32);
+	oldseg = get_fs();
+	set_fs(KERNEL_DS);
+	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
+	set_fs(oldseg);
+	if (err < 0)
+		goto __end;
+	err = 0;
+	convert_to_32(pcm_hw_params, data32, data);
+	if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
+		err = -EFAULT;
+	else
+		recalculate_boundary(file);
+      __end:
+      	if (data)
+      		kfree(data);
+      	if (data32)
+      		kfree(data32);
+	return err;
+}
+
+
 /*
  */
 struct sndrv_xferi32 {
@@ -182,7 +240,7 @@
 	u32 frames;
 } __attribute__((packed));
 
-static int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_xferi(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_xferi32 data32;
 	struct sndrv_xferi data;
@@ -222,7 +280,7 @@
  * handler there expands again the same 128 pointers on stack, so it is better
  * to handle the function (calling pcm_readv/writev) directly in this handler.
  */
-static int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	snd_pcm_file_t *pcm_file;
 	snd_pcm_substream_t *substream;
@@ -343,7 +401,7 @@
 	oparams->fifo_size = params->fifo_size;
 }
 
-static int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
+static inline int _snd_ioctl32_pcm_hw_params_old(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
 {
 	struct sndrv_pcm_hw_params_old32 *data32;
 	struct sndrv_pcm_hw_params *data;
@@ -371,6 +429,8 @@
 	err = 0;
 	if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
 		err = -EFAULT;
+	else
+		recalculate_boundary(file);
       __end:
       	if (data)
       		kfree(data);
@@ -439,6 +499,30 @@
 
 
 /*
+ * When PCM is used on 32bit mode, we need to disable
+ * mmap of PCM status/control records because of the size
+ * incompatibility.
+ * 
+ * Since INFO ioctl is always called at first, we mark the
+ * mmap-disabling in this ioctl wrapper.
+ */
+static int snd_pcm_info_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp)
+{
+	snd_pcm_file_t *pcm_file;
+	snd_pcm_substream_t *substream;
+	if (! filp->f_op || ! filp->f_op->ioctl)
+		return -ENOTTY;
+	pcm_file = filp->private_data;
+	if (! pcm_file)
+		return -ENOTTY;
+	substream = pcm_file->substream;
+	if (! substream)
+		return -ENOTTY;
+	substream->no_mmap_ctrl = 1;
+	return filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+}
+
+/*
  */
 #define AP(x) snd_ioctl32_##x
 
@@ -456,13 +540,14 @@
 	SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32),
 	SNDRV_PCM_IOCTL_HW_REFINE_OLD32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old32),
 	SNDRV_PCM_IOCTL_HW_PARAMS_OLD32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old32),
-	SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr),
+	SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr32),
 
 };
 
 struct ioctl32_mapper pcm_mappers[] = {
 	MAP_COMPAT(SNDRV_PCM_IOCTL_PVERSION),
-	MAP_COMPAT(SNDRV_PCM_IOCTL_INFO),
+	/* MAP_COMPAT(SNDRV_PCM_IOCTL_INFO), */
+	{ SNDRV_PCM_IOCTL_INFO, snd_pcm_info_ioctl32 },
 	MAP_COMPAT(SNDRV_PCM_IOCTL_TSTAMP),
 	{ SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) },
 	{ SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) },
diff -Nru a/sound/core/memalloc.c b/sound/core/memalloc.c
--- a/sound/core/memalloc.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/memalloc.c	2004-10-21 14:13:16 -07:00
@@ -245,9 +245,9 @@
 	snd_assert(size > 0, return NULL);
 	snd_assert(dma != NULL, return NULL);
 	pg = get_order(size);
-	gfp_flags = GFP_KERNEL;
-	if (pg > 0)
-		gfp_flags |= __GFP_NOWARN;
+	gfp_flags = GFP_KERNEL
+		| __GFP_NORETRY /* don't trigger OOM-killer */
+		| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
 	res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
 	if (res != NULL) {
 #ifdef NEED_RESERVE_PAGES
diff -Nru a/sound/core/memory.c b/sound/core/memory.c
--- a/sound/core/memory.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/memory.c	2004-10-21 14:13:16 -07:00
@@ -257,7 +257,7 @@
  *
  * Returns zero if successful, or non-zero on failure.
  */
-int copy_to_user_fromio(void __user *dst, unsigned long src, size_t count)
+int copy_to_user_fromio(void __user *dst, const void __iomem *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
 	return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
@@ -267,7 +267,7 @@
 		size_t c = count;
 		if (c > sizeof(buf))
 			c = sizeof(buf);
-		memcpy_fromio(buf, (void*)src, c);
+		memcpy_fromio(buf, src, c);
 		if (copy_to_user(dst, buf, c))
 			return -EFAULT;
 		count -= c;
@@ -288,7 +288,7 @@
  *
  * Returns zero if successful, or non-zero on failure.
  */
-int copy_from_user_toio(unsigned long dst, const void __user *src, size_t count)
+int copy_from_user_toio(void __iomem *dst, const void __user *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
 	return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
@@ -300,7 +300,7 @@
 			c = sizeof(buf);
 		if (copy_from_user(buf, src, c))
 			return -EFAULT;
-		memcpy_toio((void*)dst, buf, c);
+		memcpy_toio(dst, buf, c);
 		count -= c;
 		dst += c;
 		src += c;
diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/oss/pcm_oss.c	2004-10-21 14:13:16 -07:00
@@ -829,13 +829,18 @@
 			xfer += tmp;
 			if ((substream->oss.setup != NULL && substream->oss.setup->partialfrag) ||
 			    runtime->oss.buffer_used == runtime->oss.period_bytes) {
-				tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.buffer_used, 1);
+				tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr, 
+							 runtime->oss.buffer_used - runtime->oss.period_ptr, 1);
 				if (tmp <= 0)
 					return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 				runtime->oss.bytes += tmp;
-				runtime->oss.buffer_used = 0;
 				runtime->oss.period_ptr += tmp;
 				runtime->oss.period_ptr %= runtime->oss.period_bytes;
+				if (runtime->oss.period_ptr == 0 ||
+				    runtime->oss.period_ptr == runtime->oss.buffer_used)
+					runtime->oss.buffer_used = 0;
+				else if ((substream->ffile->f_flags & O_NONBLOCK) != 0)
+					return xfer > 0 ? xfer : -EAGAIN;
 			}
 		} else {
 			tmp = snd_pcm_oss_write2(substream, (char *)buf, runtime->oss.period_bytes, 0);
@@ -845,6 +850,9 @@
 			buf += tmp;
 			bytes -= tmp;
 			xfer += tmp;
+			if ((substream->ffile->f_flags & O_NONBLOCK) != 0 &&
+			    tmp != runtime->oss.period_bytes)
+				break;
 		}
 	}
 	return xfer;
diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/pcm.c	2004-10-21 14:13:16 -07:00
@@ -267,7 +267,7 @@
 }
 #endif
 
-
+#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;
@@ -391,6 +391,7 @@
 	snd_iprintf(buffer, "hw_ptr      : %ld\n", runtime->status->hw_ptr);
 	snd_iprintf(buffer, "appl_ptr    : %ld\n", runtime->control->appl_ptr);
 }
+#endif
 
 #ifdef CONFIG_SND_DEBUG
 static void snd_pcm_xrun_debug_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
diff -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/pcm_lib.c	2004-10-21 14:13:16 -07:00
@@ -176,7 +176,7 @@
 		runtime->avail_max = avail;
 	if (avail >= runtime->stop_threshold) {
 		if (substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING)
-			snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
+			snd_pcm_drain_done(substream);
 		else
 			xrun(substream);
 		return -EPIPE;
diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/pcm_native.c	2004-10-21 14:13:16 -07:00
@@ -451,7 +451,7 @@
 static int snd_pcm_hw_free(snd_pcm_substream_t * substream)
 {
 	snd_pcm_runtime_t *runtime;
-	int result;
+	int result = 0;
 
 	snd_assert(substream != NULL, return -ENXIO);
 	runtime = substream->runtime;
@@ -468,11 +468,8 @@
 	snd_pcm_stream_unlock_irq(substream);
 	if (atomic_read(&runtime->mmap_count))
 		return -EBADFD;
-	if (substream->ops->hw_free == NULL) {
-		runtime->status->state = SNDRV_PCM_STATE_OPEN;
-		return 0;
-	}
-	result = substream->ops->hw_free(substream);
+	if (substream->ops->hw_free)
+		result = substream->ops->hw_free(substream);
 	runtime->status->state = SNDRV_PCM_STATE_OPEN;
 	return result;
 }
@@ -652,6 +649,7 @@
 struct action_ops {
 	int (*pre_action)(snd_pcm_substream_t *substream, int state);
 	int (*do_action)(snd_pcm_substream_t *substream, int state);
+	void (*undo_action)(snd_pcm_substream_t *substream, int state);
 	void (*post_action)(snd_pcm_substream_t *substream, int state);
 };
 
@@ -666,7 +664,8 @@
 {
 	struct list_head *pos;
 	snd_pcm_substream_t *s = NULL;
-	int err, res = 0;
+	snd_pcm_substream_t *s1;
+	int res = 0;
 
 	snd_pcm_group_for_each(pos, substream) {
 		s = snd_pcm_group_substream_entry(pos);
@@ -674,24 +673,31 @@
 			spin_lock(&s->self_group.lock);
 		res = ops->pre_action(s, state);
 		if (res < 0)
-			break;
+			goto _unlock;
 	}
-	if (res >= 0) {
-		snd_pcm_group_for_each(pos, substream) {
-			s = snd_pcm_group_substream_entry(pos);
-			err = ops->do_action(s, state);
-			if (err < 0) {
-				if (res == 0)
-					res = err;
-			} else {
-				ops->post_action(s, state);
+	snd_pcm_group_for_each(pos, substream) {
+		s = snd_pcm_group_substream_entry(pos);
+		res = ops->do_action(s, state);
+		if (res < 0) {
+			if (ops->undo_action) {
+				snd_pcm_group_for_each(pos, substream) {
+					s1 = snd_pcm_group_substream_entry(pos);
+					if (s1 == s) /* failed stream */
+						break;
+					ops->undo_action(s1, state);
+				}
 			}
-			if (do_lock && s != substream)
-				spin_unlock(&s->self_group.lock);
+			s = NULL; /* unlock all */
+			goto _unlock;
 		}
-	} else if (do_lock) {
-		snd_pcm_substream_t *s1;
-		/* unlock all streams */
+	}
+	snd_pcm_group_for_each(pos, substream) {
+		s = snd_pcm_group_substream_entry(pos);
+		ops->post_action(s, state);
+	}
+ _unlock:
+	if (do_lock) {
+		/* unlock streams */
 		snd_pcm_group_for_each(pos, substream) {
 			s1 = snd_pcm_group_substream_entry(pos);
 			if (s1 != substream)
@@ -716,9 +722,10 @@
 	if (res < 0)
 		return res;
 	res = ops->do_action(substream, state);
-	if (res == 0) {
+	if (res == 0)
 		ops->post_action(substream, state);
-	}
+	else if (ops->undo_action)
+		ops->undo_action(substream, state);
 	return res;
 }
 
@@ -787,6 +794,9 @@
 	return res;
 }
 
+/*
+ * start callbacks
+ */
 static int snd_pcm_pre_start(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -803,14 +813,20 @@
 {
 	if (substream->runtime->trigger_master != substream)
 		return 0;
-        return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+	return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+}
+
+static void snd_pcm_undo_start(snd_pcm_substream_t *substream, int state)
+{
+	if (substream->runtime->trigger_master == substream)
+		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
 }
 
 static void snd_pcm_post_start(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_trigger_tstamp(substream);
-	runtime->status->state = SNDRV_PCM_STATE_RUNNING;
+	runtime->status->state = state;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 	    runtime->silence_size > 0)
 		snd_pcm_playback_silence(substream, ULONG_MAX);
@@ -823,22 +839,27 @@
 static struct action_ops snd_pcm_action_start = {
 	.pre_action = snd_pcm_pre_start,
 	.do_action = snd_pcm_do_start,
+	.undo_action = snd_pcm_undo_start,
 	.post_action = snd_pcm_post_start
 };
 
 /**
  * snd_pcm_start
+ *
+ * Start all linked streams.
  */
 int snd_pcm_start(snd_pcm_substream_t *substream)
 {
-	return snd_pcm_action(&snd_pcm_action_start, substream, 0);
+	return snd_pcm_action(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING);
 }
 
+/*
+ * stop callbacks
+ */
 static int snd_pcm_pre_stop(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	if (substream->runtime->status->state != SNDRV_PCM_STATE_RUNNING &&
-	    substream->runtime->status->state != SNDRV_PCM_STATE_DRAINING)
+	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
 	runtime->trigger_master = substream;
 	return 0;
@@ -846,19 +867,22 @@
 
 static int snd_pcm_do_stop(snd_pcm_substream_t *substream, int state)
 {
-	if (substream->runtime->trigger_master != substream)
-		return 0;
-	return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
+	if (substream->runtime->trigger_master == substream &&
+	    snd_pcm_running(substream))
+		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
+	return 0; /* unconditonally stop all substreams */
 }
 
 static void snd_pcm_post_stop(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_trigger_tstamp(substream);
-	if (substream->timer)
-		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, &runtime->trigger_tstamp);
-	runtime->status->state = state;
-	snd_pcm_tick_set(substream, 0);
+	if (runtime->status->state != state) {
+		snd_pcm_trigger_tstamp(substream);
+		if (substream->timer)
+			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, &runtime->trigger_tstamp);
+		runtime->status->state = state;
+		snd_pcm_tick_set(substream, 0);
+	}
 	wake_up(&runtime->sleep);
 }
 
@@ -870,12 +894,30 @@
 
 /**
  * snd_pcm_stop
+ *
+ * Try to stop all running streams in the substream group.
+ * The state of each stream is changed to the given value after that unconditionally.
  */
 int snd_pcm_stop(snd_pcm_substream_t *substream, int state)
 {
 	return snd_pcm_action(&snd_pcm_action_stop, substream, state);
 }
 
+/**
+ * snd_pcm_drain_done
+ *
+ * Stop the DMA only when the given stream is playback.
+ * The state is changed to SETUP.
+ * Unlike snd_pcm_stop(), this affects only the given stream.
+ */
+int snd_pcm_drain_done(snd_pcm_substream_t *substream)
+{
+	return snd_pcm_action_single(&snd_pcm_action_stop, substream, SNDRV_PCM_STATE_SETUP);
+}
+
+/*
+ * pause callbacks
+ */
 static int snd_pcm_pre_pause(snd_pcm_substream_t *substream, int push)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -899,6 +941,14 @@
 					      SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
 }
 
+static void snd_pcm_undo_pause(snd_pcm_substream_t *substream, int push)
+{
+	if (substream->runtime->trigger_master == substream)
+		substream->ops->trigger(substream,
+					push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
+					SNDRV_PCM_TRIGGER_PAUSE_PUSH);
+}
+
 static void snd_pcm_post_pause(snd_pcm_substream_t *substream, int push)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -921,9 +971,13 @@
 static struct action_ops snd_pcm_action_pause = {
 	.pre_action = snd_pcm_pre_pause,
 	.do_action = snd_pcm_do_pause,
+	.undo_action = snd_pcm_undo_pause,
 	.post_action = snd_pcm_post_pause
 };
 
+/*
+ * Push/release the pause for all linked streams.
+ */
 static int snd_pcm_pause(snd_pcm_substream_t *substream, int push)
 {
 	return snd_pcm_action(&snd_pcm_action_pause, substream, push);
@@ -937,7 +991,6 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
 		return -EBUSY;
-	runtime->status->suspended_state = runtime->status->state;
 	runtime->trigger_master = substream;
 	return 0;
 }
@@ -947,10 +1000,10 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	if (runtime->trigger_master != substream)
 		return 0;
-	if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING &&
-	    runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING)
+	if (! snd_pcm_running(substream))
 		return 0;
-	return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
+	substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
+	return 0; /* suspend unconditionally */
 }
 
 static void snd_pcm_post_suspend(snd_pcm_substream_t *substream, int state)
@@ -959,6 +1012,7 @@
 	snd_pcm_trigger_tstamp(substream);
 	if (substream->timer)
 		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, &runtime->trigger_tstamp);
+	runtime->status->suspended_state = runtime->status->state;
 	runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
 	snd_pcm_tick_set(substream, 0);
 	wake_up(&runtime->sleep);
@@ -972,6 +1026,9 @@
 
 /**
  * snd_pcm_suspend
+ *
+ * Trigger SUSPEND to all linked streams.
+ * After this call, all streams are changed to SUSPENDED state.
  */
 int snd_pcm_suspend(snd_pcm_substream_t *substream)
 {
@@ -980,11 +1037,14 @@
 
 /**
  * snd_pcm_suspend_all
+ *
+ * Trigger SUSPEND to all substreams in the given pcm.
+ * After this call, all streams are changed to SUSPENDED state.
  */
 int snd_pcm_suspend_all(snd_pcm_t *pcm)
 {
 	snd_pcm_substream_t *substream;
-	int stream, err;
+	int stream, err = 0;
 
 	for (stream = 0; stream < 2; stream++) {
 		for (substream = pcm->streams[stream].substream; substream; substream = substream->next) {
@@ -992,15 +1052,11 @@
 			if (substream->runtime == NULL)
 				continue;
 			snd_pcm_stream_lock(substream);
-			if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-				snd_pcm_stream_unlock(substream);
-				continue;
-			}
-			if ((err = snd_pcm_suspend(substream)) < 0) {
-				snd_pcm_stream_unlock(substream);
-				return err;
-			}
+			if (substream->runtime->status->state != SNDRV_PCM_STATE_SUSPENDED)
+				err = snd_pcm_suspend(substream);
 			snd_pcm_stream_unlock(substream);
+			if (err < 0)
+				return err;
 		}
 	}
 	return 0;
@@ -1022,12 +1078,21 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	if (runtime->trigger_master != substream)
 		return 0;
+	/* DMA not running previously? */
 	if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING &&
-	    runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING)
+	    (runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING ||
+	     substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
 		return 0;
 	return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
 }
 
+static void snd_pcm_undo_resume(snd_pcm_substream_t *substream, int state)
+{
+	if (substream->runtime->trigger_master == substream &&
+	    snd_pcm_running(substream))
+		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
+}
+
 static void snd_pcm_post_resume(snd_pcm_substream_t *substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1042,6 +1107,7 @@
 static struct action_ops snd_pcm_action_resume = {
 	.pre_action = snd_pcm_pre_resume,
 	.do_action = snd_pcm_do_resume,
+	.undo_action = snd_pcm_undo_resume,
 	.post_action = snd_pcm_post_resume
 };
 
@@ -1066,6 +1132,11 @@
 
 #endif /* CONFIG_PM */
 
+/*
+ * xrun ioctl
+ *
+ * Change the RUNNING stream(s) to XRUN state.
+ */
 static int snd_pcm_xrun(snd_pcm_substream_t *substream)
 {
 	snd_card_t *card = substream->pcm->card;
@@ -1073,8 +1144,13 @@
 	int result;
 
 	snd_power_lock(card);
+	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+		result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
+		if (result < 0)
+			goto _unlock;
+	}
+
 	snd_pcm_stream_lock_irq(substream);
-       _xrun_recovery:
 	switch (runtime->status->state) {
 	case SNDRV_PCM_STATE_XRUN:
 		result = 0;	/* already there */
@@ -1082,21 +1158,18 @@
 	case SNDRV_PCM_STATE_RUNNING:
 		result = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
 		break;
-	case SNDRV_PCM_STATE_SUSPENDED:
-		snd_pcm_stream_unlock_irq(substream);
-		result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
-		snd_pcm_stream_lock_irq(substream);
-		if (result >= 0)
-			goto _xrun_recovery;
-		break;
 	default:
 		result = -EBADFD;
 	}
 	snd_pcm_stream_unlock_irq(substream);
+ _unlock:
 	snd_power_unlock(card);
 	return result;
 }
 
+/*
+ * reset ioctl
+ */
 static int snd_pcm_pre_reset(snd_pcm_substream_t * substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1145,17 +1218,17 @@
 	return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
 }
 
+/*
+ * prepare ioctl
+ */
 static int snd_pcm_pre_prepare(snd_pcm_substream_t * substream, int state)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	switch (runtime->status->state) {
-	case SNDRV_PCM_STATE_OPEN:
+	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
-	case SNDRV_PCM_STATE_RUNNING:
+	if (snd_pcm_running(substream))
 		return -EBUSY;
-	default:
-		return 0;
-	}
+	return 0;
 }
 
 static int snd_pcm_do_prepare(snd_pcm_substream_t * substream, int state)
@@ -1195,111 +1268,147 @@
 	return res;
 }
 
-static void snd_pcm_change_state(snd_pcm_substream_t *substream, int state)
+/*
+ * drain ioctl
+ */
+
+static int snd_pcm_pre_drain_init(snd_pcm_substream_t * substream, int state)
 {
-	struct list_head *pos;
-	snd_pcm_substream_t *s;
+	if (substream->ffile->f_flags & O_NONBLOCK)
+		return -EAGAIN;
+	substream->runtime->trigger_master = substream;
+	return 0;
+}
 
-	if (snd_pcm_stream_linked(substream)) {
-		if (!spin_trylock(&substream->group->lock)) {
-			spin_unlock(&substream->self_group.lock);
-			spin_lock(&substream->group->lock);
-			spin_lock(&substream->self_group.lock);
-		}
-		snd_pcm_group_for_each(pos, substream) {
-			s = snd_pcm_group_substream_entry(pos);
-			if (s != substream)
-				spin_lock(&s->self_group.lock);
-			s->runtime->status->state = state;
-			if (s != substream)
-				spin_unlock(&s->self_group.lock);
+static int snd_pcm_do_drain_init(snd_pcm_substream_t * substream, int state)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		switch (runtime->status->state) {
+		case SNDRV_PCM_STATE_PREPARED:
+			/* start playback stream if possible */
+			if (! snd_pcm_playback_empty(substream)) {
+				snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
+				snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
+			}
+			break;
+		case SNDRV_PCM_STATE_RUNNING:
+			runtime->status->state = SNDRV_PCM_STATE_DRAINING;
+			break;
+		default:
+			break;
 		}
-		spin_unlock(&substream->group->lock);
 	} else {
-		substream->runtime->status->state = state;
+		/* stop running stream */
+		if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
+			int state = snd_pcm_capture_avail(runtime) > 0 ?
+				SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
+			snd_pcm_do_stop(substream, state);
+			snd_pcm_post_stop(substream, state);
+		}
 	}
+	return 0;
+}
+
+static void snd_pcm_post_drain_init(snd_pcm_substream_t * substream, int state)
+{
 }
 
-static int snd_pcm_playback_drop(snd_pcm_substream_t *substream);
+static struct action_ops snd_pcm_action_drain_init = {
+	.pre_action = snd_pcm_pre_drain_init,
+	.do_action = snd_pcm_do_drain_init,
+	.post_action = snd_pcm_post_drain_init
+};
 
-static int snd_pcm_playback_drain(snd_pcm_substream_t * substream)
+struct drain_rec {
+	snd_pcm_substream_t *substream;
+	wait_queue_t wait;
+	snd_pcm_uframes_t stop_threshold;
+};
+
+static int snd_pcm_drop(snd_pcm_substream_t *substream);
+
+/*
+ * Drain the stream(s).
+ * When the substream is linked, sync until the draining of all playback streams
+ * is finished.
+ * After this call, all streams are supposed to be either SETUP or DRAINING
+ * (capture only) state.
+ */
+static int snd_pcm_drain(snd_pcm_substream_t *substream)
 {
 	snd_card_t *card;
 	snd_pcm_runtime_t *runtime;
-	int err, result = 0;
-	wait_queue_t wait;
-	enum { READY, EXPIRED, SUSPENDED, SIGNALED } state = READY;
-	snd_pcm_uframes_t stop_threshold;
+	struct list_head *pos;
+	int result = 0;
+	int i, num_drecs;
+	struct drain_rec *drec, drec_tmp, *d;
 
 	snd_assert(substream != NULL, return -ENXIO);
-	snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL);
-	runtime = substream->runtime;
 	card = substream->pcm->card;
+	runtime = substream->runtime;
 
+	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+		return -EBADFD;
+
+	down_read(&snd_pcm_link_rwsem);
 	snd_power_lock(card);
-	snd_pcm_stream_lock_irq(substream);
+	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+		result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
+		if (result < 0)
+			goto _unlock;
+	}
 
-	/* stop_threshold fixup to avoid endless loop when */
-	/* stop_threshold > buffer_size */
-	stop_threshold = runtime->stop_threshold;
-	if (runtime->stop_threshold > runtime->buffer_size)
-		runtime->stop_threshold = runtime->buffer_size;
+	/* allocate temporary record for drain sync */
+	if (snd_pcm_stream_linked(substream)) {
+		drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL);
+		if (! drec) {
+			result = -ENOMEM;
+			goto _unlock;
+		}
+	} else
+		drec = &drec_tmp;
 
-	switch (runtime->status->state) {
-	case SNDRV_PCM_STATE_PAUSED:
+	snd_pcm_stream_lock_irq(substream);
+	/* resume pause */
+	if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
 		snd_pcm_pause(substream, 0);
-		/* Fall through */
-	case SNDRV_PCM_STATE_RUNNING:
-	case SNDRV_PCM_STATE_DRAINING:
-		break;
-	case SNDRV_PCM_STATE_SUSPENDED:
-		snd_pcm_stream_unlock_irq(substream);
-		result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
-		snd_pcm_stream_lock_irq(substream);
-		if (result >= 0)
-			snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
-		goto _end;
-	case SNDRV_PCM_STATE_OPEN:
-		result = -EBADFD;
-		goto _end;
-	case SNDRV_PCM_STATE_PREPARED:
-		if (!snd_pcm_playback_empty(substream)) {
-			err = snd_pcm_start(substream);
-			if (err < 0) {
-				result = err;
-				goto _end;
-			}
-			break;
-		}
-		/* Fall through */
-	case SNDRV_PCM_STATE_XRUN:
-		snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
-		/* Fall through */
-	case SNDRV_PCM_STATE_SETUP:
+
+	/* pre-start/stop - all running streams are changed to DRAINING state */
+	result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
+	if (result < 0)
 		goto _end;
-	default: 
-		break; 
-	}
 
-	if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
-		if (snd_pcm_playback_empty(substream)) {
-			snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
-			goto _end;
+	/* check streams with PLAYBACK & DRAINING */
+	num_drecs = 0;
+	snd_pcm_group_for_each(pos, substream) {
+		snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos);
+		runtime = s->runtime;
+		if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) {
+			runtime->status->state = SNDRV_PCM_STATE_SETUP;
+			continue;
+		}
+		if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			d = &drec[num_drecs++];
+			d->substream = s;
+			init_waitqueue_entry(&d->wait, current);
+			add_wait_queue(&runtime->sleep, &d->wait);
+			/* stop_threshold fixup to avoid endless loop when
+			 * stop_threshold > buffer_size
+			 */
+			d->stop_threshold = runtime->stop_threshold;
+			if (runtime->stop_threshold > runtime->buffer_size)
+				runtime->stop_threshold = runtime->buffer_size;
 		}
-		snd_pcm_change_state(substream, SNDRV_PCM_STATE_DRAINING);
 	}
 
-	if (substream->ffile->f_flags & O_NONBLOCK) {
-		result = -EAGAIN;
+	if (! num_drecs)
 		goto _end;
-	}
 
-	init_waitqueue_entry(&wait, current);
-	add_wait_queue(&runtime->sleep, &wait);
-	while (1) {
+	for (;;) {
 		long tout;
 		if (signal_pending(current)) {
-			state = SIGNALED;
+			result = -ERESTARTSYS;
 			break;
 		}
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -1309,177 +1418,81 @@
 		snd_power_lock(card);
 		snd_pcm_stream_lock_irq(substream);
 		if (tout == 0) {
-			state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
+			if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
+				result = -ESTRPIPE;
+			else {
+				snd_printd("playback drain error (DMA or IRQ trouble?)\n");
+				snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
+				result = -EIO;
+			}
 			break;
 		}
-		if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) {
-			state = READY;
-			break;
+		/* all finished? */
+		for (i = 0; i < num_drecs; i++) {
+			runtime = drec[i].substream->runtime;
+			if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
+				break;
 		}
+		if (i == num_drecs)
+			break;
 	}
-	remove_wait_queue(&runtime->sleep, &wait);
-
-	switch (state) {
-	case SIGNALED:
-		result = -ERESTARTSYS;
-		goto _end;
-	case SUSPENDED:
-		result = -ESTRPIPE;
-		goto _end;
-	case EXPIRED:
-		snd_printd("playback drain error (DMA or IRQ trouble?)\n");
-		result = -EIO;
-		goto _end;
-	default:
-		break;
+	for (i = 0; i < num_drecs; i++) {
+		d = &drec[i];
+		runtime = d->substream->runtime;
+		remove_wait_queue(&runtime->sleep, &d->wait);
+		runtime->stop_threshold = d->stop_threshold;
 	}
 
-      _end:
-	runtime->stop_threshold = stop_threshold;
+ _end:
 	snd_pcm_stream_unlock_irq(substream);
+	if (drec && drec != &drec_tmp)
+		kfree(drec);
+ _unlock:
 	snd_power_unlock(card);
-	if (state == EXPIRED)
-		snd_pcm_playback_drop(substream);
+	up_read(&snd_pcm_link_rwsem);
 
 	return result;
 }
 
-static int snd_pcm_playback_drop(snd_pcm_substream_t *substream)
+/*
+ * drop ioctl
+ *
+ * Immediately put all linked substreams into SETUP state.
+ */
+static int snd_pcm_drop(snd_pcm_substream_t *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_t *card = substream->pcm->card;
-	int res = 0;
+	snd_pcm_runtime_t *runtime;
+	snd_card_t *card;
+	int result = 0;
 	
-	snd_power_lock(card);
-	snd_pcm_stream_lock_irq(substream);
-	switch (runtime->status->state) {
-	case SNDRV_PCM_STATE_OPEN:
-		res = -EBADFD;
-		break;
-	case SNDRV_PCM_STATE_SETUP:
-		break;
-	case SNDRV_PCM_STATE_PAUSED:
-		snd_pcm_pause(substream, 0);
-		/* Fall through */
-	case SNDRV_PCM_STATE_RUNNING:
-	case SNDRV_PCM_STATE_DRAINING:
-		if (snd_pcm_update_hw_ptr(substream) >= 0) {
-			snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
-			break;
-		}
-		/* Fall through */
-	case SNDRV_PCM_STATE_PREPARED:
-	case SNDRV_PCM_STATE_XRUN:
-		snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
-		break;
-	case SNDRV_PCM_STATE_SUSPENDED:
-		snd_pcm_stream_unlock_irq(substream);
-		res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
-		snd_pcm_stream_lock_irq(substream);
-		if (res >= 0)
-			snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
-		break;
-	default:
-		break; 
-	}
-	runtime->control->appl_ptr = runtime->status->hw_ptr;
-	snd_pcm_stream_unlock_irq(substream);
-	snd_power_unlock(card);
-	return res;
-}
+	snd_assert(substream != NULL, return -ENXIO);
+	runtime = substream->runtime;
+	card = substream->pcm->card;
 
-static int snd_pcm_capture_drain(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_t *card = substream->pcm->card;
-	int res = 0;
+	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+		return -EBADFD;
 
 	snd_power_lock(card);
-	snd_pcm_stream_lock_irq(substream);
-	switch (runtime->status->state) {
-	case SNDRV_PCM_STATE_OPEN:
-		res = -EBADFD;
-		break;
-	case SNDRV_PCM_STATE_PREPARED:
-		snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
-		break;
-	case SNDRV_PCM_STATE_SETUP:
-	case SNDRV_PCM_STATE_DRAINING:
-		break;
-	case SNDRV_PCM_STATE_PAUSED:
-		snd_pcm_pause(substream, 0);
-		/* Fall through */
-	case SNDRV_PCM_STATE_RUNNING:
-		if (snd_pcm_update_hw_ptr(substream) >= 0) {
-			snd_pcm_stop(substream, 
-				     snd_pcm_capture_avail(runtime) > 0 ?
-				     SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP);
-			break;
-		}
-		/* Fall through */
-	case SNDRV_PCM_STATE_XRUN:
-	       _xrun_recovery:
-		snd_pcm_change_state(substream, 
-				     snd_pcm_capture_avail(runtime) > 0 ?
-				     SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP);
-		break;
-	case SNDRV_PCM_STATE_SUSPENDED:
-		snd_pcm_stream_unlock_irq(substream);
-		res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
-		snd_pcm_stream_lock_irq(substream);
-		if (res >= 0)
-			goto _xrun_recovery;
-		break;
-	default: 
-		break; 
+	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
+		result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
+		if (result < 0)
+			goto _unlock;
 	}
-	snd_pcm_stream_unlock_irq(substream);
-	snd_power_unlock(card);
-	return res;
-}
 
-static int snd_pcm_capture_drop(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_t *card = substream->pcm->card;
-	int res = 0;
-
-	snd_power_lock(card);
 	snd_pcm_stream_lock_irq(substream);
-	switch (runtime->status->state) {
-	case SNDRV_PCM_STATE_OPEN:
-		res = -EBADFD;
-		break;
-	case SNDRV_PCM_STATE_SETUP:
-		break;
-	case SNDRV_PCM_STATE_PAUSED:
+	/* resume pause */
+	if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
 		snd_pcm_pause(substream, 0);
-		/* Fall through */
-	case SNDRV_PCM_STATE_RUNNING:
-		snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
-		break;
-	case SNDRV_PCM_STATE_SUSPENDED:
-		snd_pcm_stream_unlock_irq(substream);
-		res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
-		snd_pcm_stream_lock_irq(substream);
-		if (res < 0)
-			goto _end;
-		/* Fall through */
-	case SNDRV_PCM_STATE_PREPARED:
-	case SNDRV_PCM_STATE_DRAINING:
-	case SNDRV_PCM_STATE_XRUN:
-		snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
-		break;
-	default: 
-		break; 
-	}
-	runtime->control->appl_ptr = runtime->status->hw_ptr;
-       _end:
+
+	snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
+	/* runtime->control->appl_ptr = runtime->status->hw_ptr; */
 	snd_pcm_stream_unlock_irq(substream);
+ _unlock:
 	snd_power_unlock(card);
-	return res;
+	return result;
 }
 
+
 /* WARNING: Don't forget to fput back the file */
 extern int snd_major;
 static struct file *snd_pcm_file_fd(int fd)
@@ -1505,6 +1518,9 @@
 	return file;
 }
 
+/*
+ * PCM link handling
+ */
 static int snd_pcm_link(snd_pcm_substream_t *substream, int fd)
 {
 	int res = 0;
@@ -1512,12 +1528,6 @@
 	snd_pcm_file_t *pcm_file;
 	snd_pcm_substream_t *substream1;
 
-	snd_pcm_stream_lock_irq(substream);
-	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
-		snd_pcm_stream_unlock_irq(substream);
-		return -EBADFD;
-	}
-	snd_pcm_stream_unlock_irq(substream);
 	file = snd_pcm_file_fd(fd);
 	if (!file)
 		return -EBADFD;
@@ -1525,7 +1535,8 @@
 	substream1 = pcm_file->substream;
 	down_write(&snd_pcm_link_rwsem);
 	write_lock_irq(&snd_pcm_link_rwlock);
-	if (substream->runtime->status->state != substream1->runtime->status->state) {
+	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
+	    substream->runtime->status->state != substream1->runtime->status->state) {
 		res = -EBADFD;
 		goto _end;
 	}
@@ -1542,8 +1553,10 @@
 		spin_lock_init(&substream->group->lock);
 		INIT_LIST_HEAD(&substream->group->substreams);
 		list_add_tail(&substream->link_list, &substream->group->substreams);
+		substream->group->count = 1;
 	}
 	list_add_tail(&substream1->link_list, &substream->group->substreams);
+	substream->group->count++;
 	substream1->group = substream->group;
  _end:
 	write_unlock_irq(&snd_pcm_link_rwlock);
@@ -1562,7 +1575,7 @@
 static int snd_pcm_unlink(snd_pcm_substream_t *substream)
 {
 	struct list_head *pos;
-	int res = 0, count = 0;
+	int res = 0;
 
 	down_write(&snd_pcm_link_rwsem);
 	write_lock_irq(&snd_pcm_link_rwlock);
@@ -1571,11 +1584,8 @@
 		goto _end;
 	}
 	list_del(&substream->link_list);
-	snd_pcm_group_for_each(pos, substream) {
-		if (++count > 1)
-			break;
-	}
-	if (count == 1) {	/* detach the last stream, too */
+	substream->group->count--;
+	if (substream->group->count == 1) {	/* detach the last stream, too */
 		snd_pcm_group_for_each(pos, substream) {
 			relink_to_local(snd_pcm_group_substream_entry(pos));
 			break;
@@ -1589,6 +1599,9 @@
 	return res;
 }
 
+/*
+ * hw configurator
+ */
 static int snd_pcm_hw_rule_mul(snd_pcm_hw_params_t *params,
 			       snd_pcm_hw_rule_t *rule)
 {
@@ -1973,6 +1986,7 @@
 
 	str = substream->pstr;
 	substream->file = pcm_file;
+	substream->no_mmap_ctrl = 0;
 
 	pcm_file->substream = substream;
 
@@ -2076,10 +2090,7 @@
 	snd_assert(substream != NULL, return -ENXIO);
 	snd_assert(!atomic_read(&substream->runtime->mmap_count), );
 	pcm = substream->pcm;
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		snd_pcm_playback_drop(substream);
-	else
-		snd_pcm_capture_drop(substream);
+	snd_pcm_drop(substream);
 	fasync_helper(-1, file, 0, &substream->runtime->fasync);
 	down(&pcm->open_mutex);
 	snd_pcm_release_file(pcm_file);
@@ -2435,7 +2446,7 @@
 	case SNDRV_PCM_IOCTL_RESET:
 		return snd_pcm_reset(substream);
 	case SNDRV_PCM_IOCTL_START:
-		return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, 0);
+		return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING);
 	case SNDRV_PCM_IOCTL_LINK:
 		return snd_pcm_link(substream, (int)(unsigned long) arg);
 	case SNDRV_PCM_IOCTL_UNLINK:
@@ -2454,6 +2465,10 @@
 		return snd_pcm_hw_refine_old_user(substream, arg);
 	case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
 		return snd_pcm_hw_params_old_user(substream, arg);
+	case SNDRV_PCM_IOCTL_DRAIN:
+		return snd_pcm_drain(substream);
+	case SNDRV_PCM_IOCTL_DROP:
+		return snd_pcm_drop(substream);
 	}
 	snd_printd("unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
@@ -2542,10 +2557,6 @@
 		snd_pcm_stream_unlock_irq(substream);
 		return res;
 	}
-	case SNDRV_PCM_IOCTL_DRAIN:
-		return snd_pcm_playback_drain(substream);
-	case SNDRV_PCM_IOCTL_DROP:
-		return snd_pcm_playback_drop(substream);
 	}
 	return snd_pcm_common_ioctl1(substream, cmd, arg);
 }
@@ -2625,10 +2636,6 @@
 		__put_user(result, _frames);
 		return result < 0 ? result : 0;
 	}
-	case SNDRV_PCM_IOCTL_DRAIN:
-		return snd_pcm_capture_drain(substream);
-	case SNDRV_PCM_IOCTL_DROP:
-		return snd_pcm_capture_drop(substream);
 	}
 	return snd_pcm_common_ioctl1(substream, cmd, arg);
 }
@@ -3158,8 +3165,12 @@
 	offset = area->vm_pgoff << PAGE_SHIFT;
 	switch (offset) {
 	case SNDRV_PCM_MMAP_OFFSET_STATUS:
+		if (substream->no_mmap_ctrl)
+			return -ENXIO;
 		return snd_pcm_mmap_status(substream, file, area);
 	case SNDRV_PCM_MMAP_OFFSET_CONTROL:
+		if (substream->no_mmap_ctrl)
+			return -ENXIO;
 		return snd_pcm_mmap_control(substream, file, area);
 	default:
 		return snd_pcm_mmap_data(substream, file, area);
diff -Nru a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
--- a/sound/core/seq/oss/seq_oss.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/seq/oss/seq_oss.c	2004-10-21 14:13:16 -07:00
@@ -78,16 +78,17 @@
 		snd_seq_oss_synth_unregister,
 	};
 
+	snd_seq_autoload_lock();
 	if ((rc = register_device()) < 0)
-		return rc;
+		goto error;
 	if ((rc = register_proc()) < 0) {
 		unregister_device();
-		return rc;
+		goto error;
 	}
 	if ((rc = snd_seq_oss_create_client()) < 0) {
 		unregister_proc();
 		unregister_device();
-		return rc;
+		goto error;
 	}
 
 	if ((rc = snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OSS, &ops,
@@ -95,12 +96,15 @@
 		snd_seq_oss_delete_client();
 		unregister_proc();
 		unregister_device();
-		return rc;
+		goto error;
 	}
 
 	/* success */
 	snd_seq_oss_synth_init();
-	return 0;
+
+ error:
+	snd_seq_autoload_unlock();
+	return rc;
 }
 
 static void __exit alsa_seq_oss_exit(void)
diff -Nru a/sound/core/seq/seq.c b/sound/core/seq/seq.c
--- a/sound/core/seq/seq.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/seq/seq.c	2004-10-21 14:13:16 -07:00
@@ -70,35 +70,37 @@
  *  INIT PART
  */
 
-
 static int __init alsa_seq_init(void)
 {
 	int err;
 
+	snd_seq_autoload_lock();
 	if ((err = client_init_data()) < 0)
-		return err;
+		goto error;
 
 	/* init memory, room for selected events */
 	if ((err = snd_sequencer_memory_init()) < 0)
-		return err;
+		goto error;
 
 	/* init event queues */
 	if ((err = snd_seq_queues_init()) < 0)
-		return err;
+		goto error;
 
 	/* register sequencer device */
 	if ((err = snd_sequencer_device_init()) < 0)
-		return err;
+		goto error;
 
 	/* register proc interface */
 	if ((err = snd_seq_info_init()) < 0)
-		return err;
+		goto error;
 
 	/* register our internal client */
 	if ((err = snd_seq_system_client_init()) < 0)
-		return err;
+		goto error;
 
-	return 0;
+ error:
+	snd_seq_autoload_unlock();
+	return err;
 }
 
 static void __exit alsa_seq_exit(void)
diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
--- a/sound/core/seq/seq_clientmgr.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/seq/seq_clientmgr.c	2004-10-21 14:13:16 -07:00
@@ -420,7 +420,10 @@
 			count -= err;
 			buf += err;
 		} else {
-			copy_to_user(buf, &cell->event, sizeof(snd_seq_event_t));
+			if (copy_to_user(buf, &cell->event, sizeof(snd_seq_event_t))) {
+				err = -EFAULT;
+				break;
+			}
 			count -= sizeof(snd_seq_event_t);
 			buf += sizeof(snd_seq_event_t);
 		}
diff -Nru a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
--- a/sound/core/seq/seq_device.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/seq/seq_device.c	2004-10-21 14:13:16 -07:00
@@ -41,6 +41,7 @@
 #include <sound/core.h>
 #include <sound/info.h>
 #include <sound/seq_device.h>
+#include <sound/seq_kernel.h>
 #include <sound/initval.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
@@ -125,11 +126,31 @@
  * load all registered drivers (called from seq_clientmgr.c)
  */
 
+#ifdef CONFIG_KMOD
+/* avoid auto-loading during module_init() */
+static int snd_seq_in_init;
+void snd_seq_autoload_lock(void)
+{
+	snd_seq_in_init++;
+}
+
+void snd_seq_autoload_unlock(void)
+{
+	snd_seq_in_init--;
+}
+#endif
+
 void snd_seq_device_load_drivers(void)
 {
 #ifdef CONFIG_KMOD
 	struct list_head *head;
 
+	/* Calling request_module during module_init()
+	 * may cause blocking.
+	 */
+	if (snd_seq_in_init)
+		return;
+
 	if (! current->fs->root)
 		return;
 
@@ -309,12 +330,16 @@
 	    entry->init_device == NULL || entry->free_device == NULL)
 		return -EINVAL;
 
+	snd_seq_autoload_lock();
 	ops = find_driver(id, 1);
-	if (ops == NULL)
+	if (ops == NULL) {
+		snd_seq_autoload_unlock();
 		return -ENOMEM;
+	}
 	if (ops->driver & DRIVER_LOADED) {
 		snd_printk(KERN_WARNING "driver_register: driver '%s' already exists\n", id);
 		unlock_driver(ops);
+		snd_seq_autoload_unlock();
 		return -EBUSY;
 	}
 
@@ -332,6 +357,7 @@
 	up(&ops->reg_mutex);
 
 	unlock_driver(ops);
+	snd_seq_autoload_unlock();
 
 	return 0;
 }
@@ -543,3 +569,7 @@
 EXPORT_SYMBOL(snd_seq_device_new);
 EXPORT_SYMBOL(snd_seq_device_register_driver);
 EXPORT_SYMBOL(snd_seq_device_unregister_driver);
+#ifdef CONFIG_KMOD
+EXPORT_SYMBOL(snd_seq_autoload_lock);
+EXPORT_SYMBOL(snd_seq_autoload_unlock);
+#endif
diff -Nru a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
--- a/sound/core/seq/seq_dummy.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/seq/seq_dummy.c	2004-10-21 14:13:16 -07:00
@@ -256,7 +256,11 @@
 
 static int __init alsa_seq_dummy_init(void)
 {
-	return register_client();
+	int err;
+	snd_seq_autoload_lock();
+	err = register_client();
+	snd_seq_autoload_unlock();
+	return err;
 }
 
 static void __exit alsa_seq_dummy_exit(void)
diff -Nru a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
--- a/sound/core/seq/seq_midi.c	2004-10-21 14:13:16 -07:00
+++ b/sound/core/seq/seq_midi.c	2004-10-21 14:13:16 -07:00
@@ -279,7 +279,7 @@
 	cinfo.client = client->seq_client;
 	cinfo.type = KERNEL_CLIENT;
 	name = rmidi->name[0] ? (const char *)rmidi->name : "External MIDI";
-	snprintf(cinfo.name, sizeof(cinfo.name), "%s - Rawmidi %d", name, card->number);
+	strlcpy(cinfo.name, name, sizeof(cinfo.name));
 	return snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
 }
 
@@ -464,7 +464,9 @@
 		snd_seq_midisynth_unregister_port,
 	};
 	memset(&synths, 0, sizeof(synths));
+	snd_seq_autoload_lock();
 	snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_MIDISYNTH, &ops, 0);
+	snd_seq_autoload_unlock();
 	return 0;
 }
 
diff -Nru a/sound/drivers/Kconfig b/sound/drivers/Kconfig
--- a/sound/drivers/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/drivers/Kconfig	2004-10-21 14:13:16 -07:00
@@ -30,8 +30,14 @@
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include dummy driver. This driver does nothing, but
-	  emulates various mixer controls and PCM devices.
+	  Say Y here to include the dummy driver.  This driver does
+	  nothing, but emulates various mixer controls and PCM devices.
+
+	  You don't need this unless you're testing the hardware support
+	  of programs using the ALSA API.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-dummy.
 
 config SND_VIRMIDI
 	tristate "Virtual MIDI soundcard"
@@ -39,8 +45,14 @@
 	select SND_TIMER
 	select SND_RAWMIDI
 	help
-	  Say 'Y' or 'M' to include virtual MIDI driver. This driver allows to
-	  connect applications using raw MIDI devices to sequencer.
+	  Say Y here to include the virtual MIDI driver.  This driver
+	  allows to connect applications using raw MIDI devices to
+	  sequencer clients.
+
+	  If you don't know what MIDI is, say N here.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-virmidi.
 
 config SND_MTPAV
 	tristate "MOTU MidiTimePiece AV multiport MIDI"
@@ -48,23 +60,39 @@
 	select SND_TIMER
 	select SND_RAWMIDI
 	help
-	  Say 'Y' or 'M' to include support for MOTU MidiTimePiece AV multiport
-	  MIDI adapter.
+	  To use a MOTU MidiTimePiece AV multiport MIDI adapter
+	  connected to the parallel port, say Y here and make sure that
+	  the standard parallel port driver isn't used for the port.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-mtpav.
 
 config SND_SERIAL_U16550
-	tristate "UART16550 - MIDI only driver"
+	tristate "UART16550 serial MIDI driver"
 	depends on SND
 	select SND_TIMER
 	select SND_RAWMIDI
 	help
-	  Say 'Y' or 'M' to include support for MIDI serial port driver. It works
-	  with serial UARTs 16550 and better.
+	  To include support for MIDI serial port interfaces, say Y here
+	  and read <file:Documentation/sound/alsa/serial-u16550.txt>.
+	  This driver works with serial UARTs 16550 and better.
+
+	  This driver accesses the serial port hardware directly, so
+	  make sure that the standard serial driver isn't used or
+	  deactivated with setserial before loading this driver.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-serial-u16550.
 
 config SND_MPU401
 	tristate "Generic MPU-401 UART driver"
 	depends on SND
 	select SND_MPU401_UART
 	help
-	  Say 'Y' or 'M' to include support for MPU401 hardware using UART access.
+	  Say Y here to include support for MIDI ports compatible with
+	  the Roland MPU-401 interface in UART mode.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-mpu401.
 
 endmenu
diff -Nru a/sound/drivers/dummy.c b/sound/drivers/dummy.c
--- a/sound/drivers/dummy.c	2004-10-21 14:13:16 -07:00
+++ b/sound/drivers/dummy.c	2004-10-21 14:13:16 -07:00
@@ -556,7 +556,7 @@
 DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_MASTER)
 };
 
-int __init snd_card_dummy_new_mixer(snd_card_dummy_t * dummy)
+static int __init snd_card_dummy_new_mixer(snd_card_dummy_t * dummy)
 {
 	snd_card_t *card = dummy->card;
 	unsigned int idx;
diff -Nru a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
--- a/sound/drivers/mpu401/mpu401_uart.c	2004-10-21 14:13:16 -07:00
+++ b/sound/drivers/mpu401/mpu401_uart.c	2004-10-21 14:13:16 -07:00
@@ -70,12 +70,12 @@
 
 static void mpu401_write_mmio(mpu401_t *mpu, unsigned char data, unsigned long addr)
 {
-	writeb(data, (unsigned long*)addr);
+	writeb(data, (void __iomem *)addr);
 }
 
 static unsigned char mpu401_read_mmio(mpu401_t *mpu, unsigned long addr)
 {
-	return readb((unsigned long*)addr);
+	return readb((void __iomem *)addr);
 }
 /*  */
 
diff -Nru a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
--- a/sound/drivers/opl3/opl3_lib.c	2004-10-21 14:13:16 -07:00
+++ b/sound/drivers/opl3/opl3_lib.c	2004-10-21 14:13:16 -07:00
@@ -85,28 +85,6 @@
 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
 }
 
-void snd_opl3_cs4281_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
-{
-	unsigned long flags;
-	unsigned long port;
-
-	/*
-	 * CS4281 requires a special access to I/O registers
-	 */
-
-	port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
-
-	spin_lock_irqsave(&opl3->reg_lock, flags);
-
-	writel((unsigned int)cmd, port << 2);
-	udelay(10);
-
-	writel((unsigned int)val, (port + 1) << 2);
-	udelay(30);
-
-	spin_unlock_irqrestore(&opl3->reg_lock, flags);
-}
-
 static int snd_opl3_detect(opl3_t * opl3)
 {
 	/*
@@ -344,6 +322,9 @@
 
 static int snd_opl3_free(opl3_t *opl3)
 {
+	snd_assert(opl3 != NULL, return -ENXIO);
+	if (opl3->private_free)
+		opl3->private_free(opl3);
 	if (opl3->res_l_port) {
 		release_resource(opl3->res_l_port);
 		kfree_nocheck(opl3->res_l_port);
@@ -362,51 +343,89 @@
 	return snd_opl3_free(opl3);
 }
 
-int snd_opl3_create(snd_card_t * card,
-		    unsigned long l_port,
-		    unsigned long r_port,
-		    unsigned short hardware,
-		    int integrated,
-		    opl3_t ** ropl3)
+int snd_opl3_new(snd_card_t *card,
+		 unsigned short hardware,
+		 opl3_t **ropl3)
 {
-	opl3_t *opl3;
-	int err;
 	static snd_device_ops_t ops = {
 		.dev_free = snd_opl3_dev_free,
 	};
+	opl3_t *opl3;
+	int err;
 
 	*ropl3 = NULL;
-
 	opl3 = kcalloc(1, sizeof(*opl3), GFP_KERNEL);
 	if (opl3 == NULL)
 		return -ENOMEM;
 
-	if (integrated)
-		goto __step1; /* ports are already reserved */
+	opl3->card = card;
+	opl3->hardware = hardware;
+	spin_lock_init(&opl3->reg_lock);
+	spin_lock_init(&opl3->timer_lock);
+	init_MUTEX(&opl3->access_mutex);
 
-	if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
-		snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, opl3, &ops)) < 0) {
 		snd_opl3_free(opl3);
-		return -EBUSY;
+		return err;
 	}
-	if (r_port != 0 &&
-	    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
-		snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
-		snd_opl3_free(opl3);
-		return -EBUSY;
+
+	*ropl3 = opl3;
+	return 0;
+}
+
+int snd_opl3_init(opl3_t *opl3)
+{
+	if (! opl3->command) {
+		printk(KERN_ERR "snd_opl3_init: command not defined!\n");
+		return -EINVAL;
 	}
 
-      __step1:
+	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
+	/* Melodic mode */
+	opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
 
-	opl3->card = card;
-	opl3->hardware = hardware;
+	switch (opl3->hardware & OPL3_HW_MASK) {
+	case OPL3_HW_OPL2:
+		opl3->max_voices = MAX_OPL2_VOICES;
+		break;
+	case OPL3_HW_OPL3:
+	case OPL3_HW_OPL4:
+		opl3->max_voices = MAX_OPL3_VOICES;
+		/* Enter OPL3 mode */
+		opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
+	}
+	return 0;
+}
+
+int snd_opl3_create(snd_card_t * card,
+		    unsigned long l_port,
+		    unsigned long r_port,
+		    unsigned short hardware,
+		    int integrated,
+		    opl3_t ** ropl3)
+{
+	opl3_t *opl3;
+	int err;
+
+	*ropl3 = NULL;
+	if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
+		return err;
+	if (! integrated) {
+		if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
+			snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
+			snd_opl3_free(opl3);
+			return -EBUSY;
+		}
+		if (r_port != 0 &&
+		    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
+			snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
+			snd_opl3_free(opl3);
+			return -EBUSY;
+		}
+	}
 	opl3->l_port = l_port;
 	opl3->r_port = r_port;
 
-	spin_lock_init(&opl3->reg_lock);
-	spin_lock_init(&opl3->timer_lock);
-	init_MUTEX(&opl3->access_mutex);
-
 	switch (opl3->hardware) {
 	/* some hardware doesn't support timers */
 	case OPL3_HW_OPL3_SV:
@@ -414,9 +433,6 @@
 	case OPL3_HW_OPL3_FM801:
 		opl3->command = &snd_opl3_command;
 		break;
-	case OPL3_HW_OPL3_CS4281:
-		opl3->command = &snd_opl3_cs4281_command;
-		break;
 	default:
 		opl3->command = &snd_opl2_command;
 		if ((err = snd_opl3_detect(opl3)) < 0) {
@@ -433,23 +449,7 @@
 		}
 	}
 
-	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
-	opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);	/* Melodic mode */
-
-	switch (opl3->hardware & OPL3_HW_MASK) {
-	case OPL3_HW_OPL2:
-		opl3->max_voices = MAX_OPL2_VOICES;
-		break;
-	case OPL3_HW_OPL3:
-	case OPL3_HW_OPL4:
-		opl3->max_voices = MAX_OPL3_VOICES;
-		snd_assert(opl3->r_port != 0, snd_opl3_free(opl3); return -ENODEV);
-		opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);	/* Enter OPL3 mode */
-	}
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, opl3, &ops)) < 0) {
-		snd_opl3_free(opl3);
-		return err;
-	}
+	snd_opl3_init(opl3);
 
 	*ropl3 = opl3;
 	return 0;
@@ -531,6 +531,8 @@
 }
 
 EXPORT_SYMBOL(snd_opl3_interrupt);
+EXPORT_SYMBOL(snd_opl3_new);
+EXPORT_SYMBOL(snd_opl3_init);
 EXPORT_SYMBOL(snd_opl3_create);
 EXPORT_SYMBOL(snd_opl3_timer_new);
 EXPORT_SYMBOL(snd_opl3_hwdep_new);
diff -Nru a/sound/isa/Kconfig b/sound/isa/Kconfig
--- a/sound/isa/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/isa/Kconfig	2004-10-21 14:13:16 -07:00
@@ -10,17 +10,25 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Analog Devices SoundPort AD1816A or
-	  compatible sound chips.
+	  Say Y here to include support for Analog Devices SoundPort
+	  AD1816A or compatible sound chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ad1816a.
 
 config SND_AD1848
 	tristate "Generic AD1848/CS4248 driver"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for AD1848 (Analog Devices) or CS4248 
-	  (Cirrus Logic - Crystal Semiconductors) chips. Please, for newer chips
-	  from Cirrus Logic, use CS4231, CS4232 or CS4236+ driver.
+	  Say Y here to include support for AD1848 (Analog Devices) or
+	  CS4248 (Cirrus Logic - Crystal Semiconductors) chips.
+	  
+	  For newer chips from Cirrus Logic, use the CS4231, CS4232 or
+	  CS4236+ drivers.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ad1848.
 
 config SND_CS4231
 	tristate "Generic Cirrus Logic CS4231 driver"
@@ -28,8 +36,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for CS4231 chips from Cirrus Logic -
-	  Crystal Semiconductors.
+	  Say Y here to include support for CS4231 chips from Cirrus
+	  Logic - Crystal Semiconductors.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4231.
 
 config SND_CS4232
 	tristate "Generic Cirrus Logic CS4232 driver"
@@ -38,8 +49,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for CS4232 chips from Cirrus Logic -
-	  Crystal Semiconductors.
+	  Say Y here to include support for CS4232 chips from Cirrus
+	  Logic - Crystal Semiconductors.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4232.
 
 config SND_CS4236
 	tristate "Generic Cirrus Logic CS4236+ driver"
@@ -48,8 +62,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for CS4235,CS4236,CS4237B,CS4238B,CS4239
-	  chips from Cirrus Logic - Crystal Semiconductors.
+	  Say Y to include support for CS4235,CS4236,CS4237B,CS4238B,
+	  CS4239 chips from Cirrus Logic - Crystal Semiconductors.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4236.
 
 config SND_ES968
 	tristate "Generic ESS ES968 driver"
@@ -57,7 +74,10 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for ESS AudioDrive ES968 chip.
+	  Say Y here to include support for ESS AudioDrive ES968 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es968.
 
 config SND_ES1688
 	tristate "Generic ESS ES688/ES1688 driver"
@@ -66,7 +86,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for ESS AudioDrive ES688 or ES1688 chips.
+	  Say Y here to include support for ESS AudioDrive ES688 or
+	  ES1688 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es1688.
 
 config SND_ES18XX
 	tristate "Generic ESS ES18xx driver"
@@ -75,7 +99,10 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for ESS AudioDrive ES18xx chips.
+	  Say Y here to include support for ESS AudioDrive ES18xx chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es18xx.
 
 config SND_GUS_SYNTH
 	tristate
@@ -87,7 +114,11 @@
 	select SND_PCM
 	select SND_GUS_SYNTH
 	help
-	  Say 'Y' or 'M' to include support for Gravis UltraSound Classic soundcard.
+	  Say Y here to include support for Gravis UltraSound Classic
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-gusclassic.
 
 config SND_GUSEXTREME
 	tristate "Gravis UltraSound Extreme"
@@ -97,7 +128,11 @@
 	select SND_PCM
 	select SND_GUS_SYNTH
 	help
-	  Say 'Y' or 'M' to include support for Gravis UltraSound Extreme soundcard.
+	  Say Y here to include support for Gravis UltraSound Extreme
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-gusextreme.
 
 config SND_GUSMAX
 	tristate "Gravis UltraSound MAX"
@@ -106,7 +141,11 @@
 	select SND_PCM
 	select SND_GUS_SYNTH
 	help
-	  Say 'Y' or 'M' to include support for Gravis UltraSound MAX soundcard.
+	  Say Y here to include support for Gravis UltraSound MAX
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-gusmax.
 
 config SND_INTERWAVE
 	tristate "AMD InterWave, Gravis UltraSound PnP"
@@ -115,9 +154,12 @@
 	select SND_PCM
 	select SND_GUS_SYNTH
 	help
-	  Say 'Y' or 'M' to include support for AMD InterWave based soundcards
-	  (Gravis UltraSound Plug & Play, STB SoundRage32, MED3210, Dynasonic Pro,
-	  Panasonic PCA761AW).
+	  Say Y here to include support for AMD InterWave based
+	  soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
+	  MED3210, Dynasonic Pro, Panasonic PCA761AW).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-interwave.
 
 config SND_INTERWAVE_STB
 	tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
@@ -126,8 +168,12 @@
 	select SND_PCM
 	select SND_GUS_SYNTH
 	help
-	  Say 'Y' or 'M' to include support for AMD InterWave based soundcards
-	  with TEA6330T bass and treble regulator (UltraSound 32-Pro).
+	  Say Y here to include support for AMD InterWave based
+	  soundcards with a TEA6330T bass and treble regulator
+	  (UltraSound 32-Pro).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-interwave-stb.
 
 config SND_OPTI92X_AD1848
 	tristate "OPTi 82C92x - AD1848"
@@ -137,8 +183,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Opti92x soundcards equiped with
-	  AD1848 codec.
+	  Say Y here to include support for soundcards based on Opti
+	  82C92x or OTI-601 chips and using an AD1848 codec.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opti92x-ad1848.
 
 config SND_OPTI92X_CS4231
 	tristate "OPTi 82C92x - CS4231"
@@ -148,8 +197,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Opti92x soundcards equiped with
-	  CS4231 codec.
+	  Say Y here to include support for soundcards based on Opti
+	  82C92x chips and using a CS4231 codec.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opti92x-cs4231.
 
 config SND_OPTI93X
 	tristate "OPTi 82C93x"
@@ -158,7 +210,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Opti93x soundcards.
+	  Say Y here to include support for soundcards based on Opti
+	  82C93x chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opti93x.
 
 config SND_SB8
 	tristate "Sound Blaster 1.0/2.0/Pro (8-bit)"
@@ -167,8 +223,11 @@
 	select SND_RAWMIDI
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Sound Blaster 1.0/2.0/Pro (8-bit)
-	  soundcards or 100% compatible from Creative.
+	  Say Y here to include support for Creative Sound Blaster 1.0/
+	  2.0/Pro (8-bit) or 100% compatible soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sb8.
 
 config SND_SB16
 	tristate "Sound Blaster 16 (PnP)"
@@ -177,8 +236,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Sound Blaster 16 (including
-	  Plug and Play version).
+	  Say Y here to include support for Sound Blaster 16 soundcards
+	  (including the Plug and Play version).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sb16.
 
 config SND_SBAWE
 	tristate "Sound Blaster AWE (32,64) (PnP)"
@@ -187,16 +249,19 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Sound Blaster AWE (including
-	  Plug and Play version).
+	  Say Y here to include support for Sound Blaster AWE soundcards
+	  (including the Plug and Play version).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sbawe.
 
 config SND_SB16_CSP
 	bool "Sound Blaster 16/AWE CSP support"
 	depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
 	help
-	  Say 'Y' to include support for CSP core. This special coprocessor
-	  can do variable tasks like various compression and decompression
-	  algorithms.
+	  Say Y here to include support for the CSP core.  This special
+	  coprocessor can do variable tasks like various compression and
+	  decompression algorithms.
 
 config SND_WAVEFRONT
 	tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
@@ -205,8 +270,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Turtle Beach Maui, Tropez
-	  and Tropez+ soundcards based on Wavefront chip.
+	  Say Y here to include support for Turtle Beach Maui, Tropez
+	  and Tropez+ soundcards based on the Wavefront chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-wavefront.
 
 config SND_ALS100
 	tristate "Avance Logic ALS100/ALS120"
@@ -215,8 +283,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Avance Logic ALS100, ALS110,
-	  ALS120 and ALS200 soundcards.
+	  Say Y here to include support for soundcards based on Avance
+	  Logic ALS100, ALS110, ALS120 and ALS200 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-als100.
 
 config SND_AZT2320
 	tristate "Aztech Systems AZT2320"
@@ -225,14 +296,22 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Aztech Systems AZT2320 soundcard.
+	  Say Y here to include support for soundcards based on the
+	  Aztech Systems AZT2320 chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-azt2320.
 
 config SND_CMI8330
 	tristate "C-Media CMI8330"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for C-Media CMI8330 based soundcards.
+	  Say Y here to include support for soundcards based on the
+	  C-Media CMI8330 chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cmi8330.
 
 config SND_DT019X
 	tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
@@ -241,8 +320,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Diamond Technologies DT-019X and
-	  Avance Logic ALS-007 soundcards.
+	  Say Y here to include support for soundcards based on the
+	  Diamond Technologies DT-019X or Avance Logic ALS-007 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-dt019x.
 
 config SND_OPL3SA2
 	tristate "Yamaha OPL3-SA2/SA3"
@@ -251,14 +333,22 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Yamaha OPL3SA2 or OPL3SA3 chips.
+	  Say Y here to include support for Yamaha OPL3-SA2 and OPL3-SA3
+	  chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opl3sa2.
 
 config SND_SGALAXY
 	tristate "Aztech Sound Galaxy"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Aztech Sound Galaxy.
+	  Say Y here to include support for Aztech Sound Galaxy
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sgalaxy.
 
 config SND_SSCAPE
 	tristate "Ensoniq SoundScape PnP driver"
@@ -267,7 +357,10 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Ensoniq SoundScape PnP
-	  soundcard.
+	  Say Y here to include support for Ensoniq SoundScape PnP
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sscape.
 
 endmenu
diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c
--- a/sound/isa/es18xx.c	2004-10-21 14:13:16 -07:00
+++ b/sound/isa/es18xx.c	2004-10-21 14:13:16 -07:00
@@ -419,6 +419,11 @@
 		
 	if ((chip->caps & ES18XX_PCM2) && mode == DAC2) {
 		snd_es18xx_mixer_write(chip, 0x70, bits);
+		/*
+		 * Comment from kernel oss driver:
+		 * FKS: fascinating: 0x72 doesn't seem to work.
+		 */
+		snd_es18xx_write(chip, 0xA2, div0);
 		snd_es18xx_mixer_write(chip, 0x72, div0);
 	} else {
 		snd_es18xx_write(chip, 0xA1, bits);
diff -Nru a/sound/parisc/Kconfig b/sound/parisc/Kconfig
--- a/sound/parisc/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/parisc/Kconfig	2004-10-21 14:13:16 -07:00
@@ -8,7 +8,10 @@
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Harmony/Vivace soundchip
+	  Say Y here to include support for the Harmony/Vivace soundchip
 	  on HP712s, 715/new and many other GSC based machines.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-harmony.
 
 endmenu
diff -Nru a/sound/parisc/harmony.c b/sound/parisc/harmony.c
--- a/sound/parisc/harmony.c	2004-10-21 14:13:16 -07:00
+++ b/sound/parisc/harmony.c	2004-10-21 14:13:16 -07:00
@@ -135,11 +135,11 @@
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard.");
+MODULE_PARM_DESC(index, "Index value for Harmony device.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for Sun CS4231 soundcard.");
+MODULE_PARM_DESC(id, "ID string for Harmony device.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Sun CS4231 soundcard.");
+MODULE_PARM_DESC(enable, "Enable Harmony device.");
 
 /* Register offset (from base hpa) */
 #define REG_ID		0x00
@@ -275,7 +275,7 @@
 {
 	unsigned int idx;
 	
-	for (idx = 0; idx <= ARRAY_SIZE(snd_card_harmony_rates); idx++)
+	for (idx = 0; idx < ARRAY_SIZE(snd_card_harmony_rates); idx++)
 		if (snd_card_harmony_rates[idx] == rate)
 			return rate_bits[idx];
 	return HARMONY_SR_44KHZ; /* fallback */
@@ -741,9 +741,10 @@
 	                   snd_pcm_hw_params_t * hw_params)
 {
 	int err;
+	snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
 	
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-	if (err > 0 && substream->dma_device.type == SNDRV_DMA_TYPE_CONTINUOUS)
+	if (err > 0 && harmony->dma_dev.type == SNDRV_DMA_TYPE_CONTINUOUS)
 		substream->runtime->dma_addr = __pa(substream->runtime->dma_area);
 	DPRINTK(KERN_INFO PFX "HW Params returned %d, dma_addr %lx\n", err,
 			(unsigned long)substream->runtime->dma_addr);
@@ -1131,11 +1132,13 @@
 		{	
 			DPRINTK(KERN_INFO PFX "Freeing card %d\n", idx);
 			harmony = snd_harmony_cards[idx]->private_data;
-			free_irq(harmony->irq, snd_card_harmony_interrupt);
+			free_irq(harmony->irq, harmony);
 			printk(KERN_INFO PFX "Card unloaded %d, irq=%d\n", idx, harmony->irq);
 			snd_card_free(snd_harmony_cards[idx]);
 		}
 	}	
+	if (unregister_parisc_driver(&snd_card_harmony_driver) < 0)
+		printk(KERN_ERR PFX "Failed to unregister Harmony driver\n");
 }
 
 module_init(alsa_card_harmony_init)
diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/Kconfig	2004-10-21 14:13:16 -07:00
@@ -8,27 +8,41 @@
 	select SND_PCM
 
 config SND_ALI5451
-	tristate "ALi PCI Audio M5451"
+	tristate "ALi M5451 PCI Audio Controller"
 	depends on SND
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ALI PCI Audio M5451 sound core.
+	  Say Y here to include support for the integrated AC97 sound
+	  device on motherboards using the ALi M5451 Audio Controller
+	  (M1535/M1535D/M1535+/M1535D+ south bridges).  Newer chipsets
+	  use the "Intel/SiS/nVidia/AMD/ALi AC97 Controller" driver.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ali5451.
 
 config SND_ATIIXP
-	tristate "ATI IXP 150/200/250/300"
+	tristate "ATI IXP AC97 Controller"
 	depends on SND
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ATI IXP 150/200/250/300 AC97 controller.
+	  Say Y here to include support for the integrated AC97 sound
+	  device on motherboards with ATI chipsets (ATI IXP 150/200/250/
+	  300/400).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-atiixp.
 
 config SND_ATIIXP_MODEM
-	tristate "ATI IXP 150/200/250 Modem"
+	tristate "ATI IXP Modem"
 	depends on SND
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ATI IXP 150/200/250 AC97 modem
-	  controller.
+	  Say Y here to include support for the integrated MC97 modem on
+	  motherboards with ATI chipsets (ATI IXP 150/200/250).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-atiixp-modem.
 
 config SND_AU8810
         tristate "Aureal Advantage"
@@ -36,10 +50,14 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
         help
-          Say 'Y' or 'M' to include support for Aureal Advantage soundcards.
-          Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
+	  Say Y here to include support for Aureal Advantage soundcards.
+
+	  Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
           3D support code is in place, but not yet useable. For more info, 
           email the ALSA developer list, or mjander@users.sourceforge.net.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-au8810.
  
 config SND_AU8820
         tristate "Aureal Vortex"
@@ -47,9 +65,13 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
         help
-          Say 'Y' or 'M' to include support for Aureal Vortex soundcards.
+	  Say Y here to include support for Aureal Vortex soundcards.
+
           Supported features: Hardware Mixer and SRC. For more info, email 
           the ALSA developer list, or mjander@users.sourceforge.net.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-au8820.
  
 config SND_AU8830
         tristate "Aureal Vortex 2"
@@ -57,10 +79,14 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
         help
-          Say 'Y' or 'M' to include support for Aureal Vortex 2 soundcards.
+	  Say Y here to include support for Aureal Vortex 2 soundcards.
+
           Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
           3D support code is in place, but not yet useable. For more info, 
           email the ALSA developer list, or mjander@users.sourceforge.net.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-au8830.
  
 config SND_AZT3328
 	tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)"
@@ -69,15 +95,32 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Aztech AZF3328 (PCI168) soundcards.
+	  Say Y here to include support for Aztech AZF3328 (PCI168)
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-azt3328.
 
 config SND_BT87X
         tristate "Bt87x Audio Capture"
         depends on SND
 	select SND_PCM
         help
-          Say 'Y' or 'M' to include support for recording audio from TV cards
-          based on Brooktree Bt878/Bt879 chips.
+	  Say Y here to include support for recording audio from TV
+	  cards based on Brooktree Bt878/Bt879 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-bt87x.
+
+config SND_BT87X_OVERCLOCK
+	bool "Bt87x Audio overclocking"
+	depends on SND_BT87X
+	help
+	  Say Y here if 448000 Hz isn't enough for you and you want to
+	  record from the analog input with up to 1792000 Hz.
+
+	  Higher sample rates won't hurt your hardware, but audio
+	  quality may suffer.
 
 config SND_CS46XX
 	tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
@@ -85,14 +128,19 @@
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Cirrus Logic CS4610 / CS4612 /
-	  CS4614 / CS4615 / CS4622 / CS4624 / CS4630 / CS4280 chips.
+	  Say Y here to include support for Cirrus Logic CS4610/CS4612/
+	  CS4614/CS4615/CS4622/CS4624/CS4630/CS4280 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs46xx.
 
 config SND_CS46XX_NEW_DSP
 	bool "Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)"
 	depends on SND_CS46XX && EXPERIMENTAL
 	help
-	  Say 'Y' to use a new DSP image for SPDIF and dual codecs.
+	  Say Y here to use a new DSP image for SPDIF and dual codecs.
+
+	  This works better than the old code, so say Y.
 
 config SND_CS4281
 	tristate "Cirrus Logic (Sound Fusion) CS4281"
@@ -101,24 +149,37 @@
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Cirrus Logic CS4281.
+	  Say Y here to include support for Cirrus Logic CS4281 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4281.
 
 config SND_EMU10K1
-	tristate "EMU10K1 (SB Live! & Audigy, E-mu APS)"
+	tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
 	depends on SND
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Sound Blaster PCI 512, Live!,
-	  Audigy and E-mu APS (partially supported).
+	  Say Y to include support for Sound Blaster PCI 512, Live!,
+	  Audigy and E-mu APS (partially supported) soundcards.
+
+	  The confusing multitude of mixer controls is documented in
+	  <file:Documentation/sound/alsa/SB-Live-mixer.txt> and
+	  <file:Documentation/sound/alsa/Audigy-mixer.txt>.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-emu10k1.
 
 config SND_KORG1212
 	tristate "Korg 1212 IO"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Korg 1212IO.
+	  Say Y here to include support for Korg 1212IO soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-korg1212.
 
 config SND_MIXART
 	tristate "Digigram miXart"
@@ -126,38 +187,55 @@
 	select SND_HWDEP
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Digigram miXart soundcard.
+	  If you want to use Digigram miXart soundcards, say Y here and
+	  read <file:Documentation/sound/alsa/MIXART.txt>.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-mixart.
 
 config SND_NM256
 	tristate "NeoMagic NM256AV/ZX"
 	depends on SND
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for NeoMagic NM256AV/ZX chips.
+	  Say Y here to include support for NeoMagic NM256AV/ZX chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-nm256.
 
 config SND_RME32
 	tristate "RME Digi32, 32/8, 32 PRO"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for RME Digi32, Digi32 PRO and
-	  Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio devices.
+	  Say Y to include support for RME Digi32, Digi32 PRO and
+	  Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio
+	  devices.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rme32.
 
 config SND_RME96
 	tristate "RME Digi96, 96/8, 96/8 PRO"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for RME Digi96, Digi96/8 and
-	  Digi96/8 PRO/PAD/PST.
+	  Say Y here to include support for RME Digi96, Digi96/8 and
+	  Digi96/8 PRO/PAD/PST soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rme96.
 
 config SND_RME9652
 	tristate "RME Digi9652 (Hammerfall)"
 	depends on SND
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for RME Hammerfall (RME Digi9652 /
-	  Digi9636) soundcards.
+	  Say Y here to include support for RME Hammerfall (RME
+	  Digi9652/Digi9636) soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rme9652.
 
 config SND_HDSP
 	tristate "RME Hammerfall DSP Audio"
@@ -166,17 +244,23 @@
 	select SND_RAWMIDI
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for RME Hammerfall DSP Audio
+	  Say Y here to include support for RME Hammerfall DSP Audio
 	  soundcards.
 
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-hdsp.
+
 config SND_TRIDENT
 	tristate "Trident 4D-Wave DX/NX; SiS 7018"
 	depends on SND
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Trident 4D-Wave DX/NX and
-	  SiS 7018 soundcards.
+	  Say Y here to include support for soundcards based on Trident
+	  4D-Wave DX/NX or SiS 7018 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-trident.
 
 config SND_YMFPCI
 	tristate "Yamaha YMF724/740/744/754"
@@ -185,9 +269,12 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Yamaha PCI audio chips - 
+	  Say Y here to include support for Yamaha PCI audio chips -
 	  YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
 
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ymfpci.
+
 config SND_ALS4000
 	tristate "Avance Logic ALS4000"
 	depends on SND
@@ -195,7 +282,11 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Avance Logic ALS4000.
+	  Say Y here to include support for soundcards based on Avance Logic
+	  ALS4000 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-als4000.
 
 config SND_CMIPCI
 	tristate "C-Media 8738, 8338"
@@ -204,8 +295,12 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for C-Media CMI8338 and 8738 PCI
-	  soundcards.
+	  If you want to use soundcards based on C-Media CMI8338 or CMI8738
+	  chips, say Y here and read
+	  <file:Documentation/sound/alsa/CMIPCI.txt>.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cmipci.
 
 config SND_ENS1370
 	tristate "(Creative) Ensoniq AudioPCI 1370"
@@ -213,7 +308,10 @@
 	select SND_RAWMIDI
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370.
+	  Say Y here to include support for Ensoniq AudioPCI ES1370 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ens1370.
 
 config SND_ENS1371
 	tristate "(Creative) Ensoniq AudioPCI 1371/1373"
@@ -221,9 +319,12 @@
 	select SND_RAWMIDI
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and
+	  Say Y here to include support for Ensoniq AudioPCI ES1371 chips and
 	  Sound Blaster PCI 64 or 128 soundcards.
 
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ens1371.
+
 config SND_ES1938
 	tristate "ESS ES1938/1946/1969 (Solo-1)"
 	depends on SND
@@ -231,8 +332,11 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946, ES1969)
-	  soundcard.
+	  Say Y here to include support for soundcards based on ESS Solo-1
+	  (ES1938, ES1946, ES1969) chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es1938.
 
 config SND_ES1968
 	tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
@@ -240,14 +344,22 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ESS Maestro 1/2/2E.
+	  Say Y here to include support for soundcards based on ESS Maestro
+	  1/2/2E chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es1968.
 
 config SND_MAESTRO3
 	tristate "ESS Allegro/Maestro3"
 	depends on SND
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ESS Maestro 3 (Allegro) soundcard.
+	  Say Y here to include support for soundcards based on ESS Maestro 3
+	  (Allegro) chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-maestro3.
 
 config SND_FM801
 	tristate "ForteMedia FM801"
@@ -256,15 +368,23 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ForteMedia FM801 based soundcards.
+	  Say Y here to include support for soundcards based on the ForteMedia
+	  FM801 chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-fm801.
 
 config SND_FM801_TEA575X
 	tristate "ForteMedia FM801 + TEA5757 tuner"
 	depends on SND_FM801
         select VIDEO_DEV
 	help
-	  Say 'Y' or 'M' to include support for ForteMedia FM801 based soundcards
-          with TEA5757 tuner connected to GPIO1-3 pins (Media Forte SF256-PCS-02).
+	  Say Y here to include support for soundcards based on the ForteMedia
+	  FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media
+	  Forte SF256-PCS-02).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-fm801-tea575x.
 
 config SND_ICE1712
 	tristate "ICEnsemble ICE1712 (Envy24)"
@@ -272,10 +392,16 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ICE1712 (Envy24) based soundcards.
-	  Currently supported hardware is: MidiMan M Audio - Delta 1010(LT), Dio 2496,
-	  Delta 66/44, Audiophile 24/96; Hoontech SoundTrack DSP 24 (Value);
-	  TerraTec - EWX 24/96, EWS 88MT, EWS 88D, DMX 6Fire.
+	  Say Y here to include support for soundcards based on the
+	  ICE1712 (Envy24) chip.
+
+	  Currently supported hardware is: M-Audio Delta 1010(LT),
+	  DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442;
+	  TerraTec EWX 24/96, EWS 88MT, 88D, DMX 6Fire, Phase 88;
+	  Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ice1712.
 
 config SND_ICE1724
 	tristate "ICE/VT1724/1720 (Envy24HT/PT)"
@@ -283,27 +409,40 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for ICE/VT1724/1720 (Envy24HT/PT) based
-	  soundcards.
-	  Currently supported hardware is: MidiMan M Audio - Revolution 7.1,
-	  AMP Ltd AUDIO2000, Terratec Aureon 5.1 Sky/7.1, AudioTrak Prodigy 7.1.
+	  Say Y here to include support for soundcards based on
+	  ICE/VT1724/1720 (Envy24HT/PT) chips.
+
+	  Currently supported hardware is: AMP AUDIO2000; M-Audio
+	  Revolution 7.1; TerraTec Aureon 5.1 Sky, 7.1 Space/Universe;
+	  AudioTrak Prodigy 7.1; Pontis MS300; Albatron K8X800 Pro II;
+	  Chaintech ZNF3-150/250.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ice1724.
 
 config SND_INTEL8X0
-	tristate "Intel i8x0/MX440, SiS 7012; Ali 5455; NForce Audio; AMD768/8111"
+	tristate "Intel/SiS/nVidia/AMD/ALi AC97 Controller"
 	depends on SND
-	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Intel8x0 based soundcards,
-	  SiS 7012, AMD768/8111, NVidia NForce and ALi 5455 chips.
+	  Say Y here to include support for the integrated AC97 sound
+	  device on motherboards with Intel/SiS/nVidia/AMD chipsets, or
+	  ALi chipsets using the M5455 Audio Controller.  (There is a
+	  separate driver for ALi M5451 Audio Controllers.)
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-intel8x0.
 
 config SND_INTEL8X0M
-	tristate "Intel i8x0/MX440; SiS 7013; NForce; AMD768/8111 modems (EXPERIMENTAL)"
+	tristate "Intel/SiS/nVidia/AMD MC97 Modem (EXPERIMENTAL)"
 	depends on SND && EXPERIMENTAL
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for Intel8x0, SiS 7013, NVidia NForce
-          and AMD768/8111 based modems.
+	  Say Y here to include support for the integrated MC97 modem on
+	  motherboards with Intel/SiS/nVidia/AMD chipsets.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-intel8x0m.
 
 config SND_SONICVIBES
 	tristate "S3 SonicVibes"
@@ -312,22 +451,33 @@
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
+	  Say Y here to include support for soundcards based on the S3
+	  SonicVibes chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sonicvibes.
 
 config SND_VIA82XX
-	tristate "VIA 82C686A/B, 8233 South Bridge"
+	tristate "VIA 82C686A/B, 8233/8235 AC97 Controller"
 	depends on SND
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
-	  Say 'Y' or 'M' to include support for VIA VT82C686A/B, VT8233 South Bridge.
+	  Say Y here to include support for the integrated AC97 sound
+	  device on motherboards with VIA chipsets.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-via82xx.
 
 config SND_VX222
 	tristate "Digigram VX222"
 	depends on SND
 	select SND_VX_LIB
 	help
-	  Say 'Y' or 'M' to include support for Digigram VX222 soundcards.
+	  Say Y here to include support for Digigram VX222 soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-vx222.
 
 endmenu
 
diff -Nru a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
--- a/sound/pci/ac97/Makefile	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/Makefile	2004-10-21 14:13:16 -07:00
@@ -3,7 +3,12 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_proc.o ac97_patch.o
+snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o
+
+ifneq ($(CONFIG_PROC_FS),)
+snd-ac97-codec-objs += ac97_proc.o
+endif
+
 snd-ak4531-codec-objs := ak4531_codec.o
 
 # Toplevel Module Dependency
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_codec.c	2004-10-21 14:13:16 -07:00
@@ -118,9 +118,12 @@
 { 0x414c4770, 0xfffffff0, "ALC203",		NULL,		NULL },
 { 0x434d4941, 0xffffffff, "CMI9738",		patch_cm9738,	NULL },
 { 0x434d4961, 0xffffffff, "CMI9739",		patch_cm9739,	NULL },
+{ 0x434d4978, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
+{ 0x434d4982, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
+{ 0x434d4983, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
 { 0x43525900, 0xfffffff8, "CS4297",		NULL,		NULL },
 { 0x43525910, 0xfffffff8, "CS4297A",		patch_cirrus_spdif,	NULL },
-{ 0x43525920, 0xfffffff8, "CS4294/4298",	NULL,		NULL },
+{ 0x43525920, 0xfffffff8, "CS4298",		patch_cirrus_spdif,		NULL },
 { 0x43525928, 0xfffffff8, "CS4294",		NULL,		NULL },
 { 0x43525930, 0xfffffff8, "CS4299",		patch_cirrus_cs4299,	NULL },
 { 0x43525948, 0xfffffff8, "CS4201",		NULL,		NULL },
@@ -749,6 +752,14 @@
 static const snd_kcontrol_new_t snd_ac97_control_eapd =
 AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
 
+/* change the existing EAPD control as inverted */
+static void set_inv_eapd(ac97_t *ac97, snd_kcontrol_t *kctl)
+{
+	kctl->private_value = AC97_SINGLE_VALUE(AC97_POWERDOWN, 15, 1, 0);
+	snd_ac97_update_bits(ac97, AC97_POWERDOWN, (1<<15), (1<<15)); /* EAPD up */
+	ac97->scaps |= AC97_SCAP_INV_EAPD;
+}
+
 static int snd_ac97_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
@@ -1559,7 +1570,7 @@
 			return err;
 	}
 
-	snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x0000);
+	snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, ~AC97_GP_DRSS_MASK, 0x0000);
 
 	/* build 3D controls */
 	if (ac97->build_ops && ac97->build_ops->build_3d) {
@@ -1610,7 +1621,12 @@
 			return err;
 
 	if (snd_ac97_try_bit(ac97, AC97_POWERDOWN, 15)) {
-		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_eapd, ac97))) < 0)
+		kctl = snd_ac97_cnew(&snd_ac97_control_eapd, ac97);
+		if (! kctl)
+			return -ENOMEM;
+		if (ac97->scaps & AC97_SCAP_INV_EAPD)
+			set_inv_eapd(ac97, kctl);
+		if ((err = snd_ctl_add(card, kctl)) < 0)
 			return err;
 	}
 
@@ -1646,6 +1662,9 @@
 {
 	unsigned int result = 0;
 
+	if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
+				     AC97_EA_DRA, 0);
 	/* test a non-standard rate */
 	if (snd_ac97_test_rate(ac97, reg, shadow_reg, 11000))
 		result |= SNDRV_PCM_RATE_CONTINUOUS;
@@ -1664,6 +1683,23 @@
 		result |= SNDRV_PCM_RATE_44100;
 	if (snd_ac97_test_rate(ac97, reg, shadow_reg, 48000))
 		result |= SNDRV_PCM_RATE_48000;
+	if ((ac97->flags & AC97_DOUBLE_RATE) &&
+	    reg == AC97_PCM_FRONT_DAC_RATE) {
+		/* test standard double rates */
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
+				     AC97_EA_DRA, AC97_EA_DRA);
+		if (snd_ac97_test_rate(ac97, reg, shadow_reg, 64000 / 2))
+			result |= SNDRV_PCM_RATE_64000;
+		if (snd_ac97_test_rate(ac97, reg, shadow_reg, 88200 / 2))
+			result |= SNDRV_PCM_RATE_88200;
+		if (snd_ac97_test_rate(ac97, reg, shadow_reg, 96000 / 2))
+			result |= SNDRV_PCM_RATE_96000;
+		/* some codecs don't support variable double rates */
+		if (!snd_ac97_test_rate(ac97, reg, shadow_reg, 76100 / 2))
+			result &= ~SNDRV_PCM_RATE_CONTINUOUS;
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
+				     AC97_EA_DRA, 0);
+	}
 	*r_result = result;
 }
 
@@ -1726,6 +1762,22 @@
 	sprintf(name + strlen(name), " id %x", id & 0xff);
 }
 
+/**
+ * snd_ac97_get_short_name - retrieve codec name
+ * @ac97: the codec instance
+ *
+ * Returns the short identifying name of the codec.
+ */
+const char *snd_ac97_get_short_name(ac97_t *ac97)
+{
+	const ac97_codec_id_t *pid;
+
+	for (pid = snd_ac97_codec_ids; pid->id; pid++)
+		if (pid->id == (ac97->id & pid->mask))
+			return pid->name;
+	return "unknown codec";
+}
+
 
 /* wait for a while until registers are accessible after RESET
  * return 0 if ok, negative not ready
@@ -1733,9 +1785,10 @@
 static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
 {
 	unsigned long end_time;
+	unsigned short val;
+
 	end_time = jiffies + timeout;
 	do {
-		unsigned short ext_mid;
 		
 		/* use preliminary reads to settle the communication */
 		snd_ac97_read(ac97, AC97_RESET);
@@ -1743,17 +1796,24 @@
 		snd_ac97_read(ac97, AC97_VENDOR_ID2);
 		/* modem? */
 		if (with_modem) {
-			ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
-			if (ext_mid != 0xffff && (ext_mid & 1) != 0)
+			val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
+			if (val != 0xffff && (val & 1) != 0)
+				return 0;
+		}
+		if (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) {
+			/* probably only Xbox issue - all registers are read as zero */
+			val = snd_ac97_read(ac97, AC97_VENDOR_ID1);
+			if (val != 0 && val != 0xffff)
+				return 0;
+		} else {
+			/* because the PCM or MASTER volume registers can be modified,
+			 * the REC_GAIN register is used for tests
+			 */
+			/* test if we can write to the record gain volume register */
+			snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
+			if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
 				return 0;
 		}
-		/* because the PCM or MASTER volume registers can be modified,
-		 * the REC_GAIN register is used for tests
-		 */
-		/* test if we can write to the record gain volume register */
-		snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
-		if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
-			return 0;
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
 	} while (time_after_eq(end_time, jiffies));
@@ -2004,13 +2064,25 @@
 		ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
 	else
 		ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
-	if (ac97->ext_id & 0x0189)	/* L/R, MIC, SDAC, LDAC VRA support */
-		snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, ac97->ext_id & 0x0189);
+	if (ac97->ext_id & 0x0189) {	/* L/R, MIC, SDAC, LDAC VRA support */
+		reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
+		reg |= ac97->ext_id & 0x0189;
+		snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
+	}
+	if ((ac97->ext_id & AC97_EI_DRA) && bus->dra) {
+		/* Intel controllers require double rate data to be put in
+		 * slots 7+8, so let's hope the codec supports it. */
+		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
+		if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
+			ac97->flags |= AC97_DOUBLE_RATE;
+	}
 	if (ac97->ext_id & AC97_EI_VRA) {	/* VRA support */
 		snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
 		snd_ac97_determine_rates(ac97, AC97_PCM_LR_ADC_RATE, 0, &ac97->rates[AC97_RATES_ADC]);
 	} else {
 		ac97->rates[AC97_RATES_FRONT_DAC] = SNDRV_PCM_RATE_48000;
+		if (ac97->flags & AC97_DOUBLE_RATE)
+			ac97->rates[AC97_RATES_FRONT_DAC] |= SNDRV_PCM_RATE_96000;
 		ac97->rates[AC97_RATES_ADC] = SNDRV_PCM_RATE_48000;
 	}
 	if (ac97->ext_id & AC97_EI_SPDIF) {
@@ -2317,9 +2389,9 @@
 
 static int swap_headphone(ac97_t *ac97, int remove_master)
 {
+	if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
+		return -ENOENT;
 	if (remove_master) {
-		if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
-			return 0;
 		snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
 		snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
 	} else
@@ -2330,9 +2402,9 @@
 
 static int swap_surround(ac97_t *ac97)
 {
-	/* FIXME: error checks.. */
-	snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch");
-	snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume");
+	if (snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch") ||
+	    snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume"))
+		return -ENOENT;
 	return 0;
 }
 
@@ -2363,6 +2435,15 @@
 	return snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_alc_jack_detect, ac97));
 }
 
+static int tune_inv_eapd(ac97_t *ac97)
+{
+	snd_kcontrol_t *kctl = ctl_find(ac97, "External Amplifier", NULL);
+	if (! kctl)
+		return -ENOENT;
+	set_inv_eapd(ac97, kctl);
+	return 0;
+}
+
 static int apply_quirk(ac97_t *ac97, int quirk)
 {
 	switch (quirk) {
@@ -2378,6 +2459,8 @@
 		return tune_ad_sharing(ac97);
 	case AC97_TUNE_ALC_JACK:
 		return tune_alc_jack(ac97);
+	case AC97_TUNE_INV_EAPD:
+		return tune_inv_eapd(ac97);
 	}
 	return -EINVAL;
 }
@@ -2413,6 +2496,8 @@
 			continue;
 		if ((! quirk->mask && quirk->device == ac97->subsystem_device) ||
 		    quirk->device == (quirk->mask & ac97->subsystem_device)) {
+			if (quirk->codec_id && quirk->codec_id != ac97->id)
+				continue;
 			snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
 			result = apply_quirk(ac97, quirk->type);
 			if (result < 0)
@@ -2433,11 +2518,13 @@
 EXPORT_SYMBOL(snd_ac97_write_cache);
 EXPORT_SYMBOL(snd_ac97_update);
 EXPORT_SYMBOL(snd_ac97_update_bits);
+EXPORT_SYMBOL(snd_ac97_get_short_name);
 EXPORT_SYMBOL(snd_ac97_bus);
 EXPORT_SYMBOL(snd_ac97_mixer);
 EXPORT_SYMBOL(snd_ac97_pcm_assign);
 EXPORT_SYMBOL(snd_ac97_pcm_open);
 EXPORT_SYMBOL(snd_ac97_pcm_close);
+EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
 EXPORT_SYMBOL(snd_ac97_tune_hardware);
 EXPORT_SYMBOL(snd_ac97_set_rate);
 #ifdef CONFIG_PM
diff -Nru a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
--- a/sound/pci/ac97/ac97_id.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_id.h	2004-10-21 14:13:16 -07:00
@@ -57,3 +57,6 @@
 #define AC97_ID_VT1616		0x49434551
 #define AC97_ID_CM9738		0x434d4941
 #define AC97_ID_CM9739		0x434d4961
+#define AC97_ID_CM9761_78	0x434d4978
+#define AC97_ID_CM9761_82	0x434d4982
+#define AC97_ID_CM9761_83	0x434d4983
diff -Nru a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
--- a/sound/pci/ac97/ac97_local.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_local.h	2004-10-21 14:13:16 -07:00
@@ -51,7 +51,14 @@
 void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
 
 /* ac97_proc.c */
+#ifdef CONFIG_PROC_FS
 void snd_ac97_bus_proc_init(ac97_bus_t * ac97);
 void snd_ac97_bus_proc_done(ac97_bus_t * ac97);
 void snd_ac97_proc_init(ac97_t * ac97);
 void snd_ac97_proc_done(ac97_t * ac97);
+#else
+#define snd_ac97_bus_proc_init(ac97_bus_t) do { } while (0)
+#define snd_ac97_bus_proc_done(ac97_bus_t) do { } while (0)
+#define snd_ac97_proc_init(ac97_t) do { } while (0)
+#define snd_ac97_proc_done(ac97_t) do { } while (0)
+#endif
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_patch.c	2004-10-21 14:13:16 -07:00
@@ -1779,6 +1779,140 @@
 	return 0;
 }
 
+#define AC97_CM9761_MULTI_CHAN	0x64
+#define AC97_CM9761_SPDIF_CTRL	0x6c
+
+static int snd_ac97_cm9761_linein_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x0400)
+		ucontrol->value.integer.value[0] = 1;
+	else
+		ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int snd_ac97_cm9761_linein_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	unsigned short vals[2][2] = {
+		{ 0x0008, 0x0400 }, /* off, on */
+		{ 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
+	};
+	return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x0408,
+				    vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]);
+}
+
+static int snd_ac97_cm9761_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000)
+		ucontrol->value.integer.value[0] = 1;
+	else
+		ucontrol->value.integer.value[0] = 0;
+	if (ac97->spec.dev_flags) /* 9761-82 rev.B */
+		ucontrol->value.integer.value[0] = !ucontrol->value.integer.value[0];
+	return 0;
+}
+
+static int snd_ac97_cm9761_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	unsigned short vals[2][2] = {
+		{ 0x2000, 0x1880 }, /* off, on */
+		{ 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
+	};
+	return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3880,
+				    vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]);
+}
+
+static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Line-In As Surround",
+		.info = snd_ac97_info_single,
+		.get = snd_ac97_cm9761_linein_rear_get,
+		.put = snd_ac97_cm9761_linein_rear_put,
+		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Mic As Center/LFE",
+		.info = snd_ac97_info_single,
+		.get = snd_ac97_cm9761_center_mic_get,
+		.put = snd_ac97_cm9761_center_mic_put,
+		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
+	},
+};
+
+static int patch_cm9761_specific(ac97_t * ac97)
+{
+	return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
+}
+
+static struct snd_ac97_build_ops patch_cm9761_ops = {
+	.build_specific	= patch_cm9761_specific,
+	.build_post_spdif = patch_cm9739_post_spdif /* hope it's identical... */
+};
+
+int patch_cm9761(ac97_t *ac97)
+{
+	unsigned short val;
+
+	ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
+	if (ac97->id == AC97_ID_CM9761_82) {
+		unsigned short tmp;
+		/* check page 1, reg 0x60 */
+		val = snd_ac97_read(ac97, AC97_INT_PAGING);
+		snd_ac97_write_cache(ac97, AC97_INT_PAGING, (val & ~0x0f) | 0x01);
+		tmp = snd_ac97_read(ac97, 0x60);
+		ac97->spec.dev_flags = tmp & 1; /* revision B? */
+		snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
+	}
+
+	ac97->build_ops = &patch_cm9761_ops;
+
+	/* enable spdif */
+	/* force the SPDIF bit in ext_id - codec doesn't set this bit! */
+        ac97->ext_id |= AC97_EI_SPDIF;
+	/* to be sure: we overwrite the ext status bits */
+	snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0);
+	snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0209);
+	ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
+
+	/* set-up multi channel */
+	/* bit 15: pc master beep off
+	 * bit 14: ??
+	 * bit 13: vref ctl [= cm9739]
+	 * bit 12: center/mic [= cm9739] (reverted on rev B)
+	 * bit 11: ?? (mic/center/lfe) (reverted on rev B)
+	 * bit 10: suddound/line [= cm9739]
+	 * bit  9: mix 2 surround
+	 * bit  8: ?
+	 * bit  7: ?? (mic/center/lfe)
+	 * bit  4: ?? (front)
+	 * bit  3: ?? (line-in/rear share) (revereted with rev B)
+	 * bit  2: ?? (surround)
+	 * bit  1: front mic
+	 * bit  0: mic boost
+	 */
+
+#if 0
+	if (ac97->spec.dev_flags)
+		val = 0x0214;
+	else
+		val = 0x321c;
+	snd_ac97_write_cache(ac97, AC97_CM9761_MULTI_CHAN, val);
+#endif
+
+	/* FIXME: set up GPIO */
+	snd_ac97_write_cache(ac97, 0x70, 0x0100);
+	snd_ac97_write_cache(ac97, 0x72, 0x0020);
+
+	return 0;
+}
+       
+
 /*
  * VIA VT1616 codec
  */
diff -Nru a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
--- a/sound/pci/ac97/ac97_patch.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_patch.h	2004-10-21 14:13:16 -07:00
@@ -52,6 +52,7 @@
 int patch_alc850(ac97_t * ac97);
 int patch_cm9738(ac97_t * ac97);
 int patch_cm9739(ac97_t * ac97);
+int patch_cm9761(ac97_t * ac97);
 int patch_vt1616(ac97_t * ac97);
 int patch_it2646(ac97_t * ac97);
 int mpatch_si3036(ac97_t * ac97);
diff -Nru a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
--- a/sound/pci/ac97/ac97_pcm.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_pcm.c	2004-10-21 14:13:16 -07:00
@@ -93,54 +93,52 @@
   },
 },
 {
-  /* FIXME: double rates */
+  /* double rates */
   {
-  	/* 3&4 front, 7&8 rear, 6&9 center/lfe */
+  	/* 3&4 front, 7&8 front (t+1) */
 	AC97_PCM_FRONT_DAC_RATE,	/* slot 3 */
 	AC97_PCM_FRONT_DAC_RATE,	/* slot 4 */
 	0xff,				/* slot 5 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 6 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 7 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 8 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 9 */
+	0xff,				/* slot 6 */
+	AC97_PCM_FRONT_DAC_RATE,	/* slot 7 */
+	AC97_PCM_FRONT_DAC_RATE,	/* slot 8 */
+	0xff,				/* slot 9 */
 	0xff,				/* slot 10 */
 	0xff,				/* slot 11 */
   },
   {
-  	/* 7&8 front, 6&9 rear, 10&11 center/lfe */
+	/* not specified in the specification */
 	0xff,				/* slot 3 */
 	0xff,				/* slot 4 */
 	0xff,				/* slot 5 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 6 */
-	AC97_PCM_FRONT_DAC_RATE,	/* slot 7 */
-	AC97_PCM_FRONT_DAC_RATE,	/* slot 8 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 9 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 10 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 11 */
+	0xff,				/* slot 6 */
+	0xff,				/* slot 7 */
+	0xff,				/* slot 8 */
+	0xff,				/* slot 9 */
+	0xff,				/* slot 10 */
+	0xff,				/* slot 11 */
   },
   {
-  	/* 6&9 front, 10&11 rear, 3&4 center/lfe */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 3 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 4 */
+	0xff,				/* slot 3 */
+	0xff,				/* slot 4 */
 	0xff,				/* slot 5 */
-	AC97_PCM_FRONT_DAC_RATE,	/* slot 6 */
+	0xff,				/* slot 6 */
 	0xff,				/* slot 7 */
 	0xff,				/* slot 8 */
-	AC97_PCM_FRONT_DAC_RATE,	/* slot 9 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 10 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 11 */
+	0xff,				/* slot 9 */
+	0xff,				/* slot 10 */
+	0xff,				/* slot 11 */
   },
   {
-  	/* 10&11 front, 3&4 rear, 7&8 center/lfe */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 3 */
-	AC97_PCM_SURR_DAC_RATE,		/* slot 4 */
+	0xff,				/* slot 3 */
+	0xff,				/* slot 4 */
 	0xff,				/* slot 5 */
 	0xff,				/* slot 6 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 7 */
-	AC97_PCM_LFE_DAC_RATE,		/* slot 8 */
+	0xff,				/* slot 7 */
+	0xff,				/* slot 8 */
 	0xff,				/* slot 9 */
-	AC97_PCM_FRONT_DAC_RATE,	/* slot 10 */
-	AC97_PCM_FRONT_DAC_RATE,	/* slot 11 */
+	0xff,				/* slot 10 */
+	0xff,				/* slot 11 */
   }
 }};
 
@@ -180,6 +178,7 @@
 	if (! (ac97->ext_id & AC97_EI_SPDIF))
 		return -ENODEV;
 
+	/* TODO: double rate support */
 	if (ac97->flags & AC97_CS_SPDIF) {
 		switch (rate) {
 		case 48000: bits = 0; break;
@@ -257,10 +256,19 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate)
+int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate)
 {
+	int dbl;
 	unsigned int tmp;
 	
+	dbl = rate > 48000;
+	if (dbl) {
+		if (!(ac97->flags & AC97_DOUBLE_RATE))
+			return -EINVAL;
+		if (reg != AC97_PCM_FRONT_DAC_RATE)
+			return -EINVAL;
+	}
+
 	switch (reg) {
 	case AC97_PCM_MIC_ADC_RATE:
 		if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRM) == 0)	/* MIC VRA */
@@ -270,7 +278,7 @@
 	case AC97_PCM_FRONT_DAC_RATE:
 	case AC97_PCM_LR_ADC_RATE:
 		if ((ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_VRA) == 0)	/* VRA */
-			if (rate != 48000)
+			if (rate != 48000 && rate != 96000)
 				return -EINVAL;
 		break;
 	case AC97_PCM_SURR_DAC_RATE:
@@ -287,9 +295,14 @@
 	default:
 		return -EINVAL;
 	}
-	tmp = ((unsigned int)rate * ac97->bus->clock) / 48000;
+	if (dbl)
+		rate /= 2;
+	tmp = (rate * ac97->bus->clock) / 48000;
 	if (tmp > 65535)
 		return -EINVAL;
+	if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
+		snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
+				     AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
 	snd_ac97_update(ac97, reg, tmp & 0xffff);
 	snd_ac97_read(ac97, reg);
 	return 0;
@@ -304,13 +317,13 @@
 		if (ac97_is_rev22(ac97)) {
 			/* Note: it's simply emulation of AMAP behaviour */
 			u16 es;
-			es = ac97->regs[AC97_EXTENDED_STATUS] &= ~AC97_EI_DACS_SLOT_MASK;
+			es = ac97->regs[AC97_EXTENDED_ID] &= ~AC97_EI_DACS_SLOT_MASK;
 			switch (ac97->addr) {
 			case 1:
 			case 2: es |= (1<<AC97_EI_DACS_SLOT_SHIFT); break;
 			case 3: es |= (2<<AC97_EI_DACS_SLOT_SHIFT); break;
 			}
-			snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, es);
+			snd_ac97_write_cache(ac97, AC97_EXTENDED_ID, es);
 		}
 		switch (ac97->addr) {
 		case 0:
@@ -401,6 +414,9 @@
 		}
 		rates &= pcm->r[dbl].codec[cidx]->rates[idx];
 	}
+	if (!dbl)
+		rates &= ~(SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 |
+			   SNDRV_PCM_RATE_96000);
 	return rates;
 }
 
@@ -447,7 +463,6 @@
 			}
 		}
 	}
-	/* FIXME: add double rate allocation */
 	/* first step - exclusive devices */
 	for (i = 0; i < pcms_count; i++) {
 		pcm = &pcms[i];
@@ -498,6 +513,26 @@
 			rpcm->r[0].slots |= tmp;
 			rpcm->rates &= rates;
 		}
+		/* for double rate, we check the first codec only */
+		if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+		    bus->codec[0] && (bus->codec[0]->flags & AC97_DOUBLE_RATE) &&
+		    rate_table[pcm->stream][0] == 0) {
+			tmp = (1<<AC97_SLOT_PCM_LEFT) | (1<<AC97_SLOT_PCM_RIGHT) |
+			      (1<<AC97_SLOT_PCM_LEFT_0) | (1<<AC97_SLOT_PCM_RIGHT_0);
+			if ((tmp & pcm->r[1].slots) == tmp) {
+				rpcm->r[1].slots = tmp;
+				rpcm->r[1].rslots[0] = tmp;
+				rpcm->r[1].rate_table[0] = 0;
+				rpcm->r[1].codec[0] = bus->codec[0];
+				if (pcm->exclusive)
+					avail_slots[pcm->stream][0] &= ~tmp;
+				if (bus->no_vra)
+					rates = SNDRV_PCM_RATE_96000;
+				else
+					rates = get_rates(rpcm, 0, tmp, 1);
+				rpcm->rates |= rates;
+			}
+		}
 		if (rpcm->rates == ~0)
 			rpcm->rates = 0; /* not used */
 	}
@@ -519,13 +554,12 @@
 		      enum ac97_pcm_cfg cfg, unsigned short slots)
 {
 	ac97_bus_t *bus;
-	int i, cidx, r = 0, ok_flag;
+	int i, cidx, r, ok_flag;
 	unsigned int reg_ok = 0;
 	unsigned char reg;
 	int err = 0;
 
-	if (rate > 48000)	/* FIXME: add support for double rate */
-		return -EINVAL;
+	r = rate > 48000;
 	bus = pcm->bus;
 	if (cfg == AC97_PCM_CFG_SPDIF) {
 		int err;
@@ -613,4 +647,56 @@
 	pcm->aslots = 0;
 	spin_unlock_irq(&pcm->bus->bus_lock);
 	return 0;
+}
+
+static int double_rate_hw_constraint_rate(snd_pcm_hw_params_t *params,
+					  snd_pcm_hw_rule_t *rule)
+{
+	snd_interval_t *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	if (channels->min > 2) {
+		static const snd_interval_t single_rates = {
+			.min = 1,
+			.max = 48000,
+		};
+		snd_interval_t *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+		return snd_interval_refine(rate, &single_rates);
+	}
+	return 0;
+}
+
+static int double_rate_hw_constraint_channels(snd_pcm_hw_params_t *params,
+					      snd_pcm_hw_rule_t *rule)
+{
+	snd_interval_t *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	if (rate->min > 48000) {
+		static const snd_interval_t double_rate_channels = {
+			.min = 2,
+			.max = 2,
+		};
+		snd_interval_t *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+		return snd_interval_refine(channels, &double_rate_channels);
+	}
+	return 0;
+}
+
+/**
+ * snd_ac97_pcm_double_rate_rules - set double rate constraints
+ * @runtime: the runtime of the ac97 front playback pcm
+ *
+ * Installs the hardware constraint rules to prevent using double rates and
+ * more than two channels at the same time.
+ */
+int snd_ac97_pcm_double_rate_rules(snd_pcm_runtime_t *runtime)
+{
+	int err;
+
+	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+				  double_rate_hw_constraint_rate, NULL,
+				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+	if (err < 0)
+		return err;
+	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+				  double_rate_hw_constraint_channels, NULL,
+				  SNDRV_PCM_HW_PARAM_RATE, -1);
+	return err;
 }
diff -Nru a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
--- a/sound/pci/ac97/ac97_proc.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ac97/ac97_proc.c	2004-10-21 14:13:16 -07:00
@@ -72,9 +72,10 @@
 {
 	char name[64];
 	unsigned short val, tmp, ext, mext;
-	static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=res" };
+	static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=10/11" };
 	static const char *spdif_rates[4] = { " Rate=44.1kHz", " Rate=res", " Rate=48kHz", " Rate=32kHz" };
 	static const char *spdif_rates_cs4205[4] = { " Rate=48kHz", " Rate=44.1kHz", " Rate=res", " Rate=res" };
+	static const char *double_rate_slots[4] = { "10/11", "7/8", "reserved", "reserved" };
 
 	snd_ac97_get_name(NULL, ac97->id, name, 0);
 	snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
@@ -137,6 +138,9 @@
 		    val & 0x0200 ? "Mic" : "MIX",
 		    val & 0x0100 ? "Mic2" : "Mic1",
 		    val & 0x0080 ? "on" : "off");
+	if (ac97->ext_id & AC97_EI_DRA)
+		snd_iprintf(buffer, "Double rate slots: %s\n",
+			    double_rate_slots[(val >> 10) & 3]);
 
 	ext = snd_ac97_read(ac97, AC97_EXTENDED_ID);
 	if (ext == 0)
diff -Nru a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/atiixp.c	2004-10-21 14:13:16 -07:00
@@ -1515,7 +1515,7 @@
 	}
 	chip->addr = pci_resource_start(pci, 0);
 	chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0));
-	if (chip->remap_addr == 0) {
+	if (chip->remap_addr == NULL) {
 		snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 		snd_atiixp_free(chip);
 		return -EIO;
@@ -1584,8 +1584,10 @@
 
 	snd_atiixp_chip_start(chip);
 
-	sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
-		card->shortname, revision, chip->addr, chip->irq);
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s rev %x with %s at %#lx, irq %i", card->shortname, revision,
+		 chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?",
+		 chip->addr, chip->irq);
 
 	snd_card_set_pm_callback(card, snd_atiixp_suspend, snd_atiixp_resume, chip);
 
diff -Nru a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
--- a/sound/pci/atiixp_modem.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/atiixp_modem.c	2004-10-21 14:13:16 -07:00
@@ -1237,7 +1237,7 @@
 	}
 	chip->addr = pci_resource_start(pci, 0);
 	chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0));
-	if (chip->remap_addr == 0) {
+	if (chip->remap_addr == NULL) {
 		snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 		snd_atiixp_free(chip);
 		return -EIO;
diff -Nru a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
--- a/sound/pci/au88x0/au88x0.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/au88x0/au88x0.c	2004-10-21 14:13:16 -07:00
@@ -215,7 +215,7 @@
 	vortex_core_shutdown(chip);
       core_out:
 	//FIXME: the type of chip->mmio might need to be changed??
-	iounmap((void *)chip->mmio);
+	iounmap(chip->mmio);
       ioremap_out:
 	pci_release_regions(chip->pci_dev);
       regions_out:
@@ -315,7 +315,7 @@
 #endif
 
 	// (5)
-	strcpy(card->driver, "Aureal Vortex");
+	strcpy(card->driver, CARD_NAME_SHORT);
 	strcpy(card->shortname, CARD_NAME_SHORT);
 	sprintf(card->longname, "%s at 0x%lx irq %i",
 		card->shortname, chip->io, chip->irq);
diff -Nru a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
--- a/sound/pci/au88x0/au88x0.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/au88x0/au88x0.h	2004-10-21 14:13:16 -07:00
@@ -169,7 +169,7 @@
 
 	/* PCI hardware resources */
 	unsigned long io;
-	unsigned long *mmio;
+	unsigned long __iomem *mmio;
 	unsigned int irq;
 	spinlock_t lock;
 
diff -Nru a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
--- a/sound/pci/au88x0/au88x0_eq.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/au88x0/au88x0_eq.c	2004-10-21 14:13:16 -07:00
@@ -52,37 +52,33 @@
 	hwwrite(vortex->mmio, 0x2b3c8, level);
 }
 
+static inline short sign_invert(short a)
+{
+	/* -(-32768) -> -32768 so we do -(-32768) -> 32767 to make the result positive */
+	if (a == -32768)
+		return 32767;
+	else
+		return -a;
+}
+
 static void vortex_EqHw_SetLeftCoefs(vortex_t * vortex, u16 coefs[])
 {
 	eqhw_t *eqhw = &(vortex->eq.this04);
-	int eax, i = 0, n /*esp2c */;
+	int i = 0, n /*esp2c */;
 
 	for (n = 0; n < eqhw->this04; n++) {
 		hwwrite(vortex->mmio, 0x2b000 + n * 0x30, coefs[i + 0]);
 		hwwrite(vortex->mmio, 0x2b004 + n * 0x30, coefs[i + 1]);
 
 		if (eqhw->this08 == 0) {
-			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2]);
-			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3]);
-			eax = coefs[i + 4];	//esp24;
+			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, coefs[i + 2] & 0xffff);
+			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, coefs[i + 3] & 0xffff);
+			hwwrite(vortex->mmio, 0x2b010 + n * 0x30, coefs[i + 4] & 0xffff);
 		} else {
-			if (coefs[2 + i] == 0x8000)
-				eax = 0x7fff;
-			else
-				eax = ~coefs[2 + i];
-			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, eax & 0xffff);
-			if (coefs[3 + i] == 0x8000)
-				eax = 0x7fff;
-			else
-				eax = ~coefs[3 + i];
-			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, eax & 0xffff);
-			if (coefs[4 + i] == 0x8000)
-				eax = 0x7fff;
-			else
-				eax = ~coefs[4 + i];
+			hwwrite(vortex->mmio, 0x2b008 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff);
+			hwwrite(vortex->mmio, 0x2b00c + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff);
+		        hwwrite(vortex->mmio, 0x2b010 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff);
 		}
-		hwwrite(vortex->mmio, 0x2b010 + n * 0x30, eax);
-
 		i += 5;
 	}
 }
@@ -90,33 +86,21 @@
 static void vortex_EqHw_SetRightCoefs(vortex_t * vortex, u16 coefs[])
 {
 	eqhw_t *eqhw = &(vortex->eq.this04);
-	int i = 0, n /*esp2c */, eax;
+	int i = 0, n /*esp2c */;
 
 	for (n = 0; n < eqhw->this04; n++) {
 		hwwrite(vortex->mmio, 0x2b1e0 + n * 0x30, coefs[0 + i]);
 		hwwrite(vortex->mmio, 0x2b1e4 + n * 0x30, coefs[1 + i]);
 
 		if (eqhw->this08 == 0) {
-			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i]);
-			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i]);
-			eax = coefs[4 + i];	//*esp24;
+			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, coefs[2 + i] & 0xffff);
+			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, coefs[3 + i] & 0xffff);
+			hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, coefs[4 + i] & 0xffff);
 		} else {
-			if (coefs[2 + i] == 0x8000)
-				eax = 0x7fff;
-			else
-				eax = ~(coefs[2 + i]);
-			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, eax & 0xffff);
-			if (coefs[3 + i] == 0x8000)
-				eax = 0x7fff;
-			else
-				eax = ~coefs[3 + i];
-			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, eax & 0xffff);
-			if (coefs[4 + i] == 0x8000)
-				eax = 0x7fff;
-			else
-				eax = ~coefs[4 + i];
+			hwwrite(vortex->mmio, 0x2b1e8 + n * 0x30, sign_invert(coefs[2 + i]) & 0xffff);
+			hwwrite(vortex->mmio, 0x2b1ec + n * 0x30, sign_invert(coefs[3 + i]) & 0xffff);
+			hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, sign_invert(coefs[4 + i]) & 0xffff);
 		}
-		hwwrite(vortex->mmio, 0x2b1f0 + n * 0x30, eax);
 		i += 5;
 	}
 
@@ -188,22 +172,12 @@
 static void vortex_EqHw_SetBypassGain(vortex_t * vortex, u16 a, u16 b)
 {
 	eqhw_t *eqhw = &(vortex->eq.this04);
-	int eax;
-
 	if (eqhw->this08 == 0) {
 		hwwrite(vortex->mmio, 0x2b3d4, a);
 		hwwrite(vortex->mmio, 0x2b3ec, b);
 	} else {
-		if (a == 0x8000)
-			eax = 0x7fff;
-		else
-			eax = ~a;
-		hwwrite(vortex->mmio, 0x2b3d4, eax & 0xffff);
-		if (b == 0x8000)
-			eax = 0x7fff;
-		else
-			eax = ~b;
-		hwwrite(vortex->mmio, 0x2b3ec, eax & 0xffff);
+		hwwrite(vortex->mmio, 0x2b3d4, sign_invert(a) & 0xffff);
+		hwwrite(vortex->mmio, 0x2b3ec, sign_invert(b) & 0xffff);
 	}
 }
 
diff -Nru a/sound/pci/bt87x.c b/sound/pci/bt87x.c
--- a/sound/pci/bt87x.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/bt87x.c	2004-10-21 14:13:16 -07:00
@@ -139,6 +139,14 @@
 #define RISC_SYNC_FM1	0x6
 #define RISC_SYNC_VRO	0xc
 
+#define ANALOG_CLOCK 1792000
+#ifdef CONFIG_SND_BT87X_OVERCLOCK
+#define CLOCK_DIV_MIN 1
+#else
+#define CLOCK_DIV_MIN 4
+#endif
+#define CLOCK_DIV_MAX 15
+
 #define ERROR_INTERRUPTS (INT_FBUS | INT_FTRGT | INT_PPERR | \
 			  INT_RIPERR | INT_PABORT | INT_OCERR)
 #define MY_INTERRUPTS (INT_RISCI | ERROR_INTERRUPTS)
@@ -264,7 +272,7 @@
 				   status, pci_status);
 		}
 	}
-	if (status & INT_RISCI) {
+	if ((status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
 		int current_block, irq_block;
 
 		/* assume that exactly one line has been recorded */
@@ -303,8 +311,8 @@
 		SNDRV_PCM_INFO_MMAP_VALID,
 	.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
 	.rates = SNDRV_PCM_RATE_KNOT,
-	.rate_min = 119466,
-	.rate_max = 448000,
+	.rate_min = ANALOG_CLOCK / CLOCK_DIV_MAX,
+	.rate_max = ANALOG_CLOCK / CLOCK_DIV_MIN,
 	.channels_min = 1,
 	.channels_max = 1,
 	.buffer_bytes_max = 255 * 4092,
@@ -346,9 +354,9 @@
 static int snd_bt87x_set_analog_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
 {
 	static ratnum_t analog_clock = {
-		.num = 1792000,
-		.den_min = 4,
-		.den_max = 15,
+		.num = ANALOG_CLOCK,
+		.den_min = CLOCK_DIV_MIN,
+		.den_max = CLOCK_DIV_MAX,
 		.den_step = 1
 	};
 	static snd_pcm_hw_constraint_ratnums_t constraint_rates = {
@@ -433,7 +441,7 @@
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->reg_control &= ~(CTL_DA_SDR_MASK | CTL_DA_SBR);
-	decimation = (1792000 + runtime->rate / 4) / runtime->rate;
+	decimation = (ANALOG_CLOCK + runtime->rate / 4) / runtime->rate;
 	chip->reg_control |= decimation << CTL_DA_SDR_SHIFT;
 	if (runtime->format == SNDRV_PCM_FORMAT_S8)
 		chip->reg_control |= CTL_DA_SBR;
diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c
--- a/sound/pci/cs4281.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/cs4281.c	2004-10-21 14:13:16 -07:00
@@ -463,8 +463,8 @@
 struct snd_cs4281 {
 	int irq;
 
-	unsigned long ba0;		/* virtual (accessible) address */
-	unsigned long ba1;		/* virtual (accessible) address */
+	void __iomem *ba0;		/* virtual (accessible) address */
+	void __iomem *ba1;		/* virtual (accessible) address */
 	unsigned long ba0_addr;
 	unsigned long ba1_addr;
 
@@ -1358,9 +1358,9 @@
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
 	if (chip->ba0)
-		iounmap((void *) chip->ba0);
+		iounmap(chip->ba0);
 	if (chip->ba1)
-		iounmap((void *) chip->ba1);
+		iounmap(chip->ba1);
 	pci_release_regions(chip->pci);
 
 	kfree(chip);
@@ -1422,8 +1422,8 @@
 	}
 	chip->irq = pci->irq;
 
-	chip->ba0 = (unsigned long) ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
-	chip->ba1 = (unsigned long) ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
+	chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
+	chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
 	if (!chip->ba0 || !chip->ba1) {
 		snd_cs4281_free(chip);
 		return -ENOMEM;
@@ -1913,6 +1913,31 @@
 }
 
 
+/*
+ * OPL3 command
+ */
+static void snd_cs4281_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+{
+	unsigned long flags;
+	cs4281_t *chip = opl3->private_data;
+	void __iomem *port;
+
+	if (cmd & OPL3_RIGHT)
+		port = chip->ba0 + BA0_B1AP; /* right port */
+	else
+		port = chip->ba0 + BA0_B0AP; /* left port */
+
+	spin_lock_irqsave(&opl3->reg_lock, flags);
+
+	writel((unsigned int)cmd, port);
+	udelay(10);
+
+	writel((unsigned int)val, port + 4);
+	udelay(30);
+
+	spin_unlock_irqrestore(&opl3->reg_lock, flags);
+}
+
 static int __devinit snd_cs4281_probe(struct pci_dev *pci,
 				      const struct pci_device_id *pci_id)
 {
@@ -1950,13 +1975,13 @@
 		snd_card_free(card);
 		return err;
 	}
-	if ((err = snd_opl3_create(card,
-				   (chip->ba0 + BA0_B0AP) >> 2,
-				   (chip->ba0 + BA0_B1AP) >> 2,
-				   OPL3_HW_OPL3_CS4281, 1, &opl3)) < 0) {
+	if ((err = snd_opl3_new(card, OPL3_HW_OPL3_CS4281, &opl3)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
+	opl3->private_data = chip;
+	opl3->command = snd_cs4281_opl3_command;
+	snd_opl3_init(opl3);
 	if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
 		snd_card_free(card);
 		return err;
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/cs46xx/cs46xx_lib.c	2004-10-21 14:13:16 -07:00
@@ -203,12 +203,6 @@
 
 	val = snd_cs46xx_codec_read(chip, reg, codec_index);
 
-	/* HACK: voyetra uses EAPD bit in the reverse way.
-	 * we flip the bit to show the mixer status correctly
-	 */
-	if (reg == AC97_POWERDOWN && chip->amplifier_ctrl == amp_voyetra)
-		val ^= 0x8000;
-
 	return val;
 }
 
@@ -289,12 +283,6 @@
 		   codec_index == CS46XX_SECONDARY_CODEC_INDEX,
 		   return);
 
-	/* HACK: voyetra uses EAPD bit in the reverse way.
-	 * we flip the bit to show the mixer status correctly
-	 */
-	if (reg == AC97_POWERDOWN && chip->amplifier_ctrl == amp_voyetra)
-		val ^= 0x8000;
-
 	snd_cs46xx_codec_write(chip, reg, val, codec_index);
 }
 
@@ -308,7 +296,7 @@
                         unsigned long offset,
                         unsigned long len)
 {
-	unsigned long dst;
+	void __iomem *dst;
 	unsigned int bank = offset >> 16;
 	offset = offset & 0xffff;
 
@@ -336,7 +324,7 @@
                          unsigned long offset,
                          unsigned long len) 
 {
-	unsigned long dst;
+	void __iomem *dst;
 	unsigned int bank = offset >> 16;
 	offset = offset & 0xffff;
 
@@ -2333,16 +2321,15 @@
 {
 	unsigned long end_time;
 	int err;
-	cs46xx_t * chip = ac97->private_data;
 
 	/* reset to defaults */
 	snd_ac97_write(ac97, AC97_RESET, 0);	
 
 	/* set the desired CODEC mode */
-	if (chip->nr_ac97_codecs == 0) {
+	if (ac97->num == CS46XX_PRIMARY_CODEC_INDEX) {
 		snd_printdd("cs46xx: CODOEC1 mode %04x\n",0x0);
 		snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x0);
-	} else if (chip->nr_ac97_codecs == 1) {
+	} else if (ac97->num == CS46XX_SECONDARY_CODEC_INDEX) {
 		snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3);
 		snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3);
 	} else {
@@ -2380,10 +2367,43 @@
 }
 #endif
 
+static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec)
+{
+	int idx, err;
+	ac97_template_t ac97;
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = chip;
+	ac97.private_free = snd_cs46xx_mixer_free_ac97;
+	ac97.num = codec;
+	if (chip->amplifier_ctrl == amp_voyetra)
+		ac97.scaps = AC97_SCAP_INV_EAPD;
+
+	if (codec == CS46XX_SECONDARY_CODEC_INDEX) {
+		snd_cs46xx_codec_write(chip, AC97_RESET, 0, codec);
+		udelay(10);
+		if (snd_cs46xx_codec_read(chip, AC97_RESET, codec) & 0x8000) {
+			snd_printdd("snd_cs46xx: seconadry codec not present\n");
+			return -ENXIO;
+		}
+	}
+
+	snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, codec);
+	for (idx = 0; idx < 100; ++idx) {
+		if (snd_cs46xx_codec_read(chip, AC97_MASTER, codec) == 0x8000) {
+			err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
+			return err;
+		}
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/100);
+	}
+	snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec);
+	return -ENXIO;
+}
+
 int __devinit snd_cs46xx_mixer(cs46xx_t *chip)
 {
 	snd_card_t *card = chip->card;
-	ac97_template_t ac97;
 	snd_ctl_elem_id_t id;
 	int err;
 	unsigned int idx;
@@ -2402,70 +2422,15 @@
 		return err;
 	chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus;
 
-	memset(&ac97, 0, sizeof(ac97));
-	ac97.private_data = chip;
-	ac97.private_free = snd_cs46xx_mixer_free_ac97;
-
-	snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000,
-			       CS46XX_PRIMARY_CODEC_INDEX);
-	for (idx = 0; idx < 100; ++idx) {
-		if (snd_cs46xx_codec_read(chip, AC97_MASTER,
-					  CS46XX_PRIMARY_CODEC_INDEX) == 0x8000)
-			goto _ok;
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ/100);
-	}
-	return -ENXIO;
-
- _ok:
-	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[CS46XX_PRIMARY_CODEC_INDEX])) < 0)
-		return err;
-	snd_printdd("snd_cs46xx: primary codec phase one\n");
+	if (cs46xx_detect_codec(chip, CS46XX_PRIMARY_CODEC_INDEX) < 0)
+		return -ENXIO;
 	chip->nr_ac97_codecs = 1;
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	snd_printdd("snd_cs46xx: detecting seconadry codec\n");
 	/* try detect a secondary codec */
-	memset(&ac97, 0, sizeof(ac97));    
-	ac97.private_data = chip;
-	ac97.private_free = snd_cs46xx_mixer_free_ac97;
-	ac97.num = CS46XX_SECONDARY_CODEC_INDEX;
-
-	snd_cs46xx_codec_write(chip, AC97_RESET, 0,
-			       CS46XX_SECONDARY_CODEC_INDEX);
-	udelay(10);
-
-	if (snd_cs46xx_codec_read(chip, AC97_RESET,
-				  CS46XX_SECONDARY_CODEC_INDEX) & 0x8000) {
-		snd_printdd("snd_cs46xx: seconadry codec not present\n");
-		goto _no_sec_codec;
-	}
-
-	snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000,
-			       CS46XX_SECONDARY_CODEC_INDEX);
-	for (idx = 0; idx < 100; ++idx) {
-		if (snd_cs46xx_codec_read(chip, AC97_MASTER,
-					  CS46XX_SECONDARY_CODEC_INDEX) == 0x8000) {
-			goto _ok2;
-		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ/100);
-	}
-
- _no_sec_codec:
-	snd_printdd("snd_cs46xx: secondary codec did not respond ...\n");
-
-	chip->nr_ac97_codecs = 1;
-    
-	/* well, one codec only ... */
-	goto _end;
- _ok2:
-	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])) < 0)
-		return err;
-	chip->nr_ac97_codecs = 2;
-
- _end:
-
+	if (! cs46xx_detect_codec(chip, CS46XX_SECONDARY_CODEC_INDEX))
+		chip->nr_ac97_codecs = 2;
 #endif /* CONFIG_SND_CS46XX_NEW_DSP */
 
 	/* add cs4630 mixer controls */
@@ -2483,15 +2448,14 @@
 	chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
     
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	if (chip->nr_ac97_codecs == 1 && 
-	    (snd_cs46xx_codec_read(chip, AC97_VENDOR_ID2,
-				  CS46XX_PRIMARY_CODEC_INDEX) == 0x592b ||
-	     snd_cs46xx_codec_read(chip, AC97_VENDOR_ID2,
-				   CS46XX_PRIMARY_CODEC_INDEX) == 0x592d)) {
-		/* set primary cs4294 codec into Extended Audio Mode */
-		snd_printdd("setting EAM bit on cs4294 CODEC\n");
-		snd_cs46xx_codec_write(chip, AC97_CSR_ACMODE, 0x200,
-				       CS46XX_PRIMARY_CODEC_INDEX);
+	if (chip->nr_ac97_codecs == 1) {
+		unsigned int id2 = chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]->id & 0xffff;
+		if (id2 == 0x592b || id2 == 0x592d) {
+			/* set primary cs4294 codec into Extended Audio Mode */
+			snd_printdd("setting EAM bit on cs4294 CODEC\n");
+			snd_cs46xx_codec_write(chip, AC97_CSR_ACMODE, 0x200,
+					       CS46XX_PRIMARY_CODEC_INDEX);
+		}
 	}
 	/* do soundcard specific mixer setup */
 	if (chip->mixer_init) {
@@ -2902,7 +2866,7 @@
 	for (idx = 0; idx < 5; idx++) {
 		snd_cs46xx_region_t *region = &chip->region.idx[idx];
 		if (region->remap_addr)
-			iounmap((void *) region->remap_addr);
+			iounmap(region->remap_addr);
 		if (region->resource) {
 			release_resource(region->resource);
 			kfree_nocheck(region->resource);
@@ -3868,8 +3832,8 @@
 			snd_cs46xx_free(chip);
 			return -EBUSY;
 		}
-		region->remap_addr = (unsigned long) ioremap_nocache(region->base, region->size);
-		if (region->remap_addr == 0) {
+		region->remap_addr = ioremap_nocache(region->base, region->size);
+		if (region->remap_addr == NULL) {
 			snd_printk("%s ioremap problem\n", region->name);
 			snd_cs46xx_free(chip);
 			return -ENOMEM;
diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
--- a/sound/pci/cs46xx/dsp_spos.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/cs46xx/dsp_spos.c	2004-10-21 14:13:16 -07:00
@@ -514,7 +514,7 @@
 	cs46xx_t *chip = entry->private_data;
 	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
 	int i,j,col;
-	unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
+	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
 
 	down(&chip->spos_mutex);
 	snd_iprintf(buffer, "TASK TREES:\n");
@@ -573,7 +573,7 @@
 	cs46xx_t *chip = entry->private_data;
 	/*dsp_spos_instance_t * ins = chip->dsp_spos_instance; */
 	unsigned int i,col = 0;
-	unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
+	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
 	symbol_entry_t * symbol; 
 
 	for (i = 0;i < DSP_PARAMETER_BYTE_SIZE; i += sizeof(u32),col ++) {
@@ -599,7 +599,7 @@
 {
 	cs46xx_t *chip = entry->private_data;
 	int i,col = 0;
-	unsigned long dst = chip->region.idx[2].remap_addr;
+	void __iomem *dst = chip->region.idx[2].remap_addr;
 
 	snd_iprintf(buffer,"PCMREADER:\n");
 	for (i = PCM_READER_BUF1;i < PCM_READER_BUF1 + 0x30; i += sizeof(u32),col ++) {
@@ -909,7 +909,7 @@
 static int debug_tree;
 static void _dsp_create_task_tree (cs46xx_t *chip,u32 * task_data, u32  dest, int size)
 {
-	unsigned long spdst = chip->region.idx[1].remap_addr + 
+	void __iomem *spdst = chip->region.idx[1].remap_addr + 
 		DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
 	int i;
 
@@ -923,7 +923,7 @@
 static int debug_scb;
 static void _dsp_create_scb (cs46xx_t *chip,u32 * scb_data, u32  dest)
 {
-	unsigned long spdst = chip->region.idx[1].remap_addr + 
+	void __iomem *spdst = chip->region.idx[1].remap_addr + 
 		DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
 	int i;
 
diff -Nru a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c	2004-10-21 14:13:16 -07:00
@@ -71,7 +71,7 @@
 	dsp_spos_instance_t * ins;
 	cs46xx_t *chip = scb_info->chip;
 	int j,col;
-	unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
+	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
 
 	ins = chip->dsp_spos_instance;
 
@@ -162,7 +162,7 @@
 
 static void _dsp_clear_sample_buffer (cs46xx_t *chip, u32 sample_buffer_addr, int dword_count) 
 {
-	unsigned long dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
+	void __iomem *dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
 	int i;
   
 	for (i = 0; i < dword_count ; ++i ) {
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/emu10k1/emufx.c	2004-10-21 14:13:16 -07:00
@@ -480,7 +480,7 @@
 static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
 					u32 op, u32 r, u32 a, u32 x, u32 y)
 {
-	snd_assert(*ptr < 512, return);
+	snd_assert(*ptr < 1024, return);
 	set_bit(*ptr, icode->code_valid);
 	icode->code[*ptr    ][0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
 	icode->code[(*ptr)++][1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
@@ -505,7 +505,7 @@
 {
 	int gpr;
 
-	for (gpr = 0; gpr < 0x100; gpr++) {
+	for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
 		if (!test_bit(gpr, icode->gpr_valid))
 			continue;
 		snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, icode->gpr_map[gpr]);
@@ -516,7 +516,7 @@
 {
 	int gpr;
 
-	for (gpr = 0; gpr < 0x100; gpr++) {
+	for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
 		set_bit(gpr, icode->gpr_valid);
 		icode->gpr_map[gpr] = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
 	}
@@ -526,11 +526,16 @@
 {
 	int tram;
 
-	for (tram = 0; tram < 0xa0; tram++) {
+	for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
 		if (!test_bit(tram, icode->tram_valid))
 			continue;
 		snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, icode->tram_data_map[tram]);
-		snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
+		if (!emu->audigy)
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram]);
+		else {
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, icode->tram_addr_map[tram] << 12);
+			snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, icode->tram_addr_map[tram] >> 20);
+		}
 	}
 }
 
@@ -539,10 +544,15 @@
 	int tram;
 
 	memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
-	for (tram = 0; tram < 0xa0; tram++) {
+	for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
 		set_bit(tram, icode->tram_valid);
 		icode->tram_data_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
-		icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
+		if (!emu->audigy)
+			icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
+		else {
+			icode->tram_addr_map[tram] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
+			icode->tram_addr_map[tram] |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
+		}
 	}
 }
 
@@ -550,7 +560,7 @@
 {
 	u32 pc;
 
-	for (pc = 0; pc < 512; pc++) {
+	for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
 		if (!test_bit(pc, icode->code_valid))
 			continue;
 		snd_emu10k1_efx_write(emu, pc * 2, icode->code[pc][0]);
@@ -563,7 +573,7 @@
 	u32 pc;
 
 	memset(icode->code_valid, 0, sizeof(icode->code_valid));
-	for (pc = 0; pc < 512; pc++) {
+	for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
 		set_bit(pc, icode->code_valid);
 		icode->code[pc][0] = snd_emu10k1_efx_read(emu, pc * 2);
 		icode->code[pc][1] = snd_emu10k1_efx_read(emu, pc * 2 + 1);
@@ -962,8 +972,12 @@
 	}
 
 	/* clear free GPRs */
-	for (i = 0; i < 256; i++)
+	for (i = 0; i < 512; i++)
 		set_bit(i, icode->gpr_valid);
+		
+	/* clear TRAM data & address lines */
+	for (i = 0; i < 256; i++)
+		set_bit(i, icode->tram_valid);
 
 	strcpy(icode->name, "Audigy DSP code for ALSA");
 	ptr = 0;
@@ -1311,7 +1325,7 @@
 		goto __err;
 	}
 	/* clear remaining instruction memory */
-	while (ptr < 0x200)
+	while (ptr < 0x400)
 		A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
 
 	seg = snd_enter_user();
@@ -2067,8 +2081,6 @@
 		kfree(icode);
 		return res;
 	case SNDRV_EMU10K1_IOCTL_PCM_POKE:
-		if (emu->audigy)
-			return -EINVAL;
 		ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
 		if (ipcm == NULL)
 			return -ENOMEM;
@@ -2080,8 +2092,6 @@
 		kfree(ipcm);
 		return res;
 	case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
-		if (emu->audigy)
-			return -EINVAL;
 		ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
 		if (ipcm == NULL)
 			return -ENOMEM;
@@ -2097,8 +2107,6 @@
 		kfree(ipcm);
 		return res;
 	case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
-		if (emu->audigy)
-			return -EINVAL;
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		if (get_user(addr, (unsigned int __user *)argp))
diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/emu10k1/emupcm.c	2004-10-21 14:13:16 -07:00
@@ -1092,6 +1092,7 @@
 	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int nval[2], bits;
 	int nefx = emu->audigy ? 64 : 32;
+	int nefxb = emu->audigy ? 7 : 6;
 	int change, idx;
 	
 	nval[0] = nval[1] = 0;
@@ -1100,8 +1101,14 @@
 			nval[idx / 32] |= 1 << (idx % 32);
 			bits++;
 		}
-	if (bits != 1 && bits != 2 && bits != 4 && bits != 8)
+		
+	for (idx = 0; idx < nefxb; idx++)
+		if (1 << idx == bits)
+			break;
+	
+	if (idx >= nefxb)
 		return -EINVAL;
+
 	spin_lock_irq(&emu->reg_lock);
 	change = (nval[0] != emu->efx_voices_mask[0]) ||
 		(nval[1] != emu->efx_voices_mask[1]);
@@ -1185,7 +1192,7 @@
 	}
 	snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
 					       (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
-					       src, frames, tram_shift++);
+					       src, frames, tram_shift);
 	tram_pos -= frames;
 	pcm->tram_pos = tram_pos;
 	pcm->tram_shift = tram_shift;
diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/emu10k1/emuproc.c	2004-10-21 14:13:16 -07:00
@@ -229,7 +229,7 @@
 
 	snd_iprintf(buffer, "FX8010 Instruction List '%s'\n", emu->fx8010.name);
 	snd_iprintf(buffer, "  Code dump      :\n");
-	for (pc = 0; pc < 512; pc++) {
+	for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
 		u32 low, high;
 			
 		low = snd_emu10k1_efx_read(emu, pc * 2);
@@ -256,9 +256,13 @@
 }
 
 #define TOTAL_SIZE_GPR		(0x100*4)
+#define A_TOTAL_SIZE_GPR	(0x200*4)
 #define TOTAL_SIZE_TANKMEM_DATA	(0xa0*4)
 #define TOTAL_SIZE_TANKMEM_ADDR (0xa0*4)
+#define A_TOTAL_SIZE_TANKMEM_DATA (0x100*4)
+#define A_TOTAL_SIZE_TANKMEM_ADDR (0x100*4)
 #define TOTAL_SIZE_CODE		(0x200*8)
+#define A_TOTAL_SIZE_CODE	(0x400*8)
 
 static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
 				    struct file *file, char __user *buf,
@@ -267,12 +271,12 @@
 	long size;
 	emu10k1_t *emu = entry->private_data;
 	unsigned int offset;
+	int tram_addr = 0;
 	
 	if (!strcmp(entry->name, "fx8010_tram_addr")) {
-		if (emu->audigy) return -EINVAL;
 		offset = TANKMEMADDRREGBASE;
+		tram_addr = 1;
 	} else if (!strcmp(entry->name, "fx8010_tram_data")) {
-		if (emu->audigy) return -EINVAL;
 		offset = TANKMEMDATAREGBASE;
 	} else if (!strcmp(entry->name, "fx8010_code")) {
 		offset = emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
@@ -289,7 +293,11 @@
 		if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 		for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++)
-			tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
+			if (tram_addr && emu->audigy) {
+				tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
+				tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
+			} else 
+				tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
 		if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
 			res = -EFAULT;
 		else {
@@ -316,35 +324,35 @@
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
 		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
-		entry->size = TOTAL_SIZE_GPR;
+		entry->size = emu->audigy ? A_TOTAL_SIZE_GPR : TOTAL_SIZE_GPR;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
 	}
-	if (!emu->audigy && ! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) {
+	if (! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
 		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
-		entry->size = TOTAL_SIZE_TANKMEM_DATA;
+		entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_DATA : TOTAL_SIZE_TANKMEM_DATA ;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
 	}
-	if (!emu->audigy && ! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) {
+	if (! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
 		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
-		entry->size = TOTAL_SIZE_TANKMEM_ADDR;
+		entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_ADDR : TOTAL_SIZE_TANKMEM_ADDR ;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
 	}
 	if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_DATA;
 		entry->private_data = emu;
 		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
-		entry->size = TOTAL_SIZE_CODE;
+		entry->size = emu->audigy ? A_TOTAL_SIZE_CODE : TOTAL_SIZE_CODE;
 		entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
 	}
 	if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) {
 		entry->content = SNDRV_INFO_CONTENT_TEXT;
 		entry->private_data = emu;
 		entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
-		entry->c.text.read_size = 64*1024;
+		entry->c.text.read_size = 128*1024;
 		entry->c.text.read = snd_emu10k1_proc_acode_read;
 	}
 	return 0;
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ens1370.c	2004-10-21 14:13:16 -07:00
@@ -371,6 +371,7 @@
 
 struct _snd_ensoniq {
 	spinlock_t reg_lock;
+	struct semaphore src_mutex;
 
 	int irq;
 
@@ -512,6 +513,7 @@
 		r = inl(ES_REG(ensoniq, 1371_SMPRATE));
 		if ((r & ES_1371_SRC_RAM_BUSY) == 0)
 			return r;
+		cond_resched();
 	}
 	snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
 	return 0;
@@ -695,6 +697,7 @@
 {
 	unsigned int n, truncm, freq, result;
 
+	down(&ensoniq->src_mutex);
 	n = rate / 3000;
 	if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
 		n--;
@@ -718,12 +721,14 @@
 	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
 	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
 	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
+	up(&ensoniq->src_mutex);
 }
 
 static void snd_es1371_dac1_rate(ensoniq_t * ensoniq, unsigned int rate)
 {
 	unsigned int freq, r;
 
+	down(&ensoniq->src_mutex);
 	freq = ((rate << 15) + 1500) / 3000;
 	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | ES_1371_DIS_P1;
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
@@ -733,12 +738,14 @@
 	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
 	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1));
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
+	up(&ensoniq->src_mutex);
 }
 
 static void snd_es1371_dac2_rate(ensoniq_t * ensoniq, unsigned int rate)
 {
 	unsigned int freq, r;
 
+	down(&ensoniq->src_mutex);
 	freq = ((rate << 15) + 1500) / 3000;
 	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | ES_1371_DIS_P2;
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
@@ -748,6 +755,7 @@
 	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
 	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1));
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
+	up(&ensoniq->src_mutex);
 }
 
 #endif /* CHIP1371 */
@@ -845,6 +853,13 @@
 		mode |= 0x01;
 	spin_lock_irq(&ensoniq->reg_lock);
 	ensoniq->ctrl &= ~ES_DAC1_EN;
+#ifdef CHIP1371
+	/* 48k doesn't need SRC (it breaks AC3-passthru) */
+	if (runtime->rate == 48000)
+		ensoniq->ctrl |= ES_1373_BYPASS_P1;
+	else
+		ensoniq->ctrl &= ~ES_1373_BYPASS_P1;
+#endif
 	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
 	outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));
 	outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));
@@ -862,11 +877,12 @@
 	case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;
 	default: snd_BUG();
 	}
-#else
-	snd_es1371_dac1_rate(ensoniq, runtime->rate);
 #endif
 	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
 	spin_unlock_irq(&ensoniq->reg_lock);
+#ifndef CHIP1370
+	snd_es1371_dac1_rate(ensoniq, runtime->rate);
+#endif
 	return 0;
 }
 
@@ -900,11 +916,12 @@
 		ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
 		ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;
 	}
-#else
-	snd_es1371_dac2_rate(ensoniq, runtime->rate);
 #endif
 	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
 	spin_unlock_irq(&ensoniq->reg_lock);
+#ifndef CHIP1370
+	snd_es1371_dac2_rate(ensoniq, runtime->rate);
+#endif
 	return 0;
 }
 
@@ -936,11 +953,12 @@
 		ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));
 		ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;
 	}
-#else
-	snd_es1371_adc_rate(ensoniq, runtime->rate);
 #endif
 	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
 	spin_unlock_irq(&ensoniq->reg_lock);
+#ifndef CHIP1370
+	snd_es1371_adc_rate(ensoniq, runtime->rate);
+#endif
 	return 0;
 }
 
@@ -1878,6 +1896,7 @@
 	if (ensoniq == NULL)
 		return -ENOMEM;
 	spin_lock_init(&ensoniq->reg_lock);
+	init_MUTEX(&ensoniq->src_mutex);
 	ensoniq->card = card;
 	ensoniq->pci = pci;
 	ensoniq->irq = -1;
diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/es1968.c	2004-10-21 14:13:16 -07:00
@@ -555,6 +555,11 @@
 	int playback_streams, capture_streams;
 
 	unsigned int clock;		/* clock */
+	/* for clock measurement */
+	unsigned int in_measurement: 1;
+	unsigned int measure_apu;
+	unsigned int measure_lastpos;
+	unsigned int measure_count;
 
 	/* buffer */
 	struct snd_dma_buffer dma;
@@ -579,6 +584,7 @@
 	snd_rawmidi_t *rmidi;
 
 	spinlock_t reg_lock;
+	struct semaphore ac97_mutex;	/* ac97 lock */
 	struct tasklet_struct hwvol_tq;
 
 	/* Maestro Stuff */
@@ -671,6 +677,7 @@
 	while (timeout-- > 0) {
 		if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
 			return 0;
+		cond_resched();
 	}
 	snd_printd("es1968: ac97 timeout\n");
 	return 1; /* timeout */
@@ -679,39 +686,35 @@
 static void snd_es1968_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
 {
 	es1968_t *chip = ac97->private_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&chip->reg_lock, flags);
 
+	down(&chip->ac97_mutex);
 	snd_es1968_ac97_wait(chip);
 
 	/* Write the bus */
 	outw(val, chip->io_port + ESM_AC97_DATA);
-	mdelay(1);
+	msleep(1);
 	outb(reg, chip->io_port + ESM_AC97_INDEX);
-	mdelay(1);
+	msleep(1);
 
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	up(&chip->ac97_mutex);
 }
 
 static unsigned short snd_es1968_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	u16 data = 0;
 	es1968_t *chip = ac97->private_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&chip->reg_lock, flags);
 
+	down(&chip->ac97_mutex);
 	snd_es1968_ac97_wait(chip);
 
 	outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
-	mdelay(1);
+	msleep(1);
 
 	if (! snd_es1968_ac97_wait(chip)) {
 		data = inw(chip->io_port + ESM_AC97_DATA);
-		mdelay(1);
+		msleep(1);
 	}
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	up(&chip->ac97_mutex);
 
 	return data;
 }
@@ -1803,30 +1806,28 @@
 
 	snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */
 
+	chip->in_measurement = 1;
+	chip->measure_apu = apu;
 	spin_lock_irq(&chip->reg_lock);
+	snd_es1968_bob_inc(chip, ESM_BOB_FREQ);
 	__apu_set_register(chip, apu, 5, pa & 0xffff);
 	snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
 	do_gettimeofday(&start_time);
 	spin_unlock_irq(&chip->reg_lock);
-#if 0
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(HZ / 20); /* 50 msec */
-#else
-	/* FIXME:
-	 * schedule() above may be too inaccurate and the pointer can
-	 * overlap the boundary..
-	 */
-	mdelay(50);
-#endif
 	spin_lock_irq(&chip->reg_lock);
 	offset = __apu_get_register(chip, apu, 5);
 	do_gettimeofday(&stop_time);
 	snd_es1968_trigger_apu(chip, apu, 0); /* stop */
+	snd_es1968_bob_dec(chip);
+	chip->in_measurement = 0;
 	spin_unlock_irq(&chip->reg_lock);
 
 	/* check the current position */
 	offset -= (pa & 0xffff);
 	offset &= 0xfffe;
+	offset += chip->measure_count * (CLOCK_MEASURE_BUFSIZE/2);
 
 	t = stop_time.tv_sec - start_time.tv_sec;
 	t *= 1000000;
@@ -2004,6 +2005,12 @@
 				snd_es1968_update_pcm(chip, es);
 		}
 		spin_unlock(&chip->substream_lock);
+		if (chip->in_measurement) {
+			unsigned int curp = __apu_get_register(chip, chip->measure_apu, 5);
+			if (curp < chip->measure_lastpos)
+				chip->measure_count++;
+			chip->measure_lastpos = curp;
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -2524,6 +2531,7 @@
 	spin_lock_init(&chip->substream_lock);
 	INIT_LIST_HEAD(&chip->buf_list);
 	INIT_LIST_HEAD(&chip->substream_list);
+	init_MUTEX(&chip->ac97_mutex);
 	init_MUTEX(&chip->memory_mutex);
 	tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
 	chip->card = card;
diff -Nru a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
--- a/sound/pci/ice1712/Makefile	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/Makefile	2004-10-21 14:13:16 -07:00
@@ -5,7 +5,7 @@
 
 snd-ice17xx-ak4xxx-objs := ak4xxx.o
 snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o
+snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
diff -Nru a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
--- a/sound/pci/ice1712/aureon.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/aureon.c	2004-10-21 14:13:16 -07:00
@@ -89,6 +89,235 @@
 #define WM_OUT_MUX2		0x1e	/* output MUX */
 #define WM_RESET		0x1f	/* software reset */
 
+static void aureon_ac97_write(ice1712_t *ice, unsigned short reg, unsigned short val) {
+	unsigned int tmp;
+
+	/* Send address to XILINX chip */
+	tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp |= AUREON_AC97_ADDR;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp &= ~AUREON_AC97_ADDR;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);	
+
+	/* Send low-order byte to XILINX chip */
+	tmp &= ~AUREON_AC97_DATA_MASK;
+	tmp |= val & AUREON_AC97_DATA_MASK;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp |= AUREON_AC97_DATA_LOW;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp &= ~AUREON_AC97_DATA_LOW;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	
+	/* Send high-order byte to XILINX chip */
+	tmp &= ~AUREON_AC97_DATA_MASK;
+	tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
+
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp |= AUREON_AC97_DATA_HIGH;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp &= ~AUREON_AC97_DATA_HIGH;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	
+	/* Instruct XILINX chip to parse the data to the STAC9744 chip */
+	tmp |= AUREON_AC97_COMMIT;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	tmp &= ~AUREON_AC97_COMMIT;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(10);
+	
+	/* Store the data in out private buffer */
+	ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
+}
+
+static unsigned short aureon_ac97_read(ice1712_t *ice, unsigned short reg)
+{
+       return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
+}
+
+/*
+ * Initialize STAC9744 chip
+ */
+static int aureon_ac97_init (ice1712_t *ice) {
+	int i;
+	static unsigned short ac97_defaults[] = {
+		0x00, 0x9640,
+		0x02, 0x8000,
+		0x04, 0x8000,
+		0x06, 0x8000,
+		0x0C, 0x8008,
+		0x0E, 0x8008,
+		0x10, 0x8808,
+		0x12, 0x8808,
+		0x14, 0x8808,
+		0x16, 0x8808,
+		0x18, 0x8808,
+		0x1C, 0x8000,
+		0x26, 0x000F,
+		0x28, 0x0201,
+		0x2C, 0xBB80,
+		0x32, 0xBB80,
+		0x7C, 0x8384,
+		0x7E, 0x7644,
+		(unsigned short)-1
+	};
+	unsigned int tmp;
+
+	/* Cold reset */
+	tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(3);
+	
+	tmp &= ~AUREON_AC97_RESET;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(3);
+	
+	tmp |= AUREON_AC97_RESET;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(3);
+	
+	memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
+	for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
+		ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
+		
+	aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
+
+	return 0;
+}
+
+#define AUREON_AC97_STEREO	0x80
+
+/*
+ * AC'97 volume controls
+ */
+static int aureon_ac97_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 31;
+	return 0;
+}
+
+static int aureon_ac97_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short vol;
+
+	down(&ice->gpio_mutex);
+
+	vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
+	ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
+	if (kcontrol->private_value & AUREON_AC97_STEREO)
+		ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
+
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int aureon_ac97_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short ovol, nvol;
+	int change;
+	
+	snd_ice1712_save_gpio_status(ice);
+
+	ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
+	nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
+	if (kcontrol->private_value & AUREON_AC97_STEREO)
+		nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
+	nvol |= ovol & ~0x1F1F;
+	
+	if ((change = (ovol != nvol)))
+		aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
+
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;		
+}
+
+/*
+ * AC'97 mute controls
+ */
+#define aureon_ac97_mute_info	aureon_mono_bool_info
+
+static int aureon_ac97_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	down(&ice->gpio_mutex);
+
+	ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
+
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int aureon_ac97_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short ovol, nvol;
+	int change;
+
+	snd_ice1712_save_gpio_status(ice);
+	
+	ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
+	nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~	0x8000);
+	
+	if ((change = (ovol != nvol)))
+		aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
+		
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
+/*
+ * AC'97 mute controls
+ */
+#define aureon_ac97_micboost_info	aureon_mono_bool_info
+
+static int aureon_ac97_micboost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	down(&ice->gpio_mutex);
+
+	ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
+
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int aureon_ac97_micboost_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short ovol, nvol;
+	int change;
+
+	snd_ice1712_save_gpio_status(ice);
+	
+	ovol = aureon_ac97_read(ice, AC97_MIC);
+	nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
+	
+	if ((change = (ovol != nvol)))
+		aureon_ac97_write(ice, AC97_MIC, nvol);
+		
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
 
 /*
  * write data in the SPI mode
@@ -179,78 +408,177 @@
 }
 
 /*
+ * AC'97 master playback mute controls (Mute on WM8770 chip)
+ */
+#define aureon_ac97_mmute_info	aureon_mono_bool_info
+
+static int aureon_ac97_mmute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	down(&ice->gpio_mutex);
+
+	ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
+
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int aureon_ac97_mmute_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short ovol, nvol;
+	int change;
+	
+	snd_ice1712_save_gpio_status(ice);
+	
+	ovol = wm_get(ice, WM_OUT_MUX1);
+	nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
+	if ((change = (ovol != nvol)))
+		wm_put(ice, WM_OUT_MUX1, nvol);
+		
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
+/*
+ * Logarithmic volume values for WM8770
+ * Computed as 20 * Log10(255 / x)
+ */
+static unsigned char wm_vol[256] = {
+	127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
+	23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
+	17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
+	13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
+	11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
+	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0
+};
+
+#define WM_VOL_MAX	(sizeof(wm_vol) - 1)
+#define WM_VOL_MUTE	0x8000
+
+static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
+{
+	unsigned char nvol;
+	
+	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
+		nvol = 0;
+	else
+		nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
+	
+	wm_put(ice, index, nvol);
+	wm_put_nocache(ice, index, 0x180 | nvol);
+}
+
+/*
  * DAC mute control
  */
-#define wm_dac_mute_info	aureon_mono_bool_info
+#define wm_pcm_mute_info	aureon_mono_bool_info
 
-static int wm_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned short val;
 
 	down(&ice->gpio_mutex);
-	val = wm_get(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_MUTE);
-	ucontrol->value.integer.value[0] = ~val>>4 & 0x1;
+	ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
 	up(&ice->gpio_mutex);
 	return 0;
 }
 
-static int wm_dac_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned short new, old;
+	unsigned short nval, oval;
 	int change;
 
 	snd_ice1712_save_gpio_status(ice);
-	old = wm_get(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_MUTE);
-	new = (~ucontrol->value.integer.value[0]<<4&0x10) | (old&~0x10);
-	change = (new != old);
-	if (change)
-		wm_put(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_MUTE, new);
+	oval = wm_get(ice, WM_MUTE);
+	nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
+	if ((change = (nval != oval)))
+		wm_put(ice, WM_MUTE, nval);
 	snd_ice1712_restore_gpio_status(ice);
 
 	return change;
 }
 
 /*
+ * Master volume attenuation mixer control
+ */
+static int wm_master_vol_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 = WM_VOL_MAX;
+	return 0;
+}
+
+static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int i;
+	for (i=0; i<2; i++)
+		ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
+	return 0;
+}
+
+static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int ch, change = 0;
+
+	snd_ice1712_save_gpio_status(ice);
+	for (ch = 0; ch < 2; ch++) {
+		if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
+			int dac;
+			ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
+			ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
+			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
+				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
+					   ice->spec.aureon.vol[dac + ch],
+					   ice->spec.aureon.master[ch]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+	return change;
+}
+
+/*
  * DAC volume attenuation mixer control
  */
-static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = voices;
 	uinfo->value.integer.min = 0;		/* mute (-101dB) */
-	uinfo->value.integer.max = 101;		/* 0dB */
+	uinfo->value.integer.max = 0x7F;	/* 0dB */
 	return 0;
 }
 
-static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int i, idx, ofs, voices;
-	unsigned short vol;
+	int i, ofs, voices;
 
 	voices = kcontrol->private_value >> 8;
 	ofs = kcontrol->private_value & 0xff;
-	down(&ice->gpio_mutex);
-	for (i = 0; i < voices; i++) {
-		idx  = WM_DAC_ATTEN + ofs + i;
-		vol = wm_get(ice, idx) & 0x7f;
-		if (vol <= 0x1a)
-			ucontrol->value.integer.value[i] = 0;
-		else
-			ucontrol->value.integer.value[i] = vol - 0x1a;
-	}
-	up(&ice->gpio_mutex);
+	for (i = 0; i < voices; i++)
+		ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
-static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	int i, idx, ofs, voices;
-	unsigned short ovol, nvol;
 	int change = 0;
 
 	voices = kcontrol->private_value >> 8;
@@ -258,13 +586,11 @@
 	snd_ice1712_save_gpio_status(ice);
 	for (i = 0; i < voices; i++) {
 		idx  = WM_DAC_ATTEN + ofs + i;
-		nvol = ucontrol->value.integer.value[i] + 0x1a;
-		ovol = wm_get(ice, idx) & 0x7f;
-		if (ovol != nvol) {
-			if (nvol <= 0x1a && ovol <= 0x1a)
-				continue;
-			wm_put(ice, idx, nvol | 0x80); /* zero-detect, prelatch */
-			wm_put_nocache(ice, idx, nvol | 0x180); /* update */
+		if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
+			ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
+			ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
+			wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
+				   ice->spec.aureon.master[i]);
 			change = 1;
 		}
 	}
@@ -272,33 +598,127 @@
 	return change;
 }
 
+/*
+ * WM8770 mute control
+ */
+static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = kcontrol->private_value >> 8;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int voices, ofs, i;
+	
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xFF;
+
+	for (i = 0; i < voices; i++)
+		ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
+	return 0;
+}
+
+static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, voices, ofs, i;
+
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xFF;
+
+	snd_ice1712_save_gpio_status(ice);
+	for (i = 0; i < voices; i++) {
+		int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
+		if (ucontrol->value.integer.value[i] != val) {
+			ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
+			ice->spec.aureon.vol[ofs + i] |=
+				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
+			wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
+				   ice->spec.aureon.master[i]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
+/*
+ * WM8770 master mute control
+ */
+static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	
+	ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
+	ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
+	return 0;
+}
+
+static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, i;
+
+	snd_ice1712_save_gpio_status(ice);
+	for (i = 0; i < 2; i++) {
+		int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
+		if (ucontrol->value.integer.value[i] != val) {
+			int dac;
+			ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
+			ice->spec.aureon.master[i] |=
+				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
+			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
+				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
+					   ice->spec.aureon.vol[dac + i],
+					   ice->spec.aureon.master[i]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
 /* digital master volume */
-#define MASTER_0dB 0xff
-#define MASTER_RES 128	/* -64dB */
-#define MASTER_MIN (MASTER_0dB - MASTER_RES)
-static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+#define PCM_0dB 0xff
+#define PCM_RES 128	/* -64dB */
+#define PCM_MIN (PCM_0dB - PCM_RES)
+static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
 	uinfo->value.integer.min = 0;		/* mute (-64dB) */
-	uinfo->value.integer.max = MASTER_RES;	/* 0dB */
+	uinfo->value.integer.max = PCM_RES;	/* 0dB */
 	return 0;
 }
 
-static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	down(&ice->gpio_mutex);
 	val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
-	val = val > MASTER_MIN ? (val - MASTER_MIN) : 0;
+	val = val > PCM_MIN ? (val - PCM_MIN) : 0;
 	ucontrol->value.integer.value[0] = val;
 	up(&ice->gpio_mutex);
 	return 0;
 }
 
-static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
@@ -306,7 +726,7 @@
 
 	snd_ice1712_save_gpio_status(ice);
 	nvol = ucontrol->value.integer.value[0];
-	nvol = (nvol ? (nvol + MASTER_MIN) : 0) & 0xff;
+	nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
 	ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
 	if (ovol != nvol) {
 		wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
@@ -355,7 +775,7 @@
 		old = wm_get(ice, WM_ADC_GAIN + i);
 		new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
 		if (new != old) {
-			wm_put(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN, new);
+			wm_put(ice, WM_ADC_GAIN + i, new);
 			change = 1;
 		}
 	}
@@ -589,42 +1009,96 @@
 static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = wm_master_mute_info,
+		.get = wm_master_mute_get,
+		.put = wm_master_mute_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Volume",
+		.info = wm_master_vol_info,
+		.get = wm_master_vol_get,
+		.put = wm_master_vol_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Front Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (2 << 8) | 0
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Front Playback Volume",
-		.info = wm_dac_vol_info,
-		.get = wm_dac_vol_get,
-		.put = wm_dac_vol_put,
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
 		.private_value = (2 << 8) | 0
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Rear Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (2 << 8) | 2
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Rear Playback Volume",
-		.info = wm_dac_vol_info,
-		.get = wm_dac_vol_get,
-		.put = wm_dac_vol_put,
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
 		.private_value = (2 << 8) | 2
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Center Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (1 << 8) | 4
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Center Playback Volume",
-		.info = wm_dac_vol_info,
-		.get = wm_dac_vol_get,
-		.put = wm_dac_vol_put,
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
 		.private_value = (1 << 8) | 4
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "LFE Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (1 << 8) | 5
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "LFE Playback Volume",
-		.info = wm_dac_vol_info,
-		.get = wm_dac_vol_get,
-		.put = wm_dac_vol_put,
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
 		.private_value = (1 << 8) | 5
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Side Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (2 << 8) | 6
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Side Playback Volume",
-		.info = wm_dac_vol_info,
-		.get = wm_dac_vol_get,
-		.put = wm_dac_vol_put,
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
 		.private_value = (2 << 8) | 6
 	}
 };
@@ -632,17 +1106,17 @@
 static snd_kcontrol_new_t wm_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Switch",
-		.info = wm_dac_mute_info,
-		.get = wm_dac_mute_get,
-		.put = wm_dac_mute_put,
+		.name = "PCM Playback Switch",
+		.info = wm_pcm_mute_info,
+		.get = wm_pcm_mute_get,
+		.put = wm_pcm_mute_put
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Volume",
-		.info = wm_master_vol_info,
-		.get = wm_master_vol_get,
-		.put = wm_master_vol_put,
+		.name = "PCM Playback Volume",
+		.info = wm_pcm_vol_info,
+		.get = wm_pcm_vol_get,
+		.put = wm_pcm_vol_put
  	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -650,14 +1124,13 @@
 		.info = wm_adc_mute_info,
 		.get = wm_adc_mute_get,
 		.put = wm_adc_mute_put,
-
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Capture Volume",
 		.info = wm_adc_vol_info,
 		.get = wm_adc_vol_get,
-		.put = wm_adc_vol_put,
+		.put = wm_adc_vol_put
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -665,6 +1138,7 @@
 		.info = wm_adc_mux_info,
 		.get = wm_adc_mux_get,
 		.put = wm_adc_mux_put,
+		.private_value = 5
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -689,7 +1163,96 @@
 	},
 };
 
-
+static snd_kcontrol_new_t ac97_controls[] __devinitdata = {
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "AC97 Playback Switch",
+		.info = aureon_ac97_mmute_info,
+		.get = aureon_ac97_mmute_get,
+		.put = aureon_ac97_mmute_put,
+		.private_value = AC97_MASTER
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "AC97 Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_MASTER|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "CD Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_CD
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "CD Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_CD|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Aux Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_AUX,
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Aux Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_AUX|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Line Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_LINE
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Line Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_LINE|AUREON_AC97_STEREO
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Mic Playback Switch",
+ 		.info = aureon_ac97_mute_info,
+ 		.get = aureon_ac97_mute_get,
+ 		.put = aureon_ac97_mute_put,
+ 		.private_value = AC97_MIC
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Mic Playback Volume",
+ 		.info = aureon_ac97_vol_info,
+ 		.get = aureon_ac97_vol_get,
+ 		.put = aureon_ac97_vol_put,
+ 		.private_value = AC97_MIC
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ 		.name = "Mic Boost",
+ 		.info = aureon_ac97_micboost_info,
+ 		.get = aureon_ac97_micboost_get,
+ 		.put = aureon_ac97_micboost_put
+ 	}
+};
+ 
 static int __devinit aureon_add_controls(ice1712_t *ice)
 {
 	unsigned int i, counts;
@@ -697,7 +1260,7 @@
 
 	counts = ARRAY_SIZE(aureon_dac_controls);
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
-		counts--; /* no side */
+		counts -= 2; /* no side */
 	for (i = 0; i < counts; i++) {
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
 		if (err < 0)
@@ -709,6 +1272,13 @@
 		if (err < 0)
 			return err;
 	}
+	
+	for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
+	
 	return 0;
 }
 
@@ -720,9 +1290,9 @@
 {
 	static unsigned short wm_inits_aureon[] = {
 		/* These come first to reduce init pop noise */
-		0x1b, 0x000,		/* ADC Mux */
-		0x1c, 0x009,		/* Out Mux1 */
-		0x1d, 0x009,		/* Out Mux2 */
+		0x1b, 0x005,		/* ADC Mux (AC'97 source) */
+		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = ADC+AUX, VOUT2 = ADC) */
+		0x1d, 0x009,		/* Out Mux2 (VOUT2 = ADC, VOUT3 = ADC) */
 
 		0x18, 0x000,		/* All power-up */
 
@@ -798,14 +1368,15 @@
 	};
 	static unsigned short cs_inits[] = {
 		0x0441, /* RUN */
-		0x0100, /* no mute */
-		0x0200, /* */
-		0x0600, /* slave, 24bit */
+		0x0180, /* no mute, OMCK output on RMCK pin */
+		0x0201, /* S/PDIF source on RXP1 */
+		0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
 		(unsigned short)-1
 	};
 	unsigned int tmp;
 	unsigned short *p;
 	unsigned int cscs;
+	int err, i;
 
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
 		ice->num_total_dacs = 6;
@@ -816,23 +1387,27 @@
 		ice->num_total_adcs = 2;
 	}
 
-	/* to remeber the register values */
+	/* to remeber the register values of CS8415 */
 	ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
 	if (! ice->akm)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
+	
+	if ((err = aureon_ac97_init(ice)) != 0)
+		return err;
 
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
 		cscs = PRODIGY_CS8415_CS;
 	else
 		cscs = AUREON_CS8415_CS;
 
-	snd_ice1712_gpio_set_dir(ice, 0xbfffff); /* fix this for the time being */
+	snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
 
 	/* reset the wm codec as the SPI mode */
 	snd_ice1712_save_gpio_status(ice);
 	snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|
 					 cscs|AUREON_HP_SEL));
+
 	tmp = snd_ice1712_gpio_read(ice);
 	tmp &= ~AUREON_WM_RESET;
 	snd_ice1712_gpio_write(ice, tmp);
@@ -860,6 +1435,13 @@
 	aureon_set_headphone_amp(ice, 1);
 
 	snd_ice1712_restore_gpio_status(ice);
+	
+	ice->spec.aureon.master[0] = WM_VOL_MUTE;
+	ice->spec.aureon.master[1] = WM_VOL_MUTE;
+	for (i = 0; i < ice->num_total_dacs; i++) {
+		ice->spec.aureon.vol[i] = WM_VOL_MUTE;
+		wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
+	}
 
 	return 0;
 }
@@ -873,14 +1455,14 @@
 static unsigned char aureon51_eeprom[] __devinitdata = {
 	0x0a,	/* SYSCONF: clock 512, spdif-in/ADC, 3DACs */
 	0x80,	/* ACLINK: I2S */
-	0xf8,	/* I2S: vol, 96k, 24bit, 192k */
+	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
 	0xff,	/* GPIO_DIR */
 	0xff,	/* GPIO_DIR1 */
-	0xbf,	/* GPIO_DIR2 */
-	0xff,	/* GPIO_MASK */
-	0xff,	/* GPIO_MASK1 */
-	0xff,	/* GPIO_MASK2 */
+	0x5f,	/* GPIO_DIR2 */
+	0x00,	/* GPIO_MASK */
+	0x00,	/* GPIO_MASK1 */
+	0x00,	/* GPIO_MASK2 */
 	0x00,	/* GPIO_STATE */
 	0x00,	/* GPIO_STATE1 */
 	0x00,	/* GPIO_STATE2 */
@@ -889,11 +1471,11 @@
 static unsigned char aureon71_eeprom[] __devinitdata = {
 	0x0b,	/* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
 	0x80,	/* ACLINK: I2S */
-	0xf8,	/* I2S: vol, 96k, 24bit, 192k */
+	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
 	0xff,	/* GPIO_DIR */
 	0xff,	/* GPIO_DIR1 */
-	0xbf,	/* GPIO_DIR2 */
+	0x5f,	/* GPIO_DIR2 */
 	0x00,	/* GPIO_MASK */
 	0x00,	/* GPIO_MASK1 */
 	0x00,	/* GPIO_MASK2 */
@@ -905,11 +1487,11 @@
 static unsigned char prodigy71_eeprom[] __devinitdata = {
 	0x0b,	/* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
 	0x80,	/* ACLINK: I2S */
-	0xf8,	/* I2S: vol, 96k, 24bit, 192k */
+	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
 	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
 	0xff,	/* GPIO_DIR */
 	0xff,	/* GPIO_DIR1 */
-	0xbf,	/* GPIO_DIR2 */
+	0x5f,	/* GPIO_DIR2 */
 	0x00,	/* GPIO_MASK */
 	0x00,	/* GPIO_MASK1 */
 	0x00,	/* GPIO_MASK2 */
diff -Nru a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
--- a/sound/pci/ice1712/aureon.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/aureon.h	2004-10-21 14:13:16 -07:00
@@ -47,6 +47,11 @@
 #define AUREON_DIGITAL_SEL1	(1 << 15)
 #define AUREON_HP_SEL		(1 << 14)
 #define AUREON_WM_CS		(1 << 12)
+#define AUREON_AC97_COMMIT	(1 << 11)
+#define AUREON_AC97_ADDR	(1 << 10)
+#define AUREON_AC97_DATA_LOW	(1 << 9)
+#define AUREON_AC97_DATA_HIGH	(1 << 8)
+#define AUREON_AC97_DATA_MASK	0xFF
 
 /* Prodigy has different pin assignment for chip select */
 #define PRODIGY_CS8415_CS	(1 << 23)
diff -Nru a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
--- a/sound/pci/ice1712/delta.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/delta.c	2004-10-21 14:13:16 -07:00
@@ -526,6 +526,7 @@
 		break;
 	case ICE1712_SUBDEVICE_DELTA1010:
 	case ICE1712_SUBDEVICE_DELTA1010LT:
+	case ICE1712_SUBDEVICE_MEDIASTATION:
 		ice->num_total_dacs = 8;
 		ice->num_total_adcs = 8;
 		break;
@@ -551,6 +552,7 @@
 			return err;
 		break;
 	case ICE1712_SUBDEVICE_DELTA1010:
+	case ICE1712_SUBDEVICE_MEDIASTATION:
 		ice->gpio.set_pro_rate = delta_1010_set_rate_val;
 		break;
 	case ICE1712_SUBDEVICE_DELTADIO2496:
@@ -572,6 +574,7 @@
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DELTA1010:
 	case ICE1712_SUBDEVICE_DELTADIO2496:
+	case ICE1712_SUBDEVICE_MEDIASTATION:
 		return 0;
 	}
 
@@ -630,6 +633,7 @@
 	/* 1010 and dio specific controls */
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DELTA1010:
+	case ICE1712_SUBDEVICE_MEDIASTATION:
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice));
 		if (err < 0)
 			return err;
@@ -654,6 +658,7 @@
 	case ICE1712_SUBDEVICE_DELTA1010:
 	case ICE1712_SUBDEVICE_DELTADIO2496:
 	case ICE1712_SUBDEVICE_DELTA66:
+	case ICE1712_SUBDEVICE_MEDIASTATION:
 		err = snd_ice1712_spdif_build_controls(ice);
 		if (err < 0)
 			return err;
@@ -665,6 +670,7 @@
 	case ICE1712_SUBDEVICE_DELTA1010:
 	case ICE1712_SUBDEVICE_DELTADIO2496:
 	case ICE1712_SUBDEVICE_DELTA66:
+	case ICE1712_SUBDEVICE_MEDIASTATION:
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice));
 		if (err < 0)
 			return err;
@@ -750,6 +756,13 @@
 		.chip_init = snd_ice1712_delta_init,
 		.build_controls = snd_ice1712_delta_add_controls,
 		.no_mpu401 = 1,
+	},
+	{
+		.subvendor = ICE1712_SUBDEVICE_MEDIASTATION,
+		.name = "Lionstracs Mediastation",
+		.model = "mediastation",
+		.chip_init = snd_ice1712_delta_init,
+		.build_controls = snd_ice1712_delta_add_controls,
 	},
 	{ } /* terminator */
 };
diff -Nru a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
--- a/sound/pci/ice1712/delta.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/delta.h	2004-10-21 14:13:16 -07:00
@@ -32,7 +32,8 @@
 		"{MidiMan M Audio,Delta 66},"\
 		"{MidiMan M Audio,Delta 44},"\
 		"{MidiMan M Audio,Audiophile 24/96},"\
-		"{Digigram,VX442},"
+		"{Digigram,VX442},"\
+		"{Lionstracs,Mediastation},"
 
 #define ICE1712_SUBDEVICE_DELTA1010	0x121430d6
 #define ICE1712_SUBDEVICE_DELTADIO2496	0x121431d6
@@ -42,6 +43,7 @@
 #define ICE1712_SUBDEVICE_DELTA410	0x121438d6
 #define ICE1712_SUBDEVICE_DELTA1010LT	0x12143bd6
 #define ICE1712_SUBDEVICE_VX442		0x12143cd6
+#define ICE1712_SUBDEVICE_MEDIASTATION	0x694c0100
 
 /* entry point */
 extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
diff -Nru a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
--- a/sound/pci/ice1712/ews.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/ews.c	2004-10-21 14:13:16 -07:00
@@ -38,6 +38,13 @@
 #define SND_CS8404
 #include <sound/cs8403.h>
 
+enum {
+	EWS_I2C_CS8404 = 0, EWS_I2C_PCF1, EWS_I2C_PCF2,
+	EWS_I2C_88D = 0,
+	EWS_I2C_6FIRE = 0
+};
+	
+
 /*
  * access via i2c mode (for EWX 24/96, EWS 88MT&D)
  */
@@ -139,11 +146,11 @@
 
 	snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[1], &data, 1) != 1)
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
 		goto __error;
 	ndata = (data & 0xf0) | chip_mask;
 	if (ndata != data)
-		if (snd_i2c_sendbytes(ice->i2cdevs[1], &ndata, 1) != 1)
+		if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1)
 			goto __error;
 	snd_i2c_unlock(ice->i2c);
 	return 0;
@@ -224,13 +231,16 @@
 	case ICE1712_SUBDEVICE_EWS88MT:
 	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 	case ICE1712_SUBDEVICE_PHASE88:
-		snd_runtime_check(snd_i2c_sendbytes(ice->cs8404, &bits, 1) == 1, goto _error);
+		if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_CS8404], &bits, 1) != 1)
+			goto _error;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
-		snd_runtime_check(snd_i2c_readbytes(ice->i2cdevs[0], bytes, 2) == 2, goto _error);
+		if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
+			goto _error;
 		if (bits != bytes[1]) {
 			bytes[1] = bits;
-			snd_runtime_check(snd_i2c_readbytes(ice->i2cdevs[0], bytes, 2) == 2, goto _error);
+			if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
+				goto _error;
 		}
 		break;
 	}
@@ -416,7 +426,10 @@
 		ice->num_total_adcs = 8;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
-		break; /* no analog */
+		/* Note: not analog but ADAT I/O */
+		ice->num_total_dacs = 8;
+		ice->num_total_adcs = 8;
+		break;
 	case ICE1712_SUBDEVICE_DMX6FIRE:
 		ice->num_total_dacs = 6;
 		ice->num_total_adcs = 6;
@@ -434,7 +447,7 @@
 	/* create i2c devices */
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DMX6FIRE:
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->i2cdevs[0])) < 0) {
+		if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
 			snd_printk("PCF9554 initialization failed\n");
 			return err;
 		}
@@ -443,18 +456,18 @@
 	case ICE1712_SUBDEVICE_EWS88MT:
 	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 	case ICE1712_SUBDEVICE_PHASE88:
-		if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->cs8404)) < 0)
+		if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->spec.i2cdevs[EWS_I2C_CS8404])) < 0)
 			return err;
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->i2cdevs[0])) < 0)
+		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF1])) < 0)
 			return err;
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->i2cdevs[1])) < 0)
+		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF2])) < 0)
 			return err;
 		/* Check if the front module is connected */
 		if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
 			return err;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->i2cdevs[0])) < 0)
+		if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->spec.i2cdevs[EWS_I2C_88D])) < 0)
 			return err;
 		break;
 	}
@@ -595,7 +608,7 @@
 	unsigned char data;
 
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[1], &data, 1) != 1) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -611,12 +624,12 @@
 	unsigned char data, ndata;
 
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[1], &data, 1) != 1) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
 	ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
-	if (ndata != data && snd_i2c_sendbytes(ice->i2cdevs[1], &ndata, 1) != 1) {
+	if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -633,7 +646,7 @@
 
 	snd_assert(channel >= 0 && channel <= 7, return 0);
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[0], &data, 1) != 1) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -652,12 +665,12 @@
 
 	snd_assert(channel >= 0 && channel <= 7, return 0);
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[0], &data, 1) != 1) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
 	ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
-	if (ndata != data && snd_i2c_sendbytes(ice->i2cdevs[0], &ndata, 1) != 1) {
+	if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -704,7 +717,7 @@
 	unsigned char data[2];
 	
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[0], data, 2) != 2) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -725,7 +738,7 @@
 	int change;
 
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->i2cdevs[0], data, 2) != 2) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -738,7 +751,7 @@
 			ndata[shift >> 3] |= (1 << (shift & 7));
 	}
 	change = (data[shift >> 3] != ndata[shift >> 3]);
-	if (change && snd_i2c_sendbytes(ice->i2cdevs[0], data, 2) != 2) {
+	if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -774,9 +787,9 @@
 	unsigned char byte;
 	snd_i2c_lock(ice->i2c);
 	byte = reg;
-	snd_i2c_sendbytes(ice->i2cdevs[0], &byte, 1);
+	snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1);
 	byte = 0;
-	if (snd_i2c_readbytes(ice->i2cdevs[0], &byte, 1) != 1) {
+	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		printk("cannot read pca\n");
 		return -EIO;
@@ -791,7 +804,7 @@
 	snd_i2c_lock(ice->i2c);
 	bytes[0] = reg;
 	bytes[1] = data;
-	if (snd_i2c_sendbytes(ice->i2cdevs[0], bytes, 2) != 2) {
+	if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
diff -Nru a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
--- a/sound/pci/ice1712/hoontech.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/hoontech.c	2004-10-21 14:13:16 -07:00
@@ -49,24 +49,24 @@
 static void __devinit snd_ice1712_stdsp24_darear(ice1712_t *ice, int activate)
 {
 	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_0_DAREAR(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[0]);
+	ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
 	up(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_mute(ice1712_t *ice, int activate)
 {
 	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_MUTE(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
+	ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
 	up(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_insel(ice1712_t *ice, int activate)
 {
 	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_INSEL(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
+	ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
 	up(&ice->gpio_mutex);
 }
 
@@ -75,45 +75,45 @@
 	down(&ice->gpio_mutex);
 
 	/* select box */
-	ICE1712_STDSP24_0_BOX(ice->hoontech_boxbits, box);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[0]);
+	ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
 
 	/* prepare for write */
 	if (chn == 3)
-		ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
-
-	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[1]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
+		ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
+
+	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
 	udelay(100);
 	if (chn == 3) {
-		ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 0);
-		snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
+		ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
+		snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
 	} else {
 		switch (chn) {
-		case 0:	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 0); break;
-		case 1:	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 0); break;
-		case 2:	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 0); break;
+		case 0:	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 0); break;
+		case 1:	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 0); break;
+		case 2:	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 0); break;
 		}
-		snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[1]);
+		snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
 	}
 	udelay(100);
-	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[1]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
+	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
 	udelay(100);
 
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, 0);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
+	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
 
 	up(&ice->gpio_mutex);
 }
@@ -123,23 +123,23 @@
 	down(&ice->gpio_mutex);
 
 	/* select box */
-	ICE1712_STDSP24_0_BOX(ice->hoontech_boxbits, box);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[0]);
+	ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
 
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, master);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
+	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, master);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
 
 	udelay(100);
 	
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 0);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
+	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 0);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
 	
 	mdelay(10);
 	
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
+	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
 
 	up(&ice->gpio_mutex);
 }
@@ -147,8 +147,8 @@
 static void __devinit snd_ice1712_stdsp24_midi2(ice1712_t *ice, int activate)
 {
 	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_MIDI2(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
+	ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
 	up(&ice->gpio_mutex);
 }
 
@@ -159,57 +159,57 @@
 	ice->num_total_dacs = 8;
 	ice->num_total_adcs = 8;
 
-	ice->hoontech_boxbits[0] = 
-	ice->hoontech_boxbits[1] = 
-	ice->hoontech_boxbits[2] = 
-	ice->hoontech_boxbits[3] = 0;	/* should be already */
-
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 0, 1);
-	ICE1712_STDSP24_0_BOX(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_0_DAREAR(ice->hoontech_boxbits, 0);
-
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 1, 1);
-	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 1);
+	ice->spec.hoontech.boxbits[0] = 
+	ice->spec.hoontech.boxbits[1] = 
+	ice->spec.hoontech.boxbits[2] = 
+	ice->spec.hoontech.boxbits[3] = 0;	/* should be already */
+
+	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 0, 1);
+	ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, 0);
+
+	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 1, 1);
+	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
 	
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 2);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 2, 1);
-	ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, 0);
-
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 3);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 3, 1);
-	ICE1712_STDSP24_3_MIDI2(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_3_MUTE(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_3_INSEL(ice->hoontech_boxbits, 0);
+	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 2);
+	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 2, 1);
+	ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
+
+	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 3);
+	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 3, 1);
+	ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, 0);
 
 	/* let's go - activate only functions in first box */
-	ice->hoontech_config = 0;
+	ice->spec.hoontech.config = 0;
 			    /* ICE1712_STDSP24_MUTE |
 			       ICE1712_STDSP24_INSEL |
 			       ICE1712_STDSP24_DAREAR; */
-	ice->hoontech_boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
+	ice->spec.hoontech.boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
 				     ICE1712_STDSP24_BOX_CHN2 |
 				     ICE1712_STDSP24_BOX_CHN3 |
 				     ICE1712_STDSP24_BOX_CHN4 |
 				     ICE1712_STDSP24_BOX_MIDI1 |
 				     ICE1712_STDSP24_BOX_MIDI2;
-	ice->hoontech_boxconfig[1] = 
-	ice->hoontech_boxconfig[2] = 
-	ice->hoontech_boxconfig[3] = 0;
-	snd_ice1712_stdsp24_darear(ice, (ice->hoontech_config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
-	snd_ice1712_stdsp24_mute(ice, (ice->hoontech_config & ICE1712_STDSP24_MUTE) ? 1 : 0);
-	snd_ice1712_stdsp24_insel(ice, (ice->hoontech_config & ICE1712_STDSP24_INSEL) ? 1 : 0);
+	ice->spec.hoontech.boxconfig[1] = 
+	ice->spec.hoontech.boxconfig[2] = 
+	ice->spec.hoontech.boxconfig[3] = 0;
+	snd_ice1712_stdsp24_darear(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
+	snd_ice1712_stdsp24_mute(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_MUTE) ? 1 : 0);
+	snd_ice1712_stdsp24_insel(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_INSEL) ? 1 : 0);
 	for (box = 0; box < 4; box++) {
 		for (chn = 0; chn < 4; chn++)
-			snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->hoontech_boxconfig[box] & (1 << chn)) ? 1 : 0);
+			snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->spec.hoontech.boxconfig[box] & (1 << chn)) ? 1 : 0);
 		snd_ice1712_stdsp24_box_midi(ice, box,
-				(ice->hoontech_boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
-		if (ice->hoontech_boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
+				(ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
+		if (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
 			snd_ice1712_stdsp24_midi2(ice, 1);
 	}
 
diff -Nru a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
--- a/sound/pci/ice1712/ice1712.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/ice1712.c	2004-10-21 14:13:16 -07:00
@@ -2307,28 +2307,47 @@
 {
 	int dev = 0xa0;		/* EEPROM device address */
 	unsigned int i, size;
+	struct snd_ice1712_card_info **tbl, *c;
 
-	if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) == 0) {
-		snd_printk("ICE1712 has not detected EEPROM\n");
-		return -EIO;
-	}
-	if (modelname && *modelname) {
-		struct snd_ice1712_card_info **tbl, *c;
-		for (tbl = card_tables; *tbl; tbl++) {
-			for (c = *tbl; c->subvendor; c++) {
-				if (c->model && !strcmp(modelname, c->model)) {
-					/* use the given subvendor */
-					printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
-					ice->eeprom.subvendor = c->subvendor;
-					break;
-				}
+	if (! modelname || ! *modelname) {
+		ice->eeprom.subvendor = 0;
+		if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0)
+			ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
+				(snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | 
+				(snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | 
+				(snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
+		if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
+			/* invalid subvendor from EEPROM, try the PCI subststem ID instead */
+			u16 vendor, device;
+			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
+			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
+			ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
+			if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
+				printk(KERN_ERR "ice1712: No valid ID is found\n");
+				return -ENXIO;
 			}
 		}
-	} else
-		ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
-			(snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | 
-			(snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | 
-			(snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
+	}
+	for (tbl = card_tables; *tbl; tbl++) {
+		for (c = *tbl; c->subvendor; c++) {
+			if (modelname && c->model && ! strcmp(modelname, c->model)) {
+				printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
+				ice->eeprom.subvendor = c->subvendor;
+			} else if (c->subvendor != ice->eeprom.subvendor)
+				continue;
+			if (! c->eeprom_size || ! c->eeprom_data)
+				goto found;
+			/* if the EEPROM is given by the driver, use it */
+			snd_printdd("using the defined eeprom..\n");
+			ice->eeprom.version = 1;
+			ice->eeprom.size = c->eeprom_size + 6;
+			memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
+			goto read_skipped;
+		}
+	}
+	printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
+
+ found:
 	ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
 	if (ice->eeprom.size < 6)
 		ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
@@ -2345,6 +2364,7 @@
 	for (i = 0; i < size; i++)
 		ice->eeprom.data[i] = snd_ice1712_read_i2c(ice, dev, i + 6);
 
+ read_skipped:
 	ice->eeprom.gpiomask = ice->eeprom.data[ICE_EEP1_GPIO_MASK];
 	ice->eeprom.gpiostate = ice->eeprom.data[ICE_EEP1_GPIO_STATE];
 	ice->eeprom.gpiodir = ice->eeprom.data[ICE_EEP1_GPIO_DIR];
diff -Nru a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
--- a/sound/pci/ice1712/ice1712.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/ice1712.h	2004-10-21 14:13:16 -07:00
@@ -331,9 +331,6 @@
 	unsigned int force_rdma1: 1;	/* VT1720/4 - RDMA1 as non-spdif */
 	unsigned int num_total_dacs;	/* total DACs */
 	unsigned int num_total_adcs;	/* total ADCs */
-	unsigned char hoontech_boxbits[4];
-	unsigned int hoontech_config;
-	unsigned short hoontech_boxconfig[4];
 	unsigned int cur_rate;		/* current rate */
 
 	struct semaphore open_mutex;
@@ -344,10 +341,8 @@
 	struct snd_ice1712_spdif spdif;
 
 	snd_i2c_bus_t *i2c;		/* I2C bus */
-	snd_i2c_device_t *cs8404;	/* CS8404A I2C device */
 	snd_i2c_device_t *cs8427;	/* CS8427 I2C device */
 	unsigned int cs8427_timeout;	/* CS8427 reset timeout in HZ/100 */
-	snd_i2c_device_t *i2cdevs[2];	/* additional i2c devices */
 	
 	struct ice1712_gpio {
 		unsigned int direction;		/* current direction bits */
@@ -362,6 +357,25 @@
 		void (*set_pro_rate)(ice1712_t *ice, unsigned int rate);
 	} gpio;
 	struct semaphore gpio_mutex;
+
+	/* other board-specific data */
+	union {
+		/* additional i2c devices for EWS boards*/
+		snd_i2c_device_t *i2cdevs[3];
+		/* AC97 register cache for Aureon */
+		struct aureon_spec {
+			unsigned short stac9744[64];
+			unsigned short master[2];
+			unsigned short vol[8];
+		} aureon;
+		/* Hoontech-specific setting */
+		struct hoontech_spec {
+			unsigned char boxbits[4];
+			unsigned int config;
+			unsigned short boxconfig[4];
+		} hoontech;
+	} spec;
+
 };
 
 
diff -Nru a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
--- a/sound/pci/ice1712/ice1724.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ice1712/ice1724.c	2004-10-21 14:13:16 -07:00
@@ -46,6 +46,7 @@
 #include "aureon.h"
 #include "vt1720_mobo.h"
 #include "pontis.h"
+#include "prodigy192.h"
 
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -57,6 +58,7 @@
 	       AUREON_DEVICE_DESC
 	       VT1720_MOBO_DEVICE_DESC
 	       PONTIS_DEVICE_DESC
+	       PRODIGY192_DEVICE_DESC
 		"{VIA,VT1720},"
 		"{VIA,VT1724},"
 		"{ICEnsemble,Generic ICE1724},"
@@ -1864,6 +1866,7 @@
 	snd_vt1724_aureon_cards,
 	snd_vt1720_mobo_cards,
 	snd_vt1720_pontis_cards,
+	snd_vt1724_prodigy192_cards,
 	NULL,
 };
 
diff -Nru a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ice1712/prodigy192.c	2004-10-21 14:13:16 -07:00
@@ -0,0 +1,524 @@
+/*
+ *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
+ *
+ *   Lowlevel functions for AudioTrak Prodigy 192 cards
+ *
+ *	Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
+ *      Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
+ *      Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
+ *
+ *   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 <asm/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+
+#include "ice1712.h"
+#include "envy24ht.h"
+#include "prodigy192.h"
+#include "stac946x.h"
+
+static void stac9460_put(ice1712_t *ice, int reg, unsigned char val)
+{
+	snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
+}
+
+static unsigned char stac9460_get(ice1712_t *ice, int reg)
+{
+	return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
+}
+
+/*
+ * DAC mute control
+ */
+static int stac9460_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int stac9460_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char val;
+	int idx;
+
+	if (kcontrol->private_value)
+		idx = STAC946X_MASTER_VOLUME;
+	else
+		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
+	val = stac9460_get(ice, idx);
+	ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
+	return 0;
+}
+
+static int stac9460_dac_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char new, old;
+	int idx;
+	int change;
+
+	if (kcontrol->private_value)
+		idx = STAC946X_MASTER_VOLUME;
+	else
+		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
+	old = stac9460_get(ice, idx);
+	new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80);
+	change = (new != old);
+	if (change)
+		stac9460_put(ice, idx, new);
+
+	return change;
+}
+
+/*
+ * DAC volume attenuation mixer control
+ */
+static int stac9460_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;			/* mute */
+	uinfo->value.integer.max = 0x7f;		/* 0dB */
+	return 0;
+}
+
+static int stac9460_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx;
+	unsigned char vol;
+
+	if (kcontrol->private_value)
+		idx = STAC946X_MASTER_VOLUME;
+	else
+		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
+	vol = stac9460_get(ice, idx) & 0x7f;
+	ucontrol->value.integer.value[0] = 0x7f - vol;
+
+	return 0;
+}
+
+static int stac9460_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int idx;
+	unsigned char tmp, ovol, nvol;
+	int change;
+
+	if (kcontrol->private_value)
+		idx = STAC946X_MASTER_VOLUME;
+	else
+		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
+	nvol = ucontrol->value.integer.value[0];
+	tmp = stac9460_get(ice, idx);
+	ovol = 0x7f - (tmp & 0x7f);
+	change = (ovol != nvol);
+	if (change) {
+		stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
+	}
+	return change;
+}
+
+/*
+ * ADC mute control
+ */
+static int stac9460_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int stac9460_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char val;
+	int i;
+
+	for (i = 0; i < 2; ++i) {
+		val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
+		ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
+	}
+
+	return 0;
+}
+
+static int stac9460_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned char new, old;
+	int i, reg;
+	int change;
+
+	for (i = 0; i < 2; ++i) {
+		reg = STAC946X_MIC_L_VOLUME + i;
+		old = stac9460_get(ice, reg);
+		new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80);
+		change = (new != old);
+		if (change)
+			stac9460_put(ice, reg, new);
+	}
+
+	return change;
+}
+
+/*
+ * ADC gain mixer control
+ */
+static int stac9460_adc_vol_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;		/* 0dB */
+	uinfo->value.integer.max = 0x0f;	/* 22.5dB */
+	return 0;
+}
+
+static int stac9460_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int i, reg;
+	unsigned char vol;
+
+	for (i = 0; i < 2; ++i) {
+		reg = STAC946X_MIC_L_VOLUME + i;
+		vol = stac9460_get(ice, reg) & 0x0f;
+		ucontrol->value.integer.value[i] = 0x0f - vol;
+	}
+
+	return 0;
+}
+
+static int stac9460_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int i, reg;
+	unsigned char ovol, nvol;
+	int change;
+
+	for (i = 0; i < 2; ++i) {
+		reg = STAC946X_MIC_L_VOLUME + i;
+		nvol = ucontrol->value.integer.value[i];
+		ovol = 0x0f - stac9460_get(ice, reg);
+		change = ((ovol & 0x0f)  != nvol);
+		if (change)
+			stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
+	}
+
+	return change;
+}
+
+#if 0
+/*
+ * Headphone Amplifier
+ */
+static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
+{
+	unsigned int tmp, tmp2;
+
+	tmp2 = tmp = snd_ice1712_gpio_read(ice);
+	if (enable)
+		tmp |= AUREON_HP_SEL;
+	else
+		tmp &= ~ AUREON_HP_SEL;
+	if (tmp != tmp2) {
+		snd_ice1712_gpio_write(ice, tmp);
+		return 1;
+	}
+	return 0;
+}
+
+static int aureon_get_headphone_amp(ice1712_t *ice)
+{
+	unsigned int tmp = snd_ice1712_gpio_read(ice);
+
+	return ( tmp & AUREON_HP_SEL )!= 0;
+}
+
+static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
+	return 0;
+}
+
+
+static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
+}
+
+/*
+ * Deemphasis
+ */
+static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
+	return 0;
+}
+
+static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int temp, temp2;
+	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
+	if (ucontrol->value.integer.value[0])
+		temp |= 0xf;
+	else
+		temp &= ~0xf;
+	if (temp != temp2) {
+		wm_put(ice, WM_DAC_CTRL2, temp);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * ADC Oversampling
+ */
+static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[2] = { "128x", "64x"	};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+
+        return 0;
+}
+
+static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
+	return 0;
+}
+
+static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	int temp, temp2;
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	temp2 = temp = wm_get(ice, WM_MASTER);
+
+	if (ucontrol->value.enumerated.item[0])
+		temp |= 0x8;
+	else
+		temp &= ~0x8;
+
+	if (temp != temp2) {
+		wm_put(ice, WM_MASTER, temp);
+		return 1;
+	}
+	return 0;
+}
+#endif
+
+/*
+ * mixers
+ */
+
+static snd_kcontrol_new_t stac_controls[] __devinitdata = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = stac9460_dac_mute_info,
+		.get = stac9460_dac_mute_get,
+		.put = stac9460_dac_mute_put,
+		.private_value = 1,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Volume",
+		.info = stac9460_dac_vol_info,
+		.get = stac9460_dac_vol_get,
+		.put = stac9460_dac_vol_put,
+		.private_value = 1,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "DAC Switch",
+		.count = 6,
+		.info = stac9460_dac_mute_info,
+		.get = stac9460_dac_mute_get,
+		.put = stac9460_dac_mute_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "DAC Volume",
+		.count = 6,
+		.info = stac9460_dac_vol_info,
+		.get = stac9460_dac_vol_get,
+		.put = stac9460_dac_vol_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "ADC Switch",
+		.count = 1,
+		.info = stac9460_adc_mute_info,
+		.get = stac9460_adc_mute_get,
+		.put = stac9460_adc_mute_put,
+
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "ADC Volume",
+		.count = 1,
+		.info = stac9460_adc_vol_info,
+		.get = stac9460_adc_vol_get,
+		.put = stac9460_adc_vol_put,
+	},
+#if 0
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Route",
+		.info = wm_adc_mux_info,
+		.get = wm_adc_mux_get,
+		.put = wm_adc_mux_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Headphone Amplifier Switch",
+		.info = aureon_bool_info,
+		.get = aureon_hpamp_get,
+		.put = aureon_hpamp_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "DAC Deemphasis Switch",
+		.info = aureon_bool_info,
+		.get = aureon_deemp_get,
+		.put = aureon_deemp_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "ADC Oversampling",
+		.info = aureon_oversampling_info,
+		.get = aureon_oversampling_get,
+		.put = aureon_oversampling_put
+	},
+#endif
+};
+
+static int __devinit prodigy192_add_controls(ice1712_t *ice)
+{
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+
+/*
+ * initialize the chip
+ */
+static int __devinit prodigy192_init(ice1712_t *ice)
+{
+	static unsigned short stac_inits_prodigy[] = {
+		STAC946X_RESET, 0,
+/*		STAC946X_MASTER_VOLUME, 0,
+		STAC946X_LF_VOLUME, 0,
+		STAC946X_RF_VOLUME, 0,
+		STAC946X_LR_VOLUME, 0,
+		STAC946X_RR_VOLUME, 0,
+		STAC946X_CENTER_VOLUME, 0,
+		STAC946X_LFE_VOLUME, 0,*/
+		(unsigned short)-1
+	};
+	unsigned short *p;
+
+	/* prodigy 192 */
+	ice->num_total_dacs = 6;
+	ice->num_total_adcs = 2;
+	
+	/* initialize codec */
+	p = stac_inits_prodigy;
+	for (; *p != (unsigned short)-1; p += 2)
+		stac9460_put(ice, p[0], p[1]);
+
+	return 0;
+}
+
+
+/*
+ * Aureon boards don't provide the EEPROM data except for the vendor IDs.
+ * hence the driver needs to sets up it properly.
+ */
+
+static unsigned char prodigy71_eeprom[] __devinitdata = {
+	0x2b,	/* SYSCONF: clock 512, mpu401, spdif-in/ADC, 4DACs */
+	0x80,	/* ACLINK: I2S */
+	0xf8,	/* I2S: vol, 96k, 24bit, 192k */
+	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
+	0xff,	/* GPIO_DIR */
+	0xff,	/* GPIO_DIR1 */
+	0xbf,	/* GPIO_DIR2 */
+	0x00,	/* GPIO_MASK */
+	0x00,	/* GPIO_MASK1 */
+	0x00,	/* GPIO_MASK2 */
+	0x00,	/* GPIO_STATE */
+	0x00,	/* GPIO_STATE1 */
+	0x00,	/* GPIO_STATE2 */
+};
+
+
+/* entry point */
+struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
+	{
+		.subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
+		.name = "Audiotrak Prodigy 192",
+		.model = "prodigy192",
+		.chip_init = prodigy192_init,
+		.build_controls = prodigy192_add_controls,
+		.eeprom_size = sizeof(prodigy71_eeprom),
+		.eeprom_data = prodigy71_eeprom,
+	},
+	{ } /* terminator */
+};
diff -Nru a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ice1712/prodigy192.h	2004-10-21 14:13:16 -07:00
@@ -0,0 +1,11 @@
+#ifndef __SOUND_PRODIGY192_H
+#define __SOUND_PRODIGY192_H
+
+#define PRODIGY192_DEVICE_DESC 	       "{AudioTrak,Prodigy 192},"
+#define PRODIGY192_STAC9460_ADDR	0x54
+
+#define VT1724_SUBDEVICE_PRODIGY192VE	 0x34495345	/* PRODIGY 192 VE */
+
+extern struct snd_ice1712_card_info  snd_vt1724_prodigy192_cards[];
+
+#endif	/* __SOUND_PRODIGY192_H */
diff -Nru a/sound/pci/ice1712/stac946x.h b/sound/pci/ice1712/stac946x.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ice1712/stac946x.h	2004-10-21 14:13:16 -07:00
@@ -0,0 +1,25 @@
+#ifndef __SOUND_STAC946X_H
+#define __SOUND_STAC946X_H
+
+#define STAC946X_RESET			0x00
+#define STAC946X_STATUS			0x01
+#define STAC946X_MASTER_VOLUME		0x02
+#define STAC946X_LF_VOLUME		0x03
+#define STAC946X_RF_VOLUME		0x04
+#define STAC946X_LR_VOLUME		0x05
+#define STAC946X_RR_VOLUME		0x06
+#define STAC946X_CENTER_VOLUME		0x07
+#define STAC946X_LFE_VOLUME		0x08
+#define STAC946X_MIC_L_VOLUME		0x09
+#define STAC946X_MIC_R_VOLUME		0x0a
+#define STAC946X_DEEMPHASIS		0x0c
+#define STAC946X_GENERAL_PURPOSE	0x0d
+#define STAC946X_AUDIO_PORT_CONTROL	0x0e
+#define STAC946X_MASTER_CLOCKING	0x0f
+#define STAC946X_POWERDOWN_CTRL1	0x10
+#define STAC946X_POWERDOWN_CTRL2	0x11
+#define STAC946X_REVISION_CODE		0x12
+#define STAC946X_ADDRESS_CONTROL	0x13
+#define STAC946X_ADDRESS		0x14
+
+#endif  /*  __SOUND_STAC946X_H */
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/intel8x0.c	2004-10-21 14:13:16 -07:00
@@ -33,13 +33,11 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/gameport.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
 #include <sound/info.h>
-#include <sound/mpu401.h>
 #include <sound/initval.h>
 /* for 440MX workaround */
 #include <asm/pgtable.h>
@@ -64,23 +62,13 @@
 		"{AMD,AMD8111},"
 	        "{ALI,M5455}}");
 
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-#define SUPPORT_MIDI 1
-
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
 static int ac97_quirk[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = AC97_TUNE_DEFAULT};
 static int buggy_irq[SNDRV_CARDS];
-#ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
-#endif
-#ifdef SUPPORT_MIDI
-static int mpu_port[SNDRV_CARDS]; /* disabled */
-#endif
+static int xbox[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
@@ -405,10 +393,10 @@
 
 	unsigned int mmio;
 	unsigned long addr;
-	void __iomem * remap_addr;
+	void __iomem *remap_addr;
 	unsigned int bm_mmio;
 	unsigned long bmaddr;
-	void __iomem * remap_bmaddr;
+	void __iomem *remap_bmaddr;
 
 	struct pci_dev *pci;
 	snd_card_t *card;
@@ -417,20 +405,22 @@
 	snd_pcm_t *pcm[6];
 	ichdev_t ichd[6];
 
-	unsigned multi4: 1,
-		 multi6: 1,
-		 smp20bit: 1;
-	unsigned in_ac97_init: 1,
-		 in_sdin_init: 1;
-	unsigned fix_nocache: 1; /* workaround for 440MX */
-	unsigned buggy_irq: 1; /* workaround for buggy mobos */
+	int multi4: 1,
+	    multi6: 1,
+	    dra: 1,
+	    smp20bit: 1;
+	int in_ac97_init: 1,
+	    in_sdin_init: 1;
+	int in_measurement: 1; /* during ac97 clock measurement */
+	int fix_nocache: 1; /* workaround for 440MX */
+	int buggy_irq: 1; /* workaround for buggy mobos */
+	int xbox: 1;	  /* workaround for Xbox AC'97 detection */
+	int spdif_idx;	/* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
 
 	ac97_bus_t *ac97_bus;
 	ac97_t *ac97[3];
 	unsigned int ac97_sdin[3];
 
-	snd_rawmidi_t *rmidi;
-
 	spinlock_t reg_lock;
 	spinlock_t ac97_lock;
 	
@@ -806,7 +796,8 @@
 	}
 
 	ichdev->position += step * ichdev->fragsize1;
-	ichdev->position %= ichdev->size;
+	if (! chip->in_measurement)
+		ichdev->position %= ichdev->size;
 	ichdev->lvi += step;
 	ichdev->lvi &= ICH_REG_LVI_MASK;
 	iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
@@ -953,6 +944,7 @@
 	ichdev_t *ichdev = get_ichdev(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	size_t size = params_buffer_bytes(hw_params);
+	int dbl = params_rate(hw_params) > 48000;
 	int err;
 
 	if (chip->fix_nocache && runtime->dma_area && runtime->dma_bytes < size)
@@ -968,11 +960,11 @@
 	}
 	err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params),
 				params_channels(hw_params),
-				ichdev->pcm->r[0].slots);
+				ichdev->pcm->r[dbl].slots);
 	if (err >= 0) {
 		ichdev->pcm_open_flag = 1;
-		/* FIXME: hack to enable spdif support */
-		if (ichdev->ichd == ICHD_PCMOUT && chip->device_type == DEVICE_SIS)
+		/* Force SPDIF setting */
+		if (ichdev->ichd == ICHD_PCMOUT && chip->spdif_idx < 0)
 			snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF, params_rate(hw_params));
 	}
 	return err;
@@ -993,34 +985,35 @@
 }
 
 static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip,
-				       int channels, int sample_bits)
+				       snd_pcm_runtime_t *runtime)
 {
 	unsigned int cnt;
+	int dbl = runtime->rate > 48000;
 	switch (chip->device_type) {
 	case DEVICE_ALI:
 		cnt = igetdword(chip, ICHREG(ALI_SCR));
 		cnt &= ~ICH_ALI_SC_PCM_246_MASK;
-		if (chip->multi4 && channels == 4)
+		if (runtime->channels == 4 || dbl)
 			cnt |= ICH_ALI_SC_PCM_4;
-		else if (chip->multi6 && channels == 6)
+		else if (runtime->channels == 6)
 			cnt |= ICH_ALI_SC_PCM_6;
 		iputdword(chip, ICHREG(ALI_SCR), cnt);
 		break;
 	case DEVICE_SIS:
 		cnt = igetdword(chip, ICHREG(GLOB_CNT));
 		cnt &= ~ICH_SIS_PCM_246_MASK;
-		if (chip->multi4 && channels == 4)
+		if (runtime->channels == 4 || dbl)
 			cnt |= ICH_SIS_PCM_4;
-		else if (chip->multi6 && channels == 6)
+		else if (runtime->channels == 6)
 			cnt |= ICH_SIS_PCM_6;
 		iputdword(chip, ICHREG(GLOB_CNT), cnt);
 		break;
 	default:
 		cnt = igetdword(chip, ICHREG(GLOB_CNT));
 		cnt &= ~(ICH_PCM_246_MASK | ICH_PCM_20BIT);
-		if (chip->multi4 && channels == 4)
+		if (runtime->channels == 4 || dbl)
 			cnt |= ICH_PCM_4;
-		else if (chip->multi6 && channels == 6)
+		else if (runtime->channels == 6)
 			cnt |= ICH_PCM_6;
 		if (chip->device_type == DEVICE_NFORCE) {
 			/* reset to 2ch once to keep the 6 channel data in alignment,
@@ -1031,7 +1024,7 @@
 				msleep(50); /* grrr... */
 			}
 		} else if (chip->device_type == DEVICE_INTEL_ICH4) {
-			if (sample_bits > 16)
+			if (runtime->sample_bits > 16)
 				cnt |= ICH_PCM_20BIT;
 		}
 		iputdword(chip, ICHREG(GLOB_CNT), cnt);
@@ -1050,8 +1043,7 @@
 	ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
 	spin_lock_irq(&chip->reg_lock);
 	if (ichdev->ichd == ICHD_PCMOUT) {
-		snd_intel8x0_setup_pcm_out(chip, runtime->channels,
-					   runtime->sample_bits);
+		snd_intel8x0_setup_pcm_out(chip, runtime);
 		if (chip->device_type == DEVICE_INTEL_ICH4) {
 			ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
 		}
@@ -1167,6 +1159,9 @@
 		runtime->hw.channels_max = 4;
 		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels4);
 	}
+	if (chip->dra) {
+		snd_ac97_pcm_double_rate_rules(runtime);
+	}
 	if (chip->smp20bit) {
 		runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
 		snd_pcm_hw_constraint_msbits(runtime, 0, 32, 20);
@@ -1661,6 +1656,12 @@
 					 (1 << AC97_SLOT_PCM_SLEFT) |
 					 (1 << AC97_SLOT_PCM_SRIGHT) |
 					 (1 << AC97_SLOT_LFE)
+			},
+			{
+				.slots = (1 << AC97_SLOT_PCM_LEFT) |
+					 (1 << AC97_SLOT_PCM_RIGHT) |
+					 (1 << AC97_SLOT_PCM_LEFT_0) |
+					 (1 << AC97_SLOT_PCM_RIGHT_0)
 			}
 		}
 	},
@@ -1717,6 +1718,12 @@
 static struct ac97_quirk ac97_quirks[] __devinitdata = {
 	{
 		.vendor = 0x0e11,
+		.device = 0x008a,
+		.name = "Compaq Evo W4000",	/* AD1885 */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x0e11,
 		.device = 0x00b8,
 		.name = "Compaq Evo D510C",
 		.type = AC97_TUNE_HP_ONLY
@@ -1763,6 +1770,12 @@
 		.name = "HP xw4200",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
+	{
+		.vendor = 0x104d,
+		.device = 0x8197,
+		.name = "Sony S1XP",
+		.type = AC97_TUNE_INV_EAPD
+	},
  	{
 		.vendor = 0x1043,
 		.device = 0x80f3,
@@ -1770,6 +1783,12 @@
 		.type = AC97_TUNE_AD_SHARING
 	},
 	{
+		.vendor = 0x10cf,
+		.device = 0x11c3,
+		.name = "Fujitsu-Siemens E4010",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
 		.vendor = 0x10f1,
 		.device = 0x2665,
 		.name = "Fujitsu-Siemens Celsius",	/* AD1981? */
@@ -1870,7 +1889,6 @@
 	int err;
 	unsigned int i, codecs;
 	unsigned int glob_sta = 0;
-	int spdif_idx = -1; /* disabled */
 	ac97_bus_ops_t *ops;
 	static ac97_bus_ops_t standard_bus_ops = {
 		.write = snd_intel8x0_codec_write,
@@ -1881,16 +1899,16 @@
 		.read = snd_intel8x0_ali_codec_read,
 	};
 
+	chip->spdif_idx = -1; /* use PCMOUT (or disabled) */
 	switch (chip->device_type) {
 	case DEVICE_NFORCE:
-		spdif_idx = NVD_SPBAR;
+		chip->spdif_idx = NVD_SPBAR;
 		break;
 	case DEVICE_ALI:
-		spdif_idx = ALID_AC97SPDIFOUT;
+		chip->spdif_idx = ALID_AC97SPDIFOUT;
 		break;
-	default:
-		if (chip->device_type == DEVICE_INTEL_ICH4)
-			spdif_idx = ICHD_SPBAR;
+	case DEVICE_INTEL_ICH4:
+		chip->spdif_idx = ICHD_SPBAR;
 		break;
 	};
 
@@ -1900,6 +1918,8 @@
 	ac97.private_data = chip;
 	ac97.private_free = snd_intel8x0_mixer_free_ac97;
 	ac97.scaps = AC97_SCAP_SKIP_MODEM;
+	if (chip->xbox)
+		ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
 	if (chip->device_type != DEVICE_ALI) {
 		glob_sta = igetdword(chip, ICHREG(GLOB_STA));
 		ops = &standard_bus_ops;
@@ -1943,6 +1963,7 @@
 	/* FIXME: my test board doesn't work well with VRA... */
 	if (chip->device_type == DEVICE_ALI)
 		pbus->no_vra = 1;
+	pbus->dra = 1;
 	chip->ac97_bus = pbus;
 
 	ac97.pci = chip->pci;
@@ -1965,7 +1986,7 @@
 	i = ARRAY_SIZE(ac97_pcm_defs);
 	if (chip->device_type != DEVICE_INTEL_ICH4)
 		i -= 2;		/* do not allocate PCM2IN and MIC2 */
-	if (spdif_idx < 0)
+	if (chip->spdif_idx < 0)
 		i--;		/* do not allocate S/PDIF */
 	err = snd_ac97_pcm_assign(pbus, i, ac97_pcm_defs);
 	if (err < 0)
@@ -1973,8 +1994,8 @@
 	chip->ichd[ICHD_PCMOUT].pcm = &pbus->pcms[0];
 	chip->ichd[ICHD_PCMIN].pcm = &pbus->pcms[1];
 	chip->ichd[ICHD_MIC].pcm = &pbus->pcms[2];
-	if (spdif_idx >= 0)
-		chip->ichd[spdif_idx].pcm = &pbus->pcms[3];
+	if (chip->spdif_idx >= 0)
+		chip->ichd[chip->spdif_idx].pcm = &pbus->pcms[3];
 	if (chip->device_type == DEVICE_INTEL_ICH4) {
 		chip->ichd[ICHD_PCM2IN].pcm = &pbus->pcms[4];
 		chip->ichd[ICHD_MIC2].pcm = &pbus->pcms[5];
@@ -2003,13 +2024,24 @@
 		if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE))
 			chip->multi6 = 1;
 	}
+	if (pbus->pcms[0].r[1].rslots[0]) {
+		chip->dra = 1;
+	}
 	if (chip->device_type == DEVICE_INTEL_ICH4) {
 		if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20)
 			chip->smp20bit = 1;
 	}
 	if (chip->device_type == DEVICE_NFORCE) {
 		/* 48kHz only */
-		chip->ichd[spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;
+		chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;
+	}
+	if (chip->device_type == DEVICE_INTEL_ICH4) {
+		/* use slot 10/11 for SPDIF */
+		u32 val;
+		val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK;
+		val |= ICH_PCM_SPDIF_1011;
+		iputdword(chip, ICHREG(GLOB_CNT), val);
+		snd_ac97_update_bits(chip->ac97[0], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
 	}
 	chip->in_ac97_init = 0;
 	return 0;
@@ -2317,6 +2349,7 @@
 	snd_intel8x0_setup_periods(chip, ichdev);
 	port = ichdev->reg_offset;
 	spin_lock_irq(&chip->reg_lock);
+	chip->in_measurement = 1;
 	/* trigger */
 	if (chip->device_type != DEVICE_ALI)
 		iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE | ICH_STARTBM);
@@ -2326,18 +2359,14 @@
 	}
 	do_gettimeofday(&start_time);
 	spin_unlock_irq(&chip->reg_lock);
-#if 0
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(HZ / 20);
-#else
-	/* FIXME: schedule() can take too long time and overlap the boundary.. */
-	mdelay(50);
-#endif
 	spin_lock_irq(&chip->reg_lock);
 	/* check the position */
 	pos = ichdev->fragsize1;
 	pos -= igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift;
 	pos += ichdev->position;
+	chip->in_measurement = 0;
 	do_gettimeofday(&stop_time);
 	/* stop */
 	if (chip->device_type == DEVICE_ALI) {
@@ -2501,8 +2530,9 @@
 	if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) {	/* ICH4 and Nforce */
 		chip->mmio = 1;
 		chip->addr = pci_resource_start(pci, 2);
-		chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 2));
-		if (!chip->remap_addr) {
+		chip->remap_addr = ioremap_nocache(chip->addr,
+						   pci_resource_len(pci, 2));
+		if (chip->remap_addr == NULL) {
 			snd_printk("AC'97 space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
@@ -2513,8 +2543,9 @@
 	if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) {	/* ICH4 */
 		chip->bm_mmio = 1;
 		chip->bmaddr = pci_resource_start(pci, 3);
-		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr, pci_resource_len(pci, 3));
-		if (!chip->remap_bmaddr) {
+		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
+						     pci_resource_len(pci, 3));
+		if (chip->remap_bmaddr == NULL) {
 			snd_printk("Controller space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
@@ -2659,6 +2690,9 @@
 	case DEVICE_NFORCE:
 		strcpy(card->driver, "NFORCE");
 		break;
+	case DEVICE_INTEL_ICH4:
+		strcpy(card->driver, "ICH4");
+		break;
 	default:
 		strcpy(card->driver, "ICH");
 		break;
@@ -2678,6 +2712,8 @@
 	}
 	if (buggy_irq[dev])
 		chip->buggy_irq = 1;
+	if (xbox[dev])
+		chip->xbox = 1;
 
 	if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
 		snd_card_free(card);
@@ -2688,20 +2724,11 @@
 		return err;
 	}
 	
-	if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330) {
-		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_INTEL8X0,
-					       mpu_port[dev], 0,
-					       -1, 0, &chip->rmidi)) < 0) {
-			printk(KERN_ERR "intel8x0: no UART401 device at 0x%x, skipping.\n", mpu_port[dev]);
-			mpu_port[dev] = 0;
-		}
-	} else
-		mpu_port[dev] = 0;
-
 	snd_intel8x0_proc_init(chip);
 
-	sprintf(card->longname, "%s at 0x%lx, irq %i",
-		card->shortname, chip->addr, chip->irq);
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s with %s at %#lx, irq %i", card->shortname,
+		 snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq);
 
 	if (! ac97_clock[dev])
 		intel8x0_measure_ac97_clock(chip);
@@ -2730,129 +2757,18 @@
 };
 
 
-#if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
-/*
- * initialize joystick/midi addresses
- */
-
-#ifdef SUPPORT_JOYSTICK
-/* there is only one available device, so we keep it here */
-static struct pci_dev *ich_gameport_pci;
-static struct gameport ich_gameport = { .io = 0x200 };
-#endif
-
-static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
-						 const struct pci_device_id *id)
-{
-	u16 val;
-	static int dev;
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	pci_read_config_word(pci, 0xe6, &val);
-#ifdef SUPPORT_JOYSTICK
-	val &= ~0x100;
-	if (joystick[dev]) {
-		if (! request_region(ich_gameport.io, 8, "ICH gameport")) {
-			printk(KERN_WARNING "intel8x0: cannot grab gameport 0x%x\n",  ich_gameport.io);
-			joystick[dev] = 0;
-		} else {
-			ich_gameport_pci = pci;
-			gameport_register_port(&ich_gameport);
-			val |= 0x100;
-		}
-	}
-#endif
-#ifdef SUPPORT_MIDI
-	val &= ~0x20;
-	if (mpu_port[dev] > 0) {
-		if (mpu_port[dev] == 0x300 || mpu_port[dev] == 0x330) {
-			u8 b;
-			val |= 0x20;
-			pci_read_config_byte(pci, 0xe2, &b);
-			if (mpu_port[dev] == 0x300)
-				b |= 0x08;
-			else
-				b &= ~0x08;
-			pci_write_config_byte(pci, 0xe2, b);
-		}
-	}
-#endif
-	pci_write_config_word(pci, 0xe6, val);
-	return 0;
-}
-
-static void __devexit snd_intel8x0_joystick_remove(struct pci_dev *pci)
-{
-	u16 val;
-#ifdef SUPPORT_JOYSTICK
-	if (ich_gameport_pci == pci) {
-		gameport_unregister_port(&ich_gameport);
-		release_region(ich_gameport.io, 8);
-		ich_gameport_pci = NULL;
-	}
-#endif
-	/* disable joystick and MIDI */
-	pci_read_config_word(pci, 0xe6, &val);
-	val &= ~0x120;
-	pci_write_config_word(pci, 0xe6, val);
-}
-
-static struct pci_device_id snd_intel8x0_joystick_ids[] = {
-	{ 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* 82801AA */
-	{ 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* 82901AB */
-	{ 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH2 */
-	{ 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH2M */
-	{ 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* ICH3 */
-	// { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* 440MX */
-	// { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* SI7012 */
-	{ 0x10de, 0x01b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* NFORCE */
-	{ 0x10de, 0x006b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* NFORCE2 */
-	{ 0x10de, 0x00db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	/* NFORCE3 */
-	{ 0, }
-};
-
-static struct pci_driver joystick_driver = {
-	.name = "Intel ICH Joystick",
-	.id_table = snd_intel8x0_joystick_ids,
-	.probe = snd_intel8x0_joystick_probe,
-	.remove = __devexit_p(snd_intel8x0_joystick_remove),
-};
-
-static int have_joystick;
-#endif
-
 static int __init alsa_card_intel8x0_init(void)
 {
 	int err;
 
         if ((err = pci_module_init(&driver)) < 0)
                 return err;
-
-#if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
-	if (pci_module_init(&joystick_driver) < 0) {
-		snd_printdd(KERN_INFO "no joystick found\n");
-		have_joystick = 0;
-	} else {
-		snd_printdd(KERN_INFO "joystick(s) found\n");
-		have_joystick = 1;
-	}
-#endif
         return 0;
-
 }
 
 static void __exit alsa_card_intel8x0_exit(void)
 {
 	pci_unregister_driver(&driver);
-#if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI)
-	if (have_joystick)
-		pci_unregister_driver(&joystick_driver);
-#endif
 }
 
 module_init(alsa_card_intel8x0_init)
diff -Nru a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
--- a/sound/pci/intel8x0m.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/intel8x0m.c	2004-10-21 14:13:16 -07:00
@@ -30,13 +30,11 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-#include <linux/gameport.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
 #include <sound/info.h>
-#include <sound/mpu401.h>
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -48,8 +46,13 @@
 		"{Intel,82801CA-ICH3},"
 		"{Intel,82801DB-ICH4},"
 		"{Intel,ICH5},"
-	        "{Intel,MX440}}");
-
+	        "{Intel,MX440},"
+		"{SiS,7013},"
+		"{NVidia,NForce Modem},"
+		"{NVidia,NForce2 Modem},"
+		"{NVidia,NForce2s Modem},"
+		"{NVidia,NForce3 Modem},"
+		"{AMD,AMD768}}");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
@@ -232,10 +235,10 @@
 
 	unsigned int mmio;
 	unsigned long addr;
-	unsigned long remap_addr;
+	void __iomem *remap_addr;
 	unsigned int bm_mmio;
 	unsigned long bmaddr;
-	unsigned long remap_bmaddr;
+	void __iomem *remap_bmaddr;
 
 	struct pci_dev *pci;
 	snd_card_t *card;
@@ -1065,9 +1068,9 @@
 	if (chip->bdbars.area)
 		snd_dma_free_pages(&chip->bdbars);
 	if (chip->remap_addr)
-		iounmap((void *) chip->remap_addr);
+		iounmap(chip->remap_addr);
 	if (chip->remap_bmaddr)
-		iounmap((void *) chip->remap_bmaddr);
+		iounmap(chip->remap_bmaddr);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
 	pci_release_regions(chip->pci);
@@ -1192,9 +1195,9 @@
 	if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) {	/* ICH4 and Nforce */
 		chip->mmio = 1;
 		chip->addr = pci_resource_start(pci, 2);
-		chip->remap_addr = (unsigned long) ioremap_nocache(chip->addr,
-								   pci_resource_len(pci, 2));
-		if (chip->remap_addr == 0) {
+		chip->remap_addr = ioremap_nocache(chip->addr,
+						   pci_resource_len(pci, 2));
+		if (chip->remap_addr == NULL) {
 			snd_printk("AC'97 space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
@@ -1205,9 +1208,9 @@
 	if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) {	/* ICH4 */
 		chip->bm_mmio = 1;
 		chip->bmaddr = pci_resource_start(pci, 3);
-		chip->remap_bmaddr = (unsigned long) ioremap_nocache(chip->bmaddr,
-								     pci_resource_len(pci, 3));
-		if (chip->remap_bmaddr == 0) {
+		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
+						     pci_resource_len(pci, 3));
+		if (chip->remap_bmaddr == NULL) {
 			snd_printk("Controller space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
@@ -1331,15 +1334,7 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	switch (pci_id->driver_data) {
-	case DEVICE_NFORCE:
-		strcpy(card->driver, "NFORCE-MODEM");
-		break;
-	default:
-		strcpy(card->driver, "ICH-MODEM");
-		break;
-	}
-
+	strcpy(card->driver, "ICH-MODEM");
 	strcpy(card->shortname, "Intel ICH");
 	for (name = shortnames; name->id; name++) {
 		if (pci->device == name->id) {
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/korg1212/korg1212.c	2004-10-21 14:13:16 -07:00
@@ -168,7 +168,7 @@
 #define DOORBELL_VAL_MASK    0x00FF    // the doorbell value is one byte
 
 #define CARD_BOOT_DELAY_IN_MS  10
-
+#define CARD_BOOT_TIMEOUT      10
 #define DSP_BOOT_DELAY_IN_MS   200
 
 #define kNumBuffers		8
@@ -341,7 +341,7 @@
 	unsigned long iomem2;
         unsigned long irqcount;
         unsigned long inIRQ;
-        unsigned long iobase;
+        void __iomem *iobase;
 
 	struct snd_dma_buffer dma_dsp;
         struct snd_dma_buffer dma_play;
@@ -364,16 +364,16 @@
 	u32 RoutingTablePhy;
 	u32 AdatTimeCodePhy;
 
-        u32 * statusRegPtr;	     // address of the interrupt status/control register
-        u32 * outDoorbellPtr;	     // address of the host->card doorbell register
-        u32 * inDoorbellPtr;	     // address of the card->host doorbell register
-        u32 * mailbox0Ptr;	     // address of mailbox 0 on the card
-        u32 * mailbox1Ptr;	     // address of mailbox 1 on the card
-        u32 * mailbox2Ptr;	     // address of mailbox 2 on the card
-        u32 * mailbox3Ptr;	     // address of mailbox 3 on the card
-        u32 * controlRegPtr;	     // address of the EEPROM, PCI, I/O, Init ctrl reg
-        u16 * sensRegPtr;	     // address of the sensitivity setting register
-        u32 * idRegPtr;		     // address of the device and vendor ID registers
+        u32 __iomem * statusRegPtr;	     // address of the interrupt status/control register
+        u32 __iomem * outDoorbellPtr;	     // address of the host->card doorbell register
+        u32 __iomem * inDoorbellPtr;	     // address of the card->host doorbell register
+        u32 __iomem * mailbox0Ptr;	     // address of mailbox 0 on the card
+        u32 __iomem * mailbox1Ptr;	     // address of mailbox 1 on the card
+        u32 __iomem * mailbox2Ptr;	     // address of mailbox 2 on the card
+        u32 __iomem * mailbox3Ptr;	     // address of mailbox 3 on the card
+        u32 __iomem * controlRegPtr;	     // address of the EEPROM, PCI, I/O, Init ctrl reg
+        u16 __iomem * sensRegPtr;	     // address of the sensitivity setting register
+        u32 __iomem * idRegPtr;		     // address of the device and vendor ID registers
 
         size_t periodsize;
 	int channels;
@@ -382,6 +382,9 @@
         snd_pcm_substream_t *playback_substream;
         snd_pcm_substream_t *capture_substream;
 
+	pid_t capture_pid;
+	pid_t playback_pid;
+
  	CardState cardState;
         int running;
         int idleMonitorOn;           // indicates whether the card is in idle monitor mode.
@@ -796,11 +799,12 @@
 
 static void snd_korg1212_EnableCardInterrupts(korg1212_t * korg1212)
 {
-	* korg1212->statusRegPtr = PCI_INT_ENABLE_BIT            |
-                                   PCI_DOORBELL_INT_ENABLE_BIT   |
-                                   LOCAL_INT_ENABLE_BIT          |
-                                   LOCAL_DOORBELL_INT_ENABLE_BIT |
-                                   LOCAL_DMA1_INT_ENABLE_BIT;
+	writel(PCI_INT_ENABLE_BIT            |
+	       PCI_DOORBELL_INT_ENABLE_BIT   |
+	       LOCAL_INT_ENABLE_BIT          |
+	       LOCAL_DOORBELL_INT_ENABLE_BIT |
+	       LOCAL_DMA1_INT_ENABLE_BIT,
+	       korg1212->statusRegPtr);
 }
 
 #if 0 /* not used */
@@ -843,6 +847,20 @@
 
 #endif /* not used */
 
+static inline int snd_korg1212_use_is_exclusive(korg1212_t *korg1212)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&korg1212->lock, flags);
+	if ((korg1212->playback_pid != korg1212->capture_pid) &&
+	    (korg1212->playback_pid >= 0) && (korg1212->capture_pid >= 0)) {
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&korg1212->lock, flags);
+	return ret;
+}
+
 static int snd_korg1212_SetRate(korg1212_t *korg1212, int rate)
 {
         static ClockSourceIndex s44[] = { K1212_CLKIDX_AdatAt44_1K,
@@ -854,6 +872,10 @@
                                           K1212_CLKIDX_LocalAt48K };
         int parm;
 
+        if (!snd_korg1212_use_is_exclusive (korg1212)) {
+                return -EBUSY;
+        }
+
         switch(rate) {
                 case 44100:
                 parm = s44[korg1212->clkSource];
@@ -897,7 +919,7 @@
 
 static void snd_korg1212_DisableCardInterrupts(korg1212_t *korg1212)
 {
-	* korg1212->statusRegPtr = 0;
+	writel(0, korg1212->statusRegPtr);
 }
 
 static int snd_korg1212_WriteADCSensitivity(korg1212_t *korg1212)
@@ -1244,7 +1266,7 @@
 	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
 #endif
 
-	if (! sleep_on_timeout(&korg1212->wait, HZ * 4))
+	if (! sleep_on_timeout(&korg1212->wait, HZ * CARD_BOOT_TIMEOUT))
 		return -EBUSY; /* timeout */
 
 	snd_korg1212_OnDSPDownloadComplete(korg1212);
@@ -1413,6 +1435,7 @@
         spin_lock_irqsave(&korg1212->lock, flags);
 
         korg1212->playback_substream = substream;
+	korg1212->playback_pid = current->pid;
         korg1212->periodsize = K1212_PERIODS;
 	korg1212->channels = K1212_CHANNELS;
 
@@ -1443,6 +1466,7 @@
         spin_lock_irqsave(&korg1212->lock, flags);
 
         korg1212->capture_substream = substream;
+	korg1212->capture_pid = current->pid;
         korg1212->periodsize = K1212_PERIODS;
 	korg1212->channels = K1212_CHANNELS;
 
@@ -1465,6 +1489,7 @@
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
+	korg1212->playback_pid = -1;
         korg1212->playback_substream = NULL;
         korg1212->periodsize = 0;
 
@@ -1485,6 +1510,7 @@
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
+	korg1212->capture_pid = -1;
         korg1212->capture_substream = NULL;
         korg1212->periodsize = 0;
 
@@ -1521,22 +1547,45 @@
         unsigned long flags;
         korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
         int err;
+	pid_t this_pid;
+	pid_t other_pid;
 
 #if K1212_DEBUG_LEVEL > 0
 		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n", stateName[korg1212->cardState]);
 #endif
 
         spin_lock_irqsave(&korg1212->lock, flags);
+
+	if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		this_pid = korg1212->playback_pid;
+		other_pid = korg1212->capture_pid;
+	} else {
+		this_pid = korg1212->capture_pid;
+		other_pid = korg1212->playback_pid;
+	}
+
+	if ((other_pid > 0) && (this_pid != other_pid)) {
+
+		/* The other stream is open, and not by the same
+		   task as this one. Make sure that the parameters
+		   that matter are the same.
+		 */
+
+		if ((int)params_rate(params) != korg1212->clkRate) {
+			spin_unlock_irqrestore(&korg1212->lock, flags);
+			_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
+			return -EBUSY;
+		}
+
+        	spin_unlock_irqrestore(&korg1212->lock, flags);
+	        return 0;
+	}
+
         if ((err = snd_korg1212_SetRate(korg1212, params_rate(params))) < 0) {
                 spin_unlock_irqrestore(&korg1212->lock, flags);
                 return err;
         }
-/*
-        if (params_format(params) != SNDRV_PCM_FORMAT_S16_LE) {
-                spin_unlock_irqrestore(&korg1212->lock, flags);
-                return -EINVAL;
-        }
-*/
+
 	korg1212->channels = params_channels(params);
         korg1212->periodsize = K1212_PERIOD_BYTES;
 
@@ -2090,9 +2139,9 @@
                 korg1212->irq = -1;
         }
         
-        if (korg1212->iobase != 0) {
-                iounmap((void *)korg1212->iobase);
-                korg1212->iobase = 0;
+        if (korg1212->iobase != NULL) {
+                iounmap(korg1212->iobase);
+                korg1212->iobase = NULL;
         }
         
 	pci_release_regions(korg1212->pci);
@@ -2182,6 +2231,8 @@
 	korg1212->opencnt = 0;
 	korg1212->playcnt = 0;
 	korg1212->setcnt = 0;
+	korg1212->playback_pid = -1;
+	korg1212->capture_pid = -1;
         snd_korg1212_setCardState(korg1212, K1212_STATE_UNINITIALIZED);
         korg1212->idleMonitorOn = 0;
         korg1212->clkSrcRate = K1212_CLKIDX_LocalAt44_1K;
@@ -2216,9 +2267,9 @@
 		   stateName[korg1212->cardState]);
 #endif
 
-        if ((korg1212->iobase = (unsigned long) ioremap(korg1212->iomem, iomem_size)) == 0) {
-		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", korg1212->iobase,
-                           korg1212->iobase + iomem_size - 1);
+        if ((korg1212->iobase = ioremap(korg1212->iomem, iomem_size)) == NULL) {
+		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
+                           korg1212->iomem + iomem_size - 1);
                 return -EBUSY;
         }
 
@@ -2235,16 +2286,16 @@
 
 	pci_set_master(korg1212->pci);
 
-        korg1212->statusRegPtr = (u32 *) (korg1212->iobase + STATUS_REG_OFFSET);
-        korg1212->outDoorbellPtr = (u32 *) (korg1212->iobase + OUT_DOORBELL_OFFSET);
-        korg1212->inDoorbellPtr = (u32 *) (korg1212->iobase + IN_DOORBELL_OFFSET);
-        korg1212->mailbox0Ptr = (u32 *) (korg1212->iobase + MAILBOX0_OFFSET);
-        korg1212->mailbox1Ptr = (u32 *) (korg1212->iobase + MAILBOX1_OFFSET);
-        korg1212->mailbox2Ptr = (u32 *) (korg1212->iobase + MAILBOX2_OFFSET);
-        korg1212->mailbox3Ptr = (u32 *) (korg1212->iobase + MAILBOX3_OFFSET);
-        korg1212->controlRegPtr = (u32 *) (korg1212->iobase + PCI_CONTROL_OFFSET);
-        korg1212->sensRegPtr = (u16 *) (korg1212->iobase + SENS_CONTROL_OFFSET);
-        korg1212->idRegPtr = (u32 *) (korg1212->iobase + DEV_VEND_ID_OFFSET);
+        korg1212->statusRegPtr = (u32 __iomem *) (korg1212->iobase + STATUS_REG_OFFSET);
+        korg1212->outDoorbellPtr = (u32 __iomem *) (korg1212->iobase + OUT_DOORBELL_OFFSET);
+        korg1212->inDoorbellPtr = (u32 __iomem *) (korg1212->iobase + IN_DOORBELL_OFFSET);
+        korg1212->mailbox0Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX0_OFFSET);
+        korg1212->mailbox1Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX1_OFFSET);
+        korg1212->mailbox2Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX2_OFFSET);
+        korg1212->mailbox3Ptr = (u32 __iomem *) (korg1212->iobase + MAILBOX3_OFFSET);
+        korg1212->controlRegPtr = (u32 __iomem *) (korg1212->iobase + PCI_CONTROL_OFFSET);
+        korg1212->sensRegPtr = (u16 __iomem *) (korg1212->iobase + SENS_CONTROL_OFFSET);
+        korg1212->idRegPtr = (u32 __iomem *) (korg1212->iobase + DEV_VEND_ID_OFFSET);
 
 #if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: card registers:\n"
@@ -2311,7 +2362,7 @@
 
 #if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: Record Data Area = 0x%p (0x%08x), %d bytes\n",
-		korg1212->recordDataBufsPtr, korg1212->RecDataBufsPhy, korg1212->DataBufsSize);
+		korg1212->recordDataBufsPtr, korg1212->RecDataPhy, korg1212->DataBufsSize);
 #endif
 
 #else // K1212_LARGEALLOC
diff -Nru a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
--- a/sound/pci/mixart/mixart.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/mixart/mixart.c	2004-10-21 14:13:16 -07:00
@@ -1077,7 +1077,7 @@
 	/* release the i/o ports */
 	for (i = 0; i < 2; i++) {
 		if (mgr->mem[i].virt)
-			iounmap((void *)mgr->mem[i].virt);
+			iounmap(mgr->mem[i].virt);
 	}
 	pci_release_regions(mgr->pci);
 
@@ -1311,8 +1311,8 @@
 	}
 	for (i = 0; i < 2; i++) {
 		mgr->mem[i].phys = pci_resource_start(pci, i);
-		mgr->mem[i].virt = (unsigned long)ioremap_nocache(mgr->mem[i].phys,
-								  pci_resource_len(pci, i));
+		mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys,
+						   pci_resource_len(pci, i));
 	}
 
 	if (request_irq(pci->irq, snd_mixart_interrupt, SA_INTERRUPT|SA_SHIRQ, CARD_NAME, (void *)mgr)) {
diff -Nru a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h
--- a/sound/pci/mixart/mixart.h	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/mixart/mixart.h	2004-10-21 14:13:16 -07:00
@@ -53,7 +53,7 @@
 
 struct mem_area {
 	unsigned long phys;
-	unsigned long virt;
+	void __iomem *virt;
 	struct resource *res;
 };
 
diff -Nru a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
--- a/sound/pci/nm256/nm256.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/nm256/nm256.c	2004-10-21 14:13:16 -07:00
@@ -61,6 +61,8 @@
 static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
 static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
 static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
+static int reset_workaround[SNDRV_CARDS];
+static int boot_devs;
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -80,6 +82,8 @@
 MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
 module_param_array(vaio_hack, bool, NULL, 0444);
 MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
+module_param_array(reset_workaround, bool, boot_devs, 0444);
+MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
 
 /*
  * hw definitions
@@ -189,7 +193,7 @@
 	
 	u32 buf;	/* offset from chip->buffer */
 	int bufsize;	/* buffer size in bytes */
-	unsigned long bufptr;		/* mapped pointer */
+	void __iomem *bufptr;		/* mapped pointer */
 	unsigned long bufptr_addr;	/* physical address of the mapped pointer */
 
 	int dma_size;		/* buffer size of the substream in bytes */
@@ -204,11 +208,11 @@
 	
 	snd_card_t *card;
 
-	unsigned long cport;		/* control port */
+	void __iomem *cport;		/* control port */
 	struct resource *res_cport;	/* its resource */
 	unsigned long cport_addr;	/* physical address */
 
-	unsigned long buffer;		/* buffer */
+	void __iomem *buffer;		/* buffer */
 	struct resource *res_buffer;	/* its resource */
 	unsigned long buffer_addr;	/* buffer phyiscal address */
 
@@ -221,7 +225,7 @@
 
 	unsigned int coeffs_current: 1;	/* coeff. table is loaded? */
 	unsigned int use_cache: 1;	/* use one big coef. table */
-	unsigned int latitude_workaround: 1; /* Dell Latitude LS workaround needed */
+	unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
 
 	int mixer_base;			/* register offset of ac97 mixer */
 	int mixer_status_offset;	/* offset of mixer status reg. */
@@ -328,7 +332,7 @@
 		return;
 	}
 #endif
-	memcpy_toio((void *)chip->buffer + offset, src, size);
+	memcpy_toio(chip->buffer + offset, src, size);
 }
 
 /*
@@ -886,8 +890,8 @@
 
 	for (i = 0; i < 2; i++) {
 		nm256_stream_t *s = &chip->streams[i];
-		s->bufptr = chip->buffer +  s->buf - chip->buffer_start;
-		s->bufptr_addr = chip->buffer_addr + s->buf - chip->buffer_start;
+		s->bufptr = chip->buffer + (s->buf - chip->buffer_start);
+		s->bufptr_addr = chip->buffer_addr + (s->buf - chip->buffer_start);
 	}
 
 	err = snd_pcm_new(chip->card, chip->card->driver, device,
@@ -1161,16 +1165,14 @@
 {
 	nm256_t *chip = ac97->private_data;
 
-	spin_lock(&chip->reg_lock);
 	/* Reset the mixer.  'Tis magic!  */
 	snd_nm256_writeb(chip, 0x6c0, 1);
-	if (chip->latitude_workaround) {
+	if (! chip->reset_workaround) {
 		/* Dell latitude LS will lock up by this */
 		snd_nm256_writeb(chip, 0x6cc, 0x87);
 	}
 	snd_nm256_writeb(chip, 0x6cc, 0x80);
 	snd_nm256_writeb(chip, 0x6cc, 0x0);
-	spin_unlock(&chip->reg_lock);
 }
 
 /* create an ac97 mixer interface */
@@ -1225,13 +1227,13 @@
 snd_nm256_peek_for_sig(nm256_t *chip)
 {
 	/* The signature is located 1K below the end of video RAM.  */
-	unsigned long temp;
+	void __iomem *temp;
 	/* Default buffer end is 5120 bytes below the top of RAM.  */
 	unsigned long pointer_found = chip->buffer_end - 0x1400;
 	u32 sig;
 
-	temp = (unsigned long) ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
-	if (temp == 0) {
+	temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
+	if (temp == NULL) {
 		snd_printk("Unable to scan for card signature in video RAM\n");
 		return -EBUSY;
 	}
@@ -1247,7 +1249,7 @@
 		    pointer < chip->buffer_size ||
 		    pointer > chip->buffer_end) {
 			snd_printk("invalid signature found: 0x%x\n", pointer);
-			iounmap((void *)temp);
+			iounmap(temp);
 			return -ENODEV;
 		} else {
 			pointer_found = pointer;
@@ -1255,7 +1257,7 @@
 		}
 	}
 
-	iounmap((void *)temp);
+	iounmap(temp);
 	chip->buffer_end = pointer_found;
 
 	return 0;
@@ -1304,9 +1306,9 @@
 		synchronize_irq(chip->irq);
 
 	if (chip->cport)
-		iounmap((void *) chip->cport);
+		iounmap(chip->cport);
 	if (chip->buffer)
-		iounmap((void *) chip->buffer);
+		iounmap(chip->buffer);
 	if (chip->res_cport) {
 		release_resource(chip->res_cport);
 		kfree_nocheck(chip->res_cport);
@@ -1342,7 +1344,6 @@
 		.dev_free =	snd_nm256_dev_free,
 	};
 	u32 addr;
-	u16 subsystem_vendor, subsystem_device;
 
 	*chip_ret = NULL;
 
@@ -1379,8 +1380,8 @@
 		err = -EBUSY;
 		goto __error;
 	}
-	chip->cport = (unsigned long) ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
-	if (chip->cport == 0) {
+	chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
+	if (chip->cport == NULL) {
 		snd_printk("unable to map control port %lx\n", chip->cport_addr);
 		err = -ENOMEM;
 		goto __error;
@@ -1444,8 +1445,8 @@
 		err = -EBUSY;
 		goto __error;
 	}
-	chip->buffer = (unsigned long) ioremap_nocache(chip->buffer_addr, chip->buffer_size);
-	if (chip->buffer == 0) {
+	chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
+	if (chip->buffer == NULL) {
 		err = -ENOMEM;
 		snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr);
 		goto __error;
@@ -1479,19 +1480,6 @@
 
 	chip->coeffs_current = 0;
 
-	/* check workarounds */
-	chip->latitude_workaround = 1;
-	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
-	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
-	if (subsystem_vendor == 0x104d && subsystem_device == 0x8041) {
-		/* this workaround will cause lock-up after suspend/resume on Sony PCG-F305 */
-		chip->latitude_workaround = 0;
-	}
-	if (subsystem_vendor == 0x1028 && subsystem_device == 0x0080) {
-		/* this workaround will cause lock-up after suspend/resume on a Dell laptop */
-		chip->latitude_workaround = 0;
-	}
-
 	snd_nm256_init_chip(chip);
 
 	if ((err = snd_nm256_pcm(chip, 0)) < 0)
@@ -1524,11 +1512,15 @@
 	int type;
 };
 
-#define NM_BLACKLISTED	1
+enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
 
 static struct nm256_quirk nm256_quirks[] __devinitdata = {
 	/* HP omnibook 4150 has cs4232 codec internally */
 	{ .vendor = 0x103c, .device = 0x0007, .type = NM_BLACKLISTED },
+	/* Sony PCG-F305 */
+	{ .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
+	/* Dell Latitude LS */
+	{ .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
 	{ } /* terminator */
 };
 
@@ -1559,9 +1551,13 @@
 
 	for (q = nm256_quirks; q->vendor; q++) {
 		if (q->vendor == subsystem_vendor && q->device == subsystem_device) {
-			if (q->type == NM_BLACKLISTED) {
+			switch (q->type) {
+			case NM_BLACKLISTED:
 				printk(KERN_INFO "nm256: The device is blacklisted.  Loading stopped\n");
 				return -ENODEV;
+			case NM_RESET_WORKAROUND:
+				reset_workaround[dev] = 1;
+				break;
 			}
 		}
 	}
@@ -1608,6 +1604,11 @@
 				    &chip)) < 0) {
 		snd_card_free(card);
 		return err;
+	}
+
+	if (reset_workaround[dev]) {
+		snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
+		chip->reset_workaround = 1;
 	}
 
 	sprintf(card->shortname, "NeoMagic %s", card->driver);
diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/rme32.c	2004-10-21 14:13:16 -07:00
@@ -210,7 +210,7 @@
 	spinlock_t lock;
 	int irq;
 	unsigned long port;
-	unsigned long iobase;
+	void __iomem *iobase;
 
 	u32 wcreg;		/* cached write control register value */
 	u32 wcreg_spdif;	/* S/PDIF setup */
@@ -725,9 +725,8 @@
 	/* S/PDIF setup */
 	if ((rme32->wcreg & RME32_WCR_ADAT) == 0) {
 		rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
-		writel(rme32->wcreg |=
-		       rme32->wcreg_spdif_stream,
-		       rme32->iobase + RME32_IO_CONTROL_REGISTER);
+		rme32->wcreg |= rme32->wcreg_spdif_stream;
+		writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	}
 	spin_unlock_irq(&rme32->lock);
 
@@ -1123,7 +1122,7 @@
 	}
 	
 	/* prefill playback buffer */
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
+	if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) {
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == rme32->playback_substream) {
@@ -1344,8 +1343,8 @@
 		rme32->irq = -1;
 	}
 	if (rme32->iobase) {
-		iounmap((void *) rme32->iobase);
-		rme32->iobase = 0;
+		iounmap(rme32->iobase);
+		rme32->iobase = NULL;
 	}
 	if (rme32->port) {
 		pci_release_regions(rme32->pci);
@@ -1387,7 +1386,7 @@
 	}
 	rme32->irq = pci->irq;
 
-	if ((rme32->iobase = (unsigned long) ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
+	if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
 		snd_printk("unable to remap memory region 0x%lx-0x%lx\n",
 			   rme32->port, rme32->port + RME32_IO_SIZE - 1);
 		return -ENOMEM;
@@ -1636,8 +1635,8 @@
 		val &= ~RME32_WCR_MUTE;
 	else
 		val |= RME32_WCR_MUTE;
-	writel(rme32->wcreg =
-	       val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
+	rme32->wcreg = val;
+	writel(val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	spin_unlock_irq(&rme32->lock);
 	return change;
 }
@@ -1861,7 +1860,8 @@
 	change = val != rme32->wcreg_spdif_stream;
 	rme32->wcreg_spdif_stream = val;
 	rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);
-	writel(rme32->wcreg |= val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
+	rme32->wcreg |= val;
+	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	spin_unlock_irq(&rme32->lock);
 	return change;
 }
@@ -1969,16 +1969,14 @@
 	snd_card_t *card;
 	int err;
 
-	for (; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev]) {
-			dev++;
-			return -ENOENT;
-		}
-		break;
-	}
 	if (dev >= SNDRV_CARDS) {
 		return -ENODEV;
 	}
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(rme32_t))) == NULL)
 		return -ENOMEM;
diff -Nru a/sound/pci/rme96.c b/sound/pci/rme96.c
--- a/sound/pci/rme96.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/rme96.c	2004-10-21 14:13:16 -07:00
@@ -225,7 +225,7 @@
 	spinlock_t    lock;
 	int irq;
 	unsigned long port;
-	unsigned long iobase;
+	void __iomem *iobase;
 	
 	u32 wcreg;    /* cached write control register value */
 	u32 wcreg_spdif;		/* S/PDIF setup */
@@ -1547,8 +1547,8 @@
 		rme96->irq = -1;
 	}
 	if (rme96->iobase) {
-		iounmap((void *)rme96->iobase);
-		rme96->iobase = 0;
+		iounmap(rme96->iobase);
+		rme96->iobase = NULL;
 	}
 	if (rme96->port) {
 		pci_release_regions(rme96->pci);
@@ -1592,7 +1592,7 @@
 	}
 	rme96->irq = pci->irq;
 
-	if ((rme96->iobase = (unsigned long) ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
+	if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
 		snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
 		return -ENOMEM;
 	}
@@ -1859,7 +1859,8 @@
 	spin_lock_irq(&rme96->lock);
 	val = (rme96->wcreg & ~RME96_WCR_SEL) | val;
 	change = val != rme96->wcreg;
-	writel(rme96->wcreg = val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+	rme96->wcreg = val;
+	writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	spin_unlock_irq(&rme96->lock);
 	return change;
 }
@@ -2177,7 +2178,8 @@
 	change = val != rme96->wcreg_spdif_stream;
 	rme96->wcreg_spdif_stream = val;
 	rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
-	writel(rme96->wcreg |= val, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+	rme96->wcreg |= val;
+	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	spin_unlock_irq(&rme96->lock);
 	return change;
 }
diff -Nru a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/rme9652/hdsp.c	2004-10-21 14:13:16 -07:00
@@ -470,7 +470,7 @@
 	int                   dev;
 	int                   irq;
 	unsigned long         port;
-        unsigned long         iobase;
+        void __iomem         *iobase;
 	snd_card_t           *card;
 	snd_pcm_t            *pcm;
 	snd_hwdep_t          *hwdep;
@@ -934,9 +934,7 @@
 	}
 
 	position &= HDSP_BufferPositionMask;
-	position /= 4;
-	position -= 32;
-	position &= (HDSP_CHANNEL_BUFFER_SAMPLES-1);
+	position &= (hdsp->period_bytes/2) - 1;
 	return position;
 }
 
@@ -3227,7 +3225,7 @@
 	snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
 		    hdsp->capture_buffer, hdsp->playback_buffer);
 	snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
-		    hdsp->irq, hdsp->port, hdsp->iobase);
+		    hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase);
 	snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register);
 	snd_iprintf(buffer, "Control2 register: 0x%x\n", hdsp->control2_register);
 	snd_iprintf(buffer, "Status register: 0x%x\n", status);
@@ -4433,6 +4431,130 @@
 }
 
 
+/* helper functions for copying meter values */
+static inline int copy_u32_le(void __user *dest, void __iomem *src)
+{
+	u32 val = readl(src);
+	return copy_to_user(dest, &val, 4);
+}
+
+static inline int copy_u64_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
+{
+	u32 rms_low, rms_high;
+	u64 rms;
+	rms_low = readl(src_low);
+	rms_high = readl(src_high);
+	rms = ((u64)rms_high << 32) | rms_low;
+	return copy_to_user(dest, &rms, 8);
+}
+
+static inline int copy_u48_le(void __user *dest, void __iomem *src_low, void __iomem *src_high)
+{
+	u32 rms_low, rms_high;
+	u64 rms;
+	rms_low = readl(src_low) & 0xffffff00;
+	rms_high = readl(src_high) & 0xffffff00;
+	rms = ((u64)rms_high << 32) | rms_low;
+	return copy_to_user(dest, &rms, 8);
+}
+
+static int hdsp_9652_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
+{
+	int doublespeed = 0;
+	int i, j, channels, ofs;
+
+	if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
+		doublespeed = 1;
+	channels = doublespeed ? 14 : 26;
+	for (i = 0, j = 0; i < 26; ++i) {
+		if (doublespeed && (i & 4))
+			continue;
+		ofs = HDSP_9652_peakBase - j * 4;
+		if (copy_u32_le(&peak_rms->input_peaks[i], hdsp->iobase + ofs))
+			return -EFAULT;
+		ofs -= channels * 4;
+		if (copy_u32_le(&peak_rms->playback_peaks[i], hdsp->iobase + ofs))
+			return -EFAULT;
+		ofs -= channels * 4;
+		if (copy_u32_le(&peak_rms->output_peaks[i], hdsp->iobase + ofs))
+			return -EFAULT;
+		ofs = HDSP_9652_rmsBase + j * 8;
+		if (copy_u48_le(&peak_rms->input_rms[i], hdsp->iobase + ofs,
+				hdsp->iobase + ofs + 4))
+			return -EFAULT;
+		ofs += channels * 8;
+		if (copy_u48_le(&peak_rms->playback_rms[i], hdsp->iobase + ofs,
+				hdsp->iobase + ofs + 4))
+			return -EFAULT;
+		ofs += channels * 8;
+		if (copy_u48_le(&peak_rms->output_rms[i], hdsp->iobase + ofs,
+				hdsp->iobase + ofs + 4))
+			return -EFAULT;
+		j++;
+	}
+	return 0;
+}
+
+static int hdsp_9632_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
+{
+	int i, j;
+	hdsp_9632_meters_t __iomem *m;
+	int doublespeed = 0;
+
+	if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
+		doublespeed = 1;
+	m = (hdsp_9632_meters_t __iomem *)(hdsp->iobase+HDSP_9632_metersBase);
+	for (i = 0, j = 0; i < 16; ++i, ++j) {
+		if (copy_u32_le(&peak_rms->input_peaks[i], &m->input_peak[j]))
+			return -EFAULT;
+		if (copy_u32_le(&peak_rms->playback_peaks[i], &m->playback_peak[j]))
+			return -EFAULT;
+		if (copy_u32_le(&peak_rms->output_peaks[i], &m->output_peak[j]))
+			return -EFAULT;
+		if (copy_u64_le(&peak_rms->input_rms[i], &m->input_rms_low[j],
+				&m->input_rms_high[j]))
+			return -EFAULT;
+		if (copy_u64_le(&peak_rms->playback_rms[i], &m->playback_rms_low[j],
+				&m->playback_rms_high[j]))
+			return -EFAULT;
+		if (copy_u64_le(&peak_rms->output_rms[i], &m->output_rms_low[j],
+				&m->output_rms_high[j]))
+			return -EFAULT;
+		if (doublespeed && i == 3) i += 4;
+	}
+	return 0;
+}
+
+static int hdsp_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
+{
+	int i;
+
+	for (i = 0; i < 26; i++) {
+		if (copy_u32_le(&peak_rms->playback_peaks[i],
+				hdsp->iobase + HDSP_playbackPeakLevel + i * 4))
+			return -EFAULT;
+		if (copy_u32_le(&peak_rms->input_peaks[i],
+				hdsp->iobase + HDSP_inputPeakLevel + i * 4))
+			return -EFAULT;
+	}
+	for (i = 0; i < 28; i++) {
+		if (copy_u32_le(&peak_rms->output_peaks[i],
+				hdsp->iobase + HDSP_outputPeakLevel + i * 4))
+			return -EFAULT;
+	}
+	for (i = 0; i < 26; ++i) {
+		if (copy_u64_le(&peak_rms->playback_rms[i],
+				hdsp->iobase + HDSP_playbackRmsLevel + i * 8,
+				hdsp->iobase + HDSP_playbackRmsLevel + i * 8 + 4))
+			return -EFAULT;
+		if (copy_u64_le(&peak_rms->input_rms[i], 
+				hdsp->iobase + HDSP_inputRmsLevel + i * 8,
+				hdsp->iobase + HDSP_inputRmsLevel + i * 8 + 4))
+			return -EFAULT;
+	}
+	return 0;
+}
+
 static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	hdsp_t *hdsp = (hdsp_t *)hw->private_data;	
@@ -4440,108 +4562,21 @@
 
 	switch (cmd) {
 	case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
-		hdsp_peak_rms_t __user *peak_rms;
-		int i;
-		
-		if (hdsp->io_type == H9652) {
-			unsigned long rms_low, rms_high;
-			int doublespeed = 0;
-			if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
-				doublespeed = 1;
-			peak_rms = (hdsp_peak_rms_t __user *)arg;
-			for (i = 0; i < 26; ++i) {
-				if (!(doublespeed && (i & 4))) {
-					if (copy_to_user_fromio((void __user *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0)
-						return -EFAULT;
-					if (copy_to_user_fromio((void __user *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
-						return -EFAULT;
-					if (copy_to_user_fromio((void __user *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
-						return -EFAULT;
-					rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8) & 0xFFFFFF00;
-					rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8+4) & 0xFFFFFF00;
-					rms_high += (rms_low >> 24);
-					rms_low <<= 8;
-					if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &rms_low, 4) != 0)
-						return -EFAULT;
-					if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0)
-						return -EFAULT;					
-					rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
-					rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
-					rms_high += (rms_low >> 24);
-					rms_low <<= 8;
-					if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0)
-						return -EFAULT;
-					if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0)
-						return -EFAULT;					
-					rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
-					rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
-					rms_high += (rms_low >> 24);
-					rms_low <<= 8;
-					if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &rms_low, 4) != 0)
-						return -EFAULT;
-					if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0)
-						return -EFAULT;					
-				}
-			}
-			return 0;
-		}
-		if (hdsp->io_type == H9632) {
-			int j;
-			hdsp_9632_meters_t *m;
-			int doublespeed = 0;
-			if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
-				doublespeed = 1;
-			m = (hdsp_9632_meters_t *)(hdsp->iobase+HDSP_9632_metersBase);
-			peak_rms = (hdsp_peak_rms_t __user *)arg;
-			for (i = 0, j = 0; i < 16; ++i, ++j) {
-				if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, &(m->input_peak[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, &(m->playback_peak[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, &(m->output_peak[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &(m->input_rms_low[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &(m->playback_rms_low[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &(m->output_rms_low[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &(m->input_rms_high[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &(m->playback_rms_high[j]), 4) != 0)
-					return -EFAULT;
-				if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &(m->output_rms_high[j]), 4) != 0)
-					return -EFAULT;
-				if (doublespeed && i == 3) i += 4;
-			}
-			return 0;
-		}
+		hdsp_peak_rms_t __user *peak_rms = (hdsp_peak_rms_t __user *)arg;
+
 		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
-			snd_printk("firmware needs to be uploaded to the card.\n");	
+			snd_printk(KERN_ERR "firmware needs to be uploaded to the card.\n");
 			return -EINVAL;
 		}
-		peak_rms = (hdsp_peak_rms_t __user *)arg;
-		for (i = 0; i < 26; ++i) {
-		    if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, (void *)hdsp->iobase+HDSP_playbackPeakLevel+i*4, 4) != 0)
-			    return -EFAULT;
-		    if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, (void *)hdsp->iobase+HDSP_inputPeakLevel+i*4, 4) != 0)
-			    return -EFAULT;
-		}
-		for (i = 0; i < 26; ++i) {
-			if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8, 4) != 0)
-				return -EFAULT;
-			if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8+4, 4) != 0)
-				return -EFAULT;
-			if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8, 4) != 0)
-				return -EFAULT;
-			if (copy_to_user((void __user *)peak_rms->input_rms+i*8, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8+4, 4) != 0)
-				return -EFAULT;
-		}
-		for (i = 0; i < 28; ++i) {
-		    if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, (void *)hdsp->iobase+HDSP_outputPeakLevel+i*4, 4) != 0)
-			    return -EFAULT;
+
+		switch (hdsp->io_type) {
+		case H9652:
+			return hdsp_9652_get_peak(hdsp, peak_rms);
+		case H9632:
+			return hdsp_9632_get_peak(hdsp, peak_rms);
+		default:
+			return hdsp_get_peak(hdsp, peak_rms);
 		}
-		break;
 	}
 	case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: {
 		hdsp_config_info_t info;
@@ -4619,7 +4654,7 @@
 	}
 	case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
 		hdsp_firmware_t __user *firmware;
-		unsigned long __user *firmware_data;
+		u32 __user *firmware_data;
 		int err;
 		
 		if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
@@ -4637,7 +4672,7 @@
 			return -EIO;
 		}
 
-		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(unsigned long)*24413) != 0) {
+		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) {
 			return -EFAULT;
 		}
 		
@@ -4878,7 +4913,7 @@
 	hdsp->midi[1].output = NULL;
 	spin_lock_init(&hdsp->midi[0].lock);
 	spin_lock_init(&hdsp->midi[1].lock);
-	hdsp->iobase = 0;
+	hdsp->iobase = NULL;
 	hdsp->control_register = 0;
 	hdsp->control2_register = 0;
 	hdsp->io_type = Undefined;
@@ -4936,7 +4971,7 @@
 	if ((err = pci_request_regions(pci, "hdsp")) < 0)
 		return err;
 	hdsp->port = pci_resource_start(pci, 0);
-	if ((hdsp->iobase = (unsigned long) ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == 0) {
+	if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
 		snd_printk("unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
 		return -EBUSY;
 	}
@@ -5020,7 +5055,7 @@
 	snd_hdsp_free_buffers(hdsp);
 	
 	if (hdsp->iobase)
-		iounmap((void *) hdsp->iobase);
+		iounmap(hdsp->iobase);
 
 	if (hdsp->port)
 		pci_release_regions(hdsp->pci);
diff -Nru a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
--- a/sound/pci/rme9652/rme9652.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/rme9652/rme9652.c	2004-10-21 14:13:16 -07:00
@@ -211,7 +211,7 @@
 	spinlock_t lock;
 	int irq;
 	unsigned long port;
-	unsigned long iobase;
+	void __iomem *iobase;
 	
 	int precise_ptr;
 
@@ -1628,7 +1628,7 @@
 	snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
 		    rme9652->capture_buffer, rme9652->playback_buffer);
 	snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
-		    rme9652->irq, rme9652->port, rme9652->iobase);
+		    rme9652->irq, rme9652->port, (unsigned long)rme9652->iobase);
 	snd_iprintf(buffer, "Control register: %x\n", rme9652->control_register);
 
 	snd_iprintf(buffer, "\n");
@@ -1808,7 +1808,7 @@
 	if (rme9652->irq >= 0)
 		free_irq(rme9652->irq, (void *)rme9652);
 	if (rme9652->iobase)
-		iounmap((void *) rme9652->iobase);
+		iounmap(rme9652->iobase);
 	if (rme9652->port)
 		pci_release_regions(rme9652->pci);
 
@@ -2496,8 +2496,8 @@
 	if ((err = pci_request_regions(pci, "rme9652")) < 0)
 		return err;
 	rme9652->port = pci_resource_start(pci, 0);
-	rme9652->iobase = (unsigned long) ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
-	if (rme9652->iobase == 0) {
+	rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
+	if (rme9652->iobase == NULL) {
 		snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
 		return -EBUSY;
 	}
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/via82xx.c	2004-10-21 14:13:16 -07:00
@@ -126,6 +126,7 @@
 #define VIA_REV_8233		0x30	/* 2 rec, 4 pb, 1 multi-pb, spdif */
 #define VIA_REV_8233A		0x40	/* 1 rec, 1 multi-pb, spdf */
 #define VIA_REV_8235		0x50	/* 2 rec, 4 pb, 1 multi-pb, spdif */
+#define VIA_REV_8237		0x60
 
 /*
  *  Direct registers
@@ -622,11 +623,6 @@
 	unsigned int status;
 	unsigned int i;
 
-#if 0
-	/* FIXME: does it work on via823x? */
-	if (chip->chip_type != TYPE_VIA686)
-		goto _skip_sgd;
-#endif
 	status = inl(VIAREG(chip, SGD_SHADOW));
 	if (! (status & chip->intr_mask)) {
 		if (chip->rmidi)
@@ -634,7 +630,6 @@
 			return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
 		return IRQ_NONE;
 	}
-// _skip_sgd:
 
 	/* check status for each stream */
 	spin_lock(&chip->reg_lock);
@@ -1546,6 +1541,13 @@
 }
 
 static struct ac97_quirk ac97_quirks[] = {
+	{
+		.vendor = 0x1106,
+		.device = 0x4161,
+		.codec_id = 0x56494161, /* VT1612A */
+		.name = "Soltek SL-75DRV5",
+		.type = AC97_TUNE_NONE
+	},
 	{	/* FIXME: which codec? */
 		.vendor = 0x1106,
 		.device = 0x4161,
@@ -1605,6 +1607,7 @@
 		return err;
 	chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
 	chip->ac97_bus->clock = chip->ac97_clock;
+	chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
@@ -2068,6 +2071,7 @@
 	{ VIA_REV_8233, "VIA 8233", TYPE_VIA8233 },
 	{ VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
 	{ VIA_REV_8235, "VIA 8235", TYPE_VIA8233 },
+	{ VIA_REV_8237, "VIA 8237", TYPE_VIA8233 },
 };
 
 /*
@@ -2094,10 +2098,11 @@
 		{ .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
 		{ .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
 		{ .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
+		{ .vendor = 0x1106, .device = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */
 		{ .vendor = 0x1106, .device = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */
 		{ .vendor = 0x1297, .device = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
 		{ .vendor = 0x1297, .device = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */
-		{ .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_NO_VRA }, /* Gigabyte GA-7VAXP (FIXME: or DXS_ENABLE?) */
+		{ .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
 		{ .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
 		{ .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
 		{ .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
@@ -2193,6 +2198,8 @@
 		}
 		if (chip_type == TYPE_VIA8233A)
 			strcpy(card->driver, "VIA8233A");
+		else if (revision >= VIA_REV_8237)
+			strcpy(card->driver, "VIA8237"); /* no slog assignment */
 		else
 			strcpy(card->driver, "VIA8233");
 		break;
@@ -2234,8 +2241,9 @@
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 
-	sprintf(card->longname, "%s at 0x%lx, irq %d",
-		card->shortname, chip->port, chip->irq);
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s with %s at %#lx, irq %d", card->shortname,
+		 snd_ac97_get_short_name(chip->ac97), chip->port, chip->irq);
 
 	snd_via82xx_proc_init(chip);
 
diff -Nru a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
--- a/sound/pci/ymfpci/ymfpci_main.c	2004-10-21 14:13:16 -07:00
+++ b/sound/pci/ymfpci/ymfpci_main.c	2004-10-21 14:13:16 -07:00
@@ -2085,7 +2085,7 @@
 	}
 #endif
 	if (chip->reg_area_virt)
-		iounmap((void *)chip->reg_area_virt);
+		iounmap(chip->reg_area_virt);
 	if (chip->work_ptr.area)
 		snd_dma_free_pages(&chip->work_ptr);
 	
@@ -2217,7 +2217,7 @@
 	chip->device_id = pci->device;
 	pci_read_config_byte(pci, PCI_REVISION_ID, (u8 *)&chip->rev);
 	chip->reg_area_phys = pci_resource_start(pci, 0);
-	chip->reg_area_virt = (unsigned long)ioremap_nocache(chip->reg_area_phys, 0x8000);
+	chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
 	pci_set_master(pci);
 
 	if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
diff -Nru a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig
--- a/sound/pcmcia/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/pcmcia/Kconfig	2004-10-21 14:13:16 -07:00
@@ -8,20 +8,32 @@
 	depends on SND && PCMCIA && ISA
 	select SND_VX_LIB
 	help
-	  Say 'Y' or 'M' to include support for Digigram VXpocket soundcard.
+	  Say Y here to include support for Digigram VXpocket
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-vxpocket.
 
 config SND_VXP440
 	tristate "Digigram VXpocket 440"
 	depends on SND && PCMCIA && ISA
 	select SND_VX_LIB
 	help
-	  Say 'Y' or 'M' to include support for Digigram VXpocket 440 soundcard.
+	  Say Y here to include support for Digigram VXpocket 440
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-vxp440.
 
 config SND_PDAUDIOCF
 	tristate "Sound Core PDAudioCF"
 	depends on SND && PCMCIA && ISA
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Sound Core PDAudioCF soundcard.
+	  Say Y here to include support for Sound Core PDAudioCF
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-pdaudiocf.
 
 endmenu
diff -Nru a/sound/ppc/Kconfig b/sound/ppc/Kconfig
--- a/sound/ppc/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/ppc/Kconfig	2004-10-21 14:13:16 -07:00
@@ -13,6 +13,11 @@
 	tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
 	depends on SND && I2C && INPUT
 	select SND_PCM
+	help
+	  Say Y here to include support for the integrated sound device.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-powermac.
 
 endmenu
 
diff -Nru a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
--- a/sound/ppc/tumbler.c	2004-10-21 14:13:16 -07:00
+++ b/sound/ppc/tumbler.c	2004-10-21 14:13:16 -07:00
@@ -79,7 +79,7 @@
 #ifdef CONFIG_PPC_HAS_FEATURE_CALLS
 	unsigned int addr;
 #else
-	void *addr;
+	void __iomem *addr;
 #endif
 	int active_state;
 } pmac_gpio_t;
@@ -162,7 +162,7 @@
 {
 	if (gp->addr) {
 		iounmap(gp->addr);
-		gp->addr = 0;
+		gp->addr = NULL;
 	}
 }
 #endif /* CONFIG_PPC_HAS_FEATURE_CALLS */
@@ -968,7 +968,7 @@
 #ifdef CONFIG_PPC_HAS_FEATURE_CALLS
 	gp->addr = (*base) & 0x0000ffff;
 #else
-	gp->addr = (void*)ioremap((unsigned long)(*base), 1);
+	gp->addr = ioremap((unsigned long)(*base), 1);
 #endif
 	base = (u32 *)get_property(node, "audio-gpio-active-state", NULL);
 	if (base)
diff -Nru a/sound/usb/Kconfig b/sound/usb/Kconfig
--- a/sound/usb/Kconfig	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/Kconfig	2004-10-21 14:13:16 -07:00
@@ -1,6 +1,6 @@
 # ALSA USB drivers
 
-menu "ALSA USB devices"
+menu "USB devices"
 	depends on SND!=n && USB!=n
 
 config SND_USB_AUDIO
@@ -9,7 +9,11 @@
 	select SND_RAWMIDI
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for USB audio and USB MIDI devices.
+	  Say Y here to include support for USB audio and USB MIDI
+	  devices.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-usb-audio.
 
 config SND_USB_USX2Y
 	tristate "Tascam US-122, US-224 and US-428 USB driver"
@@ -18,8 +22,11 @@
 	select SND_RAWMIDI
 	select SND_PCM
 	help
-	  Say 'Y' or 'M' to include support for Tascam USB Audio/MIDI 
+	  Say Y here to include support for Tascam USB Audio/MIDI
 	  interfaces or controllers US-122, US-224 and US-428.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-usb-usx2y.
 
 endmenu
 
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usbaudio.c	2004-10-21 14:13:16 -07:00
@@ -736,11 +736,11 @@
 		if (test_bit(i, &subs->active_mask)) {
 			if (! test_and_set_bit(i, &subs->unlink_mask)) {
 				struct urb *u = subs->dataurb[i].urb;
-				if (async)
+				if (async) {
 					u->transfer_flags |= URB_ASYNC_UNLINK;
-				else
-					u->transfer_flags &= ~URB_ASYNC_UNLINK;
-				usb_unlink_urb(u);
+					usb_unlink_urb(u);
+				} else
+					usb_kill_urb(u);
 			}
 		}
 	}
@@ -749,11 +749,11 @@
 			if (test_bit(i+16, &subs->active_mask)) {
  				if (! test_and_set_bit(i+16, &subs->unlink_mask)) {
 					struct urb *u = subs->syncurb[i].urb;
-					if (async)
+					if (async) {
 						u->transfer_flags |= URB_ASYNC_UNLINK;
-					else
-						u->transfer_flags &= ~URB_ASYNC_UNLINK;
-					usb_unlink_urb(u);
+						usb_unlink_urb(u);
+					} else
+						usb_kill_urb(u);
 				}
 			}
 		}
@@ -2746,12 +2746,13 @@
 }
 
 /*
- * Create a stream for an Edirol UA-700 interface.  The only way
+ * Create a stream for an Edirol UA-700/UA-25 interface.  The only way
  * to detect the sample rate is by looking at wMaxPacketSize.
  */
-static int create_ua700_quirk(snd_usb_audio_t *chip, struct usb_interface *iface)
+static int create_ua700_ua25_quirk(snd_usb_audio_t *chip,
+				   struct usb_interface *iface)
 {
-	static const struct audioformat ua700_format = {
+	static const struct audioformat ua_format = {
 		.format = SNDRV_PCM_FORMAT_S24_3LE,
 		.channels = 2,
 		.fmt_type = USB_FORMAT_TYPE_I,
@@ -2771,15 +2772,28 @@
 	altsd = get_iface_desc(alts);
 
 	if (altsd->bNumEndpoints == 2) {
-		static const snd_usb_midi_endpoint_info_t ep = {
+		static const snd_usb_midi_endpoint_info_t ua700_ep = {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		};
-		static const snd_usb_audio_quirk_t quirk = {
+		static const snd_usb_audio_quirk_t ua700_quirk = {
+			.type = QUIRK_MIDI_FIXED_ENDPOINT,
+			.data = &ua700_ep
+		};
+		static const snd_usb_midi_endpoint_info_t ua25_ep = {
+			.out_cables = 0x0001,
+			.in_cables  = 0x0001
+		};
+		static const snd_usb_audio_quirk_t ua25_quirk = {
 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
-			.data = &ep
+			.data = &ua25_ep
 		};
-		return snd_usb_create_midi_interface(chip, iface, &quirk);
+		if (chip->dev->descriptor.idProduct == 0x002b)
+			return snd_usb_create_midi_interface(chip, iface,
+							     &ua700_quirk);
+		else
+			return snd_usb_create_midi_interface(chip, iface,
+							     &ua25_quirk);
 	}
 
 	if (altsd->bNumEndpoints != 1)
@@ -2788,7 +2802,7 @@
 	fp = kmalloc(sizeof(*fp), GFP_KERNEL);
 	if (!fp)
 		return -ENOMEM;
-	memcpy(fp, &ua700_format, sizeof(*fp));
+	memcpy(fp, &ua_format, sizeof(*fp));
 
 	fp->iface = altsd->bInterfaceNumber;
 	fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
@@ -2800,9 +2814,11 @@
 		fp->rate_max = fp->rate_min = 44100;
 		break;
 	case 0x138:
+	case 0x140:
 		fp->rate_max = fp->rate_min = 48000;
 		break;
 	case 0x258:
+	case 0x260:
 		fp->rate_max = fp->rate_min = 96000;
 		break;
 	default:
@@ -2822,6 +2838,56 @@
 	return 0;
 }
 
+/*
+ * Create a stream for an Edirol UA-1000 interface.
+ */
+static int create_ua1000_quirk(snd_usb_audio_t *chip, struct usb_interface *iface)
+{
+	static const struct audioformat ua1000_format = {
+		.format = SNDRV_PCM_FORMAT_S32_LE,
+		.fmt_type = USB_FORMAT_TYPE_I,
+		.altsetting = 1,
+		.altset_idx = 1,
+		.attributes = 0,
+		.rates = SNDRV_PCM_RATE_CONTINUOUS,
+	};
+	struct usb_host_interface *alts;
+	struct usb_interface_descriptor *altsd;
+	struct audioformat *fp;
+	int stream, err;
+
+	if (iface->num_altsetting != 2)
+		return -ENXIO;
+	alts = &iface->altsetting[1];
+	altsd = get_iface_desc(alts);
+	if (alts->extralen != 11 || alts->extra[1] != CS_AUDIO_INTERFACE ||
+	    altsd->bNumEndpoints != 1)
+		return -ENXIO;
+
+	fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+	if (!fp)
+		return -ENOMEM;
+	memcpy(fp, &ua1000_format, sizeof(*fp));
+
+	fp->channels = alts->extra[4];
+	fp->iface = altsd->bInterfaceNumber;
+	fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
+	fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+	fp->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
+	fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
+
+	stream = (fp->endpoint & USB_DIR_IN)
+		? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+	err = add_audio_endpoint(chip, stream, fp);
+	if (err < 0) {
+		kfree(fp);
+		return err;
+	}
+	/* FIXME: playback must be synchronized to capture */
+	usb_set_interface(chip->dev, fp->iface, 0);
+	return 0;
+}
+
 static int snd_usb_create_quirk(snd_usb_audio_t *chip,
 				struct usb_interface *iface,
 				const snd_usb_audio_quirk_t *quirk);
@@ -2909,8 +2975,10 @@
 	case QUIRK_AUDIO_STANDARD_INTERFACE:
 	case QUIRK_MIDI_STANDARD_INTERFACE:
 		return create_standard_interface_quirk(chip, iface, quirk);
-	case QUIRK_AUDIO_EDIROL_UA700:
-		return create_ua700_quirk(chip, iface);
+	case QUIRK_AUDIO_EDIROL_UA700_UA25:
+		return create_ua700_ua25_quirk(chip, iface);
+	case QUIRK_AUDIO_EDIROL_UA1000:
+		return create_ua1000_quirk(chip, iface);
 	default:
 		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
 		return -ENXIO;
diff -Nru a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
--- a/sound/usb/usbaudio.h	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usbaudio.h	2004-10-21 14:13:16 -07:00
@@ -155,7 +155,8 @@
 #define QUIRK_AUDIO_FIXED_ENDPOINT	4
 #define QUIRK_AUDIO_STANDARD_INTERFACE	5
 #define QUIRK_MIDI_STANDARD_INTERFACE	6
-#define QUIRK_AUDIO_EDIROL_UA700	7
+#define QUIRK_AUDIO_EDIROL_UA700_UA25	7
+#define QUIRK_AUDIO_EDIROL_UA1000	8
 
 typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
 typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
@@ -187,7 +188,7 @@
 
 /* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
 
-/* for QUIRK_AUDIO_EDIROL_UA700, data is NULL */
+/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
 
 /*
  */
diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usbmidi.c	2004-10-21 14:13:16 -07:00
@@ -715,9 +715,9 @@
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
 		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
 		if (ep->out && ep->out->urb)
-			usb_unlink_urb(ep->out->urb);
+			usb_kill_urb(ep->out->urb);
 		if (ep->in && ep->in->urb)
-			usb_unlink_urb(ep->in->urb);
+			usb_kill_urb(ep->in->urb);
 	}
 }
 
@@ -1161,7 +1161,7 @@
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
 		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
 		if (ep->in)
-			usb_unlink_urb(ep->in->urb);
+			usb_kill_urb(ep->in->urb);
 	}
 }
 
diff -Nru a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
--- a/sound/usb/usbmixer_maps.c	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usbmixer_maps.c	2004-10-21 14:13:16 -07:00
@@ -91,6 +91,14 @@
 	{ 0 } /* terminator */
 };
 
+/* LineX FM Transmitter entry - needed to bypass controls bug */
+static struct usbmix_name_map linex_map[] = {
+	/* 1: IT pcm */
+	/* 2: OT Speaker */ 
+	{ 3, "Master" }, /* FU: master volume - left / right / mute */
+	{ 0 } /* terminator */
+};
+
 /* Section "justlink_map" below added by James Courtier-Dutton <James@superbug.demon.co.uk>
  * sourced from Maplin Electronics (http://www.maplin.co.uk), part number A56AK
  * Part has 2 connectors that act as a single output. (TOSLINK Optical for digital out, and 3.5mm Jack for Analogue out.)
@@ -120,6 +128,7 @@
 
 static struct usbmix_ctl_map usbmix_ctl_maps[] = {
 	{ 0x41e, 0x3000, extigy_map, 1 },
+	{ 0x8bb, 0x2702, linex_map, 1 },
 	{ 0xc45, 0x1158, justlink_map, 0 },
 	{ 0 } /* terminator */
 };
diff -Nru a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
--- a/sound/usb/usbquirks.h	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usbquirks.h	2004-10-21 14:13:16 -07:00
@@ -534,15 +534,15 @@
 		.data = (const snd_usb_audio_quirk_t[]) {
 			{
 				.ifnum = 1,
-				.type = QUIRK_AUDIO_EDIROL_UA700
+				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
 			},
 			{
 				.ifnum = 2,
-				.type = QUIRK_AUDIO_EDIROL_UA700
+				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
 			},
 			{
 				.ifnum = 3,
-				.type = QUIRK_AUDIO_EDIROL_UA700
+				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
 			},
 			{
 				.ifnum = -1
@@ -638,37 +638,11 @@
 		.data = (const snd_usb_audio_quirk_t[]) {
 			{
 				.ifnum = 1,
-				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
-				.data = & (const struct audioformat) {
-					.format = SNDRV_PCM_FORMAT_S24,
-					.channels = 12,
-					.iface = 1,
-					.altsetting = 1,
-					.altset_idx = 1,
-					.attributes = 0,
-					.endpoint = 0x81,
-					.ep_attr = 0x01,
-					.rates = SNDRV_PCM_RATE_CONTINUOUS,
-					.rate_min = 48000,
-					.rate_max = 48000,
-				}
+				.type = QUIRK_AUDIO_EDIROL_UA1000
 			},
 			{
 				.ifnum = 2,
-				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
-				.data = & (const struct audioformat) {
-					.format = SNDRV_PCM_FORMAT_S24,
-					.channels = 10,
-					.iface = 2,
-					.altsetting = 1,
-					.altset_idx = 1,
-					.attributes = 0,
-					.endpoint = 0x02,
-					.ep_attr = 0x01,
-					.rates = SNDRV_PCM_RATE_CONTINUOUS,
-					.rate_min = 48000,
-					.rate_max = 48000,
-				}
+				.type = QUIRK_AUDIO_EDIROL_UA1000
 			},
 			{
 				.ifnum = 3,
@@ -756,6 +730,37 @@
 		.product_name = "UM-1SX",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_STANDARD_INTERFACE
+	}
+},
+{	/*
+	 * This quirk is for the "Advanced" modes of the Edirol UA-25.
+	 * If the switch is not in an advanced setting, the UA-25 has
+	 * ID 0x0582/0x0073 and is standard compliant (no quirks), but
+	 * offers only 16-bit PCM at 44.1 kHz and no MIDI.
+	 */
+	USB_DEVICE_VENDOR_SPEC(0x0582, 0x0074),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "EDIROL",
+		.product_name = "UA-25",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
+			},
+			{
+				.ifnum = -1
+			}
+		}
 	}
 },
 
diff -Nru a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
--- a/sound/usb/usx2y/usbusx2y.c	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usx2y/usbusx2y.c	2004-10-21 14:13:16 -07:00
@@ -1,6 +1,10 @@
 /*
  * usbus428.c - ALSA USB US-428 Driver
  *
+2004-09-20 Karsten Wiese
+	Version 0.7.3:
+	Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb().
+
 2004-07-13 Karsten Wiese
 	Version 0.7.1:
 	Don't sleep in START/STOP callbacks anymore.
@@ -115,7 +119,7 @@
 
 
 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.7.2");
+MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.7.3");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
 
@@ -276,7 +280,7 @@
 	int	i;
 	for (i = 0; i < URBS_AsyncSeq; ++i) {
 		if (S[i].urb) {
-			usb_unlink_urb(S->urb[i]);
+			usb_kill_urb(S->urb[i]);
 			usb_free_urb(S->urb[i]);
 			S->urb[i] = NULL;
 		}
@@ -407,7 +411,7 @@
 		usX2Y->chip.shutdown = 1;
 		usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
 		usX2Y_unlinkSeq(&usX2Y->AS04);
-		usb_unlink_urb(usX2Y->In04urb);
+		usb_kill_urb(usX2Y->In04urb);
 		snd_card_disconnect((snd_card_t*)ptr);
 		/* release the midi resources */
 		list_for_each(p, &usX2Y->chip.midi_list) {
diff -Nru a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
--- a/sound/usb/usx2y/usbusx2yaudio.c	2004-10-21 14:13:16 -07:00
+++ b/sound/usb/usx2y/usbusx2yaudio.c	2004-10-21 14:13:16 -07:00
@@ -656,7 +656,7 @@
 		if (us) {
 			us->submitted =	2*NOOF_SETRATE_URBS;
 			for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
-				usb_unlink_urb(us->urb[i]);
+				usb_kill_urb(us->urb[i]);
 				usb_free_urb(us->urb[i]);
 			}
 			usX2Y->US04 = NULL;
@@ -671,7 +671,7 @@
 
 static int usX2Y_format_set(usX2Ydev_t *usX2Y, snd_pcm_format_t format)
 {
-	int alternate, unlink_err, err;
+	int alternate, err;
 	struct list_head* p;
 	if (format == SNDRV_PCM_FORMAT_S24_3LE) {
 		alternate = 2;
@@ -683,15 +683,13 @@
 	list_for_each(p, &usX2Y->chip.midi_list) {
 		snd_usbmidi_input_stop(p);
 	}
-	unlink_err = usb_unlink_urb(usX2Y->In04urb);
+	usb_kill_urb(usX2Y->In04urb);
 	if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) {
 		snd_printk("usb_set_interface error \n");
 		return err;
 	}
-	if (0 == unlink_err) {
-		usX2Y->In04urb->dev = usX2Y->chip.dev;
-		err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
-	}
+	usX2Y->In04urb->dev = usX2Y->chip.dev;
+	err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
 	list_for_each(p, &usX2Y->chip.midi_list) {
 		snd_usbmidi_input_start(p);
 	}
@@ -824,20 +822,20 @@
 			subs->prepared = 1;
 		}
 		while (subs->submitted_urbs)
-		for (u = 0; u < NRURBS; u++) {
-			snd_printdd("%i\n", subs->urb[u]->status);
-			while(subs->urb[u]->status  ||  NULL != subs->urb[u]->hcpriv) {
-				signed long timeout;
-				snd_printdd("ep=%i waiting for urb=%p status=%i hcpriv=%p\n",
-					   subs->endpoint, subs->urb[u],
-					   subs->urb[u]->status, subs->urb[u]->hcpriv);
-				set_current_state(TASK_INTERRUPTIBLE);
-				timeout = schedule_timeout(HZ/10);
-				if (signal_pending(current)) {
-					return -ERESTARTSYS;
+			for (u = 0; u < NRURBS; u++) {
+				snd_printdd("%i\n", subs->urb[u]->status);
+				while(subs->urb[u]->status  ||  NULL != subs->urb[u]->hcpriv) {
+					signed long timeout;
+					snd_printdd("ep=%i waiting for urb=%p status=%i hcpriv=%p\n",
+						    subs->endpoint, subs->urb[u],
+						    subs->urb[u]->status, subs->urb[u]->hcpriv);
+					set_current_state(TASK_INTERRUPTIBLE);
+					timeout = schedule_timeout(HZ/10);
+					if (signal_pending(current)) {
+						return -ERESTARTSYS;
+					}
 				}
 			}
-		}
 		subs->completed_urb = NULL;
 		subs->next_urb_complete = -1;
 		subs->stalled = 0;
