]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ALSA patch for 2.5.6pre2
authorJaroslav Kysela <perex@suse.cz>
Thu, 7 Mar 2002 02:10:05 +0000 (18:10 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Thu, 7 Mar 2002 02:10:05 +0000 (18:10 -0800)
Hello,

this recent ALSA patch includes:

- added initial version of Config.help files
- moved /proc/asound/sndstat to /proc/asound/oss/sndstat
- moved /proc/asound/oss-devices to /proc/asound/oss/devices
- snd-rtctimer updates (blocking of RTC driver change)
- added ioctl conversion code for 32-bit applications running on 64-bit kernels
- fixed dependencies in makefiles
- wavefront driver cleanups (removed LOOPS_PER_SEC)
- created Documentation/sound/alsa directory

Jaroslav

54 files changed:
Documentation/sound/alsa/CMIPCI.txt [new file with mode: 0644]
Documentation/sound/alsa/SB-Live-mixer.txt [new file with mode: 0644]
Documentation/sound/alsa/seq_oss.html [new file with mode: 0644]
include/sound/core.h
include/sound/driver.h
include/sound/info.h
include/sound/pcm.h
include/sound/pcm_params.h
include/sound/version.h
sound/Config.help [new file with mode: 0644]
sound/core/Config.help [new file with mode: 0644]
sound/core/Config.in
sound/core/Makefile
sound/core/info.c
sound/core/info_oss.c
sound/core/ioctl32/Makefile [new file with mode: 0644]
sound/core/ioctl32/hwdep32.c [new file with mode: 0644]
sound/core/ioctl32/ioctl32.c [new file with mode: 0644]
sound/core/ioctl32/ioctl32.h [new file with mode: 0644]
sound/core/ioctl32/pcm32.c [new file with mode: 0644]
sound/core/ioctl32/rawmidi32.c [new file with mode: 0644]
sound/core/ioctl32/timer32.c [new file with mode: 0644]
sound/core/oss/pcm_oss.c
sound/core/rtctimer.c
sound/core/seq/Makefile
sound/core/seq/seq_midi_event.c
sound/core/seq/seq_virmidi.c
sound/core/sound_oss.c
sound/drivers/Config.help [new file with mode: 0644]
sound/drivers/mpu401/Makefile
sound/drivers/mpu401/mpu401_uart.c
sound/drivers/mtpav.c
sound/drivers/opl3/Makefile
sound/drivers/opl3/opl3_lib.c
sound/drivers/serial-u16550.c
sound/i2c/Makefile
sound/isa/Config.help [new file with mode: 0644]
sound/isa/ad1816a/ad1816a_lib.c
sound/isa/ad1848/ad1848_lib.c
sound/isa/azt2320.c
sound/isa/cs423x/cs4231_lib.c
sound/isa/es1688/es1688_lib.c
sound/isa/gus/gus_main.c
sound/isa/opl3sa2.c
sound/isa/sb/Makefile
sound/isa/sb/emu8000.c
sound/isa/sb/sb16_main.c
sound/isa/sb/sb8.c
sound/isa/sb/sb_common.c
sound/isa/sgalaxy.c
sound/isa/wavefront/wavefront_synth.c
sound/pci/Config.help [new file with mode: 0644]
sound/pci/ymfpci/ymfpci.c
sound/synth/Makefile

diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
new file mode 100644 (file)
index 0000000..582781b
--- /dev/null
@@ -0,0 +1,228 @@
+              Brief Notes on C-Media 8738/8338 Driver
+              =======================================
+
+                   Takashi Iwai <tiwai@suse.de>
+
+
+Front/Rear Multi-channel Playback
+---------------------------------
+
+CM8x38 chip can use ADC as the second DAC so that two different stereo
+channels can be used for front/rear playbacks.  Since there are two
+DACs, both streams are handled independently unlike the 4/6ch multi-
+channel playbacks in the section below.
+
+As default, ALSA driver assigns the first PCM device (i.e. hw:0,0 for
+card#0) for front and 4/6ch playbacks, while the second PCM device
+(hw:0,1) is assigned to the second DAC for rear playback.
+
+There are slight difference between two DACs.
+
+- The first DAC supports U8 and S16LE formats, while the second DAC
+  supports only S16LE.
+- The second DAC supports only two channel stereo.
+
+Please note that the CM8x38 DAC doesn't support continuous playback
+rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000,
+44100 and 48000 Hz.
+
+The rear output can be heard only when "Four Channel Mode" switch is
+disabled.  Otherwise no signal will be routed to the rear speakers.
+As default it's turned on.
+
+*** WARNING ***
+When "Four Channel Mode" switch is off, the output from rear speakers
+will be FULL VOLUME regardless of Master and PCM volumes.
+This might damage your audio equipment.  Please disconnect speakers
+before your turn off this switch.
+*** WARNING ***
+
+[ Well.. I once got the output with correct volume (i.e. same with the
+  front one) and was so excited.  It was even with "Four Channel" bit
+  on and "double DAC" mode.  Actually I could hear separate 4 channels
+  from front and rear speakers!  But.. after reboot, all was gone.
+  It's a very pity that I didn't save the register dump at that
+  time..  Maybe there is an unknown register to achieve this... ]
+
+If your card has an extra output jack for the rear output, the rear
+playback should be routed there as default.  If not, there is a
+control switch in the driver "Line-In As Rear", which you can change
+via alsamixer or somewhat else.  When this switch is on, line-in jack
+is used as rear output.
+
+There are two more controls regarding to the rear output.
+The "Exchange DAC" switch is used to exchange front and rear playback
+routes, i.e. the 2nd DAC is output from front output.
+
+
+4/6 Multi-Channel Playback
+--------------------------
+
+The recent CM8738 chips support for the 4/6 multi-channel playback
+function.  This is useful especially for AC3 decoding.
+
+When the multi-channel is supported, the driver name has a suffix
+"-MC" such like "CMI8738-MC6".  You can check this name from
+/proc/asound/cards.
+
+When the 4/6-ch output is enabled, the front DAC accepts up to 6 (or
+4) channels.  This is different from the dual DACs described in the
+previous section.  While the dual DAC supports two different rates or
+formats, the 4/6-ch playback supports only the same condition for all
+channels.
+
+For using 4/6 channel playback, you need to specify the PCM channels
+as you like and set the format S16LE.  For example, for playback with
+4 channels,
+
+       snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
+           // or mmap if you like
+       snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_S16_LE);
+       snd_pcm_hw_params_set_channels(pcm, hw, 4);
+
+and use the interleaved 4 channel data.
+
+There is a control switch, "Line-In As Bass".  As you can imagine from
+its name, the line-in jack is used for the bass (5th and 6th channels)
+output.
+
+
+Digital I/O
+-----------
+
+The CM8x38 provides the excellent SPDIF capability with very chip
+price (yes, that's the reason I bought the card :)
+
+The SPDIF playback and capture are done via the third PCM device
+(hw:0,2).  Usually this is assigned to the PCM device "spdif".
+The available rates are 44100 and 48000 Hz.
+For playback with aplay, you can run like below:
+
+       % aplay -Dhw:0,2 foo.wav
+
+or
+
+       % aplay -Dspdif foo.wav
+
+So far, only S16LE format is supported.  Still no 24bit.  Sorry, not
+enough info for this.
+
+The playback and capture over SPDIF use normal DAC and ADC,
+respectively, so you cannot playback both analog and digital streams
+simultaneously.
+
+To enable SPDIF output, you need to turn on "IEC958 Output Switch"
+control via mixer or alsactl.  Then you'll see the red light on from
+the card so you know that's working obviously :)
+The SPDIF input is always enabled, so you can hear SPDIF input data
+from line-out with "IEC958 In Monitor" switch at any time (see
+below).
+
+You can play via SPDIF even with the first device (hw:0,0),
+but SPDIF is enabled only when the proper format (S16LE), sample rate
+(441100 or 48000) and channels (2) are used.  Otherwise it's turned
+off.  (Also don't forget to turn on "IEC958 Output Switch", too.)
+
+
+Additionally there are relevant control switches:
+
+"IEC958 Mix Analog" - Mix analog PCM playback and FM-OPL/3 streams and
+       output through SPDIF.  This switch appears only on old chip
+       models (CM8738 033 and 037).
+       Note: without this control you can output PCM to SPDIF.
+       This is "mixing" of streams, so e.g. it's not for AC3 output
+       (see the next section).
+
+"IEC958 In Select"  - Select SPDIF input, the internal CD-in (false)
+       and the external input (true).  This switch appears only on
+       the chip models 039 or later.
+
+"IEC958 Loop"       - SPDIF input data is loop back into SPDIF
+       output (aka bypass)
+
+"IEC958 Copyright"  - Set the copyright bit.
+
+"IEC958 5V"         - Select 0.5V (coax) or 5V (optical) interface.
+       On some cards this doesn't work and you need to change the
+       configuration with hardware dip-switch.
+
+"IEC958 In Monitor" - SPDIF input is routed to DAC.
+
+"IEC958 In Phase Inverse" - Set SPDIF input format as inverse.
+       [FIXME: this doesn't work on all chips..]
+
+"IEC958 In Valid"   - Set input validity flag detection.
+
+Note: When "PCM Playback Switch" is on, you'll hear the digital output
+stream through analog line-out.
+
+
+The AC3 (RAW DIGITAL) OUTPUT
+----------------------------
+
+The driver supports raw digital (typically AC3) i/o over SPDIF.  This
+can be toggled via IEC958 playback control, but usually you need to
+access it via alsa-lib.  See alsa-lib documents for more details.
+
+On the raw digital mode, the "PCM Playback Switch" is automatically
+turned off so that non-audio data is heard from the analog line-out.
+Similarly the following switches are off: "IEC958 Mix Analog" and
+"IEC958 Loop".  The switches are resumed after closing the SPDIF PCM
+device automatically to the previous state.
+
+
+ANALOG MIXER INTERFACE
+----------------------
+
+The mixer interface on CM8x38 is similar to SB16.
+There are Master, PCM, Synth, CD, Line, Mic and PC Speaker playback
+volumes.  Synth, CD, Line and Mic have playback and capture switches,
+too, as well as SB16.
+
+In addition to the standard SB mixer, CM8x38 provides more functions.
+- PCM playback switch
+- PCM capture switch (to capture the data sent to DAC)
+- Mic Boost switch
+- Mic capture volume
+- Aux playback volume/switch and capture switch
+- 3D control switch
+
+
+MIDI CONTROLLER
+---------------
+
+The MPU401-UART interface is enabled as default only for the first
+(CMIPCI) card.  You need to set module option "snd_midi_port" properly
+for the 2nd (CMIPCI) card.
+
+There is _no_ hardware wavetable function on this chip (except for
+OPL3 synth below).
+What's said as MIDI synth on Windows is a software synthesizer
+emulation.  On Linux use TiMidity or other softsynth program for
+playing MIDI music.
+
+
+FM OPL/3 Synth
+--------------
+
+The FM OPL/3 is also enabled as default only for the first card.
+Set "snd_fm_port" module option for more cards.
+
+The output quality of FM OPL/3 is, however, very weird.
+I don't know why..
+
+
+Joystick and Modem
+------------------
+
+The joystick and modem should be available by enabling the control
+switch "Joystick" and "Modem" respectively.  But I myself have never
+tested them yet.
+
+
+Debugging Information
+---------------------
+
+The registers are shown in /proc/asound/cardX/cmipci.  If you have any
+problem (especially unexpected behavior of mixer), please attach the
+output of this proc file together with the bug report.
diff --git a/Documentation/sound/alsa/SB-Live-mixer.txt b/Documentation/sound/alsa/SB-Live-mixer.txt
new file mode 100644 (file)
index 0000000..d37b0e6
--- /dev/null
@@ -0,0 +1,356 @@
+
+               Sound Blaster Live mixer / default DSP code
+               ===========================================
+
+
+The EMU10K1 chips have a DSP part which can be programmed to support
+various ways of sample processing, which is described here.
+(This acticle does not deal with the overall functionality of the 
+EMU10K1 chips. See the manuals section for further details.)
+
+The ALSA driver programs this portion of chip by default code
+(can be altered later) which offers the following functionality:
+
+
+1) IEC958 (S/PDIF) raw PCM
+--------------------------
+
+This PCM device (it's the 4th PCM device (index 3!) and first subdevice
+(index 0) for a given card) allows to forward 48kHz, stereo, 16-bit
+little endian streams without any modifications to the digital output
+(coaxial or optical). The universal interface allows the creation of up
+to 8 raw PCM devices operating at 48kHz, 16-bit little endian. It would
+be easy to add support for multichannel devices to the current code,
+but the conversion routines exist only for stereo (2-channel streams)
+at the time. 
+
+Look to tram_poke routines in lowlevel/emu10k1/emufx.c for more details.
+
+
+2) Digital mixer controls
+-------------------------
+
+These controls are built using the DSP instructions. They offer extended
+functionality. Only the default build-in code in the ALSA driver is described
+here. Note that the controls work as attenuators: the maximum value is the 
+neutral position leaving the signal unchanged. Note that if the  same destination 
+is mentioned in multiple controls, the signal is accumulated and can be wrapped 
+(set to maximal or minimal value without checking of overflow).
+
+
+Explanation of used abbreviations:
+
+DAC    - digital to analog converter
+ADC    - analog to digital converter
+I2S    - one-way three wire serial bus for digital sound by Philips Semiconductors
+         (this standard is used for connecting standalone DAC and ADC converters)
+LFE    - low frequency effects (subwoofer signal)
+AC97   - a chip containing an analog mixer, DAC and ADC converters
+IEC958 - S/PDIF
+FX-bus - the EMU10K1 chip has an effect bus containing 16 accumulators.
+         Each of the synthesizer voices can feed its output to these accumulators
+         and the DSP microcontroller can operate with the resulting sum.
+
+
+name='Wave Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
+The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Wave Surround Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
+The result samples are forwarded to the rear I2S DACs. These DACs operates
+separately (they are not inside the AC97 codec).
+
+name='Wave Center Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
+The result is mixed to mono signal (single channel) and forwarded to
+the ??rear?? right DAC PCM slot of the AC97 codec.
+
+name='Wave LFE Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM.
+The result is mixed to mono signal (single channel) and forwarded to
+the ??rear?? left DAC PCM slot of the AC97 codec.
+
+name='Wave Capture Volume',index=0
+name='Wave Capture Switch',index=0
+
+These controls are used to attenuate samples for left and right PCM FX-bus
+accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Music Playback Volume',index=0
+
+This control is used to attenuate samples for left and right MIDI FX-bus
+accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
+The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Music Capture Volume',index=0
+name='Music Capture Switch',index=0
+
+These controls are used to attenuate samples for left and right MIDI FX-bus
+accumulator. ALSA uses accumulators 4 and 5 for left and right PCM.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Surround Digital Playback Volume',index=0
+
+This control is used to attenuate samples for left and right rear PCM FX-bus
+accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.
+The result samples are forwarded to the rear I2S DACs. These DACs operate
+separately (they are not inside the AC97 codec).
+
+name='Surround Digital Capture Volume',index=0
+name='Surround Digital Capture Switch',index=0
+
+These controls are used to attenuate samples for left and right rear PCM FX-bus
+accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Center Playback Volume',index=0
+
+This control is used to attenuate sample for center PCM FX-bus accumulator.
+ALSA uses accumulator 6 for center PCM sample. The result sample is forwarded
+to the ??rear?? right DAC PCM slot of the AC97 codec.
+
+name='LFE Playback Volume',index=0
+
+This control is used to attenuate sample for center PCM FX-bus accumulator.
+ALSA uses accumulator 6 for center PCM sample. The result sample is forwarded
+to the ??rear?? left DAC PCM slot of the AC97 codec.
+
+name='AC97 Playback Volume',index=0
+
+This control is used to attenuate samples for left and right front ADC PCM slots
+of the AC97 codec. The result samples are forwarded to the front DAC PCM
+slots of the AC97 codec.
+********************************************************************************
+*** Note: This control should be zero for the standard operations, otherwise ***
+*** a digital loopback is activated.                                         ***
+********************************************************************************
+
+name='AC97 Capture Volume',index=0
+
+This control is used to attenuate samples for left and right front ADC PCM slots
+of the AC97 codec. The result is forwarded to the ADC capture FIFO (thus to
+the standard capture PCM device).
+********************************************************************************
+*** Note: This control should be 100 (maximal value), otherwise no analog    ***
+*** inputs of the AC97 codec can be captured (recorded).                     ***
+********************************************************************************
+
+name='IEC958 TTL Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 TTL
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='IEC958 TTL Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 TTL
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the ADC capture FIFO (thus to the standard capture PCM device).
+
+name='Zoom Video Playback Volume',index=0
+
+This control is used to attenuate samples from left and right zoom video
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Zoom Video Capture Volume',index=0
+
+This control is used to attenuate samples from left and right zoom video
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the ADC capture FIFO (thus to the standard capture PCM device).
+
+name='IEC958 Optical Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 optical
+digital input. The result samples are forwarded to the front DAC PCM slots
+of the AC97 codec.
+
+name='IEC958 Optical Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 optical
+digital inputs. The result samples are forwarded to the ADC capture FIFO
+(thus to the standard capture PCM device).
+
+name='IEC958 Coaxial Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 coaxial
+digital inputs. The result samples are forwarded to the front DAC PCM slots
+of the AC97 codec.
+
+name='IEC958 Coaxial Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 coaxial
+digital inputs. The result samples are forwarded to the ADC capture FIFO
+(thus to the standard capture PCM device).
+
+name='Line LiveDrive Playback Volume',index=0
+name='Line LiveDrive Playback Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the LiveDrive). The result samples are forwarded to the front
+DAC PCM slots of the AC97 codec.
+
+name='Line LiveDrive Capture Volume',index=1
+name='Line LiveDrive Capture Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the LiveDrive). The result samples are forwarded to the ADC
+capture FIFO (thus to the standard capture PCM device).
+
+name='Tone Control - Switch',index=0
+
+This control turns the tone control on or off. The samples for front, rear
+and center / LFE outputs are affected.
+
+name='Tone Control - Bass',index=0
+
+This control sets the bass intensity. There is no neutral value!!
+When the tone control code is activated, the samples are always modified.
+The closest value to pure signal is 20.
+
+name='Tone Control - Treble',index=0
+
+This control sets the treble intensity. There is no neutral value!!
+When the tone control code is activated, the samples are always modified.
+The closest value to pure signal is 20.
+
+name='IEC958 Optical Raw Playback Switch',index=0
+
+If this switch is on, then the samples for the IEC958 (S/PDIF) digital
+output are taken only from the raw FX8010 PCM, otherwise standard front
+PCM samples are taken.
+
+name='Headphone Playback Volume',index=1
+
+This control attenuates the samples for the headphone output.
+
+name='Headphone Center Playback Switch',index=1
+
+If this switch is on, then the sample for the center PCM is put to the
+left headphone output (useful for SB Live cards without separate center/LFE
+output).
+
+name='Headphone LFE Playback Switch',index=1
+
+If this switch is on, then the sample for the center PCM is put to the
+right headphone output (useful for SB Live cards without separate center/LFE
+output).
+
+
+3) PCM stream related controls
+------------------------------
+
+name='EMU10K1 PCM Volume',index 0-31
+
+Channel volume attenuation in range 0-0xffff. The maximum value (no
+attenuation) is default. The channel mapping for three values is
+as follows:
+
+       0 - mono, default 0xffff (no attenuation)
+       1 - left, default 0xffff (no attenuation)
+       2 - right, default 0xffff (no attenuation)
+
+name='EMU10K1 PCM Send Routing',index 0-31
+
+This control specifies the destination - FX-bus accumulators. There are
+twelve values with this mapping:
+
+        0 -  mono, A destination (FX-bus 0-15), default 0
+        1 -  mono, B destination (FX-bus 0-15), default 1
+        2 -  mono, C destination (FX-bus 0-15), default 2
+        3 -  mono, D destination (FX-bus 0-15), default 3
+        4 -  left, A destination (FX-bus 0-15), default 0
+        5 -  left, B destination (FX-bus 0-15), default 1
+        6 -  left, C destination (FX-bus 0-15), default 2
+        7 -  left, D destination (FX-bus 0-15), default 3
+        8 - right, A destination (FX-bus 0-15), default 0
+        9 - right, B destination (FX-bus 0-15), default 1
+       10 - right, C destination (FX-bus 0-15), default 2
+       11 - right, D destination (FX-bus 0-15), default 3
+
+Don't forget that it's illegal to assign a channel to the same FX-bus accumulator 
+more than once (it means 0=0 && 1=0 is an invalid combination).
+name='EMU10K1 PCM Send Volume',index 0-31
+
+It specifies the attenuation (amount) for given destination in range 0-255.
+The channel mapping is following:
+
+        0 -  mono, A destination attn, default 255 (no attenuation)
+        1 -  mono, B destination attn, default 255 (no attenuation)
+        2 -  mono, C destination attn, default 0 (mute)
+        3 -  mono, D destination attn, default 0 (mute)
+        4 -  left, A destination attn, default 255 (no attenuation)
+        5 -  left, B destination attn, default 0 (mute)
+        6 -  left, C destination attn, default 0 (mute)
+        7 -  left, D destination attn, default 0 (mute)
+        8 - right, A destination attn, default 0 (mute)
+        9 - right, B destination attn, default 255 (no attenuation)
+       10 - right, C destination attn, default 0 (mute)
+       11 - right, D destination attn, default 0 (mute)
+
+
+
+4) MANUALS/PATENTS:
+-------------------
+
+ftp://opensource.creative.com/pub/doc
+-------------------------------------
+
+        Files:
+        LM4545.pdf      AC97 Codec
+
+        m2049.pdf       The EMU10K1 Digital Audio Processor
+
+        hog63.ps        FX8010 - A DSP Chip Architecture for Audio Effects
+
+
+WIPO Patents
+------------
+        Patent numbers:
+        WO 9901813 (A1) Audio Effects Processor with multiple asynchronous (Jan. 14, 1999)
+                        streams
+
+        WO 9901814 (A1) Processor with Instruction Set for Audio Effects (Jan. 14, 1999)
+
+        WO 9901953 (A1) Audio Effects Processor having Decoupled Instruction
+                        Execution and Audio Data Sequencing (Jan. 14, 1999)
+
+
+US Patents (http://www.uspto.gov/)
+----------------------------------
+
+        US 5925841      Digital Sampling Instrument employing cache memory (Jul. 20, 1999)
+
+        US 5928342      Audio Effects Processor integrated on a single chip (Jul. 27, 1999)
+                        with a multiport memory onto which multiple asynchronous
+                        digital sound samples can be concurrently loaded
+
+        US 5930158      Processor with Instruction Set for Audio Effects (Jul. 27, 1999)
+
+        US 6032235      Memory initialization circuit (Tram) (Feb. 29, 2000)
+
+        US 6138207      Interpolation looping of audio samples in cache connected to    (Oct. 24, 2000)
+                        system bus with prioritization and modification of bus transfers
+                        in accordance with loop ends and minimum block sizes
+
+        US 6151670      Method for conserving memory storage using a (Nov. 21, 2000)
+                        pool of  short term memory registers
+
+        US 6195715      Interrupt control for multiple programs communicating with      (Feb. 27, 2001)
+                        a common interrupt by associating programs to GP registers,
+                        defining interrupt register, polling GP registers, and invoking
+                        callback routine associated with defined interrupt register
diff --git a/Documentation/sound/alsa/seq_oss.html b/Documentation/sound/alsa/seq_oss.html
new file mode 100644 (file)
index 0000000..d9776cf
--- /dev/null
@@ -0,0 +1,409 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+   <TITLE>OSS Sequencer Emulation on ALSA</TITLE>
+</HEAD>
+<BODY>
+
+<CENTER>
+<H1>
+
+<HR WIDTH="100%"></H1></CENTER>
+
+<CENTER>
+<H1>
+OSS Sequencer Emulation on ALSA</H1></CENTER>
+
+<HR WIDTH="100%">
+<P>Copyright (c) 1998,1999 by Takashi Iwai
+<TT><A HREF="mailto:iwai@ww.uni-erlangen.de">&lt;iwai@ww.uni-erlangen.de></A></TT>
+<P>ver.0.1.8; Nov. 16, 1999
+<H2>
+
+<HR WIDTH="100%"></H2>
+
+<H2>
+1. Description</H2>
+This directory contains the OSS sequencer emulation driver on ALSA. Note
+that this program is still in the development state.
+<P>What this does - it provides the emulation of the OSS sequencer, access
+via
+<TT>/dev/sequencer</TT> and <TT>/dev/music</TT> devices.
+The most of applications using OSS can run if the appropriate ALSA
+sequencer is prepared.
+<P>The following features are emulated by this driver:
+<UL>
+<LI>
+Normal sequencer and MIDI events:</LI>
+
+<BR>They are converted to the ALSA sequencer events, and sent to the corresponding
+port.
+<LI>
+Timer events:</LI>
+
+<BR>The timer is not selectable by ioctl. The control rate is fixed to
+100 regardless of HZ. That is, even on Alpha system, a tick is always
+1/100 second. The base rate and tempo can be changed in <TT>/dev/music</TT>.
+
+<LI>
+Patch loading:</LI>
+
+<BR>It purely depends on the synth drivers whether it's supported since
+the patch loading is realized by callback to the synth driver.
+<LI>
+I/O controls:</LI>
+
+<BR>Most of controls are accepted. Some controls
+are dependent on the synth driver, as well as even on original OSS.</UL>
+Furthermore, you can find the following advanced features:
+<UL>
+<LI>
+Better queue mechanism:</LI>
+
+<BR>The events are queued before processing them.
+<LI>
+Multiple applications:</LI>
+
+<BR>You can run two or more applications simultaneously (even for OSS sequencer)!
+However, each MIDI device is exclusive - that is, if a MIDI device is opened
+once by some application, other applications can't use it. No such a restriction
+in synth devices.
+<LI>
+Real-time event processing:</LI>
+
+<BR>The events can be processed in real time without using out of bound
+ioctl. To switch to real-time mode, send ABSTIME 0 event. The followed
+events will be processed in real-time without queued. To switch off the
+real-time mode, send RELTIME 0 event.
+<LI>
+<TT>/proc</TT> interface:</LI>
+
+<BR>The status of applications and devices can be shown via <TT>/proc/asound/seq/oss</TT>
+at any time. In the later version, configuration will be changed via <TT>/proc</TT>
+interface, too.</UL>
+
+<H2>
+2. Installation</H2>
+Run configure script with both sequencer support (<TT>--with-sequencer=yes</TT>)
+and OSS emulation (<TT>--with-oss=yes</TT>) options. A module <TT>snd-seq-oss.o</TT>
+will be created. If the synth module of your sound card supports for OSS
+emulation (so far, only Emu8000 driver), this module will be loaded automatically.
+Otherwise, you need to load this module manually.
+<P>At beginning, this module probes all the MIDI ports which have been
+already connected to the sequencer. Once after that, the creation and deletion
+of ports are watched by announcement mechanism of ALSA sequencer.
+<P>The available synth and MIDI devices can be found in proc interface.
+Run "<TT>cat /proc/asound/seq/oss</TT>", and check the devices. For example,
+if you use an AWE64 card, you'll see like the following:
+<PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OSS sequencer emulation version 0.1.8
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALSA client number 63
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALSA receiver port 0
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of applications: 0
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of synth devices: 1
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synth 0: [EMU8000]
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type 0x1 : subtype 0x20 : voices 32
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capabilties : ioctl enabled / load_patch enabled
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of MIDI devices: 3
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; midi 0: [Emu8000 Port-0] ALSA port 65:0
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capability write / opened none
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; midi 1: [Emu8000 Port-1] ALSA port 65:1
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capability write / opened none
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; midi 2: [0: MPU-401 (UART)] ALSA port 64:0
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capability read/write / opened none</PRE>
+Note that the device number may be different from the information of
+<TT>/proc/asound/oss-devices</TT>
+or ones of the original OSS driver. Use the device number listed in <TT>/proc/asound/seq/oss</TT>
+to play via OSS sequencer emulation.
+<H2>
+3. Using Synthesizer Devices</H2>
+Run your favorite program. I've tested playmidi-2.4, awemidi-0.4.3, gmod-3.1
+and xmp-1.1.5. You can load samples via <TT>/dev/sequencer</TT> like sfxload,
+too.
+<P>If the lowlevel driver supports multiple access to synth devices (like
+Emu8000 driver), two or more applications are allowed to run at the same
+time.
+<H2>
+4. Using MIDI Devices</H2>
+So far, only MIDI output was tested. MIDI input was not checked at all,
+but hopefully it will work. Use the device number listed in <TT>/proc/asound/seq/oss</TT>.
+Be aware that these numbers are mostly different from the list in
+<TT>/proc/asound/oss-devices</TT>.
+<H2>
+5. Module Options</H2>
+The following module options are available:
+<UL>
+<LI>
+<TT>maxqlen</TT></LI>
+
+<BR>specifies the maximum read/write queue length. This queue is private
+for OSS sequencer, so that it is independent from the queue length of ALSA
+sequencer. Default value is 1024.
+<LI>
+<TT>seq_oss_debug</TT></LI>
+
+<BR>specifies the debug level and accepts zero (= no debug message) or
+positive integer. Default value is 0.</UL>
+
+<H2>
+6. Queue Mechanism</H2>
+OSS sequencer emulation uses an ALSA priority queue. The
+events from <TT>/dev/sequencer</TT> are processed and put onto the queue
+specified by module option.
+<P>All the events from <TT>/dev/sequencer</TT> are parsed at beginning.
+The timing events are also parsed at this moment, so that the events may
+be processed in real-time. Sending an event ABSTIME 0 switches the operation
+mode to real-time mode, and sending an event RELTIME 0 switches it off.
+In the real-time mode, all events are dispatched immediately.
+<P>The queued events are dispatched to the corresponding ALSA sequencer
+ports after scheduled time by ALSA sequencer dispatcher.
+<P>If the write-queue is full, the application sleeps until a certain amount
+(as default one half) becomes empty in blocking mode. The synchronization
+to write timing was implemented, too.
+<P>The input from MIDI devices or echo-back events are stored on read FIFO
+queue. If application reads <TT>/dev/sequencer</TT> in blocking mode, the
+process will be awaked.
+
+<H2>
+7. Interface to Synthesizer Device</H2>
+
+<H3>
+7.1. Registration</H3>
+To register an OSS synthesizer device, use <TT>snd_seq_oss_synth_register</TT>
+function.
+<PRE>int snd_seq_oss_synth_register(char *name, int type, int subtype, int nvoices,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snd_seq_oss_callback_t *oper, void *private_data)</PRE>
+The arguments <TT>name</TT>, <TT>type</TT>, <TT>subtype</TT> and
+<TT>nvoices</TT>
+are used for making the appropriate synth_info structure for ioctl. The
+return value is an index number of this device. This index must be remembered
+for unregister. If registration is failed, -errno will be returned.
+<P>To release this device, call <TT>snd_seq_oss_synth_unregister function</TT>:
+<PRE>int snd_seq_oss_synth_unregister(int index),</PRE>
+where the <TT>index</TT> is the index number returned by register function.
+<H3>
+7.2. Callbacks</H3>
+OSS synthesizer devices have capability for sample downloading and ioctls
+like sample reset. In OSS emulation, these special features are realized
+by using callbacks. The registration argument oper is used to specify these
+callbacks. The following callback functions must be defined:
+<PRE>snd_seq_oss_callback_t:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*open)(snd_seq_oss_arg_t *p, void *closure);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*close)(snd_seq_oss_arg_t *p);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char *buf, int offs, int count);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*reset)(snd_seq_oss_arg_t *p);
+Except for <TT>open</TT> and <TT>close</TT> callbacks, they are allowed
+to be NULL.
+<P>Each callback function takes the argument type snd_seq_oss_arg_t as the
+first argument.
+<PRE>struct snd_seq_oss_arg_t {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int app_index;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int file_mode;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int seq_mode;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snd_seq_addr_t addr;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *private_data;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int event_passing;
+};</PRE>
+The first three fields, <TT>app_index</TT>, <TT>file_mode</TT> and
+<TT>seq_mode</TT>
+are initialized by OSS sequencer. The <TT>app_index</TT> is the application
+index which is unique to each application opening OSS sequencer. The
+<TT>file_mode</TT>
+is bit-flags indicating the file operation mode. See
+<TT>seq_oss.h</TT>
+for its meaning. The <TT>seq_mode</TT> is sequencer operation mode. In
+the current version, only <TT>SND_OSSSEQ_MODE_SYNTH</TT> is used.
+<P>The next two fields, <TT>addr</TT> and <TT>private_data</TT>, must be
+filled by the synth driver at open callback. The <TT>addr</TT> contains
+the address of ALSA sequencer port which is assigned to this device. If
+the driver allocates memory for <TT>private_data</TT>, it must be released
+in close callback by itself.
+<P>The last field, <TT>event_passing</TT>, indicates how to translate note-on
+/ off events. In <TT>PROCESS_EVENTS</TT> mode, the note 255 is regarded
+as velocity change, and key pressure event is passed to the port. In <TT>PASS_EVENTS</TT>
+mode, all note on/off events are passed to the port without modified. <TT>PROCESS_KEYPRESS</TT>
+mode checks the note above 128 and regards it as key pressure event (mainly
+for Emu8000 driver).
+<H4>
+7.2.1. Open Callback</H4>
+The <TT>open</TT> is called at each time this device is opened by an application
+using OSS sequencer. This must not be NULL. Typically, the open callback
+does the following procedure:
+<OL>
+<LI>
+Allocate private data record.</LI>
+
+<LI>
+Create an ALSA sequencer port.</LI>
+
+<LI>
+Set the new port address on arg->addr.</LI>
+
+<LI>
+Set the private data record pointer on arg->private_data.</LI>
+</OL>
+Note that the type bit-flags in port_info of this synth port must NOT contain
+<TT>TYPE_MIDI_GENERIC</TT>
+bit. Instead, <TT>TYPE_SPECIFIC</TT> should be used. Also, <TT>CAP_SUBSCRIPTION</TT>
+bit should NOT be included, too. This is necessary to tell it from other
+normal MIDI devices. If the open procedure succeeded, return zero. Otherwise,
+return -errno.
+<H4>
+7.2.2 Ioctl Callback</H4>
+The <TT>ioctl</TT> callback is called when the sequencer receives device-specific
+ioctls. The following two ioctls should be processed by this callback:
+<UL>
+<LI>
+<TT>IOCTL_SEQ_RESET_SAMPLES</TT></LI>
+
+<BR>reset all samples on memory -- return 0
+<LI>
+<TT>IOCTL_SYNTH_MEMAVL</TT></LI>
+
+<BR>return the available memory size
+<LI>
+<TT>FM_4OP_ENABLE</TT></LI>
+
+<BR>can be ignored usually</UL>
+The other ioctls are processed inside the sequencer without passing to
+the lowlevel driver.
+<H4>
+7.2.3 Load_Patch Callback</H4>
+The <TT>load_patch</TT> callback is used for sample-downloading. This callback
+must read the data on user-space and transfer to each device. Return 0
+if succeeded, and -errno if failed. The format argument is the patch key
+in patch_info record. The buf is user-space pointer where patch_info record
+is stored. The offs can be ignored. The count is total data size of this
+sample data.
+<H4>
+7.2.4 Close Callback</H4>
+The <TT>close</TT> callback is called when this device is closed by the
+applicaion. If any private data was allocated in open callback, it must
+be released in the close callback. The deletion of ALSA port should be
+done here, too. This callback must not be NULL.
+<H4>
+7.2.5 Reset Callback</H4>
+The <TT>reset</TT> callback is called when sequencer device is reset or
+closed by applications. The callback should turn off the sounds on the
+relevant port immediately, and initialize the status of the port. If this
+callback is undefined, OSS seq sends a <TT>HEARTBEAT</TT> event to the
+port.
+<H3>
+7.3 Events</H3>
+Most of the events are processed by sequencer and translated to the adequate
+ALSA sequencer events, so that each synth device can receive by input_event
+callback of ALSA sequencer port. The following ALSA events should be implemented
+by the driver:
+<BR>&nbsp;
+<TABLE BORDER WIDTH="75%" NOSAVE >
+<TR NOSAVE>
+<TD NOSAVE><B>ALSA event</B></TD>
+
+<TD><B>Original OSS events</B></TD>
+</TR>
+
+<TR>
+<TD>NOTEON</TD>
+
+<TD>SEQ_NOTEON
+<BR>MIDI_NOTEON</TD>
+</TR>
+
+<TR>
+<TD>NOTE</TD>
+
+<TD>SEQ_NOTEOFF
+<BR>MIDI_NOTEOFF</TD>
+</TR>
+
+<TR NOSAVE>
+<TD NOSAVE>KEYPRESS</TD>
+
+<TD>MIDI_KEY_PRESSURE</TD>
+</TR>
+
+<TR NOSAVE>
+<TD>CHANPRESS</TD>
+
+<TD NOSAVE>SEQ_AFTERTOUCH
+<BR>MIDI_CHN_PRESSURE</TD>
+</TR>
+
+<TR NOSAVE>
+<TD NOSAVE>PGMCHANGE</TD>
+
+<TD NOSAVE>SEQ_PGMCHANGE
+<BR>MIDI_PGM_CHANGE</TD>
+</TR>
+
+<TR>
+<TD>PITCHBEND</TD>
+
+<TD>SEQ_CONTROLLER(CTRL_PITCH_BENDER)
+<BR>MIDI_PITCH_BEND</TD>
+</TR>
+
+<TR>
+<TD>CONTROLLER</TD>
+
+<TD>MIDI_CTL_CHANGE
+<BR>SEQ_BALANCE (with CTL_PAN)</TD>
+</TR>
+
+<TR>
+<TD>CONTROL14</TD>
+
+<TD>SEQ_CONTROLLER</TD>
+</TR>
+
+<TR>
+<TD>REGPARAM</TD>
+
+<TD>SEQ_CONTROLLER(CTRL_PITCH_BENDER_RANGE)</TD>
+</TR>
+
+<TR>
+<TD>SYSEX</TD>
+
+<TD>SEQ_SYSEX</TD>
+</TR>
+</TABLE>
+
+<P>The most of these behavior can be realized by MIDI emulation driver
+included in the Emu8000 lowlevel driver. In the future release, this module
+will be independent.
+<P>Some OSS events (<TT>SEQ_PRIVATE</TT> and <TT>SEQ_VOLUME</TT> events) are passed as event
+type SND_SEQ_OSS_PRIVATE.  The OSS sequencer passes these event 8 byte
+packets without any modification. The lowlevel driver should process these
+events appropriately.
+<H2>
+8. Interface to MIDI Device</H2>
+Since the OSS emulation probes the creation and deletion of ALSA MIDI sequencer
+ports automatically by receiving announcement from ALSA sequencer, the
+MIDI devices don't need to be registered explicitly like synth devices.
+However, the MIDI port_info registered to ALSA sequencer must include a group
+name <TT>SND_SEQ_GROUP_DEVICE</TT> and a capability-bit <TT>CAP_READ</TT> or
+<TT>CAP_WRITE</TT>. Also, subscription capabilities, <TT>CAP_SUBS_READ</TT> or <TT>CAP_SUBS_WRITE</TT>,
+must be defined, too. If these conditions are not satisfied, the port is not
+registered as OSS sequencer MIDI device.
+<P>The events via MIDI devices are parsed in OSS sequencer and converted
+to the corresponding ALSA sequencer events. The input from MIDI sequencer
+is also converted to MIDI byte events by OSS sequencer. This works just
+a reverse way of seq_midi module.
+<H2>
+9. Known Problems / TODO's</H2>
+
+<UL>
+<LI>
+Patch loading via ALSA instrument layer is not implemented yet.</LI>
+</UL>
+
+</BODY>
+</HTML>
index 5744cdd5cc8e7846f195a698ddda77febd1faa0c..94590bff56fbcff0b1fc0ef7d3259a9055793dd8 100644 (file)
  *
  */
 
+#ifdef CONFIG_PM
+#include <linux/sched.h>               /* wake_up() and struct semaphore */
+#endif
+
 /* Typedef's */
 typedef struct timeval snd_timestamp_t;
 typedef struct sndrv_interval snd_interval_t;
index ca4d4ab28e460caeee1508b3a299de17daaf1081..2fd88e2701b8292904f295a2ba352dd18248b236 100644 (file)
@@ -78,12 +78,4 @@ void snd_wrapper_vfree(void *);
 
 #include "sndmagic.h"
 
-/*
- * Temporary hack, until linux/init.h is fixed.
- */
-#include <linux/init.h>
-#ifndef __devexit_p
-#define __devexit_p(x) x
-#endif
-
 #endif /* __SOUND_DRIVER_H */
index 98d58dad1495366517c5f99825fb9934e97d3da7..ec841506e6db6741a6c415d5e047401b52683b66 100644 (file)
@@ -104,6 +104,11 @@ extern int snd_info_minor_unregister(void);
 #ifdef CONFIG_PROC_FS
 
 extern snd_info_entry_t *snd_seq_root;
+#ifdef CONFIG_SND_OSSEMUL
+extern snd_info_entry_t *snd_oss_root;
+#else
+#define snd_oss_root NULL
+#endif
 
 int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) __attribute__ ((format (printf, 2, 3)));
 int snd_info_init(void);
