http://linux-sound.bkbits.net/linux-sound
perex@suse.cz|ChangeSet|20040531064928|46574 perex

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/06/02 13:14:41-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/06/02 13:14:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/31 16:02:35-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/isa/wavefront/wavefront_synth.c
#   2004/05/31 16:02:31-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/31 08:49:28+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   AC97 Codec Core
#   Fixed mutex deadlocks.
# 
# sound/pci/ac97/ac97_patch.c
#   2004/05/30 11:40:05+02:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2004/05/30 17:40:04
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.135->1.136 
#   F:pci/ac97/ac97_patch.c:1.52->1.53 
#   L:Fixed mutex deadlocks.
# 
# sound/pci/ac97/ac97_codec.c
#   2004/05/30 11:40:04+02:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2004/05/30 17:40:04
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.135->1.136 
#   F:pci/ac97/ac97_patch.c:1.52->1.53 
#   L:Fixed mutex deadlocks.
# 
# ChangeSet
#   2004/05/30 14:01:08+02:00 perex@suse.cz 
#   ALSA 1.0.5
# 
# include/sound/version.h
#   2004/05/30 14:00:09+02:00 perex@suse.cz +2 -2
#   ALSA 1.0.5
# 
# ChangeSet
#   2004/05/30 13:57:33+02:00 perex@suse.cz 
#   ALSA CVS update - Jaroslav Kysela <perex@suse.cz>
#   ALSA Core
#   Fixed warnings for pci PM callbacks when not CONFIG_PCI
# 
# include/sound/core.h
#   2004/05/30 06:50:15+02:00 perex@suse.cz +4 -0
#   ALSA CVS update
#   D:2004/05/30 12:50:15
#   C:ALSA Core
#   A:Jaroslav Kysela <perex@suse.cz>
#   F:include/core.h:1.51->1.52 
#   L:Fixed warnings for pci PM callbacks when not CONFIG_PCI
# 
# ChangeSet
#   2004/05/28 16:58:34-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/28 16:58:31-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/28 13:15:53-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/28 13:15:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/28 15:04:32+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   AC97 Codec Core
#   - Added the single mixer control with AC97 2.3 paging.
#   - Handle the paging for some ALC655/658 registers.
#   - Added the experimental support for ALC850.
# 
# sound/pci/ac97/ac97_patch.h
#   2004/05/28 04:27:09+02:00 perex@suse.cz +1 -0
#   ALSA CVS update
#   D:2004/05/28 10:27:09
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.134->1.135 
#   F:pci/ac97/ac97_id.h:1.8->1.9 
#   F:pci/ac97/ac97_local.h:1.6->1.7 
#   F:pci/ac97/ac97_patch.c:1.51->1.52 
#   F:pci/ac97/ac97_patch.h:1.15->1.16 
#   L:- Added the single mixer control with AC97 2.3 paging.
#   L:- Handle the paging for some ALC655/658 registers.
#   L:- Added the experimental support for ALC850.
# 
# sound/pci/ac97/ac97_patch.c
#   2004/05/28 04:27:09+02:00 perex@suse.cz +148 -28
#   ALSA CVS update
#   D:2004/05/28 10:27:09
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.134->1.135 
#   F:pci/ac97/ac97_id.h:1.8->1.9 
#   F:pci/ac97/ac97_local.h:1.6->1.7 
#   F:pci/ac97/ac97_patch.c:1.51->1.52 
#   F:pci/ac97/ac97_patch.h:1.15->1.16 
#   L:- Added the single mixer control with AC97 2.3 paging.
#   L:- Handle the paging for some ALC655/658 registers.
#   L:- Added the experimental support for ALC850.
# 
# sound/pci/ac97/ac97_local.h
#   2004/05/28 04:27:09+02:00 perex@suse.cz +7 -0
#   ALSA CVS update
#   D:2004/05/28 10:27:09
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.134->1.135 
#   F:pci/ac97/ac97_id.h:1.8->1.9 
#   F:pci/ac97/ac97_local.h:1.6->1.7 
#   F:pci/ac97/ac97_patch.c:1.51->1.52 
#   F:pci/ac97/ac97_patch.h:1.15->1.16 
#   L:- Added the single mixer control with AC97 2.3 paging.
#   L:- Handle the paging for some ALC655/658 registers.
#   L:- Added the experimental support for ALC850.
# 
# sound/pci/ac97/ac97_id.h
#   2004/05/28 04:27:09+02:00 perex@suse.cz +7 -0
#   ALSA CVS update
#   D:2004/05/28 10:27:09
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.134->1.135 
#   F:pci/ac97/ac97_id.h:1.8->1.9 
#   F:pci/ac97/ac97_local.h:1.6->1.7 
#   F:pci/ac97/ac97_patch.c:1.51->1.52 
#   F:pci/ac97/ac97_patch.h:1.15->1.16 
#   L:- Added the single mixer control with AC97 2.3 paging.
#   L:- Handle the paging for some ALC655/658 registers.
#   L:- Added the experimental support for ALC850.
# 
# sound/pci/ac97/ac97_codec.c
#   2004/05/28 04:27:09+02:00 perex@suse.cz +61 -18
#   ALSA CVS update
#   D:2004/05/28 10:27:09
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.134->1.135 
#   F:pci/ac97/ac97_id.h:1.8->1.9 
#   F:pci/ac97/ac97_local.h:1.6->1.7 
#   F:pci/ac97/ac97_patch.c:1.51->1.52 
#   F:pci/ac97/ac97_patch.h:1.15->1.16 
#   L:- Added the single mixer control with AC97 2.3 paging.
#   L:- Handle the paging for some ALC655/658 registers.
#   L:- Added the experimental support for ALC850.
# 
# ChangeSet
#   2004/05/28 15:04:07+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   AC97 Codec Core
#   Avoid warning message during codec probing in case SKIP_AUDIO flag is not set.
# 
# sound/pci/ac97/ac97_codec.c
#   2004/05/27 13:15:54+02:00 perex@suse.cz +6 -4
#   ALSA CVS update
#   D:2004/05/27 19:15:54
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ac97/ac97_codec.c:1.133->1.134 
#   L:Avoid warning message during codec probing in case SKIP_AUDIO flag is not set.
# 
# ChangeSet
#   2004/05/28 15:03:42+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   PARISC Harmony driver
#   fixed typos.
# 
# sound/parisc/harmony.c
#   2004/05/26 11:02:12+02:00 perex@suse.cz +2 -2
#   ALSA CVS update
#   D:2004/05/26 17:02:12
#   C:PARISC Harmony driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:parisc/harmony.c:1.11->1.12 
#   L:fixed typos.
# 
# ChangeSet
#   2004/05/28 15:03:20+02:00 perex@suse.cz 
#   ALSA CVS update - Jaroslav Kysela <perex@suse.cz>
#   AC97 Codec Core
#   Signed-off-by: Kevin Mack <kevmack@accesscomm.ca>
#   For Gateway M675 notebook - this will direct mixer
#   output to speaker, headphone and line-out instead
#   of just the front(DAC-A) signal.
# 
# sound/pci/ac97/ac97_patch.c
#   2004/05/26 02:34:55+02:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2004/05/26 08:34:55
#   C:AC97 Codec Core
#   A:Jaroslav Kysela <perex@suse.cz>
#   F:pci/ac97/ac97_patch.c:1.50->1.51 
#   L:Signed-off-by: Kevin Mack <kevmack@accesscomm.ca>
#   L:For Gateway M675 notebook - this will direct mixer
#   L:output to speaker, headphone and line-out instead
#   L:of just the front(DAC-A) signal.
# 
# ChangeSet
#   2004/05/28 15:02:56+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   VIA82xx driver
#   - use snd_pcm_limit_hw_rates() and removed redundant codes.
#   - fixed the rate constraints when 'IEC958 Output Switch' is on.
#   - check the SPDIF support on AC97 and don't build IEC958 stuffs if not available.
# 
# sound/pci/via82xx.c
#   2004/05/25 12:54:55+02:00 perex@suse.cz +15 -38
#   ALSA CVS update
#   D:2004/05/25 18:54:55
#   C:VIA82xx driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/via82xx.c:1.102->1.103 
#   L:- use snd_pcm_limit_hw_rates() and removed redundant codes.
#   L:- fixed the rate constraints when 'IEC958 Output Switch' is on.
#   L:- check the SPDIF support on AC97 and don't build IEC958 stuffs if not available.
# 
# ChangeSet
#   2004/05/28 15:02:35+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   AC97 Codec Core
#   added ac97_can_spdif() for checking the SPDIF support.
# 
# include/sound/ac97_codec.h
#   2004/05/25 12:52:57+02:00 perex@suse.cz +4 -0
#   ALSA CVS update
#   D:2004/05/25 18:52:57
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:include/ac97_codec.h:1.45->1.46 
#   L:added ac97_can_spdif() for checking the SPDIF support.
# 
# ChangeSet
#   2004/05/28 15:02:13+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   VIA82xx driver
#   added the DXS entry for Mitac/Vobis/Yakumo laptop.
# 
# sound/pci/via82xx.c
#   2004/05/25 10:10:38+02:00 perex@suse.cz +1 -0
#   ALSA CVS update
#   D:2004/05/25 16:10:38
#   C:VIA82xx driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/via82xx.c:1.101->1.102 
#   L:added the DXS entry for Mitac/Vobis/Yakumo laptop.
# 
# ChangeSet
#   2004/05/28 15:01:53+02:00 perex@suse.cz 
#   ALSA CVS update - Clemens Ladisch <clemens@ladisch.de>
#   Wavefront drivers
#   fix possible buffer overflow in wavefront_download_firmware()
# 
# sound/isa/wavefront/wavefront_synth.c
#   2004/05/25 07:10:48+02:00 perex@suse.cz +6 -0
#   ALSA CVS update
#   D:2004/05/25 13:10:48
#   C:Wavefront drivers
#   A:Clemens Ladisch <clemens@ladisch.de>
#   F:isa/wavefront/wavefront_synth.c:1.17->1.18 
#   L:fix possible buffer overflow in wavefront_download_firmware()
# 
# ChangeSet
#   2004/05/28 14:20:37+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   ICE1724 driver
#   avoid to change the AC97 rate registers.  this seems conflicting
#   with the rate conversion on VT172x.
# 
# sound/pci/ice1712/ice1724.c
#   2004/05/25 04:56:22+02:00 perex@suse.cz +2 -17
#   ALSA CVS update
#   D:2004/05/25 10:56:22
#   C:ICE1724 driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/ice1712/ice1724.c:1.32->1.33 
#   L:avoid to change the AC97 rate registers.  this seems conflicting
#   L:with the rate conversion on VT172x.
# 
# ChangeSet
#   2004/05/28 14:20:17+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   Digigram VX core
#   added 'Clock Mode' control to choose the clock source.
# 
# sound/drivers/vx/vx_uer.c
#   2004/05/24 12:12:43+02:00 perex@suse.cz +8 -7
#   ALSA CVS update
#   D:2004/05/24 18:12:43
#   C:Digigram VX core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:drivers/vx/vx_core.c:1.7->1.8 
#   F:drivers/vx/vx_mixer.c:1.2->1.3 
#   F:drivers/vx/vx_uer.c:1.1->1.2 
#   F:include/vx_core.h:1.1->1.2 
#   L:added 'Clock Mode' control to choose the clock source.
# 
# sound/drivers/vx/vx_mixer.c
#   2004/05/24 12:12:43+02:00 perex@suse.cz +51 -0
#   ALSA CVS update
#   D:2004/05/24 18:12:43
#   C:Digigram VX core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:drivers/vx/vx_core.c:1.7->1.8 
#   F:drivers/vx/vx_mixer.c:1.2->1.3 
#   F:drivers/vx/vx_uer.c:1.1->1.2 
#   F:include/vx_core.h:1.1->1.2 
#   L:added 'Clock Mode' control to choose the clock source.
# 
# sound/drivers/vx/vx_core.c
#   2004/05/24 12:12:43+02:00 perex@suse.cz +3 -0
#   ALSA CVS update
#   D:2004/05/24 18:12:43
#   C:Digigram VX core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:drivers/vx/vx_core.c:1.7->1.8 
#   F:drivers/vx/vx_mixer.c:1.2->1.3 
#   F:drivers/vx/vx_uer.c:1.1->1.2 
#   F:include/vx_core.h:1.1->1.2 
#   L:added 'Clock Mode' control to choose the clock source.
# 
# include/sound/vx_core.h
#   2004/05/24 12:12:43+02:00 perex@suse.cz +8 -0
#   ALSA CVS update
#   D:2004/05/24 18:12:43
#   C:Digigram VX core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:drivers/vx/vx_core.c:1.7->1.8 
#   F:drivers/vx/vx_mixer.c:1.2->1.3 
#   F:drivers/vx/vx_uer.c:1.1->1.2 
#   F:include/vx_core.h:1.1->1.2 
#   L:added 'Clock Mode' control to choose the clock source.
# 
# ChangeSet
#   2004/05/28 14:19:53+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   Digigram VX core
#   fixed the compile warnings due to the last change.
# 
# sound/drivers/vx/vx_pcm.c
#   2004/05/24 12:11:58+02:00 perex@suse.cz +2 -1
#   ALSA CVS update
#   D:2004/05/24 18:11:58
#   C:Digigram VX core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:drivers/vx/vx_pcm.c:1.4->1.5 
#   L:fixed the compile warnings due to the last change.
# 
# ChangeSet
#   2004/05/28 14:19:28+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   PARISC Harmony driver
#   - fixed the buffer handling without dma_alloc_coherent support.
# 
# sound/parisc/harmony.c
#   2004/05/24 09:51:51+02:00 perex@suse.cz +31 -9
#   ALSA CVS update
#   D:2004/05/24 15:51:51
#   C:PARISC Harmony driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:parisc/harmony.c:1.10->1.11 
#   L:- fixed the buffer handling without dma_alloc_coherent support.
# 
# ChangeSet
#   2004/05/28 14:19:07+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   Digigram VX core
#   fixed sleep while atomic in the trigger callback.
# 
# sound/drivers/vx/vx_pcm.c
#   2004/05/24 09:06:17+02:00 perex@suse.cz +2 -8
#   ALSA CVS update
#   D:2004/05/24 15:06:17
#   C:Digigram VX core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:drivers/vx/vx_pcm.c:1.3->1.4 
#   L:fixed sleep while atomic in the trigger callback.
# 
# ChangeSet
#   2004/05/28 14:14:19+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   AC97 Codec Core
#   - added the global mutex for ac97_t (ad18xx mutex is removed).
#     used to protect paging and AD18xx multi-codecs.
#   - set PAGE_INT register explicitly before accessing (for STAC9758).
#   - moved ALC650 revision check to patch_alc650().
#   - support stereo Mic playback.
#   - moved STAC9708 quirk to patch_stac9708().
#   - don't clear PC_BEEP high bits (ac97 2.3 sets frequency there).
#   - avoid the unnecessary RESET-waiting for audio/modem codec.
#   - fixed the evaluation of modem codec to call mpatch callback properly.
#   - determine the SPDIF rate in the build path.
#   - added suffix argument to snd_ac97_rename|remove|swap_ctl().
#   - added snd_ac97_rename_vol_ctl().
# 
# sound/pci/ac97/ac97_proc.c
#   2004/05/24 08:24:42+02:00 perex@suse.cz +6 -4
#   ALSA CVS update
#   D:2004/05/24 14:24:42
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:include/ac97_codec.h:1.44->1.45 
#   F:pci/ac97/ac97_codec.c:1.132->1.133 
#   F:pci/ac97/ac97_local.h:1.5->1.6 
#   F:pci/ac97/ac97_patch.c:1.49->1.50 
#   F:pci/ac97/ac97_proc.c:1.7->1.8 
#   L:- added the global mutex for ac97_t (ad18xx mutex is removed).
#   L:  used to protect paging and AD18xx multi-codecs.
#   L:- set PAGE_INT register explicitly before accessing (for STAC9758).
#   L:- moved ALC650 revision check to patch_alc650().
#   L:- support stereo Mic playback.
#   L:- moved STAC9708 quirk to patch_stac9708().
#   L:- don't clear PC_BEEP high bits (ac97 2.3 sets frequency there).
#   L:- avoid the unnecessary RESET-waiting for audio/modem codec.
#   L:- fixed the evaluation of modem codec to call mpatch callback properly.
#   L:- determine the SPDIF rate in the build path.
#   L:- added suffix argument to snd_ac97_rename|remove|swap_ctl().
#   L:- added snd_ac97_rename_vol_ctl().
# 
# sound/pci/ac97/ac97_patch.c
#   2004/05/24 08:24:42+02:00 perex@suse.cz +75 -30
#   ALSA CVS update
#   D:2004/05/24 14:24:42
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:include/ac97_codec.h:1.44->1.45 
#   F:pci/ac97/ac97_codec.c:1.132->1.133 
#   F:pci/ac97/ac97_local.h:1.5->1.6 
#   F:pci/ac97/ac97_patch.c:1.49->1.50 
#   F:pci/ac97/ac97_proc.c:1.7->1.8 
#   L:- added the global mutex for ac97_t (ad18xx mutex is removed).
#   L:  used to protect paging and AD18xx multi-codecs.
#   L:- set PAGE_INT register explicitly before accessing (for STAC9758).
#   L:- moved ALC650 revision check to patch_alc650().
#   L:- support stereo Mic playback.
#   L:- moved STAC9708 quirk to patch_stac9708().
#   L:- don't clear PC_BEEP high bits (ac97 2.3 sets frequency there).
#   L:- avoid the unnecessary RESET-waiting for audio/modem codec.
#   L:- fixed the evaluation of modem codec to call mpatch callback properly.
#   L:- determine the SPDIF rate in the build path.
#   L:- added suffix argument to snd_ac97_rename|remove|swap_ctl().
#   L:- added snd_ac97_rename_vol_ctl().
# 
# sound/pci/ac97/ac97_local.h
#   2004/05/24 08:24:42+02:00 perex@suse.cz +4 -3
#   ALSA CVS update
#   D:2004/05/24 14:24:42
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:include/ac97_codec.h:1.44->1.45 
#   F:pci/ac97/ac97_codec.c:1.132->1.133 
#   F:pci/ac97/ac97_local.h:1.5->1.6 
#   F:pci/ac97/ac97_patch.c:1.49->1.50 
#   F:pci/ac97/ac97_proc.c:1.7->1.8 
#   L:- added the global mutex for ac97_t (ad18xx mutex is removed).
#   L:  used to protect paging and AD18xx multi-codecs.
#   L:- set PAGE_INT register explicitly before accessing (for STAC9758).
#   L:- moved ALC650 revision check to patch_alc650().
#   L:- support stereo Mic playback.
#   L:- moved STAC9708 quirk to patch_stac9708().
#   L:- don't clear PC_BEEP high bits (ac97 2.3 sets frequency there).
#   L:- avoid the unnecessary RESET-waiting for audio/modem codec.
#   L:- fixed the evaluation of modem codec to call mpatch callback properly.
#   L:- determine the SPDIF rate in the build path.
#   L:- added suffix argument to snd_ac97_rename|remove|swap_ctl().
#   L:- added snd_ac97_rename_vol_ctl().
# 
# sound/pci/ac97/ac97_codec.c
#   2004/05/24 08:24:42+02:00 perex@suse.cz +93 -70
#   ALSA CVS update
#   D:2004/05/24 14:24:42
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:include/ac97_codec.h:1.44->1.45 
#   F:pci/ac97/ac97_codec.c:1.132->1.133 
#   F:pci/ac97/ac97_local.h:1.5->1.6 
#   F:pci/ac97/ac97_patch.c:1.49->1.50 
#   F:pci/ac97/ac97_proc.c:1.7->1.8 
#   L:- added the global mutex for ac97_t (ad18xx mutex is removed).
#   L:  used to protect paging and AD18xx multi-codecs.
#   L:- set PAGE_INT register explicitly before accessing (for STAC9758).
#   L:- moved ALC650 revision check to patch_alc650().
#   L:- support stereo Mic playback.
#   L:- moved STAC9708 quirk to patch_stac9708().
#   L:- don't clear PC_BEEP high bits (ac97 2.3 sets frequency there).
#   L:- avoid the unnecessary RESET-waiting for audio/modem codec.
#   L:- fixed the evaluation of modem codec to call mpatch callback properly.
#   L:- determine the SPDIF rate in the build path.
#   L:- added suffix argument to snd_ac97_rename|remove|swap_ctl().
#   L:- added snd_ac97_rename_vol_ctl().
# 
# include/sound/ac97_codec.h
#   2004/05/24 08:24:42+02:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2004/05/24 14:24:42
#   C:AC97 Codec Core
#   A:Takashi Iwai <tiwai@suse.de>
#   F:include/ac97_codec.h:1.44->1.45 
#   F:pci/ac97/ac97_codec.c:1.132->1.133 
#   F:pci/ac97/ac97_local.h:1.5->1.6 
#   F:pci/ac97/ac97_patch.c:1.49->1.50 
#   F:pci/ac97/ac97_proc.c:1.7->1.8 
#   L:- added the global mutex for ac97_t (ad18xx mutex is removed).
#   L:  used to protect paging and AD18xx multi-codecs.
#   L:- set PAGE_INT register explicitly before accessing (for STAC9758).
#   L:- moved ALC650 revision check to patch_alc650().
#   L:- support stereo Mic playback.
#   L:- moved STAC9708 quirk to patch_stac9708().
#   L:- don't clear PC_BEEP high bits (ac97 2.3 sets frequency there).
#   L:- avoid the unnecessary RESET-waiting for audio/modem codec.
#   L:- fixed the evaluation of modem codec to call mpatch callback properly.
#   L:- determine the SPDIF rate in the build path.
#   L:- added suffix argument to snd_ac97_rename|remove|swap_ctl().
#   L:- added snd_ac97_rename_vol_ctl().
# 
# ChangeSet
#   2004/05/28 14:13:55+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   Memalloc module
#   - added ifdef CONFIG_PCI around the enable module option to avoid the compile
#     warnings without PCI support.
# 
# sound/core/memalloc.c
#   2004/05/24 08:19:55+02:00 perex@suse.cz +4 -0
#   ALSA CVS update
#   D:2004/05/24 14:19:55
#   C:Memalloc module
#   A:Takashi Iwai <tiwai@suse.de>
#   F:core/memalloc.c:1.31->1.32 
#   L:- added ifdef CONFIG_PCI around the enable module option to avoid the compile
#   L:  warnings without PCI support.
# 
# ChangeSet
#   2004/05/28 14:13:31+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   Documentation,ICE1712 driver,ICE1724 driver
#   - fixed the description of model module parameters for ice1712 and ice1724
#     drivers.
#   - added the support of VT1720-based mobo.
#     (still experimental and supporting AC97 only)
# 
# sound/pci/ice1712/vt1720_mobo.h
#   2004/05/28 13:46:26+02:00 perex@suse.cz +35 -0
#   ALSA CVS update
#   D:2004/05/24 14:18:20
#   C:Documentation,ICE1712 driver,ICE1724 driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:Documentation/ALSA-Configuration.txt:1.44->1.45 
#   F:pci/ice1712/Makefile:1.11->1.12 
#   F:pci/ice1712/ice1724.c:1.31->1.32 
#   F:pci/ice1712/vt1720_mobo.c:INITIAL->1.1 
#   F:pci/ice1712/vt1720_mobo.h:INITIAL->1.1 
#   L:- fixed the description of model module parameters for ice1712 and ice1724
#   L:  drivers.
#   L:- added the support of VT1720-based mobo.
#   L:  (still experimental and supporting AC97 only)
# 
# sound/pci/ice1712/vt1720_mobo.h
#   2004/05/28 13:46:26+02:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/ice1712/vt1720_mobo.h
# 
# sound/pci/ice1712/vt1720_mobo.c
#   2004/05/28 13:46:21+02:00 perex@suse.cz +97 -0
#   ALSA CVS update
#   D:2004/05/24 14:18:20
#   C:Documentation,ICE1712 driver,ICE1724 driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:Documentation/ALSA-Configuration.txt:1.44->1.45 
#   F:pci/ice1712/Makefile:1.11->1.12 
#   F:pci/ice1712/ice1724.c:1.31->1.32 
#   F:pci/ice1712/vt1720_mobo.c:INITIAL->1.1 
#   F:pci/ice1712/vt1720_mobo.h:INITIAL->1.1 
#   L:- fixed the description of model module parameters for ice1712 and ice1724
#   L:  drivers.
#   L:- added the support of VT1720-based mobo.
#   L:  (still experimental and supporting AC97 only)
# 
# sound/pci/ice1712/ice1724.c
#   2004/05/24 08:18:20+02:00 perex@suse.cz +6 -6
#   ALSA CVS update
#   D:2004/05/24 14:18:20
#   C:Documentation,ICE1712 driver,ICE1724 driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:Documentation/ALSA-Configuration.txt:1.44->1.45 
#   F:pci/ice1712/Makefile:1.11->1.12 
#   F:pci/ice1712/ice1724.c:1.31->1.32 
#   F:pci/ice1712/vt1720_mobo.c:INITIAL->1.1 
#   F:pci/ice1712/vt1720_mobo.h:INITIAL->1.1 
#   L:- fixed the description of model module parameters for ice1712 and ice1724
#   L:  drivers.
#   L:- added the support of VT1720-based mobo.
#   L:  (still experimental and supporting AC97 only)
# 
# sound/pci/ice1712/Makefile
#   2004/05/24 08:18:20+02:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2004/05/24 14:18:20
#   C:Documentation,ICE1712 driver,ICE1724 driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:Documentation/ALSA-Configuration.txt:1.44->1.45 
#   F:pci/ice1712/Makefile:1.11->1.12 
#   F:pci/ice1712/ice1724.c:1.31->1.32 
#   F:pci/ice1712/vt1720_mobo.c:INITIAL->1.1 
#   F:pci/ice1712/vt1720_mobo.h:INITIAL->1.1 
#   L:- fixed the description of model module parameters for ice1712 and ice1724
#   L:  drivers.
#   L:- added the support of VT1720-based mobo.
#   L:  (still experimental and supporting AC97 only)
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2004/05/24 08:18:20+02:00 perex@suse.cz +3 -2
#   ALSA CVS update
#   D:2004/05/24 14:18:20
#   C:Documentation,ICE1712 driver,ICE1724 driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:Documentation/ALSA-Configuration.txt:1.44->1.45 
#   F:pci/ice1712/Makefile:1.11->1.12 
#   F:pci/ice1712/ice1724.c:1.31->1.32 
#   F:pci/ice1712/vt1720_mobo.c:INITIAL->1.1 
#   F:pci/ice1712/vt1720_mobo.h:INITIAL->1.1 
#   L:- fixed the description of model module parameters for ice1712 and ice1724
#   L:  drivers.
#   L:- added the support of VT1720-based mobo.
#   L:  (still experimental and supporting AC97 only)
# 
# sound/pci/ice1712/vt1720_mobo.c
#   2004/05/28 13:46:21+02:00 perex@suse.cz +0 -0
#   BitKeeper file /home/perex/bk/linux-sound/work/sound/pci/ice1712/vt1720_mobo.c
# 
# ChangeSet
#   2004/05/28 14:13:07+02:00 perex@suse.cz 
#   ALSA CVS update - Takashi Iwai <tiwai@suse.de>
#   ATIIXP driver
#   - continue to probe other codecs even if a codec returns error
#     (instead of breaking the probing).
#     this will fix some cases with both AC97 and MC97 codecs.
# 
# sound/pci/atiixp.c
#   2004/05/24 08:16:43+02:00 perex@suse.cz +4 -12
#   ALSA CVS update
#   D:2004/05/24 14:16:43
#   C:ATIIXP driver
#   A:Takashi Iwai <tiwai@suse.de>
#   F:pci/atiixp.c:1.9->1.10 
#   L:- continue to probe other codecs even if a codec returns error
#   L:  (instead of breaking the probing).
#   L:  this will fix some cases with both AC97 and MC97 codecs.
# 
# ChangeSet
#   2004/05/28 14:12:17+02:00 perex@suse.cz 
#   ALSA CVS update - Clemens Ladisch <clemens@ladisch.de>
#   ALSA sequencer,ALSA<-OSS sequencer
#   export snd_seq_set_queue_tempo() for OSS to prevent calling
#   snd_seq_kernel_client_ctl() (using copy_from_user()) in interrupt
#   context
# 
# sound/core/seq/seq_clientmgr.c
#   2004/05/24 07:31:18+02:00 perex@suse.cz +9 -9
#   ALSA CVS update
#   D:2004/05/24 13:31:18
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   A:Clemens Ladisch <clemens@ladisch.de>
#   F:core/seq/seq.c:1.12->1.13 
#   F:core/seq/seq_clientmgr.c:1.28->1.29 
#   F:core/seq/oss/seq_oss_timer.c:1.5->1.6 
#   F:include/seq_kernel.h:1.9->1.10 
#   L:export snd_seq_set_queue_tempo() for OSS to prevent calling
#   L:snd_seq_kernel_client_ctl() (using copy_from_user()) in interrupt
#   L:context
# 
# sound/core/seq/seq.c
#   2004/05/24 07:31:18+02:00 perex@suse.cz +1 -0
#   ALSA CVS update
#   D:2004/05/24 13:31:18
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   A:Clemens Ladisch <clemens@ladisch.de>
#   F:core/seq/seq.c:1.12->1.13 
#   F:core/seq/seq_clientmgr.c:1.28->1.29 
#   F:core/seq/oss/seq_oss_timer.c:1.5->1.6 
#   F:include/seq_kernel.h:1.9->1.10 
#   L:export snd_seq_set_queue_tempo() for OSS to prevent calling
#   L:snd_seq_kernel_client_ctl() (using copy_from_user()) in interrupt
#   L:context
# 
# sound/core/seq/oss/seq_oss_timer.c
#   2004/05/24 07:31:19+02:00 perex@suse.cz +1 -1
#   ALSA CVS update
#   D:2004/05/24 13:31:18
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   A:Clemens Ladisch <clemens@ladisch.de>
#   F:core/seq/seq.c:1.12->1.13 
#   F:core/seq/seq_clientmgr.c:1.28->1.29 
#   F:core/seq/oss/seq_oss_timer.c:1.5->1.6 
#   F:include/seq_kernel.h:1.9->1.10 
#   L:export snd_seq_set_queue_tempo() for OSS to prevent calling
#   L:snd_seq_kernel_client_ctl() (using copy_from_user()) in interrupt
#   L:context
# 
# include/sound/seq_kernel.h
#   2004/05/24 07:31:18+02:00 perex@suse.cz +3 -0
#   ALSA CVS update
#   D:2004/05/24 13:31:18
#   C:ALSA sequencer,ALSA<-OSS sequencer
#   A:Clemens Ladisch <clemens@ladisch.de>
#   F:core/seq/seq.c:1.12->1.13 
#   F:core/seq/seq_clientmgr.c:1.28->1.29 
#   F:core/seq/oss/seq_oss_timer.c:1.5->1.6 
#   F:include/seq_kernel.h:1.9->1.10 
#   L:export snd_seq_set_queue_tempo() for OSS to prevent calling
#   L:snd_seq_kernel_client_ctl() (using copy_from_user()) in interrupt
#   L:context
# 
# ChangeSet
#   2004/05/24 11:20:24-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/au88x0/au88x0_game.c
#   2004/05/24 11:20:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/05/24 11:20:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/22 23:24:51-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/22 23:24:48-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/18 23:40:49-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# sound/pci/au88x0/au88x0_game.c
#   2004/05/18 23:40:46-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/05/18 23:40:46-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/18 14:26:58-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/pcmcia/pdaudiocf/pdaudiocf.c
#   2004/05/18 14:26:55-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/wavefront/wavefront_synth.c
#   2004/05/18 14:26:55-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/es1688/es1688.c
#   2004/05/18 14:26:55-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/05/18 14:26:55-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/18 14:25:56-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/18 14:25:53-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/16 01:22:31-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/16 01:22:28-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/14 21:18:25-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/14 21:18:22-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/05/11 16:33:03-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/05/11 16:33:00-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/29 15:39:10-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/04/29 15:39:07-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/26 18:08:46-07:00 akpm@bix.(none) 
#   Merge http://linux-sound.bkbits.net/linux-sound
#   into bix.(none):/usr/src/bk-alsa
# 
# sound/pcmcia/pdaudiocf/pdaudiocf.c
#   2004/04/26 18:08:43-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/wavefront/wavefront_synth.c
#   2004/04/26 18:08:43-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# sound/isa/es1688/es1688.c
#   2004/04/26 18:08:43-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/pci_ids.h
#   2004/04/26 18:08:43-07:00 akpm@bix.(none) +0 -2
#   Auto merged
# 
# ChangeSet
#   2004/04/25 22:42:13-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/04/25 22:42:10-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/16 12:26:24-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/04/16 12:26:21-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/14 18:18:38-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/04/14 18:18:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/13 17:03:26-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/04/13 17:03:23-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/12 20:38:27-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa
# 
# include/linux/pci_ids.h
#   2004/04/12 20:38:24-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/01 14:38:57-08:00 akpm@bix.(none) 
#   x
# 
# include/linux/pci_ids.h
#   2004/04/01 14:38:53-08:00 akpm@bix.(none) +2 -3
#   x
# 
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	2004-06-02 23:31:42 -07:00
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	2004-06-02 23:31:42 -07:00
@@ -613,7 +613,7 @@
     model       - Use the given board model, one of the following:
 		  delta1010, dio2496, delta66, delta44, audiophile, delta410,
 		  delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d,
-		  dmx6fire, dsp24, dsp24_71, ez8
+		  dmx6fire, dsp24, dsp24_value, dsp24_71, ez8
     omni	- Omni I/O support for MidiMan M-Audio Delta44/66
     cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
                      in msec resolution, default value is 500 (0.5 sec)
@@ -631,7 +631,8 @@
 			* TerraTec Aureon Sky-5.1, Space-7.1
 
     model       - Use the given board model, one of the following:
-		  revo71, amp2000, prodigy71, aureon51, aureon71
+		  revo71, amp2000, prodigy71, aureon51, aureon71,
+		  k8x800
 
     Module supports up to 8 cards and autoprobe.
 
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	2004-06-02 23:31:42 -07:00
+++ b/include/sound/ac97_codec.h	2004-06-02 23:31:42 -07:00
@@ -441,6 +441,7 @@
 	unsigned short subsystem_vendor;
 	unsigned short subsystem_device;
 	spinlock_t reg_lock;
+	struct semaphore mutex;	/* mutex for AD18xx multi-codecs and paging (2.3) */
 	unsigned short num;	/* number of codec: 0 = primary, 1 = secondary */
 	unsigned short addr;	/* physical address of codec [0-3] */
 	unsigned int id;	/* identification of codec */
@@ -461,7 +462,6 @@
 			unsigned short id[3];		// codec IDs (lower 16-bit word)
 			unsigned short pcmreg[3];	// PCM registers
 			unsigned short codec_cfg[3];	// CODEC_CFG bits
-			struct semaphore mutex;
 		} ad18xx;
 		unsigned int dev_flags;		/* device specific */
 	} spec;
@@ -483,6 +483,10 @@
 static inline int ac97_can_amap(ac97_t * ac97)
 {
 	return (ac97->ext_id & AC97_EI_AMAP) != 0;
+}
+static inline int ac97_can_spdif(ac97_t * ac97)
+{
+	return (ac97->ext_id & AC97_EI_SPDIF) != 0;
 }
 
 /* functions */
diff -Nru a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h	2004-06-02 23:31:42 -07:00
+++ b/include/sound/core.h	2004-06-02 23:31:42 -07:00
@@ -211,12 +211,14 @@
 				 void *private_data);
 #define snd_card_set_isa_pm_callback(card,suspend,resume,data) \
 	snd_card_set_dev_pm_callback(card, PM_ISA_DEV, suspend, resume, data)
+#ifdef CONFIG_PCI
 #ifndef SND_PCI_PM_CALLBACKS
 int snd_card_pci_suspend(struct pci_dev *dev, u32 state);
 int snd_card_pci_resume(struct pci_dev *dev);
 #define SND_PCI_PM_CALLBACKS \
 	.suspend = snd_card_pci_suspend,  .resume = snd_card_pci_resume
 #endif
+#endif
 #else
 #define snd_power_lock(card)		do { (void)(card); } while (0)
 #define snd_power_unlock(card)		do { (void)(card); } while (0)
@@ -226,7 +228,9 @@
 #define snd_card_set_pm_callback(card,suspend,resume,data) -EINVAL
 #define snd_card_set_dev_pm_callback(card,suspend,resume,data) -EINVAL
 #define snd_card_set_isa_pm_callback(card,suspend,resume,data) -EINVAL
+#ifdef CONFIG_PCI
 #define SND_PCI_PM_CALLBACKS
+#endif
 #endif
 
 /* device.c */
diff -Nru a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
--- a/include/sound/seq_kernel.h	2004-06-02 23:31:42 -07:00
+++ b/include/sound/seq_kernel.h	2004-06-02 23:31:42 -07:00
@@ -168,6 +168,9 @@
 int snd_seq_expand_var_event(const snd_seq_event_t *event, int count, char *buf, int in_kernel, int size_aligned);
 int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t func, void *private_data);
 
+/* interface for OSS emulation */
+int snd_seq_set_queue_tempo(int client, snd_seq_queue_tempo_t *tempo);
+
 /* port callback routines */
 void snd_port_init_callback(snd_seq_port_callback_t *p);
 snd_seq_port_callback_t *snd_port_alloc_callback(void);
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	2004-06-02 23:31:42 -07:00
+++ b/include/sound/version.h	2004-06-02 23:31:42 -07:00
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.4"
-#define CONFIG_SND_DATE " (Mon May 17 14:31:44 2004 UTC)"
+#define CONFIG_SND_VERSION "1.0.5"
+#define CONFIG_SND_DATE " (Sun May 30 10:49:40 2004 UTC)"
diff -Nru a/include/sound/vx_core.h b/include/sound/vx_core.h
--- a/include/sound/vx_core.h	2004-06-02 23:31:42 -07:00
+++ b/include/sound/vx_core.h	2004-06-02 23:31:42 -07:00
@@ -182,6 +182,7 @@
 	/* clock and audio sources */
 	unsigned int audio_source;	/* current audio input source */
 	unsigned int audio_source_target;
+	unsigned int clock_mode;	/* clock mode (VX_CLOCK_MODE_XXX) */
 	unsigned int clock_source;	/* current clock source (INTERNAL_QUARTZ or UER_SYNC) */
 	unsigned int freq;		/* current frequency */
 	unsigned int freq_detected;	/* detected frequency from digital in */
@@ -362,6 +363,13 @@
 enum {
 	INTERNAL_QUARTZ,
 	UER_SYNC
+};
+
+/* clock mode */
+enum {
+	VX_CLOCK_MODE_AUTO,	/* depending on the current audio source */
+	VX_CLOCK_MODE_INTERNAL,	/* fixed to internal quartz */
+	VX_CLOCK_MODE_EXTERNAL	/* fixed to UER sync */
 };
 
 /* SPDIF/UER type */
diff -Nru a/sound/core/memalloc.c b/sound/core/memalloc.c
--- a/sound/core/memalloc.c	2004-06-02 23:31:42 -07:00
+++ b/sound/core/memalloc.c	2004-06-02 23:31:42 -07:00
@@ -45,10 +45,14 @@
 #ifndef SNDRV_CARDS
 #define SNDRV_CARDS	8
 #endif
+
+/* FIXME: so far only some PCI devices have the preallocation table */
+#ifdef CONFIG_PCI
 static int enable[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
 static int boot_devs;
 module_param_array(enable, bool, boot_devs, 0444);
 MODULE_PARM_DESC(enable, "Enable cards to allocate buffers.");
+#endif
 
 /*
  */
diff -Nru a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
--- a/sound/core/seq/oss/seq_oss_timer.c	2004-06-02 23:31:42 -07:00
+++ b/sound/core/seq/oss/seq_oss_timer.c	2004-06-02 23:31:42 -07:00
@@ -168,7 +168,7 @@
 	tmprec.queue = dp->queue;
 	tmprec.ppq = timer->ppq;
 	tmprec.tempo = timer->tempo;
-	snd_seq_kernel_client_ctl(dp->cseq, SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, &tmprec);
+	snd_seq_set_queue_tempo(dp->cseq, &tmprec);
 
 	send_timer_event(dp, SNDRV_SEQ_EVENT_START, 0);
 	timer->running = 1;
diff -Nru a/sound/core/seq/seq.c b/sound/core/seq/seq.c
--- a/sound/core/seq/seq.c	2004-06-02 23:31:42 -07:00
+++ b/sound/core/seq/seq.c	2004-06-02 23:31:42 -07:00
@@ -133,6 +133,7 @@
 EXPORT_SYMBOL(snd_seq_kernel_client_dispatch);
 EXPORT_SYMBOL(snd_seq_kernel_client_ctl);
 EXPORT_SYMBOL(snd_seq_kernel_client_write_poll);
+EXPORT_SYMBOL(snd_seq_set_queue_tempo);
   /* seq_memory.c */
 EXPORT_SYMBOL(snd_seq_expand_var_event);
 EXPORT_SYMBOL(snd_seq_dump_var_event);
diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
--- a/sound/core/seq/seq_clientmgr.c	2004-06-02 23:31:42 -07:00
+++ b/sound/core/seq/seq_clientmgr.c	2004-06-02 23:31:42 -07:00
@@ -1694,6 +1694,13 @@
 
 
 /* SET_QUEUE_TEMPO ioctl() */
+int snd_seq_set_queue_tempo(int client, snd_seq_queue_tempo_t *tempo)
+{
+	if (!snd_seq_queue_check_access(tempo->queue, client))
+		return -EPERM;
+	return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
+}
+
 static int snd_seq_ioctl_set_queue_tempo(client_t * client, void __user *arg)
 {
 	int result;
@@ -1702,15 +1709,8 @@
 	if (copy_from_user(&tempo, arg, sizeof(tempo)))
 		return -EFAULT;
 
-	if (snd_seq_queue_check_access(tempo.queue, client->number)) {
-		result = snd_seq_queue_timer_set_tempo(tempo.queue, client->number, &tempo);
-		if (result < 0)
-			return result;
-	} else {
-		return -EPERM;
-	}	
-
-	return 0;
+	result = snd_seq_set_queue_tempo(client->number, &tempo);
+	return result < 0 ? result : 0;
 }
 
 
diff -Nru a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
--- a/sound/drivers/vx/vx_core.c	2004-06-02 23:31:42 -07:00
+++ b/sound/drivers/vx/vx_core.c	2004-06-02 23:31:42 -07:00
@@ -572,6 +572,7 @@
 	if (cold_reset) {
 		chip->audio_source_target = chip->audio_source;
 		chip->clock_source = INTERNAL_QUARTZ;
+		chip->clock_mode = VX_CLOCK_MODE_AUTO;
 		chip->freq = 48000;
 		chip->uer_detected = VX_UER_MODE_NOT_PRESENT;
 		chip->uer_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
@@ -606,6 +607,7 @@
 	vx_core_t *chip = snd_magic_cast(vx_core_t, entry->private_data, return);
 	static char *audio_src_vxp[] = { "Line", "Mic", "Digital" };
 	static char *audio_src_vx2[] = { "Analog", "Analog", "Digital" };
+	static char *clock_mode[] = { "Auto", "Internal", "External" };
 	static char *clock_src[] = { "Internal", "External" };
 	static char *uer_type[] = { "Consumer", "Professional", "Not Present" };
 	
@@ -629,6 +631,7 @@
 	snd_iprintf(buffer, "Input Source: %s\n", vx_is_pcmcia(chip) ?
 		    audio_src_vxp[chip->audio_source] :
 		    audio_src_vx2[chip->audio_source]);
+	snd_iprintf(buffer, "Clock Mode: %s\n", clock_mode[chip->clock_mode]);
 	snd_iprintf(buffer, "Clock Source: %s\n", clock_src[chip->clock_source]);
 	snd_iprintf(buffer, "Frequency: %d\n", chip->freq);
 	snd_iprintf(buffer, "Detected Frequency: %d\n", chip->freq_detected);
diff -Nru a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
--- a/sound/drivers/vx/vx_mixer.c	2004-06-02 23:31:42 -07:00
+++ b/sound/drivers/vx/vx_mixer.c	2004-06-02 23:31:42 -07:00
@@ -524,6 +524,54 @@
 };
 
 /*
+ * clock mode selection
+ */
+static int vx_clock_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[3] = {
+		"Auto", "Internal", "External"
+	};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item > 2)
+		uinfo->value.enumerated.item = 2;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int vx_clock_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = chip->clock_mode;
+	return 0;
+}
+
+static int vx_clock_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	down(&chip->mixer_mutex);
+	if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
+		chip->clock_mode = ucontrol->value.enumerated.item[0];
+		vx_set_clock(chip, chip->freq);
+		up(&chip->mixer_mutex);
+		return 1;
+	}
+	up(&chip->mixer_mutex);
+	return 0;
+}
+
+static snd_kcontrol_new_t vx_control_clock_mode = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Clock Mode",
+	.info =		vx_clock_mode_info,
+	.get =		vx_clock_mode_get,
+	.put =		vx_clock_mode_put,
+};
+
+/*
  * Audio Gain
  */
 static int vx_audio_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
@@ -912,6 +960,9 @@
 
 	/* Audio source */
 	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_audio_src, chip))) < 0)
+		return err;
+	/* clock mode */
+	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_clock_mode, chip))) < 0)
 		return err;
 	/* IEC958 controls */
 	if ((err = snd_ctl_add(card, snd_ctl_new1(&vx_control_iec958_mask, chip))) < 0)
diff -Nru a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
--- a/sound/drivers/vx/vx_pcm.c	2004-06-02 23:31:42 -07:00
+++ b/sound/drivers/vx/vx_pcm.c	2004-06-02 23:31:42 -07:00
@@ -48,6 +48,7 @@
 #include <sound/driver.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/delay.h>
 #include <sound/core.h>
 #include <sound/asoundef.h>
 #include <sound/pcm.h>
@@ -381,7 +382,7 @@
  */
 static int vx_toggle_pipe(vx_core_t *chip, vx_pipe_t *pipe, int state)
 {
-	int err, i, cur_state, delay;
+	int err, i, cur_state;
 
 	/* Check the pipe is not already in the requested state */
 	if (vx_get_pipe_state(chip, pipe, &cur_state) < 0)
@@ -394,17 +395,14 @@
 	 * enough sound buffer for this pipe)
 	 */
 	if (state) {
-		int delay = CAN_START_DELAY;
 		for (i = 0 ; i < MAX_WAIT_FOR_DSP; i++) {
-			snd_vx_delay(chip, delay);
 			err = vx_pipe_can_start(chip, pipe);
 			if (err > 0)
 				break;
 			/* Wait for a few, before asking again
 			 * to avoid flooding the DSP with our requests
 			 */
-			if ((i % 4 ) == 0)
-				delay <<= 1;
+			mdelay(1);
 		}
 	}
     
@@ -418,15 +416,12 @@
 	 * reaching the expected state before returning
 	 * Check one pipe only (since they are synchronous)
 	 */
-	delay = WAIT_STATE_DELAY;
 	for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
-		snd_vx_delay(chip, delay);
 		err = vx_get_pipe_state(chip, pipe, &cur_state);
 		if (err < 0 || cur_state == state)
 			break;
 		err = -EIO;
-		if ((i % 4 ) == 0)
-			delay <<= 1;
+		mdelay(1);
 	}
 	return err < 0 ? -EIO : 0;
 }
diff -Nru a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
--- a/sound/drivers/vx/vx_uer.c	2004-06-02 23:31:42 -07:00
+++ b/sound/drivers/vx/vx_uer.c	2004-06-02 23:31:42 -07:00
@@ -263,17 +263,17 @@
 	/* change the audio source if possible */
 	vx_sync_audio_source(chip);
 
-	switch (chip->audio_source) {
-	case VX_AUDIO_SRC_DIGITAL:
+	if (chip->clock_mode == VX_CLOCK_MODE_EXTERNAL ||
+	    (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
+	     chip->audio_source == VX_AUDIO_SRC_DIGITAL)) {
 		if (chip->clock_source != UER_SYNC) {
 			vx_change_clock_source(chip, UER_SYNC);
 			mdelay(6);
 			src_changed = 1;
 		}
-		if (chip->freq == freq)
-			return 0;
-		break;
-	default:
+	} else if (chip->clock_mode == VX_CLOCK_MODE_INTERNAL ||
+		   (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
+		    chip->audio_source != VX_AUDIO_SRC_DIGITAL)) {
 		if (chip->clock_source != INTERNAL_QUARTZ) {
 			vx_change_clock_source(chip, INTERNAL_QUARTZ);
 			src_changed = 1;
@@ -283,8 +283,9 @@
 		vx_set_internal_clock(chip, freq);
 		if (src_changed)
 			vx_modify_board_inputs(chip);
-		break;
 	}
+	if (chip->freq == freq)
+		return 0;
 	chip->freq = freq;
 	vx_modify_board_clock(chip, 1);
 	return 0;
diff -Nru a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
--- a/sound/isa/wavefront/wavefront_synth.c	2004-06-02 23:31:42 -07:00
+++ b/sound/isa/wavefront/wavefront_synth.c	2004-06-02 23:31:42 -07:00
@@ -1966,6 +1966,12 @@
 			break;
 		}
 
+		if (section_length < 0 || section_length > WF_SECTION_MAX) {
+			snd_printk ("invalid firmware section length %d\n",
+				    section_length);
+			goto failure;
+		}
+
 		if (sys_read (fd, section, section_length) != section_length) {
 			snd_printk ("firmware section "
 				"read error.\n");
diff -Nru a/sound/parisc/harmony.c b/sound/parisc/harmony.c
--- a/sound/parisc/harmony.c	2004-06-02 23:31:42 -07:00
+++ b/sound/parisc/harmony.c	2004-06-02 23:31:42 -07:00
@@ -556,7 +556,7 @@
 	harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate);
 
 	/* data format */
-	harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format);
+	harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format);
 
 	/* number of channels */
 	if (runtime->channels == 2)
@@ -587,7 +587,7 @@
 	harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate);
 	
 	/* data format */
-	harmony->data_format = snd_harmony_set_data_format(haromny, runtime->format);
+	harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format);
 	
 	/* number of channels */
 	if (runtime->channels == 1)
@@ -751,6 +751,8 @@
 	int err;
 	
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+	if (err > 0 && substream->dma_device.type == SNDRV_DMA_TYPE_CONTINUOUS)
+		substream->runtime->dma_addr = __pa(substream->runtime->dma_area);
 	DPRINTK(KERN_INFO PFX "HW Params returned %d, dma_addr %lx\n", err,
 			(unsigned long)substream->runtime->dma_addr);
 	return err;
@@ -784,7 +786,7 @@
 	.pointer =		snd_card_harmony_capture_pointer,
 };
 
-static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony, int device)
+static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony)
 {
 	snd_pcm_t *pcm;
 	int err;
@@ -797,7 +799,7 @@
 	
 	snd_harmony_disable_interrupts(harmony);
 	
-   	if ((err = snd_pcm_new(harmony->card, "Harmony", device, 1, 1, &pcm)) < 0)
+   	if ((err = snd_pcm_new(harmony->card, "Harmony", 0, 1, 1, &pcm)) < 0)
 		return err;
 	
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_harmony_playback_ops);
@@ -813,26 +815,46 @@
 	harmony->dma_dev.dev = &harmony->pa_dev->dev;
 	err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*GRAVEYARD_BUFS,
 				  &harmony->graveyard_dma);
-	if (err < 0)
+	if (err == -ENOMEM) {
+		/* use continuous buffers */
+		harmony->dma_dev.type = SNDRV_DMA_TYPE_CONTINUOUS;
+		harmony->dma_dev.dev = snd_dma_continuous_data(GFP_KERNEL);
+		err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*GRAVEYARD_BUFS,
+					  &harmony->graveyard_dma);
+	}
+	if (err < 0) {
+		printk(KERN_ERR PFX "can't allocate graveyard buffer\n");
 		return err;
+	}
 	harmony->graveyard_count = 0;
 	
 	/* initialize silence buffers */
 	err = snd_dma_alloc_pages(&harmony->dma_dev, HARMONY_BUF_SIZE*SILENCE_BUFS,
 				  &harmony->silence_dma);
-	if (err < 0)
+	if (err < 0) {
+		printk(KERN_ERR PFX "can't allocate silence buffer\n");
 		return err;
+	}
 	harmony->silence_count = 0;
 
+	if (harmony->dma_dev.type == SNDRV_DMA_TYPE_CONTINUOUS) {
+		harmony->graveyard_dma.addr = __pa(harmony->graveyard_dma.area);
+		harmony->silence_dma.addr = __pa(harmony->silence_dma.area);
+	}
+
 	harmony->ply_stopped = harmony->cap_stopped = 1;
 	
 	harmony->playback_substream = NULL;
 	harmony->capture_substream = NULL;
 	harmony->graveyard_count = 0;
-	
-	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      &harmony->pa_dev->dev,
-					      MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
+
+	err = snd_pcm_lib_preallocate_pages_for_all(pcm, harmony->dma_dev.type,
+						    harmony->dma_dev.dev,
+						    MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
+	if (err < 0) {
+		printk(KERN_ERR PFX "buffer allocation error %d\n", err);
+		// return err;
+	}
 
 	return 0;
 }
@@ -1037,7 +1059,7 @@
 		snd_card_free(card);
 		return err;
 	}
-	if ((err = snd_card_harmony_pcm_init(chip, dev)) < 0) {
+	if ((err = snd_card_harmony_pcm_init(chip)) < 0) {
 		printk(KERN_ERR PFX "PCM Init failed\n");
 		snd_card_free(card);
 		return err;
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ac97/ac97_codec.c	2004-06-02 23:31:42 -07:00
@@ -108,12 +108,13 @@
 { 0x41445375, 0xffffffff, "AD1985",		patch_ad1985,	NULL },
 { 0x414c4300, 0xffffff00, "ALC100/100P", 	NULL,		NULL },
 { 0x414c4710, 0xfffffff0, "ALC200/200P",	NULL,		NULL },
+{ 0x414c4721, 0xffffffff, "ALC650D",		NULL,	NULL }, /* already patched */
+{ 0x414c4722, 0xffffffff, "ALC650E",		NULL,	NULL }, /* already patched */
+{ 0x414c4723, 0xffffffff, "ALC650F",		NULL,	NULL }, /* already patched */
 { 0x414c4720, 0xfffffff0, "ALC650",		patch_alc650,	NULL },
-{ 0x414c4721, 0xfffffff0, "ALC650D",		patch_alc650,	NULL },
-{ 0x414c4722, 0xfffffff0, "ALC650E",		patch_alc650,	NULL },
-{ 0x414c4723, 0xfffffff0, "ALC650F",		patch_alc650,	NULL },
 { 0x414c4760, 0xfffffff0, "ALC655",		patch_alc655,	NULL },
 { 0x414c4780, 0xfffffff0, "ALC658",		patch_alc655,	NULL },
+{ 0x414c4790, 0xfffffff0, "ALC850",		patch_alc850,	NULL },
 { 0x414c4730, 0xffffffff, "ALC101",		NULL,		NULL },
 { 0x414c4740, 0xfffffff0, "ALC202",		NULL,		NULL },
 { 0x414c4750, 0xfffffff0, "ALC250",		NULL,		NULL },
@@ -274,7 +275,7 @@
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return;
-	if ((ac97->id & 0xffffff00) == 0x414c4300) {
+	if ((ac97->id & 0xffffff00) == AC97_ID_ALC100) {
 		/* Fix H/W bug of ALC100/100P */
 		if (reg == AC97_MASTER || reg == AC97_HEADPHONE)
 			ac97->bus->write(ac97, AC97_RESET, 0);	/* reset audio codec */
@@ -398,7 +399,7 @@
 	int change;
 	unsigned short old, new, cfg;
 
-	down(&ac97->spec.ad18xx.mutex);
+	down(&ac97->mutex);
 	spin_lock(&ac97->reg_lock);
 	old = ac97->spec.ad18xx.pcmreg[codec];
 	new = (old & ~mask) | value;
@@ -418,7 +419,7 @@
 				 cfg | 0x7000);
 	} else
 		spin_unlock(&ac97->reg_lock);
-	up(&ac97->spec.ad18xx.mutex);
+	up(&ac97->mutex);
 	return change;
 }
 
@@ -545,7 +546,7 @@
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
-	int invert = (kcontrol->private_value >> 24) & 0xff;
+	int invert = (kcontrol->private_value >> 24) & 0x01;
 	
 	ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift) & mask;
 	if (invert)
@@ -559,7 +560,7 @@
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
-	int invert = (kcontrol->private_value >> 24) & 0xff;
+	int invert = (kcontrol->private_value >> 24) & 0x01;
 	unsigned short val;
 	
 	val = (ucontrol->value.integer.value[0] & mask);
@@ -625,6 +626,40 @@
 				    (val1 << shift_left) | (val2 << shift_right));
 }
 
+int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol,
+			 int (*func)(snd_kcontrol_t *, snd_ctl_elem_value_t *))
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	int reg = kcontrol->private_value & 0xff;
+	int err;
+
+	if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 &&
+	    (reg >= 0x60 && reg < 0x70)) {
+		unsigned short page_save;
+		unsigned short page = (kcontrol->private_value >> 25) & 0x0f;
+		down(&ac97->mutex); /* lock paging */
+		page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
+		snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
+		err = func(kcontrol, ucontrol);
+		snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
+		up(&ac97->mutex); /* unlock paging */
+	} else
+		err = func(kcontrol, ucontrol);
+	return err;
+}
+
+/* for rev2.3 paging */
+int snd_ac97_page_get_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_get_single);
+}
+
+/* for rev2.3 paging */
+int snd_ac97_page_put_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_put_single);
+}
+
 static const snd_kcontrol_new_t snd_ac97_controls_master_mono[2] = {
 AC97_SINGLE("Master Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
 AC97_SINGLE("Master Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1)
@@ -1120,6 +1155,7 @@
 	snd_ac97_write_cache(ac97, reg, 0x8000);
 }
 
+/* check the volume resolution of center/lfe */
 static void snd_ac97_change_volume_params2(ac97_t * ac97, int reg, int shift, unsigned char *max)
 {
 	unsigned short val, val1;
@@ -1135,6 +1171,7 @@
 	snd_ac97_write_cache(ac97, reg, 0x8080);
 }
 
+/* check whether the volume resolution is 4 or 5 bits */
 static void snd_ac97_change_volume_params3(ac97_t * ac97, int reg, unsigned char *max)
 {
 	unsigned short val, val1;
@@ -1150,6 +1187,18 @@
 	snd_ac97_write_cache(ac97, reg, 0x8000);
 }
 
+/* check whether the volume is mono or stereo */
+static int snd_ac97_is_stereo_vol(ac97_t *ac97, int reg)
+{
+	unsigned short val, val1, val2;
+	val = snd_ac97_read(ac97, reg);
+	val1 = val | 0x8000 | (0x01 << 8);
+	snd_ac97_write(ac97, reg, val1);
+	val2 = snd_ac97_read(ac97, reg);
+	snd_ac97_write(ac97, reg, val); /* restore */
+	return val1 == val2;
+}
+
 static inline int printable(unsigned int x)
 {
 	x &= 0xff;
@@ -1239,6 +1288,8 @@
 }
 
 
+static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97);
+
 static int snd_ac97_mixer_build(ac97_t * ac97)
 {
 	snd_card_t *card = ac97->bus->card;
@@ -1293,11 +1344,8 @@
 	}
 
 	/* build headphone controls */
-	if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE) || ac97->id == AC97_ID_STAC9708) {
-		const char *name = ac97->id == AC97_ID_STAC9708 ? 
-			"Sigmatel Surround Playback" :
-			"Headphone Playback";
-		if ((err = snd_ac97_cmix_new(card, name, AC97_HEADPHONE, 1, ac97)) < 0)
+	if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) {
+		if ((err = snd_ac97_cmix_new(card, "Headphone Playback", AC97_HEADPHONE, 1, ac97)) < 0)
 			return err;
 	}
 	
@@ -1332,7 +1380,8 @@
 		for (idx = 0; idx < 2; idx++)
 			if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
 				return err;
-		snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x801e);
+		snd_ac97_write_cache(ac97, AC97_PC_BEEP,
+				     snd_ac97_read(ac97, AC97_PC_BEEP) | 0x801e);
 	}
 	
 	/* build Phone controls */
@@ -1349,15 +1398,26 @@
 	
 	/* build MIC controls */
 	snd_ac97_change_volume_params3(ac97, AC97_MIC, &max);
-	for (idx = 0; idx < 3; idx++) {
-		if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_mic[idx], ac97))) < 0)
+	if (snd_ac97_is_stereo_vol(ac97, AC97_MIC)) {
+		/* build stereo mic */
+		if ((err = snd_ac97_cmute_new(card, "Mic Playback Switch", AC97_MIC, ac97)) < 0)
 			return err;
-		if (idx == 1) {		// volume
-			kctl->private_value &= ~(0xff << 16);
-			kctl->private_value |= (int)max << 16;
+		if ((err = snd_ac97_cvol_new(card, "Mic Playback Volume", AC97_MIC, max, ac97)) < 0)
+			return err;
+		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic[2], ac97))) < 0)
+			return err;
+	} else {
+		/* build mono mic */
+		for (idx = 0; idx < 3; idx++) {
+			if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_mic[idx], ac97))) < 0)
+				return err;
+			if (idx == 1) {		// volume
+				kctl->private_value &= ~(0xff << 16);
+				kctl->private_value |= (int)max << 16;
+			}
 		}
+		snd_ac97_write_cache(ac97, AC97_MIC, 0x8000 | max);
 	}
-	snd_ac97_write_cache(ac97, AC97_MIC, 0x8000 | max);
 
 	/* build Line controls */
 	if ((err = snd_ac97_cmix_new(card, "Line Playback", AC97_LINE, 0, ac97)) < 0)
@@ -1410,9 +1470,7 @@
 		if ((err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97)) < 0)
 			return err;
 		/* FIXME: C-Media chips have no PCM volume!! */
-		if (/*ac97->id == 0x434d4941 ||*/
-		    ac97->id == 0x434d4942 ||
-		    ac97->id == 0x434d4961)
+		if (ac97->id == AC97_ID_CM9739)
 			snd_ac97_write_cache(ac97, AC97_PCM, 0x9f1f);
 		else {
 			if ((err = snd_ac97_cvol_new(card, "PCM Playback Volume", AC97_PCM, 31, ac97)) < 0)
@@ -1520,6 +1578,7 @@
 			/* set default PCM S/PDIF params */
 			/* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
 			snd_ac97_write_cache(ac97, AC97_SPDIF, 0x2a20);
+			ac97->rates[AC97_RATES_SPDIF] = snd_ac97_determine_spdif_rates(ac97);
 		}
 		ac97->spdif_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
 	}
@@ -1675,7 +1734,7 @@
 		if (snd_ac97_read(ac97, AC97_REC_GAIN) == 0x8a05)
 			return 0;
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/100);
+		schedule_timeout(1);
 	} while (time_after_eq(end_time, jiffies));
 	return -ENODEV;
 }
@@ -1774,6 +1833,7 @@
 	ac97->bus = bus;
 	bus->codec[ac97->num] = ac97;
 	spin_lock_init(&ac97->reg_lock);
+	init_MUTEX(&ac97->mutex);
 
 	if (ac97->pci) {
 		pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_VENDOR_ID, &ac97->subsystem_vendor);
@@ -1789,8 +1849,14 @@
 		bus->wait(ac97);
 	else {
 		udelay(50);
-		if (ac97_reset_wait(ac97, HZ/2, 0) < 0 &&
-		    ac97_reset_wait(ac97, HZ/2, 1) < 0) {
+		if (ac97->scaps & AC97_SCAP_SKIP_AUDIO)
+			err = ac97_reset_wait(ac97, HZ/2, 1);
+		else {
+			err = ac97_reset_wait(ac97, HZ/2, 0);
+			if (err < 0)
+				err = ac97_reset_wait(ac97, 0, 1);
+		}
+		if (err < 0) {
 			snd_printk(KERN_WARNING "AC'97 %d does not respond - RESET\n", ac97->num);
 			/* proceed anyway - it's often non-critical */
 		}
@@ -1803,20 +1869,6 @@
 		snd_ac97_free(ac97);
 		return -EIO;
 	}
-	/* AC97 audio codec chip revision detection. */
-	/* Currently only Realtek ALC650 detection implemented. */
-	switch(ac97->id & 0xfffffff0) {
-	case 0x414c4720:        /* ALC650 */
-		reg = snd_ac97_read(ac97, AC97_ALC650_REVISION);
-		if (((reg & 0x3f) >= 0) && ((reg & 0x3f) < 3))
-			ac97->id = 0x414c4720;          /* Old version */
-		else if (((reg & 0x3f) >= 3) && ((reg & 0x3f) < 0x10))
-			ac97->id = 0x414c4721;          /* D version */
-		else if ((reg&0x30) == 0x10)
-			ac97->id = 0x414c4722;          /* E version */
-		else if ((reg&0x30) == 0x20)
-			ac97->id = 0x414c4723;          /* F version */
-        }
 	
 	/* test for AC'97 */
 	if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO) && !(ac97->scaps & AC97_SCAP_AUDIO)) {
@@ -1865,9 +1917,9 @@
 			if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
 				goto __ready_ok;
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ/10);
+			schedule_timeout(1);
 		} while (time_after_eq(end_time, jiffies));
-		snd_printk(KERN_ERR "AC'97 %d analog subsections not ready\n", ac97->num);
+		snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
 	}
 
 	/* FIXME: add powerdown control */
@@ -1898,9 +1950,9 @@
 			if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
 				goto __ready_ok;
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ/10);
+			schedule_timeout(1);
 		} while (time_after_eq(end_time, jiffies));
-		snd_printk(KERN_ERR "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
+		snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
 	}
 	
       __ready_ok:
@@ -1919,12 +1971,7 @@
 	}
 	if (ac97->ext_id & AC97_EI_SPDIF) {
 		/* codec specific code (patch) should override these values */
-		if (ac97->flags & AC97_CS_SPDIF)
-			ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100;
-		else if (ac97->id == AC97_ID_CM9739)
-			ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
-		else
-			ac97->rates[AC97_RATES_SPDIF] = snd_ac97_determine_spdif_rates(ac97);
+		ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_32000;
 	}
 	if (ac97->ext_id & AC97_EI_VRM) {	/* MIC VRA support */
 		snd_ac97_determine_rates(ac97, AC97_PCM_MIC_ADC_RATE, 0, &ac97->rates[AC97_RATES_MIC_ADC]);
@@ -1942,8 +1989,8 @@
 	/* additional initializations */
 	if (bus->init)
 		bus->init(ac97);
-	snd_ac97_get_name(ac97, ac97->id, name, 0);
-	snd_ac97_get_name(NULL, ac97->id, name, 0);  // ac97->id might be changed in the special setup code
+	snd_ac97_get_name(ac97, ac97->id, name, !ac97_is_audio(ac97));
+	snd_ac97_get_name(NULL, ac97->id, name, !ac97_is_audio(ac97));  // ac97->id might be changed in the special setup code
 	if (ac97_is_audio(ac97)) {
 		if (card->mixername[0] == '\0') {
 			strcpy(card->mixername, name);
@@ -2066,18 +2113,28 @@
 	snd_ac97_write(ac97, AC97_GENERAL_PURPOSE, 0);
 
 	snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
-	ac97->bus->write(ac97, AC97_MASTER, 0x8101);
-	for (i = 0; i < 10; i++) {
-		if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
-			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-	}
-	/* FIXME: extra delay */
-	ac97->bus->write(ac97, AC97_MASTER, 0x8000);
-	if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/4);
+	if (ac97_is_audio(ac97)) {
+		ac97->bus->write(ac97, AC97_MASTER, 0x8101);
+		for (i = HZ/10; i >= 0; i--) {
+			if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
+				break;
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		}
+		/* FIXME: extra delay */
+		ac97->bus->write(ac97, AC97_MASTER, 0x8000);
+		if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) {
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(HZ/4);
+		}
+	} else {
+		for (i = HZ/10; i >= 0; i--) {
+			unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
+			if (val != 0xffff && (val & 1) != 0)
+				break;
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		}
 	}
 __reset_ready:
 
@@ -2151,42 +2208,57 @@
 
 /*
  */
-int snd_ac97_remove_ctl(ac97_t *ac97, const char *name)
+static void set_ctl_name(char *dst, const char *src, const char *suffix)
+{
+	if (suffix)
+		sprintf(dst, "%s %s", src, suffix);
+	else
+		strcpy(dst, src);
+}	
+
+int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix)
 {
 	snd_ctl_elem_id_t id;
 	memset(&id, 0, sizeof(id));
-	strcpy(id.name, name);
+	set_ctl_name(id.name, name, suffix);
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_remove_id(ac97->bus->card, &id);
 }
 
-static snd_kcontrol_t *ctl_find(ac97_t *ac97, const char *name)
+static snd_kcontrol_t *ctl_find(ac97_t *ac97, const char *name, const char *suffix)
 {
 	snd_ctl_elem_id_t sid;
 	memset(&sid, 0, sizeof(sid));
-	strcpy(sid.name, name);
+	set_ctl_name(sid.name, name, suffix);
 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_find_id(ac97->bus->card, &sid);
 }
 
-int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst)
+int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix)
 {
-	snd_kcontrol_t *kctl = ctl_find(ac97, src);
+	snd_kcontrol_t *kctl = ctl_find(ac97, src, suffix);
 	if (kctl) {
-		strcpy(kctl->id.name, dst);
+		set_ctl_name(kctl->id.name, dst, suffix);
 		return 0;
 	}
 	return -ENOENT;
 }
 
-int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2)
+/* rename both Volume and Switch controls - don't check the return value */
+void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst)
+{
+	snd_ac97_rename_ctl(ac97, src, dst, "Switch");
+	snd_ac97_rename_ctl(ac97, src, dst, "Volume");
+}
+
+int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix)
 {
 	snd_kcontrol_t *kctl1, *kctl2;
-	kctl1 = ctl_find(ac97, s1);
-	kctl2 = ctl_find(ac97, s2);
+	kctl1 = ctl_find(ac97, s1, suffix);
+	kctl2 = ctl_find(ac97, s2, suffix);
 	if (kctl1 && kctl2) {
-		strcpy(kctl1->id.name, s2);
-		strcpy(kctl2->id.name, s1);
+		set_ctl_name(kctl1->id.name, s2, suffix);
+		set_ctl_name(kctl2->id.name, s1, suffix);
 		return 0;
 	}
 	return -ENOENT;
@@ -2194,26 +2266,22 @@
 
 static int swap_headphone(ac97_t *ac97, int remove_master)
 {
-	/* FIXME: error checks.. */
 	if (remove_master) {
-		if (ctl_find(ac97, "Headphone Playback Switch") == NULL)
+		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 {
-		snd_ac97_rename_ctl(ac97, "Master Playback Switch", "Line-Out Playback Switch");
-		snd_ac97_rename_ctl(ac97, "Master Playback Volume", "Line-Out Playback Volume");
-	}
-	snd_ac97_rename_ctl(ac97, "Headphone Playback Switch", "Master Playback Switch");
-	snd_ac97_rename_ctl(ac97, "Headphone Playback Volume", "Master Playback Volume");
+		snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
+		snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
+	} else
+		snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Line-Out Playback");
+	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
 	return 0;
 }
 
 static int swap_surround(ac97_t *ac97)
 {
 	/* FIXME: error checks.. */
-	snd_ac97_swap_ctl(ac97, "Master Playback Switch", "Surround Playback Switch");
-	snd_ac97_swap_ctl(ac97, "Master Playback Volume", "Surround Playback Volume");
+	snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch");
+	snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume");
 	return 0;
 }
 
diff -Nru a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
--- a/sound/pci/ac97/ac97_id.h	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ac97/ac97_id.h	2004-06-02 23:31:42 -07:00
@@ -45,7 +45,14 @@
 #define AC97_ID_CS4201		0x43525948
 #define AC97_ID_CS4205		0x43525958
 #define AC97_ID_CS_MASK		0xfffffff8	/* bit 0-2: rev */
+#define AC97_ID_ALC100		0x414c4300
 #define AC97_ID_ALC650		0x414c4720
+#define AC97_ID_ALC650D		0x414c4721
+#define AC97_ID_ALC650E		0x414c4722
+#define AC97_ID_ALC650F		0x414c4723
+#define AC97_ID_ALC655		0x414c4760
+#define AC97_ID_ALC658		0x414c4780
+#define AC97_ID_ALC850		0x414c4790
 #define AC97_ID_YMF753		0x594d4803
 #define AC97_ID_VT1616		0x49434551
 #define AC97_ID_CM9738		0x434d4941
diff -Nru a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
--- a/sound/pci/ac97/ac97_local.h	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ac97/ac97_local.h	2004-06-02 23:31:42 -07:00
@@ -23,10 +23,15 @@
  */
 
 #define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
+#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24) | ((page) << 25))
 #define AC97_SINGLE(xname, reg, shift, mask, invert) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_single, \
   .get = snd_ac97_get_single, .put = snd_ac97_put_single, \
   .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
+#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)		\
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_single, \
+  .get = snd_ac97_page_get_single, .put = snd_ac97_page_put_single, \
+  .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
 
 /* ac97_codec.c */
 extern const char *snd_ac97_stereo_enhancements[];
@@ -37,10 +42,13 @@
 int snd_ac97_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
 int snd_ac97_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
 int snd_ac97_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ac97_page_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ac97_page_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
 int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit);
-int snd_ac97_remove_ctl(ac97_t *ac97, const char *name);
-int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst);
-int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2);
+int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix);
+int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix);
+int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix);
+void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
 
 /* ac97_proc.c */
 void snd_ac97_bus_proc_init(ac97_bus_t * ac97);
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ac97/ac97_patch.c	2004-06-02 23:31:42 -07:00
@@ -51,6 +51,21 @@
 	return 0;
 }
 
+/* set to the page, update bits and restore the page */
+static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
+{
+	unsigned short page_save;
+	int ret;
+
+	down(&ac97->mutex);
+	page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
+	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
+	ret = snd_ac97_update_bits(ac97, reg, mask, value);
+	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
+	up(&ac97->mutex); /* unlock paging */
+	return ret;
+}
+
 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
 
 /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */
@@ -204,7 +219,7 @@
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
 		return err;
 	strcpy(kctl->id.name, "3D Control - Wide");
-	kctl->private_value = AC97_3D_CONTROL | (9 << 8) | (7 << 16);
+	kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
 	snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
 	if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_ymf753_controls_speaker, ac97))) < 0)
 		return err;
@@ -315,7 +330,7 @@
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
 		return err;
 	strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
-	kctl->private_value = AC97_3D_CONTROL | (3 << 16);
+	kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
 	snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
 	return 0;
 }
@@ -328,11 +343,11 @@
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
 		return err;
 	strcpy(kctl->id.name, "3D Control Sigmatel - Depth");
-	kctl->private_value = AC97_3D_CONTROL | (3 << 16);
+	kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 0, 3, 0);
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
 		return err;
 	strcpy(kctl->id.name, "3D Control Sigmatel - Rear Depth");
-	kctl->private_value = AC97_3D_CONTROL | (2 << 8) | (3 << 16);
+	kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 2, 3, 0);
 	snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
 	return 0;
 }
@@ -373,17 +388,23 @@
 	.build_specific	= patch_sigmatel_stac97xx_specific
 };
 
-static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
-	.build_3d	= patch_sigmatel_stac9708_3d,
-	.build_specific	= patch_sigmatel_stac97xx_specific
-};
-
 int patch_sigmatel_stac9700(ac97_t * ac97)
 {
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
 	return 0;
 }
 
+static int patch_sigmatel_stac9708_specific(ac97_t *ac97)
+{
+	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
+	return patch_sigmatel_stac97xx_specific(ac97);
+}
+
+static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
+	.build_3d	= patch_sigmatel_stac9708_3d,
+	.build_specific	= patch_sigmatel_stac9708_specific
+};
+
 int patch_sigmatel_stac9708(ac97_t * ac97)
 {
 	unsigned int codec72, codec6c;
@@ -467,11 +488,11 @@
 	int shift = kcontrol->private_value;
 	unsigned short val;
 
-	val = ac97->regs[AC97_SIGMATEL_OUTSEL];
-	if (!((val >> shift) & 4))
+	val = ac97->regs[AC97_SIGMATEL_OUTSEL] >> shift;
+	if (!(val & 4))
 		ucontrol->value.enumerated.item[0] = 0;
 	else
-		ucontrol->value.enumerated.item[0] = 1 + ((val >> shift) & 3);
+		ucontrol->value.enumerated.item[0] = 1 + (val & 3);
 	return 0;
 }
 
@@ -480,6 +501,7 @@
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value;
 	unsigned short val;
+	int ret;
 
 	if (ucontrol->value.enumerated.item[0] > 4)
 		return -EINVAL;
@@ -487,8 +509,10 @@
 		val = 0;
 	else
 		val = 4 | (ucontrol->value.enumerated.item[0] - 1);
