http://linux-sound.bkbits.net/linux-sound perex@suse.cz|ChangeSet|20040623130218|18211 perex # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/06/23 11:50:26-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/06/23 11:50:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # sound/core/seq/seq_clientmgr.c # 2004/06/23 11:50:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/sound/vx_core.h # 2004/06/23 11:50:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/sound/seq_kernel.h # 2004/06/23 11:50:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/sound/core.h # 2004/06/23 11:50:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/23 15:02:18+02:00 perex@suse.cz # ALSA CVS update # PCM Midlevel # Each of snd_pcm_hw_refine_old_user() and snd_pcm_hw_params_old_user() # consume 856 bytes of stack and can invoke deep calls via the page allocator. # # Signed-off-by: Andrew Morton # Signed-off-by: Jaroslav Kysela # # sound/core/pcm_native.c # 2004/06/01 02:57:54+02:00 perex@suse.cz +55 -18 # ALSA CVS update # D:2004/06/01 08:57:54 # C:PCM Midlevel # F:core/pcm_native.c:1.91->1.92 # L:Each of snd_pcm_hw_refine_old_user() and snd_pcm_hw_params_old_user() # L:consume 856 bytes of stack and can invoke deep calls via the page allocator. # Signed-off-by: Andrew Morton # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/06/23 13:18:33+02:00 perex@suse.cz # ALSA CVS update # CMIPCI driver # don't sleep in prepare callback # # Signed-off-by: Clemens Ladisch # # sound/pci/cmipci.c # 2004/06/23 02:38:17+02:00 perex@suse.cz +1 -1 # ALSA CVS update # D:2004/06/23 08:38:17 # C:CMIPCI driver # F:pci/cmipci.c:1.66->1.67 # L:don't sleep in prepare callback # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 13:17:12+02:00 perex@suse.cz # ALSA CVS update # PCM Midlevel,ALSA<-OSS emulation,CMIPCI driver # reduce stack usage # # Signed-off-by: Clemens Ladisch # # sound/pci/cmipci.c # 2004/06/22 11:18:41+02:00 perex@suse.cz +38 -21 # ALSA CVS update # D:2004/06/22 17:22:34 # C:PCM Midlevel,ALSA<-OSS emulation,CMIPCI driver # F:core/pcm_native.c:1.93->1.94 # F:core/oss/pcm_oss.c:1.69->1.70 # F:pci/cmipci.c:1.65->1.66 # L:reduce stack usage # Signed-off-by: Clemens Ladisch # # sound/core/pcm_native.c # 2004/06/22 11:22:34+02:00 perex@suse.cz +36 -12 # ALSA CVS update # D:2004/06/22 17:22:34 # C:PCM Midlevel,ALSA<-OSS emulation,CMIPCI driver # F:core/pcm_native.c:1.93->1.94 # F:core/oss/pcm_oss.c:1.69->1.70 # F:pci/cmipci.c:1.65->1.66 # L:reduce stack usage # Signed-off-by: Clemens Ladisch # # sound/core/oss/pcm_oss.c # 2004/06/22 11:20:43+02:00 perex@suse.cz +10 -5 # ALSA CVS update # D:2004/06/22 17:22:34 # C:PCM Midlevel,ALSA<-OSS emulation,CMIPCI driver # F:core/pcm_native.c:1.93->1.94 # F:core/oss/pcm_oss.c:1.69->1.70 # F:pci/cmipci.c:1.65->1.66 # L:reduce stack usage # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 13:15:50+02:00 perex@suse.cz # ALSA CVS update # au88x0 driver # - Fixed the wrong pointer cast on 64bit architectures. # # Signed-off-by: Andi Kleen # Signed-off-by: Takashi Iwai # # sound/pci/au88x0/au88x0_a3d.c # 2004/06/21 11:53:37+02:00 perex@suse.cz +4 -4 # ALSA CVS update # D:2004/06/21 17:53:37 # C:au88x0 driver # F:pci/au88x0/au88x0_a3d.c:1.3->1.4 # L:- Fixed the wrong pointer cast on 64bit architectures. # Signed-off-by: Andi Kleen # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:14:16+02:00 perex@suse.cz # ALSA CVS update # EMU10K1/EMU10K2 driver # Merge EFX playback and capture streams to the single device (hw:0,2). # # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/emupcm.c # 2004/06/21 11:52:18+02:00 perex@suse.cz +272 -1 # ALSA CVS update # D:2004/06/21 17:52:17 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.39->1.40 # F:pci/emu10k1/emu10k1.c:1.24->1.25 # F:pci/emu10k1/emufx.c:1.52->1.53 # F:pci/emu10k1/emupcm.c:1.25->1.26 # L:Merge EFX playback and capture streams to the single device (hw:0,2). # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/emufx.c # 2004/06/21 11:52:18+02:00 perex@suse.cz +2 -308 # ALSA CVS update # D:2004/06/21 17:52:17 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.39->1.40 # F:pci/emu10k1/emu10k1.c:1.24->1.25 # F:pci/emu10k1/emufx.c:1.52->1.53 # F:pci/emu10k1/emupcm.c:1.25->1.26 # L:Merge EFX playback and capture streams to the single device (hw:0,2). # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/emu10k1.c # 2004/06/21 11:52:18+02:00 perex@suse.cz +0 -4 # ALSA CVS update # D:2004/06/21 17:52:17 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.39->1.40 # F:pci/emu10k1/emu10k1.c:1.24->1.25 # F:pci/emu10k1/emufx.c:1.52->1.53 # F:pci/emu10k1/emupcm.c:1.25->1.26 # L:Merge EFX playback and capture streams to the single device (hw:0,2). # Signed-off-by: Takashi Iwai # # include/sound/emu10k1.h # 2004/06/21 11:52:17+02:00 perex@suse.cz +9 -0 # ALSA CVS update # D:2004/06/21 17:52:17 # C:EMU10K1/EMU10K2 driver # F:include/emu10k1.h:1.39->1.40 # F:pci/emu10k1/emu10k1.c:1.24->1.25 # F:pci/emu10k1/emufx.c:1.52->1.53 # F:pci/emu10k1/emupcm.c:1.25->1.26 # L:Merge EFX playback and capture streams to the single device (hw:0,2). # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:12:57+02:00 perex@suse.cz # ALSA CVS update # PCM Midlevel,ALSA Core,RME32 driver,RME96 driver,NM256 driver # - Fix the mmap via io_remap_page_range() on nm256, rme32 and rme96. # Added SNDRV_PCM_INFO_MMAP_IOMEM to handle this case. # - Clean up the indirect accessing on RME32/RME96 drivers. # # Signed-off-by: Takashi Iwai # # sound/pci/rme96.c # 2004/06/21 11:50:09+02:00 perex@suse.cz +14 -110 # ALSA CVS update # D:2004/06/21 17:50:08 # C:PCM Midlevel,ALSA Core,RME32 driver,RME96 driver,NM256 driver # F:core/pcm_native.c:1.92->1.93 # F:include/asound.h:1.40->1.41 # F:pci/rme32.c:1.33->1.34 # F:pci/rme96.c:1.35->1.36 # F:pci/nm256/nm256.c:1.38->1.39 # L:- Fix the mmap via io_remap_page_range() on nm256, rme32 and rme96. # L: Added SNDRV_PCM_INFO_MMAP_IOMEM to handle this case. # L:- Clean up the indirect accessing on RME32/RME96 drivers. # Signed-off-by: Takashi Iwai # # sound/pci/rme32.c # 2004/06/21 11:50:09+02:00 perex@suse.cz +16 -105 # ALSA CVS update # D:2004/06/21 17:50:08 # C:PCM Midlevel,ALSA Core,RME32 driver,RME96 driver,NM256 driver # F:core/pcm_native.c:1.92->1.93 # F:include/asound.h:1.40->1.41 # F:pci/rme32.c:1.33->1.34 # F:pci/rme96.c:1.35->1.36 # F:pci/nm256/nm256.c:1.38->1.39 # L:- Fix the mmap via io_remap_page_range() on nm256, rme32 and rme96. # L: Added SNDRV_PCM_INFO_MMAP_IOMEM to handle this case. # L:- Clean up the indirect accessing on RME32/RME96 drivers. # Signed-off-by: Takashi Iwai # # sound/pci/nm256/nm256.c # 2004/06/21 11:50:09+02:00 perex@suse.cz +6 -10 # ALSA CVS update # D:2004/06/21 17:50:08 # C:PCM Midlevel,ALSA Core,RME32 driver,RME96 driver,NM256 driver # F:core/pcm_native.c:1.92->1.93 # F:include/asound.h:1.40->1.41 # F:pci/rme32.c:1.33->1.34 # F:pci/rme96.c:1.35->1.36 # F:pci/nm256/nm256.c:1.38->1.39 # L:- Fix the mmap via io_remap_page_range() on nm256, rme32 and rme96. # L: Added SNDRV_PCM_INFO_MMAP_IOMEM to handle this case. # L:- Clean up the indirect accessing on RME32/RME96 drivers. # Signed-off-by: Takashi Iwai # # sound/core/pcm_native.c # 2004/06/21 11:50:08+02:00 perex@suse.cz +14 -0 # ALSA CVS update # D:2004/06/21 17:50:08 # C:PCM Midlevel,ALSA Core,RME32 driver,RME96 driver,NM256 driver # F:core/pcm_native.c:1.92->1.93 # F:include/asound.h:1.40->1.41 # F:pci/rme32.c:1.33->1.34 # F:pci/rme96.c:1.35->1.36 # F:pci/nm256/nm256.c:1.38->1.39 # L:- Fix the mmap via io_remap_page_range() on nm256, rme32 and rme96. # L: Added SNDRV_PCM_INFO_MMAP_IOMEM to handle this case. # L:- Clean up the indirect accessing on RME32/RME96 drivers. # Signed-off-by: Takashi Iwai # # include/sound/asound.h # 2004/06/21 11:50:08+02:00 perex@suse.cz +1 -0 # ALSA CVS update # D:2004/06/21 17:50:08 # C:PCM Midlevel,ALSA Core,RME32 driver,RME96 driver,NM256 driver # F:core/pcm_native.c:1.92->1.93 # F:include/asound.h:1.40->1.41 # F:pci/rme32.c:1.33->1.34 # F:pci/rme96.c:1.35->1.36 # F:pci/nm256/nm256.c:1.38->1.39 # L:- Fix the mmap via io_remap_page_range() on nm256, rme32 and rme96. # L: Added SNDRV_PCM_INFO_MMAP_IOMEM to handle this case. # L:- Clean up the indirect accessing on RME32/RME96 drivers. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:11:34+02:00 perex@suse.cz # ALSA CVS update # USB generic driver # handle devices that allow setting but not reading sample rate # # Signed-off-by: Clemens Ladisch # # sound/usb/usbaudio.c # 2004/06/21 09:45:12+02:00 perex@suse.cz +2 -2 # ALSA CVS update # D:2004/06/21 15:45:12 # C:USB generic driver # F:usb/usbaudio.c:1.101->1.102 # L:handle devices that allow setting but not reading sample rate # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 13:10:13+02:00 perex@suse.cz # ALSA CVS update # VIA82xx driver # Fixed the calculation of the current DMA position at the period boundary. # # In some cases, DMA residue returns the value 0 during the transition # at the DMA boundary. The patch handles it as the position 0. # This may prevent the flood of 'invalid last pointer' debug messages # on some devices. # # Signed-off-by: Takashi Iwai # # sound/pci/via82xx.c # 2004/06/18 11:52:36+02:00 perex@suse.cz +5 -1 # ALSA CVS update # D:2004/06/18 17:52:36 # C:VIA82xx driver # F:pci/via82xx.c:1.104->1.105 # L:Fixed the calculation of the current DMA position at the period boundary. # L: # L:In some cases, DMA residue returns the value 0 during the transition # L:at the DMA boundary. The patch handles it as the position 0. # L:This may prevent the flood of 'invalid last pointer' debug messages # L:on some devices. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:08:53+02:00 perex@suse.cz # ALSA CVS update # Intel8x0 driver # Fixed the calculation of the current DMA position on some sloppy devices. # # Signed-off-by: Takashi Iwai # # sound/pci/intel8x0.c # 2004/06/18 11:50:52+02:00 perex@suse.cz +15 -9 # ALSA CVS update # D:2004/06/18 17:50:52 # C:Intel8x0 driver # F:pci/intel8x0.c:1.138->1.139 # L:Fixed the calculation of the current DMA position on some sloppy devices. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:07:19+02:00 perex@suse.cz # ALSA CVS update # PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # Trident driver # Clean up the buffer management in the PCM runtime record. # # The buffer-allocation record is hold in runtime instance, so that # it can be checked more cleanly. # # dma_private is removed from runtime (it's used for SG-buffers). # The macro snd_pcm_substream_sgbuf() should be used instead of direct # access to the pointer, to retrieve the sgbuf struct from the PCM # substream instance. # # Signed-off-by: Takashi Iwai # # sound/pci/trident/trident_memory.c # 2004/06/18 11:46:32+02:00 perex@suse.cz +1 -1 # ALSA CVS update # D:2004/06/18 17:46:31 # C:PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # C:Trident driver # F:core/pcm_memory.c:1.28->1.29 # F:include/pcm.h:1.41->1.42 # F:pci/es1968.c:1.67->1.68 # F:pci/emu10k1/memory.c:1.17->1.18 # F:pci/korg1212/korg1212.c:1.38->1.39 # F:pci/trident/trident_memory.c:1.14->1.15 # L:Clean up the buffer management in the PCM runtime record. # L: # L:The buffer-allocation record is hold in runtime instance, so that # L:it can be checked more cleanly. # L: # L:dma_private is removed from runtime (it's used for SG-buffers). # L:The macro snd_pcm_substream_sgbuf() should be used instead of direct # L:access to the pointer, to retrieve the sgbuf struct from the PCM # L:substream instance. # Signed-off-by: Takashi Iwai # # sound/pci/korg1212/korg1212.c # 2004/06/18 11:46:32+02:00 perex@suse.cz +6 -4 # ALSA CVS update # D:2004/06/18 17:46:31 # C:PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # C:Trident driver # F:core/pcm_memory.c:1.28->1.29 # F:include/pcm.h:1.41->1.42 # F:pci/es1968.c:1.67->1.68 # F:pci/emu10k1/memory.c:1.17->1.18 # F:pci/korg1212/korg1212.c:1.38->1.39 # F:pci/trident/trident_memory.c:1.14->1.15 # L:Clean up the buffer management in the PCM runtime record. # L: # L:The buffer-allocation record is hold in runtime instance, so that # L:it can be checked more cleanly. # L: # L:dma_private is removed from runtime (it's used for SG-buffers). # L:The macro snd_pcm_substream_sgbuf() should be used instead of direct # L:access to the pointer, to retrieve the sgbuf struct from the PCM # L:substream instance. # Signed-off-by: Takashi Iwai # # sound/pci/es1968.c # 2004/06/18 11:46:31+02:00 perex@suse.cz +32 -30 # ALSA CVS update # D:2004/06/18 17:46:31 # C:PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # C:Trident driver # F:core/pcm_memory.c:1.28->1.29 # F:include/pcm.h:1.41->1.42 # F:pci/es1968.c:1.67->1.68 # F:pci/emu10k1/memory.c:1.17->1.18 # F:pci/korg1212/korg1212.c:1.38->1.39 # F:pci/trident/trident_memory.c:1.14->1.15 # L:Clean up the buffer management in the PCM runtime record. # L: # L:The buffer-allocation record is hold in runtime instance, so that # L:it can be checked more cleanly. # L: # L:dma_private is removed from runtime (it's used for SG-buffers). # L:The macro snd_pcm_substream_sgbuf() should be used instead of direct # L:access to the pointer, to retrieve the sgbuf struct from the PCM # L:substream instance. # Signed-off-by: Takashi Iwai # # sound/pci/emu10k1/memory.c # 2004/06/18 11:46:31+02:00 perex@suse.cz +1 -1 # ALSA CVS update # D:2004/06/18 17:46:31 # C:PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # C:Trident driver # F:core/pcm_memory.c:1.28->1.29 # F:include/pcm.h:1.41->1.42 # F:pci/es1968.c:1.67->1.68 # F:pci/emu10k1/memory.c:1.17->1.18 # F:pci/korg1212/korg1212.c:1.38->1.39 # F:pci/trident/trident_memory.c:1.14->1.15 # L:Clean up the buffer management in the PCM runtime record. # L: # L:The buffer-allocation record is hold in runtime instance, so that # L:it can be checked more cleanly. # L: # L:dma_private is removed from runtime (it's used for SG-buffers). # L:The macro snd_pcm_substream_sgbuf() should be used instead of direct # L:access to the pointer, to retrieve the sgbuf struct from the PCM # L:substream instance. # Signed-off-by: Takashi Iwai # # sound/core/pcm_memory.c # 2004/06/18 11:46:31+02:00 perex@suse.cz +18 -22 # ALSA CVS update # D:2004/06/18 17:46:31 # C:PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # C:Trident driver # F:core/pcm_memory.c:1.28->1.29 # F:include/pcm.h:1.41->1.42 # F:pci/es1968.c:1.67->1.68 # F:pci/emu10k1/memory.c:1.17->1.18 # F:pci/korg1212/korg1212.c:1.38->1.39 # F:pci/trident/trident_memory.c:1.14->1.15 # L:Clean up the buffer management in the PCM runtime record. # L: # L:The buffer-allocation record is hold in runtime instance, so that # L:it can be checked more cleanly. # L: # L:dma_private is removed from runtime (it's used for SG-buffers). # L:The macro snd_pcm_substream_sgbuf() should be used instead of direct # L:access to the pointer, to retrieve the sgbuf struct from the PCM # L:substream instance. # Signed-off-by: Takashi Iwai # # include/sound/pcm.h # 2004/06/18 11:46:31+02:00 perex@suse.cz +19 -2 # ALSA CVS update # D:2004/06/18 17:46:31 # C:PCM Midlevel,ES1968 driver,EMU10K1/EMU10K2 driver,KORG1212 driver # C:Trident driver # F:core/pcm_memory.c:1.28->1.29 # F:include/pcm.h:1.41->1.42 # F:pci/es1968.c:1.67->1.68 # F:pci/emu10k1/memory.c:1.17->1.18 # F:pci/korg1212/korg1212.c:1.38->1.39 # F:pci/trident/trident_memory.c:1.14->1.15 # L:Clean up the buffer management in the PCM runtime record. # L: # L:The buffer-allocation record is hold in runtime instance, so that # L:it can be checked more cleanly. # L: # L:dma_private is removed from runtime (it's used for SG-buffers). # L:The macro snd_pcm_substream_sgbuf() should be used instead of direct # L:access to the pointer, to retrieve the sgbuf struct from the PCM # L:substream instance. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:05:35+02:00 perex@suse.cz # ALSA CVS update # Generic drivers # Do the buffer allocation in hw_params callback instead of open callback. # # This will prevent to use the allocation of excessive size. # Pre-allocation is called with the default size 0, ie. no buffer will be # pre-allocated as default. # # Signed-off-by: Takashi Iwai # # sound/drivers/dummy.c # 2004/06/18 11:43:33+02:00 perex@suse.cz +20 -31 # ALSA CVS update # D:2004/06/18 17:43:33 # C:Generic drivers # F:drivers/dummy.c:1.27->1.28 # L:Do the buffer allocation in hw_params callback instead of open callback. # L: # L:This will prevent to use the allocation of excessive size. # L:Pre-allocation is called with the default size 0, ie. no buffer will be # L:pre-allocated as default. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:04:14+02:00 perex@suse.cz # ALSA CVS update # ES1968 driver # Fix the crash at unloading the module due to the shared interrupt # with other devices. # # Signed-off-by: Karsten Wiese # Signed-off-by: Takashi Iwai # # sound/pci/es1968.c # 2004/06/18 08:40:17+02:00 perex@suse.cz +2 -2 # ALSA CVS update # D:2004/06/18 14:40:17 # C:ES1968 driver # F:pci/es1968.c:1.66->1.67 # L:Fix the crash at unloading the module due to the shared interrupt # L:with other devices. # Signed-off-by: Karsten Wiese # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:02:56+02:00 perex@suse.cz # ALSA CVS update # PCM Midlevel # Removed the obsoleted init for boot parameters. # # Signed-off-by: Takashi Iwai # # sound/core/pcm_memory.c # 2004/06/18 08:38:26+02:00 perex@suse.cz +0 -15 # ALSA CVS update # D:2004/06/18 14:38:26 # C:PCM Midlevel # F:core/pcm_memory.c:1.27->1.28 # L:Removed the obsoleted init for boot parameters. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 13:01:38+02:00 perex@suse.cz # ALSA CVS update # CS46xx driver,MIXART driver # reduce stack usage # # Signed-off-by: Clemens Ladisch # # sound/pci/mixart/mixart.c # 2004/06/16 08:32:20+02:00 perex@suse.cz +27 -19 # ALSA CVS update # D:2004/06/16 14:35:18 # C:CS46xx driver,MIXART driver # F:pci/cs46xx/dsp_spos.c:1.23->1.24 # F:pci/mixart/mixart.c:1.8->1.9 # L:reduce stack usage # Signed-off-by: Clemens Ladisch # # sound/pci/cs46xx/dsp_spos.c # 2004/06/16 08:35:18+02:00 perex@suse.cz +16 -11 # ALSA CVS update # D:2004/06/16 14:35:18 # C:CS46xx driver,MIXART driver # F:pci/cs46xx/dsp_spos.c:1.23->1.24 # F:pci/mixart/mixart.c:1.8->1.9 # L:reduce stack usage # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 12:58:32+02:00 perex@suse.cz # ALSA CVS update # OSS sequencer emulation # # Use separate functions for some ioctls to reduce stack usage. # # Signed-off-by: Clemens Ladisch # Signed-off-by: Jaroslav Kysela # # sound/core/seq/oss/seq_oss_ioctl.c # 2004/06/23 12:58:02+02:00 perex@suse.cz +46 -28 # ALSA CVS update # D:2004/06/16 14:28:13 # C:ALSA<-OSS sequencer # F:core/seq/oss/seq_oss_ioctl.c:1.5->1.6 # L:use separate functions for some ioctls to reduce stack usage # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 12:44:07+02:00 perex@suse.cz # ALSA CVS update # OPL4 # add newline at end of file # # Signed-off-by: Clemens Ladisch # # sound/drivers/opl4/Makefile # 2004/06/16 04:46:02+02:00 perex@suse.cz +1 -1 # ALSA CVS update # D:2004/06/16 10:46:02 # C:OPL4 # F:drivers/opl4/Makefile:1.3->1.4 # L:add newline at end of file # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 12:42:44+02:00 perex@suse.cz # ALSA CVS update # Opti9xx drivers # Fixed spin deadlocks. # # Signed-off-by: Takashi Iwai # # sound/isa/opti9xx/opti92x-ad1848.c # 2004/06/15 05:39:57+02:00 perex@suse.cz +2 -19 # ALSA CVS update # D:2004/06/15 11:39:57 # C:Opti9xx drivers # F:isa/opti9xx/opti92x-ad1848.c:1.44->1.45 # L:Fixed spin deadlocks. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 12:41:27+02:00 perex@suse.cz # ALSA CVS update # USB generic driver # Quattro USB: handle the different endianness of playback and recording sample data # # Signed-off-by: Clemens Ladisch # # sound/usb/usbquirks.h # 2004/06/14 12:12:05+02:00 perex@suse.cz +36 -5 # ALSA CVS update # D:2004/06/14 18:12:05 # C:USB generic driver # F:usb/usbaudio.c:1.100->1.101 # F:usb/usbquirks.h:1.33->1.34 # L:Quattro USB: handle the different endianness of playback and recording sample data # Signed-off-by: Clemens Ladisch # # sound/usb/usbaudio.c # 2004/06/14 12:12:05+02:00 perex@suse.cz +20 -6 # ALSA CVS update # D:2004/06/14 18:12:05 # C:USB generic driver # F:usb/usbaudio.c:1.100->1.101 # F:usb/usbquirks.h:1.33->1.34 # L:Quattro USB: handle the different endianness of playback and recording sample data # Signed-off-by: Clemens Ladisch # # ChangeSet # 2004/06/23 12:40:10+02:00 perex@suse.cz # ALSA CVS update # PCM Midlevel,ALSA<-OSS emulation # Clean up and optimization of PCM format-specific functions. # # - Use array indexing instead of huge swith/case. # - Removed superfluous handling of floats. # - Use memcpy for silencing to simplify the codes. # # Signed-off-by: Takashi Iwai # # sound/core/pcm_misc.c # 2004/06/09 12:36:14+02:00 perex@suse.cz +249 -459 # ALSA CVS update # D:2004/06/09 18:36:14 # C:PCM Midlevel,ALSA<-OSS emulation # F:core/pcm_misc.c:1.13->1.14 # F:core/oss/pcm_plugin.c:1.18->1.19 # F:include/pcm.h:1.40->1.41 # L:Clean up and optimization of PCM format-specific functions. # L: # L:- Use array indexing instead of huge swith/case. # L:- Removed superfluous handling of floats. # L:- Use memcpy for silencing to simplify the codes. # Signed-off-by: Takashi Iwai # # sound/core/oss/pcm_plugin.c # 2004/06/09 12:36:14+02:00 perex@suse.cz +27 -96 # ALSA CVS update # D:2004/06/09 18:36:14 # C:PCM Midlevel,ALSA<-OSS emulation # F:core/pcm_misc.c:1.13->1.14 # F:core/oss/pcm_plugin.c:1.18->1.19 # F:include/pcm.h:1.40->1.41 # L:Clean up and optimization of PCM format-specific functions. # L: # L:- Use array indexing instead of huge swith/case. # L:- Removed superfluous handling of floats. # L:- Use memcpy for silencing to simplify the codes. # Signed-off-by: Takashi Iwai # # include/sound/pcm.h # 2004/06/09 12:36:15+02:00 perex@suse.cz +1 -1 # ALSA CVS update # D:2004/06/09 18:36:14 # C:PCM Midlevel,ALSA<-OSS emulation # F:core/pcm_misc.c:1.13->1.14 # F:core/oss/pcm_plugin.c:1.18->1.19 # F:include/pcm.h:1.40->1.41 # L:Clean up and optimization of PCM format-specific functions. # L: # L:- Use array indexing instead of huge swith/case. # L:- Removed superfluous handling of floats. # L:- Use memcpy for silencing to simplify the codes. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 12:38:51+02:00 perex@suse.cz # ALSA CVS update # Intel8x0 driver # Added the PCI ID for nVidia CK8. # # Signed-off-by: Takashi Iwai # # sound/pci/intel8x0.c # 2004/06/09 12:02:00+02:00 perex@suse.cz +5 -0 # ALSA CVS update # D:2004/06/09 18:02:00 # C:Intel8x0 driver # F:pci/intel8x0.c:1.137->1.138 # L:Added the PCI ID for nVidia CK8. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 12:37:24+02:00 perex@suse.cz # ALSA CVS update # ATIIXP driver,VIA82xx driver # Added the missing RESUME info bits to pcm. # # Signed-off-by: Takashi Iwai # # sound/pci/via82xx.c # 2004/06/09 12:01:05+02:00 perex@suse.cz +1 -0 # ALSA CVS update # D:2004/06/09 18:01:05 # C:ATIIXP driver,VIA82xx driver # F:pci/atiixp.c:1.10->1.11 # F:pci/via82xx.c:1.103->1.104 # L:Added the missing RESUME info bits to pcm. # Signed-off-by: Takashi Iwai # # sound/pci/atiixp.c # 2004/06/09 12:01:05+02:00 perex@suse.cz +1 -0 # ALSA CVS update # D:2004/06/09 18:01:05 # C:ATIIXP driver,VIA82xx driver # F:pci/atiixp.c:1.10->1.11 # F:pci/via82xx.c:1.103->1.104 # L:Added the missing RESUME info bits to pcm. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 12:33:49+02:00 perex@suse.cz # ALSA CVS update # ICE1724 driver # SPDIF output fixes # # - Fixed the encoding of SPDIF status bits in the consumer mode. # - Change the SPDIF status bits according to the current sample rate. # # Signed-off-by: Takashi Iwai # # sound/pci/ice1712/ice1724.c # 2004/06/08 11:15:26+02:00 perex@suse.cz +40 -11 # ALSA CVS update # D:2004/06/08 17:15:26 # C:ICE1724 driver # F:pci/ice1712/ice1724.c:1.33->1.34 # L:SPDIF output fixes # L: # L:- Fixed the encoding of SPDIF status bits in the consumer mode. # L:- Change the SPDIF status bits according to the current sample rate. # Signed-off-by: Takashi Iwai # # ChangeSet # 2004/06/23 12:28:34+02:00 perex@suse.cz # ALSA CVS update # Documentation # Added snd-fm801 tuner parameter description # Signed-off-by: Jaroslav Kysela # # Documentation/sound/alsa/ALSA-Configuration.txt # 2004/06/01 02:56:20+02:00 perex@suse.cz +7 -0 # ALSA CVS update # D:2004/06/01 08:56:20 # C:Documentation # F:Documentation/ALSA-Configuration.txt:1.45->1.46 # L:Added snd-fm801 tuner parameter description # Signed-off-by: Jaroslav Kysela # # ChangeSet # 2004/06/18 11:41: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/06/18 11:40:59-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/16 11:59:16+02:00 perex@suse.cz # Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5 # into suse.cz:/home/perex/bk/linux-sound/linux-sound # # sound/isa/wavefront/wavefront_synth.c # 2004/06/16 11:58:53+02:00 perex@suse.cz +0 -0 # Auto merged # # sound/core/seq/seq_clientmgr.c # 2004/06/16 11:58:53+02:00 perex@suse.cz +0 -0 # Auto merged # # include/sound/vx_core.h # 2004/06/16 11:58:53+02:00 perex@suse.cz +0 -0 # Auto merged # # include/sound/seq_kernel.h # 2004/06/16 11:58:53+02:00 perex@suse.cz +0 -0 # Auto merged # # include/sound/core.h # 2004/06/16 11:58:53+02:00 perex@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/06/15 21:01:33-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa # # include/linux/pci_ids.h # 2004/06/15 21:01:29-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/04 02:14:21-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa # # include/sound/vx_core.h # 2004/06/04 02:14:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/03 18:39:45-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-alsa # # sound/isa/wavefront/wavefront_synth.c # 2004/06/03 18:39:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # sound/core/seq/seq_clientmgr.c # 2004/06/03 18:39:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/sound/seq_kernel.h # 2004/06/03 18:39:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # include/sound/core.h # 2004/06/03 18:39:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/03 10:17:49-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/03 10:17:46-07:00 akpm@bix.(none) +0 -0 # Auto merged # # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # AC97 Codec Core # Signed-off-by: Kevin Mack # 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 # F:pci/ac97/ac97_patch.c:1.50->1.51 # L:Signed-off-by: Kevin Mack # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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-23 11:51:27 -07:00 +++ b/Documentation/sound/alsa/ALSA-Configuration.txt 2004-06-23 11:51:27 -07:00 @@ -516,6 +516,13 @@ Module for ForteMedia FM801 based PCI soundcards. + tea575x_tuner - Enable TEA575x tuner + - 1 = MediaForte 256-PCS + - 2 = MediaForte 256-PCPR + - 3 = MediaForte 64-PCR + - High 16-bits are video (radio) device number + 1 + - example: 0x10002 (MediaForte 256-PCPR, device 1) + Module supports up to 8 cards and autoprobe. Module snd-gusclassic @@ -613,7 +620,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 +638,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-23 11:51:27 -07:00 +++ b/include/sound/ac97_codec.h 2004-06-23 11:51:27 -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/asound.h b/include/sound/asound.h --- a/include/sound/asound.h 2004-06-23 11:51:27 -07:00 +++ b/include/sound/asound.h 2004-06-23 11:51:27 -07:00 @@ -274,6 +274,7 @@ #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ #define SNDRV_PCM_INFO_NONATOMIC_OPS 0x00800000 /* non-atomic prepare callback */ +#define SNDRV_PCM_INFO_MMAP_IOMEM 0x01000000 /* mmap on IO memory */ enum sndrv_pcm_state { SNDRV_PCM_STATE_OPEN = 0, /* stream is open */ diff -Nru a/include/sound/core.h b/include/sound/core.h --- a/include/sound/core.h 2004-06-23 11:51:28 -07:00 +++ b/include/sound/core.h 2004-06-23 11:51:28 -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/emu10k1.h b/include/sound/emu10k1.h --- a/include/sound/emu10k1.h 2004-06-23 11:51:27 -07:00 +++ b/include/sound/emu10k1.h 2004-06-23 11:51:27 -07:00 @@ -1069,6 +1069,15 @@ /* proc interface */ int snd_emu10k1_proc_init(emu10k1_t * emu); +/* fx8010 irq handler */ +int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu, + snd_fx8010_irq_handler_t *handler, + unsigned char gpr_running, + void *private_data, + snd_emu10k1_fx8010_irq_t **r_irq); +int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu, + snd_emu10k1_fx8010_irq_t *irq); + #endif /* __KERNEL__ */ /* diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h --- a/include/sound/pcm.h 2004-06-23 11:51:27 -07:00 +++ b/include/sound/pcm.h 2004-06-23 11:51:27 -07:00 @@ -351,7 +351,8 @@ unsigned char *dma_area; /* DMA area */ dma_addr_t dma_addr; /* physical bus address (not accessible from main CPU) */ size_t dma_bytes; /* size of DMA area */ - void *dma_private; /* private DMA data for the memory allocator */ + + struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */ #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) /* -- OSS things -- */ @@ -851,7 +852,7 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format); int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */ int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */ -u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format); +const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format); int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames); snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian); ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples); @@ -892,6 +893,22 @@ int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime); +static inline void snd_pcm_set_runtime_buffer(snd_pcm_substream_t *substream, + struct snd_dma_buffer *bufp) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + if (bufp) { + runtime->dma_buffer_p = bufp; + runtime->dma_area = bufp->area; + runtime->dma_addr = bufp->addr; + runtime->dma_bytes = bufp->bytes; + } else { + runtime->dma_buffer_p = NULL; + runtime->dma_area = NULL; + runtime->dma_addr = 0; + runtime->dma_bytes = 0; + } +} /* * Timer interface @@ -916,7 +933,7 @@ int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size); int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream); -#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_private) +#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_buffer_p->private_data) #define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size) #define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs) struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset); diff -Nru a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h --- a/include/sound/seq_kernel.h 2004-06-23 11:51:28 -07:00 +++ b/include/sound/seq_kernel.h 2004-06-23 11:51:28 -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-23 11:51:27 -07:00 +++ b/include/sound/version.h 2004-06-23 11:51:27 -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-23 11:51:27 -07:00 +++ b/include/sound/vx_core.h 2004-06-23 11:51:27 -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-23 11:51:28 -07:00 +++ b/sound/core/memalloc.c 2004-06-23 11:51:28 -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/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c --- a/sound/core/oss/pcm_oss.c 2004-06-23 11:51:28 -07:00 +++ b/sound/core/oss/pcm_oss.c 2004-06-23 11:51:28 -07:00 @@ -1177,10 +1177,11 @@ snd_pcm_substream_t *substream; int err; int direct; - snd_pcm_hw_params_t params; + snd_pcm_hw_params_t *params; unsigned int formats = 0; snd_mask_t format_mask; int fmt; + if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) return err; if (atomic_read(&substream->runtime->mmap_count)) { @@ -1194,10 +1195,14 @@ AFMT_S16_LE | AFMT_S16_BE | AFMT_S8 | AFMT_U16_LE | AFMT_U16_BE; - _snd_pcm_hw_params_any(¶ms); - err = snd_pcm_hw_refine(substream, ¶ms); + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) + return -ENOMEM; + _snd_pcm_hw_params_any(params); + err = snd_pcm_hw_refine(substream, params); + format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + kfree(params); snd_assert(err >= 0, return err); - format_mask = *hw_param_mask(¶ms, SNDRV_PCM_HW_PARAM_FORMAT); for (fmt = 0; fmt < 32; ++fmt) { if (snd_mask_test(&format_mask, fmt)) { int f = snd_pcm_oss_format_to(fmt); @@ -2280,7 +2285,7 @@ snd_info_buffer_t * buffer) { snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data; - char line[512], str[32], task_name[32], *ptr; + char line[256], str[32], task_name[32], *ptr; int idx1; snd_pcm_oss_setup_t *setup, *setup1, template; diff -Nru a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c --- a/sound/core/oss/pcm_plugin.c 2004-06-23 11:51:27 -07:00 +++ b/sound/core/oss/pcm_plugin.c 2004-06-23 11:51:27 -07:00 @@ -846,41 +846,31 @@ size_t samples, int format) { /* FIXME: sub byte resolution and odd dst_offset */ - char *dst; + unsigned char *dst; unsigned int dst_step; int width; - u_int64_t silence; + const unsigned char *silence; if (!dst_area->addr) return 0; dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8; width = snd_pcm_format_physical_width(format); + if (width <= 0) + return -EINVAL; + if (dst_area->step == (unsigned int) width && width >= 8) + return snd_pcm_format_set_silence(format, dst, samples); silence = snd_pcm_format_silence_64(format); - if (dst_area->step == (unsigned int) width) { - size_t dwords = samples * width / 64; - u_int64_t *dst64 = (u_int64_t *)dst; - - samples -= dwords * 64 / width; - while (dwords-- > 0) - *dst64++ = silence; - if (samples == 0) - return 0; - dst = (char *)dst64; - } + if (! silence) + return -EINVAL; dst_step = dst_area->step / 8; - switch (width) { - case 4: { - u_int8_t s0 = silence & 0xf0; - u_int8_t s1 = silence & 0x0f; + if (width == 4) { + /* Ima ADPCM */ int dstbit = dst_area->first % 8; int dstbit_step = dst_area->step % 8; while (samples-- > 0) { - if (dstbit) { + if (dstbit) *dst &= 0xf0; - *dst |= s1; - } else { + else *dst &= 0x0f; - *dst |= s0; - } dst += dst_step; dstbit += dstbit_step; if (dstbit == 8) { @@ -888,41 +878,12 @@ dstbit = 0; } } - break; - } - case 8: { - u_int8_t sil = silence; - while (samples-- > 0) { - *dst = sil; - dst += dst_step; - } - break; - } - case 16: { - u_int16_t sil = silence; - while (samples-- > 0) { - *(u_int16_t*)dst = sil; - dst += dst_step; - } - break; - } - case 32: { - u_int32_t sil = silence; - while (samples-- > 0) { - *(u_int32_t*)dst = sil; - dst += dst_step; - } - break; - } - case 64: { + } else { + width /= 8; while (samples-- > 0) { - *(u_int64_t*)dst = silence; + memcpy(dst, silence, width); dst += dst_step; } - break; - } - default: - snd_BUG(); } return 0; } @@ -942,18 +903,18 @@ if (!dst_area->addr) return 0; width = snd_pcm_format_physical_width(format); + if (width <= 0) + return -EINVAL; if (src_area->step == (unsigned int) width && - dst_area->step == (unsigned int) width) { + dst_area->step == (unsigned int) width && width >= 8) { size_t bytes = samples * width / 8; - samples -= bytes * 8 / width; memcpy(dst, src, bytes); - if (samples == 0) - return 0; + return 0; } src_step = src_area->step / 8; dst_step = dst_area->step / 8; - switch (width) { - case 4: { + if (width == 4) { + /* Ima ADPCM */ int srcbit = src_area->first % 8; int srcbit_step = src_area->step % 8; int dstbit = dst_area->first % 8; @@ -963,12 +924,11 @@ if (srcbit) srcval = *src & 0x0f; else - srcval = *src & 0xf0; + srcval = (*src & 0xf0) >> 4; if (dstbit) - *dst &= 0xf0; + *dst = (*dst & 0xf0) | srcval; else - *dst &= 0x0f; - *dst |= srcval; + *dst = (*dst & 0x0f) | (srcval << 4); src += src_step; srcbit += srcbit_step; if (srcbit == 8) { @@ -982,42 +942,13 @@ dstbit = 0; } } - break; - } - case 8: { - while (samples-- > 0) { - *dst = *src; - src += src_step; - dst += dst_step; - } - break; - } - case 16: { + } else { + width /= 8; while (samples-- > 0) { - *(u_int16_t*)dst = *(u_int16_t*)src; + memcpy(dst, src, width); src += src_step; dst += dst_step; } - break; - } - case 32: { - while (samples-- > 0) { - *(u_int32_t*)dst = *(u_int32_t*)src; - src += src_step; - dst += dst_step; - } - break; - } - case 64: { - while (samples-- > 0) { - *(u_int64_t*)dst = *(u_int64_t*)src; - src += src_step; - dst += dst_step; - } - break; - } - default: - snd_BUG(); } return 0; } diff -Nru a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c --- a/sound/core/pcm_memory.c 2004-06-23 11:51:28 -07:00 +++ b/sound/core/pcm_memory.c 2004-06-23 11:51:28 -07:00 @@ -314,31 +314,35 @@ int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size) { snd_pcm_runtime_t *runtime; - struct snd_dma_buffer dmab; + struct snd_dma_buffer *dmab = NULL; snd_assert(substream->dma_device.type != SNDRV_DMA_TYPE_UNKNOWN, return -EINVAL); snd_assert(substream != NULL, return -EINVAL); runtime = substream->runtime; - snd_assert(runtime != NULL, return -EINVAL); + snd_assert(runtime != NULL, return -EINVAL); - if (runtime->dma_area != NULL) { + if (runtime->dma_buffer_p) { /* perphaps, we might free the large DMA memory region to save some space here, but the actual solution costs us less time */ - if (runtime->dma_bytes >= size) + if (runtime->dma_buffer_p->bytes >= size) { + runtime->dma_bytes = size; return 0; /* ok, do not change */ + } snd_pcm_lib_free_pages(substream); } if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) { - dmab = substream->dma_buffer; /* use the pre-allocated buffer */ + dmab = &substream->dma_buffer; /* use the pre-allocated buffer */ } else { - memset(&dmab, 0, sizeof(dmab)); /* allocate a new buffer */ - if (snd_dma_alloc_pages(&substream->dma_device, size, &dmab) < 0) + dmab = snd_kcalloc(sizeof(*dmab), GFP_KERNEL); + if (! dmab) + return -ENOMEM; + if (snd_dma_alloc_pages(&substream->dma_device, size, dmab) < 0) { + kfree(dmab); return -ENOMEM; + } } - runtime->dma_area = dmab.area; - runtime->dma_addr = dmab.addr; - runtime->dma_private = dmab.private_data; + snd_pcm_set_runtime_buffer(substream, dmab); runtime->dma_bytes = size; return 1; /* area was changed */ } @@ -360,34 +364,11 @@ snd_assert(runtime != NULL, return -EINVAL); if (runtime->dma_area == NULL) return 0; - if (runtime->dma_area != substream->dma_buffer.area) { + if (runtime->dma_buffer_p != &substream->dma_buffer) { /* it's a newly allocated buffer. release it now. */ - struct snd_dma_buffer dmab; - memset(&dmab, 0, sizeof(dmab)); - dmab.area = runtime->dma_area; - dmab.addr = runtime->dma_addr; - dmab.bytes = runtime->dma_bytes; - dmab.private_data = runtime->dma_private; - snd_dma_free_pages(&substream->dma_device, &dmab); + snd_dma_free_pages(&substream->dma_device, runtime->dma_buffer_p); + kfree(runtime->dma_buffer_p); } - runtime->dma_area = NULL; - runtime->dma_addr = 0UL; - runtime->dma_bytes = 0; - runtime->dma_private = NULL; + snd_pcm_set_runtime_buffer(substream, NULL); return 0; } - -#ifndef MODULE - -/* format is: snd-pcm=preallocate_dma,maximum_substreams */ - -static int __init alsa_pcm_setup(char *str) -{ - (void)(get_option(&str,&preallocate_dma) == 2 && - get_option(&str,&maximum_substreams) == 2); - return 1; -} - -__setup("snd-pcm=", alsa_pcm_setup); - -#endif /* ifndef MODULE */ diff -Nru a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c --- a/sound/core/pcm_misc.c 2004-06-23 11:51:28 -07:00 +++ b/sound/core/pcm_misc.c 2004-06-23 11:51:28 -07:00 @@ -23,12 +23,169 @@ #include #include #include -#define bswap_16 swab16 -#define bswap_32 swab32 -#define bswap_64 swab64 #define SND_PCM_FORMAT_UNKNOWN (-1) -#define snd_enum_to_int(v) (v) -#define snd_int_to_enum(v) (v) + +struct pcm_format_data { + char width; /* bit width */ + char phys; /* physical bit width */ + char le; /* 0 = big-endian, 1 = little-endian, -1 = others */ + char signd; /* 0 = unsigned, 1 = signed, -1 = others */ + unsigned char silence[8]; /* silence data to fill */ +}; + +static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = { + [SNDRV_PCM_FORMAT_S8] = { + .width = 8, .phys = 8, .le = -1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U8] = { + .width = 8, .phys = 8, .le = -1, .signd = 0, + .silence = { 0x80 }, + }, + [SNDRV_PCM_FORMAT_S16_LE] = { + .width = 16, .phys = 16, .le = 1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_S16_BE] = { + .width = 16, .phys = 16, .le = 0, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U16_LE] = { + .width = 16, .phys = 16, .le = 1, .signd = 0, + .silence = { 0x00, 0x80 }, + }, + [SNDRV_PCM_FORMAT_U16_BE] = { + .width = 16, .phys = 16, .le = 0, .signd = 0, + .silence = { 0x80, 0x00 }, + }, + [SNDRV_PCM_FORMAT_S24_LE] = { + .width = 24, .phys = 32, .le = 1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_S24_BE] = { + .width = 24, .phys = 32, .le = 0, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U24_LE] = { + .width = 24, .phys = 32, .le = 1, .signd = 0, + .silence = { 0x00, 0x00, 0x80 }, + }, + [SNDRV_PCM_FORMAT_U24_BE] = { + .width = 24, .phys = 32, .le = 0, .signd = 0, + .silence = { 0x80, 0x00, 0x00 }, + }, + [SNDRV_PCM_FORMAT_S32_LE] = { + .width = 32, .phys = 32, .le = 1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_S32_BE] = { + .width = 32, .phys = 32, .le = 0, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U32_LE] = { + .width = 32, .phys = 32, .le = 1, .signd = 0, + .silence = { 0x00, 0x00, 0x00, 0x80 }, + }, + [SNDRV_PCM_FORMAT_U32_BE] = { + .width = 32, .phys = 32, .le = 0, .signd = 0, + .silence = { 0x80, 0x00, 0x00, 0x00 }, + }, + [SNDRV_PCM_FORMAT_FLOAT_LE] = { + .width = 32, .phys = 32, .le = 1, .signd = -1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_FLOAT_BE] = { + .width = 32, .phys = 32, .le = 0, .signd = -1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_FLOAT64_LE] = { + .width = 64, .phys = 64, .le = 1, .signd = -1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_FLOAT64_BE] = { + .width = 64, .phys = 64, .le = 0, .signd = -1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE] = { + .width = 32, .phys = 32, .le = 1, .signd = -1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE] = { + .width = 32, .phys = 32, .le = 0, .signd = -1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_MU_LAW] = { + .width = 8, .phys = 8, .le = -1, .signd = -1, + .silence = { 0x7f }, + }, + [SNDRV_PCM_FORMAT_A_LAW] = { + .width = 8, .phys = 8, .le = -1, .signd = -1, + .silence = { 0x55 }, + }, + [SNDRV_PCM_FORMAT_IMA_ADPCM] = { + .width = 4, .phys = 4, .le = -1, .signd = -1, + .silence = {}, + }, + /* FIXME: the following three formats are not defined properly yet */ + [SNDRV_PCM_FORMAT_MPEG] = { + .le = -1, .signd = -1, + }, + [SNDRV_PCM_FORMAT_GSM] = { + .le = -1, .signd = -1, + }, + [SNDRV_PCM_FORMAT_SPECIAL] = { + .le = -1, .signd = -1, + }, + [SNDRV_PCM_FORMAT_S24_3LE] = { + .width = 24, .phys = 24, .le = 1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_S24_3BE] = { + .width = 24, .phys = 24, .le = 0, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U24_3LE] = { + .width = 24, .phys = 24, .le = 1, .signd = 0, + .silence = { 0x00, 0x00, 0x80 }, + }, + [SNDRV_PCM_FORMAT_U24_3BE] = { + .width = 24, .phys = 24, .le = 0, .signd = 0, + .silence = { 0x80, 0x00, 0x00 }, + }, + [SNDRV_PCM_FORMAT_S20_3LE] = { + .width = 20, .phys = 24, .le = 1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_S20_3BE] = { + .width = 20, .phys = 24, .le = 0, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U20_3LE] = { + .width = 20, .phys = 24, .le = 1, .signd = 0, + .silence = { 0x00, 0x00, 0x08 }, + }, + [SNDRV_PCM_FORMAT_U20_3BE] = { + .width = 20, .phys = 24, .le = 0, .signd = 0, + .silence = { 0x08, 0x00, 0x00 }, + }, + [SNDRV_PCM_FORMAT_S18_3LE] = { + .width = 18, .phys = 24, .le = 1, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_S18_3BE] = { + .width = 18, .phys = 24, .le = 0, .signd = 1, + .silence = {}, + }, + [SNDRV_PCM_FORMAT_U18_3LE] = { + .width = 18, .phys = 24, .le = 1, .signd = 0, + .silence = { 0x00, 0x00, 0x02 }, + }, + [SNDRV_PCM_FORMAT_U18_3BE] = { + .width = 18, .phys = 24, .le = 0, .signd = 0, + .silence = { 0x02, 0x00, 0x00 }, + }, +}; + /** * snd_pcm_format_signed - Check the PCM format is signed linear @@ -39,38 +196,12 @@ */ int snd_pcm_format_signed(snd_pcm_format_t format) { - switch (snd_enum_to_int(format)) { - case SNDRV_PCM_FORMAT_S8: - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_3BE: - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S20_3BE: - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_S18_3BE: - return 1; - case SNDRV_PCM_FORMAT_U8: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_U16_BE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_U32_BE: - case SNDRV_PCM_FORMAT_U24_3LE: - case SNDRV_PCM_FORMAT_U24_3BE: - case SNDRV_PCM_FORMAT_U20_3LE: - case SNDRV_PCM_FORMAT_U20_3BE: - case SNDRV_PCM_FORMAT_U18_3LE: - case SNDRV_PCM_FORMAT_U18_3BE: - return 0; - default: + int val; + if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) return -EINVAL; - } + if ((val = pcm_formats[format].signd) < 0) + return -EINVAL; + return val; } /** @@ -110,42 +241,12 @@ */ int snd_pcm_format_little_endian(snd_pcm_format_t format) { - switch (snd_enum_to_int(format)) { - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_FLOAT_LE: - case SNDRV_PCM_FORMAT_FLOAT64_LE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_U24_3LE: - case SNDRV_PCM_FORMAT_U20_3LE: - case SNDRV_PCM_FORMAT_U18_3LE: - return 1; - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_U16_BE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_U32_BE: - case SNDRV_PCM_FORMAT_FLOAT_BE: - case SNDRV_PCM_FORMAT_FLOAT64_BE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE: - case SNDRV_PCM_FORMAT_S24_3BE: - case SNDRV_PCM_FORMAT_S20_3BE: - case SNDRV_PCM_FORMAT_S18_3BE: - case SNDRV_PCM_FORMAT_U24_3BE: - case SNDRV_PCM_FORMAT_U20_3BE: - case SNDRV_PCM_FORMAT_U18_3BE: - return 0; - default: + int val; + if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) return -EINVAL; - } + if ((val = pcm_formats[format].le) < 0) + return -EINVAL; + return val; } /** @@ -190,55 +291,12 @@ */ int snd_pcm_format_width(snd_pcm_format_t format) { - switch (snd_enum_to_int(format)) { - case SNDRV_PCM_FORMAT_S8: - case SNDRV_PCM_FORMAT_U8: - return 8; - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_U16_BE: - return 16; - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_S18_3BE: - case SNDRV_PCM_FORMAT_U18_3LE: - case SNDRV_PCM_FORMAT_U18_3BE: - return 18; - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S20_3BE: - case SNDRV_PCM_FORMAT_U20_3LE: - case SNDRV_PCM_FORMAT_U20_3BE: - return 20; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_3BE: - case SNDRV_PCM_FORMAT_U24_3LE: - case SNDRV_PCM_FORMAT_U24_3BE: - return 24; - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_U32_BE: - case SNDRV_PCM_FORMAT_FLOAT_LE: - case SNDRV_PCM_FORMAT_FLOAT_BE: - return 32; - case SNDRV_PCM_FORMAT_FLOAT64_LE: - case SNDRV_PCM_FORMAT_FLOAT64_BE: - return 64; - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE: - return 32; - case SNDRV_PCM_FORMAT_MU_LAW: - case SNDRV_PCM_FORMAT_A_LAW: - return 8; - case SNDRV_PCM_FORMAT_IMA_ADPCM: - return 4; - default: + int val; + if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) return -EINVAL; - } + if ((val = pcm_formats[format].width) == 0) + return -EINVAL; + return val; } /** @@ -250,52 +308,12 @@ */ int snd_pcm_format_physical_width(snd_pcm_format_t format) { - switch (snd_enum_to_int(format)) { - case SNDRV_PCM_FORMAT_S8: - case SNDRV_PCM_FORMAT_U8: - return 8; - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_U16_BE: - return 16; - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_S18_3BE: - case SNDRV_PCM_FORMAT_U18_3LE: - case SNDRV_PCM_FORMAT_U18_3BE: - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S20_3BE: - case SNDRV_PCM_FORMAT_U20_3LE: - case SNDRV_PCM_FORMAT_U20_3BE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_3BE: - case SNDRV_PCM_FORMAT_U24_3LE: - case SNDRV_PCM_FORMAT_U24_3BE: - return 24; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_U32_BE: - case SNDRV_PCM_FORMAT_FLOAT_LE: - case SNDRV_PCM_FORMAT_FLOAT_BE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE: - return 32; - case SNDRV_PCM_FORMAT_FLOAT64_LE: - case SNDRV_PCM_FORMAT_FLOAT64_BE: - return 64; - case SNDRV_PCM_FORMAT_MU_LAW: - case SNDRV_PCM_FORMAT_A_LAW: - return 8; - case SNDRV_PCM_FORMAT_IMA_ADPCM: - return 4; - default: + int val; + if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) return -EINVAL; - } + if ((val = pcm_formats[format].phys) == 0) + return -EINVAL; + return val; } /** @@ -307,216 +325,25 @@ */ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) { - switch (snd_enum_to_int(format)) { - case SNDRV_PCM_FORMAT_S8: - case SNDRV_PCM_FORMAT_U8: - return samples; - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_U16_BE: - return samples * 2; - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_S18_3BE: - case SNDRV_PCM_FORMAT_U18_3LE: - case SNDRV_PCM_FORMAT_U18_3BE: - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S20_3BE: - case SNDRV_PCM_FORMAT_U20_3LE: - case SNDRV_PCM_FORMAT_U20_3BE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_3BE: - case SNDRV_PCM_FORMAT_U24_3LE: - case SNDRV_PCM_FORMAT_U24_3BE: - return samples * 3; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_U24_BE: - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_U32_LE: - case SNDRV_PCM_FORMAT_U32_BE: - case SNDRV_PCM_FORMAT_FLOAT_LE: - case SNDRV_PCM_FORMAT_FLOAT_BE: - return samples * 4; - case SNDRV_PCM_FORMAT_FLOAT64_LE: - case SNDRV_PCM_FORMAT_FLOAT64_BE: - return samples * 8; - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE: - return samples * 4; - case SNDRV_PCM_FORMAT_MU_LAW: - case SNDRV_PCM_FORMAT_A_LAW: - return samples; - case SNDRV_PCM_FORMAT_IMA_ADPCM: - if (samples & 1) - return -EINVAL; - return samples / 2; - default: + int phys_width = snd_pcm_format_physical_width(format); + if (phys_width < 0) return -EINVAL; - } + return samples * phys_width / 8; } /** - * snd_pcm_format_silence_64 - return the silent data in 64bit integer + * snd_pcm_format_silence_64 - return the silent data in 8 bytes array * @format: the format to check * - * Returns the silent data in 64bit integer for the given format. + * Returns the format pattern to fill or NULL if error. */ -u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format) +const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) { - switch (snd_enum_to_int(format)) { - case SNDRV_PCM_FORMAT_S8: - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: - case SNDRV_PCM_FORMAT_S32_LE: - case SNDRV_PCM_FORMAT_S32_BE: - case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_S24_3BE: - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S20_3BE: - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_S18_3BE: - return 0; - case SNDRV_PCM_FORMAT_U8: - return 0x8080808080808080ULL; -#ifdef SNDRV_LITTLE_ENDIAN - case SNDRV_PCM_FORMAT_U16_LE: - return 0x8000800080008000ULL; - case SNDRV_PCM_FORMAT_U24_LE: - return 0x0080000000800000ULL; - case SNDRV_PCM_FORMAT_U32_LE: - return 0x8000000080000000ULL; - case SNDRV_PCM_FORMAT_U16_BE: - return 0x0080008000800080ULL; - case SNDRV_PCM_FORMAT_U24_BE: - return 0x0000800000008000ULL; - case SNDRV_PCM_FORMAT_U32_BE: - return 0x0000008000000080ULL; - case SNDRV_PCM_FORMAT_U24_3LE: - return 0x0000800000800000ULL; - case SNDRV_PCM_FORMAT_U24_3BE: - return 0x0080000080000080ULL; - case SNDRV_PCM_FORMAT_U20_3LE: - return 0x0000080000080000ULL; - case SNDRV_PCM_FORMAT_U20_3BE: - return 0x0008000008000008ULL; - case SNDRV_PCM_FORMAT_U18_3LE: - return 0x0000020000020000ULL; - case SNDRV_PCM_FORMAT_U18_3BE: - return 0x0002000002000002ULL; -#else - case SNDRV_PCM_FORMAT_U16_LE: - return 0x0080008000800080ULL; - case SNDRV_PCM_FORMAT_U24_LE: - return 0x0000800000008000ULL; - case SNDRV_PCM_FORMAT_U32_LE: - return 0x0000008000000080ULL; - case SNDRV_PCM_FORMAT_U16_BE: - return 0x8000800080008000ULL; - case SNDRV_PCM_FORMAT_U24_BE: - return 0x0080000000800000ULL; - case SNDRV_PCM_FORMAT_U32_BE: - return 0x8000000080000000ULL; - case SNDRV_PCM_FORMAT_U24_3LE: - return 0x0080000080000080ULL; - case SNDRV_PCM_FORMAT_U24_3BE: - return 0x0000800000800000ULL; - case SNDRV_PCM_FORMAT_U20_3LE: - return 0x0008000008000008ULL; - case SNDRV_PCM_FORMAT_U20_3BE: - return 0x0000080000080000ULL; - case SNDRV_PCM_FORMAT_U18_3LE: - return 0x0002000002000002ULL; - case SNDRV_PCM_FORMAT_U18_3BE: - return 0x0000020000020000ULL; -#endif - case SNDRV_PCM_FORMAT_FLOAT_LE: - { - union { - float f; - u_int32_t i; - } u; - u.f = 0.0; -#ifdef SNDRV_LITTLE_ENDIAN - return u.i; -#else - return bswap_32(u.i); -#endif - } - case SNDRV_PCM_FORMAT_FLOAT64_LE: - { - union { - double f; - u_int64_t i; - } u; - u.f = 0.0; -#ifdef SNDRV_LITTLE_ENDIAN - return u.i; -#else - return bswap_64(u.i); -#endif - } - case SNDRV_PCM_FORMAT_FLOAT_BE: - { - union { - float f; - u_int32_t i; - } u; - u.f = 0.0; -#ifdef SNDRV_LITTLE_ENDIAN - return bswap_32(u.i); -#else - return u.i; -#endif - } - case SNDRV_PCM_FORMAT_FLOAT64_BE: - { - union { - double f; - u_int64_t i; - } u; - u.f = 0.0; -#ifdef SNDRV_LITTLE_ENDIAN - return bswap_64(u.i); -#else - return u.i; -#endif - } - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE: - case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE: - return 0; - case SNDRV_PCM_FORMAT_MU_LAW: - return 0x7f7f7f7f7f7f7f7fULL; - case SNDRV_PCM_FORMAT_A_LAW: - return 0x5555555555555555ULL; - case SNDRV_PCM_FORMAT_IMA_ADPCM: /* special case */ - case SNDRV_PCM_FORMAT_MPEG: - case SNDRV_PCM_FORMAT_GSM: - case SNDRV_PCM_FORMAT_SPECIAL: - return 0; - default: - return -EINVAL; - } - return 0; -} - -u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format) -{ - return (u_int32_t)snd_pcm_format_silence_64(format); -} - -u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format) -{ - return (u_int16_t)snd_pcm_format_silence_64(format); -} - -u_int8_t snd_pcm_format_silence(snd_pcm_format_t format) -{ - return (u_int8_t)snd_pcm_format_silence_64(format); + if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) + return NULL; + if (! pcm_formats[format].phys) + return NULL; + return pcm_formats[format].silence; } /** @@ -531,99 +358,73 @@ */ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples) { + int width; + unsigned char *dst, *pat; + + if (format < 0 || format > SNDRV_PCM_FORMAT_LAST) + return -EINVAL; if (samples == 0) return 0; - switch (snd_pcm_format_width(format)) { - case 4: { - u_int8_t silence = snd_pcm_format_silence_64(format); - unsigned int samples1; - if (samples % 2 != 0) - return -EINVAL; - samples1 = samples / 2; - memset(data, silence, samples1); - break; + width = pcm_formats[format].phys; /* physical width */ + pat = pcm_formats[format].silence; + if (! width) + return -EINVAL; + /* signed or 1 byte data */ + if (pcm_formats[format].signd == 1 || width <= 8) { + unsigned int bytes = samples * width / 8; + memset(data, *pat, bytes); + return 0; } - case 8: { - u_int8_t silence = snd_pcm_format_silence_64(format); - memset(data, silence, samples); - break; + /* non-zero samples, fill using a loop */ + width /= 8; + dst = data; +#if 0 + while (samples--) { + memcpy(dst, pat, width); + dst += width; } - case 16: { - u_int16_t silence = snd_pcm_format_silence_64(format); - if (! silence) - memset(data, 0, samples * 2); - else { - u_int16_t *data16 = data; - while (samples-- > 0) - *data16++ = silence; +#else + /* a bit optimization for constant width */ + switch (width) { + case 2: + while (samples--) { + memcpy(dst, pat, 2); + dst += 2; } break; - } - case 24: { - u_int32_t silence = snd_pcm_format_silence_64(format); - if (! silence) - memset(data, 0, samples * 3); - else { - while (samples-- > 0) { - u_int8_t *data8 = data; -#ifdef SNDRV_LITTLE_ENDIAN - *data8++ = silence >> 0; - *data8++ = silence >> 8; - *data8++ = silence >> 16; -#else - *data8++ = silence >> 16; - *data8++ = silence >> 8; - *data8++ = silence >> 0; -#endif - } + case 3: + while (samples--) { + memcpy(dst, pat, 3); + dst += 3; } break; - } - case 32: { - u_int32_t silence = snd_pcm_format_silence_64(format); - if (! silence) - memset(data, 0, samples * 4); - else { - u_int32_t *data32 = data; - while (samples-- > 0) - *data32++ = silence; + case 4: + while (samples--) { + memcpy(dst, pat, 4); + dst += 4; } break; - } - case 64: { - u_int64_t silence = snd_pcm_format_silence_64(format); - if (! silence) - memset(data, 0, samples * 8); - else { - u_int64_t *data64 = data; - while (samples-- > 0) - *data64++ = silence; + case 8: + while (samples--) { + memcpy(dst, pat, 8); + dst += 8; } break; } - default: - return -EINVAL; - } +#endif return 0; } -static int linear_formats[4*2*2] = { - SNDRV_PCM_FORMAT_S8, - SNDRV_PCM_FORMAT_S8, - SNDRV_PCM_FORMAT_U8, - SNDRV_PCM_FORMAT_U8, - SNDRV_PCM_FORMAT_S16_LE, - SNDRV_PCM_FORMAT_S16_BE, - SNDRV_PCM_FORMAT_U16_LE, - SNDRV_PCM_FORMAT_U16_BE, - SNDRV_PCM_FORMAT_S24_LE, - SNDRV_PCM_FORMAT_S24_BE, - SNDRV_PCM_FORMAT_U24_LE, - SNDRV_PCM_FORMAT_U24_BE, - SNDRV_PCM_FORMAT_S32_LE, - SNDRV_PCM_FORMAT_S32_BE, - SNDRV_PCM_FORMAT_U32_LE, - SNDRV_PCM_FORMAT_U32_BE +/* [width][unsigned][bigendian] */ +static int linear_formats[4][2][2] = { + {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, + { SNDRV_PCM_FORMAT_U8, SNDRV_PCM_FORMAT_U8}}, + {{SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_FORMAT_S16_BE}, + {SNDRV_PCM_FORMAT_U16_LE, SNDRV_PCM_FORMAT_U16_BE}}, + {{SNDRV_PCM_FORMAT_S24_LE, SNDRV_PCM_FORMAT_S24_BE}, + {SNDRV_PCM_FORMAT_U24_LE, SNDRV_PCM_FORMAT_U24_BE}}, + {{SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_S32_BE}, + {SNDRV_PCM_FORMAT_U32_LE, SNDRV_PCM_FORMAT_U32_BE}} }; /** @@ -636,23 +437,12 @@ */ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian) { - switch (width) { - case 8: - width = 0; - break; - case 16: - width = 1; - break; - case 24: - width = 2; - break; - case 32: - width = 3; - break; - default: + if (width & 7) return SND_PCM_FORMAT_UNKNOWN; - } - return snd_int_to_enum(((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian]); + width = (width / 8) - 1; + if (width < 0 || width >= 4) + return SND_PCM_FORMAT_UNKNOWN; + return linear_formats[width][!!unsignd][!!big_endian]; } /** diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c --- a/sound/core/pcm_native.c 2004-06-23 11:51:27 -07:00 +++ b/sound/core/pcm_native.c 2004-06-23 11:51:27 -07:00 @@ -304,13 +304,25 @@ static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params) { - snd_pcm_hw_params_t params; + snd_pcm_hw_params_t *params; int err; - if (copy_from_user(¶ms, _params, sizeof(params))) - return -EFAULT; - err = snd_pcm_hw_refine(substream, ¶ms); - if (copy_to_user(_params, ¶ms, sizeof(params))) - return -EFAULT; + + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) { + err = -ENOMEM; + goto out; + } + if (copy_from_user(params, _params, sizeof(*params))) { + err = -EFAULT; + goto out; + } + err = snd_pcm_hw_refine(substream, params); + if (copy_to_user(_params, params, sizeof(*params))) { + if (!err) + err = -EFAULT; + } +out: + kfree(params); return err; } @@ -408,13 +420,25 @@ static int snd_pcm_hw_params_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params) { - snd_pcm_hw_params_t params; + snd_pcm_hw_params_t *params; int err; - if (copy_from_user(¶ms, _params, sizeof(params))) - return -EFAULT; - err = snd_pcm_hw_params(substream, ¶ms); - if (copy_to_user(_params, ¶ms, sizeof(params))) - return -EFAULT; + + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) { + err = -ENOMEM; + goto out; + } + if (copy_from_user(params, _params, sizeof(*params))) { + err = -EFAULT; + goto out; + } + err = snd_pcm_hw_params(substream, params); + if (copy_to_user(_params, params, sizeof(*params))) { + if (!err) + err = -EFAULT; + } +out: + kfree(params); return err; } @@ -3009,6 +3033,12 @@ .nopage = snd_pcm_mmap_data_nopage, }; +static struct vm_operations_struct snd_pcm_vm_ops_data_mmio = +{ + .open = snd_pcm_mmap_data_open, + .close = snd_pcm_mmap_data_close, +}; + int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file, struct vm_area_struct *area) { @@ -3044,6 +3074,14 @@ area->vm_ops = &snd_pcm_vm_ops_data; area->vm_private_data = substream; area->vm_flags |= VM_RESERVED; + if (runtime->hw.info & SNDRV_PCM_INFO_MMAP_IOMEM) { + area->vm_ops = &snd_pcm_vm_ops_data_mmio; + area->vm_flags |= VM_IO; + if (io_remap_page_range(area, area->vm_start, + runtime->dma_addr + offset, + size, area->vm_page_prot)) + return -EAGAIN; + } atomic_inc(&runtime->mmap_count); return 0; } @@ -3133,31 +3171,68 @@ static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams) { - snd_pcm_hw_params_t params; - struct sndrv_pcm_hw_params_old oparams; + snd_pcm_hw_params_t *params; + struct sndrv_pcm_hw_params_old *oparams = NULL; int err; - if (copy_from_user(&oparams, _oparams, sizeof(oparams))) - return -EFAULT; - snd_pcm_hw_convert_from_old_params(¶ms, &oparams); - err = snd_pcm_hw_refine(substream, ¶ms); - snd_pcm_hw_convert_to_old_params(&oparams, ¶ms); - if (copy_to_user(_oparams, &oparams, sizeof(oparams))) - return -EFAULT; + + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) { + err = -ENOMEM; + goto out; + } + oparams = kmalloc(sizeof(*oparams), GFP_KERNEL); + if (!oparams) { + err = -ENOMEM; + goto out; + } + + if (copy_from_user(oparams, _oparams, sizeof(*oparams))) { + err = -EFAULT; + goto out; + } + snd_pcm_hw_convert_from_old_params(params, oparams); + err = snd_pcm_hw_refine(substream, params); + snd_pcm_hw_convert_to_old_params(oparams, params); + if (copy_to_user(_oparams, oparams, sizeof(*oparams))) { + if (!err) + err = -EFAULT; + } +out: + kfree(params); + kfree(oparams); return err; } static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams) { - snd_pcm_hw_params_t params; - struct sndrv_pcm_hw_params_old oparams; + snd_pcm_hw_params_t *params; + struct sndrv_pcm_hw_params_old *oparams = NULL; int err; - if (copy_from_user(&oparams, _oparams, sizeof(oparams))) - return -EFAULT; - snd_pcm_hw_convert_from_old_params(¶ms, &oparams); - err = snd_pcm_hw_params(substream, ¶ms); - snd_pcm_hw_convert_to_old_params(&oparams, ¶ms); - if (copy_to_user(_oparams, &oparams, sizeof(oparams))) - return -EFAULT; + + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) { + err = -ENOMEM; + goto out; + } + oparams = kmalloc(sizeof(*oparams), GFP_KERNEL); + if (!oparams) { + err = -ENOMEM; + goto out; + } + if (copy_from_user(oparams, _oparams, sizeof(*oparams))) { + err = -EFAULT; + goto out; + } + snd_pcm_hw_convert_from_old_params(params, oparams); + err = snd_pcm_hw_params(substream, params); + snd_pcm_hw_convert_to_old_params(oparams, params); + if (copy_to_user(_oparams, oparams, sizeof(*oparams))) { + if (!err) + err = -EFAULT; + } +out: + kfree(params); + kfree(oparams); return err; } diff -Nru a/sound/core/seq/oss/seq_oss_ioctl.c b/sound/core/seq/oss/seq_oss_ioctl.c --- a/sound/core/seq/oss/seq_oss_ioctl.c 2004-06-23 11:51:27 -07:00 +++ b/sound/core/seq/oss/seq_oss_ioctl.c 2004-06-23 11:51:27 -07:00 @@ -28,16 +28,54 @@ #include "seq_oss_midi.h" #include "seq_oss_event.h" +static int snd_seq_oss_synth_info_user(seq_oss_devinfo_t *dp, void __user *arg) +{ + struct synth_info info; + + if (copy_from_user(&info, arg, sizeof(info))) + return -EFAULT; + if (snd_seq_oss_synth_make_info(dp, info.device, &info) < 0) + return -EINVAL; + if (copy_to_user(arg, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static int snd_seq_oss_midi_info_user(seq_oss_devinfo_t *dp, void __user *arg) +{ + struct midi_info info; + + if (copy_from_user(&info, arg, sizeof(info))) + return -EFAULT; + if (snd_seq_oss_midi_make_info(dp, info.device, &info) < 0) + return -EINVAL; + if (copy_to_user(arg, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static int snd_seq_oss_oob_user(seq_oss_devinfo_t *dp, void __user *arg) +{ + unsigned char ev[8]; + snd_seq_event_t tmpev; + + if (copy_from_user(ev, arg, 8)) + return -EFAULT; + memset(&tmpev, 0, sizeof(tmpev)); + snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client); + tmpev.time.tick = 0; + if (! snd_seq_oss_process_event(dp, (evrec_t*)ev, &tmpev)) { + snd_seq_oss_dispatch(dp, &tmpev, 0, 0); + } + return 0; +} + int snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg) { int dev, val; - struct synth_info inf; - struct midi_info minf; - unsigned char ev[8]; void __user *arg = (void __user *)carg; int __user *p = arg; - snd_seq_event_t tmpev; switch (cmd) { case SNDCTL_TMR_TIMEBASE: @@ -124,35 +162,15 @@ case SNDCTL_SYNTH_INFO: case SNDCTL_SYNTH_ID: debug_printk(("synth info\n")); - if (copy_from_user(&inf, arg, sizeof(inf))) - return -EFAULT; - if (snd_seq_oss_synth_make_info(dp, inf.device, &inf) < 0) - return -EINVAL; - if (copy_to_user(arg, &inf, sizeof(inf))) - return -EFAULT; - return 0; + return snd_seq_oss_synth_info_user(dp, arg); case SNDCTL_SEQ_OUTOFBAND: - debug_printk(("out of bound\n")); - if (copy_from_user(ev, arg, 8)) - return -EFAULT; - memset(&tmpev, 0, sizeof(tmpev)); - snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client); - tmpev.time.tick = 0; - if (! snd_seq_oss_process_event(dp, (evrec_t*)ev, &tmpev)) { - snd_seq_oss_dispatch(dp, &tmpev, 0, 0); - } - return 0; + debug_printk(("out of band\n")); + return snd_seq_oss_oob_user(dp, arg); case SNDCTL_MIDI_INFO: debug_printk(("midi info\n")); - if (copy_from_user(&minf, arg, sizeof(minf))) - return -EFAULT; - if (snd_seq_oss_midi_make_info(dp, minf.device, &minf) < 0) - return -EINVAL; - if (copy_to_user(arg, &minf, sizeof(minf))) - return -EFAULT; - return 0; + return snd_seq_oss_midi_info_user(dp, arg); case SNDCTL_SEQ_THRESHOLD: debug_printk(("threshold\n")); 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-23 11:51:27 -07:00 +++ b/sound/core/seq/oss/seq_oss_timer.c 2004-06-23 11:51:27 -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-23 11:51:28 -07:00 +++ b/sound/core/seq/seq.c 2004-06-23 11:51:28 -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-23 11:51:27 -07:00 +++ b/sound/core/seq/seq_clientmgr.c 2004-06-23 11:51:27 -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/dummy.c b/sound/drivers/dummy.c --- a/sound/drivers/dummy.c 2004-06-23 11:51:28 -07:00 +++ b/sound/drivers/dummy.c 2004-06-23 11:51:28 -07:00 @@ -180,20 +180,6 @@ static snd_card_t *snd_dummy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; -static int snd_card_dummy_playback_ioctl(snd_pcm_substream_t * substream, - unsigned int cmd, - void *arg) -{ - return snd_pcm_lib_ioctl(substream, cmd, arg); -} - -static int snd_card_dummy_capture_ioctl(snd_pcm_substream_t * substream, - unsigned int cmd, - void *arg) -{ - return snd_pcm_lib_ioctl(substream, cmd, arg); -} - static void snd_card_dummy_pcm_timer_start(snd_pcm_substream_t * substream) { snd_pcm_runtime_t *runtime = substream->runtime; @@ -342,6 +328,17 @@ snd_magic_kfree(dpcm); } +static int snd_card_dummy_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) +{ + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); +} + +static int snd_card_dummy_hw_free(snd_pcm_substream_t * substream) +{ + return snd_pcm_lib_free_pages(substream); +} + static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream) { snd_pcm_runtime_t *runtime = substream->runtime; @@ -351,10 +348,6 @@ dpcm = snd_magic_kcalloc(snd_card_dummy_pcm_t, 0, GFP_KERNEL); if (dpcm == NULL) return -ENOMEM; - if ((runtime->dma_area = snd_malloc_pages_fallback(MAX_BUFFER_SIZE, GFP_KERNEL, &runtime->dma_bytes)) == NULL) { - snd_magic_kfree(dpcm); - return -ENOMEM; - } init_timer(&dpcm->timer); dpcm->timer.data = (unsigned long) dpcm; dpcm->timer.function = snd_card_dummy_pcm_timer_function; @@ -386,11 +379,6 @@ dpcm = snd_magic_kcalloc(snd_card_dummy_pcm_t, 0, GFP_KERNEL); if (dpcm == NULL) return -ENOMEM; - if ((runtime->dma_area = snd_malloc_pages_fallback(MAX_BUFFER_SIZE, GFP_KERNEL, &runtime->dma_bytes)) == NULL) { - snd_magic_kfree(dpcm); - return -ENOMEM; - } - memset(runtime->dma_area, 0, runtime->dma_bytes); init_timer(&dpcm->timer); dpcm->timer.data = (unsigned long) dpcm; dpcm->timer.function = snd_card_dummy_pcm_timer_function; @@ -415,24 +403,20 @@ static int snd_card_dummy_playback_close(snd_pcm_substream_t * substream) { - snd_pcm_runtime_t *runtime = substream->runtime; - - snd_free_pages(runtime->dma_area, runtime->dma_bytes); return 0; } static int snd_card_dummy_capture_close(snd_pcm_substream_t * substream) { - snd_pcm_runtime_t *runtime = substream->runtime; - - snd_free_pages(runtime->dma_area, runtime->dma_bytes); return 0; } static snd_pcm_ops_t snd_card_dummy_playback_ops = { .open = snd_card_dummy_playback_open, .close = snd_card_dummy_playback_close, - .ioctl = snd_card_dummy_playback_ioctl, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_card_dummy_hw_params, + .hw_free = snd_card_dummy_hw_free, .prepare = snd_card_dummy_playback_prepare, .trigger = snd_card_dummy_playback_trigger, .pointer = snd_card_dummy_playback_pointer, @@ -441,7 +425,9 @@ static snd_pcm_ops_t snd_card_dummy_capture_ops = { .open = snd_card_dummy_capture_open, .close = snd_card_dummy_capture_close, - .ioctl = snd_card_dummy_capture_ioctl, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_card_dummy_hw_params, + .hw_free = snd_card_dummy_hw_free, .prepare = snd_card_dummy_capture_prepare, .trigger = snd_card_dummy_capture_trigger, .pointer = snd_card_dummy_capture_pointer, @@ -459,6 +445,9 @@ pcm->private_data = dummy; pcm->info_flags = 0; strcpy(pcm->name, "Dummy PCM"); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + 0, 64*1024); return 0; } diff -Nru a/sound/drivers/opl4/Makefile b/sound/drivers/opl4/Makefile --- a/sound/drivers/opl4/Makefile 2004-06-23 11:51:28 -07:00 +++ b/sound/drivers/opl4/Makefile 2004-06-23 11:51:28 -07:00 @@ -15,4 +15,4 @@ sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) obj-$(CONFIG_SND_OPL4_LIB) += snd-opl4-lib.o -obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-opl4-synth.o \ No newline at end of file +obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-opl4-synth.o 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-23 11:51:28 -07:00 +++ b/sound/drivers/vx/vx_core.c 2004-06-23 11:51:28 -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-23 11:51:27 -07:00 +++ b/sound/drivers/vx/vx_mixer.c 2004-06-23 11:51:27 -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-23 11:51:27 -07:00 +++ b/sound/drivers/vx/vx_pcm.c 2004-06-23 11:51:27 -07:00 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -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-23 11:51:27 -07:00 +++ b/sound/drivers/vx/vx_uer.c 2004-06-23 11:51:27 -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/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c --- a/sound/isa/opti9xx/opti92x-ad1848.c 2004-06-23 11:51:27 -07:00 +++ b/sound/isa/opti9xx/opti92x-ad1848.c 2004-06-23 11:51:27 -07:00 @@ -474,7 +474,6 @@ unsigned char dma_bits; unsigned char mpu_port_bits = 0; unsigned char mpu_irq_bits; - unsigned long flags; switch (chip->hardware) { #ifndef OPTi93X @@ -601,13 +600,11 @@ dma_bits |= 0x04; #endif /* CS4231 || OPTi93X */ - spin_lock_irqsave(&chip->lock, flags); #ifndef OPTi93X outb(irq_bits << 3 | dma_bits, chip->wss_base); #else /* OPTi93X */ snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); #endif /* OPTi93X */ - spin_unlock_irqrestore(&chip->lock, flags); __skip_resources: if (chip->hardware > OPTi9XX_HW_82C928) { @@ -767,15 +764,10 @@ static void snd_opti93x_mute(opti93x_t *chip, int mute) { - unsigned long flags; - - spin_lock_irqsave(&chip->lock, flags); - mute = mute ? 1 : 0; - if (chip->mute == mute) { - spin_unlock_irqrestore(&chip->lock, flags); + if (chip->mute == mute) return; - } + chip->mute = mute; snd_opti93x_mute_reg(chip, OPTi93X_CD_LEFT_INPUT, mute); @@ -800,8 +792,6 @@ snd_opti93x_mute_reg(chip, OPTi93X_MIC_RIGHT_INPUT, mute); snd_opti93x_mute_reg(chip, OPTi93X_OUT_LEFT, mute); snd_opti93x_mute_reg(chip, OPTi93X_OUT_RIGHT, mute); - - spin_unlock_irqrestore(&chip->lock, flags); } @@ -873,10 +863,8 @@ static void snd_opti93x_playback_format(opti93x_t *chip, unsigned char fmt) { - unsigned long flags; unsigned char mask; - spin_lock_irqsave(&chip->lock, flags); snd_opti93x_mute(chip, 1); snd_opti93x_mce_up(chip); @@ -885,14 +873,10 @@ snd_opti93x_mce_down(chip); snd_opti93x_mute(chip, 0); - spin_unlock_irqrestore(&chip->lock, flags); } static void snd_opti93x_capture_format(opti93x_t *chip, unsigned char fmt) { - unsigned long flags; - - spin_lock_irqsave(&chip->lock, flags); snd_opti93x_mute(chip, 1); snd_opti93x_mce_up(chip); @@ -904,7 +888,6 @@ snd_opti93x_mce_down(chip); snd_opti93x_mute(chip, 0); - spin_unlock_irqrestore(&chip->lock, flags); } 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-23 11:51:27 -07:00 +++ b/sound/isa/wavefront/wavefront_synth.c 2004-06-23 11:51:27 -07:00 @@ -1961,6 +1961,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-23 11:51:27 -07:00 +++ b/sound/parisc/harmony.c 2004-06-23 11:51:27 -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-23 11:51:27 -07:00 +++ b/sound/pci/ac97/ac97_codec.c 2004-06-23 11:51:27 -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-23 11:51:28 -07:00 +++ b/sound/pci/ac97/ac97_id.h 2004-06-23 11:51:28 -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-23 11:51:27 -07:00 +++ b/sound/pci/ac97/ac97_local.h 2004-06-23 11:51:27 -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-23 11:51:28 -07:00 +++ b/sound/pci/ac97/ac97_patch.c 2004-06-23 11:51:28 -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-23 11:51:27 -07:00 +++ b/sound/pci/ac97/ac97_patch.h 2004-06-23 11:51:27 -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-23 11:51:28 -07:00 +++ b/sound/pci/ac97/ac97_proc.c 2004-06-23 11:51:28 -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", ®, &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-23 11:51:27 -07:00 +++ b/sound/pci/atiixp.c 2004-06-23 11:51:27 -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 * @@ -996,6 +996,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_48000, @@ -1387,17 +1388,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/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c --- a/sound/pci/au88x0/au88x0_a3d.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/au88x0/au88x0_a3d.c 2004-06-23 11:51:27 -07:00 @@ -864,7 +864,7 @@ if ((kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, vortex)) == NULL) return -ENOMEM; - kcontrol->private_value = (int)&(vortex->a3d[i]); + kcontrol->private_value = (long)&(vortex->a3d[i]); kcontrol->id.numid = CTRLID_HRTF; kcontrol->info = snd_vortex_a3d_hrtf_info; kcontrol->put = snd_vortex_a3d_hrtf_put; @@ -876,7 +876,7 @@ if ((kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, vortex)) == NULL) return -ENOMEM; - kcontrol->private_value = (int)&(vortex->a3d[i]); + kcontrol->private_value = (long)&(vortex->a3d[i]); kcontrol->id.numid = CTRLID_ITD; kcontrol->info = snd_vortex_a3d_itd_info; kcontrol->put = snd_vortex_a3d_itd_put; @@ -888,7 +888,7 @@ if ((kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, vortex)) == NULL) return -ENOMEM; - kcontrol->private_value = (int)&(vortex->a3d[i]); + kcontrol->private_value = (long)&(vortex->a3d[i]); kcontrol->id.numid = CTRLID_GAINS; kcontrol->info = snd_vortex_a3d_ild_info; kcontrol->put = snd_vortex_a3d_ild_put; @@ -900,7 +900,7 @@ if ((kcontrol = snd_ctl_new1(&vortex_a3d_kcontrol, vortex)) == NULL) return -ENOMEM; - kcontrol->private_value = (int)&(vortex->a3d[i]); + kcontrol->private_value = (long)&(vortex->a3d[i]); kcontrol->id.numid = CTRLID_FILTER; kcontrol->info = snd_vortex_a3d_filter_info; kcontrol->put = snd_vortex_a3d_filter_put; diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c --- a/sound/pci/cmipci.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/cmipci.c 2004-06-23 11:51:28 -07:00 @@ -1072,30 +1072,36 @@ */ /* save mixer setting and mute for AC3 playback */ -static void save_mixer_state(cmipci_t *cm) +static int save_mixer_state(cmipci_t *cm) { if (! cm->mixer_insensitive) { + snd_ctl_elem_value_t *val; unsigned int i; + + val = kmalloc(sizeof(*val), GFP_ATOMIC); + if (!val) + return -ENOMEM; for (i = 0; i < CM_SAVED_MIXERS; i++) { snd_kcontrol_t *ctl = cm->mixer_res_ctl[i]; if (ctl) { - snd_ctl_elem_value_t val; int event; - memset(&val, 0, sizeof(val)); - ctl->get(ctl, &val); - cm->mixer_res_status[i] = val.value.integer.value[0]; - val.value.integer.value[0] = cm_saved_mixer[i].toggle_on; + memset(val, 0, sizeof(*val)); + ctl->get(ctl, val); + cm->mixer_res_status[i] = val->value.integer.value[0]; + val->value.integer.value[0] = cm_saved_mixer[i].toggle_on; event = SNDRV_CTL_EVENT_MASK_INFO; - if (cm->mixer_res_status[i] != val.value.integer.value[0]) { - ctl->put(ctl, &val); /* toggle */ + if (cm->mixer_res_status[i] != val->value.integer.value[0]) { + ctl->put(ctl, val); /* toggle */ event |= SNDRV_CTL_EVENT_MASK_VALUE; } ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(cm->card, event, &ctl->id); } } + kfree(val); cm->mixer_insensitive = 1; } + return 0; } @@ -1103,27 +1109,32 @@ static void restore_mixer_state(cmipci_t *cm) { if (cm->mixer_insensitive) { + snd_ctl_elem_value_t *val; unsigned int i; + + val = kmalloc(sizeof(*val), GFP_KERNEL); + if (!val) + return; cm->mixer_insensitive = 0; /* at first clear this; otherwise the changes will be ignored */ for (i = 0; i < CM_SAVED_MIXERS; i++) { snd_kcontrol_t *ctl = cm->mixer_res_ctl[i]; if (ctl) { - snd_ctl_elem_value_t val; int event; - memset(&val, 0, sizeof(val)); + memset(val, 0, sizeof(*val)); ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; - ctl->get(ctl, &val); + ctl->get(ctl, val); event = SNDRV_CTL_EVENT_MASK_INFO; - if (val.value.integer.value[0] != cm->mixer_res_status[i]) { - val.value.integer.value[0] = cm->mixer_res_status[i]; - ctl->put(ctl, &val); + if (val->value.integer.value[0] != cm->mixer_res_status[i]) { + val->value.integer.value[0] = cm->mixer_res_status[i]; + ctl->put(ctl, val); event |= SNDRV_CTL_EVENT_MASK_VALUE; } snd_ctl_notify(cm->card, event, &ctl->id); } } + kfree(val); } } @@ -1175,15 +1186,16 @@ } } -static void setup_spdif_playback(cmipci_t *cm, snd_pcm_substream_t *subs, int up, int do_ac3) +static int setup_spdif_playback(cmipci_t *cm, snd_pcm_substream_t *subs, int up, int do_ac3) { - int rate; + int rate, err; unsigned long flags; rate = subs->runtime->rate; if (up && do_ac3) - save_mixer_state(cm); + if ((err = save_mixer_state(cm)) < 0) + return err; spin_lock_irqsave(&cm->reg_lock, flags); cm->spdif_playback_avail = up; @@ -1208,6 +1220,7 @@ setup_ac3(cm, subs, 0, 0); } spin_unlock_irqrestore(&cm->reg_lock, flags); + return 0; } @@ -1220,13 +1233,15 @@ { cmipci_t *cm = snd_pcm_substream_chip(substream); int rate = substream->runtime->rate; - int do_spdif, do_ac3 = 0; + int err, do_spdif, do_ac3 = 0; + do_spdif = ((rate == 44100 || rate == 48000) && substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE && substream->runtime->channels == 2); if (do_spdif && cm->can_ac3_hw) do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO; - setup_spdif_playback(cm, substream, do_spdif, do_ac3); + if ((err = setup_spdif_playback(cm, substream, do_spdif, do_ac3)) < 0) + return err; return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream); } @@ -1234,12 +1249,14 @@ static int snd_cmipci_playback_spdif_prepare(snd_pcm_substream_t *substream) { cmipci_t *cm = snd_pcm_substream_chip(substream); - int do_ac3; + int err, do_ac3; + if (cm->can_ac3_hw) do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO; else do_ac3 = 1; /* doesn't matter */ - setup_spdif_playback(cm, substream, 1, do_ac3); + if ((err = setup_spdif_playback(cm, substream, 1, do_ac3)) < 0) + return err; return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream); } diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c --- a/sound/pci/cs46xx/dsp_spos.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/cs46xx/dsp_spos.c 2004-06-23 11:51:28 -07:00 @@ -1057,7 +1057,7 @@ int fifo_addr,fifo_span,valid_slots; - spos_control_block_t sposcb = { + static spos_control_block_t sposcb = { /* 0 */ HFG_TREE_SCB,HFG_STACK, /* 1 */ SPOSCB_ADDR,BG_TREE_SCB_ADDR, /* 2 */ DSP_SPOS_DC,0, @@ -1110,18 +1110,18 @@ { /* create the null SCB */ - generic_scb_t null_scb = { + static generic_scb_t null_scb = { { 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, NULL_SCB_ADDR, NULL_SCB_ADDR, - null_algorithm->address, 0, - 0,0,0, + 0, 0, 0, 0, 0, { 0,0, 0,0, } }; + null_scb.entry_point = null_algorithm->address; ins->the_null_scb = cs46xx_dsp_create_scb(chip, "nullSCB", (u32 *)&null_scb, NULL_SCB_ADDR); ins->the_null_scb->task_entry = null_algorithm; ins->the_null_scb->sub_list_ptr = ins->the_null_scb; @@ -1132,7 +1132,7 @@ { /* setup foreground task tree */ - task_tree_control_block_t fg_task_tree_hdr = { + static task_tree_control_block_t fg_task_tree_hdr = { { FG_TASK_HEADER_ADDR | (DSP_SPOS_DC << 0x10), DSP_SPOS_DC_DC, DSP_SPOS_DC_DC, @@ -1145,7 +1145,7 @@ { BG_TREE_SCB_ADDR,TIMINGMASTER_SCB_ADDR, - fg_task_tree_header_code->address, + 0, FG_TASK_HEADER_ADDR + TCBData, }, @@ -1158,7 +1158,7 @@ }, { - DSP_SPOS_DC,task_tree_thread->address, + DSP_SPOS_DC,0, DSP_SPOS_DC,DSP_SPOS_DC, DSP_SPOS_DC,DSP_SPOS_DC, DSP_SPOS_DC,DSP_SPOS_DC, @@ -1200,13 +1200,15 @@ } }; + fg_task_tree_hdr.links.entry_point = fg_task_tree_header_code->address; + fg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address; cs46xx_dsp_create_task_tree(chip,"FGtaskTreeHdr",(u32 *)&fg_task_tree_hdr,FG_TASK_HEADER_ADDR,0x35); } { /* setup foreground task tree */ - task_tree_control_block_t bg_task_tree_hdr = { + static task_tree_control_block_t bg_task_tree_hdr = { { DSP_SPOS_DC_DC, DSP_SPOS_DC_DC, DSP_SPOS_DC_DC, @@ -1219,7 +1221,7 @@ { NULL_SCB_ADDR,NULL_SCB_ADDR, /* Set up the background to do nothing */ - task_tree_header_code->address, + 0, BG_TREE_SCB_ADDR + TCBData, }, @@ -1232,7 +1234,7 @@ }, { - DSP_SPOS_DC,task_tree_thread->address, + DSP_SPOS_DC,0, DSP_SPOS_DC,DSP_SPOS_DC, DSP_SPOS_DC,DSP_SPOS_DC, DSP_SPOS_DC,DSP_SPOS_DC, @@ -1273,6 +1275,9 @@ 0,0 } }; + + bg_task_tree_hdr.links.entry_point = task_tree_header_code->address; + bg_task_tree_hdr.context_blk.stack0 = task_tree_thread->address; cs46xx_dsp_create_task_tree(chip,"BGtaskTreeHdr",(u32 *)&bg_task_tree_hdr,BG_TREE_SCB_ADDR,0x35); } @@ -1312,7 +1317,7 @@ if (!write_back_scb) goto _fail_end; { - mix2_ostream_spb_t mix2_ostream_spb = { + static mix2_ostream_spb_t mix2_ostream_spb = { 0x00020000, 0x0000ffff }; diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c --- a/sound/pci/emu10k1/emu10k1.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/emu10k1/emu10k1.c 2004-06-23 11:51:27 -07:00 @@ -134,10 +134,6 @@ snd_card_free(card); return err; } - if ((err = snd_emu10k1_fx8010_pcm(emu, 3, NULL)) < 0) { - snd_card_free(card); - return err; - } if ((err = snd_emu10k1_mixer(emu)) < 0) { snd_card_free(card); return err; diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c --- a/sound/pci/emu10k1/emufx.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/emu10k1/emufx.c 2004-06-23 11:51:27 -07:00 @@ -405,7 +405,7 @@ } } -static int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu, +int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu, snd_fx8010_irq_handler_t *handler, unsigned char gpr_running, void *private_data, @@ -438,7 +438,7 @@ return 0; } -static int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu, +int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu, snd_emu10k1_fx8010_irq_t *irq) { snd_emu10k1_fx8010_irq_t *tmp; @@ -460,312 +460,6 @@ } spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags); kfree(irq); - return 0; -} - -/* - * PCM streams - */ - -#define INITIAL_TRAM_SHIFT 14 -#define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1) - -static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data) -{ - snd_pcm_substream_t *substream = snd_magic_cast(snd_pcm_substream_t, private_data, return); - snd_pcm_period_elapsed(substream); -} - -static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left, - unsigned short *dst_right, - unsigned short *src, - unsigned int count, - unsigned int tram_shift) -{ - // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); - if ((tram_shift & 1) == 0) { - while (count--) { - *dst_left-- = *src++; - *dst_right-- = *src++; - } - } else { - while (count--) { - *dst_right-- = *src++; - *dst_left-- = *src++; - } - } -} - -static void snd_emu10k1_fx8010_playback_tram_poke(emu10k1_t *emu, - unsigned int *tram_pos, - unsigned int *tram_shift, - unsigned int tram_size, - unsigned short *src, - unsigned int frames) -{ - unsigned int count; - - while (frames > *tram_pos) { - count = *tram_pos + 1; - snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos, - (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2, - src, count, *tram_shift); - src += count * 2; - frames -= count; - *tram_pos = (tram_size / 2) - 1; - (*tram_shift)++; - } - snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos, - (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2, - src, frames, *tram_shift++); - *tram_pos -= frames; -} - -static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr; - snd_pcm_sframes_t diff = appl_ptr - pcm->appl_ptr; - snd_pcm_uframes_t buffer_size = pcm->buffer_size / 2; - - if (diff) { - if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) - diff += runtime->boundary; - pcm->sw_ready += diff; - pcm->appl_ptr = appl_ptr; - } - while (pcm->hw_ready < buffer_size && - pcm->sw_ready > 0) { - size_t hw_to_end = buffer_size - pcm->hw_data; - size_t sw_to_end = (runtime->buffer_size << 2) - pcm->sw_data; - size_t tframes = buffer_size - pcm->hw_ready; - if (pcm->sw_ready < tframes) - tframes = pcm->sw_ready; - if (hw_to_end < tframes) - tframes = hw_to_end; - if (sw_to_end < tframes) - tframes = sw_to_end; - snd_emu10k1_fx8010_playback_tram_poke(emu, &pcm->tram_pos, &pcm->tram_shift, - pcm->buffer_size, - (unsigned short *)(runtime->dma_area + (pcm->sw_data << 2)), - tframes); - pcm->hw_data += tframes; - if (pcm->hw_data == buffer_size) - pcm->hw_data = 0; - pcm->sw_data += tframes; - if (pcm->sw_data == runtime->buffer_size) - pcm->sw_data = 0; - pcm->hw_ready += tframes; - pcm->sw_ready -= tframes; - } - return 0; -} - -static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream, - snd_pcm_hw_params_t * hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); -} - -static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - unsigned int i; - - for (i = 0; i < pcm->channels; i++) - snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0); - snd_pcm_lib_free_pages(substream); - return 0; -} - -static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - unsigned int i; - - // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); - pcm->sw_data = pcm->sw_io = pcm->sw_ready = 0; - pcm->hw_data = pcm->hw_io = pcm->hw_ready = 0; - pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size); - pcm->tram_shift = 0; - pcm->appl_ptr = 0; - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0); /* reset */ - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); /* reset */ - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size); - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0); /* reset ptr number */ - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size); - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size); - for (i = 0; i < pcm->channels; i++) - snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels)); - return 0; -} - -static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - unsigned long flags; - int result = 0; - - spin_lock_irqsave(&emu->reg_lock, flags); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - /* follow thru */ - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -#ifdef EMU10K1_SET_AC3_IEC958 - { - int i; - for (i = 0; i < 3; i++) { - unsigned int bits; - bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | - SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | - 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA; - snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits); - } - } -#endif - result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq); - if (result < 0) - goto __err; - snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */ - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL; - snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); - pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size); - pcm->tram_shift = 0; - break; - default: - result = -EINVAL; - break; - } - __err: - spin_unlock_irqrestore(&emu->reg_lock, flags); - return result; -} - -static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - size_t ptr; - snd_pcm_sframes_t frames; - - if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0)) - return 0; - ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0); - frames = ptr - pcm->hw_io; - if (frames < 0) - frames += runtime->buffer_size; - pcm->hw_io = ptr; - pcm->hw_ready -= frames; - pcm->sw_io += frames; - if (pcm->sw_io >= runtime->buffer_size) - pcm->sw_io -= runtime->buffer_size; - snd_emu10k1_fx8010_playback_transfer(substream); - return pcm->sw_io; -} - -static snd_pcm_hardware_t snd_emu10k1_fx8010_playback = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_48000, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 1, - .buffer_bytes_max = (128*1024), - .period_bytes_min = 1024, - .period_bytes_max = (128*1024), - .periods_min = 1, - .periods_max = 1024, - .fifo_size = 0, -}; - -static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - - runtime->hw = snd_emu10k1_fx8010_playback; - runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels; - runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2; - spin_lock(&emu->reg_lock); - if (pcm->valid == 0) { - spin_unlock(&emu->reg_lock); - return -ENODEV; - } - pcm->opened = 1; - spin_unlock(&emu->reg_lock); - return 0; -} - -static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - - spin_lock(&emu->reg_lock); - pcm->opened = 0; - spin_unlock(&emu->reg_lock); - return 0; -} - -static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = { - .open = snd_emu10k1_fx8010_playback_open, - .close = snd_emu10k1_fx8010_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_emu10k1_fx8010_playback_hw_params, - .hw_free = snd_emu10k1_fx8010_playback_hw_free, - .prepare = snd_emu10k1_fx8010_playback_prepare, - .trigger = snd_emu10k1_fx8010_playback_trigger, - .pointer = snd_emu10k1_fx8010_playback_pointer, - .ack = snd_emu10k1_fx8010_playback_transfer, -}; - -static void snd_emu10k1_fx8010_pcm_free(snd_pcm_t *pcm) -{ - emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return); - emu->pcm_fx8010 = NULL; - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) -{ - snd_pcm_t *pcm; - int err; - - if (rpcm) - *rpcm = NULL; - - if ((err = snd_pcm_new(emu->card, "emu10k1", device, 8, 0, &pcm)) < 0) - return err; - - pcm->private_data = emu; - pcm->private_free = snd_emu10k1_fx8010_pcm_free; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops); - - pcm->info_flags = 0; - strcpy(pcm->name, "EMU10K1 FX8010"); - emu->pcm_fx8010 = pcm; - - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 0); - - if (rpcm) - *rpcm = pcm; - return 0; } diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c --- a/sound/pci/emu10k1/emupcm.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/emu10k1/emupcm.c 2004-06-23 11:51:27 -07:00 @@ -1125,6 +1125,276 @@ .pointer = snd_emu10k1_capture_pointer, }; + +/* EFX playback */ + +#define INITIAL_TRAM_SHIFT 14 +#define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1) + +static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data) +{ + snd_pcm_substream_t *substream = snd_magic_cast(snd_pcm_substream_t, private_data, return); + snd_pcm_period_elapsed(substream); +} + +static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left, + unsigned short *dst_right, + unsigned short *src, + unsigned int count, + unsigned int tram_shift) +{ + // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); + if ((tram_shift & 1) == 0) { + while (count--) { + *dst_left-- = *src++; + *dst_right-- = *src++; + } + } else { + while (count--) { + *dst_right-- = *src++; + *dst_left-- = *src++; + } + } +} + +static void snd_emu10k1_fx8010_playback_tram_poke(emu10k1_t *emu, + unsigned int *tram_pos, + unsigned int *tram_shift, + unsigned int tram_size, + unsigned short *src, + unsigned int frames) +{ + unsigned int count; + + while (frames > *tram_pos) { + count = *tram_pos + 1; + snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos, + (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2, + src, count, *tram_shift); + src += count * 2; + frames -= count; + *tram_pos = (tram_size / 2) - 1; + (*tram_shift)++; + } + snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + *tram_pos, + (unsigned short *)emu->fx8010.etram_pages.area + *tram_pos + tram_size / 2, + src, frames, *tram_shift++); + *tram_pos -= frames; +} + +static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr; + snd_pcm_sframes_t diff = appl_ptr - pcm->appl_ptr; + snd_pcm_uframes_t buffer_size = pcm->buffer_size / 2; + + if (diff) { + if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) + diff += runtime->boundary; + pcm->sw_ready += diff; + pcm->appl_ptr = appl_ptr; + } + while (pcm->hw_ready < buffer_size && + pcm->sw_ready > 0) { + size_t hw_to_end = buffer_size - pcm->hw_data; + size_t sw_to_end = (runtime->buffer_size << 2) - pcm->sw_data; + size_t tframes = buffer_size - pcm->hw_ready; + if (pcm->sw_ready < tframes) + tframes = pcm->sw_ready; + if (hw_to_end < tframes) + tframes = hw_to_end; + if (sw_to_end < tframes) + tframes = sw_to_end; + snd_emu10k1_fx8010_playback_tram_poke(emu, &pcm->tram_pos, &pcm->tram_shift, + pcm->buffer_size, + (unsigned short *)(runtime->dma_area + (pcm->sw_data << 2)), + tframes); + pcm->hw_data += tframes; + if (pcm->hw_data == buffer_size) + pcm->hw_data = 0; + pcm->sw_data += tframes; + if (pcm->sw_data == runtime->buffer_size) + pcm->sw_data = 0; + pcm->hw_ready += tframes; + pcm->sw_ready -= tframes; + } + return 0; +} + +static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) +{ + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); +} + +static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + unsigned int i; + + for (i = 0; i < pcm->channels; i++) + snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0); + snd_pcm_lib_free_pages(substream); + return 0; +} + +static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + unsigned int i; + + // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); + pcm->sw_data = pcm->sw_io = pcm->sw_ready = 0; + pcm->hw_data = pcm->hw_io = pcm->hw_ready = 0; + pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size); + pcm->tram_shift = 0; + pcm->appl_ptr = 0; + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0); /* reset */ + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); /* reset */ + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size); + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0); /* reset ptr number */ + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size); + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size); + for (i = 0; i < pcm->channels; i++) + snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels)); + return 0; +} + +static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + unsigned long flags; + int result = 0; + + spin_lock_irqsave(&emu->reg_lock, flags); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* follow thru */ + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +#ifdef EMU10K1_SET_AC3_IEC958 + { + int i; + for (i = 0; i < 3; i++) { + unsigned int bits; + bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | + SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | + 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA; + snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits); + } + } +#endif + result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq); + if (result < 0) + goto __err; + snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */ + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL; + snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); + pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size); + pcm->tram_shift = 0; + break; + default: + result = -EINVAL; + break; + } + __err: + spin_unlock_irqrestore(&emu->reg_lock, flags); + return result; +} + +static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + size_t ptr; + snd_pcm_sframes_t frames; + + if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0)) + return 0; + ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0); + frames = ptr - pcm->hw_io; + if (frames < 0) + frames += runtime->buffer_size; + pcm->hw_io = ptr; + pcm->hw_ready -= frames; + pcm->sw_io += frames; + if (pcm->sw_io >= runtime->buffer_size) + pcm->sw_io -= runtime->buffer_size; + snd_emu10k1_fx8010_playback_transfer(substream); + return pcm->sw_io; +} + +static snd_pcm_hardware_t snd_emu10k1_fx8010_playback = +{ + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE), + .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = (128*1024), + .period_bytes_min = 1024, + .period_bytes_max = (128*1024), + .periods_min = 1, + .periods_max = 1024, + .fifo_size = 0, +}; + +static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + + runtime->hw = snd_emu10k1_fx8010_playback; + runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels; + runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2; + spin_lock(&emu->reg_lock); + if (pcm->valid == 0) { + spin_unlock(&emu->reg_lock); + return -ENODEV; + } + pcm->opened = 1; + spin_unlock(&emu->reg_lock); + return 0; +} + +static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream) +{ + emu10k1_t *emu = snd_pcm_substream_chip(substream); + snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; + + spin_lock(&emu->reg_lock); + pcm->opened = 0; + spin_unlock(&emu->reg_lock); + return 0; +} + +static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = { + .open = snd_emu10k1_fx8010_playback_open, + .close = snd_emu10k1_fx8010_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_emu10k1_fx8010_playback_hw_params, + .hw_free = snd_emu10k1_fx8010_playback_hw_free, + .prepare = snd_emu10k1_fx8010_playback_prepare, + .trigger = snd_emu10k1_fx8010_playback_trigger, + .pointer = snd_emu10k1_fx8010_playback_pointer, + .ack = snd_emu10k1_fx8010_playback_transfer, +}; + static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm) { emu10k1_t *emu = snd_magic_cast(emu10k1_t, pcm->private_data, return); @@ -1140,12 +1410,13 @@ if (rpcm) *rpcm = NULL; - if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 0, 1, &pcm)) < 0) + if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0) return err; pcm->private_data = emu; pcm->private_free = snd_emu10k1_pcm_efx_free; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops); pcm->info_flags = 0; diff -Nru a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c --- a/sound/pci/emu10k1/memory.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/emu10k1/memory.c 2004-06-23 11:51:28 -07:00 @@ -291,7 +291,7 @@ snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; - struct snd_sg_buf *sgbuf = runtime->dma_private; + struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); snd_util_memhdr_t *hdr; emu10k1_memblk_t *blk; int page, err, idx; diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c --- a/sound/pci/es1968.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/es1968.c 2004-06-23 11:51:28 -07:00 @@ -522,9 +522,7 @@ /* DMA Hack! */ struct snd_esm_memory { - char *buf; - unsigned long addr; - int size; + struct snd_dma_buffer buf; int empty; /* status */ struct list_head list; }; @@ -1078,10 +1076,10 @@ for (channel = 0; channel <= high_apu; channel++) { apu = es->apu[channel]; - snd_es1968_program_wavecache(chip, es, channel, es->memory->addr, 0); + snd_es1968_program_wavecache(chip, es, channel, es->memory->buf.addr, 0); /* Offset to PCMBAR */ - pa = es->memory->addr; + pa = es->memory->buf.addr; pa -= chip->dma.addr; pa >>= 1; /* words */ @@ -1230,20 +1228,20 @@ /* input mixer (left/mono) */ /* parallel in crap, see maestro reg 0xC [8-11] */ init_capture_apu(chip, es, 2, - es->mixbuf->addr, ESM_MIXBUF_SIZE/4, /* in words */ + es->mixbuf->buf.addr, ESM_MIXBUF_SIZE/4, /* in words */ ESM_APU_INPUTMIXER, 0x14); /* SRC (left/mono); get input from inputing apu */ - init_capture_apu(chip, es, 0, es->memory->addr, size, + init_capture_apu(chip, es, 0, es->memory->buf.addr, size, ESM_APU_SRCONVERTOR, es->apu[2]); if (es->fmt & ESS_FMT_STEREO) { /* input mixer (right) */ init_capture_apu(chip, es, 3, - es->mixbuf->addr + ESM_MIXBUF_SIZE/2, + es->mixbuf->buf.addr + ESM_MIXBUF_SIZE/2, ESM_MIXBUF_SIZE/4, /* in words */ ESM_APU_INPUTMIXER, 0x15); /* SRC (right) */ init_capture_apu(chip, es, 1, - es->memory->addr + size*2, size, + es->memory->buf.addr + size*2, size, ESM_APU_SRCONVERTOR, es->apu[3]); } @@ -1408,8 +1406,8 @@ down(&chip->memory_mutex); list_for_each(p, &chip->buf_list) { esm_memory_t *buf = list_entry(p, esm_memory_t, list); - if (buf->empty && buf->size > max_size) - max_size = buf->size; + if (buf->empty && buf->buf.bytes > max_size) + max_size = buf->buf.bytes; } up(&chip->memory_mutex); if (max_size >= 128*1024) @@ -1427,24 +1425,25 @@ down(&chip->memory_mutex); list_for_each(p, &chip->buf_list) { buf = list_entry(p, esm_memory_t, list); - if (buf->empty && buf->size >= size) + if (buf->empty && buf->buf.bytes >= size) goto __found; } up(&chip->memory_mutex); return NULL; __found: - if (buf->size > size) { + if (buf->buf.bytes > size) { esm_memory_t *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); if (chunk == NULL) { up(&chip->memory_mutex); return NULL; } - chunk->size = buf->size - size; - chunk->buf = buf->buf + size; - chunk->addr = buf->addr + size; + chunk->buf = buf->buf; + chunk->buf.bytes -= size; + chunk->buf.area += size; + chunk->buf.addr += size; chunk->empty = 1; - buf->size = size; + buf->buf.bytes = size; list_add(&chunk->list, &buf->list); } buf->empty = 0; @@ -1462,7 +1461,7 @@ if (buf->list.prev != &chip->buf_list) { chunk = list_entry(buf->list.prev, esm_memory_t, list); if (chunk->empty) { - chunk->size += buf->size; + chunk->buf.bytes += buf->buf.bytes; list_del(&buf->list); kfree(buf); buf = chunk; @@ -1471,7 +1470,7 @@ if (buf->list.next != &chip->buf_list) { chunk = list_entry(buf->list.next, esm_memory_t, list); if (chunk->empty) { - buf->size += chunk->size; + buf->buf.bytes += chunk->buf.bytes; list_del(&chunk->list); kfree(chunk); } @@ -1525,9 +1524,10 @@ return -ENOMEM; } memset(chip->dma.area, 0, ESM_MEM_ALIGN); - chunk->buf = chip->dma.area + ESM_MEM_ALIGN; - chunk->addr = chip->dma.addr + ESM_MEM_ALIGN; - chunk->size = chip->dma.bytes - ESM_MEM_ALIGN; + chunk->buf = chip->dma; + chunk->buf.area += ESM_MEM_ALIGN; + chunk->buf.addr += ESM_MEM_ALIGN; + chunk->buf.bytes -= ESM_MEM_ALIGN; chunk->empty = 1; list_add(&chunk->list, &chip->buf_list); @@ -1545,7 +1545,7 @@ int size = params_buffer_bytes(hw_params); if (chan->memory) { - if (chan->memory->size >= size) { + if (chan->memory->buf.bytes >= size) { runtime->dma_bytes = size; return 0; } @@ -1556,9 +1556,7 @@ // snd_printd("cannot allocate dma buffer: size = %d\n", size); return -ENOMEM; } - runtime->dma_bytes = size; - runtime->dma_area = chan->memory->buf; - runtime->dma_addr = chan->memory->addr; + snd_pcm_set_runtime_buffer(substream, &chan->memory->buf); return 1; /* area was changed */ } @@ -1637,6 +1635,8 @@ es->substream = substream; es->mode = ESM_MODE_PLAY; + substream->dma_device = chip->dma_dev; /* for mmap */ + runtime->private_data = es; runtime->hw = snd_es1968_playback; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = @@ -1695,7 +1695,9 @@ snd_magic_kfree(es); return -ENOMEM; } - memset(es->mixbuf->buf, 0, ESM_MIXBUF_SIZE); + memset(es->mixbuf->buf.area, 0, ESM_MIXBUF_SIZE); + + substream->dma_device = chip->dma_dev; /* for mmap */ runtime->private_data = es; runtime->hw = snd_es1968_capture; @@ -1800,11 +1802,11 @@ return; } - memset(memory->buf, 0, CLOCK_MEASURE_BUFSIZE); + memset(memory->buf.area, 0, CLOCK_MEASURE_BUFSIZE); - wave_set_register(chip, apu << 3, (memory->addr - 0x10) & 0xfff8); + wave_set_register(chip, apu << 3, (memory->buf.addr - 0x10) & 0xfff8); - pa = (unsigned int)((memory->addr - chip->dma.addr) >> 1); + pa = (unsigned int)((memory->buf.addr - chip->dma.addr) >> 1); pa |= 0x00400000; /* System RAM (Bit 22) */ /* initialize apu */ @@ -2470,6 +2472,8 @@ outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ } + if (chip->irq >= 0) + free_irq(chip->irq, (void *)chip); #ifdef SUPPORT_JOYSTICK if (chip->res_joystick) { gameport_unregister_port(&chip->gameport); @@ -2484,8 +2488,6 @@ release_resource(chip->res_io_port); kfree_nocheck(chip->res_io_port); } - if (chip->irq >= 0) - free_irq(chip->irq, (void *)chip); snd_magic_kfree(chip); return 0; } diff -Nru a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile --- a/sound/pci/ice1712/Makefile 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/ice1712/Makefile 2004-06-23 11:51:27 -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-23 11:51:27 -07:00 +++ b/sound/pci/ice1712/ice1724.c 2004-06-23 11:51:27 -07:00 @@ -44,6 +44,7 @@ #include "amp.h" #include "revo.h" #include "aureon.h" +#include "vt1720_mobo.h" MODULE_AUTHOR("Jaroslav Kysela "); @@ -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; } @@ -864,8 +851,45 @@ .pause = VT1724_RDMA1_PAUSE, }; +/* update spdif control bits; call with reg_lock */ +static void update_spdif_bits(ice1712_t *ice, unsigned int val) +{ + unsigned char cbit, disabled; + + cbit = inb(ICEREG1724(ice, SPDIF_CFG)); + disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN; + if (cbit != disabled) + outb(disabled, ICEREG1724(ice, SPDIF_CFG)); + outw(val, ICEMT1724(ice, SPDIF_CTRL)); + if (cbit != disabled) + outb(cbit, ICEREG1724(ice, SPDIF_CFG)); + outw(val, ICEMT1724(ice, SPDIF_CTRL)); +} + +/* update SPDIF control bits according to the given rate */ +static void update_spdif_rate(ice1712_t *ice, unsigned int rate) +{ + unsigned int val, nval; + unsigned long flags; + + spin_lock_irqsave(&ice->reg_lock, flags); + nval = val = inw(ICEMT1724(ice, SPDIF_CTRL)); + nval &= ~(7 << 12); + switch (rate) { + case 44100: break; + case 48000: nval |= 2 << 12; break; + case 32000: nval |= 3 << 12; break; + } + if (val != nval) + update_spdif_bits(ice, nval); + spin_unlock_irqrestore(&ice->reg_lock, flags); +} + static int snd_vt1724_playback_spdif_prepare(snd_pcm_substream_t * substream) { + ice1712_t *ice = snd_pcm_substream_chip(substream); + if (! ice->force_pdma4) + update_spdif_rate(ice, substream->runtime->rate); return snd_vt1724_pcm_prepare(substream, &vt1724_playback_spdif_reg); } @@ -1274,7 +1298,7 @@ } } else { /* consumer */ - val |= diga->status[0] & 0x04; /* copyright */ + val |= diga->status[1] & 0x04; /* copyright */ if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS)== IEC958_AES0_CON_EMPHASIS_5015) val |= 1U << 3; val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */ @@ -1331,16 +1355,8 @@ val = encode_spdif_bits(&ucontrol->value.iec958); spin_lock_irqsave(&ice->reg_lock, flags); old = inw(ICEMT1724(ice, SPDIF_CTRL)); - if (val != old) { - unsigned char cbit, disabled; - cbit = inb(ICEREG1724(ice, SPDIF_CFG)); - disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN; - if (cbit != disabled) - outb(disabled, ICEREG1724(ice, SPDIF_CFG)); - outw(val, ICEMT1724(ice, SPDIF_CTRL)); - if (cbit != disabled) - outb(cbit, ICEREG1724(ice, SPDIF_CFG)); - } + if (val != old) + update_spdif_bits(ice, val); spin_unlock_irqrestore(&ice->reg_lock, flags); return (val != old); } @@ -1815,6 +1831,7 @@ snd_vt1724_revo_cards, snd_vt1724_amp_cards, snd_vt1724_aureon_cards, + snd_vt1720_mobo_cards, 0, }; @@ -1929,9 +1946,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-23 11:51:28 -07:00 @@ -0,0 +1,97 @@ +/* + * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT) + * + * Lowlevel functions for VT1720-based motherboards + * + * Copyright (c) 2004 Takashi Iwai + * + * 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 +#include +#include +#include +#include +#include +#include + +#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-23 11:51:28 -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 + * + * 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/intel8x0.c b/sound/pci/intel8x0.c --- a/sound/pci/intel8x0.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/intel8x0.c 2004-06-23 11:51:27 -07:00 @@ -149,6 +149,9 @@ #ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #endif +#ifndef PCI_DEVICE_ID_NVIDIA_CK8_AUDIO +#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a +#endif #ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da #endif @@ -463,6 +466,7 @@ { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */ { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */ { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */ + { 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8 */ { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */ { 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8S */ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ @@ -1058,17 +1062,23 @@ { intel8x0_t *chip = snd_pcm_substream_chip(substream); ichdev_t *ichdev = get_ichdev(substream); - unsigned long flags; size_t ptr1, ptr; + int civ, timeout = 10; + unsigned int position; - ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << ichdev->pos_shift; - if (ptr1 != 0) - ptr = ichdev->fragsize1 - ptr1; - else - ptr = 0; - spin_lock_irqsave(&chip->reg_lock, flags); - ptr += ichdev->position; - spin_unlock_irqrestore(&chip->reg_lock, flags); + do { + civ = igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV); + ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb); + position = ichdev->position; + if (ptr1 == 0) + udelay(1); + if (civ == igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV) && + ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) + break; + } while (timeout--); + ptr1 <<= ichdev->pos_shift; + ptr = ichdev->fragsize1 - ptr1; + ptr += position; if (ptr >= ichdev->size) return 0; return bytes_to_frames(substream->runtime, ptr); @@ -2614,6 +2624,7 @@ { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" }, { PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" }, { PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" }, + { PCI_DEVICE_ID_NVIDIA_CK8_AUDIO, "NVidia CK8" }, { 0x746d, "AMD AMD8111" }, { 0x7445, "AMD AMD768" }, { 0x5455, "ALi M5455" }, diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c --- a/sound/pci/korg1212/korg1212.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/korg1212/korg1212.c 2004-06-23 11:51:27 -07:00 @@ -1414,13 +1414,14 @@ K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n", stateName[korg1212->cardState]); #endif + substream->dma_device = korg1212->dma_dev; /* set for mmap */ + snd_pcm_set_sync(substream); // ??? snd_korg1212_OpenCard(korg1212); runtime->hw = snd_korg1212_playback_info; - runtime->dma_area = (char *) korg1212->playDataBufsPtr; - runtime->dma_bytes = K1212_BUF_SIZE; + snd_pcm_set_runtime_buffer(substream, &korg1212->dma_play); spin_lock_irqsave(&korg1212->lock, flags); @@ -1445,13 +1446,14 @@ K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n", stateName[korg1212->cardState]); #endif + substream->dma_device = korg1212->dma_dev; /* set for mmap */ + snd_pcm_set_sync(substream); // ??? snd_korg1212_OpenCard(korg1212); runtime->hw = snd_korg1212_capture_info; - runtime->dma_area = (char *) korg1212->recordDataBufsPtr; - runtime->dma_bytes = K1212_BUF_SIZE; + snd_pcm_set_runtime_buffer(substream, &korg1212->dma_rec); spin_lock_irqsave(&korg1212->lock, flags); diff -Nru a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c --- a/sound/pci/mixart/mixart.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/mixart/mixart.c 2004-06-23 11:51:28 -07:00 @@ -247,21 +247,27 @@ /* pipe is not yet defined */ if( pipe->status == PIPE_UNDEFINED ) { int err, i; - mixart_streaming_group_t streaming_group_resp; - mixart_streaming_group_req_t streaming_group_req; + struct { + mixart_streaming_group_req_t sgroup_req; + mixart_streaming_group_t sgroup_resp; + } *buf; snd_printdd("add_ref_pipe audio chip(%d) pcm(%d)\n", chip->chip_idx, pcm_number); + buf = kmalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return NULL; + request.uid = (mixart_uid_t){0,0}; /* should be StreamManagerUID, but zero is OK if there is only one ! */ - request.data = &streaming_group_req; - request.size = sizeof(streaming_group_req); + request.data = &buf->sgroup_req; + request.size = sizeof(buf->sgroup_req); - memset(&streaming_group_req, 0, sizeof(streaming_group_req)); + memset(&buf->sgroup_req, 0, sizeof(buf->sgroup_req)); - streaming_group_req.stream_count = stream_count; - streaming_group_req.channel_count = 2; - streaming_group_req.latency = 256; - streaming_group_req.connector = pipe->uid_left_connector; /* the left connector */ + buf->sgroup_req.stream_count = stream_count; + buf->sgroup_req.channel_count = 2; + buf->sgroup_req.latency = 256; + buf->sgroup_req.connector = pipe->uid_left_connector; /* the left connector */ for (i=0; isgroup_req.stream_info[i].size_max_byte_frame = 1024; + buf->sgroup_req.stream_info[i].size_max_sample_frame = 256; + buf->sgroup_req.stream_info[i].nb_bytes_max_per_sample = MIXART_FLOAT_P__4_0_TO_HEX; /* is 4.0f */ /* find the right bufferinfo_array */ j = (chip->chip_idx * MIXART_MAX_STREAM_PER_CARD) + (pcm_number * (MIXART_PLAYBACK_STREAMS + MIXART_CAPTURE_STREAMS)) + i; if(capture) j += MIXART_PLAYBACK_STREAMS; /* in the array capture is behind playback */ - streaming_group_req.flow_entry[i] = j; + buf->sgroup_req.flow_entry[i] = j; flowinfo = (struct mixart_flowinfo *)chip->mgr->flowinfo.area; flowinfo[j].bufferinfo_array_phy_address = (u32)chip->mgr->bufferinfo.addr + (j * sizeof(mixart_bufferinfo_t)); @@ -294,17 +300,19 @@ } } - err = snd_mixart_send_msg(chip->mgr, &request, sizeof(streaming_group_resp), &streaming_group_resp); - if((err < 0) || (streaming_group_resp.status != 0)) { - snd_printk(KERN_ERR "error MSG_STREAM_ADD_**PUT_GROUP err=%x stat=%x !\n", err, streaming_group_resp.status); + err = snd_mixart_send_msg(chip->mgr, &request, sizeof(buf->sgroup_resp), &buf->sgroup_resp); + if((err < 0) || (buf->sgroup_resp.status != 0)) { + snd_printk(KERN_ERR "error MSG_STREAM_ADD_**PUT_GROUP err=%x stat=%x !\n", err, buf->sgroup_resp.status); + kfree(buf); return NULL; } - pipe->group_uid = streaming_group_resp.group; /* id of the pipe, as returned by embedded */ - pipe->stream_count = streaming_group_resp.stream_count; - /* pipe->stream_uid[i] = streaming_group_resp.stream[i].stream_uid; */ + pipe->group_uid = buf->sgroup_resp.group; /* id of the pipe, as returned by embedded */ + pipe->stream_count = buf->sgroup_resp.stream_count; + /* pipe->stream_uid[i] = buf->sgroup_resp.stream[i].stream_uid; */ pipe->status = PIPE_STOPPED; + kfree(buf); } if(monitoring) pipe->monitoring = 1; diff -Nru a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c --- a/sound/pci/nm256/nm256.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/nm256/nm256.c 2004-06-23 11:51:28 -07:00 @@ -660,9 +660,9 @@ return bytes_to_frames(substream->runtime, curp); } +/* Remapped I/O space can be accessible as pointer on i386 */ +/* This might be changed in the future */ #ifndef __i386__ -/* FIXME: I/O space is not accessible via pointers on all architectures */ - /* * silence / copy for playback */ @@ -757,10 +757,8 @@ */ static snd_pcm_hardware_t snd_nm256_playback = { - .info = -#ifdef __i386__ - SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID| -#endif + .info = SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID| + SNDRV_PCM_INFO_MMAP_IOMEM| SNDRV_PCM_INFO_INTERLEAVED | /*SNDRV_PCM_INFO_PAUSE |*/ SNDRV_PCM_INFO_RESUME, @@ -779,10 +777,8 @@ static snd_pcm_hardware_t snd_nm256_capture = { - .info = -#ifdef __i386__ - SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID| -#endif + .info = SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID| + SNDRV_PCM_INFO_MMAP_IOMEM| SNDRV_PCM_INFO_INTERLEAVED | /*SNDRV_PCM_INFO_PAUSE |*/ SNDRV_PCM_INFO_RESUME, diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c --- a/sound/pci/rme32.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/rme32.c 2004-06-23 11:51:28 -07:00 @@ -213,10 +213,6 @@ size_t playback_periodsize; /* in bytes, zero if not used */ size_t capture_periodsize; /* in bytes, zero if not used */ - snd_pcm_uframes_t playback_last_appl_ptr; - size_t playback_ptr; - size_t capture_ptr; - snd_card_t *card; snd_pcm_t *spdif_pcm; snd_pcm_t *adat_pcm; @@ -329,6 +325,7 @@ static snd_pcm_hardware_t snd_rme32_playback_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | @@ -354,6 +351,7 @@ static snd_pcm_hardware_t snd_rme32_capture_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | @@ -380,6 +378,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats= SNDRV_PCM_FMTBIT_S16_LE, @@ -404,6 +403,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = SNDRV_PCM_FMTBIT_S16_LE, @@ -678,10 +678,12 @@ { int err, rate, dummy; rme32_t *rme32 = _snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER); + runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER; + runtime->dma_bytes = RME32_BUFFER_SIZE; - if ((err = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(params))) < 0) - return err; spin_lock_irq(&rme32->lock); if ((rme32->rcreg & RME32_RCR_KMODE) && (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { @@ -719,12 +721,6 @@ return 0; } -static int snd_rme32_playback_hw_free(snd_pcm_substream_t * substream) -{ - snd_pcm_lib_free_pages(substream); - return 0; -} - static int snd_rme32_capture_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * params) @@ -734,9 +730,10 @@ rme32_t *rme32 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; - if ((err = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(params))) < 0) - return err; + runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER); + runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER; + runtime->dma_bytes = RME32_BUFFER_SIZE; + spin_lock_irqsave(&rme32->lock, flags); /* enable AutoSync for record-preparing */ rme32->wcreg |= RME32_WCR_AUTOSYNC; @@ -780,18 +777,10 @@ return 0; } -static int snd_rme32_capture_hw_free(snd_pcm_substream_t * substream) -{ - snd_pcm_lib_free_pages(substream); - return 0; -} - static void snd_rme32_playback_start(rme32_t * rme32, int from_pause) { if (!from_pause) { writel(0, rme32->iobase + RME32_IO_RESET_POS); - rme32->playback_last_appl_ptr = 0; - rme32->playback_ptr = 0; } rme32->wcreg |= RME32_WCR_START; @@ -882,8 +871,6 @@ rme32->wcreg &= ~RME32_WCR_ADAT; writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER); rme32->playback_substream = substream; - rme32->playback_last_appl_ptr = 0; - rme32->playback_ptr = 0; spin_unlock_irqrestore(&rme32->lock, flags); runtime->hw = snd_rme32_playback_spdif_info; @@ -927,7 +914,6 @@ return -EBUSY; } rme32->capture_substream = substream; - rme32->capture_ptr = 0; spin_unlock_irqrestore(&rme32->lock, flags); runtime->hw = snd_rme32_capture_spdif_info; @@ -972,8 +958,6 @@ rme32->wcreg |= RME32_WCR_ADAT; writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER); rme32->playback_substream = substream; - rme32->playback_last_appl_ptr = 0; - rme32->playback_ptr = 0; spin_unlock_irqrestore(&rme32->lock, flags); runtime->hw = snd_rme32_playback_adat_info; @@ -1017,7 +1001,6 @@ return -EBUSY; } rme32->capture_substream = substream; - rme32->capture_ptr = 0; spin_unlock_irqrestore(&rme32->lock, flags); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, @@ -1178,36 +1161,6 @@ snd_rme32_playback_pointer(snd_pcm_substream_t * substream) { rme32_t *rme32 = _snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_sframes_t diff; - size_t bytes; - - - if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { - diff = runtime->control->appl_ptr - - rme32->playback_last_appl_ptr; - rme32->playback_last_appl_ptr = runtime->control->appl_ptr; - if (diff != 0 && diff < -(snd_pcm_sframes_t) (runtime->boundary >> 1)) { - diff += runtime->boundary; - } - bytes = diff << rme32->playback_frlog; - if (bytes > RME32_BUFFER_SIZE - rme32->playback_ptr) { - memcpy_toio((void *)(rme32->iobase + RME32_IO_DATA_BUFFER + rme32->playback_ptr), - runtime->dma_area + rme32->playback_ptr, - RME32_BUFFER_SIZE - rme32->playback_ptr); - bytes -= RME32_BUFFER_SIZE - rme32->playback_ptr; - if (bytes > RME32_BUFFER_SIZE) { - bytes = RME32_BUFFER_SIZE; - } - memcpy_toio((void *)(rme32->iobase + RME32_IO_DATA_BUFFER), - runtime->dma_area, bytes); - rme32->playback_ptr = bytes; - } else if (bytes != 0) { - memcpy_toio((void *)(rme32->iobase + RME32_IO_DATA_BUFFER + rme32->playback_ptr), - runtime->dma_area + rme32->playback_ptr, bytes); - rme32->playback_ptr += bytes; - } - } return snd_rme32_playback_ptr(rme32); } @@ -1215,31 +1168,7 @@ snd_rme32_capture_pointer(snd_pcm_substream_t * substream) { rme32_t *rme32 = _snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_uframes_t frameptr; - size_t ptr; - - frameptr = snd_rme32_capture_ptr(rme32); - if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { - ptr = frameptr << rme32->capture_frlog; - if (ptr > rme32->capture_ptr) { - memcpy_fromio(runtime->dma_area + rme32->capture_ptr, - (void *)(rme32->iobase + RME32_IO_DATA_BUFFER + - rme32->capture_ptr), - ptr - rme32->capture_ptr); - rme32->capture_ptr += ptr - rme32->capture_ptr; - } else if (ptr < rme32->capture_ptr) { - memcpy_fromio(runtime->dma_area + rme32->capture_ptr, - (void *)(rme32->iobase + RME32_IO_DATA_BUFFER + - rme32->capture_ptr), - RME32_BUFFER_SIZE - rme32->capture_ptr); - memcpy_fromio(runtime->dma_area, - (void *)(rme32->iobase + RME32_IO_DATA_BUFFER), - ptr); - rme32->capture_ptr = ptr; - } - } - return frameptr; + return snd_rme32_capture_ptr(rme32); } static snd_pcm_ops_t snd_rme32_playback_spdif_ops = { @@ -1247,7 +1176,6 @@ .close = snd_rme32_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme32_playback_hw_params, - .hw_free = snd_rme32_playback_hw_free, .prepare = snd_rme32_playback_prepare, .trigger = snd_rme32_playback_trigger, .pointer = snd_rme32_playback_pointer, @@ -1260,7 +1188,6 @@ .close = snd_rme32_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme32_capture_hw_params, - .hw_free = snd_rme32_capture_hw_free, .prepare = snd_rme32_capture_prepare, .trigger = snd_rme32_capture_trigger, .pointer = snd_rme32_capture_pointer, @@ -1272,7 +1199,6 @@ .close = snd_rme32_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme32_playback_hw_params, - .hw_free = snd_rme32_playback_hw_free, .prepare = snd_rme32_playback_prepare, .trigger = snd_rme32_playback_trigger, .pointer = snd_rme32_playback_pointer, @@ -1285,7 +1211,6 @@ .close = snd_rme32_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme32_capture_hw_params, - .hw_free = snd_rme32_capture_hw_free, .prepare = snd_rme32_capture_prepare, .trigger = snd_rme32_capture_trigger, .pointer = snd_rme32_capture_pointer, @@ -1319,7 +1244,6 @@ { rme32_t *rme32 = (rme32_t *) pcm->private_data; rme32->spdif_pcm = NULL; - snd_pcm_lib_preallocate_free_for_all(pcm); } static void @@ -1327,7 +1251,6 @@ { rme32_t *rme32 = (rme32_t *) pcm->private_data; rme32->adat_pcm = NULL; - snd_pcm_lib_preallocate_free_for_all(pcm); } static int __devinit snd_rme32_create(rme32_t * rme32) @@ -1376,13 +1299,7 @@ snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme32_capture_spdif_ops); - rme32->spdif_pcm->info_flags = 0; - - snd_pcm_lib_preallocate_pages_for_all(rme32->spdif_pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - RME32_BUFFER_SIZE, - RME32_BUFFER_SIZE); + rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; /* set up ALSA pcm device for ADAT */ if ((pci->device == PCI_DEVICE_ID_DIGI32) || @@ -1404,13 +1321,7 @@ snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme32_capture_adat_ops); - rme32->adat_pcm->info_flags = 0; - - snd_pcm_lib_preallocate_pages_for_all(rme32->adat_pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - RME32_BUFFER_SIZE, - RME32_BUFFER_SIZE); + rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; } diff -Nru a/sound/pci/rme96.c b/sound/pci/rme96.c --- a/sound/pci/rme96.c 2004-06-23 11:51:27 -07:00 +++ b/sound/pci/rme96.c 2004-06-23 11:51:27 -07:00 @@ -250,10 +250,6 @@ size_t playback_periodsize; /* in bytes, zero if not used */ size_t capture_periodsize; /* in bytes, zero if not used */ - snd_pcm_uframes_t playback_last_appl_ptr; - size_t playback_ptr; - size_t capture_ptr; - snd_card_t *card; snd_pcm_t *spdif_pcm; snd_pcm_t *adat_pcm; @@ -394,6 +390,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | @@ -423,6 +420,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | @@ -452,6 +450,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | @@ -477,6 +476,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE), .formats = (SNDRV_PCM_FMTBIT_S16_LE | @@ -993,10 +993,13 @@ { unsigned long flags; rme96_t *rme96 = _snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; int err, rate, dummy; - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0) - return err; + runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER); + runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER; + runtime->dma_bytes = RME96_BUFFER_SIZE; + spin_lock_irqsave(&rme96->lock, flags); if (!(rme96->wcreg & RME96_WCR_MASTER) && snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && @@ -1038,13 +1041,6 @@ } static int -snd_rme96_playback_hw_free(snd_pcm_substream_t *substream) -{ - snd_pcm_lib_free_pages(substream); - return 0; -} - -static int snd_rme96_capture_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params) { @@ -1053,8 +1049,10 @@ snd_pcm_runtime_t *runtime = substream->runtime; int err, isadat, rate; - if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0) - return err; + runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER); + runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER; + runtime->dma_bytes = RME96_BUFFER_SIZE; + spin_lock_irqsave(&rme96->lock, flags); if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) { spin_unlock_irqrestore(&rme96->lock, flags); @@ -1096,21 +1094,12 @@ return 0; } -static int -snd_rme96_capture_hw_free(snd_pcm_substream_t *substream) -{ - snd_pcm_lib_free_pages(substream); - return 0; -} - static void snd_rme96_playback_start(rme96_t *rme96, int from_pause) { if (!from_pause) { writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); - rme96->playback_last_appl_ptr = 0; - rme96->playback_ptr = 0; } rme96->wcreg |= RME96_WCR_START; @@ -1123,7 +1112,6 @@ { if (!from_pause) { writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); - rme96->capture_ptr = 0; } rme96->wcreg |= RME96_WCR_START_2; @@ -1212,8 +1200,6 @@ rme96->wcreg &= ~RME96_WCR_ADAT; writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); rme96->playback_substream = substream; - rme96->playback_last_appl_ptr = 0; - rme96->playback_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); runtime->hw = snd_rme96_playback_spdif_info; @@ -1264,7 +1250,6 @@ return -EBUSY; } rme96->capture_substream = substream; - rme96->capture_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); @@ -1291,8 +1276,6 @@ rme96->wcreg |= RME96_WCR_ADAT; writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); rme96->playback_substream = substream; - rme96->playback_last_appl_ptr = 0; - rme96->playback_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); runtime->hw = snd_rme96_playback_adat_info; @@ -1341,7 +1324,6 @@ return -EBUSY; } rme96->capture_substream = substream; - rme96->capture_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); @@ -1509,42 +1491,6 @@ snd_rme96_playback_pointer(snd_pcm_substream_t *substream) { rme96_t *rme96 = _snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_sframes_t diff; - size_t bytes; - - if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { - diff = runtime->control->appl_ptr - - rme96->playback_last_appl_ptr; - rme96->playback_last_appl_ptr = runtime->control->appl_ptr; - if (diff != 0 && - diff < -(snd_pcm_sframes_t)(runtime->boundary >> 1)) - { - diff += runtime->boundary; - } - bytes = diff << rme96->playback_frlog; - - if (bytes > RME96_BUFFER_SIZE - rme96->playback_ptr) { - memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER + - rme96->playback_ptr), - runtime->dma_area + rme96->playback_ptr, - RME96_BUFFER_SIZE - rme96->playback_ptr); - bytes -= RME96_BUFFER_SIZE - rme96->playback_ptr; - if (bytes > RME96_BUFFER_SIZE) { - bytes = RME96_BUFFER_SIZE; - } - memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER), - runtime->dma_area, - bytes); - rme96->playback_ptr = bytes; - } else if (bytes != 0) { - memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER + - rme96->playback_ptr), - runtime->dma_area + rme96->playback_ptr, - bytes); - rme96->playback_ptr += bytes; - } - } return snd_rme96_playback_ptr(rme96); } @@ -1552,31 +1498,7 @@ snd_rme96_capture_pointer(snd_pcm_substream_t *substream) { rme96_t *rme96 = _snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_uframes_t frameptr; - size_t ptr; - - frameptr = snd_rme96_capture_ptr(rme96); - if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { - ptr = frameptr << rme96->capture_frlog; - if (ptr > rme96->capture_ptr) { - memcpy_fromio(runtime->dma_area + rme96->capture_ptr, - (void *)(rme96->iobase + RME96_IO_REC_BUFFER + - rme96->capture_ptr), - ptr - rme96->capture_ptr); - rme96->capture_ptr += ptr - rme96->capture_ptr; - } else if (ptr < rme96->capture_ptr) { - memcpy_fromio(runtime->dma_area + rme96->capture_ptr, - (void *)(rme96->iobase + RME96_IO_REC_BUFFER + - rme96->capture_ptr), - RME96_BUFFER_SIZE - rme96->capture_ptr); - memcpy_fromio(runtime->dma_area, - (void *)(rme96->iobase + RME96_IO_REC_BUFFER), - ptr); - rme96->capture_ptr = ptr; - } - } - return frameptr; + return snd_rme96_capture_ptr(rme96); } static snd_pcm_ops_t snd_rme96_playback_spdif_ops = { @@ -1584,7 +1506,6 @@ .close = snd_rme96_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_playback_hw_params, - .hw_free = snd_rme96_playback_hw_free, .prepare = snd_rme96_playback_prepare, .trigger = snd_rme96_playback_trigger, .pointer = snd_rme96_playback_pointer, @@ -1597,7 +1518,6 @@ .close = snd_rme96_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_capture_hw_params, - .hw_free = snd_rme96_capture_hw_free, .prepare = snd_rme96_capture_prepare, .trigger = snd_rme96_capture_trigger, .pointer = snd_rme96_capture_pointer, @@ -1609,7 +1529,6 @@ .close = snd_rme96_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_playback_hw_params, - .hw_free = snd_rme96_playback_hw_free, .prepare = snd_rme96_playback_prepare, .trigger = snd_rme96_playback_trigger, .pointer = snd_rme96_playback_pointer, @@ -1622,7 +1541,6 @@ .close = snd_rme96_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_capture_hw_params, - .hw_free = snd_rme96_capture_hw_free, .prepare = snd_rme96_capture_prepare, .trigger = snd_rme96_capture_trigger, .pointer = snd_rme96_capture_pointer, @@ -1661,7 +1579,6 @@ { rme96_t *rme96 = (rme96_t *) pcm->private_data; rme96->spdif_pcm = NULL; - snd_pcm_lib_preallocate_free_for_all(pcm); } static void @@ -1669,7 +1586,6 @@ { rme96_t *rme96 = (rme96_t *) pcm->private_data; rme96->adat_pcm = NULL; - snd_pcm_lib_preallocate_free_for_all(pcm); } static int __devinit @@ -1719,12 +1635,6 @@ rme96->spdif_pcm->info_flags = 0; - snd_pcm_lib_preallocate_pages_for_all(rme96->spdif_pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - RME96_BUFFER_SIZE, - RME96_BUFFER_SIZE); - /* set up ALSA pcm device for ADAT */ if (pci->device == PCI_DEVICE_ID_DIGI96) { /* ADAT is not available on the base model */ @@ -1742,12 +1652,6 @@ snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops); rme96->adat_pcm->info_flags = 0; - - snd_pcm_lib_preallocate_pages_for_all(rme96->adat_pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - RME96_BUFFER_SIZE, - RME96_BUFFER_SIZE); } rme96->playback_periodsize = 0; diff -Nru a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c --- a/sound/pci/trident/trident_memory.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/trident/trident_memory.c 2004-06-23 11:51:28 -07:00 @@ -189,7 +189,7 @@ snd_util_memblk_t *blk; snd_pcm_runtime_t *runtime = substream->runtime; int idx, page; - struct snd_sg_buf *sgbuf = runtime->dma_private; + struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); hdr = trident->tlb.memhdr; diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c --- a/sound/pci/via82xx.c 2004-06-23 11:51:28 -07:00 +++ b/sound/pci/via82xx.c 2004-06-23 11:51:28 -07:00 @@ -725,7 +725,11 @@ unsigned int size, res; size = viadev->idx_table[idx].size; - res = viadev->idx_table[idx].offset + size - count; + /* FIXME: is this always true? */ + if (count) + res = viadev->idx_table[idx].offset + size - count; + else + res = viadev->idx_table[idx].offset; /* check the validity of the calculated position */ if (size < count || (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))) { @@ -1035,6 +1039,7 @@ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, @@ -1060,19 +1065,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 +1072,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 +1083,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 +1338,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 +1639,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 +1653,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 +2096,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 */ diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c --- a/sound/usb/usbaudio.c 2004-06-23 11:51:28 -07:00 +++ b/sound/usb/usbaudio.c 2004-06-23 11:51:28 -07:00 @@ -1183,9 +1183,9 @@ if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { - snd_printk(KERN_ERR "%d:%d:%d: cannot get freq at ep 0x%x\n", + snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep 0x%x\n", dev->devnum, iface, fmt->altsetting, ep); - return err; + return 0; /* some devices don't support reading */ } crate = data[0] | (data[1] << 8) | (data[2] << 16); if (crate != rate) { @@ -2182,6 +2182,24 @@ /* + * check if the device uses big-endian samples + */ +static int is_big_endian_format(struct usb_device *dev, struct audioformat *fp) +{ + /* M-Audio */ + if (dev->descriptor.idVendor == 0x0763) { + /* Quattro: captured data only */ + if (dev->descriptor.idProduct == 0x2001 && + fp->endpoint & USB_DIR_IN) + return 1; + /* Audiophile USB */ + if (dev->descriptor.idProduct == 0x2003) + return 1; + } + return 0; +} + +/* * parse the audio format type I descriptor * and returns the corresponding pcm format * @@ -2217,17 +2235,13 @@ pcm_format = SNDRV_PCM_FORMAT_S8; break; case 2: - /* M-Audio audiophile USB workaround */ - if (dev->descriptor.idVendor == 0x0763 && - dev->descriptor.idProduct == 0x2003) + if (is_big_endian_format(dev, fp)) pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */ else pcm_format = SNDRV_PCM_FORMAT_S16_LE; break; case 3: - /* M-Audio audiophile USB workaround */ - if (dev->descriptor.idVendor == 0x0763 && - dev->descriptor.idProduct == 0x2003) + if (is_big_endian_format(dev, fp)) pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */ else pcm_format = SNDRV_PCM_FORMAT_S24_3LE; diff -Nru a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h --- a/sound/usb/usbquirks.h 2004-06-23 11:51:27 -07:00 +++ b/sound/usb/usbquirks.h 2004-06-23 11:51:27 -07:00 @@ -830,11 +830,42 @@ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "M-Audio", .product_name = "Quattro", - .ifnum = 9, - .type = QUIRK_MIDI_MIDIMAN, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0001, - .in_cables = 0x0001 + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = & (const snd_usb_audio_quirk_t[]) { + /* + * Interfaces 0-2 are "Windows-compatible", 16-bit only, + * and share endpoints with the other interfaces. + * Ignore them. The other interfaces can do 24 bits, + * but captured samples are big-endian (see usbaudio.c). + */ + { + .ifnum = 4, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 5, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 7, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 8, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 9, + .type = QUIRK_MIDI_MIDIMAN, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } } } },