http://linux-sound.bkbits.net/linux-sound
perex@suse.cz|ChangeSet|20040906183307|53702 perex

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/09/11 14:57:37-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/intel8x0.c
#   2004/09/11 14:57:32-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/08 11:38:39-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/emu10k1/emuproc.c
#   2004/09/08 11:38:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/09/08 11:38:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/09/08 11:38:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# 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>
# 
# ChangeSet
#   2004/09/03 14:06:33-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# mm/slab.c
#   2004/09/03 14:06:28-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/slab.h
#   2004/09/03 14:06:28-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/31 22:37:51-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/mixart/mixart.c
#   2004/08/31 22:37:47-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/slab.h
#   2004/08/31 22:37:47-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/28 16:15:33-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/08/28 16:15:28-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/27 14:52:37-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# mm/slab.c
#   2004/08/27 14:52:33-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/08/27 14:52:33-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/27 13:07:53-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# mm/slab.c
#   2004/08/27 13:07:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/08/27 13:07:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/26 19:24:29-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# mm/slab.c
#   2004/08/26 19:24:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/slab.h
#   2004/08/26 19:24:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/25 14:00:17-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/parisc/harmony.c
#   2004/08/25 14:00:13-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/wavefront/wavefront_fx.c
#   2004/08/25 14:00:13-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# mm/slab.c
#   2004/08/25 14:00:13-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/08/25 14:00:13-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/24 17:30:19-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# mm/slab.c
#   2004/08/24 17:30:14-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/slab.h
#   2004/08/24 17:30:13-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/23 16:35:28-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/08/23 16:35:23-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/23 13:44:30-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/isa/wavefront/wavefront_fx.c
#   2004/08/23 13:44:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# mm/slab.c
#   2004/08/23 13:44:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/08/23 13:44:25-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/22 21:04:53-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/parisc/harmony.c
#   2004/08/22 21:04:49-07:00 akpm@bix.(none) +0 -2
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/08/22 21:04:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/15 13:40:16-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/mixart/mixart.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/emu10k1/emuproc.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/gus/gus_mem_proc.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/drivers/opl4/opl4_proc.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/core/info.c
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/sound/info.h
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/08/15 13:40:12-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/09 18:30:30-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/mixart/mixart.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/emu10k1/emuproc.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs46xx/cs46xx_lib.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/pci/cs4281.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/gus/gus_mem_proc.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/drivers/opl4/opl4_proc.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/core/info.c
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/sound/info.h
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/08/09 18:30:26-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/06 15:27:08-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/08/06 15:27:05-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/02 12:47:26-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
#   2004/08/02 12:47:22-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	2004-09-12 21:54:59 -07:00
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	2004-09-12 21:54:59 -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
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-09-12 21:54:59 -07:00
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl	2004-09-12 21:54:59 -07:00
@@ -4060,8 +4060,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>
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	2004-09-12 21:54:59 -07:00
+++ b/include/sound/ac97_codec.h	2004-09-12 21:54:59 -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,7 @@
 #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 */
 
 /* ac97->flags */
 #define AC97_HAS_PC_BEEP	(1<<0)	/* force PC Speaker usage */
@@ -355,6 +362,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 +377,7 @@
 	AC97_SHARED_TYPE_NONE,
 	AC97_SHARED_TYPE_ICH,
 	AC97_SHARED_TYPE_ATIIXP,
+	AC97_SHARED_TYPE_VIA,
 	AC97_SHARED_TYPES
 };
 