@@ -138,6 +143,7 @@ void snd_remove_proc_entry(struct proc_dir_entry *parent,
 #else
 
 #define snd_seq_root NULL
+#define snd_oss_root NULL
 
 static inline int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) { return 0; }
 static inline int snd_info_init(void) { return 0; }
index 3d24d3c04273a92614ee1cfda5ff49a2939ba6f1..09653070905e100c8afdd9e29904ae20991114f9 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <sound/asound.h>
 #include <linux/poll.h>
+#include <linux/bitops.h>
 
 typedef sndrv_pcm_uframes_t snd_pcm_uframes_t;
 typedef sndrv_pcm_sframes_t snd_pcm_sframes_t;
index 9d008650e5f298fbba4fd9cbcb0a96f23763018d..769d8738f2fd3b252b9af9e4c750c1ab32fc69f2 100644 (file)
@@ -22,8 +22,6 @@
  *
  */
 
-#include <linux/bitops.h>
-
 extern int snd_pcm_hw_param_mask(snd_pcm_substream_t *pcm, snd_pcm_hw_params_t *params,
                                 snd_pcm_hw_param_t var, const snd_mask_t *val);
 extern unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
index 50a7e6f090d824fe14f130a538b18f8e0825c9e6..21ced3f5bc473cb4db8f814b6706ac3717529917 100644 (file)
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated automatically by configure.  */
 #define CONFIG_SND_VERSION "0.9.0beta12"
-#define CONFIG_SND_DATE " (Tue Feb 26 09:34:24 2002 UTC)"
+#define CONFIG_SND_DATE " (Wed Mar 06 07:56:20 2002 UTC)"
diff --git a/sound/Config.help b/sound/Config.help
new file mode 100644 (file)
index 0000000..3d00354
--- /dev/null
@@ -0,0 +1,7 @@
+CONFIG_SOUND_PRIME
+  Say 'Y' or 'M' to enable Open Sound System drivers.
+
+CONFIG_SOUND_SND
+  Say 'Y' or 'M' to enable Advanced Linux Sound Architecture (ALSA) drivers.
+  You need to install also alsa-lib and alsa-utils packages available on
+  the ALSA website at <http://www.alsa-project.org>.
diff --git a/sound/core/Config.help b/sound/core/Config.help
new file mode 100644 (file)
index 0000000..85541f1
--- /dev/null
@@ -0,0 +1,40 @@
+CONFIG_SND_SEQUENCER
+  Say 'Y' or 'M' to enable MIDI sequencer and router support. This feature
+  allows routing and enqueing MIDI events. Events can be processed at given
+  time.
+
+CONFIG_SND_SEQ_DUMMY
+  Say 'Y' or 'M' to enable dummy sequencer client. This client is a simple
+  midi-through client. All normal input events are redirected to output port
+  immediately.
+
+CONFIG_SND_OSSEMUL
+  Say 'Y' to enable OSS (Open Sound System) API emulation code.
+
+CONFIG_SND_MIXER_OSS
+  Say 'Y' or 'M' to enable mixer OSS API emulation (/dev/mixer*).
+
+CONFIG_SND_PCM_OSS
+  Say 'Y' or 'M' to enable digital audio (PCM) OSS API emulation (/dev/dsp*).
+
+CONFIG_SND_SEQUENCER_OSS
+  Say 'Y' or 'M' to enable OSS sequencer emulation (both /dev/sequencer and
+  /dev/music interfaces).
+
+CONFIG_SND_RTCTIMER
+  Say 'Y' or 'M' to enable RTC timer support for ALSA. ALSA code uses RTC
+  timer as precise timing source and maps the RTC timer to the ALSA's timer
+  interface. ALSA sequencer code can also use this timing source.
+
+CONFIG_SND_VERBOSE_PRINTK
+  Say 'Y' to enable verbose log messages. These messages will help to
+  identify source file and position containing printed messages.
+
+CONFIG_SND_DEBUG
+  Say 'Y' to enable ALSA debug code.
+
+CONFIG_SND_DEBUG_MEMORY
+  Say 'Y' to enable debugging of memory allocation.
+
+CONFIG_SND_DEBUG_DETECTION
+  Say 'Y' to enable debugging of hardware detection.
index 5e9b5a1c176a416e23a1c00f64d19c056488c8a8..38c93ed8bb1c655e466366789dbd5245e73f7357 100644 (file)
@@ -1,5 +1,14 @@
 # ALSA soundcard-configuration
 
+if [ "$CONFIG_X86_64" = "y" -a "$CONFIG_IA32_EMULATION" = "y" ]; then
+  dep_tristate '  Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL
+fi
+if [ "$CONFIG_PPC64" = "y" ]; then
+  dep_tristate '  Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL
+fi
+if [ "$CONFIG_SPARC64" = "y" ]; then
+  dep_tristate '  Emulation for 32-bit applications' CONFIG_SND_BIT32_EMUL
+fi
 dep_tristate '  Sequencer support' CONFIG_SND_SEQUENCER $CONFIG_SND
 if [ "$CONFIG_SND_SEQUENCER" != "n" ]; then
   dep_tristate '  Sequencer dummy client' CONFIG_SND_SEQ_DUMMY $CONFIG_SND_SEQUENCER
index 50dd397f48430e66c08f4c3afb437c2a0cc8f7d4..83f5d792b5e7d728da5f99ad205f68483f5f494e 100644 (file)
@@ -45,6 +45,11 @@ endif
 
 obj-$(CONFIG_SND_SEQUENCER) += snd-timer.o
 
+subdir-$(CONFIG_SND_BIT32_EMUL) += ioctl32
+ifeq ($(CONFIG_SND_BIT32_EMUL),y)
+  obj-y += ioctl32/_ioctl32.o
+endif
+
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_DUMMY) += snd-pcm.o snd-timer.o snd.o
 obj-$(CONFIG_SND_VIRMIDI) += snd-rawmidi.o snd.o snd-timer.o
@@ -72,8 +77,8 @@ obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o sn
 obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
 obj-$(CONFIG_SND_OPTI93X) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
 obj-$(CONFIG_SND_SB8) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
-obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi.o
-obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi.o
+obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
+obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
 obj-$(CONFIG_SND_ES968) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
 obj-$(CONFIG_SND_WAVEFRONT) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
 obj-$(CONFIG_SND_ALS4000) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
@@ -85,7 +90,7 @@ obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd.o snd-hwdep.o snd-rawmidi.
 obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
 obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
 obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
-obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd.o
+obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
 obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd.o
 obj-$(CONFIG_SND_RME96) += snd-pcm.o snd-timer.o snd.o
 obj-$(CONFIG_SND_SONICVIBES) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
@@ -100,6 +105,10 @@ obj-$(CONFIG_SND_RME9652) += snd-pcm.o snd-timer.o snd.o
 obj-$(CONFIG_SND_TRIDENT) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o
 obj-$(CONFIG_SND_YMFPCI) += snd-pcm.o snd-timer.o snd.o snd-rawmidi.o snd-hwdep.o
 obj-$(CONFIG_SND_POWERMAC) += snd-pcm.o snd-timer.o snd.o
+ifeq ($(CONFIG_SND_SB16_CSP),y)
+  obj-$(CONFIG_SND_SB16) += snd-hwdep.o
+  obj-$(CONFIG_SND_SBAWE) += snd-hwdep.o
+endif
 
 include $(TOPDIR)/Rules.make
 
index 5e6eb497eac42a58c02fcfb83ec9acc31bd56b05..da8e938bb6cd7746bb9a5bcc1a149c32c207bc05 100644 (file)
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/time.h>
+#include <linux/smp_lock.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
 #include <sound/version.h>
 #include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
 #ifdef CONFIG_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
 #endif
@@ -55,7 +55,7 @@ int snd_info_check_reserved_words(const char *str)
                "memdebug",
                "detect",
                "devices",
-               "oss-devices",
+               "oss",
                "cards",
                "timers",
                "synth",
@@ -124,6 +124,9 @@ int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
 struct proc_dir_entry *snd_proc_root = NULL;
 struct proc_dir_entry *snd_proc_dev = NULL;
 snd_info_entry_t *snd_seq_root = NULL;
+#ifdef CONFIG_SND_OSSEMUL
+snd_info_entry_t *snd_oss_root = NULL;
+#endif
 
 #ifdef LINUX_2_2
 static void snd_info_fill_inode(struct inode *inode, int fill)
@@ -163,11 +166,13 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
 {
        snd_info_private_data_t *data;
        struct snd_info_entry *entry;
-       int ret = -EINVAL;
+       loff_t ret;
 
        data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
        entry = data->entry;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3)
        lock_kernel();
+#endif
        switch (entry->content) {
        case SNDRV_INFO_CONTENT_TEXT:
                switch (orig) {
@@ -181,6 +186,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
                        goto out;
                case 2: /* SEEK_END */
                default:
+                       ret = -EINVAL;
                        goto out;
                }
                break;
@@ -195,7 +201,9 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
        }
        ret = -ENXIO;
 out:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3)
        unlock_kernel();
+#endif
        return ret;
 }
 
@@ -623,6 +631,19 @@ int __init snd_info_init(void)
        if (p == NULL)
                return -ENOMEM;
        snd_proc_dev = p;
+#ifdef CONFIG_SND_OSSEMUL
+       {
+               snd_info_entry_t *entry;
+               if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL)
+                       return -ENOMEM;
+               entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+               if (snd_info_register(entry) < 0) {
+                       snd_info_free_entry(entry);
+                       return -ENOMEM;
+               }
+               snd_oss_root = entry;
+       }
+#endif
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
        {
                snd_info_entry_t *entry;
@@ -663,6 +684,10 @@ int __exit snd_info_done(void)
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
                if (snd_seq_root)
                        snd_info_unregister(snd_seq_root);
+#endif
+#ifdef CONFIG_SND_OSSEMUL
+               if (snd_oss_root)
+                       snd_info_unregister(snd_oss_root);
 #endif
                snd_remove_proc_entry(snd_proc_root, snd_proc_dev);
                snd_remove_proc_entry(&proc_root, snd_proc_root);
index 940882ff8531746c594e15891307222da186592e..85e7bcbb72eb36c457d8e556151c7406b4bf510a 100644 (file)
@@ -114,7 +114,7 @@ int snd_info_minor_register(void)
        snd_info_entry_t *entry;
 
        memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings));
-       if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", NULL)) != NULL) {
+       if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) {
                entry->content = SNDRV_INFO_CONTENT_TEXT;
                entry->c.text.read_size = 2048;
                entry->c.text.read = snd_sndstat_proc_read;
diff --git a/sound/core/ioctl32/Makefile b/sound/core/ioctl32/Makefile
new file mode 100644 (file)
index 0000000..ddd94bf
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Makefile for ALSA
+# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+#
+
+O_TARGET     := _ioctl32.o
+
+list-multi   := snd-ioctl32.o
+
+snd-ioctl32-objs := ioctl32.o pcm32.o rawmidi32.o timer32.o hwdep32.o
+
+obj-$(CONFIG_SND_BIT32_EMUL) += snd-ioctl32.o
+
+include $(TOPDIR)/Rules.make
+
+snd-ioctl32.o: $(snd-ioctl32-objs)
+       $(LD) $(LD_RFLAG) -r -o $@ $(snd-ioctl32-objs)
diff --git a/sound/core/ioctl32/hwdep32.c b/sound/core/ioctl32/hwdep32.c
new file mode 100644 (file)
index 0000000..5d0eb0c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *   32bit -> 64bit ioctl wrapper for timer API
+ *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define __NO_VERSION__
+#include <sound/driver.h>
+#include <linux/time.h>
+#include <sound/core.h>
+#include <sound/timer.h>
+#include <asm/uaccess.h>
+#include "ioctl32.h"
+
+#define AP(x) snd_ioctl32_##x
+
+struct ioctl32_mapper hwdep_mappers[] = {
+       { SNDRV_HWDEP_IOCTL_PVERSION, NULL },
+       { SNDRV_HWDEP_IOCTL_INFO, NULL },
+       { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
+       { SNDRV_CTL_IOCTL_HWDEP_INFO, NULL },
+       { 0 },
+};
diff --git a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c
new file mode 100644 (file)
index 0000000..cb22362
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ *   32bit -> 64bit ioctl wrapper for control API
+ *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define __NO_VERSION__
+#include <sound/driver.h>
+#include <linux/smp_lock.h>
+#include <linux/time.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <asm/uaccess.h>
+#include "ioctl32.h"
+
+/*
+ * register/unregister mappers
+ * exported for other modules
+ */
+
+int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
+int unregister_ioctl32_conversion(unsigned int cmd);
+
+
+int snd_ioctl32_register(struct ioctl32_mapper *mappers)
+{
+       int err;
+       struct ioctl32_mapper *m;
+
+       lock_kernel();
+       for (m = mappers; m->cmd; m++) {
+               err = register_ioctl32_conversion(m->cmd, m->handler);
+               if (err < 0) {
+                       unlock_kernel();
+                       return err;
+               }
+               m->registered++;
+       }
+       return 0;
+}
+
+void snd_ioctl32_unregister(struct ioctl32_mapper *mappers)
+{
+       struct ioctl32_mapper *m;
+
+       lock_kernel();
+       for (m = mappers; m->cmd; m++) {
+               if (m->registered) {
+                       unregister_ioctl32_conversion(m->cmd);
+                       m->registered = 0;
+               }
+       }
+       unlock_kernel();
+}
+
+
+/*
+ * Controls
+ */
+
+struct sndrv_ctl_elem_list32 {
+       u32 offset;
+       u32 space;
+       u32 used;
+       u32 count;
+       u32 pids;
+       unsigned char reserved[50];
+};
+
+#define CVT_sndrv_ctl_elem_list()\
+{\
+       COPY(offset);\
+       COPY(space);\
+       COPY(used);\
+       COPY(count);\
+       CPTR(pids);\
+}
+
+DEFINE_ALSA_IOCTL(ctl_elem_list);
+
+
+/*
+ * control element info
+ * it uses union, so the things are not easy..
+ */
+
+struct sndrv_ctl_elem_info32 {
+       struct sndrv_ctl_elem_id id; // the size of struct is same
+       s32 type;
+       u32 access;
+       u32 count;
+       s32 owner;
+       union {
+               struct {
+                       s32 min;
+                       s32 max;
+                       s32 step;
+               } integer;
+               struct {
+                       u32 items;
+                       u32 item;
+                       char name[64];
+               } enumerated;
+               unsigned char reserved[128];
+       } value;
+       unsigned char reserved[64];
+};
+
+static int snd_ioctl32_ctl_elem_info(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
+{
+       struct sndrv_ctl_elem_info data;
+       struct sndrv_ctl_elem_info32 data32;
+       int err;
+
+       if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
+               return -EFAULT;
+       memset(&data, 0, sizeof(data));
+       data.id = data32.id;
+       err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data);
+       if (err < 0)
+               return err;
+       /* restore info to 32bit */
+       data32.type = data.type;
+       data32.access = data.access;
+       data32.count = data.count;
+       data32.owner = data.owner;
+       switch (data.type) {
+       case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+       case SNDRV_CTL_ELEM_TYPE_INTEGER:
+               data32.value.integer.min = data.value.integer.min;
+               data32.value.integer.max = data.value.integer.min;
+               data32.value.integer.step = data.value.integer.step;
+               break;
+       case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+               data32.value.enumerated.items = data.value.enumerated.items;
+               data32.value.enumerated.item = data.value.enumerated.item;
+               memcpy(data32.value.enumerated.name, data.value.enumerated.name,
+                      sizeof(data.value.enumerated.name));
+               break;
+       default:
+               break;
+       }
+       if (copy_to_user((void*)arg, &data32, sizeof(data32)))
+               return -EFAULT;
+       return err;
+}
+
+
+struct sndrv_ctl_elem_value32 {
+       struct sndrv_ctl_elem_id id;
+       unsigned int indirect: 1;
+        union {
+               union {
+                       s32 value[128];
+                       u32 value_ptr;
+               } integer;
+               union {
+                       u32 item[128];
+                       u32 item_ptr;
+               } enumerated;
+               union {
+                       unsigned char data[512];
+                       u32 data_ptr;
+               } bytes;
+               struct sndrv_aes_iec958 iec958;
+        } value;
+        unsigned char reserved[128];
+};
+
+
+/* hmm, it's so hard to retrieve the value type from the control id.. */
+static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id)
+{
+       snd_ctl_file_t *ctl;
+       snd_kcontrol_t *kctl;
+       snd_ctl_elem_info_t info;
+       int err;
+
+       ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
+
+       read_lock(&ctl->card->control_rwlock);
+       kctl = snd_ctl_find_id(ctl->card, id);
+       if (! kctl) {
+               read_unlock(&ctl->card->control_rwlock);
+               return -ENXIO;
+       }
+       info.id = *id;
+       err = kctl->info(kctl, &info);
+       if (err >= 0)
+               err = info.type;
+       read_unlock(&ctl->card->control_rwlock);
+       return err;
+}
+
+
+static int snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
+{
+       // too big?
+       struct sndrv_ctl_elem_value data;
+       struct sndrv_ctl_elem_value32 data32;
+       int err, i;
+       int type;
+       /* FIXME: check the sane ioctl.. */
+
+       if (copy_from_user(&data32, (void*)arg, sizeof(data32)))
+               return -EFAULT;
+       memset(&data, 0, sizeof(data));
+       data.id = data32.id;
+       data.indirect = data32.indirect;
+       if (data.indirect) /* FIXME: this is not correct for long arrays */
+               data.value.integer.value_ptr = (void*)TO_PTR(data32.value.integer.value_ptr);
+       type = get_ctl_type(file, &data.id);
+       if (type < 0)
+               return type;
+       if (! data.indirect) {
+               switch (type) {
+               case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+               case SNDRV_CTL_ELEM_TYPE_INTEGER:
+                       for (i = 0; i < 128; i++)
+                               data.value.integer.value[i] = data32.value.integer.value[i];
+                       break;
+               case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+                       for (i = 0; i < 128; i++)
+                               data.value.enumerated.item[i] = data32.value.enumerated.item[i];
+                       break;
+               case SNDRV_CTL_ELEM_TYPE_BYTES:
+                       memcpy(data.value.bytes.data, data32.value.bytes.data,
+                              sizeof(data.value.bytes.data));
+                       break;
+               case SNDRV_CTL_ELEM_TYPE_IEC958:
+                       data.value.iec958 = data32.value.iec958;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data);
+       if (err < 0)
+               return err;
+       /* restore info to 32bit */
+       if (! data.indirect) {
+               switch (type) {
+               case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+               case SNDRV_CTL_ELEM_TYPE_INTEGER:
+                       for (i = 0; i < 128; i++)
+                               data.value.integer.value[i] = data32.value.integer.value[i];
+                       break;
+               case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+                       for (i = 0; i < 128; i++)
+                               data.value.enumerated.item[i] = data32.value.enumerated.item[i];
+                       break;
+               case SNDRV_CTL_ELEM_TYPE_BYTES:
+                       memcpy(data.value.bytes.data, data32.value.bytes.data,
+                              sizeof(data.value.bytes.data));
+                       break;
+               case SNDRV_CTL_ELEM_TYPE_IEC958:
+                       data.value.iec958 = data32.value.iec958;
+                       break;
+               default:
+                       break;
+               }
+       }
+       if (copy_to_user((void*)arg, &data32, sizeof(data32)))
+               return -EFAULT;
+       return err;
+}
+
+
+/*
+ */
+
+#define AP(x) snd_ioctl32_##x
+
+static struct ioctl32_mapper control_mappers[] = {
+       /* controls (without rawmidi, hwdep, timer releated ones) */
+       { SNDRV_CTL_IOCTL_PVERSION, NULL },
+       { SNDRV_CTL_IOCTL_CARD_INFO , NULL },
+       { SNDRV_CTL_IOCTL_ELEM_LIST, AP(ctl_elem_list) },
+       { SNDRV_CTL_IOCTL_ELEM_INFO, AP(ctl_elem_info) },
+       { SNDRV_CTL_IOCTL_ELEM_READ, AP(ctl_elem_value) },
+       { SNDRV_CTL_IOCTL_ELEM_WRITE, AP(ctl_elem_value) },
+       { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL },
+       { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL },
+       { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL },
+       { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL },
+       { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL },
+       { SNDRV_CTL_IOCTL_PCM_INFO, NULL },
+       { SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL },
+       { SNDRV_CTL_IOCTL_POWER, NULL },
+       { SNDRV_CTL_IOCTL_POWER_STATE, NULL },
+       { 0 }
+};
+
+
+/*
+ */
+
+extern struct ioctl32_mapper pcm_mappers[];
+extern struct ioctl32_mapper rawmidi_mappers[];
+extern struct ioctl32_mapper timer_mappers[];
+extern struct ioctl32_mapper hwdep_mappers[];
+
+static void snd_ioctl32_done(void)
+{
+       snd_ioctl32_unregister(hwdep_mappers);
+       snd_ioctl32_unregister(timer_mappers);
+       snd_ioctl32_unregister(rawmidi_mappers);
+       snd_ioctl32_unregister(pcm_mappers);
+       snd_ioctl32_unregister(control_mappers);
+}
+
+static int __init snd_ioctl32_init(void)
+{
+       int err;
+       
+       err = snd_ioctl32_register(control_mappers);
+       if (err < 0)
+               return err;
+       err = snd_ioctl32_register(pcm_mappers);
+       if (err < 0) {
+               snd_ioctl32_done();
+               return err;
+       }
+       err = snd_ioctl32_register(rawmidi_mappers);
+       if (err < 0) {
+               snd_ioctl32_done();
+               return err;
+       }
+       err = snd_ioctl32_register(timer_mappers);
+       if (err < 0) {
+               snd_ioctl32_done();
+               return err;
+       }
+       err = snd_ioctl32_register(hwdep_mappers);
+       if (err < 0) {
+               snd_ioctl32_done();
+               return err;
+       }
+}
+
+module_init(snd_ioctl32_init)
+module_exit(snd_ioctl32_done)
diff --git a/sound/core/ioctl32/ioctl32.h b/sound/core/ioctl32/ioctl32.h
new file mode 100644 (file)
index 0000000..08c20d5
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *   32bit -> 64bit ioctl helpers
+ *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *
+ * This file registers the converters from 32-bit ioctls to 64-bit ones.
+ * The converter assumes that a 32-bit user-pointer can be casted by A(x)
+ * macro to a valid 64-bit pointer which is accessible via copy_from/to_user.
+ *
+ */
+
+#ifndef __ALSA_IOCTL32_H
+#define __ALSA_IOCTL32_H
+
+#define TO_PTR(x)  A(x)
+
+#define COPY(x)  (dst->x = src->x)
+#define CPTR(x)         (dst->x = (typeof(dst->x))A(src->x))
+
+#define convert_from_32(type, dstp, srcp)\
+{\
+       struct sndrv_##type *dst = dstp;\
+       struct sndrv_##type##32 *src = srcp;\
+       CVT_##sndrv_##type();\
+}
+
+#define convert_to_32(type, dstp, srcp)\
+{\
+       struct sndrv_##type *src = srcp;\
+       struct sndrv_##type##32 *dst = dstp;\
+       CVT_##sndrv_##type();\
+}
+
+
+#define DEFINE_ALSA_IOCTL(type) \
+static int snd_ioctl32_##type(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)\
+{\
+       struct sndrv_##type##32 data32;\
+       struct sndrv_##type data;\
+       int err;\
+       if (copy_from_user(&data32, (void*)arg, sizeof(data32)))\
+               return -EFAULT;\
+       memset(&data, 0, sizeof(data));\
+       convert_from_32(type, &data, &data32);\
+       err = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, (unsigned long)&data);\
+       if (err < 0)\
+               return err;\
+       if (cmd & (_IOC_READ << _IOC_DIRSHIFT)) {\
+               convert_to_32(type, &data32, &data);\
+               if (copy_to_user((void*)arg, &data32, sizeof(data32)))\
+                       return -EFAULT;\
+       }\
+       return err;\
+}
+
+struct ioctl32_mapper {
+       unsigned int cmd;
+       int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
+       int registered;
+};
+
+int snd_ioctl32_register(struct ioctl32_mapper *mappers);
+void snd_ioctl32_unregister(struct ioctl32_mapper *mappers);
+
+#endif /* __ALSA_IOCTL32_H */
diff --git a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c
new file mode 100644 (file)
index 0000000..3aa994c
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ *   32bit -> 64bit ioctl wrapper for PCM API
+ *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define __NO_VERSION__
+#include <sound/driver.h>
+#include <linux/time.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include "ioctl32.h"
+
+
+/* wrapper for sndrv_pcm_[us]frames */
+struct sndrv_pcm_sframes_str {
+       sndrv_pcm_sframes_t val;
+};
+struct sndrv_pcm_sframes_str32 {
+       s32 val;
+};
+struct sndrv_pcm_uframes_str {
+       sndrv_pcm_uframes_t val;
+};
+struct sndrv_pcm_uframes_str32 {
+       u32 val;
+};
+
+#define CVT_sndrv_pcm_sframes_str() { COPY(val); }
+#define CVT_sndrv_pcm_uframes_str() { COPY(val); }
+
+
+struct sndrv_interval32 {
+       u32 min, max;
+       unsigned int openmin:1,
+                    openmax:1,
+                    integer:1,
+                    empty:1;
+};
+
+struct sndrv_pcm_hw_params32 {
+       u32 flags;
+       u32 masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+       struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+       u32 rmask;
+       u32 cmask;
+       u32 info;
+       u32 msbits;
+       u32 rate_num;
+       u32 rate_den;
+       u32 fifo_size;
+       unsigned char reserved[64];
+};
+
+#define numberof(array)  (sizeof(array)/sizeof(array[0]))
+
+#define CVT_sndrv_pcm_hw_params()\
+{\
+       int i;\
+       COPY(flags);\
+       for (i = 0; i < numberof(dst->masks); i++)\
+               COPY(masks[i]);\
+       for (i = 0; i < numberof(dst->intervals); i++) {\
+               COPY(intervals[i].min);\
+               COPY(intervals[i].max);\
+               COPY(intervals[i].openmin);\
+               COPY(intervals[i].openmax);\
+               COPY(intervals[i].integer);\
+               COPY(intervals[i].empty);\
+       }\
+       COPY(rmask);\
+       COPY(cmask);\
+       COPY(info);\
+       COPY(msbits);\
+       COPY(rate_num);\
+       COPY(rate_den);\
+       COPY(fifo_size);\
+}
+
+struct sndrv_pcm_sw_params32 {
+       s32 tstamp_mode;
+       u32 period_step;
+       u32 sleep_min;
+       u32 avail_min;
+       u32 xfer_align;
+       u32 start_threshold;
+       u32 stop_threshold;
+       u32 silence_threshold;
+       u32 silence_size;
+       u32 boundary;
+       unsigned char reserved[64];
+};
+
+#define CVT_sndrv_pcm_sw_params()\
+{\
+       COPY(tstamp_mode);\
+       COPY(period_step);\
+       COPY(sleep_min);\
+       COPY(avail_min);\
+       COPY(xfer_align);\
+       COPY(start_threshold);\
+       COPY(stop_threshold);\
+       COPY(silence_threshold);\
+       COPY(silence_size);\
+       COPY(boundary);\
+}
+
+struct sndrv_pcm_channel_info32 {
+       u32 channel;
+       u32 offset;
+       u32 first;
+       u32 step;
+};
+
+#define CVT_sndrv_pcm_channel_info()\
+{\
+       COPY(channel);\
+       COPY(offset);\
+       COPY(first);\
+       COPY(step);\
+}
+
+struct timeval32 {
+       s32 tv_sec;
+       s32 tv_usec;
+};
+
+struct sndrv_pcm_status32 {
+       s32 state;
+       struct timeval32 trigger_tstamp;
+       struct timeval32 tstamp;
+       u32 appl_ptr;
+       u32 hw_ptr;
+       s32 delay;
+       u32 avail;
+       u32 avail_max;
+       u32 overrange;
+       s32 suspended_state;
+       unsigned char reserved[60];
+};
+
+#define CVT_sndrv_pcm_status()\
+{\
+       COPY(state);\
+       COPY(trigger_tstamp.tv_sec);\
+       COPY(trigger_tstamp.tv_usec);\
+       COPY(tstamp.tv_sec);\
+       COPY(tstamp.tv_usec);\
+       COPY(appl_ptr);\
+       COPY(hw_ptr);\
+       COPY(delay);\
+       COPY(avail);\
+       COPY(avail_max);\
+       COPY(overrange);\
+       COPY(suspended_state);\
+}
+
+struct sndrv_xferi32 {
+       s32 result;
+       u32 buf;
+       u32 frames;
+};
+
+#define CVT_sndrv_xferi()\
+{\
+       COPY(result);\
+       CPTR(buf);\
+       COPY(frames);\
+}
+
+DEFINE_ALSA_IOCTL(pcm_uframes_str);
+DEFINE_ALSA_IOCTL(pcm_sframes_str);
+DEFINE_ALSA_IOCTL(pcm_hw_params);
+DEFINE_ALSA_IOCTL(pcm_sw_params);
+DEFINE_ALSA_IOCTL(pcm_channel_info);
+DEFINE_ALSA_IOCTL(pcm_status);
+DEFINE_ALSA_IOCTL(xferi);
+
+/* snd_xfern needs remapping of bufs */
+struct sndrv_xfern32 {
+       s32 result;
+       u32 bufs;  /* this is void **; */
+       u32 frames;
+};
+
+/*
+ * xfern ioctl nees to copy (up to) 128 pointers on stack.
+ * although we may pass the copied pointers through f_op->ioctl, but the ioctl
+ * handler there expands again the same 128 pointers on stack, so it is better
+ * to handle the function (calling pcm_readv/writev) directly in this handler.
+ */
+static int snd_ioctl32_xfern(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
+{
+       snd_pcm_file_t *pcm_file;
+       snd_pcm_substream_t *substream;
+       struct sndrv_xfern32 data32, *srcptr = (struct sndrv_xfern32*)arg;
+       void *bufs[128];
+       int err = 0, ch, i;
+       u32 *bufptr;
+
+       /* FIXME: need to check whether fop->ioctl is sane */
+
+       pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO);
+       substream = pcm_file->substream;
+       snd_assert(substream != NULL && substream->runtime, return -ENXIO);
+
+       /* check validty of the command */
+       switch (cmd) {
+       case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
+               if (substream->stream  != SNDRV_PCM_STREAM_PLAYBACK)
+                       return -EINVAL;
+               if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
+                       return -EBADFD;
+       case SNDRV_PCM_IOCTL_READN_FRAMES:
+               if (substream->stream  != SNDRV_PCM_STREAM_CAPTURE)
+                       return -EINVAL;
+               break;
+       }
+       if ((ch = substream->runtime->channels) > 128)
+               return -EINVAL;
+       if (get_user(data32.frames, &srcptr->frames))
+               return -EFAULT;
+       __get_user(data32.bufs, &srcptr->bufs);
+       bufptr = (u32*)TO_PTR(data32.bufs);
+       for (i = 0; i < ch; i++) {
+               u32 ptr;
+               if (get_user(ptr, bufptr))
+                       return -EFAULT;
+               bufs[ch] = (void*)TO_PTR(ptr);
+               bufptr++;
+       }
+       switch (cmd) {
+       case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
+               err = snd_pcm_lib_writev(substream, bufs, data32.frames);
+               break;
+       case SNDRV_PCM_IOCTL_READN_FRAMES:
+               err = snd_pcm_lib_readv(substream, bufs, data32.frames);
+               break;
+       }
+       
+       if (err < 0)
+               return err;
+       if (put_user(err, &srcptr->result))
+               return -EFAULT;
+       return err < 0 ? err : 0;
+}
+
+
+#define AP(x) snd_ioctl32_##x
+
+struct ioctl32_mapper pcm_mappers[] = {
+       { SNDRV_PCM_IOCTL_PVERSION, NULL },
+       { SNDRV_PCM_IOCTL_INFO, NULL },
+       { SNDRV_PCM_IOCTL_HW_REFINE, AP(pcm_hw_params) },
+       { SNDRV_PCM_IOCTL_HW_PARAMS, AP(pcm_hw_params) },
+       { SNDRV_PCM_IOCTL_HW_FREE, NULL },
+       { SNDRV_PCM_IOCTL_SW_PARAMS, AP(pcm_sw_params) },
+       { SNDRV_PCM_IOCTL_STATUS, AP(pcm_status) },
+       { SNDRV_PCM_IOCTL_DELAY, AP(pcm_sframes_str) },
+       { SNDRV_PCM_IOCTL_CHANNEL_INFO, AP(pcm_channel_info) },
+       { SNDRV_PCM_IOCTL_PREPARE, NULL },
+       { SNDRV_PCM_IOCTL_RESET, NULL },
+       { SNDRV_PCM_IOCTL_START, NULL },
+       { SNDRV_PCM_IOCTL_DROP, NULL },
+       { SNDRV_PCM_IOCTL_DRAIN, NULL },
+       { SNDRV_PCM_IOCTL_PAUSE, NULL },
+       { SNDRV_PCM_IOCTL_REWIND, AP(pcm_uframes_str) },
+       { SNDRV_PCM_IOCTL_RESUME, NULL },
+       { SNDRV_PCM_IOCTL_XRUN, NULL },
+       { SNDRV_PCM_IOCTL_WRITEI_FRAMES, AP(xferi) },
+       { SNDRV_PCM_IOCTL_READI_FRAMES, AP(xferi) },
+       { SNDRV_PCM_IOCTL_WRITEN_FRAMES, AP(xfern) },
+       { SNDRV_PCM_IOCTL_READN_FRAMES, AP(xfern) },
+       { SNDRV_PCM_IOCTL_LINK, NULL },
+       { SNDRV_PCM_IOCTL_UNLINK, NULL },
+
+       { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL },
+       { SNDRV_CTL_IOCTL_PCM_INFO, NULL },
+       { SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL },
+
+       { 0 },
+};
diff --git a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c
new file mode 100644 (file)
index 0000000..d5e89ff
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *   32bit -> 64bit ioctl wrapper for raw MIDI API
+ *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define __NO_VERSION__
+#include <sound/driver.h>
+#include <linux/time.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+#include <asm/uaccess.h>
+#include "ioctl32.h"
+
+struct sndrv_rawmidi_params32 {
+       s32 stream;
+       u32 buffer_size;
+       u32 avail_min;
+       unsigned int no_active_sensing: 1;
+       unsigned char reserved[16];
+};
+
+#define CVT_sndrv_rawmidi_params()\
+{\
+       COPY(stream);\
+       COPY(buffer_size);\
+       COPY(avail_min);\
+       COPY(no_active_sensing);\
+}
+
+struct timeval32 {
+       s32 tv_sec;
+       s32 tv_usec;
+};
+
+struct sndrv_rawmidi_status32 {
+       s32 stream;
+       struct timeval32 tstamp;
+       u32 avail;
+       u32 xruns;
+       unsigned char reserved[16];
+};
+
+#define CVT_sndrv_rawmidi_status()\
+{\
+       COPY(stream);\
+       COPY(tstamp.tv_sec);\
+       COPY(tstamp.tv_usec);\
+       COPY(avail);\
+       COPY(xruns);\
+}
+
+DEFINE_ALSA_IOCTL(rawmidi_params);
+DEFINE_ALSA_IOCTL(rawmidi_status);
+
+
+#define AP(x) snd_ioctl32_##x
+
+struct ioctl32_mapper rawmidi_mappers[] = {
+       { SNDRV_RAWMIDI_IOCTL_PVERSION, NULL },
+       { SNDRV_RAWMIDI_IOCTL_INFO, NULL },
+       { SNDRV_RAWMIDI_IOCTL_PARAMS, AP(rawmidi_params) },
+       { SNDRV_RAWMIDI_IOCTL_STATUS, AP(rawmidi_status) },
+       { SNDRV_RAWMIDI_IOCTL_DROP, NULL },
+       { SNDRV_RAWMIDI_IOCTL_DRAIN, NULL },
+
+       { SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE, NULL },
+       { SNDRV_CTL_IOCTL_RAWMIDI_INFO, NULL },
+       { SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, NULL },
+
+       { 0 },
+};
diff --git a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c
new file mode 100644 (file)
index 0000000..4e657f7
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ *   32bit -> 64bit ioctl wrapper for timer API
+ *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define __NO_VERSION__
+#include <sound/driver.h>
+#include <linux/time.h>
+#include <sound/core.h>
+#include <sound/timer.h>
+#include <asm/uaccess.h>
+#include "ioctl32.h"
+
+struct sndrv_timer_info32 {
+       u32 flags;
+       s32 card;
+       unsigned char id[64];
+       unsigned char name[80];
+       u32 ticks;
+       u32 resolution;
+       unsigned char reserved[64];
+};
+
+#define CVT_sndrv_timer_info()\
+{\
+       COPY(flags);\
+       COPY(card);\
+       memcpy(dst->id, src->id, sizeof(src->id));\
+       memcpy(dst->name, src->name, sizeof(src->name));\
+       COPY(ticks);\
+       COPY(resolution);\
+}
+
+struct timeval32 {
+       s32 tv_sec;
+       s32 tv_usec;
+};
+
+struct sndrv_timer_status32 {
+       struct timeval32 tstamp;
+       u32 resolution;
+       u32 lost;
+       u32 overrun;
+       u32 queue;
+       unsigned char reserved[64];
+};
+
+#define CVT_sndrv_timer_status()\
+{\
+       COPY(tstamp.tv_sec);\
+       COPY(tstamp.tv_usec);\
+       COPY(resolution);\
+       COPY(lost);\
+       COPY(overrun);\
+       COPY(queue);\
+}
+
+DEFINE_ALSA_IOCTL(timer_info);
+DEFINE_ALSA_IOCTL(timer_status);
+
+
+/*
+ */
+
+#define AP(x) snd_ioctl32_##x
+
+struct ioctl32_mapper timer_mappers[] = {
+       { SNDRV_TIMER_IOCTL_PVERSION, NULL },
+       { SNDRV_TIMER_IOCTL_NEXT_DEVICE, NULL },
+       { SNDRV_TIMER_IOCTL_SELECT, NULL },
+       { SNDRV_TIMER_IOCTL_INFO, AP(timer_info) },
+       { SNDRV_TIMER_IOCTL_PARAMS, NULL },
+       { SNDRV_TIMER_IOCTL_STATUS, AP(timer_status) },
+       { SNDRV_TIMER_IOCTL_START, NULL },
+       { SNDRV_TIMER_IOCTL_STOP, NULL },
+       { SNDRV_TIMER_IOCTL_CONTINUE, NULL },
+       { 0 },
+};
index 57bcaa94802c654a879f8c7ac62f022dc5585935..03cc8bce04b20e86020f068bff204cbf07eec648 100644 (file)
@@ -516,7 +516,6 @@ static int snd_pcm_oss_make_ready(snd_pcm_substream_t *substream)
 snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       mm_segment_t fs;
        int ret;
        while (1) {
                if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -525,11 +524,14 @@ snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char
                        if (ret < 0)
                                break;
                }
-               if (in_kernel)
+               if (in_kernel) {
+                       mm_segment_t fs;
                        fs = snd_enter_user();
-               ret = snd_pcm_lib_write(substream, ptr, frames);
-               if (in_kernel)
+                       ret = snd_pcm_lib_write(substream, ptr, frames);
                        snd_leave_user(fs);
+               } else {
+                       ret = snd_pcm_lib_write(substream, ptr, frames);
+               }
                if (ret != -EPIPE && ret != -ESTRPIPE)
                        break;
                /* test, if we can't store new data, because the stream */
@@ -543,7 +545,6 @@ snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char
 snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       mm_segment_t fs;
        int ret;
        while (1) {
                if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -556,11 +557,15 @@ snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, s
                        if (ret < 0)
                                break;
                }
-               if (in_kernel)
-                       fs = snd_enter_user();
                ret = snd_pcm_lib_read(substream, ptr, frames);
-               if (in_kernel)
+               if (in_kernel) {
+                       mm_segment_t fs;
+                       fs = snd_enter_user();
+                       ret = snd_pcm_lib_read(substream, ptr, frames);
                        snd_leave_user(fs);
+               } else {
+                       ret = snd_pcm_lib_read(substream, ptr, frames);
+               }
                if (ret != -EPIPE && ret != -ESTRPIPE)
                        break;
        }
@@ -570,7 +575,6 @@ snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, s
 snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       mm_segment_t fs;
        int ret;
        while (1) {
                if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -579,13 +583,17 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **buf
                        if (ret < 0)
                                break;
                }
-               if (in_kernel)
+               if (in_kernel) {
+                       mm_segment_t fs;
                        fs = snd_enter_user();
-               ret = snd_pcm_lib_writev(substream, bufs, frames);
-               if (in_kernel)
+                       ret = snd_pcm_lib_writev(substream, bufs, frames);
                        snd_leave_user(fs);
+               } else {
+                       ret = snd_pcm_lib_writev(substream, bufs, frames);
+               }
                if (ret != -EPIPE && ret != -ESTRPIPE)
                        break;
+
                /* test, if we can't store new data, because the stream */
                /* has not been started */
                if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
@@ -597,7 +605,6 @@ snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **buf
 snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
-       mm_segment_t fs;
        int ret;
        while (1) {
                if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -610,11 +617,14 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs
                        if (ret < 0)
                                break;
                }
-               if (in_kernel)
+               if (in_kernel) {
+                       mm_segment_t fs;
                        fs = snd_enter_user();
-               ret = snd_pcm_lib_readv(substream, bufs, frames);
-               if (in_kernel)
+                       ret = snd_pcm_lib_readv(substream, bufs, frames);
                        snd_leave_user(fs);
+               } else {
+                       ret = snd_pcm_lib_readv(substream, bufs, frames);
+               }
                if (ret != -EPIPE && ret != -ESTRPIPE)
                        break;
        }
index 51005b69d76b11f3cb5851e4a9812300ab2d03be..c7085ae4aef50815b2d4dc4f718ce120f2a7dd98 100644 (file)
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
- * 
- *================================================================
- * For enabling this timer, apply the patch file to your kernel.
- * The configure script checks the patch automatically.
- * The patches, rtc-xxx.dif, are found under utils/patches, where
- * xxx is the kernel version.
- *================================================================
- *
  */
 
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/time.h>
+#include <linux/interrupt.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 #include <sound/info.h>
@@ -59,7 +52,7 @@ static int rtctimer_stop(snd_timer_t *t);
 
 
 /*
- * The harware depenant description for this timer.
+ * The hardware dependent description for this timer.
  */
 static struct _snd_timer_hardware rtc_hw = {
        flags:          SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO,
@@ -72,7 +65,7 @@ static struct _snd_timer_hardware rtc_hw = {
 
 int rtctimer_freq = RTC_FREQ;          /* frequency */
 static snd_timer_t *rtctimer;
-static volatile int rtc_inc = 0;
+static atomic_t rtc_inc = ATOMIC_INIT(0);
 static rtc_task_t rtc_task;
 
 /* tasklet */
@@ -83,6 +76,10 @@ static struct tasklet_struct rtc_tq;
 static int
 rtctimer_open(snd_timer_t *t)
 {
+       err = rtc_register(&rtc_task);
+       if (err < 0)
+               return err;
+       t->private_data = &rtc_task;
        MOD_INC_USE_COUNT;
        return 0;
 }
@@ -90,6 +87,11 @@ rtctimer_open(snd_timer_t *t)
 static int
 rtctimer_close(snd_timer_t *t)
 {
+       rtc_task_t *rtc = t->private_data;
+       if (rtc) {
+               rtc_unregister(rtc);
+               t->private_data = NULL;
+       }
        MOD_DEC_USE_COUNT;
        return 0;
 }
@@ -101,7 +103,7 @@ rtctimer_start(snd_timer_t *timer)
        snd_assert(rtc != NULL, return -EINVAL);
        rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
        rtc_control(rtc, RTC_PIE_ON, 0);
-       rtc_inc = 0;
+       atomic_set(&rtc_inc, 0);
        return 0;
 }
 
@@ -119,12 +121,15 @@ rtctimer_stop(snd_timer_t *timer)
  */
 static void rtctimer_interrupt(void *private_data)
 {
-       rtc_inc++;
+       atomic_inc(&rtc_inc);
 #ifdef USE_TASKLET
        tasklet_hi_schedule(&rtc_tq);
 #else
-       snd_timer_interrupt((snd_timer_t*)private_data, rtc_inc);
-       rtc_inc = 0;
+       {
+               int ticks = atomic_read(&rtc_inc);
+               snd_timer_interrupt((snd_timer_t*)private_data, ticks);
+               atomic_sub(ticks, &rtc_inc);
+       }
 #endif /* USE_TASKLET */
 }
 
@@ -132,20 +137,16 @@ static void rtctimer_interrupt(void *private_data)
 static void rtctimer_interrupt2(unsigned long private_data)
 {
        snd_timer_t *timer = (snd_timer_t *)private_data;
+       int ticks;
+
        snd_assert(timer != NULL, return);
        do {
-               snd_timer_interrupt(timer, 1);
-       } while (--rtc_inc > 0);
+               ticks = atomic_read(&rtc_inc);
+               snd_timer_interrupt(timer, ticks);
+       } while (!atomic_sub_and_test(ticks, &rtc_inc));
 }
 #endif /* USE_TASKLET */
 