-	return snd_ac97_update_bits(ac97, AC97_SIGMATEL_OUTSEL,
-				    7 << shift, val << shift);
+	ret = snd_ac97_update_bits(ac97, AC97_SIGMATEL_OUTSEL,
+				   7 << shift, val << shift);
+	up(&ac97->mutex);
+	return ret;
 }
 
 static int snd_ac97_stac9758_input_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
@@ -521,8 +545,8 @@
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value;
 
-	return snd_ac97_update_bits(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
-				    ucontrol->value.enumerated.item[0] << shift);
+	return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
+				     ucontrol->value.enumerated.item[0] << shift, 0);
 }
 
 static int snd_ac97_stac9758_phonesel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
@@ -550,8 +574,8 @@
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 
-	return snd_ac97_update_bits(ac97, AC97_SIGMATEL_IOMISC, 3,
-				    ucontrol->value.enumerated.item[0]);
+	return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3,
+				     ucontrol->value.enumerated.item[0], 0);
 }
 
 #define STAC9758_OUTPUT_JACK(xname, shift) \
@@ -596,6 +620,14 @@
 				   ARRAY_SIZE(snd_ac97_sigmatel_stac9758_controls));
 	if (err < 0)
 		return err;
+	/* DAC-A direct */
+	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Front Playback");
+	/* DAC-A to Mix = PCM */
+	/* DAC-B direct = Surround */
+	/* DAC-B to Mix */
+	snd_ac97_rename_vol_ctl(ac97, "Video Playback", "Surround Mix Playback");
+	/* DAC-C direct = Center/LFE */
+
 	return 0;
 }
 
@@ -613,16 +645,16 @@
 		AC97_SIGMATEL_VARIOUS
 	};
 	static unsigned short def_regs[4] = {
-		/* OUTSEL */ 0xd794,
+		/* OUTSEL */ 0xd794, /* CL:CL, SR:SR, LO:MX, LI:DS, MI:DS */
 		/* IOMISC */ 0x2001,
-		/* INSEL */ 0x0201,
+		/* INSEL */ 0x0201, /* LI:LI, MI:M1 */
 		/* VARIOUS */ 0x0040
 	};
 	static unsigned short m675_regs[4] = {
-		/* OUTSEL */ 0x9040,
-		/* IOMISC */ 0x2102,
-		/* INSEL */ 0x0203,
-		/* VARIOUS */ 0x0041
+		/* OUTSEL */ 0xfc70, /* CL:MX, SR:MX, LO:DS, LI:MX, MI:DS */
+		/* IOMISC */ 0x2102, /* HP amp on */
+		/* INSEL */ 0x0203, /* LI:LI, MI:FR */
+		/* VARIOUS */ 0x0041 /* stereo mic */
 	};
 	unsigned short *pregs = def_regs;
 	int i;
@@ -635,6 +667,8 @@
 
 	// patch for SigmaTel
 	ac97->build_ops = &patch_sigmatel_stac9758_ops;
+	/* FIXME: assume only page 0 for writing cache */
+	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
 	for (i = 0; i < 4; i++)
 		snd_ac97_write_cache(ac97, regs[i], pregs[i]);
 
@@ -654,8 +688,10 @@
 {
 	int err;
 
+	/* con mask, pro mask, default */
 	if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
 		return err;
+	/* switch, spsa */
 	if ((err = patch_build_controls(ac97, &snd_ac97_cirrus_controls_spdif[0], 1)) < 0)
 		return err;
 	switch (ac97->id & AC97_ID_CS_MASK) {
@@ -714,8 +750,10 @@
 {
 	int err;
 
+	/* con mask, pro mask, default */
 	if ((err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3)) < 0)
 		return err;
+	/* switch */
 	if ((err = patch_build_controls(ac97, &snd_ac97_conexant_controls_spdif[0], 1)) < 0)
 		return err;
 	/* set default PCM S/PDIF params */
@@ -734,6 +772,7 @@
 	ac97->build_ops = &patch_conexant_ops;
 	ac97->flags |= AC97_CX_SPDIF;
         ac97->ext_id |= AC97_EI_SPDIF;	/* force the detection of spdif */
+	ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
 	return 0;
 }
 
@@ -821,8 +860,6 @@
 	unsigned short val;
 	int idx, num;
 
-	init_MUTEX(&ac97->spec.ad18xx.mutex);
-
 	val = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
 	snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, val);
 	codecs[0] = patch_ad1881_unchained(ac97, 0, (1<<12));
@@ -1114,10 +1151,8 @@
 static int patch_ad1888_specific(ac97_t *ac97)
 {
 	/* rename 0x04 as "Master" and 0x02 as "Master Surround" */
-	snd_ac97_rename_ctl(ac97, "Master Playback Switch", "Master Surround Playback Switch");
-	snd_ac97_rename_ctl(ac97, "Master Playback Volume", "Master Surround Playback Volume");
-	snd_ac97_rename_ctl(ac97, "Headphone Playback Switch", "Master Playback Switch");
-	snd_ac97_rename_ctl(ac97, "Headphone Playback Volume", "Master Playback Volume");
+	snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback");
+	snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
 	return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
 }
 
@@ -1213,7 +1248,7 @@
 }
 
 /*
- * realtek ALC65x codecs
+ * realtek ALC65x/850 codecs
  */
 static int snd_ac97_alc650_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
@@ -1303,6 +1338,17 @@
 
 	ac97->build_ops = &patch_alc650_ops;
 
+	/* determine the revision */
+	val = snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f;
+	if (val < 3)
+		ac97->id = 0x414c4720;          /* Old version */
+	else if (val < 0x10)
+		ac97->id = 0x414c4721;          /* D version */
+	else if (val < 0x20)
+		ac97->id = 0x414c4722;          /* E version */
+	else if (val < 0x30)
+		ac97->id = 0x414c4723;          /* F version */
+
 	/* revision E or F */
 	/* FIXME: what about revision D ? */
 	ac97->spec.dev_flags = (ac97->id == 0x414c4722 ||
@@ -1351,20 +1397,19 @@
 static int snd_ac97_alc655_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
         ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-        int change;
 
 	/* misc control; vrefout disable */
 	snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
 			     ucontrol->value.integer.value[0] ? (1 << 12) : 0);
-	change = snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
-				      ucontrol->value.integer.value[0] ? (1 << 10) : 0);
-	return change;
+	return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
+				     ucontrol->value.integer.value[0] ? (1 << 10) : 0,
+				     0);
 }
 
 
 static const snd_kcontrol_new_t snd_ac97_controls_alc655[] = {
-	AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
-	AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0),
+	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
+	AC97_PAGE_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0, 0),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Mic As Center/LFE",
@@ -1391,7 +1436,6 @@
 	       texts_658[uinfo->value.enumerated.item] :
 	       texts_655[uinfo->value.enumerated.item]);
 	return 0;
-
 }
 
 static int alc655_iec958_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
@@ -1410,13 +1454,15 @@
 static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	return snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 3 << 12,
-				    (unsigned short)ucontrol->value.enumerated.item[0]);
+
+	return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
+				     (unsigned short)ucontrol->value.enumerated.item[0],
+				     0);
 }
 
 static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = {
-        AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0),
-        AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0),
+        AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0),
+        AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0),
 	{
 		.iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name   = "IEC958 Playback Route",
@@ -1451,6 +1497,9 @@
 
 	ac97->build_ops = &patch_alc655_ops;
 
+	/* assume only page 0 for writing cache */
+	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
+
 	/* adjust default values */
 	val = snd_ac97_read(ac97, 0x7a); /* misc control */
 	val |= (1 << 1); /* spdif input pin */
@@ -1469,6 +1518,120 @@
 	return 0;
 }
 
+
+#define AC97_ALC850_JACK_SELECT	0x76
+#define AC97_ALC850_MISC1	0x7a
+
+static int ac97_alc850_surround_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+        ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 12) & 7) == 2;
+        return 0;
+}
+
+static int ac97_alc850_surround_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+
+	/* SURR 1kOhm (bit4), Amp (bit5) */
+	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
+			     ucontrol->value.integer.value[0] ? (1<<5) : (1<<4));
+	/* LINE-IN = 0, SURROUND = 2 */
+	return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
+				    ucontrol->value.integer.value[0] ? (2<<12) : (0<<12));
+}
+
+static int ac97_alc850_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+        ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 4) & 7) == 2;
+        return 0;
+}
+
+static int ac97_alc850_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+
+	/* Vref disable (bit12), 1kOhm (bit13) */
+	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
+			     ucontrol->value.integer.value[0] ? (1<<12) : (1<<13));
+	/* MIC-IN = 1, CENTER-LFE = 2 */
+	return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
+				    ucontrol->value.integer.value[0] ? (2<<4) : (1<<4));
+}
+
+static const snd_kcontrol_new_t snd_ac97_controls_alc850[] = {
+	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Line-In As Surround",
+		.info = snd_ac97_info_single,
+		.get = ac97_alc850_surround_get,
+		.put = ac97_alc850_surround_put,
+		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Mic As Center/LFE",
+		.info = snd_ac97_info_single,
+		.get = ac97_alc850_mic_get,
+		.put = ac97_alc850_mic_put,
+		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
+	},
+
+};
+
+static int patch_alc850_specific(ac97_t *ac97)
+{
+	int err;
+
+	if ((err = patch_build_controls(ac97, snd_ac97_controls_alc850, ARRAY_SIZE(snd_ac97_controls_alc850))) < 0)
+		return err;
+	if (ac97->ext_id & AC97_EI_SPDIF) {
+		if ((err = patch_build_controls(ac97, snd_ac97_spdif_controls_alc655, ARRAY_SIZE(snd_ac97_spdif_controls_alc655))) < 0)
+			return err;
+	}
+	return 0;
+}
+
+static struct snd_ac97_build_ops patch_alc850_ops = {
+	.build_specific	= patch_alc850_specific
+};
+
+int patch_alc850(ac97_t *ac97)
+{
+	ac97->build_ops = &patch_alc850_ops;
+
+	ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */
+
+	/* assume only page 0 for writing cache */
+	snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
+
+	/* adjust default values */
+	/* set default: spdif-in enabled,
+	   spdif-in monitor off, spdif-in PCM off
+	   center on mic off, surround on line-in off
+	   duplicate front off
+	*/
+	snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
+	/* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
+	 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
+	 */
+	snd_ac97_write_cache(ac97, 0x7a, (1<<1)|(1<<4)|(0<<5)|(1<<6)|
+			     (1<<7)|(0<<12)|(1<<13)|(0<<14));
+	/* detection UIO2,3: all path floating, UIO3: MIC, Vref2: disable,
+	 * UIO1: FRONT, Vref3: disable, UIO3: LINE, Front-Mic: mute
+	 */
+	snd_ac97_write_cache(ac97, 0x76, (0<<0)|(0<<2)|(1<<4)|(1<<7)|(2<<8)|
+			     (1<<11)|(0<<12)|(1<<15));
+
+	/* full DAC volume */
+	snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
+	snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
+	return 0;
+}
+
+
 /*
  * C-Media CM97xx codecs
  */
@@ -1599,8 +1762,10 @@
 		/* enable spdif in */
 		snd_ac97_write_cache(ac97, AC97_CM9739_SPDIF_CTRL,
 				     snd_ac97_read(ac97, AC97_CM9739_SPDIF_CTRL) | 0x01);
+		ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
 	} else {
 		ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */
+		ac97->rates[AC97_RATES_SPDIF] = 0;
 	}
 
 	/* set-up multi channel */
diff -Nru a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
--- a/sound/pci/ac97/ac97_patch.h	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ac97/ac97_patch.h	2004-06-02 23:31:42 -07:00
@@ -49,6 +49,7 @@
 int patch_ad1985(ac97_t * ac97);
 int patch_alc650(ac97_t * ac97);
 int patch_alc655(ac97_t * ac97);
+int patch_alc850(ac97_t * ac97);
 int patch_cm9738(ac97_t * ac97);
 int patch_cm9739(ac97_t * ac97);
 int patch_vt1616(ac97_t * ac97);
diff -Nru a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
--- a/sound/pci/ac97/ac97_proc.c	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ac97/ac97_proc.c	2004-06-02 23:31:42 -07:00
@@ -292,9 +292,9 @@
 {
 	ac97_t *ac97 = snd_magic_cast(ac97_t, entry->private_data, return);
 	
+	down(&ac97->mutex);
 	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86
 		int idx;
-		down(&ac97->spec.ad18xx.mutex);
 		for (idx = 0; idx < 3; idx++)
 			if (ac97->spec.ad18xx.id[idx]) {
 				/* select single codec */
@@ -305,7 +305,6 @@
 			}
 		/* select all codecs */
 		snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
-		up(&ac97->spec.ad18xx.mutex);
 		
 		snd_iprintf(buffer, "\nAD18XX configuration\n");
 		snd_iprintf(buffer, "Unchained        : 0x%04x,0x%04x,0x%04x\n",
@@ -319,6 +318,7 @@
 	} else {
 		snd_ac97_proc_read_main(ac97, buffer, 0);
 	}
+	up(&ac97->mutex);
 }
 
 #ifdef CONFIG_SND_DEBUG