@@ -432,6 +441,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 */
@@ -538,18 +548,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 +569,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/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h	2004-09-12 21:54:59 -07:00
+++ b/include/sound/emu10k1.h	2004-09-12 21:54:59 -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 */
+	unsigned long gpr_valid[0x200/(sizeof(unsigned long)*8)]; /* 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 */
+	unsigned long tram_valid[0x100/(sizeof(unsigned long)*8)]; /* 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 */
+	unsigned long code_valid[1024/(sizeof(unsigned long)*8)];  /* 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/sound/core/memalloc.c b/sound/core/memalloc.c
--- a/sound/core/memalloc.c	2004-09-12 21:54:59 -07:00
+++ b/sound/core/memalloc.c	2004-09-12 21:54:59 -07:00
@@ -246,9 +246,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/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
--- a/sound/core/seq/seq_clientmgr.c	2004-09-12 21:54:59 -07:00
+++ b/sound/core/seq/seq_clientmgr.c	2004-09-12 21:54:59 -07:00
@@ -156,7 +156,10 @@
 					card_requested[card] = 1;
 					snd_request_card(card);
 				}
-				snd_seq_device_load_drivers();
+				/* FIXME: may cause blocking when called from
+				 * module_init(), so disable this feature
+				 */
+				/* snd_seq_device_load_drivers(); */
 			}
 		}
 		spin_lock_irqsave(&clients_lock, flags);
diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c
--- a/sound/isa/es18xx.c	2004-09-12 21:54:59 -07:00
+++ b/sound/isa/es18xx.c	2004-09-12 21:54:59 -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/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/Kconfig	2004-09-12 21:54:59 -07:00
@@ -291,7 +291,6 @@
 config SND_INTEL8X0
 	tristate "Intel i8x0/MX440, SiS 7012; Ali 5455; NForce Audio; AMD768/8111"
 	depends on SND
-	select SND_MPU401_UART
 	select SND_AC97_CODEC
 	help
 	  Say 'Y' or 'M' to include support for Intel8x0 based soundcards,
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/ac97/ac97_codec.c	2004-09-12 21:54:59 -07:00
@@ -749,6 +749,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 +1567,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 +1618,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 +1659,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 +1680,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;
 }
 
@@ -2006,11 +2039,20 @@
 		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 & 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 +2359,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 +2372,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 +2405,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 +2429,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 +2466,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)
@@ -2438,6 +2493,7 @@
 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_pcm.c b/sound/pci/ac97/ac97_pcm.c
--- a/sound/pci/ac97/ac97_pcm.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/ac97/ac97_pcm.c	2004-09-12 21:54:59 -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;
@@ -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-09-12 21:54:59 -07:00
+++ b/sound/pci/ac97/ac97_proc.c	2004-09-12 21:54:59 -07:00
@@ -75,6 +75,7 @@
 	static const char *spdif_slots[4] = { " SPDIF=3/4", " SPDIF=7/8", " SPDIF=6/9", " SPDIF=res" };
 	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/bt87x.c b/sound/pci/bt87x.c
--- a/sound/pci/bt87x.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/bt87x.c	2004-09-12 21:54:59 -07:00
@@ -264,8 +264,9 @@
 			snd_printk(KERN_ERR "Aieee - PCI error! status %#08x, PCI status %#04x\n",
 				   status, pci_status);
 		}
-	}
-	if (status & INT_RISCI) {
+		if (chip->reg_control & CTL_ACAP_EN)
+			snd_pcm_stop(chip->substream, SNDRV_PCM_STATE_XRUN);
+	} else if ((status & INT_RISCI) && (chip->reg_control & CTL_ACAP_EN)) {
 		int current_block, irq_block;
 
 		/* assume that exactly one line has been recorded */
diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/cs46xx/cs46xx_lib.c	2004-09-12 21:54:59 -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);
 }
 
@@ -2405,6 +2393,8 @@
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
 	ac97.private_free = snd_cs46xx_mixer_free_ac97;
+	if (chip->amplifier_ctrl == amp_voyetra)
+		ac97.scaps = AC97_SCAP_INV_EAPD;
 
 	snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000,
 			       CS46XX_PRIMARY_CODEC_INDEX);
diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/emu10k1/emufx.c	2004-09-12 21:54:59 -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/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/emu10k1/emuproc.c	2004-09-12 21:54:59 -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-09-12 21:54:59 -07:00
+++ b/sound/pci/ens1370.c	2004-09-12 21:54:59 -07:00
@@ -372,6 +372,7 @@
 
 struct _snd_ensoniq {
 	spinlock_t reg_lock;
+	struct semaphore src_mutex;
 
 	int irq;
 
@@ -513,6 +514,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;
@@ -696,6 +698,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--;
@@ -719,12 +722,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));
@@ -734,12 +739,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));
@@ -749,6 +756,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 */
@@ -846,6 +854,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));
@@ -863,11 +878,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;
 }
 
@@ -901,11 +917,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;
 }
 
@@ -937,11 +954,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;
 }
 
@@ -1879,6 +1897,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/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
--- a/sound/pci/ice1712/ice1712.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/ice1712/ice1712.c	2004-09-12 21:54:59 -07:00
@@ -2308,28 +2308,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? */
@@ -2346,6 +2365,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/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/intel8x0.c	2004-09-12 21:54:59 -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,12 @@
 		"{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 boot_devs;
 
 module_param_array(index, int, boot_devs, 0444);
@@ -95,14 +82,6 @@
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
 module_param_array(buggy_irq, bool, boot_devs, 0444);
 MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
-#ifdef SUPPORT_JOYSTICK
-module_param_array(joystick, bool, boot_devs, 0444);
-MODULE_PARM_DESC(joystick, "Enable joystick for Intel i8x0 soundcard.");
-#endif
-#ifdef SUPPORT_MIDI
-module_param_array(mpu_port, int, boot_devs, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU401 port # for Intel i8x0 driver.");
-#endif
 
 /*
  *  Direct registers
@@ -420,6 +399,7 @@
 
 	int multi4: 1,
 	    multi6: 1,
+	    dra: 1,
 	    smp20bit: 1;
 	int in_ac97_init: 1,
 	    in_sdin_init: 1;
@@ -430,8 +410,6 @@
 	ac97_t *ac97[3];
 	unsigned int ac97_sdin[3];
 
-	snd_rawmidi_t *rmidi;
-
 	spinlock_t reg_lock;
 	spinlock_t ac97_lock;
 	
@@ -954,6 +932,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)
@@ -969,7 +948,7 @@
 	}
 	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 */
@@ -994,34 +973,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,
@@ -1032,7 +1012,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);
@@ -1051,8 +1031,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;
 		}
@@ -1168,6 +1147,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);
@@ -1662,6 +1644,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)
 			}
 		}
 	},
@@ -1718,6 +1706,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
@@ -1764,6 +1758,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,
@@ -1771,6 +1771,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? */
@@ -1944,6 +1950,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;
@@ -2004,6 +2011,9 @@
 		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;
@@ -2689,16 +2699,6 @@
 		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",
@@ -2731,129 +2731,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/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/korg1212/korg1212.c	2004-09-12 21:54:59 -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
@@ -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.
@@ -844,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,
@@ -855,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];
@@ -1245,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);
@@ -1414,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;
 
@@ -1444,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;
 
@@ -1466,6 +1489,7 @@
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
+	korg1212->playback_pid = -1;
         korg1212->playback_substream = NULL;
         korg1212->periodsize = 0;
 
@@ -1486,6 +1510,7 @@
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
+	korg1212->capture_pid = -1;
         korg1212->capture_substream = NULL;
         korg1212->periodsize = 0;
 
@@ -1522,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;
 
@@ -2183,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;
@@ -2312,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/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	2004-09-12 21:54:59 -07:00
+++ b/sound/pci/via82xx.c	2004-09-12 21:54:59 -07:00
@@ -1547,6 +1547,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,
@@ -1606,6 +1613,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;
diff -Nru a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
--- a/sound/usb/usbmixer_maps.c	2004-09-12 21:54:59 -07:00
+++ b/sound/usb/usbmixer_maps.c	2004-09-12 21:54:59 -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 */
 };