-static void rtctimer_private_free(snd_timer_t *timer)
-{
-       rtc_task_t *rtc = timer->private_data;
-       if (rtc)
-               rtc_unregister(rtc);
-}
-
 
 /*
  *  ENTRY functions
@@ -179,23 +180,16 @@ static int __init rtctimer_init(void)
        timer->hw = rtc_hw;
        timer->hw.resolution = NANO_SEC / rtctimer_freq;
 
-       /* register RTC callback */
+       /* set up RTC callback */
        rtc_task.func = rtctimer_interrupt;
        rtc_task.private_data = timer;
-       err = rtc_register(&rtc_task);
-       if (err < 0) {
-               snd_timer_global_free(timer);
-               return err;
-       }
-       timer->private_data = &rtc_task;
-       timer->private_free = rtctimer_private_free;
 
        err = snd_timer_global_register(timer);
        if (err < 0) {
                snd_timer_global_free(timer);
                return err;
        }
-       rtctimer = timer;
+       rtctimer = timer; /* remember this */
 
        return 0;
 }
@@ -210,7 +204,7 @@ static void __exit rtctimer_exit(void)
 
 
 /*
- * exported stuffs
+ * exported stuff
  */
 module_init(rtctimer_init)
 module_exit(rtctimer_exit)
index ef7fc7a9e5a54bfce0be79b11084f565f2497e77..569cd0ae110f2e072127126dbd4b4caf780fbbcd 100644 (file)
@@ -72,6 +72,7 @@ obj-$(CONFIG_SND_ES1938) += snd-seq-device.o snd-seq-midi-emul.o snd-seq.o snd-s
 obj-$(CONFIG_SND_ES1968) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
 obj-$(CONFIG_SND_FM801) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
 obj-$(CONFIG_SND_ICE1712) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
+obj-$(CONFIG_SND_INTEL8X0) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
 obj-$(CONFIG_SND_SONICVIBES) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
 obj-$(CONFIG_SND_VIA686) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
 obj-$(CONFIG_SND_ALI5451) += snd-seq-midi.o snd-seq.o snd-seq-device.o snd-seq-midi-event.o
index b3ced9438d9107b7dbf630f22ae3e4fd19d127fe..7ebf0514b16b9c064d000027e45ed55a4d53916f 100644 (file)
@@ -68,8 +68,8 @@ static struct status_event_list_t {
        event_decode_t decode;
 } status_event[] = {
        /* 0x80 - 0xf0 */
-       {SNDRV_SEQ_EVENT_NOTEOFF,               2, note_event, note_decode},
-       {SNDRV_SEQ_EVENT_NOTEON,                2, note_event, note_decode},
+       {SNDRV_SEQ_EVENT_NOTEOFF,       2, note_event, note_decode},
+       {SNDRV_SEQ_EVENT_NOTEON,        2, note_event, note_decode},
        {SNDRV_SEQ_EVENT_KEYPRESS,      2, note_event, note_decode},
        {SNDRV_SEQ_EVENT_CONTROLLER,    2, two_param_ctrl_event, two_param_decode},
        {SNDRV_SEQ_EVENT_PGMCHANGE,     1, one_param_ctrl_event, one_param_decode},
@@ -78,9 +78,9 @@ static struct status_event_list_t {
        {SNDRV_SEQ_EVENT_NONE,          0, NULL, NULL}, /* 0xf0 */
        /* 0xf0 - 0xff */
        {SNDRV_SEQ_EVENT_SYSEX,         1, NULL, NULL}, /* sysex: 0xf0 */
-       {SNDRV_SEQ_EVENT_QFRAME,                1, one_param_event, one_param_decode}, /* 0xf1 */
-       {SNDRV_SEQ_EVENT_SONGPOS,               2, songpos_event, songpos_decode}, /* 0xf2 */
-       {SNDRV_SEQ_EVENT_SONGSEL,               1, one_param_event, one_param_decode}, /* 0xf3 */
+       {SNDRV_SEQ_EVENT_QFRAME,        1, one_param_event, one_param_decode}, /* 0xf1 */
+       {SNDRV_SEQ_EVENT_SONGPOS,       2, songpos_event, songpos_decode}, /* 0xf2 */
+       {SNDRV_SEQ_EVENT_SONGSEL,       1, one_param_event, one_param_decode}, /* 0xf3 */
        {SNDRV_SEQ_EVENT_NONE,          0, NULL, NULL}, /* 0xf4 */
        {SNDRV_SEQ_EVENT_NONE,          0, NULL, NULL}, /* 0xf5 */
        {SNDRV_SEQ_EVENT_TUNE_REQUEST,  0, NULL, NULL}, /* 0xf6 */
@@ -92,7 +92,7 @@ static struct status_event_list_t {
        {SNDRV_SEQ_EVENT_STOP,          0, NULL, NULL}, /* 0xfc */
        {SNDRV_SEQ_EVENT_NONE,          0, NULL, NULL}, /* 0xfd */
        {SNDRV_SEQ_EVENT_SENSING,       0, NULL, NULL}, /* 0xfe */
-       {SNDRV_SEQ_EVENT_RESET,                 0, NULL, NULL}, /* 0xff */
+       {SNDRV_SEQ_EVENT_RESET,         0, NULL, NULL}, /* 0xff */
 };
 
 static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
@@ -128,6 +128,7 @@ int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev)
                }
        }
        dev->bufsize = bufsize;
+       dev->lastcmd = 0xff;
        spin_lock_init(&dev->lock);
        *rdev = dev;
        return 0;
index df7d693256ab9f41b7f3e9ff9d1a568550bb8781..62271b8b21c8a34dac9a3ba6487f05cbfbddd7e1 100644 (file)
@@ -233,8 +233,7 @@ static int snd_virmidi_output_open(snd_rawmidi_substream_t * substream)
        }
        vmidi->seq_mode = rdev->seq_mode;
        vmidi->client = rdev->client;
-       vmidi->port = rdev->port;       
-       snd_midi_event_init(vmidi->parser);
+       vmidi->port = rdev->port;
        snd_virmidi_init_event(vmidi, &vmidi->event);
        vmidi->rdev = rdev;
        runtime->private_data = vmidi;
index c3c363091fadbbcda3c2d5ffa551011a8b52758a..21ce042c818d0e074201e115809b71165848642c 100644 (file)
@@ -212,7 +212,7 @@ int __init snd_minor_info_oss_init(void)
 {
        snd_info_entry_t *entry;
 
-       entry = snd_info_create_module_entry(THIS_MODULE, "oss-devices", NULL);
+       entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
        if (entry) {
                entry->content = SNDRV_INFO_CONTENT_TEXT;
                entry->c.text.read_size = PAGE_SIZE;
diff --git a/sound/drivers/Config.help b/sound/drivers/Config.help
new file mode 100644 (file)
index 0000000..7fea384
--- /dev/null
@@ -0,0 +1,18 @@
+CONFIG_SND_DUMMY
+  Say 'Y' or 'M' to include dummy driver. This driver does nothing, but
+  emulates various mixer controls and PCM devices.
+  
+CONFIG_SND_VIRMIDI
+  Say 'Y' or 'M' to include virtual MIDI driver. This driver allows to
+  connect applications using raw MIDI devices to sequencer.
+
+CONFIG_SND_MTPAV
+  Say 'Y' or 'M' to include support for MOTU MidiTimePiece AV multiport
+  MIDI adapter.
+
+CONFIG_SND_SERIAL_U16550
+  Say 'Y' or 'M' to include support for MIDI serial port driver. It works
+  with serial UARTs 16550 and better.
+
+CONFIG_SND_MPU401
+  Say 'Y' or 'M' to include support for MPU401 hardware using UART access.
index 731ac31ac7f20b57d5055d04ff28723f711e4d23..d21747f1cd30d354e04ac5071b5332edb38f4899 100644 (file)
@@ -37,6 +37,7 @@ obj-$(CONFIG_SND_ES1938) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_ES1968) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o
+obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_VIA686) += snd-mpu401-uart.o
 obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o
index 8993ade328cf5c472ef198225df78904cbafe333..b399150e2a6fcac715f0807f1a6f1aed52cc3cc8 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/mpu401.h>
 
index 64913d5104ba55af4ef8d7a67d21133ae2a8b28b..450032e8a34ae611dfce6dfe42eeda5425125be4 100644 (file)
@@ -54,6 +54,7 @@
 #include <asm/io.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
index 77ce497b98772ed3afc12af232ecfe3d1d063241..371dfb9b1bfe86a8e05b2f3922feef1e6612b7f0 100644 (file)
@@ -29,7 +29,7 @@ obj-$(CONFIG_SND_GUSEXTREME) += snd-opl3-lib.o
 obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opl3-lib.o
 obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opl3-lib.o
 obj-$(CONFIG_SND_OPTI93X) += snd-opl3-lib.o
-obj-$(CONFIG_SND_SB) += snd-opl3-lib.o
+obj-$(CONFIG_SND_SB8) += snd-opl3-lib.o
 obj-$(CONFIG_SND_SB16) += snd-opl3-lib.o
 obj-$(CONFIG_SND_SBAWE) += snd-opl3-lib.o
 obj-$(CONFIG_SND_WAVEFRONT) += snd-opl3-lib.o
@@ -54,7 +54,7 @@ ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
   obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-opl3-synth.o
   obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-opl3-synth.o
   obj-$(CONFIG_SND_OPTI93X) += snd-opl3-synth.o
-  obj-$(CONFIG_SND_SB) += snd-opl3-synth.o
+  obj-$(CONFIG_SND_SB8) += snd-opl3-synth.o
   obj-$(CONFIG_SND_SB16) += snd-opl3-synth.o
   obj-$(CONFIG_SND_SBAWE) += snd-opl3-synth.o
   obj-$(CONFIG_SND_WAVEFRONT) += snd-opl3-synth.o
index 8f8400bee5f359e5716762c440037a4ddca1a19b..91faf5941b4b92ebc365cf4373f27ef90c029266 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/minors.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
index 51668110b7721fbc9d6d4fb952922eab399a46b5..b2ff32b3062344ba18b24c81b4adcbb4a52e0acf 100644 (file)
@@ -39,7 +39,7 @@
  * 
  *      Usage example for MS-124T, with A-B switch in A position:
  *        setserial /dev/ttyS0 uart none
- *        /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \
+ *        /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
  *            snd_adaptor=1 snd_speed=19200
  *
  *      - In MS-124W S/A mode, one raw MIDI substream is supported
@@ -49,7 +49,7 @@
  * 
  *      Usage example for S/A mode:
  *        setserial /dev/ttyS0 uart none
- *        /sbin/modprobe snd-card-serial snd_port=0x3f8 snd_irq=4 \
+ *        /sbin/modprobe snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
  *            snd_adaptor=2
  *
  *      - In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI
@@ -67,7 +67,7 @@
  * 
  *      Usage example for M/B mode:
  *        setserial /dev/ttyS0 uart none
- *        /sbin/insmod snd-card-serial snd_port=0x3f8 snd_irq=4 \
+ *        /sbin/insmod snd-serial-u16550 snd_port=0x3f8 snd_irq=4 \
  *            snd_adaptor=3
  *
  *      - The MS-124W hardware's M/A mode is currently not supported.
 #include <asm/io.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/rawmidi.h>
 #define SNDRV_GET_ID
index eff64d7553a50b8c956144a6f6b24d8aa72a7b69..b9c505fb552d8f22e2145ef4177fb4f39eb41c49 100644 (file)
@@ -13,7 +13,7 @@ snd-i2c-objs := i2c.o
 snd-cs8427-objs := cs8427.o
 snd-tea6330t-objs := tea6330t.o
 
-# Module Dependency
+# Toplevel Module Dependency
 obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o
 obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o
 
diff --git a/sound/isa/Config.help b/sound/isa/Config.help
new file mode 100644 (file)
index 0000000..eac9a93
--- /dev/null
@@ -0,0 +1,99 @@
+CONFIG_SND_AD1816A
+  Say 'Y' or 'M' to include support for Analog Devices SoundPort AD1816A or
+  compatible sound chips.
+
+CONFIG_SND_AD1848
+  Say 'Y' or 'M' to include support for AD1848 (Analog Devices) or CS4248 
+  (Cirrus Logic - Crystal Semiconductors) chips. Please, for newer chips
+  from Cirrus Logic, use CS4231, CS4232 or CS4236+ driver.
+
+CONFIG_SND_CS4231
+  Say 'Y' or 'M' to include support for CS4231 chips from Cirrus Logic -
+  Crystal Semiconductors.
+
+CONFIG_SND_CS4232
+  Say 'Y' or 'M' to include support for CS4232 chips from Cirrus Logic -
+  Crystal Semiconductors.
+
+CONFIG_SND_CS4236
+  Say 'Y' or 'M' to include support for CS4235,CS4236,CS4237B,CS4238B,CS4239
+  chips from Cirrus Logic - Crystal Semiconductors.
+
+CONFIG_SND_ES968
+  Say 'Y' or 'M' to include support for ESS AudioDrive ES968 chip.
+
+CONFIG_SND_ES1688
+  Say 'Y' or 'M' to include support for ESS AudioDrive ES688 or ES1688 chips.
+
+CONFIG_SND_ES18XX
+  Say 'Y' or 'M' to include support for ESS AudioDrive ES18xx chips.
+
+CONFIG_SND_GUSCLASSIC
+  Say 'Y' or 'M' to include support for Gravis UltraSound Classic soundcard.
+
+CONFIG_SND_GUSEXTREME
+  Say 'Y' or 'M' to include support for Gravis UltraSound Extreme soundcard.
+
+CONFIG_SND_GUSMAX
+  Say 'Y' or 'M' to include support for Gravis UltraSound MAX soundcard.
+
+CONFIG_SND_INTERWAVE
+  Say 'Y' or 'M' to include support for AMD InterWave based soundcards
+  (Gravis UltraSound Plug & Play, STB SoundRage32, MED3210, Dynasonic Pro,
+  Panasonic PCA761AW).
+
+CONFIG_SND_INTERWAVE_STB
+  Say 'Y' or 'M' to include support for AMD InterWave based soundcards
+  with TEA6330T bass and treble regulator (UltraSound 32-Pro).
+
+CONFIG_SND_OPTI92X_AD1848
+  Say 'Y' or 'M' to include support for Opti92x soundcards equiped with
+  AD1848 codec.
+
+CONFIG_SND_OPTI92X_CS4231
+  Say 'Y' or 'M' to include support for Opti92x soundcards equiped with
+  CS4231 codec.
+
+CONFIG_SND_OPTI93X
+  Say 'Y' or 'M' to include support for Opti93x soundcards.
+
+CONFIG_SND_SB8
+  Say 'Y' or 'M' to include support for Sound Blaster 1.0/2.0/Pro (8-bit)
+  soundcards or 100% compatible from Creative.
+
+CONFIG_SND_SB16
+  Say 'Y' or 'M' to include support for Sound Blaster 16 (including
+  Plug and Play version).
+
+CONFIG_SND_SBAWE
+  Say 'Y' or 'M' to include support for Sound Blaster AWE (including
+  Plug and Play version).
+
+CONFIG_SND_SB16_CSP
+  Say 'Y' to include support for CSP core. This special coprocessor
+  can do variable tasks like various compression and decompression
+  algorithms.
+
+CONFIG_SND_WAVEFRONT
+  Say 'Y' or 'M' to include support for Turtle Beach Maui, Tropez
+  and Tropez+ soundcards based on Wavefront chip.
+
+CONFIG_SND_ALS100
+  Say 'Y' or 'M' to include support for Avance Logic ALS100, ALS110,
+  ALS120 and ALS200 soundcards.
+
+CONFIG_SND_AZT2320
+  Say 'Y' or 'M' to include support for Aztech Systems AZT2320 soundcard.
+
+CONFIG_SND_CMI8330
+  Say 'Y' or 'M' to include support for C-Media CMI8330 based soundcards.
+
+CONFIG_SND_DT0197H
+  Say 'Y' or 'M' to include support for Diamond Technologies DT-0197H
+  soundcards.
+
+CONFIG_SND_OPL3SA2
+  Say 'Y' or 'M' to include support for Yamaha OPL3SA2 or OPL3SA3 chips.
+
+CONFIG_SND_SGALAXY
+  Say 'Y' or 'M' to include support for Aztech Sound Galaxy.
index 2688d1bba07a3268fc76970398f81788330bbe76..4461706461c7ad7b7bc31e74fe6ab0d911db0644 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/ad1816a.h>
 
index 9e69d06cd835f75798b918693f2e316208f7c410..7680dbf77491ecd4c4e8eea25a5827786afdf186 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/dma.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/ad1848.h>
 
index fa55a9fdf1203de9eb35d7ba6f0d428653bca1ca..8e84e21628be781140b6404929f107cbfa4e8c82 100644 (file)
@@ -134,7 +134,7 @@ static const struct isapnp_card_id *snd_azt2320_isapnp_id[SNDRV_CARDS] __devinit
 static struct isapnp_card_id snd_azt2320_pnpids[] __devinitdata = {
        /* PRO16V */
        ISAPNP_AZT2320('A','Z','T',0x1008,0x1008,0x2001),
-       /* --- */
+       /* Aztech Sound Galaxy 16 */
        ISAPNP_AZT2320('A','Z','T',0x2320,0x0001,0x0002),
        /* Packard Bell Sound III 336 AM/SP */
        ISAPNP_AZT2320('A','Z','T',0x3000,0x1003,0x2001),
index 23236e5c11113bd3eba00a35fa035cea9209e125..f3c629c124ab51da19ef3633a95e0de48c2b1b5c 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/pm.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/cs4231.h>
 
index 3102bf15d9161b497b0d49216f8d3f6dc243928b..b9f05ba2455d998aea62685fd42868cb04008a52 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/es1688.h>
 #include <sound/initval.h>
index 262f2c1639465444d2905c41fcd1e114fef160a1..9d3a947bf3e9cb2024bbbe319e5a41de24622ed1 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/control.h>
index a389a6548c994729c3b9c8be93776c007c0a30c2..1c8ca4ac6857781f9e99d7e08119362040b65081 100644 (file)
@@ -177,7 +177,7 @@ static struct isapnp_card_id snd_opl3sa2_pnpids[] __devinitdata = {
        ISAPNP_OPL3SA2('Y','M','H',0x0020,0x0021),
        /* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */
        ISAPNP_OPL3SA2('Y','M','H',0x0030,0x0021),
-       /* ??? */
+       /* Yamaha OPL3-SA2 */
        ISAPNP_OPL3SA2('Y','M','H',0x0800,0x0021),
        /* NeoMagic MagicWave 3DX */
        ISAPNP_OPL3SA2('N','M','X',0x2200,0x2210),
index abf402366675f0a40fe1da674896191755e18c00..37b6d10fe07d8458bd6ffff371e4fe72d1bef5a2 100644 (file)
@@ -27,12 +27,12 @@ obj-$(CONFIG_SND_DT0197H) += snd-sb16-dsp.o snd-sb-common.o
 obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o
 obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o
 obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o
+obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o
+obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o
 ifeq ($(CONFIG_SND_SB16_CSP),y)
   obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
   obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o
 endif
-obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o
-obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o
 ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
   obj-$(CONFIG_SND_SBAWE) += snd-emu8000-synth.o
 endif
index 61f4a013016180784b7c62dec235ae315a434c70..01f06bf660868366df3fa6daccb254b84bd7f9b1 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/emu8000.h>
 #include <sound/emu8000_reg.h>
index 0d59af55cd1bf023d3ec697f4ab368e7228c45c9..bd3ddcf38e681bc40980ab4d3d70b322450ceecb 100644 (file)
@@ -209,11 +209,11 @@ static void snd_sb16_csp_capture_close(sb_t *chip)
 #else
 #define snd_sb16_csp_playback_prepare(chip, runtime)   /*nop*/
 #define snd_sb16_csp_capture_prepare(chip, runtime)    /*nop*/
-#define snd_sb16_csp_update(chip)              /*nop*/
+#define snd_sb16_csp_update(chip)                      /*nop*/
 #define snd_sb16_csp_playback_open(chip, runtime)      /*nop*/
-#define snd_sb16_csp_playback_close(chip)      /*nop*/
+#define snd_sb16_csp_playback_close(chip)              /*nop*/
 #define snd_sb16_csp_capture_open(chip, runtime)       /*nop*/
-#define snd_sb16_csp_capture_close(chip)               /*nop*/
+#define snd_sb16_csp_capture_close(chip)               /*nop*/
 #endif
 
 
index d668a174621ad926937b7cb36e7f3964dd4df982..1cbf406d389f4728b6eece1dcccb815f489d3a0f 100644 (file)
@@ -22,6 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/opl3.h>
index 22da20bf6f21d197728587d88a881ee7ff3902cd..3f7a796773a06445f23a3fddaae891d1f8c2f03d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/initval.h>
index 10f4fdf0edb504a8090b365d2e216ce99b887a1b..869c351d9fe8b2664f06dffaa171ab1c4a67d047 100644 (file)
@@ -119,7 +119,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
        static int dma_bits[] = {1, 2, 0, 3};
        int tmp, tmp1;
 
-       unsigned int flags;
+       unsigned long flags;
 
        if ((tmp = inb(port + 3)) == 0xff)
        {
index b356878ebb870b41953ea0b7bb2e073df904778b..777bb390fc0d3691806d97af8b3c4772d9bd620b 100644 (file)
@@ -111,30 +111,6 @@ MODULE_PARM_DESC(ramcheck_time, "how many seconds to wait for the RAM test");
 MODULE_PARM(osrun_time,"i");
 MODULE_PARM_DESC(osrun_time, "how many seconds to wait for the ICS2115 OS");
 
-/*
- *     This sucks, hopefully it'll get standardised
- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,18) && LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#define loops_per_sec loops_per_jiffy*HZ
-#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,4,0) && defined(I_DIRTY_PAGES) /* linux/fs.h */
-#define loops_per_sec loops_per_jiffy*HZ
-#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
-#define loops_per_sec loops_per_jiffy*HZ
-#endif
-#if defined(__alpha__) || defined(__powerpc__)
-#ifdef __SMP__
-#define LOOPS_PER_SEC  (cpu_data[smp_processor_id()].loops_per_sec)
-#else
-#define LOOPS_PER_SEC  (loops_per_sec)
-#endif
-#endif
-
-#if defined(__i386__)
-#define LOOPS_PER_SEC  (current_cpu_data.loops_per_sec)
-#endif
 /* if WF_DEBUG not defined, no run-time debugging messages will
    be available via the debug flag setting. Given the current
    beta state of the driver, this will remain set until a future 
@@ -323,26 +299,16 @@ wavefront_wait (snd_wavefront_t *dev, int mask)
 
 {
        int             i;
-       static int      short_loop_cnt = 0;
-
-       /* Compute the loop count that lets us sleep for about the
-          right amount of time, cache issues, bus speeds and all
-          other issues being unequal but largely irrelevant.
-       */
-
-       if (short_loop_cnt == 0) {
-               short_loop_cnt = wait_usecs *
-                       (LOOPS_PER_SEC / 1000000);
-       }
 
        /* Spin for a short period of time, because >99% of all
           requests to the WaveFront can be serviced inline like this.
        */
 
-       for (i = 0; i < short_loop_cnt; i++) {
+       for (i = 0; i < wait_usecs; i += 5) {
                if (wavefront_status (dev) & mask) {
                        return 1;
                }
+               udelay(5);
        }
 
        for (i = 0; i < sleep_tries; i++) {
@@ -1316,18 +1282,21 @@ wavefront_fetch_multisample (snd_wavefront_t *dev,
     
        for (i = 0; i < num_samples; i++) {
                char d[2];
+               int val;
        
-               if ((d[0] = wavefront_read (dev)) == -1) {
+               if ((val = wavefront_read (dev)) == -1) {
                        snd_printk ("upload multisample failed "
                                    "during sample loop.\n");
                        return -(EIO);
                }
+               d[0] = val;
 
-               if ((d[1] = wavefront_read (dev)) == -1) {
+               if ((val = wavefront_read (dev)) == -1) {
                        snd_printk ("upload multisample failed "
                                    "during sample loop.\n");
                        return -(EIO);
                }
+               d[1] = val;
        
                header->hdr.ms.SampleNumber[i] =
                        demunge_int32 ((unsigned char *) d, 2);
diff --git a/sound/pci/Config.help b/sound/pci/Config.help
new file mode 100644 (file)
index 0000000..98a97d3
--- /dev/null
@@ -0,0 +1,75 @@
+CONFIG_SND_ALI5451
+  Say 'Y' or 'M' to include support for ALI PCI Audio M5451 sound core.
+
+CONFIG_SND_CS46XX
+  Say 'Y' or 'M' to include support for Cirrus Logic CS4610 / CS4612 /
+  CS4614 / CS4615 / CS4622 / CS4624 / CS4630 / CS4280 chips.
+
+CONFIG_SND_CS46XX_ACCEPT_VALID
+  Say 'Y' to allow sample resolution for mmap() transfers.
+
+CONFIG_SND_EMU10K1
+  Say 'Y' or 'M' to include support for Sound Blaster PCI 512, Live!,
+  Audigy and E-mu APS (partially supported).
+
+CONFIG_SND_KORG1212
+  Say 'Y' or 'M' to include support for Korg 1212IO.
+
+CONFIG_SND_NM256
+  Say 'Y' or 'M' to include support for NeoMagic NM256AV/ZX chips.
+
+CONFIG_SND_RME96
+  Say 'Y' or 'M' to include support for RME Digi96, Digi96/8 and
+  Digi96/8 PRO/PAD/PST.
+
+CONFIG_SND_RME9652
+  Say 'Y' or 'M' to include support for RME Hammerfall (RME Digi9652 /
+  Digi9636) soundcards.
+
+CONFIG_SND_TRIDENT
+
+CONFIG_SND_YMFPCI
+  Say 'Y' or 'M' to include support for Yamaha PCI audio chips - 
+  YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
+
+CONFIG_SND_ALS4000
+  Say 'Y' or 'M' to include support for Avance Logic ALS4000.
+
+CONFIG_SND_CMIPCI
+  Say 'Y' or 'M' to include support for C-Media CMI8338 and 8738 PCI
+  soundcards.
+
+CONFIG_SND_ENS1370
+  Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1370.
+
+CONFIG_SND_ENS1371
+  Say 'Y' or 'M' to include support for Ensoniq AudioPCI ES1371 and
+  Sound Blaster PCI 64 or 128 soundcards.
+
+CONFIG_SND_ES1938
+  Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946)
+  soundcard.
+
+CONFIG_SND_ES1968
+  Say 'Y' or 'M' to include support for ESS Maestro 1/2/2E.
+
+CONFIG_SND_MAESTRO3
+  Say 'Y' or 'M' to include support for ESS Maestro 3 (Allegro) soundcard.
+
+CONFIG_SND_FM801
+  Say 'Y' or 'M' to include support for ForteMedia FM801 based soundcards.
+
+CONFIG_SND_ICE1712
+  Say 'Y' or 'M' to include support for ICE1712 (Envy24) based soundcards.
+
+CONFIG_SND_INTEL8X0
+  Say 'Y' or 'M' to include support for Intel8x0 based soundcards.
+
+CONFIG_SND_SONICVIBES
+  Say 'Y' or 'M' to include support for S3 SonicVibes based soundcards.
+
+CONFIG_SND_VIA686
+  Say 'Y' or 'M' to include support for VIA VT82C686A/B South Bridge.
+
+CONFIG_SND_VIA8233
+  Say 'Y' or 'M' to include support for VIA VT8233 South Bridge.
index 1bfa2b6e4a65a9e756be93d37aaad6b552e42895..9d9df8f76c5a419889477c0942c5cc04d02bca01 100644 (file)
@@ -109,7 +109,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
        }
 
        legacy_ctrl = 0;
-       legacy_ctrl2 = 0;
+       legacy_ctrl2 = 0x0800;  /* SMOD = 01 */
 
        if (id->device >= 0x0010) { /* YMF 744/754 */
                if (snd_fm_port[dev] < 0)
index 6fc37031ca266af6b367d9e9ca8793fd816c4351..7bcf311f089dc3f896e9e3f88b09031b50422a71 100644 (file)
@@ -15,8 +15,8 @@ export-objs  := util_mem.o
 snd-util-mem-objs := util_mem.o
 
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_TRIDENT) += snd-util-mem.o
 obj-$(CONFIG_SND_EMU10K1) += snd-util-mem.o
+obj-$(CONFIG_SND_TRIDENT) += snd-util-mem.o
 ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
   obj-$(CONFIG_SND_SBAWE) += snd-util-mem.o
 endif