@@ -328,6 +328,7 @@
 	ac97_t *ac97 = snd_magic_cast(ac97_t, entry->private_data, return);
 	char line[64];
 	unsigned int reg, val;
+	down(&ac97->mutex);
 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
 		if (sscanf(line, "%x %x", &reg, &val) != 2)
 			continue;
@@ -335,6 +336,7 @@
 		if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
 			snd_ac97_write_cache(ac97, reg, val);
 	}
+	up(&ac97->mutex);
 }
 #endif
 
@@ -353,10 +355,10 @@
 {
 	ac97_t *ac97 = snd_magic_cast(ac97_t, entry->private_data, return);
 
+	down(&ac97->mutex);
 	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86
 
 		int idx;
-		down(&ac97->spec.ad18xx.mutex);
 		for (idx = 0; idx < 3; idx++)
 			if (ac97->spec.ad18xx.id[idx]) {
 				/* select single codec */
@@ -366,10 +368,10 @@
 			}
 		/* select all codecs */
 		snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x7000, 0x7000);
-		up(&ac97->spec.ad18xx.mutex);
 	} else {
 		snd_ac97_proc_regs_read_main(ac97, buffer, 0);
 	}	
+	up(&ac97->mutex);
 }
 
 void snd_ac97_proc_init(ac97_t * ac97)
diff -Nru a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/atiixp.c	2004-06-02 23:31:42 -07:00
@@ -1,5 +1,5 @@
 /*
- *   ALSA driver for ATI IXP 150/200/250 AC97 controllers
+ *   ALSA driver for ATI IXP 150/200/250/300 AC97 controllers
  *
  *	Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
  *
@@ -1387,17 +1387,9 @@
 		ac97.num = i;
 		ac97.scaps = AC97_SCAP_SKIP_MODEM;
 		if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
-			if (chip->codec_not_ready_bits)
-				/* codec(s) was detected but not available.
-				 * return the error
-				 */
-				return err;
-			else {
-				/* codec(s) was NOT detected, so just ignore here */
-				chip->ac97[i] = NULL; /* to be sure */
-				snd_printd("atiixp: codec %d not found\n", i);
-				continue;
-			}
+			chip->ac97[i] = NULL; /* to be sure */
+			snd_printdd("atiixp: codec %d not available for audio\n", i);
+			continue;
 		}
 		codec_count++;
 	}
diff -Nru a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
--- a/sound/pci/ice1712/Makefile	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ice1712/Makefile	2004-06-02 23:31:42 -07:00
@@ -5,7 +5,7 @@
 
 snd-ice17xx-ak4xxx-objs := ak4xxx.o
 snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o
+snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
diff -Nru a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
--- a/sound/pci/ice1712/ice1724.c	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/ice1712/ice1724.c	2004-06-02 23:31:42 -07:00
@@ -44,6 +44,7 @@
 #include "amp.h"
 #include "revo.h"
 #include "aureon.h"
+#include "vt1720_mobo.h"
 
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -54,6 +55,7 @@
 	       REVO_DEVICE_DESC
 	       AMP_AUDIO2000_DEVICE_DESC
 	       AUREON_DEVICE_DESC
+	       VT1720_MOBO_DEVICE_DESC
 		"{VIA,VT1720},"
 		"{VIA,VT1724},"
 		"{ICEnsemble,Generic ICE1724},"
@@ -419,7 +421,7 @@
 	ice->cur_rate = rate;
 
 	/* check MT02 */
-	if (ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) {
+	if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
 		val = old = inb(ICEMT1724(ice, I2S_FORMAT));
 		if (rate > 96000)
 			val |= VT1724_MT_I2S_MCLK_128X; /* 128x MCLK */
@@ -446,15 +448,6 @@
 		if (ice->akm[i].ops.set_rate_val)
 			ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
 	}
-
-	/* set up AC97 registers if needed */
-	if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) && ice->ac97) {
-		snd_ac97_set_rate(ice->ac97, AC97_PCM_FRONT_DAC_RATE, rate);
-		snd_ac97_set_rate(ice->ac97, AC97_PCM_SURR_DAC_RATE, rate);
-		snd_ac97_set_rate(ice->ac97, AC97_PCM_LFE_DAC_RATE, rate);
-		snd_ac97_set_rate(ice->ac97, AC97_SPDIF, rate);
-		snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, rate);
-	}
 }
 
 static int snd_vt1724_pcm_hw_params(snd_pcm_substream_t * substream,
@@ -698,7 +691,7 @@
 static int set_rate_constraints(ice1712_t *ice, snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	if (ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) {
+	if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
 		/* I2S */
 		if (ice->eeprom.data[ICE_EEP2_I2S] & 0x08)
 			return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192);
@@ -714,15 +707,9 @@
 			ratec = AC97_RATES_FRONT_DAC;
 		else
 			ratec = AC97_RATES_ADC;
-		runtime->hw.rates = ice->ac97->rates[ratec];
 		runtime->hw.rate_max = 48000;
-		if (runtime->hw.rates == SNDRV_PCM_RATE_48000) {
-			runtime->hw.rate_min = 48000;
-			return 0;
-		} else {
-			runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000;
-			return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_48);
-		}
+		runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000;
+		return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_48);
 	}
 	return 0;
 }
@@ -1815,6 +1802,7 @@
 	snd_vt1724_revo_cards,
 	snd_vt1724_amp_cards, 
 	snd_vt1724_aureon_cards,
+	snd_vt1720_mobo_cards,
 	0,
 };
 
@@ -1929,9 +1917,6 @@
 	snd_vt1724_set_gpio_data(ice, ice->eeprom.gpiostate);
 
 	outb(0, ICEREG1724(ice, POWERDOWN));
-
-	/* read back to check the availability of SPDIF out */
-	ice->eeprom.data[ICE_EEP2_SPDIF] = inb(ICEREG1724(ice, SPDIF_CFG));
 
 	return 0;
 }
diff -Nru a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ice1712/vt1720_mobo.c	2004-06-02 23:31:42 -07:00
@@ -0,0 +1,97 @@
+/*
+ *   ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
+ *
+ *   Lowlevel functions for VT1720-based motherboards
+ *
+ *	Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */      
+
+#include <sound/driver.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+
+#include "ice1712.h"
+#include "vt1720_mobo.h"
+
+
+static int __devinit k8x800_init(ice1712_t *ice)
+{
+	ice->vt1720 = 1;
+
+	/* VT1616 codec */
+	ice->num_total_dacs = 6;
+	ice->num_total_adcs = 2;
+
+	/* WM8728 codec */
+	/* FIXME: TODO */
+
+	return 0;
+}
+
+static int __devinit k8x800_add_controls(ice1712_t *ice)
+{
+	/* FIXME: needs some quirks for VT1616? */
+	return 0;
+}
+
+/* EEPROM image */
+
+static unsigned char k8x800_eeprom[] __devinitdata = {
+	0x01,	/* SYSCONF: clock 256, 1ADC, 2DACs */
+	0x02,	/* ACLINK: ACLINK, packed */
+	0x00,	/* I2S: - */
+	0x00,	/* SPDIF: - */
+	0xff,	/* GPIO_DIR */
+	0xff,	/* GPIO_DIR1 */
+	0x00,	/* - */
+	0xff,	/* GPIO_MASK */
+	0xff,	/* GPIO_MASK1 */
+	0x00,	/* - */
+	0x00,	/* GPIO_STATE */
+	0x00,	/* GPIO_STATE1 */
+	0x00,	/* - */
+};
+
+
+/* entry point */
+struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
+	{
+		.subvendor = VT1720_SUBDEVICE_K8X800,
+		.name = "Albatron K8X800 Pro II",
+		.model = "k8x800",
+		.chip_init = k8x800_init,
+		.build_controls = k8x800_add_controls,
+		.eeprom_size = sizeof(k8x800_eeprom),
+		.eeprom_data = k8x800_eeprom,
+	},
+	{
+		.subvendor = VT1720_SUBDEVICE_ZNF3_150,
+		.name = "Chaintech ZNF3-150",
+		/* identical with k8x800 */
+		.chip_init = k8x800_init,
+		.build_controls = k8x800_add_controls,
+		.eeprom_size = sizeof(k8x800_eeprom),
+		.eeprom_data = k8x800_eeprom,
+	},
+	{ } /* terminator */
+};
+
diff -Nru a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/sound/pci/ice1712/vt1720_mobo.h	2004-06-02 23:31:42 -07:00
@@ -0,0 +1,35 @@
+#ifndef __SOUND_VT1720_MOBO_H
+#define __SOUND_VT1720_MOBO_H
+
+/*
+ *   ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
+ *
+ *   Lowlevel functions for VT1720-based motherboards
+ *
+ *	Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */      
+
+#define VT1720_MOBO_DEVICE_DESC        "{Albatron,K8X800 Pro II},"\
+				       "{Chaintech,ZNF3-150},"
+
+#define VT1720_SUBDEVICE_K8X800		0xf217052c
+#define VT1720_SUBDEVICE_ZNF3_150	0x0f2741f6
+
+extern struct snd_ice1712_card_info  snd_vt1720_mobo_cards[];
+
+#endif /* __SOUND_VT1720_MOBO_H */
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	2004-06-02 23:31:42 -07:00
+++ b/sound/pci/via82xx.c	2004-06-02 23:31:42 -07:00
@@ -1060,19 +1060,6 @@
 	int err;
 	unsigned long flags;
 	struct via_rate_lock *ratep;
-	struct ratetbl {
-		int rate;
-		unsigned int bit;
-	} ratebits[] = {
-		{8000, SNDRV_PCM_RATE_8000},
-		{11025, SNDRV_PCM_RATE_11025},
-		{16000, SNDRV_PCM_RATE_16000},
-		{22050, SNDRV_PCM_RATE_22050},
-		{32000, SNDRV_PCM_RATE_32000},
-		{44100, SNDRV_PCM_RATE_44100},
-		{48000, SNDRV_PCM_RATE_48000},
-	};
-	int i;
 
 	runtime->hw = snd_via82xx_hw;
 	
@@ -1080,10 +1067,10 @@
 	ratep = &chip->rates[viadev->direction];
 	spin_lock_irqsave(&ratep->lock, flags);
 	ratep->used++;
-	if (chip->spdif_on) {
-		runtime->hw.rates = SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000;
-		runtime->hw.rate_min = 32000;
-		runtime->hw.rate_max = 48000;
+	if (chip->spdif_on && viadev->reg_offset == 0x30) {
+		/* DXS#3 and spdif is on */
+		runtime->hw.rates = chip->ac97->rates[AC97_RATES_SPDIF];
+		snd_pcm_limit_hw_rates(runtime);
 	} else if (chip->dxs_fixed && viadev->reg_offset < 0x40) {
 		/* fixed DXS playback rate */
 		runtime->hw.rates = SNDRV_PCM_RATE_48000;
@@ -1091,27 +1078,10 @@
 	} else if (! ratep->rate) {
 		int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
 		runtime->hw.rates = chip->ac97->rates[idx];
-		for (i = 0; i < (int)ARRAY_SIZE(ratebits); i++) {
-			if (runtime->hw.rates & ratebits[i].bit) {
-				runtime->hw.rate_min = ratebits[i].rate;
-				break;
-			}
-		}
-		for (i = ARRAY_SIZE(ratebits) - 1; i >= 0; i--) {
-			if (runtime->hw.rates & ratebits[i].bit) {
-				runtime->hw.rate_max = ratebits[i].rate;
-				break;
-			}
-		}
+		snd_pcm_limit_hw_rates(runtime);
 	} else {
 		/* a fixed rate */
 		runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
-		for (i = 0; i < (int)ARRAY_SIZE(ratebits); i++) {
-			if (ratep->rate == ratebits[i].rate) {
-				runtime->hw.rates = ratebits[i].bit;
-				break;
-			}
-		}
 		runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate;
 	}
 	spin_unlock_irqrestore(&ratep->lock, flags);
@@ -1363,6 +1333,10 @@
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
 		return err;
 
+	/* SPDIF supported? */
+	if (! ac97_can_spdif(chip->ac97))
+		return 0;
+
 	/* PCM #1:  DXS3 playback (for spdif) */
 	err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 0, &pcm);
 	if (err < 0)
@@ -1660,9 +1634,11 @@
 		if (err < 0)
 			return err;
 	}
-	err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs3_spdif_control, chip));
-	if (err < 0)
-		return err;
+	if (ac97_can_spdif(chip->ac97)) {
+		err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs3_spdif_control, chip));
+		if (err < 0)
+			return err;
+	}
 	if (chip->chip_type != TYPE_VIA8233A) {
 		err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
 		if (err < 0)
@@ -1672,6 +1648,7 @@
 	/* select spdif data slot 10/11 */
 	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
 	val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
+	val &= ~VIA8233_SPDIF_DX3; /* SPDIF off as default */
 	pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val);
 
 	return 0;
@@ -2114,6 +2091,7 @@
 		{ .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
 		{ .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
 		{ .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ 
+		{ .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
 		{ .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
 		{ .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
 		{ .vendor = 0x1106, .device = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */