diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/sound | |
download | linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.bz2 linux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'Documentation/sound')
61 files changed, 18508 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt new file mode 100644 index 000000000000..71ef0498d5e0 --- /dev/null +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -0,0 +1,1505 @@ + + Advanced Linux Sound Architecture - Driver + ========================================== + Configuration guide + + +Kernel Configuration +==================== + +To enable ALSA support you need at least to build the kernel with +primary sound card support (CONFIG_SOUND). Since ALSA can emulate OSS, +you don't have to choose any of the OSS modules. + +Enable "OSS API emulation" (CONFIG_SND_OSSEMUL) and both OSS mixer and +PCM supports if you want to run OSS applications with ALSA. + +If you want to support the WaveTable functionality on cards such as +SB Live! then you need to enable "Sequencer support" +(CONFIG_SND_SEQUENCER). + +To make ALSA debug messages more verbose, enable the "Verbose printk" +and "Debug" options. To check for memory leaks, turn on "Debug memory" +too. "Debug detection" will add checks for the detection of cards. + +Please note that all the ALSA ISA drivers support the Linux isapnp API +(if the card supports ISA PnP). You don't need to configure the cards +using isapnptools. + + +Creating ALSA devices +===================== + +This depends on your distribution, but normally you use the /dev/MAKEDEV +script to create the necessary device nodes. On some systems you use a +script named 'snddevices'. + + +Module parameters +================= + +The user can load modules with options. If the module supports more than +one card and you have more than one card of the same type then you can +specify multiple values for the option separated by commas. + +Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. + + Module snd + ---------- + + The core ALSA module. It is used by all ALSA card drivers. + It takes the following options which have global effects. + + major - major number for sound driver + - Default: 116 + cards_limit + - limiting card index for auto-loading (1-8) + - Default: 1 + - For auto-loading more than one card, specify this + option together with snd-card-X aliases. + device_mode + - permission mask for dynamic sound device filesystem + - This is available only when DEVFS is enabled + - Default: 0666 + - E.g.: device_mode=0660 + + + Module snd-pcm-oss + ------------------ + + The PCM OSS emulation module. + This module takes options which change the mapping of devices. + + dsp_map - PCM device number maps assigned to the 1st OSS device. + - Default: 0 + adsp_map - PCM device number maps assigned to the 2st OSS device. + - Default: 1 + nonblock_open + - Don't block opening busy PCM devices. + + For example, when dsp_map=2, /dev/dsp will be mapped to PCM #2 of + the card #0. Similarly, when adsp_map=0, /dev/adsp will be mapped + to PCM #0 of the card #0. + For changing the second or later card, specify the option with + commas, such like "dsp_map=0,1". + + nonblock_open option is used to change the behavior of the PCM + regarding opening the device. When this option is non-zero, + opening a busy OSS PCM device won't be blocked but return + immediately with EAGAIN (just like O_NONBLOCK flag). + + Module snd-rawmidi + ------------------ + + This module takes options which change the mapping of devices. + similar to those of the snd-pcm-oss module. + + midi_map - MIDI device number maps assigned to the 1st OSS device. + - Default: 0 + amidi_map - MIDI device number maps assigned to the 2st OSS device. + - Default: 1 + + Common parameters for top sound card modules + -------------------------------------------- + + Each of top level sound card module takes the following options. + + index - index (slot #) of sound card + - Values: 0 through 7 or negative + - If nonnegative, assign that index number + - if negative, interpret as a bitmask of permissible + indices; the first free permitted index is assigned + - Default: -1 + id - card ID (identifier or name) + - Can be up to 15 characters long + - Default: the card type + - A directory by this name is created under /proc/asound/ + containing information about the card + - This ID can be used instead of the index number in + identifying the card + enable - enable card + - Default: enabled, for PCI and ISA PnP cards + + Module snd-ad1816a + ------------------ + + Module for sound cards based on Analog Devices AD1816A/AD1815 ISA chips. + + port - port # for AD1816A chip (PnP setup) + mpu_port - port # for MPU-401 UART (PnP setup) + fm_port - port # for OPL3 (PnP setup) + irq - IRQ # for AD1816A chip (PnP setup) + mpu_irq - IRQ # for MPU-401 UART (PnP setup) + dma1 - first DMA # for AD1816A chip (PnP setup) + dma2 - second DMA # for AD1816A chip (PnP setup) + + Module supports up to 8 cards, autoprobe and PnP. + + Module snd-ad1848 + ----------------- + + Module for sound cards based on AD1848/AD1847/CS4248 ISA chips. + + port - port # for AD1848 chip + irq - IRQ # for AD1848 chip + dma1 - DMA # for AD1848 chip (0,1,3) + + Module supports up to 8 cards. This module does not support autoprobe + thus main port must be specified!!! Other ports are optional. + + Module snd-ali5451 + ------------------ + + Module for ALi M5451 PCI chip. + + pcm_channels - Number of hardware channels assigned for PCM + spdif - Support SPDIF I/O + - Default: disabled + + Module supports autoprobe and multiple chips (max 8). + + The power-management is supported. + + Module snd-als100 + ----------------- + + Module for sound cards based on Avance Logic ALS100/ALS120 ISA chips. + + port - port # for ALS100 (SB16) chip (PnP setup) + irq - IRQ # for ALS100 (SB16) chip (PnP setup) + dma8 - 8-bit DMA # for ALS100 (SB16) chip (PnP setup) + dma16 - 16-bit DMA # for ALS100 (SB16) chip (PnP setup) + mpu_port - port # for MPU-401 UART (PnP setup) + mpu_irq - IRQ # for MPU-401 (PnP setup) + fm_port - port # for OPL3 FM (PnP setup) + + Module supports up to 8 cards, autoprobe and PnP. + + Module snd-als4000 + ------------------ + + Module for sound cards based on Avance Logic ALS4000 PCI chip. + + joystick_port - port # for legacy joystick support. + 0 = disabled (default), 1 = auto-detect + + Module supports up to 8 cards, autoprobe and PnP. + + Module snd-atiixp + ----------------- + + Module for ATI IXP 150/200/250 AC97 controllers. + + ac97_clock - AC'97 clock (defalut = 48000) + ac97_quirk - AC'97 workaround for strange hardware + See the description of intel8x0 module for details. + spdif_aclink - S/PDIF transfer over AC-link (default = 1) + + This module supports up to 8 cards and autoprobe. + + Module snd-atiixp-modem + ----------------------- + + Module for ATI IXP 150/200/250 AC97 modem controllers. + + Module supports up to 8 cards. + + Note: The default index value of this module is -2, i.e. the first + slot is excluded. + + Module snd-au8810, snd-au8820, snd-au8830 + ----------------------------------------- + + Module for Aureal Vortex, Vortex2 and Advantage device. + + pcifix - Control PCI workarounds + 0 = Disable all workarounds + 1 = Force the PCI latency of the Aureal card to 0xff + 2 = Force the Extend PCI#2 Internal Master for Efficient + Handling of Dummy Requests on the VIA KT133 AGP Bridge + 3 = Force both settings + 255 = Autodetect what is required (default) + + This module supports all ADB PCM channels, ac97 mixer, SPDIF, hardware + EQ, mpu401, gameport. A3D and wavetable support are still in development. + Development and reverse engineering work is being coordinated at + http://savannah.nongnu.org/projects/openvortex/ + SPDIF output has a copy of the AC97 codec output, unless you use the + "spdif" pcm device, which allows raw data passthru. + The hardware EQ hardware and SPDIF is only present in the Vortex2 and + Advantage. + + Note: Some ALSA mixer applicactions don't handle the SPDIF samplerate + control correctly. If you have problems regarding this, try + another ALSA compliant mixer (alsamixer works). + + Module snd-azt2320 + ------------------ + + Module for sound cards based on Aztech System AZT2320 ISA chip (PnP only). + + port - port # for AZT2320 chip (PnP setup) + wss_port - port # for WSS (PnP setup) + mpu_port - port # for MPU-401 UART (PnP setup) + fm_port - FM port # for AZT2320 chip (PnP setup) + irq - IRQ # for AZT2320 (WSS) chip (PnP setup) + mpu_irq - IRQ # for MPU-401 UART (PnP setup) + dma1 - 1st DMA # for AZT2320 (WSS) chip (PnP setup) + dma2 - 2nd DMA # for AZT2320 (WSS) chip (PnP setup) + + Module supports up to 8 cards, PnP and autoprobe. + + Module snd-azt3328 + ------------------ + + Module for sound cards based on Aztech AZF3328 PCI chip. + + joystick - Enable joystick (default off) + + Module supports up to 8 cards. + + Module snd-bt87x + ---------------- + + Module for video cards based on Bt87x chips. + + digital_rate - Override the default digital rate (Hz) + load_all - Load the driver even if the card model isn't known + + Module supports up to 8 cards. + + Note: The default index value of this module is -2, i.e. the first + slot is excluded. + + Module snd-ca0106 + ----------------- + + Module for Creative Audigy LS and SB Live 24bit + + Module supports up to 8 cards. + + + Module snd-cmi8330 + ------------------ + + Module for sound cards based on C-Media CMI8330 ISA chips. + + wssport - port # for CMI8330 chip (WSS) + wssirq - IRQ # for CMI8330 chip (WSS) + wssdma - first DMA # for CMI8330 chip (WSS) + sbport - port # for CMI8330 chip (SB16) + sbirq - IRQ # for CMI8330 chip (SB16) + sbdma8 - 8bit DMA # for CMI8330 chip (SB16) + sbdma16 - 16bit DMA # for CMI8330 chip (SB16) + + Module supports up to 8 cards and autoprobe. + + Module snd-cmipci + ----------------- + + Module for C-Media CMI8338 and 8738 PCI sound cards. + + mpu_port - 0x300,0x310,0x320,0x330, 0 = disable (default) + fm_port - 0x388 (default), 0 = disable (default) + soft_ac3 - Sofware-conversion of raw SPDIF packets (model 033 only) + (default = 1) + joystick_port - Joystick port address (0 = disable, 1 = auto-detect) + + Module supports autoprobe and multiple chips (max 8). + + Module snd-cs4231 + ----------------- + + Module for sound cards based on CS4231 ISA chips. + + port - port # for CS4231 chip + mpu_port - port # for MPU-401 UART (optional), -1 = disable + irq - IRQ # for CS4231 chip + mpu_irq - IRQ # for MPU-401 UART + dma1 - first DMA # for CS4231 chip + dma2 - second DMA # for CS4231 chip + + Module supports up to 8 cards. This module does not support autoprobe + thus main port must be specified!!! Other ports are optional. + + The power-management is supported. + + Module snd-cs4232 + ----------------- + + Module for sound cards based on CS4232/CS4232A ISA chips. + + port - port # for CS4232 chip (PnP setup - 0x534) + cport - control port # for CS4232 chip (PnP setup - 0x120,0x210,0xf00) + mpu_port - port # for MPU-401 UART (PnP setup - 0x300), -1 = disable + fm_port - FM port # for CS4232 chip (PnP setup - 0x388), -1 = disable + irq - IRQ # for CS4232 chip (5,7,9,11,12,15) + mpu_irq - IRQ # for MPU-401 UART (9,11,12,15) + dma1 - first DMA # for CS4232 chip (0,1,3) + dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + Module supports up to 8 cards. This module does not support autoprobe + thus main port must be specified!!! Other ports are optional. + + The power-management is supported. + + Module snd-cs4236 + ----------------- + + Module for sound cards based on CS4235/CS4236/CS4236B/CS4237B/ + CS4238B/CS4239 ISA chips. + + port - port # for CS4236 chip (PnP setup - 0x534) + cport - control port # for CS4236 chip (PnP setup - 0x120,0x210,0xf00) + mpu_port - port # for MPU-401 UART (PnP setup - 0x300), -1 = disable + fm_port - FM port # for CS4236 chip (PnP setup - 0x388), -1 = disable + irq - IRQ # for CS4236 chip (5,7,9,11,12,15) + mpu_irq - IRQ # for MPU-401 UART (9,11,12,15) + dma1 - first DMA # for CS4236 chip (0,1,3) + dma2 - second DMA # for CS4236 chip (0,1,3), -1 = disable + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + Module supports up to 8 cards. This module does not support autoprobe + (if ISA PnP is not used) thus main port and control port must be + specified!!! Other ports are optional. + + The power-management is supported. + + Module snd-cs4281 + ----------------- + + Module for Cirrus Logic CS4281 soundchip. + + dual_codec - Secondary codec ID (0 = disable, default) + + Module supports up to 8 cards. + + The power-management is supported. + + Module snd-cs46xx + ----------------- + + Module for PCI sound cards based on CS4610/CS4612/CS4614/CS4615/CS4622/ + CS4624/CS4630/CS4280 PCI chips. + + external_amp - Force to enable external amplifer. + thinkpad - Force to enable Thinkpad's CLKRUN control. + mmap_valid - Support OSS mmap mode (default = 0). + + Module supports up to 8 cards and autoprobe. + Usually external amp and CLKRUN controls are detected automatically + from PCI sub vendor/device ids. If they don't work, give the options + above explicitly. + + The power-management is supported. + + Module snd-dt019x + ----------------- + + Module for Diamond Technologies DT-019X / Avance Logic ALS-007 (PnP + only) + + port - Port # (PnP setup) + mpu_port - Port # for MPU-401 (PnP setup) + fm_port - Port # for FM OPL-3 (PnP setup) + irq - IRQ # (PnP setup) + mpu_irq - IRQ # for MPU-401 (PnP setup) + dma8 - DMA # (PnP setup) + + Module supports up to 8 cards. This module is enabled only with + ISA PnP support. + + Module snd-dummy + ---------------- + + Module for the dummy sound card. This "card" doesn't do any output + or input, but you may use this module for any application which + requires a sound card (like RealPlayer). + + Module snd-emu10k1 + ------------------ + + Module for EMU10K1/EMU10k2 based PCI sound cards. + * Sound Blaster Live! + * Sound Blaster PCI 512 + * Emu APS (partially supported) + * Sound Blaster Audigy + + extin - bitmap of available external inputs for FX8010 (see bellow) + extout - bitmap of available external outputs for FX8010 (see bellow) + seq_ports - allocated sequencer ports (4 by default) + max_synth_voices - limit of voices used for wavetable (64 by default) + max_buffer_size - specifies the maximum size of wavetable/pcm buffers + given in MB unit. Default value is 128. + enable_ir - enable IR + + Module supports up to 8 cards and autoprobe. + + Input & Output configurations [extin/extout] + * Creative Card wo/Digital out [0x0003/0x1f03] + * Creative Card w/Digital out [0x0003/0x1f0f] + * Creative Card w/Digital CD in [0x000f/0x1f0f] + * Creative Card wo/Digital out + LiveDrive [0x3fc3/0x1fc3] + * Creative Card w/Digital out + LiveDrive [0x3fc3/0x1fcf] + * Creative Card w/Digital CD in + LiveDrive [0x3fcf/0x1fcf] + * Creative Card wo/Digital out + Digital I/O 2 [0x0fc3/0x1f0f] + * Creative Card w/Digital out + Digital I/O 2 [0x0fc3/0x1f0f] + * Creative Card w/Digital CD in + Digital I/O 2 [0x0fcf/0x1f0f] + * Creative Card 5.1/w Digital out + LiveDrive [0x3fc3/0x1fff] + * Creative Card 5.1 (c) 2003 [0x3fc3/0x7cff] + * Creative Card all ins and outs [0x3fff/0x7fff] + + Module snd-emu10k1x + ------------------- + + Module for Creative Emu10k1X (SB Live Dell OEM version) + + Module supports up to 8 cards. + + Module snd-ens1370 + ------------------ + + Module for Ensoniq AudioPCI ES1370 PCI sound cards. + * SoundBlaster PCI 64 + * SoundBlaster PCI 128 + + joystick - Enable joystick (default off) + + Module supports up to 8 cards and autoprobe. + + Module snd-ens1371 + ------------------ + + Module for Ensoniq AudioPCI ES1371 PCI sound cards. + * SoundBlaster PCI 64 + * SoundBlaster PCI 128 + * SoundBlaster Vibra PCI + + joystick_port - port # for joystick (0x200,0x208,0x210,0x218), + 0 = disable (default), 1 = auto-detect + + Module supports up to 8 cards and autoprobe. + + Module snd-es968 + ---------------- + + Module for sound cards based on ESS ES968 chip (PnP only). + + port - port # for ES968 (SB8) chip (PnP setup) + irq - IRQ # for ES968 (SB8) chip (PnP setup) + dma1 - DMA # for ES968 (SB8) chip (PnP setup) + + Module supports up to 8 cards, PnP and autoprobe. + + Module snd-es1688 + ----------------- + + Module for ESS AudioDrive ES-1688 and ES-688 sound cards. + + port - port # for ES-1688 chip (0x220,0x240,0x260) + mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) + irq - IRQ # for ES-1688 chip (5,7,9,10) + mpu_irq - IRQ # for MPU-401 port (5,7,9,10) + dma8 - DMA # for ES-1688 chip (0,1,3) + + Module supports up to 8 cards and autoprobe (without MPU-401 port). + + Module snd-es18xx + ----------------- + + Module for ESS AudioDrive ES-18xx sound cards. + + port - port # for ES-18xx chip (0x220,0x240,0x260) + mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) + fm_port - port # for FM (optional, not used) + irq - IRQ # for ES-18xx chip (5,7,9,10) + dma1 - first DMA # for ES-18xx chip (0,1,3) + dma2 - first DMA # for ES-18xx chip (0,1,3) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + Module supports up to 8 cards ISA PnP and autoprobe (without MPU-401 port + if native ISA PnP routines are not used). + When dma2 is equal with dma1, the driver works as half-duplex. + + The power-management is supported. + + Module snd-es1938 + ----------------- + + Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips. + + Module supports up to 8 cards and autoprobe. + + Module snd-es1968 + ----------------- + + Module for sound cards based on ESS Maestro-1/2/2E (ES1968/ES1978) chips. + + total_bufsize - total buffer size in kB (1-4096kB) + pcm_substreams_p - playback channels (1-8, default=2) + pcm_substreams_c - capture channels (1-8, default=0) + clock - clock (0 = auto-detection) + use_pm - support the power-management (0 = off, 1 = on, + 2 = auto (default)) + enable_mpu - enable MPU401 (0 = off, 1 = on, 2 = auto (default)) + joystick - enable joystick (default off) + + Module supports up to 8 cards and autoprobe. + + The power-management is supported. + + Module snd-fm801 + ---------------- + + Module for ForteMedia FM801 based PCI sound cards. + + tea575x_tuner - Enable TEA575x tuner + - 1 = MediaForte 256-PCS + - 2 = MediaForte 256-PCPR + - 3 = MediaForte 64-PCR + - High 16-bits are video (radio) device number + 1 + - example: 0x10002 (MediaForte 256-PCPR, device 1) + + Module supports up to 8 cards and autoprobe. + + Module snd-gusclassic + --------------------- + + Module for Gravis UltraSound Classic sound card. + + port - port # for GF1 chip (0x220,0x230,0x240,0x250,0x260) + irq - IRQ # for GF1 chip (3,5,9,11,12,15) + dma1 - DMA # for GF1 chip (1,3,5,6,7) + dma2 - DMA # for GF1 chip (1,3,5,6,7,-1=disable) + joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V) + voices - GF1 voices limit (14-32) + pcm_voices - reserved PCM voices + + Module supports up to 8 cards and autoprobe. + + Module snd-gusextreme + --------------------- + + Module for Gravis UltraSound Extreme (Synergy ViperMax) sound card. + + port - port # for ES-1688 chip (0x220,0x230,0x240,0x250,0x260) + gf1_port - port # for GF1 chip (0x210,0x220,0x230,0x240,0x250,0x260,0x270) + mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable + irq - IRQ # for ES-1688 chip (5,7,9,10) + gf1_irq - IRQ # for GF1 chip (3,5,9,11,12,15) + mpu_irq - IRQ # for MPU-401 port (5,7,9,10) + dma8 - DMA # for ES-1688 chip (0,1,3) + dma1 - DMA # for GF1 chip (1,3,5,6,7) + joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V) + voices - GF1 voices limit (14-32) + pcm_voices - reserved PCM voices + + Module supports up to 8 cards and autoprobe (without MPU-401 port). + + Module snd-gusmax + ----------------- + + Module for Gravis UltraSound MAX sound card. + + port - port # for GF1 chip (0x220,0x230,0x240,0x250,0x260) + irq - IRQ # for GF1 chip (3,5,9,11,12,15) + dma1 - DMA # for GF1 chip (1,3,5,6,7) + dma2 - DMA # for GF1 chip (1,3,5,6,7,-1=disable) + joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V) + voices - GF1 voices limit (14-32) + pcm_voices - reserved PCM voices + + Module supports up to 8 cards and autoprobe. + + Module snd-hda-intel + -------------------- + + Module for Intel HD Audio (ICH6, ICH6M, ICH7) + + model - force the model name + + Module supports up to 8 cards. + + Each codec may have a model table for different configurations. + If your machine isn't listed there, the default (usually minimal) + configuration is set up. You can pass "model=<name>" option to + specify a certain model in such a case. There are different + models depending on the codec chip. + + Model name Description + ---------- ----------- + ALC880 + 3stack 3-jack in back and a headphone out + 3stack-digout 3-jack in back, a HP out and a SPDIF out + 5stack 5-jack in back, 2-jack in front + 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out + w810 3-jack + + CMI9880 + minimal 3-jack in back + min_fp 3-jack in back, 2-jack in front + full 6-jack in back, 2-jack in front + full_dig 6-jack in back, 2-jack in front, SPDIF I/O + allout 5-jack in back, 2-jack in front, SPDIF out + + Module snd-hdsp + --------------- + + Module for RME Hammerfall DSP audio interface(s) + + Module supports up to 8 cards. + + Note: The firmware data can be automatically loaded via hotplug + when CONFIG_FW_LOADER is set. Otherwise, you need to load + the firmware via hdsploader utility included in alsa-tools + package. + The firmware data is found in alsa-firmware package. + + Note: snd-page-alloc module does the job which snd-hammerfall-mem + module did formerly. It will allocate the buffers in advance + when any HDSP cards are found. To make the buffer + allocation sure, load snd-page-alloc module in the early + stage of boot sequence. + + Module snd-ice1712 + ------------------ + + Module for Envy24 (ICE1712) based PCI sound cards. + * MidiMan M Audio Delta 1010 + * MidiMan M Audio Delta 1010LT + * MidiMan M Audio Delta DiO 2496 + * MidiMan M Audio Delta 66 + * MidiMan M Audio Delta 44 + * MidiMan M Audio Delta 410 + * MidiMan M Audio Audiophile 2496 + * TerraTec EWS 88MT + * TerraTec EWS 88D + * TerraTec EWX 24/96 + * TerraTec DMX 6Fire + * Hoontech SoundTrack DSP 24 + * Hoontech SoundTrack DSP 24 Value + * Hoontech SoundTrack DSP 24 Media 7.1 + * Digigram VX442 + + model - Use the given board model, one of the following: + delta1010, dio2496, delta66, delta44, audiophile, delta410, + delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d, + dmx6fire, dsp24, dsp24_value, dsp24_71, ez8 + omni - Omni I/O support for MidiMan M-Audio Delta44/66 + cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever) + in msec resolution, default value is 500 (0.5 sec) + + Module supports up to 8 cards and autoprobe. Note: The consumer part + is not used with all Envy24 based cards (for example in the MidiMan Delta + serie). + + Module snd-ice1724 + ------------------ + + Module for Envy24HT (VT/ICE1724) based PCI sound cards. + * MidiMan M Audio Revolution 7.1 + * AMP Ltd AUDIO2000 + * TerraTec Aureon Sky-5.1, Space-7.1 + + model - Use the given board model, one of the following: + revo71, amp2000, prodigy71, aureon51, aureon71, + k8x800 + + Module supports up to 8 cards and autoprobe. + + Module snd-intel8x0 + ------------------- + + Module for AC'97 motherboards from Intel and compatibles. + * Intel i810/810E, i815, i820, i830, i84x, MX440 + * SiS 7012 (SiS 735) + * NVidia NForce, NForce2 + * AMD AMD768, AMD8111 + * ALi m5455 + + ac97_clock - AC'97 codec clock base (0 = auto-detect) + ac97_quirk - AC'97 workaround for strange hardware + The following strings are accepted: + default = don't override the default setting + disable = disable the quirk + hp_only = use headphone control as master + swap_hp = swap headphone and master controls + swap_surround = swap master and surround controls + ad_sharing = for AD1985, turn on OMS bit and use headphone + alc_jack = for ALC65x, turn on the jack sense mode + inv_eapd = inverted EAPD implementation + mute_led = bind EAPD bit for turning on/off mute LED + For backward compatibility, the corresponding integer + value -1, 0, ... are accepted, too. + buggy_irq - Enable workaround for buggy interrupts on some + motherboards (default off) + + Module supports autoprobe and multiple bus-master chips (max 8). + + Note: the latest driver supports auto-detection of chip clock. + if you still encounter too fast playback, specify the clock + explicitly via the module option "ac97_clock=41194". + + Joystick/MIDI ports are not supported by this driver. If your + motherboard has these devices, use the ns558 or snd-mpu401 + modules, respectively. + + The ac97_quirk option is used to enable/override the workaround + for specific devices. Some hardware have swapped output pins + between Master and Headphone, or Surround. The driver provides + the auto-detection of known problematic devices, but some might + be unknown or wrongly detected. In such a case, pass the proper + value with this option. + + The power-management is supported. + + Module snd-intel8x0m + -------------------- + + Module for Intel ICH (i8x0) chipset MC97 modems. + + ac97_clock - AC'97 codec clock base (0 = auto-detect) + + This module supports up to 8 cards and autoprobe. + + Note: The default index value of this module is -2, i.e. the first + slot is excluded. + + Module snd-interwave + -------------------- + + Module for Gravis UltraSound PnP, Dynasonic 3-D/Pro, STB Sound Rage 32 + and other sound cards based on AMD InterWave (tm) chip. + + port - port # for InterWave chip (0x210,0x220,0x230,0x240,0x250,0x260) + irq - IRQ # for InterWave chip (3,5,9,11,12,15) + dma1 - DMA # for InterWave chip (0,1,3,5,6,7) + dma2 - DMA # for InterWave chip (0,1,3,5,6,7,-1=disable) + joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V) + midi - 1 = MIDI UART enable, 0 = MIDI UART disable (default) + pcm_voices - reserved PCM voices for the synthesizer (default 2) + effect - 1 = InterWave effects enable (default 0); + requires 8 voices + + Module supports up to 8 cards, autoprobe and ISA PnP. + + Module snd-interwave-stb + ------------------------ + + Module for UltraSound 32-Pro (sound card from STB used by Compaq) + and other sound cards based on AMD InterWave (tm) chip with TEA6330T + circuit for extended control of bass, treble and master volume. + + port - port # for InterWave chip (0x210,0x220,0x230,0x240,0x250,0x260) + port_tc - tone control (i2c bus) port # for TEA6330T chip (0x350,0x360,0x370,0x380) + irq - IRQ # for InterWave chip (3,5,9,11,12,15) + dma1 - DMA # for InterWave chip (0,1,3,5,6,7) + dma2 - DMA # for InterWave chip (0,1,3,5,6,7,-1=disable) + joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V) + midi - 1 = MIDI UART enable, 0 = MIDI UART disable (default) + pcm_voices - reserved PCM voices for the synthesizer (default 2) + effect - 1 = InterWave effects enable (default 0); + requires 8 voices + + Module supports up to 8 cards, autoprobe and ISA PnP. + + Module snd-korg1212 + ------------------- + + Module for Korg 1212 IO PCI card + + Module supports up to 8 cards. + + Module snd-maestro3 + ------------------- + + Module for Allegro/Maestro3 chips + + external_amp - enable external amp (enabled by default) + amp_gpio - GPIO pin number for external amp (0-15) or + -1 for default pin (8 for allegro, 1 for + others) + + Module supports autoprobe and multiple chips (max 8). + + Note: the binding of amplifier is dependent on hardware. + If there is no sound even though all channels are unmuted, try to + specify other gpio connection via amp_gpio option. + For example, a Panasonic notebook might need "amp_gpio=0x0d" + option. + + The power-management is supported. + + Module snd-mixart + ----------------- + + Module for Digigram miXart8 sound cards. + + Module supports multiple cards. + Note: One miXart8 board will be represented as 4 alsa cards. + See MIXART.txt for details. + + When the driver is compiled as a module and the hotplug firmware + is supported, the firmware data is loaded via hotplug automatically. + Install the necessary firmware files in alsa-firmware package. + When no hotplug fw loader is available, you need to load the + firmware via mixartloader utility in alsa-tools package. + + Module snd-mpu401 + ----------------- + + Module for MPU-401 UART devices. + + port - port number or -1 (disable) + irq - IRQ number or -1 (disable) + pnp - PnP detection - 0 = disable, 1 = enable (default) + + Module supports multiple devices (max 8) and PnP. + + Module snd-mtpav + ---------------- + + Module for MOTU MidiTimePiece AV multiport MIDI (on the parallel + port). + + port - I/O port # for MTPAV (0x378,0x278, default=0x378) + irq - IRQ # for MTPAV (7,5, default=7) + hwports - number of supported hardware ports, default=8. + + Module supports only 1 card. This module has no enable option. + + Module snd-nm256 + ---------------- + + Module for NeoMagic NM256AV/ZX chips + + playback_bufsize - max playback frame size in kB (4-128kB) + capture_bufsize - max capture frame size in kB (4-128kB) + force_ac97 - 0 or 1 (disabled by default) + buffer_top - specify buffer top address + use_cache - 0 or 1 (disabled by default) + vaio_hack - alias buffer_top=0x25a800 + reset_workaround - enable AC97 RESET workaround for some laptops + + Module supports autoprobe and multiple chips (max 8). + + The power-management is supported. + + Note: on some notebooks the buffer address cannot be detected + automatically, or causes hang-up during initialization. + In such a case, specify the buffer top address explicity via + buffer_top option. + For example, + Sony F250: buffer_top=0x25a800 + Sony F270: buffer_top=0x272800 + The driver supports only ac97 codec. It's possible to force + to initialize/use ac97 although it's not detected. In such a + case, use force_ac97=1 option - but *NO* guarantee whether it + works! + + Note: The NM256 chip can be linked internally with non-AC97 + codecs. This driver supports only the AC97 codec, and won't work + with machines with other (most likely CS423x or OPL3SAx) chips, + even though the device is detected in lspci. In such a case, try + other drivers, e.g. snd-cs4232 or snd-opl3sa2. Some has ISA-PnP + but some doesn't have ISA PnP. You'll need to speicfy isapnp=0 + and proper hardware parameters in the case without ISA PnP. + + Note: some laptops need a workaround for AC97 RESET. For the + known hardware like Dell Latitude LS and Sony PCG-F305, this + workaround is enabled automatically. For other laptops with a + hard freeze, you can try reset_workaround=1 option. + + Note: This driver is really crappy. It's a porting from the + OSS driver, which is a result of black-magic reverse engineering. + The detection of codec will fail if the driver is loaded *after* + X-server as described above. You might be able to force to load + the module, but it may result in hang-up. Hence, make sure that + you load this module *before* X if you encounter this kind of + problem. + + Module snd-opl3sa2 + ------------------ + + Module for Yamaha OPL3-SA2/SA3 sound cards. + + port - control port # for OPL3-SA chip (0x370) + sb_port - SB port # for OPL3-SA chip (0x220,0x240) + wss_port - WSS port # for OPL3-SA chip (0x530,0xe80,0xf40,0x604) + midi_port - port # for MPU-401 UART (0x300,0x330), -1 = disable + fm_port - FM port # for OPL3-SA chip (0x388), -1 = disable + irq - IRQ # for OPL3-SA chip (5,7,9,10) + dma1 - first DMA # for Yamaha OPL3-SA chip (0,1,3) + dma2 - second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + Module supports up to 8 cards and ISA PnP. This module does not support + autoprobe (if ISA PnP is not used) thus all ports must be specified!!! + + The power-management is supported. + + Module snd-opti92x-ad1848 + ------------------------- + + Module for sound cards based on OPTi 82c92x and Analog Devices AD1848 chips. + Module works with OAK Mozart cards as well. + + port - port # for WSS chip (0x530,0xe80,0xf40,0x604) + mpu_port - port # for MPU-401 UART (0x300,0x310,0x320,0x330) + fm_port - port # for OPL3 device (0x388) + irq - IRQ # for WSS chip (5,7,9,10,11) + mpu_irq - IRQ # for MPU-401 UART (5,7,9,10) + dma1 - first DMA # for WSS chip (0,1,3) + + This module supports only one card, autoprobe and PnP. + + Module snd-opti92x-cs4231 + ------------------------- + + Module for sound cards based on OPTi 82c92x and Crystal CS4231 chips. + + port - port # for WSS chip (0x530,0xe80,0xf40,0x604) + mpu_port - port # for MPU-401 UART (0x300,0x310,0x320,0x330) + fm_port - port # for OPL3 device (0x388) + irq - IRQ # for WSS chip (5,7,9,10,11) + mpu_irq - IRQ # for MPU-401 UART (5,7,9,10) + dma1 - first DMA # for WSS chip (0,1,3) + dma2 - second DMA # for WSS chip (0,1,3) + + This module supports only one card, autoprobe and PnP. + + Module snd-opti93x + ------------------ + + Module for sound cards based on OPTi 82c93x chips. + + port - port # for WSS chip (0x530,0xe80,0xf40,0x604) + mpu_port - port # for MPU-401 UART (0x300,0x310,0x320,0x330) + fm_port - port # for OPL3 device (0x388) + irq - IRQ # for WSS chip (5,7,9,10,11) + mpu_irq - IRQ # for MPU-401 UART (5,7,9,10) + dma1 - first DMA # for WSS chip (0,1,3) + dma2 - second DMA # for WSS chip (0,1,3) + + This module supports only one card, autoprobe and PnP. + + Module snd-powermac (on ppc only) + --------------------------------- + + Module for PowerMac, iMac and iBook on-board soundchips + + enable_beep - enable beep using PCM (enabled as default) + + Module supports autoprobe a chip. + + Note: the driver may have problems regarding endianess. + + The power-management is supported. + + Module snd-rme32 + ---------------- + + Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, + Prodif96 and Prodif Gold) sound cards. + + Module supports up to 8 cards. + + Module snd-rme96 + ---------------- + + Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards. + + Module supports up to 8 cards. + + Module snd-rme9652 + ------------------ + + Module for RME Digi9652 (Hammerfall, Hammerfall-Light) sound cards. + + precise_ptr - Enable precise pointer (doesn't work reliably). + (default = 0) + + Module supports up to 8 cards. + + Note: snd-page-alloc module does the job which snd-hammerfall-mem + module did formerly. It will allocate the buffers in advance + when any RME9652 cards are found. To make the buffer + allocation sure, load snd-page-alloc module in the early + stage of boot sequence. + + Module snd-sa11xx-uda1341 (on arm only) + --------------------------------------- + + Module for Philips UDA1341TS on Compaq iPAQ H3600 sound card. + + Module supports only one card. + Module has no enable and index options. + + Module snd-sb8 + -------------- + + Module for 8-bit SoundBlaster cards: SoundBlaster 1.0, + SoundBlaster 2.0, + SoundBlaster Pro + + port - port # for SB DSP chip (0x220,0x240,0x260) + irq - IRQ # for SB DSP chip (5,7,9,10) + dma8 - DMA # for SB DSP chip (1,3) + + Module supports up to 8 cards and autoprobe. + + Module snd-sb16 and snd-sbawe + ----------------------------- + + Module for 16-bit SoundBlaster cards: SoundBlaster 16 (PnP), + SoundBlaster AWE 32 (PnP), + SoundBlaster AWE 64 PnP + + port - port # for SB DSP 4.x chip (0x220,0x240,0x260) + mpu_port - port # for MPU-401 UART (0x300,0x330), -1 = disable + awe_port - base port # for EMU8000 synthesizer (0x620,0x640,0x660) + (snd-sbawe module only) + irq - IRQ # for SB DSP 4.x chip (5,7,9,10) + dma8 - 8-bit DMA # for SB DSP 4.x chip (0,1,3) + dma16 - 16-bit DMA # for SB DSP 4.x chip (5,6,7) + mic_agc - Mic Auto-Gain-Control - 0 = disable, 1 = enable (default) + csp - ASP/CSP chip support - 0 = disable (default), 1 = enable + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + Module supports up to 8 cards, autoprobe and ISA PnP. + + Note: To use Vibra16X cards in 16-bit half duplex mode, you must + disable 16bit DMA with dma16 = -1 module parameter. + Also, all Sound Blaster 16 type cards can operate in 16-bit + half duplex mode through 8-bit DMA channel by disabling their + 16-bit DMA channel. + + Module snd-sgalaxy + ------------------ + + Module for Aztech Sound Galaxy sound card. + + sbport - Port # for SB16 interface (0x220,0x240) + wssport - Port # for WSS interface (0x530,0xe80,0xf40,0x604) + irq - IRQ # (7,9,10,11) + dma1 - DMA # + + Module supports up to 8 cards. + + Module snd-sscape + ----------------- + + Module for ENSONIQ SoundScape PnP cards. + + port - Port # (PnP setup) + irq - IRQ # (PnP setup) + mpu_irq - MPU-401 IRQ # (PnP setup) + dma - DMA # (PnP setup) + + Module supports up to 8 cards. ISA PnP must be enabled. + You need sscape_ctl tool in alsa-tools package for loading + the microcode. + + Module snd-sun-amd7930 (on sparc only) + -------------------------------------- + + Module for AMD7930 sound chips found on Sparcs. + + Module supports up to 8 cards. + + Module snd-sun-cs4231 (on sparc only) + ------------------------------------- + + Module for CS4231 sound chips found on Sparcs. + + Module supports up to 8 cards. + + Module snd-wavefront + -------------------- + + Module for Turtle Beach Maui, Tropez and Tropez+ sound cards. + + cs4232_pcm_port - Port # for CS4232 PCM interface. + cs4232_pcm_irq - IRQ # for CS4232 PCM interface (5,7,9,11,12,15). + cs4232_mpu_port - Port # for CS4232 MPU-401 interface. + cs4232_mpu_irq - IRQ # for CS4232 MPU-401 interface (9,11,12,15). + use_cs4232_midi - Use CS4232 MPU-401 interface + (inaccessibly located inside your computer) + ics2115_port - Port # for ICS2115 + ics2115_irq - IRQ # for ICS2115 + fm_port - FM OPL-3 Port # + dma1 - DMA1 # for CS4232 PCM interface. + dma2 - DMA2 # for CS4232 PCM interface. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + Module supports up to 8 cards and ISA PnP. + + Module snd-sonicvibes + --------------------- + + Module for S3 SonicVibes PCI sound cards. + * PINE Schubert 32 PCI + + reverb - Reverb Enable - 1 = enable, 0 = disable (default) + - SoundCard must have onboard SRAM for this. + mge - Mic Gain Enable - 1 = enable, 0 = disable (default) + + Module supports up to 8 cards and autoprobe. + + Module snd-serial-u16550 + ------------------------ + + Module for UART16550A serial MIDI ports. + + port - port # for UART16550A chip + irq - IRQ # for UART16550A chip, -1 = poll mode + speed - speed in bauds (9600,19200,38400,57600,115200) + 38400 = default + base - base for divisor in bauds (57600,115200,230400,460800) + 115200 = default + outs - number of MIDI ports in a serial port (1-4) + 1 = default + adaptor - Type of adaptor. + 0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A, + 3 = MS-124W M/B, 4 = Generic + + Module supports up to 8 cards. This module does not support autoprobe + thus the main port must be specified!!! Other options are optional. + + Module snd-trident + ------------------ + + Module for Trident 4DWave DX/NX sound cards. + * Best Union Miss Melody 4DWave PCI + * HIS 4DWave PCI + * Warpspeed ONSpeed 4DWave PCI + * AzTech PCI 64-Q3D + * Addonics SV 750 + * CHIC True Sound 4Dwave + * Shark Predator4D-PCI + * Jaton SonicWave 4D + + pcm_channels - max channels (voices) reserved for PCM + wavetable_size - max wavetable size in kB (4-?kb) + + Module supports up to 8 cards and autoprobe. + + The power-management is supported. + + Module snd-usb-audio + -------------------- + + Module for USB audio and USB MIDI devices. + + vid - Vendor ID for the device (optional) + pid - Product ID for the device (optional) + + This module supports up to 8 cards, autoprobe and hotplugging. + + Module snd-usb-usx2y + -------------------- + + Module for Tascam USB US-122, US-224 and US-428 devices. + + This module supports up to 8 cards, autoprobe and hotplugging. + + Note: you need to load the firmware via usx2yloader utility included + in alsa-tools and alsa-firmware packages. + + Module snd-via82xx + ------------------ + + Module for AC'97 motherboards based on VIA 82C686A/686B, 8233, + 8233A, 8233C, 8235 (south) bridge. + + mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup + [VIA686A/686B only] + joystick - Enable joystick (default off) [VIA686A/686B only] + ac97_clock - AC'97 codec clock base (default 48000Hz) + dxs_support - support DXS channels, + 0 = auto (defalut), 1 = enable, 2 = disable, + 3 = 48k only, 4 = no VRA + [VIA8233/C,8235 only] + ac97_quirk - AC'97 workaround for strange hardware + See the description of intel8x0 module for details. + + Module supports autoprobe and multiple bus-master chips (max 8). + + Note: on some SMP motherboards like MSI 694D the interrupts might + not be generated properly. In such a case, please try to + set the SMP (or MPS) version on BIOS to 1.1 instead of + default value 1.4. Then the interrupt number will be + assigned under 15. You might also upgrade your BIOS. + + Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound) + channels as the first PCM. On these channels, up to 4 + streams can be played at the same time. + As default (dxs_support = 0), 48k fixed rate is chosen + except for the known devices since the output is often + noisy except for 48k on some mother boards due to the + bug of BIOS. + Please try once dxs_support=1 and if it works on other + sample rates (e.g. 44.1kHz of mp3 playback), please let us + know the PCI subsystem vendor/device id's (output of + "lspci -nv"). + If it doesn't work, try dxs_support=4. If it still doesn't + work and the default setting is ok, dxs_support=3 is the + right choice. If the default setting doesn't work at all, + try dxs_support=2 to disable the DXS channels. + In any cases, please let us know the result and the + subsystem vendor/device ids. + + Note: for the MPU401 on VIA823x, use snd-mpu401 driver + additonally. The mpu_port option is for VIA686 chips only. + + Module snd-via82xx-modem + ------------------------ + + Module for VIA82xx AC97 modem + + ac97_clock - AC'97 codec clock base (default 48000Hz) + + Module supports up to 8 cards. + + Note: The default index value of this module is -2, i.e. the first + slot is excluded. + + Module snd-virmidi + ------------------ + + Module for virtual rawmidi devices. + This module creates virtual rawmidi devices which communicate + to the corresponding ALSA sequencer ports. + + midi_devs - MIDI devices # (1-8, default=4) + + Module supports up to 8 cards. + + Module snd-vx222 + ---------------- + + Module for Digigram VX-Pocket VX222, V222 v2 and Mic cards. + + mic - Enable Microphone on V222 Mic (NYI) + ibl - Capture IBL size. (default = 0, minimum size) + + Module supports up to 8 cards. + + When the driver is compiled as a module and the hotplug firmware + is supported, the firmware data is loaded via hotplug automatically. + Install the necessary firmware files in alsa-firmware package. + When no hotplug fw loader is available, you need to load the + firmware via vxloader utility in alsa-tools package. To invoke + vxloader automatically, add the following to /etc/modprobe.conf + + install snd-vx222 /sbin/modprobe --first-time -i snd-vx222 && /usr/bin/vxloader + + (for 2.2/2.4 kernels, add "post-install /usr/bin/vxloader" to + /etc/modules.conf, instead.) + IBL size defines the interrupts period for PCM. The smaller size + gives smaller latency but leads to more CPU consumption, too. + The size is usually aligned to 126. As default (=0), the smallest + size is chosen. The possible IBL values can be found in + /proc/asound/cardX/vx-status proc file. + + Module snd-vxpocket + ------------------- + + Module for Digigram VX-Pocket VX2 PCMCIA card. + + ibl - Capture IBL size. (default = 0, minimum size) + + Module supports up to 8 cards. The module is compiled only when + PCMCIA is supported on kernel. + + To activate the driver via the card manager, you'll need to set + up /etc/pcmcia/vxpocket.conf. See the sound/pcmcia/vx/vxpocket.c. + + When the driver is compiled as a module and the hotplug firmware + is supported, the firmware data is loaded via hotplug automatically. + Install the necessary firmware files in alsa-firmware package. + When no hotplug fw loader is available, you need to load the + firmware via vxloader utility in alsa-tools package. + + About capture IBL, see the description of snd-vx222 module. + + Note: the driver is build only when CONFIG_ISA is set. + + Module snd-vxp440 + ----------------- + + Module for Digigram VX-Pocket 440 PCMCIA card. + + ibl - Capture IBL size. (default = 0, minimum size) + + Module supports up to 8 cards. The module is compiled only when + PCMCIA is supported on kernel. + + To activate the driver via the card manager, you'll need to set + up /etc/pcmcia/vxp440.conf. See the sound/pcmcia/vx/vxp440.c. + + When the driver is compiled as a module and the hotplug firmware + is supported, the firmware data is loaded via hotplug automatically. + Install the necessary firmware files in alsa-firmware package. + When no hotplug fw loader is available, you need to load the + firmware via vxloader utility in alsa-tools package. + + About capture IBL, see the description of snd-vx222 module. + + Note: the driver is build only when CONFIG_ISA is set. + + Module snd-ymfpci + ----------------- + + Module for Yamaha PCI chips (YMF72x, YMF74x & YMF75x). + + mpu_port - 0x300,0x330,0x332,0x334, 0 (disable) by default, + 1 (auto-detect for YMF744/754 only) + fm_port - 0x388,0x398,0x3a0,0x3a8, 0 (disable) by default + 1 (auto-detect for YMF744/754 only) + joystick_port - 0x201,0x202,0x204,0x205, 0 (disable) by default, + 1 (auto-detect) + rear_switch - enable shared rear/line-in switch (bool) + + Module supports autoprobe and multiple chips (max 8). + + The power-management is supported. + + Module snd-pdaudiocf + -------------------- + + Module for Sound Core PDAudioCF sound card. + + Note: the driver is build only when CONFIG_ISA is set. + + +Configuring Non-ISAPNP Cards +============================ + +When the kernel is configured with ISA-PnP support, the modules +supporting the isapnp cards will have module options "isapnp". +If this option is set, *only* the ISA-PnP devices will be probed. +For probing the non ISA-PnP cards, you have to pass "isapnp=0" option +together with the proper i/o and irq configuration. + +When the kernel is configured without ISA-PnP support, isapnp option +will be not built in. + + +Module Autoloading Support +========================== + +The ALSA drivers can be loaded automatically on demand by defining +module aliases. The string 'snd-card-%1' is requested for ALSA native +devices where %i is sound card number from zero to seven. + +To auto-load an ALSA driver for OSS services, define the string +'sound-slot-%i' where %i means the slot number for OSS, which +corresponds to the card index of ALSA. Usually, define this +as the the same card module. + +An example configuration for a single emu10k1 card is like below: +----- /etc/modprobe.conf +alias snd-card-0 snd-emu10k1 +alias sound-slot-0 snd-emu10k1 +----- /etc/modprobe.conf + +The available number of auto-loaded sound cards depends on the module +option "cards_limit" of snd module. As default it's set to 1. +To enable the auto-loading of multiple cards, specify the number of +sound cards in that option. + +When multiple cards are available, it'd better to specify the index +number for each card via module option, too, so that the order of +cards is kept consistent. + +An example configuration for two sound cards is like below: + +----- /etc/modprobe.conf +# ALSA portion +options snd cards_limit=2 +alias snd-card-0 snd-interwave +alias snd-card-1 snd-ens1371 +options snd-interwave index=0 +options snd-ens1371 index=1 +# OSS/Free portion +alias sound-slot-0 snd-interwave +alias sound-slot-1 snd-ens1371 +----- /etc/moprobe.conf + +In this example, the interwave card is always loaded as the first card +(index 0) and ens1371 as the second (index 1). + + +ALSA PCM devices to OSS devices mapping +======================================= + +/dev/snd/pcmC0D0[c|p] -> /dev/audio0 (/dev/audio) -> minor 4 +/dev/snd/pcmC0D0[c|p] -> /dev/dsp0 (/dev/dsp) -> minor 3 +/dev/snd/pcmC0D1[c|p] -> /dev/adsp0 (/dev/adsp) -> minor 12 +/dev/snd/pcmC1D0[c|p] -> /dev/audio1 -> minor 4+16 = 20 +/dev/snd/pcmC1D0[c|p] -> /dev/dsp1 -> minor 3+16 = 19 +/dev/snd/pcmC1D1[c|p] -> /dev/adsp1 -> minor 12+16 = 28 +/dev/snd/pcmC2D0[c|p] -> /dev/audio2 -> minor 4+32 = 36 +/dev/snd/pcmC2D0[c|p] -> /dev/dsp2 -> minor 3+32 = 39 +/dev/snd/pcmC2D1[c|p] -> /dev/adsp2 -> minor 12+32 = 44 + +The first number from /dev/snd/pcmC{X}D{Y}[c|p] expression means +sound card number and second means device number. The ALSA devices +have either 'c' or 'p' suffix indicating the direction, capture and +playback, respectively. + +Please note that the device mapping above may be varied via the module +options of snd-pcm-oss module. + + +DEVFS support +============= + +The ALSA driver fully supports the devfs extension. +You should add lines below to your devfsd.conf file: + +LOOKUP snd MODLOAD ACTION snd +REGISTER ^sound/.* PERMISSIONS root.audio 660 +REGISTER ^snd/.* PERMISSIONS root.audio 660 + +Warning: These lines assume that you have the audio group in your system. + Otherwise replace audio word with another group name (root for + example). + + +Proc interfaces (/proc/asound) +============================== + +/proc/asound/card#/pcm#[cp]/oss +------------------------------- + String "erase" - erase all additional informations about OSS applications + String "<app_name> <fragments> <fragment_size> [<options>]" + + <app_name> - name of application with (higher priority) or without path + <fragments> - number of fragments or zero if auto + <fragment_size> - size of fragment in bytes or zero if auto + <options> - optional parameters + - disable the application tries to open a pcm device for + this channel but does not want to use it. + (Cause a bug or mmap needs) + It's good for Quake etc... + - direct don't use plugins + - block force block mode (rvplayer) + - non-block force non-block mode + - whole-frag write only whole fragments (optimization affecting + playback only) + - no-silence do not fill silence ahead to avoid clicks + + Example: echo "x11amp 128 16384" > /proc/asound/card0/pcm0p/oss + echo "squake 0 0 disable" > /proc/asound/card0/pcm0c/oss + echo "rvplayer 0 0 block" > /proc/asound/card0/pcm0p/oss + + +Links +===== + + ALSA project homepage + http://www.alsa-project.org + diff --git a/Documentation/sound/alsa/Audigy-mixer.txt b/Documentation/sound/alsa/Audigy-mixer.txt new file mode 100644 index 000000000000..5132fd95e074 --- /dev/null +++ b/Documentation/sound/alsa/Audigy-mixer.txt @@ -0,0 +1,345 @@ + + Sound Blaster Audigy mixer / default DSP code + =========================================== + +This is based on SB-Live-mixer.txt. + +The EMU10K2 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 +EMU10K2 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) 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 EMU10K2 chip has an effect bus containing 64 accumulators. + Each of the synthesizer voices can feed its output to these accumulators + and the DSP microcontroller can operate with the resulting sum. + +name='PCM Front Playback Volume',index=0 + +This control is used to attenuate samples for left and right front PCM FX-bus +accumulators. ALSA uses accumulators 8 and 9 for left and right front PCM +samples for 5.1 playback. The result samples are forwarded to the front DAC PCM +slots of the Philips DAC. + +name='PCM Surround Playback Volume',index=0 + +This control is used to attenuate samples for left and right surround PCM FX-bus +accumulators. ALSA uses accumulators 2 and 3 for left and right surround PCM +samples for 5.1 playback. The result samples are forwarded to the surround DAC PCM +slots of the Philips DAC. + +name='PCM Center Playback Volume',index=0 + +This control is used to attenuate samples for center PCM FX-bus accumulator. +ALSA uses accumulator 6 for center PCM sample for 5.1 playback. The result sample +is forwarded to the center DAC PCM slot of the Philips DAC. + +name='PCM LFE Playback Volume',index=0 + +This control is used to attenuate sample for LFE PCM FX-bus accumulator. +ALSA uses accumulator 7 for LFE PCM sample for 5.1 playback. The result sample +is forwarded to the LFE DAC PCM slot of the Philips DAC. + +name='PCM 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 for +stereo playback. The result samples are forwarded to the front DAC PCM slots +of the Philips DAC. + +name='PCM Capture Volume',index=0 + +This control is 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 + +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='Mic Playback Volume',index=0 + +This control is used to attenuate samples for left and right Mic input. +For Mic input is used AC97 codec. The result samples are forwarded to +the front DAC PCM slots of the Philips DAC. Samples are forwarded to Mic +capture FIFO (device 1 - 16bit/8KHz mono) too without volume control. + +name='Mic Capture Volume',index=0 + +This control is used to attenuate samples for left and right Mic input. +The result is forwarded to the ADC capture FIFO (thus to the standard capture +PCM device). + +name='Audigy CD 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 Philips DAC. + +name='Audigy CD 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='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 Philips DAC. + +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='Line2 Playback Volume',index=0 + +This control is used to attenuate samples from left and right I2S ADC +inputs (on the AudigyDrive). The result samples are forwarded to the front +DAC PCM slots of the Philips DAC. + +name='Line2 Capture Volume',index=1 + +This control is used to attenuate samples from left and right I2S ADC +inputs (on the AudigyDrive). The result samples are forwarded to the ADC +capture FIFO (thus to the standard capture PCM device). + +name='Analog Mix Playback Volume',index=0 + +This control is used to attenuate samples from left and right I2S ADC +inputs from Philips ADC. The result samples are forwarded to the front +DAC PCM slots of the Philips DAC. This contains mix from analog sources +like CD, Line In, Aux, .... + +name='Analog Mix Capture Volume',index=1 + +This control is used to attenuate samples from left and right I2S ADC +inputs Philips ADC. The result samples are forwarded to the ADC +capture FIFO (thus to the standard capture PCM device). + +name='Aux2 Playback Volume',index=0 + +This control is used to attenuate samples from left and right I2S ADC +inputs (on the AudigyDrive). The result samples are forwarded to the front +DAC PCM slots of the Philips DAC. + +name='Aux2 Capture Volume',index=1 + +This control is used to attenuate samples from left and right I2S ADC +inputs (on the AudigyDrive). The result samples are forwarded to the ADC +capture FIFO (thus to the standard capture PCM device). + +name='Front Playback Volume',index=0 + +All stereo signals are mixed together and mirrored to surround, center and LFE. +This control is used to attenuate samples for left and right front speakers of +this mix. + +name='Surround Playback Volume',index=0 + +All stereo signals are mixed together and mirrored to surround, center and LFE. +This control is used to attenuate samples for left and right surround speakers of +this mix. + +name='Center Playback Volume',index=0 + +All stereo signals are mixed together and mirrored to surround, center and LFE. +This control is used to attenuate sample for center speaker of this mix. + +name='LFE Playback Volume',index=0 + +All stereo signals are mixed together and mirrored to surround, center and LFE. +This control is used to attenuate sample for LFE speaker of this mix. + +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='Master Playback Volume',index=0 + +This control is used to attenuate samples for front, surround, center and +LFE outputs. + +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. + + +2) 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 24 +values with this mapping: + + 0 - mono, A destination (FX-bus 0-63), default 0 + 1 - mono, B destination (FX-bus 0-63), default 1 + 2 - mono, C destination (FX-bus 0-63), default 2 + 3 - mono, D destination (FX-bus 0-63), default 3 + 4 - mono, E destination (FX-bus 0-63), default 0 + 5 - mono, F destination (FX-bus 0-63), default 0 + 6 - mono, G destination (FX-bus 0-63), default 0 + 7 - mono, H destination (FX-bus 0-63), default 0 + 8 - left, A destination (FX-bus 0-63), default 0 + 9 - left, B destination (FX-bus 0-63), default 1 + 10 - left, C destination (FX-bus 0-63), default 2 + 11 - left, D destination (FX-bus 0-63), default 3 + 12 - left, E destination (FX-bus 0-63), default 0 + 13 - left, F destination (FX-bus 0-63), default 0 + 14 - left, G destination (FX-bus 0-63), default 0 + 15 - left, H destination (FX-bus 0-63), default 0 + 16 - right, A destination (FX-bus 0-63), default 0 + 17 - right, B destination (FX-bus 0-63), default 1 + 18 - right, C destination (FX-bus 0-63), default 2 + 19 - right, D destination (FX-bus 0-63), default 3 + 20 - right, E destination (FX-bus 0-63), default 0 + 21 - right, F destination (FX-bus 0-63), default 0 + 22 - right, G destination (FX-bus 0-63), default 0 + 23 - right, H destination (FX-bus 0-63), default 0 + +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 - mono, E destination attn, default 0 (mute) + 5 - mono, F destination attn, default 0 (mute) + 6 - mono, G destination attn, default 0 (mute) + 7 - mono, H destination attn, default 0 (mute) + 8 - left, A destination attn, default 255 (no attenuation) + 9 - left, B destination attn, default 0 (mute) + 10 - left, C destination attn, default 0 (mute) + 11 - left, D destination attn, default 0 (mute) + 12 - left, E destination attn, default 0 (mute) + 13 - left, F destination attn, default 0 (mute) + 14 - left, G destination attn, default 0 (mute) + 15 - left, H destination attn, default 0 (mute) + 16 - right, A destination attn, default 0 (mute) + 17 - right, B destination attn, default 255 (no attenuation) + 18 - right, C destination attn, default 0 (mute) + 19 - right, D destination attn, default 0 (mute) + 20 - right, E destination attn, default 0 (mute) + 21 - right, F destination attn, default 0 (mute) + 22 - right, G destination attn, default 0 (mute) + 23 - right, H 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/Bt87x.txt b/Documentation/sound/alsa/Bt87x.txt new file mode 100644 index 000000000000..11edb2fd2a5a --- /dev/null +++ b/Documentation/sound/alsa/Bt87x.txt @@ -0,0 +1,78 @@ +Intro +===== + +You might have noticed that the bt878 grabber cards have actually +_two_ PCI functions: + +$ lspci +[ ... ] +00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02) +00:0a.1 Multimedia controller: Brooktree Corporation Bt878 (rev 02) +[ ... ] + +The first does video, it is backward compatible to the bt848. The second +does audio. snd-bt87x is a driver for the second function. It's a sound +driver which can be used for recording sound (and _only_ recording, no +playback). As most TV cards come with a short cable which can be plugged +into your sound card's line-in you probably don't need this driver if all +you want to do is just watching TV... + +Some cards do not bother to connect anything to the audio input pins of +the chip, and some other cards use the audio function to transport MPEG +video data, so it's quite possible that audio recording may not work +with your card. + + +Driver Status +============= + +The driver is now stable. However, it doesn't know about many TV cards, +and it refuses to load for cards it doesn't know. + +If the driver complains ("Unknown TV card found, the audio driver will +not load"), you can specify the load_all=1 option to force the driver to +try to use the audio capture function of your card. If the frequency of +recorded data is not right, try to specify the digital_rate option with +other values than the default 32000 (often it's 44100 or 64000). + +If you have an unknown card, please mail the ID and board name to +<alsa-devel@lists.sf.net>, regardless of whether audio capture works or +not, so that future versions of this driver know about your card. + + +Audio modes +=========== + +The chip knows two different modes (digital/analog). snd-bt87x +registers two PCM devices, one for each mode. They cannot be used at +the same time. + + +Digital audio mode +================== + +The first device (hw:X,0) gives you 16 bit stereo sound. The sample +rate depends on the external source which feeds the Bt87x with digital +sound via I2S interface. + + +Analog audio mode (A/D) +======================= + +The second device (hw:X,1) gives you 8 or 16 bit mono sound. Supported +sample rates are between 119466 and 448000 Hz (yes, these numbers are +that high). If you've set the CONFIG_SND_BT87X_OVERCLOCK option, the +maximum sample rate is 1792000 Hz, but audio data becomes unusable +beyond 896000 Hz on my card. + +The chip has three analog inputs. Consequently you'll get a mixer +device to control these. + + +Have fun, + + Clemens + + +Written by Clemens Ladisch <clemens@ladisch.de> +big parts copied from btaudio.txt by Gerd Knorr <kraxel@bytesex.org> diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt new file mode 100644 index 000000000000..4a7df771b806 --- /dev/null +++ b/Documentation/sound/alsa/CMIPCI.txt @@ -0,0 +1,242 @@ + 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 seconde 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 second DAC accepts up to 6 (or +4) channels. While the dual DAC supports two different rates or +formats, the 4/6-ch playback supports only the same condition for all +channels. Since the multi-channel playback mode uses both DACs, you +cannot operate with full-duplex. + +The 4.0 and 5.1 modes are defined as the pcm "surround40" and "surround51" +in alsa-lib. For example, you can play a WAV file with 6 channels like + + % aplay -Dsurround51 sixchannels.wav + +For programmin the 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 are some control switchs affecting to the speaker connections: + +"Line-In As Rear" - As mentioned above, the line-in jack is used + for the rear (3th and 4th channels) output. +"Line-In As Bass" - The line-in jack is used for the bass (5th + and 6th channels) output. +"Mic As Center/LFE" - The mic jack is used for the bass output. + If this switch is on, you cannot use a microphone as a capture + source, of course. + + +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 + +24bit format is also supported experimentally. + +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). + +"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. + +On the model 033, AC3 is implemented by the software conversion in +the alsa-lib. If you need to bypass the software conversion of IEC958 +subframes, pass the "soft_ac3=0" module option. This doesn't matter +on the newer models. + + +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 "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 "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/ControlNames.txt b/Documentation/sound/alsa/ControlNames.txt new file mode 100644 index 000000000000..5b18298e9495 --- /dev/null +++ b/Documentation/sound/alsa/ControlNames.txt @@ -0,0 +1,84 @@ +This document describes standard names of mixer controls. + +Syntax: SOURCE [DIRECTION] FUNCTION + +DIRECTION: + <nothing> (both directions) + Playback + Capture + Bypass Playback + Bypass Capture + +FUNCTION: + Switch (on/off switch) + Volume + Route (route control, hardware specific) + +SOURCE: + Master + Master Mono + Hardware Master + Headphone + PC Speaker + Phone + Phone Input + Phone Output + Synth + FM + Mic + Line + CD + Video + Zoom Video + Aux + PCM + PCM Front + PCM Rear + PCM Pan + Loopback + Analog Loopback (D/A -> A/D loopback) + Digital Loopback (playback -> capture loopback - without analog path) + Mono + Mono Output + Multi + ADC + Wave + Music + I2S + IEC958 + +Exceptions: + [Digital] Capture Source + [Digital] Capture Switch (aka input gain switch) + [Digital] Capture Volume (aka input gain volume) + [Digital] Playback Switch (aka output gain switch) + [Digital] Playback Volume (aka output gain volume) + Tone Control - Switch + Tone Control - Bass + Tone Control - Treble + 3D Control - Switch + 3D Control - Center + 3D Control - Depth + 3D Control - Wide + 3D Control - Space + 3D Control - Level + Mic Boost [(?dB)] + +PCM interface: + + Sample Clock Source { "Word", "Internal", "AutoSync" } + Clock Sync Status { "Lock", "Sync", "No Lock" } + External Rate /* external capture rate */ + Capture Rate /* capture rate taken from external source */ + +IEC958 (S/PDIF) interface: + + IEC958 [...] [Playback|Capture] Switch /* turn on/off the IEC958 interface */ + IEC958 [...] [Playback|Capture] Volume /* digital volume control */ + IEC958 [...] [Playback|Capture] Default /* default or global value - read/write */ + IEC958 [...] [Playback|Capture] Mask /* consumer and professional mask */ + IEC958 [...] [Playback|Capture] Con Mask /* consumer mask */ + IEC958 [...] [Playback|Capture] Pro Mask /* professional mask */ + IEC958 [...] [Playback|Capture] PCM Stream /* the settings assigned to a PCM stream */ + IEC958 Q-subcode [Playback|Capture] Default /* Q-subcode bits */ + IEC958 Preamble [Playback|Capture] Default /* burst preamble words (4*16bits) */ diff --git a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl new file mode 100644 index 000000000000..1f3ae3e32d69 --- /dev/null +++ b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl @@ -0,0 +1,100 @@ +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> + +<book> +<?dbhtml filename="index.html"> + +<!-- ****************************************************** --> +<!-- Header --> +<!-- ****************************************************** --> + <bookinfo> + <title>The ALSA Driver API</title> + + <legalnotice> + <para> + This document is free; 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. + </para> + + <para> + This document is distributed in the hope that it will be useful, + but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the + implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE</emphasis>. See the GNU General Public License + for more details. + </para> + + <para> + 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 + </para> + </legalnotice> + + </bookinfo> + + <chapter><title>Management of Cards and Devices</title> + <sect1><title>Card Managment</title> +!Esound/core/init.c + </sect1> + <sect1><title>Device Components</title> +!Esound/core/device.c + </sect1> + <sect1><title>KMOD and Device File Entries</title> +!Esound/core/sound.c + </sect1> + <sect1><title>Memory Management Helpers</title> +!Esound/core/memory.c +!Esound/core/memalloc.c + </sect1> + </chapter> + <chapter><title>PCM API</title> + <sect1><title>PCM Core</title> +!Esound/core/pcm.c +!Esound/core/pcm_lib.c +!Esound/core/pcm_native.c + </sect1> + <sect1><title>PCM Format Helpers</title> +!Esound/core/pcm_misc.c + </sect1> + <sect1><title>PCM Memory Managment</title> +!Esound/core/pcm_memory.c + </sect1> + </chapter> + <chapter><title>Control/Mixer API</title> + <sect1><title>General Control Interface</title> +!Esound/core/control.c + </sect1> + <sect1><title>AC97 Codec API</title> +!Esound/pci/ac97/ac97_codec.c +!Esound/pci/ac97/ac97_pcm.c + </sect1> + </chapter> + <chapter><title>MIDI API</title> + <sect1><title>Raw MIDI API</title> +!Esound/core/rawmidi.c + </sect1> + <sect1><title>MPU401-UART API</title> +!Esound/drivers/mpu401/mpu401_uart.c + </sect1> + </chapter> + <chapter><title>Proc Info API</title> + <sect1><title>Proc Info Interface</title> +!Esound/core/info.c + </sect1> + </chapter> + <chapter><title>Miscellaneous Functions</title> + <sect1><title>Hardware-Dependent Devices API</title> +!Esound/core/hwdep.c + </sect1> + <sect1><title>ISA DMA Helpers</title> +!Esound/core/isadma.c + </sect1> + <sect1><title>Other Helper Macros</title> +!Iinclude/sound/core.h + </sect1> + </chapter> + +</book> diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl new file mode 100644 index 000000000000..e789475304b6 --- /dev/null +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -0,0 +1,6045 @@ +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> + +<book> +<?dbhtml filename="index.html"> + +<!-- ****************************************************** --> +<!-- Header --> +<!-- ****************************************************** --> + <bookinfo> + <title>Writing an ALSA Driver</title> + <author> + <firstname>Takashi</firstname> + <surname>Iwai</surname> + <affiliation> + <address> + <email>tiwai@suse.de</email> + </address> + </affiliation> + </author> + + <date>March 6, 2005</date> + <edition>0.3.4</edition> + + <abstract> + <para> + This document describes how to write an ALSA (Advanced Linux + Sound Architecture) driver. + </para> + </abstract> + + <legalnotice> + <para> + Copyright (c) 2002-2004 Takashi Iwai <email>tiwai@suse.de</email> + </para> + + <para> + This document is free; 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. + </para> + + <para> + This document is distributed in the hope that it will be useful, + but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the + implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE</emphasis>. See the GNU General Public License + for more details. + </para> + + <para> + 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 + </para> + </legalnotice> + + </bookinfo> + +<!-- ****************************************************** --> +<!-- Preface --> +<!-- ****************************************************** --> + <preface id="preface"> + <title>Preface</title> + <para> + This document describes how to write an + <ulink url="http://www.alsa-project.org/"><citetitle> + ALSA (Advanced Linux Sound Architecture)</citetitle></ulink> + driver. The document focuses mainly on the PCI soundcard. + In the case of other device types, the API might + be different, too. However, at least the ALSA kernel API is + consistent, and therefore it would be still a bit help for + writing them. + </para> + + <para> + The target of this document is ones who already have enough + skill of C language and have the basic knowledge of linux + kernel programming. This document doesn't explain the general + topics of linux kernel codes and doesn't cover the detail of + implementation of each low-level driver. It describes only how is + the standard way to write a PCI sound driver on ALSA. + </para> + + <para> + If you are already familiar with the older ALSA ver.0.5.x, you + can check the drivers such as <filename>es1938.c</filename> or + <filename>maestro3.c</filename> which have also almost the same + code-base in the ALSA 0.5.x tree, so you can compare the differences. + </para> + + <para> + This document is still a draft version. Any feedbacks and + corrections, please!! + </para> + </preface> + + +<!-- ****************************************************** --> +<!-- File Tree Structure --> +<!-- ****************************************************** --> + <chapter id="file-tree"> + <title>File Tree Structure</title> + + <section id="file-tree-general"> + <title>General</title> + <para> + The ALSA drivers are provided in the two ways. + </para> + + <para> + One is the trees provided as a tarball or via cvs from the + ALSA's ftp site, and another is the 2.6 (or later) Linux kernel + tree. To synchronize both, the ALSA driver tree is split into + two different trees: alsa-kernel and alsa-driver. The former + contains purely the source codes for the Linux 2.6 (or later) + tree. This tree is designed only for compilation on 2.6 or + later environment. The latter, alsa-driver, contains many subtle + files for compiling the ALSA driver on the outside of Linux + kernel like configure script, the wrapper functions for older, + 2.2 and 2.4 kernels, to adapt the latest kernel API, + and additional drivers which are still in development or in + tests. The drivers in alsa-driver tree will be moved to + alsa-kernel (eventually 2.6 kernel tree) once when they are + finished and confirmed to work fine. + </para> + + <para> + The file tree structure of ALSA driver is depicted below. Both + alsa-kernel and alsa-driver have almost the same file + structure, except for <quote>core</quote> directory. It's + named as <quote>acore</quote> in alsa-driver tree. + + <example> + <title>ALSA File Tree Structure</title> + <literallayout> + sound + /core + /oss + /seq + /oss + /instr + /ioctl32 + /include + /drivers + /mpu401 + /opl3 + /i2c + /l3 + /synth + /emux + /pci + /(cards) + /isa + /(cards) + /arm + /ppc + /sparc + /usb + /pcmcia /(cards) + /oss + </literallayout> + </example> + </para> + </section> + + <section id="file-tree-core-directory"> + <title>core directory</title> + <para> + This directory contains the middle layer, that is, the heart + of ALSA drivers. In this directory, the native ALSA modules are + stored. The sub-directories contain different modules and are + dependent upon the kernel config. + </para> + + <section id="file-tree-core-directory-oss"> + <title>core/oss</title> + + <para> + The codes for PCM and mixer OSS emulation modules are stored + in this directory. The rawmidi OSS emulation is included in + the ALSA rawmidi code since it's quite small. The sequencer + code is stored in core/seq/oss directory (see + <link linkend="file-tree-core-directory-seq-oss"><citetitle> + below</citetitle></link>). + </para> + </section> + + <section id="file-tree-core-directory-ioctl32"> + <title>core/ioctl32</title> + + <para> + This directory contains the 32bit-ioctl wrappers for 64bit + architectures such like x86-64, ppc64 and sparc64. For 32bit + and alpha architectures, these are not compiled. + </para> + </section> + + <section id="file-tree-core-directory-seq"> + <title>core/seq</title> + <para> + This and its sub-directories are for the ALSA + sequencer. This directory contains the sequencer core and + primary sequencer modules such like snd-seq-midi, + snd-seq-virmidi, etc. They are compiled only when + <constant>CONFIG_SND_SEQUENCER</constant> is set in the kernel + config. + </para> + </section> + + <section id="file-tree-core-directory-seq-oss"> + <title>core/seq/oss</title> + <para> + This contains the OSS sequencer emulation codes. + </para> + </section> + + <section id="file-tree-core-directory-deq-instr"> + <title>core/seq/instr</title> + <para> + This directory contains the modules for the sequencer + instrument layer. + </para> + </section> + </section> + + <section id="file-tree-include-directory"> + <title>include directory</title> + <para> + This is the place for the public header files of ALSA drivers, + which are to be exported to the user-space, or included by + several files at different directories. Basically, the private + header files should not be placed in this directory, but you may + still find files there, due to historical reason :) + </para> + </section> + + <section id="file-tree-drivers-directory"> + <title>drivers directory</title> + <para> + This directory contains the codes shared among different drivers + on the different architectures. They are hence supposed not to be + architecture-specific. + For example, the dummy pcm driver and the serial MIDI + driver are found in this directory. In the sub-directories, + there are the codes for components which are independent from + bus and cpu architectures. + </para> + + <section id="file-tree-drivers-directory-mpu401"> + <title>drivers/mpu401</title> + <para> + The MPU401 and MPU401-UART modules are stored here. + </para> + </section> + + <section id="file-tree-drivers-directory-opl3"> + <title>drivers/opl3 and opl4</title> + <para> + The OPL3 and OPL4 FM-synth stuff is found here. + </para> + </section> + </section> + + <section id="file-tree-i2c-directory"> + <title>i2c directory</title> + <para> + This contains the ALSA i2c components. + </para> + + <para> + Although there is a standard i2c layer on Linux, ALSA has its + own i2c codes for some cards, because the soundcard needs only a + simple operation and the standard i2c API is too complicated for + such a purpose. + </para> + + <section id="file-tree-i2c-directory-l3"> + <title>i2c/l3</title> + <para> + This is a sub-directory for ARM L3 i2c. + </para> + </section> + </section> + + <section id="file-tree-synth-directory"> + <title>synth directory</title> + <para> + This contains the synth middle-level modules. + </para> + + <para> + So far, there is only Emu8000/Emu10k1 synth driver under + synth/emux sub-directory. + </para> + </section> + + <section id="file-tree-pci-directory"> + <title>pci directory</title> + <para> + This and its sub-directories hold the top-level card modules + for PCI soundcards and the codes specific to the PCI BUS. + </para> + + <para> + The drivers compiled from a single file is stored directly on + pci directory, while the drivers with several source files are + stored on its own sub-directory (e.g. emu10k1, ice1712). + </para> + </section> + + <section id="file-tree-isa-directory"> + <title>isa directory</title> + <para> + This and its sub-directories hold the top-level card modules + for ISA soundcards. + </para> + </section> + + <section id="file-tree-arm-ppc-sparc-directories"> + <title>arm, ppc, and sparc directories</title> + <para> + These are for the top-level card modules which are + specific to each given architecture. + </para> + </section> + + <section id="file-tree-usb-directory"> + <title>usb directory</title> + <para> + This contains the USB-audio driver. On the latest version, the + USB MIDI driver is integrated together with usb-audio driver. + </para> + </section> + + <section id="file-tree-pcmcia-directory"> + <title>pcmcia directory</title> + <para> + The PCMCIA, especially PCCard drivers will go here. CardBus + drivers will be on pci directory, because its API is identical + with the standard PCI cards. + </para> + </section> + + <section id="file-tree-oss-directory"> + <title>oss directory</title> + <para> + The OSS/Lite source files are stored here on Linux 2.6 (or + later) tree. (In the ALSA driver tarball, it's empty, of course :) + </para> + </section> + </chapter> + + +<!-- ****************************************************** --> +<!-- Basic Flow for PCI Drivers --> +<!-- ****************************************************** --> + <chapter id="basic-flow"> + <title>Basic Flow for PCI Drivers</title> + + <section id="basic-flow-outline"> + <title>Outline</title> + <para> + The minimum flow of PCI soundcard is like the following: + + <itemizedlist> + <listitem><para>define the PCI ID table (see the section + <link linkend="pci-resource-entries"><citetitle>PCI Entries + </citetitle></link>).</para></listitem> + <listitem><para>create <function>probe()</function> callback.</para></listitem> + <listitem><para>create <function>remove()</function> callback.</para></listitem> + <listitem><para>create pci_driver table which contains the three pointers above.</para></listitem> + <listitem><para>create <function>init()</function> function just calling <function>pci_module_init()</function> to register the pci_driver table defined above.</para></listitem> + <listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem> + </itemizedlist> + </para> + </section> + + <section id="basic-flow-example"> + <title>Full Code Example</title> + <para> + The code example is shown below. Some parts are kept + unimplemented at this moment but will be filled in the + succeeding sections. The numbers in comment lines of + <function>snd_mychip_probe()</function> function are the + markers. + + <example> + <title>Basic Flow for PCI Drivers Example</title> + <programlisting> +<![CDATA[ + #include <sound/driver.h> + #include <linux/init.h> + #include <linux/pci.h> + #include <linux/slab.h> + #include <sound/core.h> + #include <sound/initval.h> + + /* module parameters (see "Module Parameters") */ + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; + static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; + static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + + /* definition of the chip-specific record */ + typedef struct snd_mychip mychip_t; + struct snd_mychip { + snd_card_t *card; + // rest of implementation will be in the section + // "PCI Resource Managements" + }; + + /* chip-specific destructor + * (see "PCI Resource Managements") + */ + static int snd_mychip_free(mychip_t *chip) + { + .... // will be implemented later... + } + + /* component-destructor + * (see "Management of Cards and Components") + */ + static int snd_mychip_dev_free(snd_device_t *device) + { + mychip_t *chip = device->device_data; + return snd_mychip_free(chip); + } + + /* chip-specific constructor + * (see "Management of Cards and Components") + */ + static int __devinit snd_mychip_create(snd_card_t *card, + struct pci_dev *pci, + mychip_t **rchip) + { + mychip_t *chip; + int err; + static snd_device_ops_t ops = { + .dev_free = snd_mychip_dev_free, + }; + + *rchip = NULL; + + // check PCI availability here + // (see "PCI Resource Managements") + .... + + /* allocate a chip-specific data with zero filled */ + chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + + chip->card = card; + + // rest of initialization here; will be implemented + // later, see "PCI Resource Managements" + .... + + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, + chip, &ops)) < 0) { + snd_mychip_free(chip); + return err; + } + + snd_card_set_dev(card, &pci->dev); + + *rchip = chip; + return 0; + } + + /* constructor -- see "Constructor" sub-section */ + static int __devinit snd_mychip_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) + { + static int dev; + snd_card_t *card; + mychip_t *chip; + int err; + + /* (1) */ + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } + + /* (2) */ + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + /* (3) */ + if ((err = snd_mychip_create(card, pci, &chip)) < 0) { + snd_card_free(card); + return err; + } + + /* (4) */ + strcpy(card->driver, "My Chip"); + strcpy(card->shortname, "My Own Chip 123"); + sprintf(card->longname, "%s at 0x%lx irq %i", + card->shortname, chip->ioport, chip->irq); + + /* (5) */ + .... // implemented later + + /* (6) */ + if ((err = snd_card_register(card)) < 0) { + snd_card_free(card); + return err; + } + + /* (7) */ + pci_set_drvdata(pci, card); + dev++; + return 0; + } + + /* destructor -- see "Destructor" sub-section */ + static void __devexit snd_mychip_remove(struct pci_dev *pci) + { + snd_card_free(pci_get_drvdata(pci)); + pci_set_drvdata(pci, NULL); + } +]]> + </programlisting> + </example> + </para> + </section> + + <section id="basic-flow-constructor"> + <title>Constructor</title> + <para> + The real constructor of PCI drivers is probe callback. The + probe callback and other component-constructors which are called + from probe callback should be defined with + <parameter>__devinit</parameter> prefix. You + cannot use <parameter>__init</parameter> prefix for them, + because any PCI device could be a hotplug device. + </para> + + <para> + In the probe callback, the following scheme is often used. + </para> + + <section id="basic-flow-constructor-device-index"> + <title>1) Check and increment the device index.</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int dev; + .... + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } +]]> + </programlisting> + </informalexample> + + where enable[dev] is the module option. + </para> + + <para> + At each time probe callback is called, check the + availability of the device. If not available, simply increment + the device index and returns. dev will be incremented also + later (<link + linkend="basic-flow-constructor-set-pci"><citetitle>step + 7</citetitle></link>). + </para> + </section> + + <section id="basic-flow-constructor-create-card"> + <title>2) Create a card instance</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + snd_card_t *card; + .... + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The detail will be explained in the section + <link linkend="card-management-card-instance"><citetitle> + Management of Cards and Components</citetitle></link>. + </para> + </section> + + <section id="basic-flow-constructor-create-main"> + <title>3) Create a main component</title> + <para> + In this part, the PCI resources are allocated. + + <informalexample> + <programlisting> +<![CDATA[ + mychip_t *chip; + .... + if ((err = snd_mychip_create(card, pci, &chip)) < 0) { + snd_card_free(card); + return err; + } +]]> + </programlisting> + </informalexample> + + The detail will be explained in the section <link + linkend="pci-resource"><citetitle>PCI Resource + Managements</citetitle></link>. + </para> + </section> + + <section id="basic-flow-constructor-main-component"> + <title>4) Set the driver ID and name strings.</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + strcpy(card->driver, "My Chip"); + strcpy(card->shortname, "My Own Chip 123"); + sprintf(card->longname, "%s at 0x%lx irq %i", + card->shortname, chip->ioport, chip->irq); +]]> + </programlisting> + </informalexample> + + The driver field holds the minimal ID string of the + chip. This is referred by alsa-lib's configurator, so keep it + simple but unique. + Even the same driver can have different driver IDs to + distinguish the functionality of each chip type. + </para> + + <para> + The shortname field is a string shown as more verbose + name. The longname field contains the information which is + shown in <filename>/proc/asound/cards</filename>. + </para> + </section> + + <section id="basic-flow-constructor-create-other"> + <title>5) Create other components, such as mixer, MIDI, etc.</title> + <para> + Here you define the basic components such as + <link linkend="pcm-interface"><citetitle>PCM</citetitle></link>, + mixer (e.g. <link linkend="api-ac97"><citetitle>AC97</citetitle></link>), + MIDI (e.g. <link linkend="midi-interface"><citetitle>MPU-401</citetitle></link>), + and other interfaces. + Also, if you want a <link linkend="proc-interface"><citetitle>proc + file</citetitle></link>, define it here, too. + </para> + </section> + + <section id="basic-flow-constructor-register-card"> + <title>6) Register the card instance.</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + if ((err = snd_card_register(card)) < 0) { + snd_card_free(card); + return err; + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + Will be explained in the section <link + linkend="card-management-registration"><citetitle>Management + of Cards and Components</citetitle></link>, too. + </para> + </section> + + <section id="basic-flow-constructor-set-pci"> + <title>7) Set the PCI driver data and return zero.</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + pci_set_drvdata(pci, card); + dev++; + return 0; +]]> + </programlisting> + </informalexample> + + In the above, the card record is stored. This pointer is + referred in the remove callback and power-management + callbacks, too. + </para> + </section> + </section> + + <section id="basic-flow-destructor"> + <title>Destructor</title> + <para> + The destructor, remove callback, simply releases the card + instance. Then the ALSA middle layer will release all the + attached components automatically. + </para> + + <para> + It would be typically like the following: + + <informalexample> + <programlisting> +<![CDATA[ + static void __devexit snd_mychip_remove(struct pci_dev *pci) + { + snd_card_free(pci_get_drvdata(pci)); + pci_set_drvdata(pci, NULL); + } +]]> + </programlisting> + </informalexample> + + The above code assumes that the card pointer is set to the PCI + driver data. + </para> + </section> + + <section id="basic-flow-header-files"> + <title>Header Files</title> + <para> + For the above example, at least the following include files + are necessary. + + <informalexample> + <programlisting> +<![CDATA[ + #include <sound/driver.h> + #include <linux/init.h> + #include <linux/pci.h> + #include <linux/slab.h> + #include <sound/core.h> + #include <sound/initval.h> +]]> + </programlisting> + </informalexample> + + where the last one is necessary only when module options are + defined in the source file. If the codes are split to several + files, the file without module options don't need them. + </para> + + <para> + In addition to them, you'll need + <filename><linux/interrupt.h></filename> for the interrupt + handling, and <filename><asm/io.h></filename> for the i/o + access. If you use <function>mdelay()</function> or + <function>udelay()</function> functions, you'll need to include + <filename><linux/delay.h></filename>, too. + </para> + + <para> + The ALSA interfaces like PCM or control API are defined in other + header files as <filename><sound/xxx.h></filename>. + They have to be included after + <filename><sound/core.h></filename>. + </para> + + </section> + </chapter> + + +<!-- ****************************************************** --> +<!-- Management of Cards and Components --> +<!-- ****************************************************** --> + <chapter id="card-management"> + <title>Management of Cards and Components</title> + + <section id="card-management-card-instance"> + <title>Card Instance</title> + <para> + For each soundcard, a <quote>card</quote> record must be allocated. + </para> + + <para> + A card record is the headquarters of the soundcard. It manages + the list of whole devices (components) on the soundcard, such as + PCM, mixers, MIDI, synthesizer, and so on. Also, the card + record holds the ID and the name strings of the card, manages + the root of proc files, and controls the power-management states + and hotplug disconnections. The component list on the card + record is used to manage the proper releases of resources at + destruction. + </para> + + <para> + As mentioned above, to create a card instance, call + <function>snd_card_new()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_card_t *card; + card = snd_card_new(index, id, module, extra_size); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The function takes four arguments, the card-index number, the + id string, the module pointer (usually + <constant>THIS_MODULE</constant>), + and the size of extra-data space. The last argument is used to + allocate card->private_data for the + chip-specific data. Note that this data + <emphasis>is</emphasis> allocated by + <function>snd_card_new()</function>. + </para> + </section> + + <section id="card-management-component"> + <title>Components</title> + <para> + After the card is created, you can attach the components + (devices) to the card instance. On ALSA driver, a component is + represented as a <type>snd_device_t</type> object. + A component can be a PCM instance, a control interface, a raw + MIDI interface, etc. Each of such instances has one component + entry. + </para> + + <para> + A component can be created via + <function>snd_device_new()</function> function. + + <informalexample> + <programlisting> +<![CDATA[ + snd_device_new(card, SNDRV_DEV_XXX, chip, &ops); +]]> + </programlisting> + </informalexample> + </para> + + <para> + This takes the card pointer, the device-level + (<constant>SNDRV_DEV_XXX</constant>), the data pointer, and the + callback pointers (<parameter>&ops</parameter>). The + device-level defines the type of components and the order of + registration and de-registration. For most of components, the + device-level is already defined. For a user-defined component, + you can use <constant>SNDRV_DEV_LOWLEVEL</constant>. + </para> + + <para> + This function itself doesn't allocate the data space. The data + must be allocated manually beforehand, and its pointer is passed + as the argument. This pointer is used as the identifier + (<parameter>chip</parameter> in the above example) for the + instance. + </para> + + <para> + Each ALSA pre-defined component such as ac97 or pcm calls + <function>snd_device_new()</function> inside its + constructor. The destructor for each component is defined in the + callback pointers. Hence, you don't need to take care of + calling a destructor for such a component. + </para> + + <para> + If you would like to create your own component, you need to + set the destructor function to dev_free callback in + <parameter>ops</parameter>, so that it can be released + automatically via <function>snd_card_free()</function>. The + example will be shown later as an implementation of a + chip-specific data. + </para> + </section> + + <section id="card-management-chip-specific"> + <title>Chip-Specific Data</title> + <para> + The chip-specific information, e.g. the i/o port address, its + resource pointer, or the irq number, is stored in the + chip-specific record. + Usually, the chip-specific record is typedef'ed as + <type>xxx_t</type> like the following: + + <informalexample> + <programlisting> +<![CDATA[ + typedef struct snd_mychip mychip_t; + struct snd_mychip { + .... + }; +]]> + </programlisting> + </informalexample> + </para> + + <para> + In general, there are two ways to allocate the chip record. + </para> + + <section id="card-management-chip-specific-snd-card-new"> + <title>1. Allocating via <function>snd_card_new()</function>.</title> + <para> + As mentioned above, you can pass the extra-data-length to the 4th argument of <function>snd_card_new()</function>, i.e. + + <informalexample> + <programlisting> +<![CDATA[ + card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(mychip_t)); +]]> + </programlisting> + </informalexample> + + whether <type>mychip_t</type> is the type of the chip record. + </para> + + <para> + In return, the allocated record can be accessed as + + <informalexample> + <programlisting> +<![CDATA[ + mychip_t *chip = (mychip_t *)card->private_data; +]]> + </programlisting> + </informalexample> + + With this method, you don't have to allocate twice. + The record is released together with the card instance. + </para> + </section> + + <section id="card-management-chip-specific-allocate-extra"> + <title>2. Allocating an extra device.</title> + + <para> + After allocating a card instance via + <function>snd_card_new()</function> (with + <constant>NULL</constant> on the 4th arg), call + <function>kcalloc()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_card_t *card; + mychip_t *chip; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL); + ..... + chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The chip record should have the field to hold the card + pointer at least, + + <informalexample> + <programlisting> +<![CDATA[ + struct snd_mychip { + snd_card_t *card; + .... + }; +]]> + </programlisting> + </informalexample> + </para> + + <para> + Then, set the card pointer in the returned chip instance. + + <informalexample> + <programlisting> +<![CDATA[ + chip->card = card; +]]> + </programlisting> + </informalexample> + </para> + + <para> + Next, initialize the fields, and register this chip + record as a low-level device with a specified + <parameter>ops</parameter>, + + <informalexample> + <programlisting> +<![CDATA[ + static snd_device_ops_t ops = { + .dev_free = snd_mychip_dev_free, + }; + .... + snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); +]]> + </programlisting> + </informalexample> + + <function>snd_mychip_dev_free()</function> is the + device-destructor function, which will call the real + destructor. + </para> + + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_mychip_dev_free(snd_device_t *device) + { + mychip_t *chip = device->device_data; + return snd_mychip_free(chip); + } +]]> + </programlisting> + </informalexample> + + where <function>snd_mychip_free()</function> is the real destructor. + </para> + </section> + </section> + + <section id="card-management-registration"> + <title>Registration and Release</title> + <para> + After all components are assigned, register the card instance + by calling <function>snd_card_register()</function>. The access + to the device files are enabled at this point. That is, before + <function>snd_card_register()</function> is called, the + components are safely inaccessible from external side. If this + call fails, exit the probe function after releasing the card via + <function>snd_card_free()</function>. + </para> + + <para> + For releasing the card instance, you can call simply + <function>snd_card_free()</function>. As already mentioned, all + components are released automatically by this call. + </para> + + <para> + As further notes, the destructors (both + <function>snd_mychip_dev_free</function> and + <function>snd_mychip_free</function>) cannot be defined with + <parameter>__devexit</parameter> prefix, because they may be + called from the constructor, too, at the false path. + </para> + + <para> + For a device which allows hotplugging, you can use + <function>snd_card_free_in_thread</function>. This one will + postpone the destruction and wait in a kernel-thread until all + devices are closed. + </para> + + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- PCI Resource Managements --> +<!-- ****************************************************** --> + <chapter id="pci-resource"> + <title>PCI Resource Managements</title> + + <section id="pci-resource-example"> + <title>Full Code Example</title> + <para> + In this section, we'll finish the chip-specific constructor, + destructor and PCI entries. The example code is shown first, + below. + + <example> + <title>PCI Resource Managements Example</title> + <programlisting> +<![CDATA[ + struct snd_mychip { + snd_card_t *card; + struct pci_dev *pci; + + unsigned long port; + int irq; + }; + + static int snd_mychip_free(mychip_t *chip) + { + /* disable hardware here if any */ + .... // (not implemented in this document) + + /* release the irq */ + if (chip->irq >= 0) + free_irq(chip->irq, (void *)chip); + /* release the i/o ports & memory */ + pci_release_regions(chip->pci); + /* disable the PCI entry */ + pci_disable_device(chip->pci); + /* release the data */ + kfree(chip); + return 0; + } + + /* chip-specific constructor */ + static int __devinit snd_mychip_create(snd_card_t *card, + struct pci_dev *pci, + mychip_t **rchip) + { + mychip_t *chip; + int err; + static snd_device_ops_t ops = { + .dev_free = snd_mychip_dev_free, + }; + + *rchip = NULL; + + /* initialize the PCI entry */ + if ((err = pci_enable_device(pci)) < 0) + return err; + /* check PCI availability (28bit DMA) */ + if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { + printk(KERN_ERR "error to set 28bit mask DMA\n"); + pci_disable_device(pci); + return -ENXIO; + } + + chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + pci_disable_device(pci); + return -ENOMEM; + } + + /* initialize the stuff */ + chip->card = card; + chip->pci = pci; + chip->irq = -1; + + /* (1) PCI resource allocation */ + if ((err = pci_request_regions(pci, "My Chip")) < 0) { + kfree(chip); + pci_disable_device(pci); + return err; + } + chip->port = pci_resource_start(pci, 0); + if (request_irq(pci->irq, snd_mychip_interrupt, + SA_INTERRUPT|SA_SHIRQ, "My Chip", + (void *)chip)) { + printk(KERN_ERR "cannot grab irq %d\n", pci->irq); + snd_mychip_free(chip); + return -EBUSY; + } + chip->irq = pci->irq; + + /* (2) initialization of the chip hardware */ + .... // (not implemented in this document) + + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, + chip, &ops)) < 0) { + snd_mychip_free(chip); + return err; + } + + snd_card_set_dev(card, &pci->dev); + + *rchip = chip; + return 0; + } + + /* PCI IDs */ + static struct pci_device_id snd_mychip_ids[] = { + { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, + .... + { 0, } + }; + MODULE_DEVICE_TABLE(pci, snd_mychip_ids); + + /* pci_driver definition */ + static struct pci_driver driver = { + .name = "My Own Chip", + .id_table = snd_mychip_ids, + .probe = snd_mychip_probe, + .remove = __devexit_p(snd_mychip_remove), + }; + + /* initialization of the module */ + static int __init alsa_card_mychip_init(void) + { + return pci_module_init(&driver); + } + + /* clean up the module */ + static void __exit alsa_card_mychip_exit(void) + { + pci_unregister_driver(&driver); + } + + module_init(alsa_card_mychip_init) + module_exit(alsa_card_mychip_exit) + + EXPORT_NO_SYMBOLS; /* for old kernels only */ +]]> + </programlisting> + </example> + </para> + </section> + + <section id="pci-resource-some-haftas"> + <title>Some Hafta's</title> + <para> + The allocation of PCI resources is done in the + <function>probe()</function> function, and usually an extra + <function>xxx_create()</function> function is written for this + purpose. + </para> + + <para> + In the case of PCI devices, you have to call at first + <function>pci_enable_device()</function> function before + allocating resources. Also, you need to set the proper PCI DMA + mask to limit the accessed i/o range. In some cases, you might + need to call <function>pci_set_master()</function> function, + too. + </para> + + <para> + Suppose the 28bit mask, and the code to be added would be like: + + <informalexample> + <programlisting> +<![CDATA[ + if ((err = pci_enable_device(pci)) < 0) + return err; + if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || + pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { + printk(KERN_ERR "error to set 28bit mask DMA\n"); + pci_disable_device(pci); + return -ENXIO; + } + +]]> + </programlisting> + </informalexample> + </para> + </section> + + <section id="pci-resource-resource-allocation"> + <title>Resource Allocation</title> + <para> + The allocation of I/O ports and irqs are done via standard kernel + functions. Unlike ALSA ver.0.5.x., there are no helpers for + that. And these resources must be released in the destructor + function (see below). Also, on ALSA 0.9.x, you don't need to + allocate (pseudo-)DMA for PCI like ALSA 0.5.x. + </para> + + <para> + Now assume that this PCI device has an I/O port with 8 bytes + and an interrupt. Then <type>mychip_t</type> will have the + following fields: + + <informalexample> + <programlisting> +<![CDATA[ + struct snd_mychip { + snd_card_t *card; + + unsigned long port; + int irq; + }; +]]> + </programlisting> + </informalexample> + </para> + + <para> + For an i/o port (and also a memory region), you need to have + the resource pointer for the standard resource management. For + an irq, you have to keep only the irq number (integer). But you + need to initialize this number as -1 before actual allocation, + since irq 0 is valid. The port address and its resource pointer + can be initialized as null by + <function>kcalloc()</function> automatically, so you + don't have to take care of resetting them. + </para> + + <para> + The allocation of an i/o port is done like this: + + <informalexample> + <programlisting> +<![CDATA[ + if ((err = pci_request_regions(pci, "My Chip")) < 0) { + kfree(chip); + pci_disable_device(pci); + return err; + } + chip->port = pci_resource_start(pci, 0); +]]> + </programlisting> + </informalexample> + </para> + + <para> + <!-- obsolete --> + It will reserve the i/o port region of 8 bytes of the given + PCI device. The returned value, chip->res_port, is allocated + via <function>kmalloc()</function> by + <function>request_region()</function>. The pointer must be + released via <function>kfree()</function>, but there is some + problem regarding this. This issue will be explained more below. + </para> + + <para> + The allocation of an interrupt source is done like this: + + <informalexample> + <programlisting> +<![CDATA[ + if (request_irq(pci->irq, snd_mychip_interrupt, + SA_INTERRUPT|SA_SHIRQ, "My Chip", + (void *)chip)) { + printk(KERN_ERR "cannot grab irq %d\n", pci->irq); + snd_mychip_free(chip); + return -EBUSY; + } + chip->irq = pci->irq; +]]> + </programlisting> + </informalexample> + + where <function>snd_mychip_interrupt()</function> is the + interrupt handler defined <link + linkend="pcm-interface-interrupt-handler"><citetitle>later</citetitle></link>. + Note that chip->irq should be defined + only when <function>request_irq()</function> succeeded. + </para> + + <para> + On the PCI bus, the interrupts can be shared. Thus, + <constant>SA_SHIRQ</constant> is given as the interrupt flag of + <function>request_irq()</function>. + </para> + + <para> + The last argument of <function>request_irq()</function> is the + data pointer passed to the interrupt handler. Usually, the + chip-specific record is used for that, but you can use what you + like, too. + </para> + + <para> + I won't define the detail of the interrupt handler at this + point, but at least its appearance can be explained now. The + interrupt handler looks usually like the following: + + <informalexample> + <programlisting> +<![CDATA[ + static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id, + struct pt_regs *regs) + { + mychip_t *chip = dev_id; + .... + return IRQ_HANDLED; + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + Now let's write the corresponding destructor for the resources + above. The role of destructor is simple: disable the hardware + (if already activated) and release the resources. So far, we + have no hardware part, so the disabling is not written here. + </para> + + <para> + For releasing the resources, <quote>check-and-release</quote> + method is a safer way. For the interrupt, do like this: + + <informalexample> + <programlisting> +<![CDATA[ + if (chip->irq >= 0) + free_irq(chip->irq, (void *)chip); +]]> + </programlisting> + </informalexample> + + Since the irq number can start from 0, you should initialize + chip->irq with a negative value (e.g. -1), so that you can + check the validity of the irq number as above. + </para> + + <para> + When you requested I/O ports or memory regions via + <function>pci_request_region()</function> or + <function>pci_request_regions()</function> like this example, + release the resource(s) using the corresponding function, + <function>pci_release_region()</function> or + <function>pci_release_regions()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + pci_release_regions(chip->pci); +]]> + </programlisting> + </informalexample> + </para> + + <para> + When you requested manually via <function>request_region()</function> + or <function>request_mem_region</function>, you can release it via + <function>release_resource()</function>. Suppose that you keep + the resource pointer returned from <function>request_region()</function> + in chip->res_port, the release procedure looks like below: + + <informalexample> + <programlisting> +<![CDATA[ + if (chip->res_port) { + release_resource(chip->res_port); + kfree_nocheck(chip->res_port); + } +]]> + </programlisting> + </informalexample> + + As you can see, the resource pointer is also to be freed + via <function>kfree_nocheck()</function> after + <function>release_resource()</function> is called. You + cannot use <function>kfree()</function> here, because on ALSA, + <function>kfree()</function> may be a wrapper to its own + allocator with the memory debugging. Since the resource pointer + is allocated externally outside the ALSA, it must be released + via the native + <function>kfree()</function>. + <function>kfree_nocheck()</function> is used for that; it calls + the native <function>kfree()</function> without wrapper. + </para> + + <para> + Don't forget to call <function>pci_disable_device()</function> + before all finished. + </para> + + <para> + And finally, release the chip-specific record. + + <informalexample> + <programlisting> +<![CDATA[ + kfree(chip); +]]> + </programlisting> + </informalexample> + </para> + + <para> + Again, remember that you cannot + set <parameter>__devexit</parameter> prefix for this destructor. + </para> + + <para> + We didn't implement the hardware-disabling part in the above. + If you need to do this, please note that the destructor may be + called even before the initialization of the chip is completed. + It would be better to have a flag to skip the hardware-disabling + if the hardware was not initialized yet. + </para> + + <para> + When the chip-data is assigned to the card using + <function>snd_device_new()</function> with + <constant>SNDRV_DEV_LOWLELVEL</constant> , its destructor is + called at the last. That is, it is assured that all other + components like PCMs and controls have been already released. + You don't have to call stopping PCMs, etc. explicitly, but just + stop the hardware in the low-level. + </para> + + <para> + The management of a memory-mapped region is almost as same as + the management of an i/o port. You'll need three fields like + the following: + + <informalexample> + <programlisting> +<![CDATA[ + struct snd_mychip { + .... + unsigned long iobase_phys; + void __iomem *iobase_virt; + }; +]]> + </programlisting> + </informalexample> + + and the allocation would be like below: + + <informalexample> + <programlisting> +<![CDATA[ + if ((err = pci_request_regions(pci, "My Chip")) < 0) { + kfree(chip); + return err; + } + chip->iobase_phys = pci_resource_start(pci, 0); + chip->iobase_virt = ioremap_nocache(chip->iobase_phys, + pci_resource_len(pci, 0)); +]]> + </programlisting> + </informalexample> + + and the corresponding destructor would be: + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_mychip_free(mychip_t *chip) + { + .... + if (chip->iobase_virt) + iounmap(chip->iobase_virt); + .... + pci_release_regions(chip->pci); + .... + } +]]> + </programlisting> + </informalexample> + </para> + + </section> + + <section id="pci-resource-device-struct"> + <title>Registration of Device Struct</title> + <para> + At some point, typically after calling <function>snd_device_new()</function>, + you need to register the <structname>struct device</structname> of the chip + you're handling for udev and co. ALSA provides a macro for compatibility with + older kernels. Simply call like the following: + <informalexample> + <programlisting> +<![CDATA[ + snd_card_set_dev(card, &pci->dev); +]]> + </programlisting> + </informalexample> + so that it stores the PCI's device pointer to the card. This will be + referred by ALSA core functions later when the devices are registered. + </para> + <para> + In the case of non-PCI, pass the proper device struct pointer of the BUS + instead. (In the case of legacy ISA without PnP, you don't have to do + anything.) + </para> + </section> + + <section id="pci-resource-entries"> + <title>PCI Entries</title> + <para> + So far, so good. Let's finish the rest of missing PCI + stuffs. At first, we need a + <structname>pci_device_id</structname> table for this + chipset. It's a table of PCI vendor/device ID number, and some + masks. + </para> + + <para> + For example, + + <informalexample> + <programlisting> +<![CDATA[ + static struct pci_device_id snd_mychip_ids[] = { + { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, + .... + { 0, } + }; + MODULE_DEVICE_TABLE(pci, snd_mychip_ids); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The first and second fields of + <structname>pci_device_id</structname> struct are the vendor and + device IDs. If you have nothing special to filter the matching + devices, you can use the rest of fields like above. The last + field of <structname>pci_device_id</structname> struct is a + private data for this entry. You can specify any value here, for + example, to tell the type of different operations per each + device IDs. Such an example is found in intel8x0 driver. + </para> + + <para> + The last entry of this list is the terminator. You must + specify this all-zero entry. + </para> + + <para> + Then, prepare the <structname>pci_driver</structname> record: + + <informalexample> + <programlisting> +<![CDATA[ + static struct pci_driver driver = { + .name = "My Own Chip", + .id_table = snd_mychip_ids, + .probe = snd_mychip_probe, + .remove = __devexit_p(snd_mychip_remove), + }; +]]> + </programlisting> + </informalexample> + </para> + + <para> + The <structfield>probe</structfield> and + <structfield>remove</structfield> functions are what we already + defined in + the previous sections. The <structfield>remove</structfield> should + be defined with + <function>__devexit_p()</function> macro, so that it's not + defined for built-in (and non-hot-pluggable) case. The + <structfield>name</structfield> + field is the name string of this device. Note that you must not + use a slash <quote>/</quote> in this string. + </para> + + <para> + And at last, the module entries: + + <informalexample> + <programlisting> +<![CDATA[ + static int __init alsa_card_mychip_init(void) + { + return pci_module_init(&driver); + } + + static void __exit alsa_card_mychip_exit(void) + { + pci_unregister_driver(&driver); + } + + module_init(alsa_card_mychip_init) + module_exit(alsa_card_mychip_exit) +]]> + </programlisting> + </informalexample> + </para> + + <para> + Note that these module entries are tagged with + <parameter>__init</parameter> and + <parameter>__exit</parameter> prefixes, not + <parameter>__devinit</parameter> nor + <parameter>__devexit</parameter>. + </para> + + <para> + Oh, one thing was forgotten. If you have no exported symbols, + you need to declare it on 2.2 or 2.4 kernels (on 2.6 kernels + it's not necessary, though). + + <informalexample> + <programlisting> +<![CDATA[ + EXPORT_NO_SYMBOLS; +]]> + </programlisting> + </informalexample> + + That's all! + </para> + </section> + </chapter> + + +<!-- ****************************************************** --> +<!-- PCM Interface --> +<!-- ****************************************************** --> + <chapter id="pcm-interface"> + <title>PCM Interface</title> + + <section id="pcm-interface-general"> + <title>General</title> + <para> + The PCM middle layer of ALSA is quite powerful and it is only + necessary for each driver to implement the low-level functions + to access its hardware. + </para> + + <para> + For accessing to the PCM layer, you need to include + <filename><sound/pcm.h></filename> above all. In addition, + <filename><sound/pcm_params.h></filename> might be needed + if you access to some functions related with hw_param. + </para> + + <para> + Each card device can have up to four pcm instances. A pcm + instance corresponds to a pcm device file. The limitation of + number of instances comes only from the available bit size of + the linux's device number. Once when 64bit device number is + used, we'll have more available pcm instances. + </para> + + <para> + A pcm instance consists of pcm playback and capture streams, + and each pcm stream consists of one or more pcm substreams. Some + soundcard supports the multiple-playback function. For example, + emu10k1 has a PCM playback of 32 stereo substreams. In this case, at + each open, a free substream is (usually) automatically chosen + and opened. Meanwhile, when only one substream exists and it was + already opened, the succeeding open will result in the blocking + or the error with <constant>EAGAIN</constant> according to the + file open mode. But you don't have to know the detail in your + driver. The PCM middle layer will take all such jobs. + </para> + </section> + + <section id="pcm-interface-example"> + <title>Full Code Example</title> + <para> + The example code below does not include any hardware access + routines but shows only the skeleton, how to build up the PCM + interfaces. + + <example> + <title>PCM Example Code</title> + <programlisting> +<![CDATA[ + #include <sound/pcm.h> + .... + + /* hardware definition */ + static snd_pcm_hardware_t snd_mychip_playback_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 32768, + .period_bytes_min = 4096, + .period_bytes_max = 32768, + .periods_min = 1, + .periods_max = 1024, + }; + + /* hardware definition */ + static snd_pcm_hardware_t snd_mychip_capture_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 32768, + .period_bytes_min = 4096, + .period_bytes_max = 32768, + .periods_min = 1, + .periods_max = 1024, + }; + + /* open callback */ + static int snd_mychip_playback_open(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + runtime->hw = snd_mychip_playback_hw; + // more hardware-initialization will be done here + return 0; + } + + /* close callback */ + static int snd_mychip_playback_close(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + // the hardware-specific codes will be here + return 0; + + } + + /* open callback */ + static int snd_mychip_capture_open(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + runtime->hw = snd_mychip_capture_hw; + // more hardware-initialization will be done here + return 0; + } + + /* close callback */ + static int snd_mychip_capture_close(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + // the hardware-specific codes will be here + return 0; + + } + + /* hw_params callback */ + static int snd_mychip_pcm_hw_params(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t * hw_params) + { + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + } + + /* hw_free callback */ + static int snd_mychip_pcm_hw_free(snd_pcm_substream_t *substream) + { + return snd_pcm_lib_free_pages(substream); + } + + /* prepare callback */ + static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + /* set up the hardware with the current configuration + * for example... + */ + mychip_set_sample_format(chip, runtime->format); + mychip_set_sample_rate(chip, runtime->rate); + mychip_set_channels(chip, runtime->channels); + mychip_set_dma_setup(chip, runtime->dma_area, + chip->buffer_size, + chip->period_size); + return 0; + } + + /* trigger callback */ + static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream, + int cmd) + { + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + // do something to start the PCM engine + break; + case SNDRV_PCM_TRIGGER_STOP: + // do something to stop the PCM engine + break; + default: + return -EINVAL; + } + } + + /* pointer callback */ + static snd_pcm_uframes_t + snd_mychip_pcm_pointer(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + unsigned int current_ptr; + + /* get the current hardware pointer */ + current_ptr = mychip_get_hw_pointer(chip); + return current_ptr; + } + + /* operators */ + static snd_pcm_ops_t snd_mychip_playback_ops = { + .open = snd_mychip_playback_open, + .close = snd_mychip_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_mychip_pcm_hw_params, + .hw_free = snd_mychip_pcm_hw_free, + .prepare = snd_mychip_pcm_prepare, + .trigger = snd_mychip_pcm_trigger, + .pointer = snd_mychip_pcm_pointer, + }; + + /* operators */ + static snd_pcm_ops_t snd_mychip_capture_ops = { + .open = snd_mychip_capture_open, + .close = snd_mychip_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_mychip_pcm_hw_params, + .hw_free = snd_mychip_pcm_hw_free, + .prepare = snd_mychip_pcm_prepare, + .trigger = snd_mychip_pcm_trigger, + .pointer = snd_mychip_pcm_pointer, + }; + + /* + * definitions of capture are omitted here... + */ + + /* create a pcm device */ + static int __devinit snd_mychip_new_pcm(mychip_t *chip) + { + snd_pcm_t *pcm; + int err; + + if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, + &pcm)) < 0) + return err; + pcm->private_data = chip; + strcpy(pcm->name, "My Chip"); + chip->pcm = pcm; + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_mychip_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_mychip_capture_ops); + /* pre-allocation of buffers */ + /* NOTE: this may fail */ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + 64*1024, 64*1024); + return 0; + } +]]> + </programlisting> + </example> + </para> + </section> + + <section id="pcm-interface-constructor"> + <title>Constructor</title> + <para> + A pcm instance is allocated by <function>snd_pcm_new()</function> + function. It would be better to create a constructor for pcm, + namely, + + <informalexample> + <programlisting> +<![CDATA[ + static int __devinit snd_mychip_new_pcm(mychip_t *chip) + { + snd_pcm_t *pcm; + int err; + + if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, + &pcm)) < 0) + return err; + pcm->private_data = chip; + strcpy(pcm->name, "My Chip"); + chip->pcm = pcm; + .... + return 0; + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + The <function>snd_pcm_new()</function> function takes the four + arguments. The first argument is the card pointer to which this + pcm is assigned, and the second is the ID string. + </para> + + <para> + The third argument (<parameter>index</parameter>, 0 in the + above) is the index of this new pcm. It begins from zero. When + you will create more than one pcm instances, specify the + different numbers in this argument. For example, + <parameter>index</parameter> = 1 for the second PCM device. + </para> + + <para> + The fourth and fifth arguments are the number of substreams + for playback and capture, respectively. Here both 1 are given in + the above example. When no playback or no capture is available, + pass 0 to the corresponding argument. + </para> + + <para> + If a chip supports multiple playbacks or captures, you can + specify more numbers, but they must be handled properly in + open/close, etc. callbacks. When you need to know which + substream you are referring to, then it can be obtained from + <type>snd_pcm_substream_t</type> data passed to each callback + as follows: + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_substream_t *substream; + int index = substream->number; +]]> + </programlisting> + </informalexample> + </para> + + <para> + After the pcm is created, you need to set operators for each + pcm stream. + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_mychip_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_mychip_capture_ops); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The operators are defined typically like this: + + <informalexample> + <programlisting> +<![CDATA[ + static snd_pcm_ops_t snd_mychip_playback_ops = { + .open = snd_mychip_pcm_open, + .close = snd_mychip_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_mychip_pcm_hw_params, + .hw_free = snd_mychip_pcm_hw_free, + .prepare = snd_mychip_pcm_prepare, + .trigger = snd_mychip_pcm_trigger, + .pointer = snd_mychip_pcm_pointer, + }; +]]> + </programlisting> + </informalexample> + + Each of callbacks is explained in the subsection + <link linkend="pcm-interface-operators"><citetitle> + Operators</citetitle></link>. + </para> + + <para> + After setting the operators, most likely you'd like to + pre-allocate the buffer. For the pre-allocation, simply call + the following: + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + 64*1024, 64*1024); +]]> + </programlisting> + </informalexample> + + It will allocate up to 64kB buffer as default. The details of + buffer management will be described in the later section <link + linkend="buffer-and-memory"><citetitle>Buffer and Memory + Management</citetitle></link>. + </para> + + <para> + Additionally, you can set some extra information for this pcm + in pcm->info_flags. + The available values are defined as + <constant>SNDRV_PCM_INFO_XXX</constant> in + <filename><sound/asound.h></filename>, which is used for + the hardware definition (described later). When your soundchip + supports only half-duplex, specify like this: + + <informalexample> + <programlisting> +<![CDATA[ + pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; +]]> + </programlisting> + </informalexample> + </para> + </section> + + <section id="pcm-interface-destructor"> + <title>... And the Destructor?</title> + <para> + The destructor for a pcm instance is not always + necessary. Since the pcm device will be released by the middle + layer code automatically, you don't have to call destructor + explicitly. + </para> + + <para> + The destructor would be necessary when you created some + special records internally and need to release them. In such a + case, set the destructor function to + pcm->private_free: + + <example> + <title>PCM Instance with a Destructor</title> + <programlisting> +<![CDATA[ + static void mychip_pcm_free(snd_pcm_t *pcm) + { + mychip_t *chip = snd_pcm_chip(pcm); + /* free your own data */ + kfree(chip->my_private_pcm_data); + // do what you like else + .... + } + + static int __devinit snd_mychip_new_pcm(mychip_t *chip) + { + snd_pcm_t *pcm; + .... + /* allocate your own data */ + chip->my_private_pcm_data = kmalloc(...); + /* set the destructor */ + pcm->private_data = chip; + pcm->private_free = mychip_pcm_free; + .... + } +]]> + </programlisting> + </example> + </para> + </section> + + <section id="pcm-interface-runtime"> + <title>Runtime Pointer - The Chest of PCM Information</title> + <para> + When the PCM substream is opened, a PCM runtime instance is + allocated and assigned to the substream. This pointer is + accessible via <constant>substream->runtime</constant>. + This runtime pointer holds the various information; it holds + the copy of hw_params and sw_params configurations, the buffer + pointers, mmap records, spinlocks, etc. Almost everyhing you + need for controlling the PCM can be found there. + </para> + + <para> + The definition of runtime instance is found in + <filename><sound/pcm.h></filename>. Here is the + copy from the file. + <informalexample> + <programlisting> +<![CDATA[ +struct _snd_pcm_runtime { + /* -- Status -- */ + snd_pcm_substream_t *trigger_master; + snd_timestamp_t trigger_tstamp; /* trigger timestamp */ + int overrange; + snd_pcm_uframes_t avail_max; + snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ + snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time*/ + + /* -- HW params -- */ + snd_pcm_access_t access; /* access mode */ + snd_pcm_format_t format; /* SNDRV_PCM_FORMAT_* */ + snd_pcm_subformat_t subformat; /* subformat */ + unsigned int rate; /* rate in Hz */ + unsigned int channels; /* channels */ + snd_pcm_uframes_t period_size; /* period size */ + unsigned int periods; /* periods */ + snd_pcm_uframes_t buffer_size; /* buffer size */ + unsigned int tick_time; /* tick time */ + snd_pcm_uframes_t min_align; /* Min alignment for the format */ + size_t byte_align; + unsigned int frame_bits; + unsigned int sample_bits; + unsigned int info; + unsigned int rate_num; + unsigned int rate_den; + + /* -- SW params -- */ + int tstamp_timespec; /* use timeval (0) or timespec (1) */ + snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */ + unsigned int period_step; + unsigned int sleep_min; /* min ticks to sleep */ + snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */ + snd_pcm_uframes_t start_threshold; + snd_pcm_uframes_t stop_threshold; + snd_pcm_uframes_t silence_threshold; /* Silence filling happens when + noise is nearest than this */ + snd_pcm_uframes_t silence_size; /* Silence filling size */ + snd_pcm_uframes_t boundary; /* pointers wrap point */ + + snd_pcm_uframes_t silenced_start; + snd_pcm_uframes_t silenced_size; + + snd_pcm_sync_id_t sync; /* hardware synchronization ID */ + + /* -- mmap -- */ + volatile snd_pcm_mmap_status_t *status; + volatile snd_pcm_mmap_control_t *control; + atomic_t mmap_count; + + /* -- locking / scheduling -- */ + spinlock_t lock; + wait_queue_head_t sleep; + struct timer_list tick_timer; + struct fasync_struct *fasync; + + /* -- private section -- */ + void *private_data; + void (*private_free)(snd_pcm_runtime_t *runtime); + + /* -- hardware description -- */ + snd_pcm_hardware_t hw; + snd_pcm_hw_constraints_t hw_constraints; + + /* -- interrupt callbacks -- */ + void (*transfer_ack_begin)(snd_pcm_substream_t *substream); + void (*transfer_ack_end)(snd_pcm_substream_t *substream); + + /* -- timer -- */ + unsigned int timer_resolution; /* timer resolution */ + + /* -- DMA -- */ + unsigned char *dma_area; /* DMA area */ + dma_addr_t dma_addr; /* physical bus address (not accessible from main CPU) */ + size_t dma_bytes; /* size of DMA area */ + + struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */ + +#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) + /* -- OSS things -- */ + snd_pcm_oss_runtime_t oss; +#endif +}; +]]> + </programlisting> + </informalexample> + </para> + + <para> + For the operators (callbacks) of each sound driver, most of + these records are supposed to be read-only. Only the PCM + middle-layer changes / updates these info. The exceptions are + the hardware description (hw), interrupt callbacks + (transfer_ack_xxx), DMA buffer information, and the private + data. Besides, if you use the standard buffer allocation + method via <function>snd_pcm_lib_malloc_pages()</function>, + you don't need to set the DMA buffer information by yourself. + </para> + + <para> + In the sections below, important records are explained. + </para> + + <section id="pcm-interface-runtime-hw"> + <title>Hardware Description</title> + <para> + The hardware descriptor (<type>snd_pcm_hardware_t</type>) + contains the definitions of the fundamental hardware + configuration. Above all, you'll need to define this in + <link linkend="pcm-interface-operators-open-callback"><citetitle> + the open callback</citetitle></link>. + Note that the runtime instance holds the copy of the + descriptor, not the pointer to the existing descriptor. That + is, in the open callback, you can modify the copied descriptor + (<constant>runtime->hw</constant>) as you need. For example, if the maximum + number of channels is 1 only on some chip models, you can + still use the same hardware descriptor and change the + channels_max later: + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_runtime_t *runtime = substream->runtime; + ... + runtime->hw = snd_mychip_playback_hw; /* common definition */ + if (chip->model == VERY_OLD_ONE) + runtime->hw.channels_max = 1; +]]> + </programlisting> + </informalexample> + </para> + + <para> + Typically, you'll have a hardware descriptor like below: + <informalexample> + <programlisting> +<![CDATA[ + static snd_pcm_hardware_t snd_mychip_playback_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 32768, + .period_bytes_min = 4096, + .period_bytes_max = 32768, + .periods_min = 1, + .periods_max = 1024, + }; +]]> + </programlisting> + </informalexample> + </para> + + <para> + <itemizedlist> + <listitem><para> + The <structfield>info</structfield> field contains the type and + capabilities of this pcm. The bit flags are defined in + <filename><sound/asound.h></filename> as + <constant>SNDRV_PCM_INFO_XXX</constant>. Here, at least, you + have to specify whether the mmap is supported and which + interleaved format is supported. + When the mmap is supported, add + <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the + hardware supports the interleaved or the non-interleaved + format, <constant>SNDRV_PCM_INFO_INTERLEAVED</constant> or + <constant>SNDRV_PCM_INFO_NONINTERLEAVED</constant> flag must + be set, respectively. If both are supported, you can set both, + too. + </para> + + <para> + In the above example, <constant>MMAP_VALID</constant> and + <constant>BLOCK_TRANSFER</constant> are specified for OSS mmap + mode. Usually both are set. Of course, + <constant>MMAP_VALID</constant> is set only if the mmap is + really supported. + </para> + + <para> + The other possible flags are + <constant>SNDRV_PCM_INFO_PAUSE</constant> and + <constant>SNDRV_PCM_INFO_RESUME</constant>. The + <constant>PAUSE</constant> bit means that the pcm supports the + <quote>pause</quote> operation, while the + <constant>RESUME</constant> bit means that the pcm supports + the <quote>suspend/resume</quote> operation. If these flags + are set, the <structfield>trigger</structfield> callback below + must handle the corresponding commands. + </para> + + <para> + When the PCM substreams can be synchronized (typically, + synchorinized start/stop of a playback and a capture streams), + you can give <constant>SNDRV_PCM_INFO_SYNC_START</constant>, + too. In this case, you'll need to check the linked-list of + PCM substreams in the trigger callback. This will be + described in the later section. + </para> + </listitem> + + <listitem> + <para> + <structfield>formats</structfield> field contains the bit-flags + of supported formats (<constant>SNDRV_PCM_FMTBIT_XXX</constant>). + If the hardware supports more than one format, give all or'ed + bits. In the example above, the signed 16bit little-endian + format is specified. + </para> + </listitem> + + <listitem> + <para> + <structfield>rates</structfield> field contains the bit-flags of + supported rates (<constant>SNDRV_PCM_RATE_XXX</constant>). + When the chip supports continuous rates, pass + <constant>CONTINUOUS</constant> bit additionally. + The pre-defined rate bits are provided only for typical + rates. If your chip supports unconventional rates, you need to add + <constant>KNOT</constant> bit and set up the hardware + constraint manually (explained later). + </para> + </listitem> + + <listitem> + <para> + <structfield>rate_min</structfield> and + <structfield>rate_max</structfield> define the minimal and + maximal sample rate. This should correspond somehow to + <structfield>rates</structfield> bits. + </para> + </listitem> + + <listitem> + <para> + <structfield>channel_min</structfield> and + <structfield>channel_max</structfield> + define, as you might already expected, the minimal and maximal + number of channels. + </para> + </listitem> + + <listitem> + <para> + <structfield>buffer_bytes_max</structfield> defines the + maximal buffer size in bytes. There is no + <structfield>buffer_bytes_min</structfield> field, since + it can be calculated from the minimal period size and the + minimal number of periods. + Meanwhile, <structfield>period_bytes_min</structfield> and + define the minimal and maximal size of the period in bytes. + <structfield>periods_max</structfield> and + <structfield>periods_min</structfield> define the maximal and + minimal number of periods in the buffer. + </para> + + <para> + The <quote>period</quote> is a term, that corresponds to + fragment in the OSS world. The period defines the size at + which the PCM interrupt is generated. This size strongly + depends on the hardware. + Generally, the smaller period size will give you more + interrupts, that is, more controls. + In the case of capture, this size defines the input latency. + On the other hand, the whole buffer size defines the + output latency for the playback direction. + </para> + </listitem> + + <listitem> + <para> + There is also a field <structfield>fifo_size</structfield>. + This specifies the size of the hardware FIFO, but it's not + used currently in the driver nor in the alsa-lib. So, you + can ignore this field. + </para> + </listitem> + </itemizedlist> + </para> + </section> + + <section id="pcm-interface-runtime-config"> + <title>PCM Configurations</title> + <para> + Ok, let's go back again to the PCM runtime records. + The most frequently referred records in the runtime instance are + the PCM configurations. + The PCM configurations are stored on runtime instance + after the application sends <type>hw_params</type> data via + alsa-lib. There are many fields copied from hw_params and + sw_params structs. For example, + <structfield>format</structfield> holds the format type + chosen by the application. This field contains the enum value + <constant>SNDRV_PCM_FORMAT_XXX</constant>. + </para> + + <para> + One thing to be noted is that the configured buffer and period + sizes are stored in <quote>frames</quote> in the runtime + In the ALSA world, 1 frame = channels * samples-size. + For conversion between frames and bytes, you can use the + helper functions, <function>frames_to_bytes()</function> and + <function>bytes_to_frames()</function>. + <informalexample> + <programlisting> +<![CDATA[ + period_bytes = frames_to_bytes(runtime, runtime->period_size); +]]> + </programlisting> + </informalexample> + </para> + + <para> + Also, many software parameters (sw_params) are + stored in frames, too. Please check the type of the field. + <type>snd_pcm_uframes_t</type> is for the frames as unsigned + integer while <type>snd_pcm_sframes_t</type> is for the frames + as signed integer. + </para> + </section> + + <section id="pcm-interface-runtime-dma"> + <title>DMA Buffer Information</title> + <para> + The DMA buffer is defined by the following four fields, + <structfield>dma_area</structfield>, + <structfield>dma_addr</structfield>, + <structfield>dma_bytes</structfield> and + <structfield>dma_private</structfield>. + The <structfield>dma_area</structfield> holds the buffer + pointer (the logical address). You can call + <function>memcpy</function> from/to + this pointer. Meanwhile, <structfield>dma_addr</structfield> + holds the physical address of the buffer. This field is + specified only when the buffer is a linear buffer. + <structfield>dma_bytes</structfield> holds the size of buffer + in bytes. <structfield>dma_private</structfield> is used for + the ALSA DMA allocator. + </para> + + <para> + If you use a standard ALSA function, + <function>snd_pcm_lib_malloc_pages()</function>, for + allocating the buffer, these fields are set by the ALSA middle + layer, and you should <emphasis>not</emphasis> change them by + yourself. You can read them but not write them. + On the other hand, if you want to allocate the buffer by + yourself, you'll need to manage it in hw_params callback. + At least, <structfield>dma_bytes</structfield> is mandatory. + <structfield>dma_area</structfield> is necessary when the + buffer is mmapped. If your driver doesn't support mmap, this + field is not necessary. <structfield>dma_addr</structfield> + is also not mandatory. You can use + <structfield>dma_private</structfield> as you like, too. + </para> + </section> + + <section id="pcm-interface-runtime-status"> + <title>Running Status</title> + <para> + The running status can be referred via <constant>runtime->status</constant>. + This is the pointer to <type>snd_pcm_mmap_status_t</type> + record. For example, you can get the current DMA hardware + pointer via <constant>runtime->status->hw_ptr</constant>. + </para> + + <para> + The DMA application pointer can be referred via + <constant>runtime->control</constant>, which points + <type>snd_pcm_mmap_control_t</type> record. + However, accessing directly to this value is not recommended. + </para> + </section> + + <section id="pcm-interface-runtime-private"> + <title>Private Data</title> + <para> + You can allocate a record for the substream and store it in + <constant>runtime->private_data</constant>. Usually, this + done in + <link linkend="pcm-interface-operators-open-callback"><citetitle> + the open callback</citetitle></link>. + Don't mix this with <constant>pcm->private_data</constant>. + The <constant>pcm->private_data</constant> usually points the + chip instance assigned statically at the creation of PCM, while the + <constant>runtime->private_data</constant> points a dynamic + data created at the PCM open callback. + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_open(snd_pcm_substream_t *substream) + { + my_pcm_data_t *data; + .... + data = kmalloc(sizeof(*data), GFP_KERNEL); + substream->runtime->private_data = data; + .... + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + The allocated object must be released in + <link linkend="pcm-interface-operators-open-callback"><citetitle> + the close callback</citetitle></link>. + </para> + </section> + + <section id="pcm-interface-runtime-intr"> + <title>Interrupt Callbacks</title> + <para> + The field <structfield>transfer_ack_begin</structfield> and + <structfield>transfer_ack_end</structfield> are called at + the beginning and the end of + <function>snd_pcm_period_elapsed()</function>, respectively. + </para> + </section> + + </section> + + <section id="pcm-interface-operators"> + <title>Operators</title> + <para> + OK, now let me explain the detail of each pcm callback + (<parameter>ops</parameter>). In general, every callback must + return 0 if successful, or a negative number with the error + number such as <constant>-EINVAL</constant> at any + error. + </para> + + <para> + The callback function takes at least the argument with + <type>snd_pcm_substream_t</type> pointer. For retrieving the + chip record from the given substream instance, you can use the + following macro. + + <informalexample> + <programlisting> +<![CDATA[ + int xxx() { + mychip_t *chip = snd_pcm_substream_chip(substream); + .... + } +]]> + </programlisting> + </informalexample> + + The macro reads <constant>substream->private_data</constant>, + which is a copy of <constant>pcm->private_data</constant>. + You can override the former if you need to assign different data + records per PCM substream. For example, cmi8330 driver assigns + different private_data for playback and capture directions, + because it uses two different codecs (SB- and AD-compatible) for + different directions. + </para> + + <section id="pcm-interface-operators-open-callback"> + <title>open callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_open(snd_pcm_substream_t *substream); +]]> + </programlisting> + </informalexample> + + This is called when a pcm substream is opened. + </para> + + <para> + At least, here you have to initialize the runtime->hw + record. Typically, this is done by like this: + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_open(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + runtime->hw = snd_mychip_playback_hw; + return 0; + } +]]> + </programlisting> + </informalexample> + + where <parameter>snd_mychip_playback_hw</parameter> is the + pre-defined hardware description. + </para> + + <para> + You can allocate a private data in this callback, as described + in <link linkend="pcm-interface-runtime-private"><citetitle> + Private Data</citetitle></link> section. + </para> + + <para> + If the hardware configuration needs more constraints, set the + hardware constraints here, too. + See <link linkend="pcm-interface-constraints"><citetitle> + Constraints</citetitle></link> for more details. + </para> + </section> + + <section id="pcm-interface-operators-close-callback"> + <title>close callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_close(snd_pcm_substream_t *substream); +]]> + </programlisting> + </informalexample> + + Obviously, this is called when a pcm substream is closed. + </para> + + <para> + Any private instance for a pcm substream allocated in the + open callback will be released here. + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_close(snd_pcm_substream_t *substream) + { + .... + kfree(substream->runtime->private_data); + .... + } +]]> + </programlisting> + </informalexample> + </para> + </section> + + <section id="pcm-interface-operators-ioctl-callback"> + <title>ioctl callback</title> + <para> + This is used for any special action to pcm ioctls. But + usually you can pass a generic ioctl callback, + <function>snd_pcm_lib_ioctl</function>. + </para> + </section> + + <section id="pcm-interface-operators-hw-params-callback"> + <title>hw_params callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params); +]]> + </programlisting> + </informalexample> + + This and <structfield>hw_free</structfield> callbacks exist + only on ALSA 0.9.x. + </para> + + <para> + This is called when the hardware parameter + (<structfield>hw_params</structfield>) is set + up by the application, + that is, once when the buffer size, the period size, the + format, etc. are defined for the pcm substream. + </para> + + <para> + Many hardware set-up should be done in this callback, + including the allocation of buffers. + </para> + + <para> + Parameters to be initialized are retrieved by + <function>params_xxx()</function> macros. For allocating a + buffer, you can call a helper function, + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); +]]> + </programlisting> + </informalexample> + + <function>snd_pcm_lib_malloc_pages()</function> is available + only when the DMA buffers have been pre-allocated. + See the section <link + linkend="buffer-and-memory-buffer-types"><citetitle> + Buffer Types</citetitle></link> for more details. + </para> + + <para> + Note that this and <structfield>prepare</structfield> callbacks + may be called multiple times per initialization. + For example, the OSS emulation may + call these callbacks at each change via its ioctl. + </para> + + <para> + Thus, you need to take care not to allocate the same buffers + many times, which will lead to memory leak! Calling the + helper function above many times is OK. It will release the + previous buffer automatically when it was already allocated. + </para> + + <para> + Another note is that this callback is non-atomic + (schedulable). This is important, because the + <structfield>trigger</structfield> callback + is atomic (non-schedulable). That is, mutex or any + schedule-related functions are not available in + <structfield>trigger</structfield> callback. + Please see the subsection + <link linkend="pcm-interface-atomicity"><citetitle> + Atomicity</citetitle></link> for details. + </para> + </section> + + <section id="pcm-interface-operators-hw-free-callback"> + <title>hw_free callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_hw_free(snd_pcm_substream_t * substream); +]]> + </programlisting> + </informalexample> + </para> + + <para> + This is called to release the resources allocated via + <structfield>hw_params</structfield>. For example, releasing the + buffer via + <function>snd_pcm_lib_malloc_pages()</function> is done by + calling the following: + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_lib_free_pages(substream); +]]> + </programlisting> + </informalexample> + </para> + + <para> + This function is always called before the close callback is called. + Also, the callback may be called multiple times, too. + Keep track whether the resource was already released. + </para> + </section> + + <section id="pcm-interface-operators-prepare-callback"> + <title>prepare callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_prepare(snd_pcm_substream_t * substream); +]]> + </programlisting> + </informalexample> + </para> + + <para> + This callback is called when the pcm is + <quote>prepared</quote>. You can set the format type, sample + rate, etc. here. The difference from + <structfield>hw_params</structfield> is that the + <structfield>prepare</structfield> callback will be called at each + time + <function>snd_pcm_prepare()</function> is called, i.e. when + recovered after underruns, etc. + </para> + + <para> + Note that this callback became non-atomic since the recent version. + You can use schedule-related fucntions safely in this callback now. + </para> + + <para> + In this and the following callbacks, you can refer to the + values via the runtime record, + substream->runtime. + For example, to get the current + rate, format or channels, access to + runtime->rate, + runtime->format or + runtime->channels, respectively. + The physical address of the allocated buffer is set to + runtime->dma_area. The buffer and period sizes are + in runtime->buffer_size and runtime->period_size, + respectively. + </para> + + <para> + Be careful that this callback will be called many times at + each set up, too. + </para> + </section> + + <section id="pcm-interface-operators-trigger-callback"> + <title>trigger callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_trigger(snd_pcm_substream_t * substream, int cmd); +]]> + </programlisting> + </informalexample> + + This is called when the pcm is started, stopped or paused. + </para> + + <para> + Which action is specified in the second argument, + <constant>SNDRV_PCM_TRIGGER_XXX</constant> in + <filename><sound/pcm.h></filename>. At least, + <constant>START</constant> and <constant>STOP</constant> + commands must be defined in this callback. + + <informalexample> + <programlisting> +<![CDATA[ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + // do something to start the PCM engine + break; + case SNDRV_PCM_TRIGGER_STOP: + // do something to stop the PCM engine + break; + default: + return -EINVAL; + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + When the pcm supports the pause operation (given in info + field of the hardware table), <constant>PAUSE_PUSE</constant> + and <constant>PAUSE_RELEASE</constant> commands must be + handled here, too. The former is the command to pause the pcm, + and the latter to restart the pcm again. + </para> + + <para> + When the pcm supports the suspend/resume operation + (i.e. <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set), + <constant>SUSPEND</constant> and <constant>RESUME</constant> + commands must be handled, too. + These commands are issued when the power-management status is + changed. Obviously, the <constant>SUSPEND</constant> and + <constant>RESUME</constant> + do suspend and resume of the pcm substream, and usually, they + are identical with <constant>STOP</constant> and + <constant>START</constant> commands, respectively. + </para> + + <para> + As mentioned, this callback is atomic. You cannot call + the function going to sleep. + The trigger callback should be as minimal as possible, + just really triggering the DMA. The other stuff should be + initialized hw_params and prepare callbacks properly + beforehand. + </para> + </section> + + <section id="pcm-interface-operators-pointer-callback"> + <title>pointer callback</title> + <para> + <informalexample> + <programlisting> +<![CDATA[ + static snd_pcm_uframes_t snd_xxx_pointer(snd_pcm_substream_t * substream) +]]> + </programlisting> + </informalexample> + + This callback is called when the PCM middle layer inquires + the current hardware position on the buffer. The position must + be returned in frames (which was in bytes on ALSA 0.5.x), + ranged from 0 to buffer_size - 1. + </para> + + <para> + This is called usually from the buffer-update routine in the + pcm middle layer, which is invoked when + <function>snd_pcm_period_elapsed()</function> is called in the + interrupt routine. Then the pcm middle layer updates the + position and calculates the available space, and wakes up the + sleeping poll threads, etc. + </para> + + <para> + This callback is also atomic. + </para> + </section> + + <section id="pcm-interface-operators-copy-silence"> + <title>copy and silence callbacks</title> + <para> + These callbacks are not mandatory, and can be omitted in + most cases. These callbacks are used when the hardware buffer + cannot be on the normal memory space. Some chips have their + own buffer on the hardware which is not mappable. In such a + case, you have to transfer the data manually from the memory + buffer to the hardware buffer. Or, if the buffer is + non-contiguous on both physical and virtual memory spaces, + these callbacks must be defined, too. + </para> + + <para> + If these two callbacks are defined, copy and set-silence + operations are done by them. The detailed will be described in + the later section <link + linkend="buffer-and-memory"><citetitle>Buffer and Memory + Management</citetitle></link>. + </para> + </section> + + <section id="pcm-interface-operators-ack"> + <title>ack callback</title> + <para> + This callback is also not mandatory. This callback is called + when the appl_ptr is updated in read or write operations. + Some drivers like emu10k1-fx and cs46xx need to track the + current appl_ptr for the internal buffer, and this callback + is useful only for such a purpose. + </para> + <para> + This callback is atomic. + </para> + </section> + + <section id="pcm-interface-operators-page-callback"> + <title>page callback</title> + + <para> + This callback is also not mandatory. This callback is used + mainly for the non-contiguous buffer. The mmap calls this + callback to get the page address. Some examples will be + explained in the later section <link + linkend="buffer-and-memory"><citetitle>Buffer and Memory + Management</citetitle></link>, too. + </para> + </section> + </section> + + <section id="pcm-interface-interrupt-handler"> + <title>Interrupt Handler</title> + <para> + The rest of pcm stuff is the PCM interrupt handler. The + role of PCM interrupt handler in the sound driver is to update + the buffer position and to tell the PCM middle layer when the + buffer position goes across the prescribed period size. To + inform this, call <function>snd_pcm_period_elapsed()</function> + function. + </para> + + <para> + There are several types of sound chips to generate the interrupts. + </para> + + <section id="pcm-interface-interrupt-handler-boundary"> + <title>Interrupts at the period (fragment) boundary</title> + <para> + This is the most frequently found type: the hardware + generates an interrupt at each period boundary. + In this case, you can call + <function>snd_pcm_period_elapsed()</function> at each + interrupt. + </para> + + <para> + <function>snd_pcm_period_elapsed()</function> takes the + substream pointer as its argument. Thus, you need to keep the + substream pointer accessible from the chip instance. For + example, define substream field in the chip record to hold the + current running substream pointer, and set the pointer value + at open callback (and reset at close callback). + </para> + + <para> + If you aquire a spinlock in the interrupt handler, and the + lock is used in other pcm callbacks, too, then you have to + release the lock before calling + <function>snd_pcm_period_elapsed()</function>, because + <function>snd_pcm_period_elapsed()</function> calls other pcm + callbacks inside. + </para> + + <para> + A typical coding would be like: + + <example> + <title>Interrupt Handler Case #1</title> + <programlisting> +<![CDATA[ + static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id, + struct pt_regs *regs) + { + mychip_t *chip = dev_id; + spin_lock(&chip->lock); + .... + if (pcm_irq_invoked(chip)) { + /* call updater, unlock before it */ + spin_unlock(&chip->lock); + snd_pcm_period_elapsed(chip->substream); + spin_lock(&chip->lock); + // acknowledge the interrupt if necessary + } + .... + spin_unlock(&chip->lock); + return IRQ_HANDLED; + } +]]> + </programlisting> + </example> + </para> + </section> + + <section id="pcm-interface-interrupt-handler-timer"> + <title>High-frequent timer interrupts</title> + <para> + This is the case when the hardware doesn't generate interrupts + at the period boundary but do timer-interrupts at the fixed + timer rate (e.g. es1968 or ymfpci drivers). + In this case, you need to check the current hardware + position and accumulates the processed sample length at each + interrupt. When the accumulated size overcomes the period + size, call + <function>snd_pcm_period_elapsed()</function> and reset the + accumulator. + </para> + + <para> + A typical coding would be like the following. + + <example> + <title>Interrupt Handler Case #2</title> + <programlisting> +<![CDATA[ + static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id, + struct pt_regs *regs) + { + mychip_t *chip = dev_id; + spin_lock(&chip->lock); + .... + if (pcm_irq_invoked(chip)) { + unsigned int last_ptr, size; + /* get the current hardware pointer (in frames) */ + last_ptr = get_hw_ptr(chip); + /* calculate the processed frames since the + * last update + */ + if (last_ptr < chip->last_ptr) + size = runtime->buffer_size + last_ptr + - chip->last_ptr; + else + size = last_ptr - chip->last_ptr; + /* remember the last updated point */ + chip->last_ptr = last_ptr; + /* accumulate the size */ + chip->size += size; + /* over the period boundary? */ + if (chip->size >= runtime->period_size) { + /* reset the accumulator */ + chip->size %= runtime->period_size; + /* call updater */ + spin_unlock(&chip->lock); + snd_pcm_period_elapsed(substream); + spin_lock(&chip->lock); + } + // acknowledge the interrupt if necessary + } + .... + spin_unlock(&chip->lock); + return IRQ_HANDLED; + } +]]> + </programlisting> + </example> + </para> + </section> + + <section id="pcm-interface-interrupt-handler-both"> + <title>On calling <function>snd_pcm_period_elapsed()</function></title> + <para> + In both cases, even if more than one period are elapsed, you + don't have to call + <function>snd_pcm_period_elapsed()</function> many times. Call + only once. And the pcm layer will check the current hardware + pointer and update to the latest status. + </para> + </section> + </section> + + <section id="pcm-interface-atomicity"> + <title>Atomicity</title> + <para> + One of the most important (and thus difficult to debug) problem + on the kernel programming is the race condition. + On linux kernel, usually it's solved via spin-locks or + semaphores. In general, if the race condition may + happen in the interrupt handler, it's handled as atomic, and you + have to use spinlock for protecting the critical session. If it + never happens in the interrupt and it may take relatively long + time, you should use semaphore. + </para> + + <para> + As already seen, some pcm callbacks are atomic and some are + not. For example, <parameter>hw_params</parameter> callback is + non-atomic, while <parameter>trigger</parameter> callback is + atomic. This means, the latter is called already in a spinlock + held by the PCM middle layer. Please take this atomicity into + account when you use a spinlock or a semaphore in the callbacks. + </para> + + <para> + In the atomic callbacks, you cannot use functions which may call + <function>schedule</function> or go to + <function>sleep</function>. The semaphore and mutex do sleep, + and hence they cannot be used inside the atomic callbacks + (e.g. <parameter>trigger</parameter> callback). + For taking a certain delay in such a callback, please use + <function>udelay()</function> or <function>mdelay()</function>. + </para> + + <para> + All three atomic callbacks (trigger, pointer, and ack) are + called with local interrupts disabled. + </para> + + </section> + <section id="pcm-interface-constraints"> + <title>Constraints</title> + <para> + If your chip supports unconventional sample rates, or only the + limited samples, you need to set a constraint for the + condition. + </para> + + <para> + For example, in order to restrict the sample rates in the some + supported values, use + <function>snd_pcm_hw_constraint_list()</function>. + You need to call this function in the open callback. + + <example> + <title>Example of Hardware Constraints</title> + <programlisting> +<![CDATA[ + static unsigned int rates[] = + {4000, 10000, 22050, 44100}; + static snd_pcm_hw_constraint_list_t constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + + static int snd_mychip_pcm_open(snd_pcm_substream_t *substream) + { + int err; + .... + err = snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (err < 0) + return err; + .... + } +]]> + </programlisting> + </example> + </para> + + <para> + There are many different constraints. + Look in <filename>sound/pcm.h</filename> for a complete list. + You can even define your own constraint rules. + For example, let's suppose my_chip can manage a substream of 1 channel + if and only if the format is S16_LE, otherwise it supports any format + specified in the <type>snd_pcm_hardware_t</type> stucture (or in any + other constraint_list). You can build a rule like this: + + <example> + <title>Example of Hardware Constraints for Channels</title> + <programlisting> +<![CDATA[ + static int hw_rule_format_by_channels(snd_pcm_hw_params_t *params, + snd_pcm_hw_rule_t *rule) + { + snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + snd_mask_t fmt; + + snd_mask_any(&fmt); /* Init the struct */ + if (c->min < 2) { + fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_LE; + return snd_mask_refine(f, &fmt); + } + return 0; + } +]]> + </programlisting> + </example> + </para> + + <para> + Then you need to call this function to add your rule: + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + hw_rule_channels_by_format, 0, SNDRV_PCM_HW_PARAM_FORMAT, + -1); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The rule function is called when an application sets the number of + channels. But an application can set the format before the number of + channels. Thus you also need to define the inverse rule: + + <example> + <title>Example of Hardware Constraints for Channels</title> + <programlisting> +<![CDATA[ + static int hw_rule_channels_by_format(snd_pcm_hw_params_t *params, + snd_pcm_hw_rule_t *rule) + { + snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + snd_interval_t ch; + + snd_interval_any(&ch); + if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) { + ch.min = ch.max = 1; + ch.integer = 1; + return snd_interval_refine(c, &ch); + } + return 0; + } +]]> + </programlisting> + </example> + </para> + + <para> + ...and in the open callback: + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, + hw_rule_format_by_channels, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + -1); +]]> + </programlisting> + </informalexample> + </para> + + <para> + I won't explain more details here, rather I + would like to say, <quote>Luke, use the source.</quote> + </para> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- Control Interface --> +<!-- ****************************************************** --> + <chapter id="control-interface"> + <title>Control Interface</title> + + <section id="control-interface-general"> + <title>General</title> + <para> + The control interface is used widely for many switches, + sliders, etc. which are accessed from the user-space. Its most + important use is the mixer interface. In other words, on ALSA + 0.9.x, all the mixer stuff is implemented on the control kernel + API (while there was an independent mixer kernel API on 0.5.x). + </para> + + <para> + ALSA has a well-defined AC97 control module. If your chip + supports only the AC97 and nothing else, you can skip this + section. + </para> + + <para> + The control API is defined in + <filename><sound/control.h></filename>. + Include this file if you add your own controls. + </para> + </section> + + <section id="control-interface-definition"> + <title>Definition of Controls</title> + <para> + For creating a new control, you need to define the three + callbacks: <structfield>info</structfield>, + <structfield>get</structfield> and + <structfield>put</structfield>. Then, define a + <type>snd_kcontrol_new_t</type> record, such as: + + <example> + <title>Definition of a Control</title> + <programlisting> +<![CDATA[ + static snd_kcontrol_new_t my_control __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Switch", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_values = 0xffff, + .info = my_control_info, + .get = my_control_get, + .put = my_control_put + }; +]]> + </programlisting> + </example> + </para> + + <para> + Most likely the control is created via + <function>snd_ctl_new1()</function>, and in such a case, you can + add <parameter>__devinitdata</parameter> prefix to the + definition like above. + </para> + + <para> + The <structfield>iface</structfield> field specifies the type of + the control, + <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>. There are + <constant>MIXER</constant>, <constant>PCM</constant>, + <constant>CARD</constant>, etc. + </para> + + <para> + The <structfield>name</structfield> is the name identifier + string. On ALSA 0.9.x, the control name is very important, + because its role is classified from its name. There are + pre-defined standard control names. The details are described in + the subsection + <link linkend="control-interface-control-names"><citetitle> + Control Names</citetitle></link>. + </para> + + <para> + The <structfield>index</structfield> field holds the index number + of this control. If there are several different controls with + the same name, they can be distinguished by the index + number. This is the case when + several codecs exist on the card. If the index is zero, you can + omit the definition above. + </para> + + <para> + The <structfield>access</structfield> field contains the access + type of this control. Give the combination of bit masks, + <constant>SNDRV_CTL_ELEM_ACCESS_XXX</constant>, there. + The detailed will be explained in the subsection + <link linkend="control-interface-access-flags"><citetitle> + Access Flags</citetitle></link>. + </para> + + <para> + The <structfield>private_values</structfield> field contains + an arbitrary long integer value for this record. When using + generic <structfield>info</structfield>, + <structfield>get</structfield> and + <structfield>put</structfield> callbacks, you can pass a value + through this field. If several small numbers are necessary, you can + combine them in bitwise. Or, it's possible to give a pointer + (casted to unsigned long) of some record to this field, too. + </para> + + <para> + The other three are + <link linkend="control-interface-callbacks"><citetitle> + callback functions</citetitle></link>. + </para> + </section> + + <section id="control-interface-control-names"> + <title>Control Names</title> + <para> + There are some standards for defining the control names. A + control is usually defined from the three parts as + <quote>SOURCE DIRECTION FUNCTION</quote>. + </para> + + <para> + The first, <constant>SOURCE</constant>, specifies the source + of the control, and is a string such as <quote>Master</quote>, + <quote>PCM</quote>, <quote>CD</quote> or + <quote>Line</quote>. There are many pre-defined sources. + </para> + + <para> + The second, <constant>DIRECTION</constant>, is one of the + following strings according to the direction of the control: + <quote>Playback</quote>, <quote>Capture</quote>, <quote>Bypass + Playback</quote> and <quote>Bypass Capture</quote>. Or, it can + be omitted, meaning both playback and capture directions. + </para> + + <para> + The third, <constant>FUNCTION</constant>, is one of the + following strings according to the function of the control: + <quote>Switch</quote>, <quote>Volume</quote> and + <quote>Route</quote>. + </para> + + <para> + The example of control names are, thus, <quote>Master Capture + Switch</quote> or <quote>PCM Playback Volume</quote>. + </para> + + <para> + There are some exceptions: + </para> + + <section id="control-interface-control-names-global"> + <title>Global capture and playback</title> + <para> + <quote>Capture Source</quote>, <quote>Capture Switch</quote> + and <quote>Capture Volume</quote> are used for the global + capture (input) source, switch and volume. Similarly, + <quote>Playback Switch</quote> and <quote>Playback + Volume</quote> are used for the global output gain switch and + volume. + </para> + </section> + + <section id="control-interface-control-names-tone"> + <title>Tone-controls</title> + <para> + tone-control switch and volumes are specified like + <quote>Tone Control - XXX</quote>, e.g. <quote>Tone Control - + Switch</quote>, <quote>Tone Control - Bass</quote>, + <quote>Tone Control - Center</quote>. + </para> + </section> + + <section id="control-interface-control-names-3d"> + <title>3D controls</title> + <para> + 3D-control switches and volumes are specified like <quote>3D + Control - XXX</quote>, e.g. <quote>3D Control - + Switch</quote>, <quote>3D Control - Center</quote>, <quote>3D + Control - Space</quote>. + </para> + </section> + + <section id="control-interface-control-names-mic"> + <title>Mic boost</title> + <para> + Mic-boost switch is set as <quote>Mic Boost</quote> or + <quote>Mic Boost (6dB)</quote>. + </para> + + <para> + More precise information can be found in + <filename>Documentation/sound/alsa/ControlNames.txt</filename>. + </para> + </section> + </section> + + <section id="control-interface-access-flags"> + <title>Access Flags</title> + + <para> + The access flag is the bit-flags which specifies the access type + of the given control. The default access type is + <constant>SNDRV_CTL_ELEM_ACCESS_READWRITE</constant>, + which means both read and write are allowed to this control. + When the access flag is omitted (i.e. = 0), it is + regarded as <constant>READWRITE</constant> access as default. + </para> + + <para> + When the control is read-only, pass + <constant>SNDRV_CTL_ELEM_ACCESS_READ</constant> instead. + In this case, you don't have to define + <structfield>put</structfield> callback. + Similarly, when the control is write-only (although it's a rare + case), you can use <constant>WRITE</constant> flag instead, and + you don't need <structfield>get</structfield> callback. + </para> + + <para> + If the control value changes frequently (e.g. the VU meter), + <constant>VOLATILE</constant> flag should be given. This means + that the control may be changed without + <link linkend="control-interface-change-notification"><citetitle> + notification</citetitle></link>. Applications should poll such + a control constantly. + </para> + + <para> + When the control is inactive, set + <constant>INACTIVE</constant> flag, too. + There are <constant>LOCK</constant> and + <constant>OWNER</constant> flags for changing the write + permissions. + </para> + + </section> + + <section id="control-interface-callbacks"> + <title>Callbacks</title> + + <section id="control-interface-callbacks-info"> + <title>info callback</title> + <para> + The <structfield>info</structfield> callback is used to get + the detailed information of this control. This must store the + values of the given <type>snd_ctl_elem_info_t</type> + object. For example, for a boolean control with a single + element will be: + + <example> + <title>Example of info callback</title> + <programlisting> +<![CDATA[ + static int snd_myctl_info(snd_kcontrol_t *kcontrol, + snd_ctl_elem_info_t *uinfo) + { + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; + } +]]> + </programlisting> + </example> + </para> + + <para> + The <structfield>type</structfield> field specifies the type + of the control. There are <constant>BOOLEAN</constant>, + <constant>INTEGER</constant>, <constant>ENUMERATED</constant>, + <constant>BYTES</constant>, <constant>IEC958</constant> and + <constant>INTEGER64</constant>. The + <structfield>count</structfield> field specifies the + number of elements in this control. For example, a stereo + volume would have count = 2. The + <structfield>value</structfield> field is a union, and + the values stored are depending on the type. The boolean and + integer are identical. + </para> + + <para> + The enumerated type is a bit different from others. You'll + need to set the string for the currently given item index. + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_myctl_info(snd_kcontrol_t *kcontrol, + snd_ctl_elem_info_t *uinfo) + { + static char *texts[4] = { + "First", "Second", "Third", "Fourth" + }; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 4; + if (uinfo->value.enumerated.item > 3) + uinfo->value.enumerated.item = 3; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; + } +]]> + </programlisting> + </informalexample> + </para> + </section> + + <section id="control-interface-callbacks-get"> + <title>get callback</title> + + <para> + This callback is used to read the current value of the + control and to return to the user-space. + </para> + + <para> + For example, + + <example> + <title>Example of get callback</title> + <programlisting> +<![CDATA[ + static int snd_myctl_get(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *ucontrol) + { + mychip_t *chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = get_some_value(chip); + return 0; + } +]]> + </programlisting> + </example> + </para> + + <para> + Here, the chip instance is retrieved via + <function>snd_kcontrol_chip()</function> macro. This macro + converts from kcontrol->private_data to the type defined by + <type>chip_t</type>. The + kcontrol->private_data field is + given as the argument of <function>snd_ctl_new()</function> + (see the later subsection + <link linkend="control-interface-constructor"><citetitle>Constructor</citetitle></link>). + </para> + + <para> + The <structfield>value</structfield> field is depending on + the type of control as well as on info callback. For example, + the sb driver uses this field to store the register offset, + the bit-shift and the bit-mask. The + <structfield>private_value</structfield> is set like + <informalexample> + <programlisting> +<![CDATA[ + .private_value = reg | (shift << 16) | (mask << 24) +]]> + </programlisting> + </informalexample> + and is retrieved in callbacks like + <informalexample> + <programlisting> +<![CDATA[ + static int snd_sbmixer_get_single(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *ucontrol) + { + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 16) & 0xff; + int mask = (kcontrol->private_value >> 24) & 0xff; + .... + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + In <structfield>get</structfield> callback, you have to fill all the elements if the + control has more than one elements, + i.e. <structfield>count</structfield> > 1. + In the example above, we filled only one element + (<structfield>value.integer.value[0]</structfield>) since it's + assumed as <structfield>count</structfield> = 1. + </para> + </section> + + <section id="control-interface-callbacks-put"> + <title>put callback</title> + + <para> + This callback is used to write a value from the user-space. + </para> + + <para> + For example, + + <example> + <title>Example of put callback</title> + <programlisting> +<![CDATA[ + static int snd_myctl_put(snd_kcontrol_t *kcontrol, + snd_ctl_elem_value_t *ucontrol) + { + mychip_t *chip = snd_kcontrol_chip(kcontrol); + int changed = 0; + if (chip->current_value != + ucontrol->value.integer.value[0]) { + change_current_value(chip, + ucontrol->value.integer.value[0]); + changed = 1; + } + return changed; + } +]]> + </programlisting> + </example> + + As seen above, you have to return 1 if the value is + changed. If the value is not changed, return 0 instead. + If any fatal error happens, return a negative error code as + usual. + </para> + + <para> + Like <structfield>get</structfield> callback, + when the control has more than one elements, + all elemehts must be evaluated in this callback, too. + </para> + </section> + + <section id="control-interface-callbacks-all"> + <title>Callbacks are not atomic</title> + <para> + All these three callbacks are basically not atomic. + </para> + </section> + </section> + + <section id="control-interface-constructor"> + <title>Constructor</title> + <para> + When everything is ready, finally we can create a new + control. For creating a control, there are two functions to be + called, <function>snd_ctl_new1()</function> and + <function>snd_ctl_add()</function>. + </para> + + <para> + In the simplest way, you can do like this: + + <informalexample> + <programlisting> +<![CDATA[ + if ((err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip))) < 0) + return err; +]]> + </programlisting> + </informalexample> + + where <parameter>my_control</parameter> is the + <type>snd_kcontrol_new_t</type> object defined above, and chip + is the object pointer to be passed to + kcontrol->private_data + which can be referred in callbacks. + </para> + + <para> + <function>snd_ctl_new1()</function> allocates a new + <type>snd_kcontrol_t</type> instance (that's why the definition + of <parameter>my_control</parameter> can be with + <parameter>__devinitdata</parameter> + prefix), and <function>snd_ctl_add</function> assigns the given + control component to the card. + </para> + </section> + + <section id="control-interface-change-notification"> + <title>Change Notification</title> + <para> + If you need to change and update a control in the interrupt + routine, you can call <function>snd_ctl_notify()</function>. For + example, + + <informalexample> + <programlisting> +<![CDATA[ + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer); +]]> + </programlisting> + </informalexample> + + This function takes the card pointer, the event-mask, and the + control id pointer for the notification. The event-mask + specifies the types of notification, for example, in the above + example, the change of control values is notified. + The id pointer is the pointer of <type>snd_ctl_elem_id_t</type> + to be notified. + You can find some examples in <filename>es1938.c</filename> or + <filename>es1968.c</filename> for hardware volume interrupts. + </para> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- API for AC97 Codec --> +<!-- ****************************************************** --> + <chapter id="api-ac97"> + <title>API for AC97 Codec</title> + + <section> + <title>General</title> + <para> + The ALSA AC97 codec layer is a well-defined one, and you don't + have to write many codes to control it. Only low-level control + routines are necessary. The AC97 codec API is defined in + <filename><sound/ac97_codec.h></filename>. + </para> + </section> + + <section id="api-ac97-example"> + <title>Full Code Example</title> + <para> + <example> + <title>Example of AC97 Interface</title> + <programlisting> +<![CDATA[ + struct snd_mychip { + .... + ac97_t *ac97; + .... + }; + + static unsigned short snd_mychip_ac97_read(ac97_t *ac97, + unsigned short reg) + { + mychip_t *chip = ac97->private_data; + .... + // read a register value here from the codec + return the_register_value; + } + + static void snd_mychip_ac97_write(ac97_t *ac97, + unsigned short reg, unsigned short val) + { + mychip_t *chip = ac97->private_data; + .... + // write the given register value to the codec + } + + static int snd_mychip_ac97(mychip_t *chip) + { + ac97_bus_t *bus; + ac97_template_t ac97; + int err; + static ac97_bus_ops_t ops = { + .write = snd_mychip_ac97_write, + .read = snd_mychip_ac97_read, + }; + + if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0) + return err; + memset(&ac97, 0, sizeof(ac97)); + ac97.private_data = chip; + return snd_ac97_mixer(bus, &ac97, &chip->ac97); + } + +]]> + </programlisting> + </example> + </para> + </section> + + <section id="api-ac97-constructor"> + <title>Constructor</title> + <para> + For creating an ac97 instance, first call <function>snd_ac97_bus</function> + with an <type>ac97_bus_ops_t</type> record with callback functions. + + <informalexample> + <programlisting> +<![CDATA[ + ac97_bus_t *bus; + static ac97_bus_ops_t ops = { + .write = snd_mychip_ac97_write, + .read = snd_mychip_ac97_read, + }; + + snd_ac97_bus(card, 0, &ops, NULL, &pbus); +]]> + </programlisting> + </informalexample> + + The bus record is shared among all belonging ac97 instances. + </para> + + <para> + And then call <function>snd_ac97_mixer()</function> with an <type>ac97_template_t</type> + record together with the bus pointer created above. + + <informalexample> + <programlisting> +<![CDATA[ + ac97_template_t ac97; + int err; + + memset(&ac97, 0, sizeof(ac97)); + ac97.private_data = chip; + snd_ac97_mixer(bus, &ac97, &chip->ac97); +]]> + </programlisting> + </informalexample> + + where chip->ac97 is the pointer of a newly created + <type>ac97_t</type> instance. + In this case, the chip pointer is set as the private data, so that + the read/write callback functions can refer to this chip instance. + This instance is not necessarily stored in the chip + record. When you need to change the register values from the + driver, or need the suspend/resume of ac97 codecs, keep this + pointer to pass to the corresponding functions. + </para> + </section> + + <section id="api-ac97-callbacks"> + <title>Callbacks</title> + <para> + The standard callbacks are <structfield>read</structfield> and + <structfield>write</structfield>. Obviously they + correspond to the functions for read and write accesses to the + hardware low-level codes. + </para> + + <para> + The <structfield>read</structfield> callback returns the + register value specified in the argument. + + <informalexample> + <programlisting> +<![CDATA[ + static unsigned short snd_mychip_ac97_read(ac97_t *ac97, + unsigned short reg) + { + mychip_t *chip = ac97->private_data; + .... + return the_register_value; + } +]]> + </programlisting> + </informalexample> + + Here, the chip can be cast from ac97->private_data. + </para> + + <para> + Meanwhile, the <structfield>write</structfield> callback is + used to set the register value. + + <informalexample> + <programlisting> +<![CDATA[ + static void snd_mychip_ac97_write(ac97_t *ac97, + unsigned short reg, unsigned short val) +]]> + </programlisting> + </informalexample> + </para> + + <para> + These callbacks are non-atomic like the callbacks of control API. + </para> + + <para> + There are also other callbacks: + <structfield>reset</structfield>, + <structfield>wait</structfield> and + <structfield>init</structfield>. + </para> + + <para> + The <structfield>reset</structfield> callback is used to reset + the codec. If the chip requires a special way of reset, you can + define this callback. + </para> + + <para> + The <structfield>wait</structfield> callback is used for a + certain wait at the standard initialization of the codec. If the + chip requires the extra wait-time, define this callback. + </para> + + <para> + The <structfield>init</structfield> callback is used for + additional initialization of the codec. + </para> + </section> + + <section id="api-ac97-updating-registers"> + <title>Updating Registers in The Driver</title> + <para> + If you need to access to the codec from the driver, you can + call the following functions: + <function>snd_ac97_write()</function>, + <function>snd_ac97_read()</function>, + <function>snd_ac97_update()</function> and + <function>snd_ac97_update_bits()</function>. + </para> + + <para> + Both <function>snd_ac97_write()</function> and + <function>snd_ac97_update()</function> functions are used to + set a value to the given register + (<constant>AC97_XXX</constant>). The difference between them is + that <function>snd_ac97_update()</function> doesn't write a + value if the given value has been already set, while + <function>snd_ac97_write()</function> always rewrites the + value. + + <informalexample> + <programlisting> +<![CDATA[ + snd_ac97_write(ac97, AC97_MASTER, 0x8080); + snd_ac97_update(ac97, AC97_MASTER, 0x8080); +]]> + </programlisting> + </informalexample> + </para> + + <para> + <function>snd_ac97_read()</function> is used to read the value + of the given register. For example, + + <informalexample> + <programlisting> +<![CDATA[ + value = snd_ac97_read(ac97, AC97_MASTER); +]]> + </programlisting> + </informalexample> + </para> + + <para> + <function>snd_ac97_update_bits()</function> is used to update + some bits of the given register. + + <informalexample> + <programlisting> +<![CDATA[ + snd_ac97_update_bits(ac97, reg, mask, value); +]]> + </programlisting> + </informalexample> + </para> + + <para> + Also, there is a function to change the sample rate (of a + certain register such as + <constant>AC97_PCM_FRONT_DAC_RATE</constant>) when VRA or + DRA is supported by the codec: + <function>snd_ac97_set_rate()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The following registers are available for setting the rate: + <constant>AC97_PCM_MIC_ADC_RATE</constant>, + <constant>AC97_PCM_FRONT_DAC_RATE</constant>, + <constant>AC97_PCM_LR_ADC_RATE</constant>, + <constant>AC97_SPDIF</constant>. When the + <constant>AC97_SPDIF</constant> is specified, the register is + not really changed but the corresponding IEC958 status bits will + be updated. + </para> + </section> + + <section id="api-ac97-clock-adjustment"> + <title>Clock Adjustment</title> + <para> + On some chip, the clock of the codec isn't 48000 but using a + PCI clock (to save a quartz!). In this case, change the field + bus->clock to the corresponding + value. For example, intel8x0 + and es1968 drivers have the auto-measurement function of the + clock. + </para> + </section> + + <section id="api-ac97-proc-files"> + <title>Proc Files</title> + <para> + The ALSA AC97 interface will create a proc file such as + <filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and + <filename>ac97#0-0+regs</filename>. You can refer to these files to + see the current status and registers of the codec. + </para> + </section> + + <section id="api-ac97-multiple-codecs"> + <title>Multiple Codecs</title> + <para> + When there are several codecs on the same card, you need to + call <function>snd_ac97_new()</function> multiple times with + ac97.num=1 or greater. The <structfield>num</structfield> field + specifies the codec + number. + </para> + + <para> + If you have set up multiple codecs, you need to either write + different callbacks for each codec or check + ac97->num in the + callback routines. + </para> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- MIDI (MPU401-UART) Interface --> +<!-- ****************************************************** --> + <chapter id="midi-interface"> + <title>MIDI (MPU401-UART) Interface</title> + + <section id="midi-interface-general"> + <title>General</title> + <para> + Many soundcards have built-in MIDI (MPU401-UART) + interfaces. When the soundcard supports the standard MPU401-UART + interface, most likely you can use the ALSA MPU401-UART API. The + MPU401-UART API is defined in + <filename><sound/mpu401.h></filename>. + </para> + + <para> + Some soundchips have similar but a little bit different + implementation of mpu401 stuff. For example, emu10k1 has its own + mpu401 routines. + </para> + </section> + + <section id="midi-interface-constructor"> + <title>Constructor</title> + <para> + For creating a rawmidi object, call + <function>snd_mpu401_uart_new()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_rawmidi_t *rmidi; + snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated, + irq, irq_flags, &rmidi); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The first argument is the card pointer, and the second is the + index of this component. You can create up to 8 rawmidi + devices. + </para> + + <para> + The third argument is the type of the hardware, + <constant>MPU401_HW_XXX</constant>. If it's not a special one, + you can use <constant>MPU401_HW_MPU401</constant>. + </para> + + <para> + The 4th argument is the i/o port address. Many + backward-compatible MPU401 has an i/o port such as 0x330. Or, it + might be a part of its own PCI i/o region. It depends on the + chip design. + </para> + + <para> + When the i/o port address above is a part of the PCI i/o + region, the MPU401 i/o port might have been already allocated + (reserved) by the driver itself. In such a case, pass non-zero + to the 5th argument + (<parameter>integrated</parameter>). Otherwise, pass 0 to it, + and + the mpu401-uart layer will allocate the i/o ports by itself. + </para> + + <para> + Usually, the port address corresponds to the command port and + port + 1 corresponds to the data port. If not, you may change + the <structfield>cport</structfield> field of + <type>mpu401_t</type> manually + afterward. However, <type>mpu401_t</type> pointer is not + returned explicitly by + <function>snd_mpu401_uart_new()</function>. You need to cast + rmidi->private_data to + <type>mpu401_t</type> explicitly, + + <informalexample> + <programlisting> +<![CDATA[ + mpu401_t *mpu; + mpu = rmidi->private_data; +]]> + </programlisting> + </informalexample> + + and reset the cport as you like: + + <informalexample> + <programlisting> +<![CDATA[ + mpu->cport = my_own_control_port; +]]> + </programlisting> + </informalexample> + </para> + + <para> + The 6th argument specifies the irq number for UART. If the irq + is already allocated, pass 0 to the 7th argument + (<parameter>irq_flags</parameter>). Otherwise, pass the flags + for irq allocation + (<constant>SA_XXX</constant> bits) to it, and the irq will be + reserved by the mpu401-uart layer. If the card doesn't generates + UART interrupts, pass -1 as the irq number. Then a timer + interrupt will be invoked for polling. + </para> + </section> + + <section id="midi-interface-interrupt-handler"> + <title>Interrupt Handler</title> + <para> + When the interrupt is allocated in + <function>snd_mpu401_uart_new()</function>, the private + interrupt handler is used, hence you don't have to do nothing + else than creating the mpu401 stuff. Otherwise, you have to call + <function>snd_mpu401_uart_interrupt()</function> explicitly when + a UART interrupt is invoked and checked in your own interrupt + handler. + </para> + + <para> + In this case, you need to pass the private_data of the + returned rawmidi object from + <function>snd_mpu401_uart_new()</function> as the second + argument of <function>snd_mpu401_uart_interrupt()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs); +]]> + </programlisting> + </informalexample> + </para> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- RawMIDI Interface --> +<!-- ****************************************************** --> + <chapter id="rawmidi-interface"> + <title>RawMIDI Interface</title> + + <section id="rawmidi-interface-overview"> + <title>Overview</title> + + <para> + The raw MIDI interface is used for hardware MIDI ports that can + be accessed as a byte stream. It is not used for synthesizer + chips that do not directly understand MIDI. + </para> + + <para> + ALSA handles file and buffer management. All you have to do is + to write some code to move data between the buffer and the + hardware. + </para> + + <para> + The rawmidi API is defined in + <filename><sound/rawmidi.h></filename>. + </para> + </section> + + <section id="rawmidi-interface-constructor"> + <title>Constructor</title> + + <para> + To create a rawmidi device, call the + <function>snd_rawmidi_new</function> function: + <informalexample> + <programlisting> +<![CDATA[ + snd_rawmidi_t *rmidi; + err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi); + if (err < 0) + return err; + rmidi->private_data = chip; + strcpy(rmidi->name, "My MIDI"); + rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | + SNDRV_RAWMIDI_INFO_INPUT | + SNDRV_RAWMIDI_INFO_DUPLEX; +]]> + </programlisting> + </informalexample> + </para> + + <para> + The first argument is the card pointer, the second argument is + the ID string. + </para> + + <para> + The third argument is the index of this component. You can + create up to 8 rawmidi devices. + </para> + + <para> + The fourth and fifth arguments are the number of output and + input substreams, respectively, of this device. (A substream is + the equivalent of a MIDI port.) + </para> + + <para> + Set the <structfield>info_flags</structfield> field to specify + the capabilities of the device. + Set <constant>SNDRV_RAWMIDI_INFO_OUTPUT</constant> if there is + at least one output port, + <constant>SNDRV_RAWMIDI_INFO_INPUT</constant> if there is at + least one input port, + and <constant>SNDRV_RAWMIDI_INFO_DUPLEX</constant> if the device + can handle output and input at the same time. + </para> + + <para> + After the rawmidi device is created, you need to set the + operators (callbacks) for each substream. There are helper + functions to set the operators for all substream of a device: + <informalexample> + <programlisting> +<![CDATA[ + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops); + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The operators are usually defined like this: + <informalexample> + <programlisting> +<![CDATA[ + static snd_rawmidi_ops_t snd_mymidi_output_ops = { + .open = snd_mymidi_output_open, + .close = snd_mymidi_output_close, + .trigger = snd_mymidi_output_trigger, + }; +]]> + </programlisting> + </informalexample> + These callbacks are explained in the <link + linkend="rawmidi-interface-callbacks"><citetitle>Callbacks</citetitle></link> + section. + </para> + + <para> + If there is more than one substream, you should give each one a + unique name: + <informalexample> + <programlisting> +<![CDATA[ + struct list_head *list; + snd_rawmidi_substream_t *substream; + list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { + substream = list_entry(list, snd_rawmidi_substream_t, list); + sprintf(substream->name, "My MIDI Port %d", substream->number + 1); + } + /* same for SNDRV_RAWMIDI_STREAM_INPUT */ +]]> + </programlisting> + </informalexample> + </para> + </section> + + <section id="rawmidi-interface-callbacks"> + <title>Callbacks</title> + + <para> + In all callbacks, the private data that you've set for the + rawmidi device can be accessed as + substream->rmidi->private_data. + <!-- <code> isn't available before DocBook 4.3 --> + </para> + + <para> + If there is more than one port, your callbacks can determine the + port index from the snd_rawmidi_substream_t data passed to each + callback: + <informalexample> + <programlisting> +<![CDATA[ + snd_rawmidi_substream_t *substream; + int index = substream->number; +]]> + </programlisting> + </informalexample> + </para> + + <section id="rawmidi-interface-op-open"> + <title><function>open</function> callback</title> + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_open(snd_rawmidi_substream_t *substream); +]]> + </programlisting> + </informalexample> + + <para> + This is called when a substream is opened. + You can initialize the hardware here, but you should not yet + start transmitting/receiving data. + </para> + </section> + + <section id="rawmidi-interface-op-close"> + <title><function>close</function> callback</title> + + <informalexample> + <programlisting> +<![CDATA[ + static int snd_xxx_close(snd_rawmidi_substream_t *substream); +]]> + </programlisting> + </informalexample> + + <para> + Guess what. + </para> + + <para> + The <function>open</function> and <function>close</function> + callbacks of a rawmidi device are serialized with a mutex, + and can sleep. + </para> + </section> + + <section id="rawmidi-interface-op-trigger-out"> + <title><function>trigger</function> callback for output + substreams</title> + + <informalexample> + <programlisting> +<![CDATA[ + static void snd_xxx_output_trigger(snd_rawmidi_substream_t *substream, int up); +]]> + </programlisting> + </informalexample> + + <para> + This is called with a nonzero <parameter>up</parameter> + parameter when there is some data in the substream buffer that + must be transmitted. + </para> + + <para> + To read data from the buffer, call + <function>snd_rawmidi_transmit_peek</function>. It will + return the number of bytes that have been read; this will be + less than the number of bytes requested when there is no more + data in the buffer. + After the data has been transmitted successfully, call + <function>snd_rawmidi_transmit_ack</function> to remove the + data from the substream buffer: + <informalexample> + <programlisting> +<![CDATA[ + unsigned char data; + while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) { + if (mychip_try_to_transmit(data)) + snd_rawmidi_transmit_ack(substream, 1); + else + break; /* hardware FIFO full */ + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + If you know beforehand that the hardware will accept data, you + can use the <function>snd_rawmidi_transmit</function> function + which reads some data and removes it from the buffer at once: + <informalexample> + <programlisting> +<![CDATA[ + while (mychip_transmit_possible()) { + unsigned char data; + if (snd_rawmidi_transmit(substream, &data, 1) != 1) + break; /* no more data */ + mychip_transmit(data); + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + If you know beforehand how many bytes you can accept, you can + use a buffer size greater than one with the + <function>snd_rawmidi_transmit*</function> functions. + </para> + + <para> + The <function>trigger</function> callback must not sleep. If + the hardware FIFO is full before the substream buffer has been + emptied, you have to continue transmitting data later, either + in an interrupt handler, or with a timer if the hardware + doesn't have a MIDI transmit interrupt. + </para> + + <para> + The <function>trigger</function> callback is called with a + zero <parameter>up</parameter> parameter when the transmission + of data should be aborted. + </para> + </section> + + <section id="rawmidi-interface-op-trigger-in"> + <title><function>trigger</function> callback for input + substreams</title> + + <informalexample> + <programlisting> +<![CDATA[ + static void snd_xxx_input_trigger(snd_rawmidi_substream_t *substream, int up); +]]> + </programlisting> + </informalexample> + + <para> + This is called with a nonzero <parameter>up</parameter> + parameter to enable receiving data, or with a zero + <parameter>up</parameter> parameter do disable receiving data. + </para> + + <para> + The <function>trigger</function> callback must not sleep; the + actual reading of data from the device is usually done in an + interrupt handler. + </para> + + <para> + When data reception is enabled, your interrupt handler should + call <function>snd_rawmidi_receive</function> for all received + data: + <informalexample> + <programlisting> +<![CDATA[ + void snd_mychip_midi_interrupt(...) + { + while (mychip_midi_available()) { + unsigned char data; + data = mychip_midi_read(); + snd_rawmidi_receive(substream, &data, 1); + } + } +]]> + </programlisting> + </informalexample> + </para> + </section> + + <section id="rawmidi-interface-op-drain"> + <title><function>drain</function> callback</title> + + <informalexample> + <programlisting> +<![CDATA[ + static void snd_xxx_drain(snd_rawmidi_substream_t *substream); +]]> + </programlisting> + </informalexample> + + <para> + This is only used with output substreams. This function should wait + until all data read from the substream buffer has been transmitted. + This ensures that the device can be closed and the driver unloaded + without losing data. + </para> + + <para> + This callback is optional. If you do not set + <structfield>drain</structfield> in the snd_rawmidi_ops_t + structure, ALSA will simply wait for 50 milliseconds + instead. + </para> + </section> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- Miscellaneous Devices --> +<!-- ****************************************************** --> + <chapter id="misc-devices"> + <title>Miscellaneous Devices</title> + + <section id="misc-devices-opl3"> + <title>FM OPL3</title> + <para> + The FM OPL3 is still used on many chips (mainly for backward + compatibility). ALSA has a nice OPL3 FM control layer, too. The + OPL3 API is defined in + <filename><sound/opl3.h></filename>. + </para> + + <para> + FM registers can be directly accessed through direct-FM API, + defined in <filename><sound/asound_fm.h></filename>. In + ALSA native mode, FM registers are accessed through + Hardware-Dependant Device direct-FM extension API, whereas in + OSS compatible mode, FM registers can be accessed with OSS + direct-FM compatible API on <filename>/dev/dmfmX</filename> device. + </para> + + <para> + For creating the OPL3 component, you have two functions to + call. The first one is a constructor for <type>opl3_t</type> + instance. + + <informalexample> + <programlisting> +<![CDATA[ + opl3_t *opl3; + snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX, + integrated, &opl3); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The first argument is the card pointer, the second one is the + left port address, and the third is the right port address. In + most cases, the right port is placed at the left port + 2. + </para> + + <para> + The fourth argument is the hardware type. + </para> + + <para> + When the left and right ports have been already allocated by + the card driver, pass non-zero to the fifth argument + (<parameter>integrated</parameter>). Otherwise, opl3 module will + allocate the specified ports by itself. + </para> + + <para> + When the accessing to the hardware requires special method + instead of the standard I/O access, you can create opl3 instance + separately with <function>snd_opl3_new()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + opl3_t *opl3; + snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3); +]]> + </programlisting> + </informalexample> + </para> + + <para> + Then set <structfield>command</structfield>, + <structfield>private_data</structfield> and + <structfield>private_free</structfield> for the private + access function, the private data and the destructor. + The l_port and r_port are not necessarily set. Only the + command must be set properly. You can retrieve the data + from opl3->private_data field. + </para> + + <para> + After creating the opl3 instance via <function>snd_opl3_new()</function>, + call <function>snd_opl3_init()</function> to initialize the chip to the + proper state. Note that <function>snd_opl3_create()</function> always + calls it internally. + </para> + + <para> + If the opl3 instance is created successfully, then create a + hwdep device for this opl3. + + <informalexample> + <programlisting> +<![CDATA[ + snd_hwdep_t *opl3hwdep; + snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The first argument is the <type>opl3_t</type> instance you + created, and the second is the index number, usually 0. + </para> + + <para> + The third argument is the index-offset for the sequencer + client assigned to the OPL3 port. When there is an MPU401-UART, + give 1 for here (UART always takes 0). + </para> + </section> + + <section id="misc-devices-hardware-dependent"> + <title>Hardware-Dependent Devices</title> + <para> + Some chips need the access from the user-space for special + controls or for loading the micro code. In such a case, you can + create a hwdep (hardware-dependent) device. The hwdep API is + defined in <filename><sound/hwdep.h></filename>. You can + find examples in opl3 driver or + <filename>isa/sb/sb16_csp.c</filename>. + </para> + + <para> + Creation of the <type>hwdep</type> instance is done via + <function>snd_hwdep_new()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_hwdep_t *hw; + snd_hwdep_new(card, "My HWDEP", 0, &hw); +]]> + </programlisting> + </informalexample> + + where the third argument is the index number. + </para> + + <para> + You can then pass any pointer value to the + <parameter>private_data</parameter>. + If you assign a private data, you should define the + destructor, too. The destructor function is set to + <structfield>private_free</structfield> field. + + <informalexample> + <programlisting> +<![CDATA[ + mydata_t *p = kmalloc(sizeof(*p), GFP_KERNEL); + hw->private_data = p; + hw->private_free = mydata_free; +]]> + </programlisting> + </informalexample> + + and the implementation of destructor would be: + + <informalexample> + <programlisting> +<![CDATA[ + static void mydata_free(snd_hwdep_t *hw) + { + mydata_t *p = hw->private_data; + kfree(p); + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + The arbitrary file operations can be defined for this + instance. The file operators are defined in + <parameter>ops</parameter> table. For example, assume that + this chip needs an ioctl. + + <informalexample> + <programlisting> +<![CDATA[ + hw->ops.open = mydata_open; + hw->ops.ioctl = mydata_ioctl; + hw->ops.release = mydata_release; +]]> + </programlisting> + </informalexample> + + And implement the callback functions as you like. + </para> + </section> + + <section id="misc-devices-IEC958"> + <title>IEC958 (S/PDIF)</title> + <para> + Usually the controls for IEC958 devices are implemented via + control interface. There is a macro to compose a name string for + IEC958 controls, <function>SNDRV_CTL_NAME_IEC958()</function> + defined in <filename><include/asound.h></filename>. + </para> + + <para> + There are some standard controls for IEC958 status bits. These + controls use the type <type>SNDRV_CTL_ELEM_TYPE_IEC958</type>, + and the size of element is fixed as 4 bytes array + (value.iec958.status[x]). For <structfield>info</structfield> + callback, you don't specify + the value field for this type (the count field must be set, + though). + </para> + + <para> + <quote>IEC958 Playback Con Mask</quote> is used to return the + bit-mask for the IEC958 status bits of consumer mode. Similarly, + <quote>IEC958 Playback Pro Mask</quote> returns the bitmask for + professional mode. They are read-only controls, and are defined + as MIXER controls (iface = + <constant>SNDRV_CTL_ELEM_IFACE_MIXER</constant>). + </para> + + <para> + Meanwhile, <quote>IEC958 Playback Default</quote> control is + defined for getting and setting the current default IEC958 + bits. Note that this one is usually defined as a PCM control + (iface = <constant>SNDRV_CTL_ELEM_IFACE_PCM</constant>), + although in some places it's defined as a MIXER control. + </para> + + <para> + In addition, you can define the control switches to + enable/disable or to set the raw bit mode. The implementation + will depend on the chip, but the control should be named as + <quote>IEC958 xxx</quote>, preferably using + <function>SNDRV_CTL_NAME_IEC958()</function> macro. + </para> + + <para> + You can find several cases, for example, + <filename>pci/emu10k1</filename>, + <filename>pci/ice1712</filename>, or + <filename>pci/cmipci.c</filename>. + </para> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- Buffer and Memory Management --> +<!-- ****************************************************** --> + <chapter id="buffer-and-memory"> + <title>Buffer and Memory Management</title> + + <section id="buffer-and-memory-buffer-types"> + <title>Buffer Types</title> + <para> + ALSA provides several different buffer allocation functions + depending on the bus and the architecture. All these have a + consistent API. The allocation of physically-contiguous pages is + done via + <function>snd_malloc_xxx_pages()</function> function, where xxx + is the bus type. + </para> + + <para> + The allocation of pages with fallback is + <function>snd_malloc_xxx_pages_fallback()</function>. This + function tries to allocate the specified pages but if the pages + are not available, it tries to reduce the page sizes until the + enough space is found. + </para> + + <para> + For releasing the space, call + <function>snd_free_xxx_pages()</function> function. + </para> + + <para> + Usually, ALSA drivers try to allocate and reserve + a large contiguous physical space + at the time the module is loaded for the later use. + This is called <quote>pre-allocation</quote>. + As already written, you can call the following function at the + construction of pcm instance (in the case of PCI bus). + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(pci), size, max); +]]> + </programlisting> + </informalexample> + + where <parameter>size</parameter> is the byte size to be + pre-allocated and the <parameter>max</parameter> is the maximal + size to be changed via <filename>prealloc</filename> proc file. + The allocator will try to get as large area as possible + within the given size. + </para> + + <para> + The second argument (type) and the third argument (device pointer) + are dependent on the bus. + In the case of ISA bus, pass <function>snd_dma_isa_data()</function> + as the third argument with <constant>SNDRV_DMA_TYPE_DEV</constant> type. + For the continuous buffer unrelated to the bus can be pre-allocated + with <constant>SNDRV_DMA_TYPE_CONTINUOUS</constant> type and the + <function>snd_dma_continuous_data(GFP_KERNEL)</function> device pointer, + whereh <constant>GFP_KERNEL</constant> is the kernel allocation flag to + use. For the SBUS, <constant>SNDRV_DMA_TYPE_SBUS</constant> and + <function>snd_dma_sbus_data(sbus_dev)</function> are used instead. + For the PCI scatter-gather buffers, use + <constant>SNDRV_DMA_TYPE_DEV_SG</constant> with + <function>snd_dma_pci_data(pci)</function> + (see the section + <link linkend="buffer-and-memory-non-contiguous"><citetitle>Non-Contiguous Buffers + </citetitle></link>). + </para> + + <para> + Once when the buffer is pre-allocated, you can use the + allocator in the <structfield>hw_params</structfield> callback + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_lib_malloc_pages(substream, size); +]]> + </programlisting> + </informalexample> + + Note that you have to pre-allocate to use this function. + </para> + </section> + + <section id="buffer-and-memory-external-hardware"> + <title>External Hardware Buffers</title> + <para> + Some chips have their own hardware buffers and the DMA + transfer from the host memory is not available. In such a case, + you need to either 1) copy/set the audio data directly to the + external hardware buffer, or 2) make an intermediate buffer and + copy/set the data from it to the external hardware buffer in + interrupts (or in tasklets, preferably). + </para> + + <para> + The first case works fine if the external hardware buffer is enough + large. This method doesn't need any extra buffers and thus is + more effective. You need to define the + <structfield>copy</structfield> and + <structfield>silence</structfield> callbacks for + the data transfer. However, there is a drawback: it cannot + be mmapped. The examples are GUS's GF1 PCM or emu8000's + wavetable PCM. + </para> + + <para> + The second case allows the mmap of the buffer, although you have + to handle an interrupt or a tasklet for transferring the data + from the intermediate buffer to the hardware buffer. You can find an + example in vxpocket driver. + </para> + + <para> + Another case is that the chip uses a PCI memory-map + region for the buffer instead of the host memory. In this case, + mmap is available only on certain architectures like intel. In + non-mmap mode, the data cannot be transferred as the normal + way. Thus you need to define <structfield>copy</structfield> and + <structfield>silence</structfield> callbacks as well + as in the cases above. The examples are found in + <filename>rme32.c</filename> and <filename>rme96.c</filename>. + </para> + + <para> + The implementation of <structfield>copy</structfield> and + <structfield>silence</structfield> callbacks depends upon + whether the hardware supports interleaved or non-interleaved + samples. The <structfield>copy</structfield> callback is + defined like below, a bit + differently depending whether the direction is playback or + capture: + + <informalexample> + <programlisting> +<![CDATA[ + static int playback_copy(snd_pcm_substream_t *substream, int channel, + snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count); + static int capture_copy(snd_pcm_substream_t *substream, int channel, + snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count); +]]> + </programlisting> + </informalexample> + </para> + + <para> + In the case of interleaved samples, the second argument + (<parameter>channel</parameter>) is not used. The third argument + (<parameter>pos</parameter>) points the + current position offset in frames. + </para> + + <para> + The meaning of the fourth argument is different between + playback and capture. For playback, it holds the source data + pointer, and for capture, it's the destination data pointer. + </para> + + <para> + The last argument is the number of frames to be copied. + </para> + + <para> + What you have to do in this callback is again different + between playback and capture directions. In the case of + playback, you do: copy the given amount of data + (<parameter>count</parameter>) at the specified pointer + (<parameter>src</parameter>) to the specified offset + (<parameter>pos</parameter>) on the hardware buffer. When + coded like memcpy-like way, the copy would be like: + + <informalexample> + <programlisting> +<![CDATA[ + my_memcpy(my_buffer + frames_to_bytes(runtime, pos), src, + frames_to_bytes(runtime, count)); +]]> + </programlisting> + </informalexample> + </para> + + <para> + For the capture direction, you do: copy the given amount of + data (<parameter>count</parameter>) at the specified offset + (<parameter>pos</parameter>) on the hardware buffer to the + specified pointer (<parameter>dst</parameter>). + + <informalexample> + <programlisting> +<![CDATA[ + my_memcpy(dst, my_buffer + frames_to_bytes(runtime, pos), + frames_to_bytes(runtime, count)); +]]> + </programlisting> + </informalexample> + + Note that both of the position and the data amount are given + in frames. + </para> + + <para> + In the case of non-interleaved samples, the implementation + will be a bit more complicated. + </para> + + <para> + You need to check the channel argument, and if it's -1, copy + the whole channels. Otherwise, you have to copy only the + specified channel. Please check + <filename>isa/gus/gus_pcm.c</filename> as an example. + </para> + + <para> + The <structfield>silence</structfield> callback is also + implemented in a similar way. + + <informalexample> + <programlisting> +<![CDATA[ + static int silence(snd_pcm_substream_t *substream, int channel, + snd_pcm_uframes_t pos, snd_pcm_uframes_t count); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The meanings of arguments are identical with the + <structfield>copy</structfield> + callback, although there is no <parameter>src/dst</parameter> + argument. In the case of interleaved samples, the channel + argument has no meaning, as well as on + <structfield>copy</structfield> callback. + </para> + + <para> + The role of <structfield>silence</structfield> callback is to + set the given amount + (<parameter>count</parameter>) of silence data at the + specified offset (<parameter>pos</parameter>) on the hardware + buffer. Suppose that the data format is signed (that is, the + silent-data is 0), and the implementation using a memset-like + function would be like: + + <informalexample> + <programlisting> +<![CDATA[ + my_memcpy(my_buffer + frames_to_bytes(runtime, pos), 0, + frames_to_bytes(runtime, count)); +]]> + </programlisting> + </informalexample> + </para> + + <para> + In the case of non-interleaved samples, again, the + implementation becomes a bit more complicated. See, for example, + <filename>isa/gus/gus_pcm.c</filename>. + </para> + </section> + + <section id="buffer-and-memory-non-contiguous"> + <title>Non-Contiguous Buffers</title> + <para> + If your hardware supports the page table like emu10k1 or the + buffer descriptors like via82xx, you can use the scatter-gather + (SG) DMA. ALSA provides an interface for handling SG-buffers. + The API is provided in <filename><sound/pcm.h></filename>. + </para> + + <para> + For creating the SG-buffer handler, call + <function>snd_pcm_lib_preallocate_pages()</function> or + <function>snd_pcm_lib_preallocate_pages_for_all()</function> + with <constant>SNDRV_DMA_TYPE_DEV_SG</constant> + in the PCM constructor like other PCI pre-allocator. + You need to pass the <function>snd_dma_pci_data(pci)</function>, + where pci is the struct <structname>pci_dev</structname> pointer + of the chip as well. + The <type>snd_sg_buf_t</type> instance is created as + substream->dma_private. You can cast + the pointer like: + + <informalexample> + <programlisting> +<![CDATA[ + snd_pcm_sgbuf_t *sgbuf = (snd_pcm_sgbuf_t*)substream->dma_private; +]]> + </programlisting> + </informalexample> + </para> + + <para> + Then call <function>snd_pcm_lib_malloc_pages()</function> + in <structfield>hw_params</structfield> callback + as well as in the case of normal PCI buffer. + The SG-buffer handler will allocate the non-contiguous kernel + pages of the given size and map them onto the virtually contiguous + memory. The virtual pointer is addressed in runtime->dma_area. + The physical address (runtime->dma_addr) is set to zero, + because the buffer is physically non-contigous. + The physical address table is set up in sgbuf->table. + You can get the physical address at a certain offset via + <function>snd_pcm_sgbuf_get_addr()</function>. + </para> + + <para> + When a SG-handler is used, you need to set + <function>snd_pcm_sgbuf_ops_page</function> as + the <structfield>page</structfield> callback. + (See <link linkend="pcm-interface-operators-page-callback"> + <citetitle>page callback section</citetitle></link>.) + </para> + + <para> + For releasing the data, call + <function>snd_pcm_lib_free_pages()</function> in the + <structfield>hw_free</structfield> callback as usual. + </para> + </section> + + <section id="buffer-and-memory-vmalloced"> + <title>Vmalloc'ed Buffers</title> + <para> + It's possible to use a buffer allocated via + <function>vmalloc</function>, for example, for an intermediate + buffer. Since the allocated pages are not contiguous, you need + to set the <structfield>page</structfield> callback to obtain + the physical address at every offset. + </para> + + <para> + The implementation of <structfield>page</structfield> callback + would be like this: + + <informalexample> + <programlisting> +<![CDATA[ + #include <linux/vmalloc.h> + + /* get the physical page pointer on the given offset */ + static struct page *mychip_page(snd_pcm_substream_t *substream, + unsigned long offset) + { + void *pageptr = substream->runtime->dma_area + offset; + return vmalloc_to_page(pageptr); + } +]]> + </programlisting> + </informalexample> + </para> + </section> + + </chapter> + + +<!-- ****************************************************** --> +<!-- Proc Interface --> +<!-- ****************************************************** --> + <chapter id="proc-interface"> + <title>Proc Interface</title> + <para> + ALSA provides an easy interface for procfs. The proc files are + very useful for debugging. I recommend you set up proc files if + you write a driver and want to get a running status or register + dumps. The API is found in + <filename><sound/info.h></filename>. + </para> + + <para> + For creating a proc file, call + <function>snd_card_proc_new()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_info_entry_t *entry; + int err = snd_card_proc_new(card, "my-file", &entry); +]]> + </programlisting> + </informalexample> + + where the second argument specifies the proc-file name to be + created. The above example will create a file + <filename>my-file</filename> under the card directory, + e.g. <filename>/proc/asound/card0/my-file</filename>. + </para> + + <para> + Like other components, the proc entry created via + <function>snd_card_proc_new()</function> will be registered and + released automatically in the card registration and release + functions. + </para> + + <para> + When the creation is successful, the function stores a new + instance at the pointer given in the third argument. + It is initialized as a text proc file for read only. For using + this proc file as a read-only text file as it is, set the read + callback with a private data via + <function>snd_info_set_text_ops()</function>. + + <informalexample> + <programlisting> +<![CDATA[ + snd_info_set_text_ops(entry, chip, read_size, my_proc_read); +]]> + </programlisting> + </informalexample> + + where the second argument (<parameter>chip</parameter>) is the + private data to be used in the callbacks. The third parameter + specifies the read buffer size and the fourth + (<parameter>my_proc_read</parameter>) is the callback function, which + is defined like + + <informalexample> + <programlisting> +<![CDATA[ + static void my_proc_read(snd_info_entry_t *entry, + snd_info_buffer_t *buffer); +]]> + </programlisting> + </informalexample> + + </para> + + <para> + In the read callback, use <function>snd_iprintf()</function> for + output strings, which works just like normal + <function>printf()</function>. For example, + + <informalexample> + <programlisting> +<![CDATA[ + static void my_proc_read(snd_info_entry_t *entry, + snd_info_buffer_t *buffer) + { + chip_t *chip = entry->private_data; + + snd_iprintf(buffer, "This is my chip!\n"); + snd_iprintf(buffer, "Port = %ld\n", chip->port); + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + The file permission can be changed afterwards. As default, it's + set as read only for all users. If you want to add the write + permission to the user (root as default), set like below: + + <informalexample> + <programlisting> +<![CDATA[ + entry->mode = S_IFREG | S_IRUGO | S_IWUSR; +]]> + </programlisting> + </informalexample> + + and set the write buffer size and the callback + + <informalexample> + <programlisting> +<![CDATA[ + entry->c.text.write_size = 256; + entry->c.text.write = my_proc_write; +]]> + </programlisting> + </informalexample> + </para> + + <para> + The buffer size for read is set to 1024 implicitly by + <function>snd_info_set_text_ops()</function>. It should suffice + in most cases (the size will be aligned to + <constant>PAGE_SIZE</constant> anyway), but if you need to handle + very large text files, you can set it explicitly, too. + + <informalexample> + <programlisting> +<![CDATA[ + entry->c.text.read_size = 65536; +]]> + </programlisting> + </informalexample> + </para> + + <para> + For the write callback, you can use + <function>snd_info_get_line()</function> to get a text line, and + <function>snd_info_get_str()</function> to retrieve a string from + the line. Some examples are found in + <filename>core/oss/mixer_oss.c</filename>, core/oss/and + <filename>pcm_oss.c</filename>. + </para> + + <para> + For a raw-data proc-file, set the attributes like the following: + + <informalexample> + <programlisting> +<![CDATA[ + static struct snd_info_entry_ops my_file_io_ops = { + .read = my_file_io_read, + }; + + entry->content = SNDRV_INFO_CONTENT_DATA; + entry->private_data = chip; + entry->c.ops = &my_file_io_ops; + entry->size = 4096; + entry->mode = S_IFREG | S_IRUGO; +]]> + </programlisting> + </informalexample> + </para> + + <para> + The callback is much more complicated than the text-file + version. You need to use a low-level i/o functions such as + <function>copy_from/to_user()</function> to transfer the + data. + + <informalexample> + <programlisting> +<![CDATA[ + static long my_file_io_read(snd_info_entry_t *entry, + void *file_private_data, + struct file *file, + char *buf, + unsigned long count, + unsigned long pos) + { + long size = count; + if (pos + size > local_max_size) + size = local_max_size - pos; + if (copy_to_user(buf, local_data + pos, size)) + return -EFAULT; + return size; + } +]]> + </programlisting> + </informalexample> + </para> + + </chapter> + + +<!-- ****************************************************** --> +<!-- Power Management --> +<!-- ****************************************************** --> + <chapter id="power-management"> + <title>Power Management</title> + <para> + If the chip is supposed to work with with suspend/resume + functions, you need to add the power-management codes to the + driver. The additional codes for the power-management should be + <function>ifdef</function>'ed with + <constant>CONFIG_PM</constant>. + </para> + + <para> + ALSA provides the common power-management layer. Each card driver + needs to have only low-level suspend and resume callbacks. + + <informalexample> + <programlisting> +<![CDATA[ + #ifdef CONFIG_PM + static int snd_my_suspend(snd_card_t *card, pm_message_t state) + { + .... // do things for suspsend + return 0; + } + static int snd_my_resume(snd_card_t *card) + { + .... // do things for suspsend + return 0; + } + #endif +]]> + </programlisting> + </informalexample> + </para> + + <para> + The scheme of the real suspend job is as following. + + <orderedlist> + <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem> + <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem> + <listitem><para>Save the register values if necessary.</para></listitem> + <listitem><para>Stop the hardware if necessary.</para></listitem> + <listitem><para>Disable the PCI device by calling <function>pci_disable_device()</function>.</para></listitem> + </orderedlist> + </para> + + <para> + A typical code would be like: + + <informalexample> + <programlisting> +<![CDATA[ + static int mychip_suspend(snd_card_t *card, pm_message_t state) + { + /* (1) */ + mychip_t *chip = card->pm_private_data; + /* (2) */ + snd_pcm_suspend_all(chip->pcm); + /* (3) */ + snd_mychip_save_registers(chip); + /* (4) */ + snd_mychip_stop_hardware(chip); + /* (5) */ + pci_disable_device(chip->pci); + return 0; + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + The scheme of the real resume job is as following. + + <orderedlist> + <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem> + <listitem><para>Enable the pci device again by calling + <function>pci_enable_device()</function>.</para></listitem> + <listitem><para>Re-initialize the chip.</para></listitem> + <listitem><para>Restore the saved registers if necessary.</para></listitem> + <listitem><para>Resume the mixer, e.g. calling + <function>snd_ac97_resume()</function>.</para></listitem> + <listitem><para>Restart the hardware (if any).</para></listitem> + </orderedlist> + </para> + + <para> + A typical code would be like: + + <informalexample> + <programlisting> +<![CDATA[ + static void mychip_resume(mychip_t *chip) + { + /* (1) */ + mychip_t *chip = card->pm_private_data; + /* (2) */ + pci_enable_device(chip->pci); + /* (3) */ + snd_mychip_reinit_chip(chip); + /* (4) */ + snd_mychip_restore_registers(chip); + /* (5) */ + snd_ac97_resume(chip->ac97); + /* (6) */ + snd_mychip_restart_chip(chip); + return 0; + } +]]> + </programlisting> + </informalexample> + </para> + + <para> + OK, we have all callbacks now. Let's set up them now. In the + initialization of the card, add the following: + + <informalexample> + <programlisting> +<![CDATA[ + static int __devinit snd_mychip_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) + { + .... + snd_card_t *card; + mychip_t *chip; + .... + snd_card_set_pm_callback(card, snd_my_suspend, snd_my_resume, chip); + .... + } +]]> + </programlisting> + </informalexample> + + Here you don't have to put ifdef CONFIG_PM around, since it's already + checked in the header and expanded to empty if not needed. + </para> + + <para> + If you need a space for saving the registers, you'll need to + allocate the buffer for it here, too, since it would be fatal + if you cannot allocate a memory in the suspend phase. + The allocated buffer should be released in the corresponding + destructor. + </para> + + <para> + And next, set suspend/resume callbacks to the pci_driver, + This can be done by passing a macro SND_PCI_PM_CALLBACKS + in the pci_driver struct. This macro is expanded to the correct + (global) callbacks if CONFIG_PM is set. + + <informalexample> + <programlisting> +<![CDATA[ + static struct pci_driver driver = { + .name = "My Chip", + .id_table = snd_my_ids, + .probe = snd_my_probe, + .remove = __devexit_p(snd_my_remove), + SND_PCI_PM_CALLBACKS + }; +]]> + </programlisting> + </informalexample> + </para> + + </chapter> + + +<!-- ****************************************************** --> +<!-- Module Parameters --> +<!-- ****************************************************** --> + <chapter id="module-parameters"> + <title>Module Parameters</title> + <para> + There are standard module options for ALSA. At least, each + module should have <parameter>index</parameter>, + <parameter>id</parameter> and <parameter>enable</parameter> + options. + </para> + + <para> + If the module supports multiple cards (usually up to + 8 = <constant>SNDRV_CARDS</constant> cards), they should be + arrays. The default initial values are defined already as + constants for ease of programming: + + <informalexample> + <programlisting> +<![CDATA[ + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; + static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; + static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +]]> + </programlisting> + </informalexample> + </para> + + <para> + If the module supports only a single card, they could be single + variables, instead. <parameter>enable</parameter> option is not + always necessary in this case, but it wouldn't be so bad to have a + dummy option for compatibility. + </para> + + <para> + The module parameters must be declared with the standard + <function>module_param()()</function>, + <function>module_param_array()()</function> and + <function>MODULE_PARM_DESC()</function> macros. + </para> + + <para> + The typical coding would be like below: + + <informalexample> + <programlisting> +<![CDATA[ + #define CARD_NAME "My Chip" + + module_param_array(index, int, NULL, 0444); + MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); + module_param_array(id, charp, NULL, 0444); + MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); + module_param_array(enable, bool, NULL, 0444); + MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); +]]> + </programlisting> + </informalexample> + </para> + + <para> + Also, don't forget to define the module description, classes, + license and devices. Especially, the recent modprobe requires to + define the module license as GPL, etc., otherwise the system is + shown as <quote>tainted</quote>. + + <informalexample> + <programlisting> +<![CDATA[ + MODULE_DESCRIPTION("My Chip"); + MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE("{{Vendor,My Chip Name}}"); +]]> + </programlisting> + </informalexample> + </para> + + </chapter> + + +<!-- ****************************************************** --> +<!-- How To Put Your Driver --> +<!-- ****************************************************** --> + <chapter id="how-to-put-your-driver"> + <title>How To Put Your Driver Into ALSA Tree</title> + <section> + <title>General</title> + <para> + So far, you've learned how to write the driver codes. + And you might have a question now: how to put my own + driver into the ALSA driver tree? + Here (finally :) the standard procedure is described briefly. + </para> + + <para> + Suppose that you'll create a new PCI driver for the card + <quote>xyz</quote>. The card module name would be + snd-xyz. The new driver is usually put into alsa-driver + tree, <filename>alsa-driver/pci</filename> directory in + the case of PCI cards. + Then the driver is evaluated, audited and tested + by developers and users. After a certain time, the driver + will go to alsa-kernel tree (to the corresponding directory, + such as <filename>alsa-kernel/pci</filename>) and eventually + integrated into Linux 2.6 tree (the directory would be + <filename>linux/sound/pci</filename>). + </para> + + <para> + In the following sections, the driver code is supposed + to be put into alsa-driver tree. The two cases are assumed: + a driver consisting of a single source file and one consisting + of several source files. + </para> + </section> + + <section> + <title>Driver with A Single Source File</title> + <para> + <orderedlist> + <listitem> + <para> + Modify alsa-driver/pci/Makefile + </para> + + <para> + Suppose you have a file xyz.c. Add the following + two lines + <informalexample> + <programlisting> +<![CDATA[ + snd-xyz-objs := xyz.o + obj-$(CONFIG_SND_XYZ) += snd-xyz.o +]]> + </programlisting> + </informalexample> + </para> + </listitem> + + <listitem> + <para> + Create the Kconfig entry + </para> + + <para> + Add the new entry of Kconfig for your xyz driver. + <informalexample> + <programlisting> +<![CDATA[ + config SND_XYZ + tristate "Foobar XYZ" + depends on SND + select SND_PCM + help + Say Y here to include support for Foobar XYZ soundcard. + + To compile this driver as a module, choose M here: the module + will be called snd-xyz. +]]> + </programlisting> + </informalexample> + + the line, select SND_PCM, specifies that the driver xyz supports + PCM. In addition to SND_PCM, the following components are + supported for select command: + SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART, + SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC. + Add the select command for each supported component. + </para> + + <para> + Note that some selections imply the lowlevel selections. + For example, PCM includes TIMER, MPU401_UART includes RAWMIDI, + AC97_CODEC includes PCM, and OPL3_LIB includes HWDEP. + You don't need to give the lowlevel selections again. + </para> + + <para> + For the details of Kconfig script, refer to the kbuild + documentation. + </para> + + </listitem> + + <listitem> + <para> + Run cvscompile script to re-generate the configure script and + build the whole stuff again. + </para> + </listitem> + </orderedlist> + </para> + </section> + + <section> + <title>Drivers with Several Source Files</title> + <para> + Suppose that the driver snd-xyz have several source files. + They are located in the new subdirectory, + pci/xyz. + + <orderedlist> + <listitem> + <para> + Add a new directory (<filename>xyz</filename>) in + <filename>alsa-driver/pci/Makefile</filename> like below + + <informalexample> + <programlisting> +<![CDATA[ + obj-$(CONFIG_SND) += xyz/ +]]> + </programlisting> + </informalexample> + </para> + </listitem> + + <listitem> + <para> + Under the directory <filename>xyz</filename>, create a Makefile + + <example> + <title>Sample Makefile for a driver xyz</title> + <programlisting> +<![CDATA[ + ifndef SND_TOPDIR + SND_TOPDIR=../.. + endif + + include $(SND_TOPDIR)/toplevel.config + include $(SND_TOPDIR)/Makefile.conf + + snd-xyz-objs := xyz.o abc.o def.o + + obj-$(CONFIG_SND_XYZ) += snd-xyz.o + + include $(SND_TOPDIR)/Rules.make +]]> + </programlisting> + </example> + </para> + </listitem> + + <listitem> + <para> + Create the Kconfig entry + </para> + + <para> + This procedure is as same as in the last section. + </para> + </listitem> + + <listitem> + <para> + Run cvscompile script to re-generate the configure script and + build the whole stuff again. + </para> + </listitem> + </orderedlist> + </para> + </section> + + </chapter> + +<!-- ****************************************************** --> +<!-- Useful Functions --> +<!-- ****************************************************** --> + <chapter id="useful-functions"> + <title>Useful Functions</title> + + <section id="useful-functions-snd-printk"> + <title><function>snd_printk()</function> and friends</title> + <para> + ALSA provides a verbose version of + <function>printk()</function> function. If a kernel config + <constant>CONFIG_SND_VERBOSE_PRINTK</constant> is set, this + function prints the given message together with the file name + and the line of the caller. The <constant>KERN_XXX</constant> + prefix is processed as + well as the original <function>printk()</function> does, so it's + recommended to add this prefix, e.g. + + <informalexample> + <programlisting> +<![CDATA[ + snd_printk(KERN_ERR "Oh my, sorry, it's extremely bad!\n"); +]]> + </programlisting> + </informalexample> + </para> + + <para> + There are also <function>printk()</function>'s for + debugging. <function>snd_printd()</function> can be used for + general debugging purposes. If + <constant>CONFIG_SND_DEBUG</constant> is set, this function is + compiled, and works just like + <function>snd_printk()</function>. If the ALSA is compiled + without the debugging flag, it's ignored. + </para> + + <para> + <function>snd_printdd()</function> is compiled in only when + <constant>CONFIG_SND_DEBUG_DETECT</constant> is set. Please note + that <constant>DEBUG_DETECT</constant> is not set as default + even if you configure the alsa-driver with + <option>--with-debug=full</option> option. You need to give + explicitly <option>--with-debug=detect</option> option instead. + </para> + </section> + + <section id="useful-functions-snd-assert"> + <title><function>snd_assert()</function></title> + <para> + <function>snd_assert()</function> macro is similar with the + normal <function>assert()</function> macro. For example, + + <informalexample> + <programlisting> +<![CDATA[ + snd_assert(pointer != NULL, return -EINVAL); +]]> + </programlisting> + </informalexample> + </para> + + <para> + The first argument is the expression to evaluate, and the + second argument is the action if it fails. When + <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an + error message such as <computeroutput>BUG? (xxx) (called from + yyy)</computeroutput>. When no debug flag is set, this is + ignored. + </para> + </section> + + <section id="useful-functions-snd-runtime-check"> + <title><function>snd_runtime_check()</function></title> + <para> + This macro is quite similar with + <function>snd_assert()</function>. Unlike + <function>snd_assert()</function>, the expression is always + evaluated regardless of + <constant>CONFIG_SND_DEBUG</constant>. When + <constant>CONFIG_SND_DEBUG</constant> is set, the macro will + show a message like <computeroutput>ERROR (xx) (called from + yyy)</computeroutput>. + </para> + </section> + + <section id="useful-functions-snd-bug"> + <title><function>snd_BUG()</function></title> + <para> + It calls <function>snd_assert(0,)</function> -- that is, just + prints the error message at the point. It's useful to show that + a fatal error happens there. + </para> + </section> + </chapter> + + +<!-- ****************************************************** --> +<!-- Acknowledgments --> +<!-- ****************************************************** --> + <chapter id="acknowledments"> + <title>Acknowledgments</title> + <para> + I would like to thank Phil Kerr for his help for improvement and + corrections of this document. + </para> + <para> + Kevin Conder reformatted the original plain-text to the + DocBook format. + </para> + <para> + Giuliano Pochini corrected typos and contributed the example codes + in the hardware constraints section. + </para> + </chapter> + + +</book> diff --git a/Documentation/sound/alsa/Joystick.txt b/Documentation/sound/alsa/Joystick.txt new file mode 100644 index 000000000000..ccda41b10f8a --- /dev/null +++ b/Documentation/sound/alsa/Joystick.txt @@ -0,0 +1,86 @@ +Analog Joystick Support on ALSA Drivers +======================================= + Oct. 14, 2003 + Takashi Iwai <tiwai@suse.de> + +General +------- + +First of all, you need to enable GAMEPORT support on Linux kernel for +using a joystick with the ALSA driver. For the details of gameport +support, refer to Documentation/input/joystick.txt. + +The joystick support of ALSA drivers is different between ISA and PCI +cards. In the case of ISA (PnP) cards, it's usually handled by the +independent module (ns558). Meanwhile, the ALSA PCI drivers have the +built-in gameport support. Hence, when the ALSA PCI driver is built +in the kernel, CONFIG_GAMEPORT must be 'y', too. Otherwise, the +gameport support on that card will be (silently) disabled. + +Some adapter modules probe the physical connection of the device at +the load time. It'd be safer to plug in the joystick device before +loading the module. + + +PCI Cards +--------- + +For PCI cards, the joystick is enabled when the appropriate module +option is specified. Some drivers don't need options, and the +joystick support is always enabled. In the former ALSA version, there +was a dynamic control API for the joystick activation. It was +changed, however, to the static module options because of the system +stability and the resource management. + +The following PCI drivers support the joystick natively. + + Driver Module Option Available Values + --------------------------------------------------------------------------- + als4000 joystick_port 0 = disable (default), 1 = auto-detect, + manual: any address (e.g. 0x200) + au88x0 N/A N/A + azf3328 joystick 0 = disable, 1 = enable, -1 = auto (default) + ens1370 joystick 0 = disable (default), 1 = enable + ens1371 joystick_port 0 = disable (default), 1 = auto-detect, + manual: 0x200, 0x208, 0x210, 0x218 + cmipci joystick_port 0 = disable (default), 1 = auto-detect, + manual: any address (e.g. 0x200) + cs4281 N/A N/A + cs46xx N/A N/A + es1938 N/A N/A + es1968 joystick 0 = disable (default), 1 = enable + sonicvibes N/A N/A + trident N/A N/A + via82xx(*1) joystick 0 = disable (default), 1 = enable + ymfpci joystick_port 0 = disable (default), 1 = auto-detect, + manual: 0x201, 0x202, 0x204, 0x205(*2) + --------------------------------------------------------------------------- + + *1) VIA686A/B only + *2) With YMF744/754 chips, the port address can be chosen arbitrarily + +The following drivers don't support gameport natively, but there are +additional modules. Load the corresponding module to add the gameport +support. + + Driver Additional Module + ----------------------------- + emu10k1 emu10k1-gp + fm801 fm801-gp + ----------------------------- + +Note: the "pcigame" and "cs461x" modules are for the OSS drivers only. + These ALSA drivers (cs46xx, trident and au88x0) have the + built-in gameport support. + +As mentioned above, ALSA PCI drivers have the built-in gameport +support, so you don't have to load ns558 module. Just load "joydev" +and the appropriate adapter module (e.g. "analog"). + + +ISA Cards +--------- + +ALSA ISA drivers don't have the built-in gameport support. +Instead, you need to load "ns558" module in addition to "joydev" and +the adapter module (e.g. "analog"). diff --git a/Documentation/sound/alsa/MIXART.txt b/Documentation/sound/alsa/MIXART.txt new file mode 100644 index 000000000000..5cb970612870 --- /dev/null +++ b/Documentation/sound/alsa/MIXART.txt @@ -0,0 +1,100 @@ + Alsa driver for Digigram miXart8 and miXart8AES/EBU soundcards + Digigram <alsa@digigram.com> + + +GENERAL +======= + +The miXart8 is a multichannel audio processing and mixing soundcard +that has 4 stereo audio inputs and 4 stereo audio outputs. +The miXart8AES/EBU is the same with a add-on card that offers further +4 digital stereo audio inputs and outputs. +Furthermore the add-on card offers external clock synchronisation +(AES/EBU, Word Clock, Time Code and Video Synchro) + +The mainboard has a PowerPC that offers onboard mpeg encoding and +decoding, samplerate conversions and various effects. + +The driver don't work properly at all until the certain firmwares +are loaded, i.e. no PCM nor mixer devices will appear. +Use the mixartloader that can be found in the alsa-tools package. + + +VERSION 0.1.0 +============= + +One miXart8 board will be represented as 4 alsa cards, each with 1 +stereo analog capture 'pcm0c' and 1 stereo analog playback 'pcm0p' device. +With a miXart8AES/EBU there is in addition 1 stereo digital input +'pcm1c' and 1 stereo digital output 'pcm1p' per card. + +Formats +------- +U8, S16_LE, S16_BE, S24_3LE, S24_3BE, FLOAT_LE, FLOAT_BE +Sample rates : 8000 - 48000 Hz continously + +Playback +-------- +For instance the playback devices are configured to have max. 4 +substreams performing hardware mixing. This could be changed to a +maximum of 24 substreams if wished. +Mono files will be played on the left and right channel. Each channel +can be muted for each stream to use 8 analog/digital outputs seperately. + +Capture +------- +There is one substream per capture device. For instance only stereo +formats are supported. + +Mixer +----- +<Master> and <Master Capture> : analog volume control of playback and capture PCM. +<PCM 0-3> and <PCM Capture> : digital volume control of each analog substream. +<AES 0-3> and <AES Capture> : digital volume control of each AES/EBU substream. +<Monitoring> : Loopback from 'pcm0c' to 'pcm0p' with digital volume +and mute control. + +Rem : for best audio quality try to keep a 0 attenuation on the PCM +and AES volume controls which is set by 219 in the range from 0 to 255 +(about 86% with alsamixer) + + +NOT YET IMPLEMENTED +=================== + +- external clock support (AES/EBU, Word Clock, Time Code, Video Sync) +- MPEG audio formats +- mono record +- on-board effects and samplerate conversions +- linked streams + + +FIRMWARE +======== + +[As of 2.6.11, the firmware can be loaded automatically with hotplug + when CONFIG_FW_LOADER is set. The mixartloader is necessary only + for older versions or when you build the driver into kernel.] + +For loading the firmware automatically after the module is loaded, use +the post-install command. For example, add the following entry to +/etc/modprobe.conf for miXart driver: + + install snd-mixart /sbin/modprobe --first-time -i snd-mixart && \ + /usr/bin/mixartloader +(for 2.2/2.4 kernels, add "post-install snd-mixart /usr/bin/vxloader" to + /etc/modules.conf, instead.) + +The firmware binaries are installed on /usr/share/alsa/firmware +(or /usr/local/share/alsa/firmware, depending to the prefix option of +configure). There will be a miXart.conf file, which define the dsp image +files. + +The firmware files are copyright by Digigram SA + + +COPYRIGHT +========= + +Copyright (c) 2003 Digigram SA <alsa@digigram.com> +Distributalbe under GPL. diff --git a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt new file mode 100644 index 000000000000..ec2a02541d5b --- /dev/null +++ b/Documentation/sound/alsa/OSS-Emulation.txt @@ -0,0 +1,297 @@ + NOTES ON KERNEL OSS-EMULATION + ============================= + + Jan. 22, 2004 Takashi Iwai <tiwai@suse.de> + + +Modules +======= + +ALSA provides a powerful OSS emulation on the kernel. +The OSS emulation for PCM, mixer and sequencer devices is implemented +as add-on kernel modules, snd-pcm-oss, snd-mixer-oss and snd-seq-oss. +When you need to access the OSS PCM, mixer or sequencer devices, the +corresponding module has to be loaded. + +These modules are loaded automatically when the corresponding service +is called. The alias is defined sound-service-x-y, where x and y are +the card number and the minor unit number. Usually you don't have to +define these aliases by yourself. + +Only necessary step for auto-loading of OSS modules is to define the +card alias in /etc/modprobe.conf, such as + + alias sound-slot-0 snd-emu10k1 + +As the second card, define sound-slot-1 as well. +Note that you can't use the aliased name as the target name (i.e. +"alias sound-slot-0 snd-card-0" doesn't work any more like the old +modutils). + +The currently available OSS configuration is shown in +/proc/asound/oss/sndstat. This shows in the same syntax of +/dev/sndstat, which is available on the commercial OSS driver. +On ALSA, you can symlink /dev/sndstat to this proc file. + +Please note that the devices listed in this proc file appear only +after the corresponding OSS-emulation module is loaded. Don't worry +even if "NOT ENABLED IN CONFIG" is shown in it. + + +Device Mapping +============== + +ALSA supports the following OSS device files: + + PCM: + /dev/dspX + /dev/adspX + + Mixer: + /dev/mixerX + + MIDI: + /dev/midi0X + /dev/amidi0X + + Sequencer: + /dev/sequencer + /dev/sequencer2 (aka /dev/music) + +where X is the card number from 0 to 7. + +(NOTE: Some distributions have the device files like /dev/midi0 and + /dev/midi1. They are NOT for OSS but for tclmidi, which is + a totally different thing.) + +Unlike the real OSS, ALSA cannot use the device files more than the +assigned ones. For example, the first card cannot use /dev/dsp1 or +/dev/dsp2, but only /dev/dsp0 and /dev/adsp0. + +As seen above, PCM and MIDI may have two devices. Usually, the first +PCM device (hw:0,0 in ALSA) is mapped to /dev/dsp and the secondary +device (hw:0,1) to /dev/adsp (if available). For MIDI, /dev/midi and +/dev/amidi, respectively. + +You can change this device mapping via the module options of +snd-pcm-oss and snd-rawmidi. In the case of PCM, the following +options are available for snd-pcm-oss: + + dsp_map PCM device number assigned to /dev/dspX + (default = 0) + adsp_map PCM device number assigned to /dev/adspX + (default = 1) + +For example, to map the third PCM device (hw:0,2) to /dev/adsp0, +define like this: + + options snd-pcm-oss adsp_map=2 + +The options take arrays. For configuring the second card, specify +two entries separated by comma. For example, to map the third PCM +device on the second card to /dev/adsp1, define like below: + + options snd-pcm-oss adsp_map=0,2 + +To change the mapping of MIDI devices, the following options are +available for snd-rawmidi: + + midi_map MIDI device number assigned to /dev/midi0X + (default = 0) + amidi_map MIDI device number assigned to /dev/amidi0X + (default = 1) + +For example, to assign the third MIDI device on the first card to +/dev/midi00, define as follows: + + options snd-rawmidi midi_map=2 + + +PCM Mode +======== + +As default, ALSA emulates the OSS PCM with so-called plugin layer, +i.e. tries to convert the sample format, rate or channels +automatically when the card doesn't support it natively. +This will lead to some problems for some applications like quake or +wine, especially if they use the card only in the MMAP mode. + +In such a case, you can change the behavior of PCM per application by +writing a command to the proc file. There is a proc file for each PCM +stream, /proc/asound/cardX/pcmY[cp]/oss, where X is the card number +(zero-based), Y the PCM device number (zero-based), and 'p' is for +playback and 'c' for capture, respectively. Note that this proc file +exists only after snd-pcm-oss module is loaded. + +The command sequence has the following syntax: + + app_name fragments fragment_size [options] + +app_name is the name of application with (higher priority) or without +path. +fragments specifies the number of fragments or zero if no specific +number is given. +fragment_size is the size of fragment in bytes or zero if not given. +options is the optional parameters. The following options are +available: + + disable the application tries to open a pcm device for + this channel but does not want to use it. + direct don't use plugins + block force block open mode + non-block force non-block open mode + partial-frag write also partial fragments (affects playback only) + no-silence do not fill silence ahead to avoid clicks + +The disable option is useful when one stream direction (playback or +capture) is not handled correctly by the application although the +hardware itself does support both directions. +The direct option is used, as mentioned above, to bypass the automatic +conversion and useful for MMAP-applications. +For example, to playback the first PCM device without plugins for +quake, send a command via echo like the following: + + % echo "quake 0 0 direct" > /proc/asound/card0/pcm0p/oss + +While quake wants only playback, you may append the second command +to notify driver that only this direction is about to be allocated: + + % echo "quake 0 0 disable" > /proc/asound/card0/pcm0c/oss + +The permission of proc files depend on the module options of snd. +As default it's set as root, so you'll likely need to be superuser for +sending the command above. + +The block and non-block options are used to change the behavior of +opening the device file. + +As default, ALSA behaves as original OSS drivers, i.e. does not block +the file when it's busy. The -EBUSY error is returned in this case. + +This blocking behavior can be changed globally via nonblock_open +module option of snd-pcm-oss. For using the blocking mode as default +for OSS devices, define like the following: + + options snd-pcm-oss nonblock_open=0 + +The partial-frag and no-silence commands have been added recently. +Both commands are for optimization use only. The former command +specifies to invoke the write transfer only when the whole fragment is +filled. The latter stops writing the silence data ahead +automatically. Both are disabled as default. + +You can check the currently defined configuration by reading the proc +file. The read image can be sent to the proc file again, hence you +can save the current configuration + + % cat /proc/asound/card0/pcm0p/oss > /somewhere/oss-cfg + +and restore it like + + % cat /somewhere/oss-cfg > /proc/asound/card0/pcm0p/oss + +Also, for clearing all the current configuration, send "erase" command +as below: + + % echo "erase" > /proc/asound/card0/pcm0p/oss + + +Mixer Elements +============== + +Since ALSA has completely different mixer interface, the emulation of +OSS mixer is relatively complicated. ALSA builds up a mixer element +from several different ALSA (mixer) controls based on the name +string. For example, the volume element SOUND_MIXER_PCM is composed +from "PCM Playback Volume" and "PCM Playback Switch" controls for the +playback direction and from "PCM Capture Volume" and "PCM Capture +Switch" for the capture directory (if exists). When the PCM volume of +OSS is changed, all the volume and switch controls above are adjusted +automatically. + +As default, ALSA uses the following control for OSS volumes: + + OSS volume ALSA control Index + ----------------------------------------------------- + SOUND_MIXER_VOLUME Master 0 + SOUND_MIXER_BASS Tone Control - Bass 0 + SOUND_MIXER_TREBLE Tone Control - Treble 0 + SOUND_MIXER_SYNTH Synth 0 + SOUND_MIXER_PCM PCM 0 + SOUND_MIXER_SPEAKER PC Speaker 0 + SOUND_MIXER_LINE Line 0 + SOUND_MIXER_MIC Mic 0 + SOUND_MIXER_CD CD 0 + SOUND_MIXER_IMIX Monitor Mix 0 + SOUND_MIXER_ALTPCM PCM 1 + SOUND_MIXER_RECLEV (not assigned) + SOUND_MIXER_IGAIN Capture 0 + SOUND_MIXER_OGAIN Playback 0 + SOUND_MIXER_LINE1 Aux 0 + SOUND_MIXER_LINE2 Aux 1 + SOUND_MIXER_LINE3 Aux 2 + SOUND_MIXER_DIGITAL1 Digital 0 + SOUND_MIXER_DIGITAL2 Digital 1 + SOUND_MIXER_DIGITAL3 Digital 2 + SOUND_MIXER_PHONEIN Phone 0 + SOUND_MIXER_PHONEOUT Phone 1 + SOUND_MIXER_VIDEO Video 0 + SOUND_MIXER_RADIO Radio 0 + SOUND_MIXER_MONITOR Monitor 0 + +The second column is the base-string of the corresponding ALSA +control. In fact, the controls with "XXX [Playback|Capture] +[Volume|Switch]" will be checked in addition. + +The current assignment of these mixer elements is listed in the proc +file, /proc/asound/cardX/oss_mixer, which will be like the following + + VOLUME "Master" 0 + BASS "" 0 + TREBLE "" 0 + SYNTH "" 0 + PCM "PCM" 0 + ... + +where the first column is the OSS volume element, the second column +the base-string of the corresponding ALSA control, and the third the +control index. When the string is empty, it means that the +corresponding OSS control is not available. + +For changing the assignment, you can write the configuration to this +proc file. For example, to map "Wave Playback" to the PCM volume, +send the command like the following: + + % echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/oss_mixer + +The command is exactly as same as listed in the proc file. You can +change one or more elements, one volume per line. In the last +example, both "Wave Playback Volume" and "Wave Playback Switch" will +be affected when PCM volume is changed. + +Like the case of PCM proc file, the permission of proc files depend on +the module options of snd. you'll likely need to be superuser for +sending the command above. + +As well as in the case of PCM proc file, you can save and restore the +current mixer configuration by reading and writing the whole file +image. + + +Unsupported Features +==================== + +MMAP on ICE1712 driver +---------------------- +ICE1712 supports only the unconventional format, interleaved +10-channels 24bit (packed in 32bit) format. Therefore you cannot mmap +the buffer as the conventional (mono or 2-channels, 8 or 16bit) format +on OSS. + +USB devices +----------- +Some USB devices support only 24bit format packed in 3bytes. This +format is not supported by OSS and no conversion is provided by kernel +OSS emulation. You can use the user-space OSS emulation via libaoss +instead. + diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt new file mode 100644 index 000000000000..25c5d648aef6 --- /dev/null +++ b/Documentation/sound/alsa/Procfile.txt @@ -0,0 +1,191 @@ + Proc Files of ALSA Drivers + ========================== + Takashi Iwai <tiwai@suse.de> + +General +------- + +ALSA has its own proc tree, /proc/asound. Many useful information are +found in this tree. When you encounter a problem and need debugging, +check the files listed in the following sections. + +Each card has its subtree cardX, where X is from 0 to 7. The +card-specific files are stored in the card* subdirectories. + + +Global Information +------------------ + +cards + Shows the list of currently configured ALSA drivers, + index, the id string, short and long descriptions. + +version + Shows the version string and compile date. + +modules + Lists the module of each card + +devices + Lists the ALSA native device mappings. + +meminfo + Shows the status of allocated pages via ALSA drivers. + Appears only when CONFIG_SND_DEBUG=y. + +hwdep + Lists the currently available hwdep devices in format of + <card>-<device>: <name> + +pcm + Lists the currently available PCM devices in format of + <card>-<device>: <id>: <name> : <sub-streams> + +timer + Lists the currently available timer devices + + +oss/devices + Lists the OSS device mappings. + +oss/sndstat + Provides the output compatible with /dev/sndstat. + You can symlink this to /dev/sndstat. + + +Card Specific Files +------------------- + +The card-specific files are found in /proc/asound/card* directories. +Some drivers (e.g. cmipci) have their own proc entries for the +register dump, etc (e.g. /proc/asound/card*/cmipci shows the register +dump). These files would be really helpful for debugging. + +When PCM devices are available on this card, you can see directories +like pcm0p or pcm1c. They hold the PCM information for each PCM +stream. The number after 'pcm' is the PCM device number from 0, and +the last 'p' or 'c' means playback or capture direction. The files in +this subtree is described later. + +The status of MIDI I/O is found in midi* files. It shows the device +name and the received/transmitted bytes through the MIDI device. + +When the card is equipped with AC97 codecs, there are codec97#* +subdirectories (desribed later). + +When the OSS mixer emulation is enabled (and the module is loaded), +oss_mixer file appears here, too. This shows the current mapping of +OSS mixer elements to the ALSA control elements. You can change the +mapping by writing to this device. Read OSS-Emulation.txt for +details. + + +PCM Proc Files +-------------- + +card*/pcm*/info + The general information of this PCM device: card #, device #, + substreams, etc. + +card*/pcm*/xrun_debug + This file appears when CONFIG_SND_DEBUG=y. + This shows the status of xrun (= buffer overrun/xrun) debug of + ALSA PCM middle layer, as an integer from 0 to 2. The value + can be changed by writing to this file, such as + + # cat 2 > /proc/asound/card0/pcm0p/xrun_debug + + When this value is greater than 0, the driver will show the + messages to kernel log when an xrun is detected. The debug + message is shown also when the invalid H/W pointer is detected + at the update of periods (usually called from the interrupt + handler). + + When this value is greater than 1, the driver will show the + stack trace additionally. This may help the debugging. + +card*/pcm*/sub*/info + The general information of this PCM sub-stream. + +card*/pcm*/sub*/status + The current status of this PCM sub-stream, elapsed time, + H/W position, etc. + +card*/pcm*/sub*/hw_params + The hardware parameters set for this sub-stream. + +card*/pcm*/sub*/sw_params + The soft parameters set for this sub-stream. + +card*/pcm*/sub*/prealloc + The buffer pre-allocation information. + + +AC97 Codec Information +---------------------- + +card*/codec97#*/ac97#?-? + Shows the general information of this AC97 codec chip, such as + name, capabilities, set up. + +card*/codec97#0/ac97#?-?+regs + Shows the AC97 register dump. Useful for debugging. + + When CONFIG_SND_DEBUG is enabled, you can write to this file for + changing an AC97 register directly. Pass two hex numbers. + For example, + + # echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs + + +Sequencer Information +--------------------- + +seq/drivers + Lists the currently available ALSA sequencer drivers. + +seq/clients + Shows the list of currently available sequencer clinets and + ports. The connection status and the running status are shown + in this file, too. + +seq/queues + Lists the currently allocated/running sequener queues. + +seq/timer + Lists the currently allocated/running sequencer timers. + +seq/oss + Lists the OSS-compatible sequencer stuffs. + + +Help For Debugging? +------------------- + +When the problem is related with PCM, first try to turn on xrun_debug +mode. This will give you the kernel messages when and where xrun +happened. + +If it's really a bug, report it with the following information + + - the name of the driver/card, show in /proc/asound/cards + - the reigster dump, if available (e.g. card*/cmipci) + +when it's a PCM problem, + + - set-up of PCM, shown in hw_parms, sw_params, and status in the PCM + sub-stream directory + +when it's a mixer problem, + + - AC97 proc files, codec97#*/* files + +for USB audio/midi, + + - output of lsusb -v + - stream* files in card directory + + +The ALSA bug-tracking system is found at: + + https://bugtrack.alsa-project.org/alsa-bug/ diff --git a/Documentation/sound/alsa/SB-Live-mixer.txt b/Documentation/sound/alsa/SB-Live-mixer.txt new file mode 100644 index 000000000000..651adaf60473 --- /dev/null +++ b/Documentation/sound/alsa/SB-Live-mixer.txt @@ -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 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 Capture Volume',index=0 +name='Surround 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 LiveDrive 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 LiveDrive 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/VIA82xx-mixer.txt b/Documentation/sound/alsa/VIA82xx-mixer.txt new file mode 100644 index 000000000000..1b0ac06ba95d --- /dev/null +++ b/Documentation/sound/alsa/VIA82xx-mixer.txt @@ -0,0 +1,8 @@ + + VIA82xx mixer + ============= + +On many VIA82xx boards, the 'Input Source Select' mixer control does not work. +Setting it to 'Input2' on such boards will cause recording to hang, or fail +with EIO (input/output error) via OSS emulation. This control should be left +at 'Input1' for such cards. diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt new file mode 100644 index 000000000000..e9d07b8f1acb --- /dev/null +++ b/Documentation/sound/alsa/hda_codec.txt @@ -0,0 +1,299 @@ +Notes on Universal Interface for Intel High Definition Audio Codec +------------------------------------------------------------------ + +Takashi Iwai <tiwai@suse.de> + + +[Still a draft version] + + +General +======= + +The snd-hda-codec module supports the generic access function for the +High Definition (HD) audio codecs. It's designed to be independent +from the controller code like ac97 codec module. The real accessors +from/to the controller must be implemented in the lowlevel driver. + +The structure of this module is similar with ac97_codec module. +Each codec chip belongs to a bus class which communicates with the +controller. + + +Initialization of Bus Instance +============================== + +The card driver has to create struct hda_bus at first. The template +struct should be filled and passed to the constructor: + +struct hda_bus_template { + void *private_data; + struct pci_dev *pci; + const char *modelname; + struct hda_bus_ops ops; +}; + +The card driver can set and use the private_data field to retrieve its +own data in callback functions. The pci field is used when the patch +needs to check the PCI subsystem IDs, so on. For non-PCI system, it +doesn't have to be set, of course. +The modelname field specifies the board's specific configuration. The +string is passed to the codec parser, and it depends on the parser how +the string is used. +These fields, private_data, pci and modelname are all optional. + +The ops field contains the callback functions as the following: + +struct hda_bus_ops { + int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct, + unsigned int verb, unsigned int parm); + unsigned int (*get_response)(struct hda_codec *codec); + void (*private_free)(struct hda_bus *); +}; + +The command callback is called when the codec module needs to send a +VERB to the controller. It's always a single command. +The get_response callback is called when the codec requires the answer +for the last command. These two callbacks are mandatory and have to +be given. +The last, private_free callback, is optional. It's called in the +destructor to release any necessary data in the lowlevel driver. + +The bus instance is created via snd_hda_bus_new(). You need to pass +the card instance, the template, and the pointer to store the +resultant bus instance. + +int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp, + struct hda_bus **busp); + +It returns zero if successful. A negative return value means any +error during creation. + + +Creation of Codec Instance +========================== + +Each codec chip on the board is then created on the BUS instance. +To create a codec instance, call snd_hda_codec_new(). + +int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, + struct hda_codec **codecp); + +The first argument is the BUS instance, the second argument is the +address of the codec, and the last one is the pointer to store the +resultant codec instance (can be NULL if not needed). + +The codec is stored in a linked list of bus instance. You can follow +the codec list like: + + struct list_head *p; + struct hda_codec *codec; + list_for_each(p, &bus->codec_list) { + codec = list_entry(p, struct hda_codec, list); + ... + } + +The codec isn't initialized at this stage properly. The +initialization sequence is called when the controls are built later. + + +Codec Access +============ + +To access codec, use snd_codec_read() and snd_codec_write(). +snd_hda_param_read() is for reading parameters. +For writing a sequence of verbs, use snd_hda_sequence_write(). + +To retrieve the number of sub nodes connected to the given node, use +snd_hda_get_sub_nodes(). The connection list can be obtained via +snd_hda_get_connections() call. + +When an unsolicited event happens, pass the event via +snd_hda_queue_unsol_event() so that the codec routines will process it +later. + + +(Mixer) Controls +================ + +To create mixer controls of all codecs, call +snd_hda_build_controls(). It then builds the mixers and does +initialization stuff on each codec. + + +PCM Stuff +========= + +snd_hda_build_pcms() gives the necessary information to create PCM +streams. When it's called, each codec belonging to the bus stores +codec->num_pcms and codec->pcm_info fields. The num_pcms indicates +the number of elements in pcm_info array. The card driver is supposed +to traverse the codec linked list, read the pcm information in +pcm_info array, and build pcm instances according to them. + +The pcm_info array contains the following record: + +/* PCM information for each substream */ +struct hda_pcm_stream { + unsigned int substreams; /* number of substreams, 0 = not exist */ + unsigned int channels_min; /* min. number of channels */ + unsigned int channels_max; /* max. number of channels */ + hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */ + u32 rates; /* supported rates */ + u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */ + unsigned int maxbps; /* supported max. bit per sample */ + struct hda_pcm_ops ops; +}; + +/* for PCM creation */ +struct hda_pcm { + char *name; + struct hda_pcm_stream stream[2]; +}; + +The name can be passed to snd_pcm_new(). The stream field contains +the information for playback (SNDRV_PCM_STREAM_PLAYBACK = 0) and +capture (SNDRV_PCM_STREAM_CAPTURE = 1) directions. The card driver +should pass substreams to snd_pcm_new() for the number of substreams +to create. + +The channels_min, channels_max, rates and formats should be copied to +runtime->hw record. They and maxbps fields are used also to compute +the format value for the HDA codec and controller. Call +snd_hda_calc_stream_format() to get the format value. + +The ops field contains the following callback functions: + +struct hda_pcm_ops { + int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec, + snd_pcm_substream_t *substream); + int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec, + snd_pcm_substream_t *substream); + int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec, + unsigned int stream_tag, unsigned int format, + snd_pcm_substream_t *substream); + int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, + snd_pcm_substream_t *substream); +}; + +All are non-NULL, so you can call them safely without NULL check. + +The open callback should be called in PCM open after runtime->hw is +set up. It may override some setting and constraints additionally. +Similarly, the close callback should be called in the PCM close. + +The prepare callback should be called in PCM prepare. This will set +up the codec chip properly for the operation. The cleanup should be +called in hw_free to clean up the configuration. + +The caller should check the return value, at least for open and +prepare callbacks. When a negative value is returned, some error +occurred. + + +Proc Files +========== + +Each codec dumps the widget node information in +/proc/asound/card*/codec#* file. This information would be really +helpful for debugging. Please provide its contents together with the +bug report. + + +Power Management +================ + +It's simple: +Call snd_hda_suspend() in the PM suspend callback. +Call snd_hda_resume() in the PM resume callback. + + +Codec Preset (Patch) +==================== + +To set up and handle the codec functionality fully, each codec may +have a codec preset (patch). It's defined in struct hda_codec_preset: + + struct hda_codec_preset { + unsigned int id; + unsigned int mask; + unsigned int subs; + unsigned int subs_mask; + unsigned int rev; + const char *name; + int (*patch)(struct hda_codec *codec); + }; + +When the codec id and codec subsystem id match with the given id and +subs fields bitwise (with bitmask mask and subs_mask), the callback +patch is called. The patch callback should initialize the codec and +set the codec->patch_ops field. This is defined as below: + + struct hda_codec_ops { + int (*build_controls)(struct hda_codec *codec); + int (*build_pcms)(struct hda_codec *codec); + int (*init)(struct hda_codec *codec); + void (*free)(struct hda_codec *codec); + void (*unsol_event)(struct hda_codec *codec, unsigned int res); + #ifdef CONFIG_PM + int (*suspend)(struct hda_codec *codec, pm_message_t state); + int (*resume)(struct hda_codec *codec); + #endif + }; + +The build_controls callback is called from snd_hda_build_controls(). +Similarly, the build_pcms callback is called from +snd_hda_build_pcms(). The init callback is called after +build_controls to initialize the hardware. +The free callback is called as a destructor. + +The unsol_event callback is called when an unsolicited event is +received. + +The suspend and resume callbacks are for power management. + +Each entry can be NULL if not necessary to be called. + + +Generic Parser +============== + +When the device doesn't match with any given presets, the widgets are +parsed via th generic parser (hda_generic.c). Its support is +limited: no multi-channel support, for example. + + +Digital I/O +=========== + +Call snd_hda_create_spdif_out_ctls() from the patch to create controls +related with SPDIF out. In the patch resume callback, call +snd_hda_resume_spdif(). + + +Helper Functions +================ + +snd_hda_get_codec_name() stores the codec name on the given string. + +snd_hda_check_board_config() can be used to obtain the configuration +information matching with the device. Define the table with struct +hda_board_config entries (zero-terminated), and pass it to the +function. The function checks the modelname given as a module +parameter, and PCI subsystem IDs. If the matching entry is found, it +returns the config field value. + +snd_hda_add_new_ctls() can be used to create and add control entries. +Pass the zero-terminated array of snd_kcontrol_new_t. The same array +can be passed to snd_hda_resume_ctls() for resume. +Note that this will call control->put callback of these entries. So, +put callback should check codec->in_resume and force to restore the +given value if it's non-zero even if the value is identical with the +cached value. + +Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be +used for the entry of snd_kcontrol_new_t. + +The input MUX helper callbacks for such a control are provided, too: +snd_hda_input_mux_info() and snd_hda_input_mux_put(). See +patch_realtek.c for example. diff --git a/Documentation/sound/alsa/seq_oss.html b/Documentation/sound/alsa/seq_oss.html new file mode 100644 index 000000000000..d9776cf60c07 --- /dev/null +++ b/Documentation/sound/alsa/seq_oss.html @@ -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"><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> OSS sequencer emulation version 0.1.8 + ALSA client number 63 + ALSA receiver port 0 + + Number of applications: 0 + + Number of synth devices: 1 + + synth 0: [EMU8000] + type 0x1 : subtype 0x20 : voices 32 + capabilties : ioctl enabled / load_patch enabled + + Number of MIDI devices: 3 + + midi 0: [Emu8000 Port-0] ALSA port 65:0 + capability write / opened none + + midi 1: [Emu8000 Port-1] ALSA port 65:1 + capability write / opened none + + midi 2: [0: MPU-401 (UART)] ALSA port 64:0 + 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, + 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: + int (*open)(snd_seq_oss_arg_t *p, void *closure); + int (*close)(snd_seq_oss_arg_t *p); + int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg); + int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char *buf, int offs, int count); + 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 { + int app_index; + int file_mode; + int seq_mode; + snd_seq_addr_t addr; + void *private_data; + 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> +<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> diff --git a/Documentation/sound/alsa/serial-u16550.txt b/Documentation/sound/alsa/serial-u16550.txt new file mode 100644 index 000000000000..c1919559d509 --- /dev/null +++ b/Documentation/sound/alsa/serial-u16550.txt @@ -0,0 +1,88 @@ + + Serial UART 16450/16550 MIDI driver + =================================== + +The adaptor module parameter allows you to select either: + + 0 - Roland Soundcanvas support (default) + 1 - Midiator MS-124T support (1) + 2 - Midiator MS-124W S/A mode (2) + 3 - MS-124W M/B mode support (3) + 4 - Generic device with multiple input support (4) + +For the Midiator MS-124W, you must set the physical M-S and A-B +switches on the Midiator to match the driver mode you select. + +In Roland Soundcanvas mode, multiple ALSA raw MIDI substreams are supported +(midiCnD0-midiCnD15). Whenever you write to a different substream, the driver +sends the nonstandard MIDI command sequence F5 NN, where NN is the substream +number plus 1. Roland modules use this command to switch between different +"parts", so this feature lets you treat each part as a distinct raw MIDI +substream. The driver provides no way to send F5 00 (no selection) or to not +send the F5 NN command sequence at all; perhaps it ought to. + +Usage example for simple serial converter: + + /sbin/setserial /dev/ttyS0 uart none + /sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 speed=115200 + +Usage example for Roland SoundCanvas with 4 MIDI ports: + + /sbin/setserial /dev/ttyS0 uart none + /sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 outs=4 + +In MS-124T mode, one raw MIDI substream is supported (midiCnD0); the outs +module parameter is automatically set to 1. The driver sends the same data to +all four MIDI Out connectors. Set the A-B switch and the speed module +parameter to match (A=19200, B=9600). + +Usage example for MS-124T, with A-B switch in A position: + + /sbin/setserial /dev/ttyS0 uart none + /sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=1 \ + speed=19200 + +In MS-124W S/A mode, one raw MIDI substream is supported (midiCnD0); +the outs module parameter is automatically set to 1. The driver sends +the same data to all four MIDI Out connectors at full MIDI speed. + +Usage example for S/A mode: + + /sbin/setserial /dev/ttyS0 uart none + /sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=2 + +In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI substreams; +the outs module parameter is automatically set to 16. The substream +number gives a bitmask of which MIDI Out connectors the data should be +sent to, with midiCnD1 sending to Out 1, midiCnD2 to Out 2, midiCnD4 to +Out 3, and midiCnD8 to Out 4. Thus midiCnD15 sends the data to all 4 ports. +As a special case, midiCnD0 also sends to all ports, since it is not useful +to send the data to no ports. M/B mode has extra overhead to select the MIDI +Out for each byte, so the aggregate data rate across all four MIDI Outs is +at most one byte every 520 us, as compared with the full MIDI data rate of +one byte every 320 us per port. + +Usage example for M/B mode: + + /sbin/setserial /dev/ttyS0 uart none + /sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=3 + +The MS-124W hardware's M/A mode is currently not supported. This mode allows +the MIDI Outs to act independently at double the aggregate throughput of M/B, +but does not allow sending the same byte simultaneously to multiple MIDI Outs. +The M/A protocol requires the driver to twiddle the modem control lines under +timing constraints, so it would be a bit more complicated to implement than +the other modes. + +Midiator models other than MS-124W and MS-124T are currently not supported. +Note that the suffix letter is significant; the MS-124 and MS-124B are not +compatible, nor are the other known models MS-101, MS-101B, MS-103, and MS-114. +I do have documentation (tim.mann@compaq.com) that partially covers these models, +but no units to experiment with. The MS-124W support is tested with a real unit. +The MS-124T support is untested, but should work. + +The Generic driver supports multiple input and output substreams over a single +serial port. Similar to Roland Soundcanvas mode, F5 NN is used to select the +appropriate input or output stream (depending on the data direction). +Additionally, the CTS signal is used to regulate the data flow. The number of +inputs is specified by the ins parameter. diff --git a/Documentation/sound/oss/AD1816 b/Documentation/sound/oss/AD1816 new file mode 100644 index 000000000000..14bd8f25d523 --- /dev/null +++ b/Documentation/sound/oss/AD1816 @@ -0,0 +1,84 @@ +Documentation for the AD1816(A) sound driver +============================================ + +Installation: +------------- + +To get your AD1816(A) based sound card work, you'll have to enable support for +experimental code ("Prompt for development and/or incomplete code/drivers") +and isapnp ("Plug and Play support", "ISA Plug and Play support"). Enable +"Sound card support", "OSS modules support" and "Support for AD1816(A) based +cards (EXPERIMENTAL)" in the sound configuration menu, too. Now build, install +and reboot the new kernel as usual. + +Features: +--------- + +List of features supported by this driver: +- full-duplex support +- supported audio formats: unsigned 8bit, signed 16bit little endian, + signed 16bit big endian, µ-law, A-law +- supported channels: mono and stereo +- supported recording sources: Master, CD, Line, Line1, Line2, Mic +- supports phat 3d stereo circuit (Line 3) + + +Supported cards: +---------------- + +The following cards are known to work with this driver: +- Terratec Base 1 +- Terratec Base 64 +- HP Kayak +- Acer FX-3D +- SY-1816 +- Highscreen Sound-Boostar 32 Wave 3D +- Highscreen Sound-Boostar 16 +- AVM Apex Pro card +- (Aztech SC-16 3D) +- (Newcom SC-16 3D) +- (Terratec EWS64S) + +Cards listed in brackets are not supported reliable. If you have such a card +you should add the extra parameter: + options=1 +when loading the ad1816 module via modprobe. + + +Troubleshooting: +---------------- + +First of all you should check, if the driver has been loaded +properly. + +If loading of the driver succeeds, but playback/capture fails, check +if you used the correct values for irq, dma and dma2 when loading the module. +If one of them is wrong you usually get the following error message: + +Nov 6 17:06:13 tek01 kernel: Sound: DMA (output) timed out - IRQ/DRQ config error? + +If playback/capture is too fast or to slow, you should have a look at +the clock chip of your sound card. The AD1816 was designed for a 33MHz +oscillator, however most sound card manufacturer use slightly +different oscillators as they are cheaper than 33MHz oscillators. If +you have such a card you have to adjust the ad1816_clockfreq parameter +above. For example: For a card using a 32.875MHz oscillator use +ad1816_clockfreq=32875 instead of ad1816_clockfreq=33000. + + +Updates, bugfixes and bugreports: +-------------------------------- + +As the driver is still experimental and under development, you should +watch out for updates. Updates of the driver are available on the +Internet from one of my home pages: + http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html +or: + http://www.tu-darmstadt.de/~tek01/projects/linux.html + +Bugreports, bugfixes and related questions should be sent via E-Mail to: + tek@rbg.informatik.tu-darmstadt.de + +Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> +Christoph Hellwig <hch@infradead.org> + Last modified: 2000/09/20 diff --git a/Documentation/sound/oss/ALS b/Documentation/sound/oss/ALS new file mode 100644 index 000000000000..d01ffbfd5808 --- /dev/null +++ b/Documentation/sound/oss/ALS @@ -0,0 +1,66 @@ +ALS-007/ALS-100/ALS-200 based sound cards +========================================= + +Support for sound cards based around the Avance Logic +ALS-007/ALS-100/ALS-200 chip is included. These chips are a single +chip PnP sound solution which is mostly hardware compatible with the +Sound Blaster 16 card, with most differences occurring in the use of +the mixer registers. For this reason the ALS code is integrated +as part of the Sound Blaster 16 driver (adding only 800 bytes to the +SB16 driver). + +To use an ALS sound card under Linux, enable the following options as +modules in the sound configuration section of the kernel config: + - 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support + - FM synthesizer (YM3812/OPL-3) support + - standalone MPU401 support may be required for some cards; for the + ALS-007, when using isapnptools, it is required +Since the ALS-007/100/200 are PnP cards, ISAPnP support should probably be +compiled in. If kernel level PnP support is not included, isapnptools will +be required to configure the card before the sound modules are loaded. + +When using kernel level ISAPnP, the kernel should correctly identify and +configure all resources required by the card when the "sb" module is +inserted. Note that the ALS-007 does not have a 16 bit DMA channel and that +the MPU401 interface on this card uses a different interrupt to the audio +section. This should all be correctly configured by the kernel; if problems +with the MPU401 interface surface, try using the standalone MPU401 module, +passing "0" as the "sb" module's "mpu_io" module parameter to prevent the +soundblaster driver attempting to register the MPU401 itself. The onboard +synth device can be accessed using the "opl3" module. + +If isapnptools is used to wake up the sound card (as in 2.2.x), the settings +of the card's resources should be passed to the kernel modules ("sb", "opl3" +and "mpu401") using the module parameters. When configuring an ALS-007, be +sure to specify different IRQs for the audio and MPU401 sections - this card +requires they be different. For "sb", "io", "irq" and "dma" should be set +to the same values used to configure the audio section of the card with +isapnp. "dma16" should be explicitly set to "-1" for an ALS-007 since this +card does not have a 16 bit dma channel; if not specified the kernel will +default to using channel 5 anyway which will cause audio not to work. +"mpu_io" should be set to 0. The "io" parameter of the "opl3" module should +also agree with the setting used by isapnp. To get the MPU401 interface +working on an ALS-007 card, the "mpu401" module will be required since this +card uses separate IRQs for the audio and MPU401 sections and there is no +parameter available to pass a different IRQ to the "sb" driver (whose +inbuilt MPU401 driver would otherwise be fine). Insert the mpu401 module +passing appropriate values using the "io" and "irq" parameters. + +The resulting sound driver will provide the following capabilities: + - 8 and 16 bit audio playback + - 8 and 16 bit audio recording + - Software selection of record source (line in, CD, FM, mic, master) + - Record and playback of midi data via the external MPU-401 + - Playback of midi data using inbuilt FM synthesizer + - Control of the ALS-007 mixer via any OSS-compatible mixer programs. + Controls available are Master (L&R), Line in (L&R), CD (L&R), + DSP/PCM/audio out (L&R), FM (L&R) and Mic in (mono). + +Jonathan Woithe +jwoithe@physics.adelaide.edu.au +30 March 1998 + +Modified 2000-02-26 by Dave Forrest, drf5n@virginia.edu to add ALS100/ALS200 +Modified 2000-04-10 by Paul Laufer, pelaufer@csupomona.edu to add ISAPnP info. +Modified 2000-11-19 by Jonathan Woithe, jwoithe@physics.adelaide.edu.au + - updated information for kernel 2.4.x. diff --git a/Documentation/sound/oss/AWE32 b/Documentation/sound/oss/AWE32 new file mode 100644 index 000000000000..cb179bfeb522 --- /dev/null +++ b/Documentation/sound/oss/AWE32 @@ -0,0 +1,76 @@ + Installing and using Creative AWE midi sound under Linux. + +This documentation is devoted to the Creative Sound Blaster AWE32, AWE64 and +SB32. + +1) Make sure you have an ORIGINAL Creative SB32, AWE32 or AWE64 card. This + is important, because the driver works only with real Creative cards. + +2) The first thing you need to do is re-compile your kernel with support for + your sound card. Run your favourite tool to configure the kernel and when + you get to the "Sound" menu you should enable support for the following: + + Sound card support, + OSS sound modules, + 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support, + AWE32 synth + + If your card is "Plug and Play" you will also need to enable these two + options, found under the "Plug and Play configuration" menu: + + Plug and Play support + ISA Plug and Play support + + Now compile and install the kernel in normal fashion. If you don't know + how to do this you can find instructions for this in the README file + located in the root directory of the kernel source. + +3) Before you can start playing midi files you will have to load a sound + bank file. The utility needed for doing this is called "sfxload", and it + is one of the utilities found in a package called "awesfx". If this + package is not available in your distribution you can download the AWE + snapshot from Creative Labs Open Source website: + + http://www.opensource.creative.com/snapshot.html + + Once you have unpacked the AWE snapshot you will see a "awesfx" + directory. Follow the instructions in awesfx/docs/INSTALL to install the + utilities in this package. After doing this, sfxload should be installed + as: + + /usr/local/bin/sfxload + + To enable AWE general midi synthesis you should also get the sound bank + file for general midi from: + + http://members.xoom.com/yar/synthgm.sbk.gz + + Copy it to a directory of your choice, and unpack it there. + +4) Edit /etc/modprobe.conf, and insert the following lines at the end of the + file: + + alias sound-slot-0 sb + alias sound-service-0-1 awe_wave + install awe_wave /sbin/modprobe --first-time -i awe_wave && /usr/local/bin/sfxload PATH_TO_SOUND_BANK_FILE + + You will of course have to change "PATH_TO_SOUND_BANK_FILE" to the full + path of of the sound bank file. That will enable the Sound Blaster and AWE + wave synthesis. To play midi files you should get one of these programs if + you don't already have them: + + Playmidi: http://playmidi.openprojects.net + + AWEMidi Player (drvmidi) Included in the previously mentioned AWE + snapshot. + + You will probably have to pass the "-e" switch to playmidi to have it use + your midi device. drvmidi should work without switches. + + If something goes wrong please e-mail me. All comments and suggestions are + welcome. + + Yaroslav Rosomakho (alons55@dialup.ptt.ru) + http://www.yar.opennet.ru + +Last Updated: Feb 3 2001 diff --git a/Documentation/sound/oss/AudioExcelDSP16 b/Documentation/sound/oss/AudioExcelDSP16 new file mode 100644 index 000000000000..c0f08922993b --- /dev/null +++ b/Documentation/sound/oss/AudioExcelDSP16 @@ -0,0 +1,101 @@ +Driver +------ + +Informations about Audio Excel DSP 16 driver can be found in the source +file aedsp16.c +Please, read the head of the source before using it. It contain useful +informations. + +Configuration +------------- + +The Audio Excel configuration, is now done with the standard Linux setup. +You have to configure the sound card (Sound Blaster or Microsoft Sound System) +and, if you want it, the Roland MPU-401 (do not use the Sound Blaster MPU-401, +SB-MPU401) in the main driver menu. Activate the lowlevel drivers then select +the Audio Excel hardware that you want to initialize. Check the IRQ/DMA/MIRQ +of the Audio Excel initialization: it must be the same as the SBPRO (or MSS) +setup. If the parameters are different, correct it. +I you own a Gallant's audio card based on SC-6600, activate the SC-6600 support. +If you want to change the configuration of the sound board, be sure to +check off all the configuration items before re-configure it. + +Module parameters +----------------- +To use this driver as a module, you must configure some module parameters, to +set up I/O addresses, IRQ lines and DMA channels. Some parameters are +mandatory while some others are optional. Here a list of parameters you can +use with this module: + +Name Description +==== =========== +MANDATORY +io I/O base address (0x220 or 0x240) +irq irq line (5, 7, 9, 10 or 11) +dma dma channel (0, 1 or 3) + +OPTIONAL +mss_base I/O base address for activate MSS mode (default SBPRO) + (0x530 or 0xE80) +mpu_base I/O base address for activate MPU-401 mode + (0x300, 0x310, 0x320 or 0x330) +mpu_irq MPU-401 irq line (5, 7, 9, 10 or 0) + +The /etc/modprobe.conf will have lines like this: + +options opl3 io=0x388 +options ad1848 io=0x530 irq=11 dma=3 +options aedsp16 io=0x220 irq=11 dma=3 mss_base=0x530 + +Where the aedsp16 options are the options for this driver while opl3 and +ad1848 are the corresponding options for the MSS and OPL3 modules. + +Loading MSS and OPL3 needs to pre load the aedsp16 module to set up correctly +the sound card. Installation dependencies must be written in the modprobe.conf +file: + +install ad1848 /sbin/modprobe aedsp16 && /sbin/modprobe -i ad1848 +install opl3 /sbin/modprobe aedsp16 && /sbin/modprobe -i opl3 + +Then you must load the sound modules stack in this order: +sound -> aedsp16 -> [ ad1848, opl3 ] + +With the above configuration, loading ad1848 or opl3 modules, will +automatically load all the sound stack. + +Sound cards supported +--------------------- +This driver supports the SC-6000 and SC-6600 based Gallant's sound card. +It don't support the Audio Excel DSP 16 III (try the SC-6600 code). +I'm working on the III version of the card: if someone have useful +informations about it, please let me know. +For all the non-supported audio cards, you have to boot MS-DOS (or WIN95) +activating the audio card with the MS-DOS device driver, then you have to +<ctrl>-<alt>-<del> and boot Linux. +Follow these steps: + +1) Compile Linux kernel with standard sound driver, using the emulation + you want, with the parameters of your audio card, + e.g. Microsoft Sound System irq10 dma3 +2) Install your new kernel as the default boot kernel. +3) Boot MS-DOS and configure the audio card with the boot time device + driver, for MSS irq10 dma3 in our example. +4) <ctrl>-<alt>-<del> and boot Linux. This will maintain the DOS configuration + and will boot the new kernel with sound driver. The sound driver will find + the audio card and will recognize and attach it. + +Reports on User successes +------------------------- + +> Date: Mon, 29 Jul 1996 08:35:40 +0100 +> From: Mr S J Greenaway <sjg95@unixfe.rl.ac.uk> +> To: riccardo@cdc8g5.cdc.polimi.it (Riccardo Facchetti) +> Subject: Re: Audio Excel DSP 16 initialization code +> +> Just to let you know got my Audio Excel (emulating a MSS) working +> with my original SB16, thanks for the driver! + + +Last revised: 20 August 1998 +Riccardo Facchetti +fizban@tin.it diff --git a/Documentation/sound/oss/CMI8330 b/Documentation/sound/oss/CMI8330 new file mode 100644 index 000000000000..9c439f1a6dba --- /dev/null +++ b/Documentation/sound/oss/CMI8330 @@ -0,0 +1,153 @@ +Documentation for CMI 8330 (SoundPRO) +------------------------------------- +Alessandro Zummo <azummo@ita.flashnet.it> + +( Be sure to read Documentation/sound/oss/SoundPro too ) + + +This adapter is now directly supported by the sb driver. + + The only thing you have to do is to compile the kernel sound +support as a module and to enable kernel ISAPnP support, +as shown below. + + +CONFIG_SOUND=m +CONFIG_SOUND_SB=m + +CONFIG_PNP=y +CONFIG_ISAPNP=y + + +and optionally: + + +CONFIG_SOUND_MPU401=m + + for MPU401 support. + + +(I suggest you to use "make menuconfig" or "make xconfig" + for a more comfortable configuration editing) + + + +Then you can do + + modprobe sb + +and everything will be (hopefully) configured. + +You should get something similar in syslog: + +sb: CMI8330 detected. +sb: CMI8330 sb base located at 0x220 +sb: CMI8330 mpu base located at 0x330 +sb: CMI8330 mail reports to Alessandro Zummo <azummo@ita.flashnet.it> +sb: ISAPnP reports CMI 8330 SoundPRO at i/o 0x220, irq 7, dma 1,5 + + + + +The old documentation file follows for reference +purposes. + + +How to enable CMI 8330 (SOUNDPRO) soundchip on Linux +------------------------------------------ +Stefan Laudat <Stefan.Laudat@asit.ro> + +[Note: The CMI 8338 is unrelated and is supported by cmpci.o] + + + In order to use CMI8330 under Linux you just have to use a proper isapnp.conf, a good isapnp and a little bit of patience. I use isapnp 1.17, but +you may get a better one I guess at http://www.roestock.demon.co.uk/isapnptools/. + + Of course you will have to compile kernel sound support as module, as shown below: + +CONFIG_SOUND=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_ADLIB=m +CONFIG_SOUND_MPU401=m +# Mikro$chaft sound system (kinda useful here ;)) +CONFIG_SOUND_MSS=m + + The /etc/isapnp.conf file will be: + +<snip below> + + +(READPORT 0x0203) +(ISOLATE PRESERVE) +(IDENTIFY *) +(VERBOSITY 2) +(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING +(VERIFYLD N) + + +# WSS + +(CONFIGURE CMI0001/16777472 (LD 0 +(IO 0 (SIZE 8) (BASE 0x0530)) +(IO 1 (SIZE 8) (BASE 0x0388)) +(INT 0 (IRQ 7 (MODE +E))) +(DMA 0 (CHANNEL 0)) +(NAME "CMI0001/16777472[0]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + +# MPU + +(CONFIGURE CMI0001/16777472 (LD 1 +(IO 0 (SIZE 2) (BASE 0x0330)) +(INT 0 (IRQ 11 (MODE +E))) +(NAME "CMI0001/16777472[1]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + +# Joystick + +(CONFIGURE CMI0001/16777472 (LD 2 +(IO 0 (SIZE 8) (BASE 0x0200)) +(NAME "CMI0001/16777472[2]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + +# SoundBlaster + +(CONFIGURE CMI0001/16777472 (LD 3 +(IO 0 (SIZE 16) (BASE 0x0220)) +(INT 0 (IRQ 5 (MODE +E))) +(DMA 0 (CHANNEL 1)) +(DMA 1 (CHANNEL 5)) +(NAME "CMI0001/16777472[3]{CMI8330/C3D Audio Adapter}") +(ACT Y) +)) + + +(WAITFORKEY) + +<end of snip> + + The module sequence is trivial: + +/sbin/insmod soundcore +/sbin/insmod sound +/sbin/insmod uart401 +# insert this first +/sbin/insmod ad1848 io=0x530 irq=7 dma=0 soundpro=1 +# The sb module is an alternative to the ad1848 (Microsoft Sound System) +# Anyhow, this is full duplex and has MIDI +/sbin/insmod sb io=0x220 dma=1 dma16=5 irq=5 mpu_io=0x330 + + + +Alma Chao <elysian@ethereal.torsion.org> suggests the following /etc/modprobe.conf: + +alias sound ad1848 +alias synth0 opl3 +options ad1848 io=0x530 irq=7 dma=0 soundpro=1 +options opl3 io=0x388 + + diff --git a/Documentation/sound/oss/CMI8338 b/Documentation/sound/oss/CMI8338 new file mode 100644 index 000000000000..387d058c3f95 --- /dev/null +++ b/Documentation/sound/oss/CMI8338 @@ -0,0 +1,85 @@ +Audio driver for CM8338/CM8738 chips by Chen-Li Tien + + +HARDWARE SUPPORTED +================================================================================ +C-Media CMI8338 +C-Media CMI8738 +On-board C-Media chips + + +STEPS TO BUILD DRIVER +================================================================================ + + 1. Backup the Config.in and Makefile in the sound driver directory + (/usr/src/linux/driver/sound). + The Configure.help provide help when you config driver in step + 4, please backup the original one (/usr/src/linux/Document) and + copy this file. + The cmpci is document for the driver in detail, please copy it + to /usr/src/linux/Document/sound so you can refer it. Backup if + there is already one. + + 2. Extract the tar file by 'tar xvzf cmpci-xx.tar.gz' in the above + directory. + + 3. Change directory to /usr/src/linux + + 4. Config cm8338 driver by 'make menuconfig', 'make config' or + 'make xconfig' command. + + 5. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI + driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested. + For driver option, please refer 'DRIVER PARAMETER' + + 6. Compile the kernel if necessary. + + 7. Compile the modules by 'make modules'. + + 8. Install the modules by 'make modules_install' + + +INSTALL DRIVER +================================================================================ + + 1. Before first time to run the driver, create module dependency by + 'depmod -a' + + 2. To install the driver manually, enter 'modprobe cmpci'. + + 3. Driver installation for various distributions: + + a. Slackware 4.0 + Add the 'modprobe cmpci' command in your /etc/rc.d/rc.modules + file.so you can start the driver automatically each time booting. + + b. Caldera OpenLinux 2.2 + Use LISA to load the cmpci module. + + c. RedHat 6.0 and S.u.S.E. 6.1 + Add following command in /etc/conf.modules: + + alias sound cmpci + + also visit http://www.cmedia.com.tw for installation instruction. + +DRIVER PARAMETER +================================================================================ + + Some functions for the cm8738 can be configured in Kernel Configuration + or modules parameters. Set these parameters to 1 to enable. + + mpuio: I/O ports base for MPU-401, 0 if disabled. + fmio: I/O ports base for OPL-3, 0 if disabled. + spdif_inverse:Inverse the S/PDIF-in signal, this depends on your + CD-ROM or DVD-ROM. + spdif_loop: Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out + directly. + speakers: Number of speakers used. + use_line_as_rear:Enable this if you want to use line-in as + rear-out. + use_line_as_bass:Enable this if you want to use line-in as + bass-out. + joystick: Enable joystick. You will need to install Linux joystick + driver. + diff --git a/Documentation/sound/oss/CS4232 b/Documentation/sound/oss/CS4232 new file mode 100644 index 000000000000..7d6af7a5c1c2 --- /dev/null +++ b/Documentation/sound/oss/CS4232 @@ -0,0 +1,23 @@ +To configure the Crystal CS423x sound chip and activate its DSP functions, +modules may be loaded in this order: + + modprobe sound + insmod ad1848 + insmod uart401 + insmod cs4232 io=* irq=* dma=* dma2=* + +This is the meaning of the parameters: + + io--I/O address of the Windows Sound System (normally 0x534) + irq--IRQ of this device + dma and dma2--DMA channels (DMA2 may be 0) + +On some cards, the board attempts to do non-PnP setup, and fails. If you +have problems, use Linux' PnP facilities. + +To get MIDI facilities add + + insmod opl3 io=* + +where "io" is the I/O address of the OPL3 synthesizer. This will be shown +in /proc/sys/pnp and is normally 0x388. diff --git a/Documentation/sound/oss/ESS b/Documentation/sound/oss/ESS new file mode 100644 index 000000000000..bba93b4d2def --- /dev/null +++ b/Documentation/sound/oss/ESS @@ -0,0 +1,34 @@ +Documentation for the ESS AudioDrive chips + +In 2.4 kernels the SoundBlaster driver not only tries to detect an ESS chip, it +tries to detect the type of ESS chip too. The correct detection of the chip +doesn't always succeed however, so unless you use the kernel isapnp facilities +(and you chip is pnp capable) the default behaviour is 2.0 behaviour which +means: only detect ES688 and ES1688. + +All ESS chips now have a recording level setting. This is a need-to-have for +people who want to use their ESS for recording sound. + +Every chip that's detected as a later-than-es1688 chip has a 6 bits logarithmic +master volume control. + +Every chip that's detected as a ES1887 now has Full Duplex support. Made a +little testprogram that shows that is works, haven't seen a real program that +needs this however. + +For ESS chips an additional parameter "esstype" can be specified. This controls +the (auto) detection of the ESS chips. It can have 3 kinds of values: + +-1 Act like 2.0 kernels: only detect ES688 or ES1688. +0 Try to auto-detect the chip (may fail for ES1688) +688 The chip will be treated as ES688 +1688 ,, ,, ,, ,, ,, ,, ES1688 +1868 ,, ,, ,, ,, ,, ,, ES1868 +1869 ,, ,, ,, ,, ,, ,, ES1869 +1788 ,, ,, ,, ,, ,, ,, ES1788 +1887 ,, ,, ,, ,, ,, ,, ES1887 +1888 ,, ,, ,, ,, ,, ,, ES1888 + +Because Full Duplex is supported for ES1887 you can specify a second DMA +channel by specifying module parameter dma16. It can be one of: 0, 1, 3 or 5. + diff --git a/Documentation/sound/oss/ESS1868 b/Documentation/sound/oss/ESS1868 new file mode 100644 index 000000000000..55e922f21bc0 --- /dev/null +++ b/Documentation/sound/oss/ESS1868 @@ -0,0 +1,55 @@ +Documentation for the ESS1868F AudioDrive PnP sound card + +The ESS1868 sound card is a PnP ESS1688-compatible 16-bit sound card. + +It should be automatically detected by the Linux Kernel isapnp support when you +load the sb.o module. Otherwise you should take care of: + + * The ESS1868 does not allow use of a 16-bit DMA, thus DMA 0, 1, 2, and 3 + may only be used. + + * isapnptools version 1.14 does work with ESS1868. Earlier versions might + not. + + * Sound support MUST be compiled as MODULES, not statically linked + into the kernel. + + +NOTE: this is only needed when not using the kernel isapnp support! + +For configuring the sound card's I/O addresses, IRQ and DMA, here is a +sample copy of the isapnp.conf directives regarding the ESS1868: + +(CONFIGURE ESS1868/-1 (LD 1 +(IO 0 (BASE 0x0220)) +(IO 1 (BASE 0x0388)) +(IO 2 (BASE 0x0330)) +(DMA 0 (CHANNEL 1)) +(INT 0 (IRQ 5 (MODE +E))) +(ACT Y) +)) + +(for a full working isapnp.conf file, remember the +(ISOLATE) +(IDENTIFY *) +at the beginning and the +(WAITFORKEY) +at the end.) + +In this setup, the main card I/O is 0x0220, FM synthesizer is 0x0388, and +the MPU-401 MIDI port is located at 0x0330. IRQ is IRQ 5, DMA is channel 1. + +After configuring the sound card via isapnp, to use the card you must load +the sound modules with the proper I/O information. Here is my setup: + +# ESS1868F AudioDrive initialization + +/sbin/modprobe sound +/sbin/insmod uart401 +/sbin/insmod sb io=0x220 irq=5 dma=1 dma16=-1 +/sbin/insmod mpu401 io=0x330 +/sbin/insmod opl3 io=0x388 +/sbin/insmod v_midi + +opl3 is the FM synthesizer +/sbin/insmod opl3 io=0x388 diff --git a/Documentation/sound/oss/INSTALL.awe b/Documentation/sound/oss/INSTALL.awe new file mode 100644 index 000000000000..310f42ca1e83 --- /dev/null +++ b/Documentation/sound/oss/INSTALL.awe @@ -0,0 +1,134 @@ +================================================================ + INSTALLATION OF AWE32 SOUND DRIVER FOR LINUX + Takashi Iwai <iwai@ww.uni-erlangen.de> +================================================================ + +---------------------------------------------------------------- +* Attention to SB-PnP Card Users + +If you're using PnP cards, the initialization of PnP is required +before loading this driver. You have now three options: + 1. Use isapnptools. + 2. Use in-kernel isapnp support. + 3. Initialize PnP on DOS/Windows, then boot linux by loadlin. +In this document, only the case 1 case is treated. + +---------------------------------------------------------------- +* Installation on Red Hat 5.0 Sound Driver + +Please use install-rh.sh under RedHat5.0 directory. +DO NOT USE install.sh below. +See INSTALL.RH for more details. + +---------------------------------------------------------------- +* Installation/Update by Shell Script + + 1. Become root + + % su + + 2. If you have never configured the kernel tree yet, run make config + once (to make dependencies and symlinks). + + # cd /usr/src/linux + # make xconfig + + 3. Run install.sh script + + # sh ./install.sh + + 4. Configure your kernel + + (for Linux 2.[01].x user) + # cd /usr/src/linux + # make xconfig (or make menuconfig) + + (for Linux 1.2.x user) + # cd /usr/src/linux + # make config + + Answer YES to both "lowlevel drivers" and "AWE32 wave synth" items + in Sound menu. ("lowlevel drivers" will appear only in 2.x + kernel.) + + 5. Make your kernel (and modules), and install them as usual. + + 5a. make kernel image + # make zImage + + 5b. make modules and install them + # make modules && make modules_install + + 5c. If you're using lilo, copy the kernel image and run lilo. + Otherwise, copy the kernel image to suitable directory or + media for your system. + + 6. Reboot the kernel if necessary. + - If you updated only the modules, you don't have to reboot + the system. Just remove the old sound modules here. + in + # rmmod sound.o (linux-2.0 or OSS/Free) + # rmmod awe_wave.o (linux-2.1) + + 7. If your AWE card is a PnP and not initialized yet, you'll have to + do it by isapnp tools. Otherwise, skip to 8. + + This section described only a brief explanation. For more + details, please see the AWE64-Mini-HOWTO or isapnp tools FAQ. + + 7a. If you have no isapnp.conf file, generate it by pnpdump. + Otherwise, skip to 7d. + # pnpdump > /etc/isapnp.conf + + 7b. Edit isapnp.conf file. Comment out the appropriate + lines containing desirable I/O ports, DMA and IRQs. + Don't forget to enable (ACT Y) line. + + 7c. Add two i/o ports (0xA20 and 0xE20) in WaveTable part. + ex) + (CONFIGURE CTL0048/58128 (LD 2 + # ANSI string -->WaveTable<-- + (IO 0 (BASE 0x0620)) + (IO 1 (BASE 0x0A20)) + (IO 2 (BASE 0x0E20)) + (ACT Y) + )) + + 7d. Load the config file. + CAUTION: This will reset all PnP cards! + + # isapnp /etc/isapnp.conf + + 8. Load the sound module (if you configured it as a module): + + for 2.0 kernel or OSS/Free monolithic module: + + # modprobe sound.o + + for 2.1 kernel: + + # modprobe sound + # insmod uart401 + # insmod sb io=0x220 irq=5 dma=1 dma16=5 mpu_io=0x330 + (These values depend on your settings.) + # insmod awe_wave + (Be sure to load awe_wave after sb!) + + See Documentation/sound/oss/AWE32 for + more details. + + 9. (only for obsolete systems) If you don't have /dev/sequencer + device file, make it according to Readme.linux file on + /usr/src/linux/drivers/sound. (Run a shell script included in + that file). <-- This file no longer exists in the recent kernels! + + 10. OK, load your own soundfont file, and enjoy MIDI! + + % sfxload synthgm.sbk + % drvmidi foo.mid + + 11. For more advanced use (eg. dynamic loading, virtual bank and + etc.), please read the awedrv FAQ or the instructions in awesfx + and awemidi packages. + +Good luck! diff --git a/Documentation/sound/oss/Introduction b/Documentation/sound/oss/Introduction new file mode 100644 index 000000000000..15d4fb975ac0 --- /dev/null +++ b/Documentation/sound/oss/Introduction @@ -0,0 +1,459 @@ +Introduction Notes on Modular Sound Drivers and Soundcore +Wade Hampton +2/14/2001 + +Purpose: +======== +This document provides some general notes on the modular +sound drivers and their configuration, along with the +support modules sound.o and soundcore.o. + +Note, some of this probably should be added to the Sound-HOWTO! + +Note, soundlow.o was present with 2.2 kernels but is not +required for 2.4.x kernels. References have been removed +to this. + + +Copying: +======== +none + + +History: +======== +0.1.0 11/20/1998 First version, draft +1.0.0 11/1998 Alan Cox changes, incorporation in 2.2.0 + as Documentation/sound/oss/Introduction +1.1.0 6/30/1999 Second version, added notes on making the drivers, + added info on multiple sound cards of similar types,] + added more diagnostics info, added info about esd. + added info on OSS and ALSA. +1.1.1 19991031 Added notes on sound-slot- and sound-service. + (Alan Cox) +1.1.2 20000920 Modified for Kernel 2.4 (Christoph Hellwig) +1.1.3 20010214 Minor notes and corrections (Wade Hampton) + Added examples of sound-slot-0, etc. + + +Modular Sound Drivers: +====================== + +Thanks to the GREAT work by Alan Cox (alan@lxorguk.ukuu.org.uk), + +[And Oleg Drokin, Thomas Sailer, Andrew Veliath and more than a few + others - not to mention Hannu's original code being designed well + enough to cope with that kind of chopping up](Alan) + +the standard Linux kernels support a modular sound driver. From +Alan's comments in linux/drivers/sound/README.FIRST: + + The modular sound driver patches were funded by Red Hat Software + (www.redhat.com). The sound driver here is thus a modified version of + Hannu's code. Please bear that in mind when considering the appropriate + forums for bug reporting. + +The modular sound drivers may be loaded via insmod or modprobe. +To support all the various sound modules, there are two general +support modules that must be loaded first: + + soundcore.o: Top level handler for the sound system, provides + a set of functions for registration of devices + by type. + + sound.o: Common sound functions required by all modules. + +For the specific sound modules (e.g., sb.o for the Soundblaster), +read the documentation on that module to determine what options +are available, for example IRQ, address, DMA. + +Warning, the options for different cards sometime use different names +for the same or a similar feature (dma1= versus dma16=). As a last +resort, inspect the code (search for MODULE_PARM). + +Notes: + +1. There is a new OpenSource sound driver called ALSA which is + currently under development: http://www.alsa-project.org/ + The ALSA drivers support some newer hardware that may not + be supported by this sound driver and also provide some + additional features. + +2. The commercial OSS driver may be obtained from the site: + http://www/opensound.com. This may be used for cards that + are unsupported by the kernel driver, or may be used + by other operating systems. + +3. The enlightenment sound daemon may be used for playing + multiple sounds at the same time via a single card, eliminating + some of the requirements for multiple sound card systems. For + more information, see: http://www.tux.org/~ricdude/EsounD.html + The "esd" program may be used with the real-player and mpeg + players like mpg123 and x11amp. The newer real-player + and some games even include built-in support for ESD! + + +Building the Modules: +===================== + +This document does not provide full details on building the +kernel, etc. The notes below apply only to making the kernel +sound modules. If this conflicts with the kernel's README, +the README takes precedence. + +1. To make the kernel sound modules, cd to your /usr/src/linux + directory (typically) and type make config, make menuconfig, + or make xconfig (to start the command line, dialog, or x-based + configuration tool). + +2. Select the Sound option and a dialog will be displayed. + +3. Select M (module) for "Sound card support". + +4. Select your sound driver(s) as a module. For ProAudio, Sound + Blaster, etc., select M (module) for OSS sound modules. + [thanks to Marvin Stodolsky <stodolsk@erols.com>]A + +5. Make the kernel (e.g., make bzImage), and install the kernel. + +6. Make the modules and install them (make modules; make modules_install). + +Note, for 2.5.x kernels, make sure you have the newer module-init-tools +installed or modules will not be loaded properly. 2.5.x requires an +updated module-init-tools. + + +Plug and Play (PnP: +=================== + +If the sound card is an ISA PnP card, isapnp may be used +to configure the card. See the file isapnp.txt in the +directory one level up (e.g., /usr/src/linux/Documentation). + +Also the 2.4.x kernels provide PnP capabilities, see the +file NEWS in this directory. + +PCI sound cards are highly recommended, as they are far +easier to configure and from what I have read, they use +less resources and are more CPU efficient. + + +INSMOD: +======= + +If loading via insmod, the common modules must be loaded in the +order below BEFORE loading the other sound modules. The card-specific +modules may then be loaded (most require parameters). For example, +I use the following via a shell script to load my SoundBlaster: + +SB_BASE=0x240 +SB_IRQ=9 +SB_DMA=3 +SB_DMA2=5 +SB_MPU=0x300 +# +echo Starting sound +/sbin/insmod soundcore +/sbin/insmod sound +# +echo Starting sound blaster.... +/sbin/insmod uart401 +/sbin/insmod sb io=$SB_BASE irq=$SB_IRQ dma=$SB_DMA dma16=$SB_DMA2 mpu_io=$SB_MP + +When using sound as a module, I typically put these commands +in a file such as /root/soundon.sh. + + +MODPROBE: +========= + +If loading via modprobe, these common files are automatically loaded +when requested by modprobe. For example, my /etc/modprobe.conf contains: + +alias sound sb +options sb io=0x240 irq=9 dma=3 dma16=5 mpu_io=0x300 + +All you need to do to load the module is: + + /sbin/modprobe sb + + +Sound Status: +============= + +The status of sound may be read/checked by: + cat (anyfile).au >/dev/audio + +[WWH: This may not work properly for SoundBlaster PCI 128 cards +such as the es1370/1 (see the es1370/1 files in this directory) +as they do not automatically support uLaw on /dev/audio.] + +The status of the modules and which modules depend on +which other modules may be checked by: + /sbin/lsmod + +/sbin/lsmod should show something like the following: + sb 26280 0 + uart401 5640 0 [sb] + sound 57112 0 [sb uart401] + soundcore 1968 8 [sb sound] + + +Removing Sound: +=============== + +Sound may be removed by using /sbin/rmmod in the reverse order +in which you load the modules. Note, if a program has a sound device +open (e.g., xmixer), that module (and the modules on which it +depends) may not be unloaded. + +For example, I use the following to remove my Soundblaster (rmmod +in the reverse order in which I loaded the modules): + +/sbin/rmmod sb +/sbin/rmmod uart401 +/sbin/rmmod sound +/sbin/rmmod soundcore + +When using sound as a module, I typically put these commands +in a script such as /root/soundoff.sh. + + +Removing Sound for use with OSS: +================================ + +If you get really stuck or have a card that the kernel modules +will not support, you can get a commercial sound driver from +http://www.opensound.com. Before loading the commercial sound +driver, you should do the following: + +1. remove sound modules (detailed above) +2. remove the sound modules from /etc/modprobe.conf +3. move the sound modules from /lib/modules/<kernel>/misc + (for example, I make a /lib/modules/<kernel>/misc/tmp + directory and copy the sound module files to that + directory). + + +Multiple Sound Cards: +===================== + +The sound drivers will support multiple sound cards and there +are some great applications like multitrack that support them. +Typically, you need two sound cards of different types. Note, this +uses more precious interrupts and DMA channels and sometimes +can be a configuration nightmare. I have heard reports of 3-4 +sound cards (typically I only use 2). You can sometimes use +multiple PCI sound cards of the same type. + +On my machine I have two sound cards (cs4232 and Soundblaster Vibra +16). By loading sound as modules, I can control which is the first +sound device (/dev/dsp, /dev/audio, /dev/mixer) and which is +the second. Normally, the cs4232 (Dell sound on the motherboard) +would be the first sound device, but I prefer the Soundblaster. +All you have to do is to load the one you want as /dev/dsp +first (in my case "sb") and then load the other one +(in my case "cs4232"). + +If you have two cards of the same type that are jumpered +cards or different PnP revisions, you may load the same +module twice. For example, I have a SoundBlaster vibra 16 +and an older SoundBlaster 16 (jumpers). To load the module +twice, you need to do the following: + +1. Copy the sound modules to a new name. For example + sb.o could be copied (or symlinked) to sb1.o for the + second SoundBlaster. + +2. Make a second entry in /etc/modprobe.conf, for example, + sound1 or sb1. This second entry should refer to the + new module names for example sb1, and should include + the I/O, etc. for the second sound card. + +3. Update your soundon.sh script, etc. + +Warning: I have never been able to get two PnP sound cards of the +same type to load at the same time. I have tried this several times +with the Soundblaster Vibra 16 cards. OSS has indicated that this +is a PnP problem.... If anyone has any luck doing this, please +send me an E-MAIL. PCI sound cards should not have this problem.a +Since this was originally release, I have received a couple of +mails from people who have accomplished this! + +NOTE: In Linux 2.4 the Sound Blaster driver (and only this one yet) +supports multiple cards with one module by default. +Read the file 'Soundblaster' in this directory for details. + + +Sound Problems: +=============== + +First RTFM (including the troubleshooting section +in the Sound-HOWTO). + +1) If you are having problems loading the modules (for + example, if you get device conflict errors) try the + following: + + A) If you have Win95 or NT on the same computer, + write down what addresses, IRQ, and DMA channels + those were using for the same hardware. You probably + can use these addresses, IRQs, and DMA channels. + You should really do this BEFORE attempting to get + sound working! + + B) Check (cat) /proc/interrupts, /proc/ioports, + and /proc/dma. Are you trying to use an address, + IRQ or DMA port that another device is using? + + C) Check (cat) /proc/isapnp + + D) Inspect your /var/log/messages file. Often that will + indicate what IRQ or IO port could not be obtained. + + E) Try another port or IRQ. Note this may involve + using the PnP tools to move the sound card to + another location. Sometimes this is the only way + and it is more or less trial and error. + +2) If you get motor-boating (the same sound or part of a + sound clip repeated), you probably have either an IRQ + or DMA conflict. Move the card to another IRQ or DMA + port. This has happened to me when playing long files + when I had an IRQ conflict. + +3. If you get dropouts or pauses when playing high sample + rate files such as using mpg123 or x11amp/xmms, you may + have too slow of a CPU and may have to use the options to + play the files at 1/2 speed. For example, you may use + the -2 or -4 option on mpg123. You may also get this + when trying to play mpeg files stored on a CD-ROM + (my Toshiba T8000 PII/366 sometimes has this problem). + +4. If you get "cannot access device" errors, your /dev/dsp + files, etc. may be set to owner root, mode 600. You + may have to use the command: + chmod 666 /dev/dsp /dev/mixer /dev/audio + +5. If you get "device busy" errors, another program has the + sound device open. For example, if using the Enlightenment + sound daemon "esd", the "esd" program has the sound device. + If using "esd", please RTFM the docs on ESD. For example, + esddsp <program> may be used to play files via a non-esd + aware program. + +6) Ask for help on the sound list or send E-MAIL to the + sound driver author/maintainer. + +7) Turn on debug in drivers/sound/sound_config.h (DEB, DDB, MDB). + +8) If the system reports insufficient DMA memory then you may want to + load sound with the "dmabufs=1" option. Or in /etc/conf.modules add + + preinstall sound dmabufs=1 + + This makes the sound system allocate its buffers and hang onto them. + + You may also set persistent DMA when building a 2.4.x kernel. + + +Configuring Sound: +================== + +There are several ways of configuring your sound: + +1) On the kernel command line (when using the sound driver(s) + compiled in the kernel). Check the driver source and + documentation for details. + +2) On the command line when using insmod or in a bash script + using command line calls to load sound. + +3) In /etc/modprobe.conf when using modprobe. + +4) Via Red Hat's GPL'd /usr/sbin/sndconfig program (text based). + +5) Via the OSS soundconf program (with the commercial version + of the OSS driver. + +6) By just loading the module and let isapnp do everything relevant + for you. This works only with a few drivers yet and - of course - + only with isapnp hardware. + +And I am sure, several other ways. + +Anyone want to write a linuxconf module for configuring sound? + + +Module Loading: +=============== + +When a sound card is first referenced and sound is modular, the sound system +will ask for the sound devices to be loaded. Initially it requests that +the driver for the sound system is loaded. It then will ask for +sound-slot-0, where 0 is the first sound card. (sound-slot-1 the second and +so on). Thus you can do + +alias sound-slot-0 sb + +To load a soundblaster at this point. If the slot loading does not provide +the desired device - for example a soundblaster does not directly provide +a midi synth in all cases then it will request "sound-service-0-n" where n +is + + 0 Mixer + + 2 MIDI + + 3, 4 DSP audio + + +For example, I use the following to load my Soundblaster PCI 128 +(ES 1371) card first, followed by my SoundBlaster Vibra 16 card, +then by my TV card: + +# Load the Soundblaster PCI 128 as /dev/dsp, /dev/dsp1, /dev/mixer +alias sound-slot-0 es1371 + +# Load the Soundblaster Vibra 16 as /dev/dsp2, /dev/mixer1 +alias sound-slot-1 sb +options sb io=0x240 irq=5 dma=1 dma16=5 mpu_io=0x330 + +# Load the BTTV (TV card) as /dev/mixer2 +alias sound-slot-2 bttv +alias sound-service-2-0 tvmixer + +pre-install bttv modprobe tuner ; modprobe tvmixer +pre-install tvmixer modprobe msp3400; modprobe tvaudio +options tuner debug=0 type=8 +options bttv card=0 radio=0 pll=0 + + +For More Information (RTFM): +============================ +1) Information on kernel modules: manual pages for insmod and modprobe. + +2) Information on PnP, RTFM manual pages for isapnp. + +3) Sound-HOWTO and Sound-Playing-HOWTO. + +4) OSS's WWW site at http://www.opensound.com. + +5) All the files in Documentation/sound. + +6) The comments and code in linux/drivers/sound. + +7) The sndconfig and rhsound documentation from Red Hat. + +8) The Linux-sound mailing list: sound-list@redhat.com. + +9) Enlightenment documentation (for info on esd) + http://www.tux.org/~ricdude/EsounD.html. + +10) ALSA home page: http://www.alsa-project.org/ + + +Contact Information: +==================== +Wade Hampton: (whampton@staffnet.com) + diff --git a/Documentation/sound/oss/MAD16 b/Documentation/sound/oss/MAD16 new file mode 100644 index 000000000000..865dbd848742 --- /dev/null +++ b/Documentation/sound/oss/MAD16 @@ -0,0 +1,56 @@ +(This recipe has been edited to update the configuration symbols, + and change over to modprobe.conf for 2.6) + +From: Shaw Carruthers <shaw@shawc.demon.co.uk> + +I have been using mad16 sound for some time now with no problems, current +kernel 2.1.89 + +lsmod shows: + +mad16 5176 0 +sb 22044 0 [mad16] +uart401 5576 0 [mad16 sb] +ad1848 14176 1 [mad16] +sound 61928 0 [mad16 sb uart401 ad1848] + +.config has: + +CONFIG_SOUND=m +CONFIG_SOUND_ADLIB=m +CONFIG_SOUND_MAD16=m +CONFIG_SOUND_YM3812=m + +modprobe.conf has: + +alias char-major-14-* mad16 +options sb mad16=1 +options mad16 io=0x530 irq=7 dma=0 dma16=1 && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0 + + +To get the built in mixer to work this needs to be: + +options adlib_card io=0x388 # FM synthesizer +options sb mad16=1 +options mad16 io=0x530 irq=7 dma=0 dma16=1 mpu_io=816 mpu_irq=5 && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0 + +The addition of the "mpu_io=816 mpu_irq=5" to the mad16 options line is + +------------------------------------------------------------------------ +The mad16 module in addition supports the following options: + +option: meaning: default: +joystick=0,1 disabled, enabled disabled +cdtype=0x00,0x02,0x04, disabled, Sony CDU31A, disabled + 0x06,0x08,0x0a Mitsumi, Panasonic, + Secondary IDE, Primary IDE +cdport=0x340,0x320, 0x340 + 0x330,0x360 +cdirq=0,3,5,7,9,10,11 disabled, IRQ3, ... disabled +cddma=0,5,6,7 disabled, DMA5, ... DMA5 for Mitsumi or IDE +cddma=0,1,2,3 disabled, DMA1, ... DMA3 for Sony or Panasonic +opl4=0,1 OPL3, OPL4 OPL3 + +for more details see linux/drivers/sound/mad16.c + +Rui Sousa diff --git a/Documentation/sound/oss/Maestro b/Documentation/sound/oss/Maestro new file mode 100644 index 000000000000..4a80eb3f8e00 --- /dev/null +++ b/Documentation/sound/oss/Maestro @@ -0,0 +1,123 @@ + An OSS/Lite Driver for the ESS Maestro family of sound cards + + Zach Brown, December 1999 + +Driver Status and Availability +------------------------------ + +The most recent version of this driver will hopefully always be available at + http://www.zabbo.net/maestro/ + +I will try and maintain the most recent stable version of the driver +in both the stable and development kernel lines. + +ESS Maestro Chip Family +----------------------- + +There are 3 main variants of the ESS Maestro PCI sound chip. The first +is the Maestro 1. It was originally produced by Platform Tech as the +'AGOGO'. It can be recognized by Platform Tech's PCI ID 0x1285 with +0x0100 as the device ID. It was put on some sound boards and a few laptops. +ESS bought the design and cleaned it up as the Maestro 2. This starts +their marking with the ESS vendor ID 0x125D and the 'year' device IDs. +The Maestro 2 claims 0x1968 while the Maestro 2e has 0x1978. + +The various families of Maestro are mostly identical as far as this +driver is concerned. It doesn't touch the DSP parts that differ (though +it could for FM synthesis). + +Driver OSS Behavior +-------------------- + +This OSS driver exports /dev/mixer and /dev/dsp to applications, which +mostly adhere to the OSS spec. This driver doesn't register itself +with /dev/sndstat, so don't expect information to appear there. + +The /dev/dsp device exported behaves almost as expected. Playback is +supported in all the various lovely formats. 8/16bit stereo/mono from +8khz to 48khz, and mmap()ing for playback behaves. Capture/recording +is limited due to oddities with the Maestro hardware. One can only +record in 16bit stereo. For recording the maestro uses non interleaved +stereo buffers so that mmap()ing the incoming data does not result in +a ring buffer of LRLR data. mmap()ing of the read buffers is therefore +disallowed until this can be cleaned up. + +/dev/mixer is an interface to the AC'97 codec on the Maestro. It is +worth noting that there are a variety of AC'97s that can be wired to +the Maestro. Which is used is entirely up to the hardware implementor. +This should only be visible to the user by the presence, or lack, of +'Bass' and 'Treble' sliders in the mixer. Not all AC'97s have them. + +The driver doesn't support MIDI or FM playback at the moment. Typically +the Maestro is wired to an MPU MIDI chip, but some hardware implementations +don't. We need to assemble a white list of hardware implementations that +have MIDI wired properly before we can claim to support it safely. + +Compiling and Installing +------------------------ + +With the drivers inclusion into the kernel, compiling and installing +is the same as most OSS/Lite modular sound drivers. Compilation +of the driver is enabled through the CONFIG_SOUND_MAESTRO variable +in the config system. + +It may be modular or statically linked. If it is modular it should be +installed with the rest of the modules for the kernel on the system. +Typically this will be in /lib/modules/ somewhere. 'alias sound maestro' +should also be added to your module configs (typically /etc/conf.modules) +if you're using modular OSS/Lite sound and want to default to using a +maestro chip. + +As this is a PCI device, the module does not need to be informed of +any IO or IRQ resources it should use, it devines these from the +system. Sometimes, on sucky PCs, the BIOS fails to allocated resources +for the maestro. This will result in a message like: + maestro: PCI subsystem reports IRQ 0, this might not be correct. +from the kernel. Should this happen the sound chip most likely will +not operate correctly. To solve this one has to dig through their BIOS +(typically entered by hitting a hot key at boot time) and figure out +what magic needs to happen so that the BIOS will reward the maestro with +an IRQ. This operation is incredibly system specific, so you're on your +own. Sometimes the magic lies in 'PNP Capable Operating System' settings. + +There are very few options to the driver. One is 'debug' which will +tell the driver to print minimal debugging information as it runs. This +can be collected with 'dmesg' or through the klogd daemon. + +The other, more interesting option, is 'dsps_order'. Typically at +install time the driver will only register one available /dev/dsp device +for its use. The 'dsps_order' module parameter allows for more devices +to be allocated, as a power of two. Up to 4 devices can be registered +( dsps_order=2 ). These devices act as fully distinct units and use +separate channels in the maestro. + +Power Management +---------------- + +As of version 0.14, this driver has a minimal understanding of PCI +Power Management. If it finds a valid power management capability +on the PCI device it will attempt to use the power management +functions of the maestro. It will only do this on Maestro 2Es and +only on machines that are known to function well. You can +force the use of power management by setting the 'use_pm' module +option to 1, or can disable it entirely by setting it to 0. + +When using power management, the driver does a few things +differently. It will keep the chip in a lower power mode +when the module is inserted but /dev/dsp is not open. This +allows the mixer to function but turns off the clocks +on other parts of the chip. When /dev/dsp is opened the chip +is brought into full power mode, and brought back down +when it is closed. It also powers down the chip entirely +when the module is removed or the machine is shutdown. This +can have nonobvious consequences. CD audio may not work +after a power managing driver is removed. Also, software that +doesn't understand power management may not be able to talk +to the powered down chip until the machine goes through a hard +reboot to bring it back. + +.. more details .. +------------------ + +drivers/sound/maestro.c contains comments that hopefully explain +the maestro implementation. diff --git a/Documentation/sound/oss/Maestro3 b/Documentation/sound/oss/Maestro3 new file mode 100644 index 000000000000..a113718e8034 --- /dev/null +++ b/Documentation/sound/oss/Maestro3 @@ -0,0 +1,92 @@ + An OSS/Lite Driver for the ESS Maestro3 family of sound chips + + Zach Brown, January 2001 + +Driver Status and Availability +------------------------------ + +The most recent version of this driver will hopefully always be available at + http://www.zabbo.net/maestro3/ + +I will try and maintain the most recent stable version of the driver +in both the stable and development kernel lines. + +Historically I've sucked pretty hard at actually doing that, however. + +ESS Maestro3 Chip Family +----------------------- + +The 'Maestro3' is much like the Maestro2 chip. The noted improvement +is the removal of the silicon in the '2' that did PCM mixing. All that +work is now done through a custom DSP called the ASSP, the Asynchronus +Specific Signal Processor. + +The 'Allegro' is a baby version of the Maestro3. I'm not entirely clear +on the extent of the differences, but the driver supports them both :) + +The 'Allegro' shows up as PCI ID 0x1988 and the Maestro3 as 0x1998, +both under ESS's vendor ID of 0x125D. The Maestro3 can also show up as +0x199a when hardware strapping is used. + +The chip can also act as a multi function device. The modem IDs follow +the audio multimedia device IDs. (so the modem part of an Allegro shows +up as 0x1989) + +Driver OSS Behavior +-------------------- + +This OSS driver exports /dev/mixer and /dev/dsp to applications, which +mostly adhere to the OSS spec. This driver doesn't register itself +with /dev/sndstat, so don't expect information to appear there. + +The /dev/dsp device exported behaves as expected. Playback is +supported in all the various lovely formats. 8/16bit stereo/mono from +8khz to 48khz, with both read()/write(), and mmap(). + +/dev/mixer is an interface to the AC'97 codec on the Maestro3. It is +worth noting that there are a variety of AC'97s that can be wired to +the Maestro3. Which is used is entirely up to the hardware implementor. +This should only be visible to the user by the presence, or lack, of +'Bass' and 'Treble' sliders in the mixer. Not all AC'97s have them. +The Allegro has an onchip AC'97. + +The driver doesn't support MIDI or FM playback at the moment. + +Compiling and Installing +------------------------ + +With the drivers inclusion into the kernel, compiling and installing +is the same as most OSS/Lite modular sound drivers. Compilation +of the driver is enabled through the CONFIG_SOUND_MAESTRO3 variable +in the config system. + +It may be modular or statically linked. If it is modular it should be +installed with the rest of the modules for the kernel on the system. +Typically this will be in /lib/modules/ somewhere. 'alias sound-slot-0 +maestro3' should also be added to your module configs (typically +/etc/modprobe.conf) if you're using modular OSS/Lite sound and want to +default to using a maestro3 chip. + +There are very few options to the driver. One is 'debug' which will +tell the driver to print minimal debugging information as it runs. This +can be collected with 'dmesg' or through the klogd daemon. + +One is 'external_amp', which tells the driver to attempt to enable +an external amplifier. This defaults to '1', you can tell the driver +not to bother enabling such an amplifier by setting it to '0'. + +And the last is 'gpio_pin', which tells the driver which GPIO pin number +the external amp uses (0-15), The Allegro uses 8 by default, all others 1. +If everything loads correctly and seems to be working but you get no sound, +try tweaking this value. + +Systems known to need a different value + Panasonic ToughBook CF-72: gpio_pin=13 + +Power Management +---------------- + +This driver has a minimal understanding of PCI Power Management. It will +try and power down the chip when the system is suspended, and power +it up with it is resumed. It will also try and power down the chip +when the machine is shut down. diff --git a/Documentation/sound/oss/MultiSound b/Documentation/sound/oss/MultiSound new file mode 100644 index 000000000000..e4a18bb7f73a --- /dev/null +++ b/Documentation/sound/oss/MultiSound @@ -0,0 +1,1137 @@ +#! /bin/sh +# +# Turtle Beach MultiSound Driver Notes +# -- Andrew Veliath <andrewtv@usa.net> +# +# Last update: September 10, 1998 +# Corresponding msnd driver: 0.8.3 +# +# ** This file is a README (top part) and shell archive (bottom part). +# The corresponding archived utility sources can be unpacked by +# running `sh MultiSound' (the utilities are only needed for the +# Pinnacle and Fiji cards). ** +# +# +# -=-=- Getting Firmware -=-=- +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# See the section `Obtaining and Creating Firmware Files' in this +# document for instructions on obtaining the necessary firmware +# files. +# +# +# Supported Features +# ~~~~~~~~~~~~~~~~~~ +# +# Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is +# not currently available) and mixer functionality (/dev/mixer) are +# supported (memory mapped digital audio is not yet supported). +# Digital transfers and monitoring can be done as well if you have +# the digital daughterboard (see the section on using the S/PDIF port +# for more information). +# +# Support for the Turtle Beach MultiSound Hurricane architecture is +# composed of the following modules (these can also operate compiled +# into the kernel): +# +# msnd - MultiSound base (requires soundcore) +# +# msnd_classic - Base audio/mixer support for Classic, Monetery and +# Tahiti cards +# +# msnd_pinnacle - Base audio/mixer support for Pinnacle and Fiji cards +# +# +# Important Notes - Read Before Using +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# The firmware files are not included (may change in future). You +# must obtain these images from Turtle Beach (they are included in +# the MultiSound Development Kits), and place them in /etc/sound for +# example, and give the full paths in the Linux configuration. If +# you are compiling in support for the MultiSound driver rather than +# using it as a module, these firmware files must be accessible +# during kernel compilation. +# +# Please note these files must be binary files, not assembler. See +# the section later in this document for instructions to obtain these +# files. +# +# +# Configuring Card Resources +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# ** This section is very important, as your card may not work at all +# or your machine may crash if you do not do this correctly. ** +# +# * Classic/Monterey/Tahiti +# +# These cards are configured through the driver msnd_classic. You must +# know the io port, then the driver will select the irq and memory resources +# on the card. It is up to you to know if these are free locations or now, +# a conflict can lock the machine up. +# +# * Pinnacle/Fiji +# +# The Pinnacle and Fiji cards have an extra config port, either +# 0x250, 0x260 or 0x270. This port can be disabled to have the card +# configured strictly through PnP, however you lose the ability to +# access the IDE controller and joystick devices on this card when +# using PnP. The included pinnaclecfg program in this shell archive +# can be used to configure the card in non-PnP mode, and in PnP mode +# you can use isapnptools. These are described briefly here. +# +# pinnaclecfg is not required; you can use the msnd_pinnacle module +# to fully configure the card as well. However, pinnaclecfg can be +# used to change the resource values of a particular device after the +# msnd_pinnacle module has been loaded. If you are compiling the +# driver into the kernel, you must set these values during compile +# time, however other peripheral resource values can be changed with +# the pinnaclecfg program after the kernel is loaded. +# +# +# *** PnP mode +# +# Use pnpdump to obtain a sample configuration if you can; I was able +# to obtain one with the command `pnpdump 1 0x203' -- this may vary +# for you (running pnpdump by itself did not work for me). Then, +# edit this file and use isapnp to uncomment and set the card values. +# Use these values when inserting the msnd_pinnacle module. Using +# this method, you can set the resources for the DSP and the Kurzweil +# synth (Pinnacle). Since Linux does not directly support PnP +# devices, you may have difficulty when using the card in PnP mode +# when it the driver is compiled into the kernel. Using non-PnP mode +# is preferable in this case. +# +# Here is an example mypinnacle.conf for isapnp that sets the card to +# io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil +# synth to 0x330 and irq 9 (may need editing for your system): +# +# (READPORT 0x0203) +# (CSN 2) +# (IDENTIFY *) +# +# # DSP +# (CONFIGURE BVJ0440/-1 (LD 0 +# (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000)) +# (ACT Y))) +# +# # Kurzweil Synth (Pinnacle Only) +# (CONFIGURE BVJ0440/-1 (LD 1 +# (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E))) +# (ACT Y))) +# +# (WAITFORKEY) +# +# +# *** Non-PnP mode +# +# The second way is by running the card in non-PnP mode. This +# actually has some advantages in that you can access some other +# devices on the card, such as the joystick and IDE controller. To +# configure the card, unpack this shell archive and build the +# pinnaclecfg program. Using this program, you can assign the +# resource values to the card's devices, or disable the devices. As +# an alternative to using pinnaclecfg, you can specify many of the +# configuration values when loading the msnd_pinnacle module (or +# during kernel configuration when compiling the driver into the +# kernel). +# +# If you specify cfg=0x250 for the msnd_pinnacle module, it +# automatically configure the card to the given io, irq and memory +# values using that config port (the config port is jumper selectable +# on the card to 0x250, 0x260 or 0x270). +# +# See the `msnd_pinnacle Additional Options' section below for more +# information on these parameters (also, if you compile the driver +# directly into the kernel, these extra parameters can be useful +# here). +# +# +# ** It is very easy to cause problems in your machine if you choose a +# resource value which is incorrect. ** +# +# +# Examples +# ~~~~~~~~ +# +# * MultiSound Classic/Monterey/Tahiti: +# +# modprobe soundcore +# insmod msnd +# insmod msnd_classic io=0x290 irq=7 mem=0xd0000 +# +# * MultiSound Pinnacle in PnP mode: +# +# modprobe soundcore +# insmod msnd +# isapnp mypinnacle.conf +# insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values +# +# * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port, +# one of 0x250, 0x260 or 0x270): +# +# insmod soundcore +# insmod msnd +# insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 +# +# * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP +# mode, add the following (assumes you did `isapnp mypinnacle.conf'): +# +# insmod sound +# insmod mpu401 io=0x330 irq=9 <-- match mypinnacle.conf values +# +# * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP +# mode, add the following. Note how we first configure the peripheral's +# resources, _then_ install a Linux driver for it: +# +# insmod sound +# pinnaclecfg 0x250 mpu 0x330 9 +# insmod mpu401 io=0x330 irq=9 +# +# -- OR you can use the following sequence without pinnaclecfg in non-PnP mode: +# +# insmod soundcore +# insmod msnd +# insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9 +# insmod sound +# insmod mpu401 io=0x330 irq=9 +# +# * To setup the joystick port on the Pinnacle in non-PnP mode (though +# you have to find the actual Linux joystick driver elsewhere), you +# can use pinnaclecfg: +# +# pinnaclecfg 0x250 joystick 0x200 +# +# -- OR you can configure this using msnd_pinnacle with the following: +# +# insmod soundcore +# insmod msnd +# insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200 +# +# +# msnd_classic, msnd_pinnacle Required Options +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# If the following options are not given, the module will not load. +# Examine the kernel message log for informative error messages. +# WARNING--probing isn't supported so try to make sure you have the +# correct shared memory area, otherwise you may experience problems. +# +# io I/O base of DSP, e.g. io=0x210 +# irq IRQ number, e.g. irq=5 +# mem Shared memory area, e.g. mem=0xd8000 +# +# +# msnd_classic, msnd_pinnacle Additional Options +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# fifosize The digital audio FIFOs, in kilobytes. If not +# specified, the default will be used. Increasing +# this value will reduce the chance of a FIFO +# underflow at the expense of increasing overall +# latency. For example, fifosize=512 will +# allocate 512kB read and write FIFOs (1MB total). +# While this may reduce dropouts, a heavy machine +# load will undoubtedly starve the FIFO of data +# and you will eventually get dropouts. One +# option is to alter the scheduling priority of +# the playback process, using `nice' or some form +# of POSIX soft real-time scheduling. +# +# calibrate_signal Setting this to one calibrates the ADCs to the +# signal, zero calibrates to the card (defaults +# to zero). +# +# +# msnd_pinnacle Additional Options +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# digital Specify digital=1 to enable the S/PDIF input +# if you have the digital daughterboard +# adapter. This will enable access to the +# DIGITAL1 input for the soundcard in the mixer. +# Some mixer programs might have trouble setting +# the DIGITAL1 source as an input. If you have +# trouble, you can try the setdigital.c program +# at the bottom of this document. +# +# cfg Non-PnP configuration port for the Pinnacle +# and Fiji (typically 0x250, 0x260 or 0x270, +# depending on the jumper configuration). If +# this option is omitted, then it is assumed +# that the card is in PnP mode, and that the +# specified DSP resource values are already +# configured with PnP (i.e. it won't attempt to +# do any sort of configuration). +# +# When the Pinnacle is in non-PnP mode, you can use the following +# options to configure particular devices. If a full specification +# for a device is not given, then the device is not configured. Note +# that you still must use a Linux driver for any of these devices +# once their resources are setup (such as the Linux joystick driver, +# or the MPU401 driver from OSS for the Kurzweil synth). +# +# mpu_io I/O port of MPU (on-board Kurzweil synth) +# mpu_irq IRQ of MPU (on-board Kurzweil synth) +# ide_io0 First I/O port of IDE controller +# ide_io1 Second I/O port of IDE controller +# ide_irq IRQ IDE controller +# joystick_io I/O port of joystick +# +# +# Obtaining and Creating Firmware Files +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# For the Classic/Tahiti/Monterey +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Download to /tmp and unzip the following file from Turtle Beach: +# +# ftp://ftp.voyetra.com/pub/tbs/msndcl/msndvkit.zip +# +# When unzipped, unzip the file named MsndFiles.zip. Then copy the +# following firmware files to /etc/sound (note the file renaming): +# +# cp DSPCODE/MSNDINIT.BIN /etc/sound/msndinit.bin +# cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin +# +# When configuring the Linux kernel, specify /etc/sound/msndinit.bin and +# /etc/sound/msndperm.bin for the two firmware files (Linux kernel +# versions older than 2.2 do not ask for firmware paths, and are +# hardcoded to /etc/sound). +# +# If you are compiling the driver into the kernel, these files must +# be accessible during compilation, but will not be needed later. +# The files must remain, however, if the driver is used as a module. +# +# +# For the Pinnacle/Fiji +# ~~~~~~~~~~~~~~~~~~~~~ +# +# Download to /tmp and unzip the following file from Turtle Beach (be +# sure to use the entire URL; some have had trouble navigating to the +# URL): +# +# ftp://ftp.voyetra.com/pub/tbs/pinn/pnddk100.zip +# +# Unpack this shell archive, and run make in the created directory +# (you need a C compiler and flex to build the utilities). This +# should give you the executables conv, pinnaclecfg and setdigital. +# conv is only used temporarily here to create the firmware files, +# while pinnaclecfg is used to configure the Pinnacle or Fiji card in +# non-PnP mode, and setdigital can be used to set the S/PDIF input on +# the mixer (pinnaclecfg and setdigital should be copied to a +# convenient place, possibly run during system initialization). +# +# To generating the firmware files with the `conv' program, we create +# the binary firmware files by doing the following conversion +# (assuming the archive unpacked into a directory named PINNDDK): +# +# ./conv < PINNDDK/dspcode/pndspini.asm > /etc/sound/pndspini.bin +# ./conv < PINNDDK/dspcode/pndsperm.asm > /etc/sound/pndsperm.bin +# +# The conv (and conv.l) program is not needed after conversion and can +# be safely deleted. Then, when configuring the Linux kernel, specify +# /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two +# firmware files (Linux kernel versions older than 2.2 do not ask for +# firmware paths, and are hardcoded to /etc/sound). +# +# If you are compiling the driver into the kernel, these files must +# be accessible during compilation, but will not be needed later. +# The files must remain, however, if the driver is used as a module. +# +# +# Using Digital I/O with the S/PDIF Port +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# If you have a Pinnacle or Fiji with the digital daughterboard and +# want to set it as the input source, you can use this program if you +# have trouble trying to do it with a mixer program (be sure to +# insert the module with the digital=1 option, or say Y to the option +# during compiled-in kernel operation). Upon selection of the S/PDIF +# port, you should be able monitor and record from it. +# +# There is something to note about using the S/PDIF port. Digital +# timing is taken from the digital signal, so if a signal is not +# connected to the port and it is selected as recording input, you +# will find PCM playback to be distorted in playback rate. Also, +# attempting to record at a sampling rate other than the DAT rate may +# be problematic (i.e. trying to record at 8000Hz when the DAT signal +# is 44100Hz). If you have a problem with this, set the recording +# input to analog if you need to record at a rate other than that of +# the DAT rate. +# +# +# -- Shell archive attached below, just run `sh MultiSound' to extract. +# Contains Pinnacle/Fiji utilities to convert firmware, configure +# in non-PnP mode, and select the DIGITAL1 input for the mixer. +# +# +#!/bin/sh +# This is a shell archive (produced by GNU sharutils 4.2). +# To extract the files from this archive, save it to some FILE, remove +# everything before the `!/bin/sh' line above, then type `sh FILE'. +# +# Made on 1998-12-04 10:07 EST by <andrewtv@ztransform.velsoft.com>. +# Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'. +# +# Existing files will *not* be overwritten unless `-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 2046 -rw-rw-r-- MultiSound.d/setdigital.c +# 10235 -rw-rw-r-- MultiSound.d/pinnaclecfg.c +# 106 -rw-rw-r-- MultiSound.d/Makefile +# 141 -rw-rw-r-- MultiSound.d/conv.l +# 1472 -rw-rw-r-- MultiSound.d/msndreset.c +# +save_IFS="${IFS}" +IFS="${IFS}:" +gettext_dir=FAILED +locale_dir=FAILED +first_param="$1" +for dir in $PATH +do + if test "$gettext_dir" = FAILED && test -f $dir/gettext \ + && ($dir/gettext --version >/dev/null 2>&1) + then + set `$dir/gettext --version 2>&1` + if test "$3" = GNU + then + gettext_dir=$dir + fi + fi + if test "$locale_dir" = FAILED && test -f $dir/shar \ + && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) + then + locale_dir=`$dir/shar --print-text-domain-dir` + fi +done +IFS="$save_IFS" +if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED +then + echo=echo +else + TEXTDOMAINDIR=$locale_dir + export TEXTDOMAINDIR + TEXTDOMAIN=sharutils + export TEXTDOMAIN + echo="$gettext_dir/gettext -s" +fi +touch -am 1231235999 $$.touch >/dev/null 2>&1 +if test ! -f 1231235999 && test -f $$.touch; then + shar_touch=touch +else + shar_touch=: + echo + $echo 'WARNING: not restoring timestamps. Consider getting and' + $echo "installing GNU \`touch', distributed in GNU File Utilities..." + echo +fi +rm -f 1231235999 $$.touch +# +if mkdir _sh01426; then + $echo 'x -' 'creating lock directory' +else + $echo 'failed to create lock directory' + exit 1 +fi +# ============= MultiSound.d/setdigital.c ============== +if test ! -d 'MultiSound.d'; then + $echo 'x -' 'creating directory' 'MultiSound.d' + mkdir 'MultiSound.d' +fi +if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' && +/********************************************************************* +X * +X * setdigital.c - sets the DIGITAL1 input for a mixer +X * +X * Copyright (C) 1998 Andrew Veliath +X * +X * This program is free software; you can redistribute it and/or modify +X * it under the terms of the GNU General Public License as published by +X * the Free Software Foundation; either version 2 of the License, or +X * (at your option) any later version. +X * +X * This program is distributed in the hope that it will be useful, +X * but WITHOUT ANY WARRANTY; without even the implied warranty of +X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +X * GNU General Public License for more details. +X * +X * You should have received a copy of the GNU General Public License +X * along with this program; if not, write to the Free Software +X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +X * +X ********************************************************************/ +X +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/soundcard.h> +X +int main(int argc, char *argv[]) +{ +X int fd; +X unsigned long recmask, recsrc; +X +X if (argc != 2) { +X fprintf(stderr, "usage: setdigital <mixer device>\n"); +X exit(1); +X } +X +X if ((fd = open(argv[1], O_RDWR)) < 0) { +X perror(argv[1]); +X exit(1); +X } +X +X if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) { +X fprintf(stderr, "error: ioctl read recording mask failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X if (!(recmask & SOUND_MASK_DIGITAL1)) { +X fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n"); +X close(fd); +X exit(1); +X } +X +X if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) { +X fprintf(stderr, "error: ioctl read recording source failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X recsrc |= SOUND_MASK_DIGITAL1; +X +X if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) { +X fprintf(stderr, "error: ioctl write recording source failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X close(fd); +X +X return 0; +} +SHAR_EOF + $shar_touch -am 1204092598 'MultiSound.d/setdigital.c' && + chmod 0664 'MultiSound.d/setdigital.c' || + $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed' +e87217fc3e71288102ba41fd81f71ec4 MultiSound.d/setdigital.c +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`" + test 2046 -eq "$shar_count" || + $echo 'MultiSound.d/setdigital.c:' 'original size' '2046,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/pinnaclecfg.c ============== +if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' && +/********************************************************************* +X * +X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program +X * +X * This is for NON-PnP mode only. For PnP mode, use isapnptools. +X * +X * This is Linux-specific, and must be run with root permissions. +X * +X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux +X * +X * Copyright (C) 1998 Andrew Veliath +X * +X * This program is free software; you can redistribute it and/or modify +X * it under the terms of the GNU General Public License as published by +X * the Free Software Foundation; either version 2 of the License, or +X * (at your option) any later version. +X * +X * This program is distributed in the hope that it will be useful, +X * but WITHOUT ANY WARRANTY; without even the implied warranty of +X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +X * GNU General Public License for more details. +X * +X * You should have received a copy of the GNU General Public License +X * along with this program; if not, write to the Free Software +X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +X * +X ********************************************************************/ +X +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <asm/io.h> +#include <asm/types.h> +X +#define IREG_LOGDEVICE 0x07 +#define IREG_ACTIVATE 0x30 +#define LD_ACTIVATE 0x01 +#define LD_DISACTIVATE 0x00 +#define IREG_EECONTROL 0x3F +#define IREG_MEMBASEHI 0x40 +#define IREG_MEMBASELO 0x41 +#define IREG_MEMCONTROL 0x42 +#define IREG_MEMRANGEHI 0x43 +#define IREG_MEMRANGELO 0x44 +#define MEMTYPE_8BIT 0x00 +#define MEMTYPE_16BIT 0x02 +#define MEMTYPE_RANGE 0x00 +#define MEMTYPE_HIADDR 0x01 +#define IREG_IO0_BASEHI 0x60 +#define IREG_IO0_BASELO 0x61 +#define IREG_IO1_BASEHI 0x62 +#define IREG_IO1_BASELO 0x63 +#define IREG_IRQ_NUMBER 0x70 +#define IREG_IRQ_TYPE 0x71 +#define IRQTYPE_HIGH 0x02 +#define IRQTYPE_LOW 0x00 +#define IRQTYPE_LEVEL 0x01 +#define IRQTYPE_EDGE 0x00 +X +#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF)) +#define LOBYTE(w) ((BYTE)(w)) +#define MAKEWORD(low,hi) ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8))) +X +typedef __u8 BYTE; +typedef __u16 USHORT; +typedef __u16 WORD; +X +static int config_port = -1; +X +static int msnd_write_cfg(int cfg, int reg, int value) +{ +X outb(reg, cfg); +X outb(value, cfg + 1); +X if (value != inb(cfg + 1)) { +X fprintf(stderr, "error: msnd_write_cfg: I/O error\n"); +X return -EIO; +X } +X return 0; +} +X +static int msnd_read_cfg(int cfg, int reg) +{ +X outb(reg, cfg); +X return inb(cfg + 1); +} +X +static int msnd_write_cfg_io0(int cfg, int num, WORD io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io))) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_io0(int cfg, int num, WORD *io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO), +X msnd_read_cfg(cfg, IREG_IO0_BASEHI)); +X +X return 0; +} +X +static int msnd_write_cfg_io1(int cfg, int num, WORD io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io))) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_io1(int cfg, int num, WORD *io) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO), +X msnd_read_cfg(cfg, IREG_IO1_BASEHI)); +X +X return 0; +} +X +static int msnd_write_cfg_irq(int cfg, int num, WORD irq) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE)) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_irq(int cfg, int num, WORD *irq) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER); +X +X return 0; +} +X +static int msnd_write_cfg_mem(int cfg, int num, int mem) +{ +X WORD wmem; +X +X mem >>= 8; +X mem &= 0xfff; +X wmem = (WORD)mem; +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem))) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem))) +X return -EIO; +X if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT))) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_mem(int cfg, int num, int *mem) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X +X *mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO), +X msnd_read_cfg(cfg, IREG_MEMBASEHI)); +X *mem <<= 8; +X +X return 0; +} +X +static int msnd_activate_logical(int cfg, int num) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE)) +X return -EIO; +X return 0; +} +X +static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_write_cfg_io0(cfg, num, io0)) +X return -EIO; +X if (msnd_write_cfg_io1(cfg, num, io1)) +X return -EIO; +X if (msnd_write_cfg_irq(cfg, num, irq)) +X return -EIO; +X if (msnd_write_cfg_mem(cfg, num, mem)) +X return -EIO; +X if (msnd_activate_logical(cfg, num)) +X return -EIO; +X return 0; +} +X +static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem) +{ +X if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) +X return -EIO; +X if (msnd_read_cfg_io0(cfg, num, io0)) +X return -EIO; +X if (msnd_read_cfg_io1(cfg, num, io1)) +X return -EIO; +X if (msnd_read_cfg_irq(cfg, num, irq)) +X return -EIO; +X if (msnd_read_cfg_mem(cfg, num, mem)) +X return -EIO; +X return 0; +} +X +static void usage(void) +{ +X fprintf(stderr, +X "\n" +X "pinnaclecfg 1.0\n" +X "\n" +X "usage: pinnaclecfg <config port> [device config]\n" +X "\n" +X "This is for use with the card in NON-PnP mode only.\n" +X "\n" +X "Available devices (not all available for Fiji):\n" +X "\n" +X " Device Description\n" +X " -------------------------------------------------------------------\n" +X " reset Reset all devices (i.e. disable)\n" +X " show Display current device configurations\n" +X "\n" +X " dsp <io> <irq> <mem> Audio device\n" +X " mpu <io> <irq> Internal Kurzweil synth\n" +X " ide <io0> <io1> <irq> On-board IDE controller\n" +X " joystick <io> Joystick port\n" +X "\n"); +X exit(1); +} +X +static int cfg_reset(void) +{ +X int i; +X +X for (i = 0; i < 4; ++i) +X msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0); +X +X return 0; +} +X +static int cfg_show(void) +{ +X int i; +X int count = 0; +X +X for (i = 0; i < 4; ++i) { +X WORD io0, io1, irq; +X int mem; +X msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem); +X switch (i) { +X case 0: +X if (io0 || irq || mem) { +X printf("dsp 0x%x %d 0x%x\n", io0, irq, mem); +X ++count; +X } +X break; +X case 1: +X if (io0 || irq) { +X printf("mpu 0x%x %d\n", io0, irq); +X ++count; +X } +X break; +X case 2: +X if (io0 || io1 || irq) { +X printf("ide 0x%x 0x%x %d\n", io0, io1, irq); +X ++count; +X } +X break; +X case 3: +X if (io0) { +X printf("joystick 0x%x\n", io0); +X ++count; +X } +X break; +X } +X } +X +X if (count == 0) +X fprintf(stderr, "no devices configured\n"); +X +X return 0; +} +X +static int cfg_dsp(int argc, char *argv[]) +{ +X int io, irq, mem; +X +X if (argc < 3 || +X sscanf(argv[0], "0x%x", &io) != 1 || +X sscanf(argv[1], "%d", &irq) != 1 || +X sscanf(argv[2], "0x%x", &mem) != 1) +X usage(); +X +X if (!(io == 0x290 || +X io == 0x260 || +X io == 0x250 || +X io == 0x240 || +X io == 0x230 || +X io == 0x220 || +X io == 0x210 || +X io == 0x3e0)) { +X fprintf(stderr, "error: io must be one of " +X "210, 220, 230, 240, 250, 260, 290, or 3E0\n"); +X usage(); +X } +X +X if (!(irq == 5 || +X irq == 7 || +X irq == 9 || +X irq == 10 || +X irq == 11 || +X irq == 12)) { +X fprintf(stderr, "error: irq must be one of " +X "5, 7, 9, 10, 11 or 12\n"); +X usage(); +X } +X +X if (!(mem == 0xb0000 || +X mem == 0xc8000 || +X mem == 0xd0000 || +X mem == 0xd8000 || +X mem == 0xe0000 || +X mem == 0xe8000)) { +X fprintf(stderr, "error: mem must be one of " +X "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n"); +X usage(); +X } +X +X return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem); +} +X +static int cfg_mpu(int argc, char *argv[]) +{ +X int io, irq; +X +X if (argc < 2 || +X sscanf(argv[0], "0x%x", &io) != 1 || +X sscanf(argv[1], "%d", &irq) != 1) +X usage(); +X +X return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0); +} +X +static int cfg_ide(int argc, char *argv[]) +{ +X int io0, io1, irq; +X +X if (argc < 3 || +X sscanf(argv[0], "0x%x", &io0) != 1 || +X sscanf(argv[0], "0x%x", &io1) != 1 || +X sscanf(argv[1], "%d", &irq) != 1) +X usage(); +X +X return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0); +} +X +static int cfg_joystick(int argc, char *argv[]) +{ +X int io; +X +X if (argc < 1 || +X sscanf(argv[0], "0x%x", &io) != 1) +X usage(); +X +X return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0); +} +X +int main(int argc, char *argv[]) +{ +X char *device; +X int rv = 0; +X +X --argc; ++argv; +X +X if (argc < 2) +X usage(); +X +X sscanf(argv[0], "0x%x", &config_port); +X if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) { +X fprintf(stderr, "error: <config port> must be 0x250, 0x260 or 0x270\n"); +X exit(1); +X } +X if (ioperm(config_port, 2, 1)) { +X perror("ioperm"); +X fprintf(stderr, "note: pinnaclecfg must be run as root\n"); +X exit(1); +X } +X device = argv[1]; +X +X argc -= 2; argv += 2; +X +X if (strcmp(device, "reset") == 0) +X rv = cfg_reset(); +X else if (strcmp(device, "show") == 0) +X rv = cfg_show(); +X else if (strcmp(device, "dsp") == 0) +X rv = cfg_dsp(argc, argv); +X else if (strcmp(device, "mpu") == 0) +X rv = cfg_mpu(argc, argv); +X else if (strcmp(device, "ide") == 0) +X rv = cfg_ide(argc, argv); +X else if (strcmp(device, "joystick") == 0) +X rv = cfg_joystick(argc, argv); +X else { +X fprintf(stderr, "error: unknown device %s\n", device); +X usage(); +X } +X +X if (rv) +X fprintf(stderr, "error: device configuration failed\n"); +X +X return 0; +} +SHAR_EOF + $shar_touch -am 1204092598 'MultiSound.d/pinnaclecfg.c' && + chmod 0664 'MultiSound.d/pinnaclecfg.c' || + $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed' +366bdf27f0db767a3c7921d0a6db20fe MultiSound.d/pinnaclecfg.c +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`" + test 10235 -eq "$shar_count" || + $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10235,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/Makefile ============== +if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' && +CC = gcc +CFLAGS = -O +PROGS = setdigital msndreset pinnaclecfg conv +X +all: $(PROGS) +X +clean: +X rm -f $(PROGS) +SHAR_EOF + $shar_touch -am 1204092398 'MultiSound.d/Makefile' && + chmod 0664 'MultiSound.d/Makefile' || + $echo 'restore of' 'MultiSound.d/Makefile' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/Makefile:' 'MD5 check failed' +76ca8bb44e3882edcf79c97df6c81845 MultiSound.d/Makefile +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`" + test 106 -eq "$shar_count" || + $echo 'MultiSound.d/Makefile:' 'original size' '106,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/conv.l ============== +if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' && +%% +[ \n\t,\r] +\;.* +DB +[0-9A-Fa-f]+H { int n; sscanf(yytext, "%xH", &n); printf("%c", n); } +%% +int yywrap() { return 1; } +main() { yylex(); } +SHAR_EOF + $shar_touch -am 0828231798 'MultiSound.d/conv.l' && + chmod 0664 'MultiSound.d/conv.l' || + $echo 'restore of' 'MultiSound.d/conv.l' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/conv.l:' 'MD5 check failed' +d2411fc32cd71a00dcdc1f009e858dd2 MultiSound.d/conv.l +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`" + test 141 -eq "$shar_count" || + $echo 'MultiSound.d/conv.l:' 'original size' '141,' 'current size' "$shar_count!" + fi +fi +# ============= MultiSound.d/msndreset.c ============== +if test -f 'MultiSound.d/msndreset.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'MultiSound.d/msndreset.c' '(file already exists)' +else + $echo 'x -' extracting 'MultiSound.d/msndreset.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/msndreset.c' && +/********************************************************************* +X * +X * msndreset.c - resets the MultiSound card +X * +X * Copyright (C) 1998 Andrew Veliath +X * +X * This program is free software; you can redistribute it and/or modify +X * it under the terms of the GNU General Public License as published by +X * the Free Software Foundation; either version 2 of the License, or +X * (at your option) any later version. +X * +X * This program is distributed in the hope that it will be useful, +X * but WITHOUT ANY WARRANTY; without even the implied warranty of +X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +X * GNU General Public License for more details. +X * +X * You should have received a copy of the GNU General Public License +X * along with this program; if not, write to the Free Software +X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +X * +X ********************************************************************/ +X +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/soundcard.h> +X +int main(int argc, char *argv[]) +{ +X int fd; +X +X if (argc != 2) { +X fprintf(stderr, "usage: msndreset <mixer device>\n"); +X exit(1); +X } +X +X if ((fd = open(argv[1], O_RDWR)) < 0) { +X perror(argv[1]); +X exit(1); +X } +X +X if (ioctl(fd, SOUND_MIXER_PRIVATE1, 0) < 0) { +X fprintf(stderr, "error: msnd ioctl reset failed\n"); +X perror("ioctl"); +X close(fd); +X exit(1); +X } +X +X close(fd); +X +X return 0; +} +SHAR_EOF + $shar_touch -am 1204100698 'MultiSound.d/msndreset.c' && + chmod 0664 'MultiSound.d/msndreset.c' || + $echo 'restore of' 'MultiSound.d/msndreset.c' 'failed' + if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ + && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then + md5sum -c << SHAR_EOF >/dev/null 2>&1 \ + || $echo 'MultiSound.d/msndreset.c:' 'MD5 check failed' +c52f876521084e8eb25e12e01dcccb8a MultiSound.d/msndreset.c +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/msndreset.c'`" + test 1472 -eq "$shar_count" || + $echo 'MultiSound.d/msndreset.c:' 'original size' '1472,' 'current size' "$shar_count!" + fi +fi +rm -fr _sh01426 +exit 0 diff --git a/Documentation/sound/oss/NEWS b/Documentation/sound/oss/NEWS new file mode 100644 index 000000000000..a81e0ef72ae9 --- /dev/null +++ b/Documentation/sound/oss/NEWS @@ -0,0 +1,42 @@ +Linux 2.4 Sound Changes +2000-September-25 +Christoph Hellwig, <hch@infradead.org> + + + +=== isapnp support + +The Linux 2.4 Kernel does have reliable in-kernel isapnp support. +Some drivers (sb.o, ad1816.o awe_wave.o) do now support automatically +detecting and configuring isapnp devices. +If you have a not yet supported isapnp soundcard, mail me the content +of '/proc/isapnp' on your system and some information about your card +and its driver(s) so I can try to get isapnp working for it. + + + +=== soundcard resources on kernel commandline + +Before Linux 2.4 you had to specify the resources for sounddrivers +statically linked into the kernel at compile time +(in make config/menuconfig/xconfig). In Linux 2.4 the resources are +now specified at the boot-time kernel commandline (e.g. the lilo +'append=' line or everything that's after the kernel name in grub). +Read the Configure.help entry for your card for the parameters. + + +=== softoss is gone + +In Linux 2.4 the softoss in-kernel software synthesizer is no more aviable. +Use a user space software synthesizer like timidity instead. + + + +=== /dev/sndstat and /proc/sound are gone + +In older Linux versions those files exported some information about the +OSS/Free configuration to userspace. In Linux 2.3 they were removed because +they did not support the growing number of pci soundcards and there were +some general problems with this interface. + + diff --git a/Documentation/sound/oss/NM256 b/Documentation/sound/oss/NM256 new file mode 100644 index 000000000000..b503217488b3 --- /dev/null +++ b/Documentation/sound/oss/NM256 @@ -0,0 +1,280 @@ +======================================================= +Documentation for the NeoMagic 256AV/256ZX sound driver +======================================================= + +You're looking at version 1.1 of the driver. (Woohoo!) It has been +successfully tested against the following laptop models: + + Sony Z505S/Z505SX/Z505DX/Z505RX + Sony F150, F160, F180, F250, F270, F280, PCG-F26 + Dell Latitude CPi, CPt (various submodels) + +There are a few caveats, which is why you should read the entirety of +this document first. + +This driver was developed without any support or assistance from +NeoMagic. There is no warranty, expressed, implied, or otherwise. It +is free software in the public domain; feel free to use it, sell it, +give it to your best friends, even claim that you wrote it (but why?!) +but don't go whining to me, NeoMagic, Sony, Dell, or anyone else +when it blows up your computer. + +Version 1.1 contains a change to try and detect non-AC97 versions of +the hardware, and not install itself appropriately. It should also +reinitialize the hardware on an APM resume event, assuming that APM +was configured into your kernel. + +============ +Installation +============ + +Enable the sound drivers, the OSS sound drivers, and then the NM256 +driver. The NM256 driver *must* be configured as a module (it won't +give you any other choice). + +Next, do the usual "make modules" and "make modules_install". +Finally, insmod the soundcore, sound and nm256 modules. + +When the nm256 driver module is loaded, you should see a couple of +confirmation messages in the kernel logfile indicating that it found +the device (the device does *not* use any I/O ports or DMA channels). +Now try playing a wav file, futz with the CD-ROM if you have one, etc. + +The NM256 is entirely a PCI-based device, and all the necessary +information is automatically obtained from the card. It can only be +configured as a module in a vain attempt to prevent people from +hurting themselves. It works correctly if it shares an IRQ with +another device (it normally shares IRQ 9 with the builtin eepro100 +ethernet on the Sony Z505 laptops). + +It does not run the card in any sort of compatibility mode. It will +not work on laptops that have the SB16-compatible, AD1848-compatible +or CS4232-compatible codec/mixer; you will want to use the appropriate +compatible OSS driver with these chipsets. I cannot provide any +assistance with machines using the SB16, AD1848 or CS4232 compatible +versions. (The driver now attempts to detect the mixer version, and +will refuse to load if it believes the hardware is not +AC97-compatible.) + +The sound support is very basic, but it does include simultaneous +playback and record capability. The mixer support is also quite +simple, although this is in keeping with the rather limited +functionality of the chipset. + +There is no hardware synthesizer available, as the Losedows OPL-3 and +MIDI support is done via hardware emulation. + +Only three recording devices are available on the Sony: the +microphone, the CD-ROM input, and the volume device (which corresponds +to the stereo output). (Other devices may be available on other +models of laptops.) The Z505 series does not have a builtin CD-ROM, +so of course the CD-ROM input doesn't work. It does work on laptops +with a builtin CD-ROM drive. + +The mixer device does not appear to have any tone controls, at least +on the Z505 series. The mixer module checks for tone controls in the +AC97 mixer, and will enable them if they are available. + +============== +Known problems +============== + + * There are known problems with PCMCIA cards and the eepro100 ethernet + driver on the Z505S/Z505SX/Z505DX. Keep reading. + + * There are also potential problems with using a virtual X display, and + also problems loading the module after the X server has been started. + Keep reading. + + * The volume control isn't anywhere near linear. Sorry. This will be + fixed eventually, when I get sufficiently annoyed with it. (I doubt + it will ever be fixed now, since I've never gotten sufficiently + annoyed with it and nobody else seems to care.) + + * There are reports that the CD-ROM volume is very low. Since I do not + have a CD-ROM equipped laptop, I cannot test this (it's kinda hard to + do remotely). + + * Only 8 fixed-rate speeds are supported. This is mainly a chipset + limitation. It may be possible to support other speeds in the future. + + * There is no support for the telephone mixer/codec. There is support + for a phonein/phoneout device in the mixer driver; whether or not + it does anything is anyone's guess. (Reports on this would be + appreciated. You'll have to figure out how to get the phone to + go off-hook before it'll work, tho.) + + * This driver was not written with any cooperation or support from + NeoMagic. If you have any questions about this, see their website + for their official stance on supporting open source drivers. + +============ +Video memory +============ + +The NeoMagic sound engine uses a portion of the display memory to hold +the sound buffer. (Crazy, eh?) The NeoMagic video BIOS sets up a +special pointer at the top of video RAM to indicate where the top of +the audio buffer should be placed. + +At the present time XFree86 is apparently not aware of this. It will +thus write over either the pointer or the sound buffer with abandon. +(Accelerated-X seems to do a better job here.) + +This implies a few things: + + * Sometimes the NM256 driver has to guess at where the buffer + should be placed, especially if the module is loaded after the + X server is started. It's usually correct, but it will consistently + fail on the Sony F250. + + * Virtual screens greater than 1024x768x16 under XFree86 are + problematic on laptops with only 2.5MB of screen RAM. This + includes all of the 256AV-equipped laptops. (Virtual displays + may or may not work on the 256ZX, which has at least 4MB of + video RAM.) + +If you start having problems with random noise being output either +constantly (this is the usual symptom on the F250), or when windows +are moved around (this is the usual symptom when using a virtual +screen), the best fix is to + + * Don't use a virtual frame buffer. + * Make sure you load the NM256 module before the X server is + started. + +On the F250, it is possible to force the driver to load properly even +after the XFree86 server is started by doing: + + insmod nm256 buffertop=0x25a800 + +This forces the audio buffers to the correct offset in screen RAM. + +One user has reported a similar problem on the Sony F270, although +others apparently aren't seeing any problems. His suggested command +is + + insmod nm256 buffertop=0x272800 + +================= +Official WWW site +================= + +The official site for the NM256 driver is: + + http://www.uglx.org/sony.html + +You should always be able to get the latest version of the driver there, +and the driver will be supported for the foreseeable future. + +============== +Z505RX and IDE +============== + +There appears to be a problem with the IDE chipset on the Z505RX; one +of the symptoms is that sound playback periodically hangs (when the +disk is accessed). The user reporting the problem also reported that +enabling all of the IDE chipset workarounds in the kernel solved the +problem, tho obviously only one of them should be needed--if someone +can give me more details I would appreciate it. + +============================== +Z505S/Z505SX on-board Ethernet +============================== + +If you're using the on-board Ethernet Pro/100 ethernet support on the Z505 +series, I strongly encourage you to download the latest eepro100 driver from +Donald Becker's site: + + ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/test/eepro100.c + +There was a reported problem on the Z505SX that if the ethernet +interface is disabled and reenabled while the sound driver is loaded, +the machine would lock up. I have included a workaround that is +working satisfactorily. However, you may occasionally see a message +about "Releasing interrupts, over 1000 bad interrupts" which indicates +that the workaround is doing its job. + +================================== +PCMCIA and the Z505S/Z505SX/Z505DX +================================== + +There is also a known problem with the Sony Z505S and Z505SX hanging +if a PCMCIA card is inserted while the ethernet driver is loaded, or +in some cases if the laptop is suspended. This is caused by tons of +spurious IRQ 9s, probably generated from the PCMCIA or ACPI bridges. + +There is currently no fix for the problem that works in every case. +The only known workarounds are to disable the ethernet interface +before inserting or removing a PCMCIA card, or with some cards +disabling the PCMCIA card before ejecting it will also help the +problem with the laptop hanging when the card is ejected. + +One user has reported that setting the tcic's cs_irq to some value +other than 9 (like 11) fixed the problem. This doesn't work on my +Z505S, however--changing the value causes the cardmgr to stop seeing +card insertions and removals, cards don't seem to work correctly, and +I still get hangs if a card is inserted when the kernel is booted. + +Using the latest ethernet driver and pcmcia package allows me to +insert an Adaptec 1480A SlimScsi card without the laptop hanging, +although I still have to shut down the card before ejecting or +powering down the laptop. However, similar experiments with a DE-660 +ethernet card still result in hangs when the card is inserted. I am +beginning to think that the interrupts are CardBus-related, since the +Adaptec card is a CardBus card, and the DE-660 is not; however, I +don't have any other CardBus cards to test with. + +====== +Thanks +====== + +First, I want to thank everyone (except NeoMagic of course) for their +generous support and encouragement. I'd like to list everyone's name +here that replied during the development phase, but the list is +amazingly long. + +I will be rather unfair and single out a few people, however: + + Justin Maurer, for being the first random net.person to try it, + and for letting me login to his Z505SX to get it working there + + Edi Weitz for trying out several different versions, and giving + me a lot of useful feedback + + Greg Rumple for letting me login remotely to get the driver + functional on the 256ZX, for his assistance on tracking + down all sorts of random stuff, and for trying out Accel-X + + Zach Brown, for the initial AC97 mixer interface design + + Jeff Garzik, for various helpful suggestions on the AC97 + interface + + "Mr. Bumpy" for feedback on the Z505RX + + Bill Nottingham, for generous assistance in getting the mixer ID + code working + +================= +Previous versions +================= + +Versions prior to 0.3 (aka `noname') had problems with weird artifacts +in the output and failed to set the recording rate properly. These +problems have long since been fixed. + +Versions prior to 0.5 had problems with clicks in the output when +anything other than 16-bit stereo sound was being played, and also had +periodic clicks when recording. + +Version 0.7 first incorporated support for the NM256ZX chipset, which +is found on some Dell Latitude laptops (the CPt, and apparently +some CPi models as well). It also included the generic AC97 +mixer module. + +Version 0.75 renamed all the functions and files with slightly more +generic names. + +Note that previous versions of this document claimed that recording was +8-bit only; it actually has been working for 16-bits all along. diff --git a/Documentation/sound/oss/OPL3 b/Documentation/sound/oss/OPL3 new file mode 100644 index 000000000000..2468ff827688 --- /dev/null +++ b/Documentation/sound/oss/OPL3 @@ -0,0 +1,6 @@ +A pure OPL3 card is nice and easy to configure. Simply do + +insmod opl3 io=0x388 + +Change the I/O address in the very unlikely case this card is differently +configured diff --git a/Documentation/sound/oss/OPL3-SA b/Documentation/sound/oss/OPL3-SA new file mode 100644 index 000000000000..66a91835d918 --- /dev/null +++ b/Documentation/sound/oss/OPL3-SA @@ -0,0 +1,52 @@ +OPL3-SA1 sound driver (opl3sa.o) + +--- +Note: This howto only describes how to setup the OPL3-SA1 chip; this info +does not apply to the SA2, SA3, or SA4. +--- + +The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and +it's a decent little chip offering a WSS mode, a SB Pro emulation mode, MPU401 +and OPL3 FM Synth capabilities. + +You can enable inclusion of the driver via CONFIG_SOUND_OPL3SA1=m, or +CONFIG_SOUND_OPL3SA1=y through 'make config/xconfig/menuconfig'. + +You'll need to know all of the relevant info (irq, dma, and io port) for the +chip's WSS mode, since that is the mode the kernel sound driver uses, and of +course you'll also need to know about where the MPU401 and OPL3 ports and +IRQs are if you want to use those. + +Here's the skinny on how to load it as a module: + + modprobe opl3sa io=0x530 irq=11 dma=0 dma2=1 mpu_io=0x330 mpu_irq=5 + +Module options in detail: + + io: This is the WSS's port base. + irq: This is the WSS's IRQ. + dma: This is the WSS's DMA line. In my BIOS setup screen this was + listed as "WSS Play DMA" + dma2: This is the WSS's secondary DMA line. My BIOS calls it the + "WSS capture DMA" + + mpu_io: This is the MPU401's port base. + mpu_irq: This is the MPU401's IRQ. + +If you'd like to use the OPL3 FM Synthesizer, make sure you enable +CONFIG_SOUND_YM3812 (in 'make config'). That'll build the opl3.o module. + +Then a simple 'insmod opl3 io=0x388', and you now have FM Synth. + +You can also use the SoftOSS software synthesizer instead of the builtin OPL3. +Here's how: + +Say 'y' or 'm' to "SoftOSS software wave table engine" in make config. + +If you said yes, the software synth is available once you boot your new +kernel. + +If you chose to build it as a module, just insmod the resulting softoss2.o + +Questions? Comments? +<stiker@northlink.com> diff --git a/Documentation/sound/oss/OPL3-SA2 b/Documentation/sound/oss/OPL3-SA2 new file mode 100644 index 000000000000..d8b6d2bbada6 --- /dev/null +++ b/Documentation/sound/oss/OPL3-SA2 @@ -0,0 +1,210 @@ +Documentation for the OPL3-SA2, SA3, and SAx driver (opl3sa2.o) +--------------------------------------------------------------- + +Scott Murray, scott@spiteful.org +January 7, 2001 + +NOTE: All trade-marked terms mentioned below are properties of their + respective owners. + + +Supported Devices +----------------- + +This driver is for PnP soundcards based on the following Yamaha audio +controller chipsets: + +YMF711 aka OPL3-SA2 +YMF715 and YMF719 aka OPL3-SA3 + +Up until recently (December 2000), I'd thought the 719 to be a +different chipset, the OPL3-SAx. After an email exhange with +Yamaha, however, it turns out that the 719 is just a re-badged +715, and the chipsets are identical. The chipset detection code +has been updated to reflect this. + +Anyways, all of these chipsets implement the following devices: + +OPL3 FM synthesizer +Soundblaster Pro +Microsoft/Windows Sound System +MPU401 MIDI interface + +Note that this driver uses the MSS device, and to my knowledge these +chipsets enforce an either/or situation with the Soundblaster Pro +device and the MSS device. Since the MSS device has better +capabilities, I have implemented the driver to use it. + + +Mixer Channels +-------------- + +Older versions of this driver (pre-December 2000) had two mixers, +an OPL3-SA2 or SA3 mixer and a MSS mixer. The OPL3-SA[23] mixer +device contained a superset of mixer channels consisting of its own +channels and all of the MSS mixer channels. To simplify the driver +considerably, and to partition functionality better, the OPL3-SA[23] +mixer device now contains has its own specific mixer channels. They +are: + +Volume - Hardware master volume control +Bass - SA3 only, now supports left and right channels +Treble - SA3 only, now supports left and right channels +Microphone - Hardware microphone input volume control +Digital1 - Yamaha 3D enhancement "Wide" mixer + +All other mixer channels (e.g. "PCM", "CD", etc.) now have to be +controlled via the "MS Sound System (CS4231)" mixer. To facilitate +this, the mixer device creation order has been switched so that +the MSS mixer is created first. This allows accessing the majority +of the useful mixer channels even via single mixer-aware tools +such as "aumix". + + +Plug 'n Play +------------ + +In previous kernels (2.2.x), some configuration was required to +get the driver to talk to the card. Being the new millennium and +all, the 2.4.x kernels now support auto-configuration if ISA PnP +support is configured in. Theoretically, the driver even supports +having more than one card in this case. + +With the addition of PnP support to the driver, two new parameters +have been added to control it: + +isapnp - set to 0 to disable ISA PnP card detection + +multiple - set to 0 to disable multiple PnP card detection + + +Optional Parameters +------------------- + +Recent (December 2000) additions to the driver (based on a patch +provided by Peter Englmaier) are two new parameters: + +ymode - Set Yamaha 3D enhancement mode: + 0 = Desktop/Normal 5-12 cm speakers + 1 = Notebook PC (1) 3 cm speakers + 2 = Notebook PC (2) 1.5 cm speakers + 3 = Hi-Fi 16-38 cm speakers + +loopback - Set A/D input source. Useful for echo cancellation: + 0 = Mic Right channel (default) + 1 = Mono output loopback + +The ymode parameter has been tested and does work. The loopback +parameter, however, is untested. Any feedback on its usefulness +would be appreciated. + + +Manual Configuration +-------------------- + +If for some reason you decide not to compile ISA PnP support into +your kernel, or disabled the driver's usage of it by setting the +isapnp parameter as discussed above, then you will need to do some +manual configuration. There are two ways of doing this. The most +common is to use the isapnptools package to initialize the card, and +use the kernel module form of the sound subsystem and sound drivers. +Alternatively, some BIOS's allow manual configuration of installed +PnP devices in a BIOS menu, which should allow using the non-modular +sound drivers, i.e. built into the kernel. + +I personally use isapnp and modules, and do not have access to a PnP +BIOS machine to test. If you have such a beast, configuring the +driver to be built into the kernel should just work (thanks to work +done by David Luyer <luyer@ucs.uwa.edu.au>). You will still need +to specify settings, which can be done by adding: + +opl3sa2=<io>,<irq>,<dma>,<dma2>,<mssio>,<mpuio> + +to the kernel command line. For example: + +opl3sa2=0x370,5,0,1,0x530,0x330 + +If you are instead using the isapnp tools (as most people have been +before Linux 2.4.x), follow the directions in their documentation to +produce a configuration file. Here is the relevant excerpt I used to +use for my SA3 card from my isapnp.conf: + +(CONFIGURE YMH0800/-1 (LD 0 + +# NOTE: IO 0 is for the unused SoundBlaster part of the chipset. +(IO 0 (BASE 0x0220)) +(IO 1 (BASE 0x0530)) +(IO 2 (BASE 0x0388)) +(IO 3 (BASE 0x0330)) +(IO 4 (BASE 0x0370)) +(INT 0 (IRQ 5 (MODE +E))) +(DMA 0 (CHANNEL 0)) +(DMA 1 (CHANNEL 1)) + +Here, note that: + +Port Acceptable Range Purpose +---- ---------------- ------- +IO 0 0x0220 - 0x0280 SB base address, unused. +IO 1 0x0530 - 0x0F48 MSS base address +IO 2 0x0388 - 0x03F8 OPL3 base address +IO 3 0x0300 - 0x0334 MPU base address +IO 4 0x0100 - 0x0FFE card's own base address for its control I/O ports + +The IRQ and DMA values can be any that are considered acceptable for a +MSS. Assuming you've got isapnp all happy, then you should be able to +do something like the following (which matches up with the isapnp +configuration above): + +modprobe mpu401 +modprobe ad1848 +modprobe opl3sa2 io=0x370 mss_io=0x530 mpu_io=0x330 irq=5 dma=0 dma2=1 +modprobe opl3 io=0x388 + +See the section "Automatic Module Loading" below for how to set up +/etc/modprobe.conf to automate this. + +An important thing to remember that the opl3sa2 module's io argument is +for it's own control port, which handles the card's master mixer for +volume (on all cards), and bass and treble (on SA3 cards). + + +Troubleshooting +--------------- + +If all goes well and you see no error messages, you should be able to +start using the sound capabilities of your system. If you get an +error message while trying to insert the opl3sa2 module, then make +sure that the values of the various arguments match what you specified +in your isapnp configuration file, and that there is no conflict with +another device for an I/O port or interrupt. Checking the contents of +/proc/ioports and /proc/interrupts can be useful to see if you're +butting heads with another device. + +If you still cannot get the module to load, look at the contents of +your system log file, usually /var/log/messages. If you see the +message "opl3sa2: Unknown Yamaha audio controller version", then you +have a different chipset version than I've encountered so far. Look +for all messages in the log file that start with "opl3sa2: " and see +if they provide any clues. If you do not see the chipset version +message, and none of the other messages present in the system log are +helpful, email me some details and I'll try my best to help. + + +Automatic Module Loading +------------------------ + +Lastly, if you're using modules and want to set up automatic module +loading with kmod, the kernel module loader, here is the section I +currently use in my modprobe.conf file: + +# Sound +alias sound-slot-0 opl3sa2 +options opl3sa2 io=0x370 mss_io=0x530 mpu_io=0x330 irq=7 dma=0 dma2=3 +options opl3 io=0x388 + +That's all it currently takes to get an OPL3-SA3 card working on my +system. Once again, if you have any other problems, email me at the +address listed above. + +Scott diff --git a/Documentation/sound/oss/Opti b/Documentation/sound/oss/Opti new file mode 100644 index 000000000000..c15af3c07d46 --- /dev/null +++ b/Documentation/sound/oss/Opti @@ -0,0 +1,222 @@ +Support for the OPTi 82C931 chip +-------------------------------- +Note: parts of this README file apply also to other +cards that use the mad16 driver. + +Some items in this README file are based on features +added to the sound driver after Linux-2.1.91 was out. +By the time of writing this I do not know which official +kernel release will include these features. +Please do not report inconsistencies on older Linux +kernels. + +The OPTi 82C931 is supported in its non-PnP mode. +Usually you do not need to set jumpers, etc. The sound driver +will check the card status and if it is required it will +force the card into a mode in which it can be programmed. + +If you have another OS installed on your computer it is recommended +that Linux and the other OS use the same resources. + +Also, it is recommended that resources specified in /etc/modprobe.conf +and resources specified in /etc/isapnp.conf agree. + +Compiling the sound driver +-------------------------- +I highly recommend that you build a modularized sound driver. +This document does not cover a sound-driver which is built in +the kernel. + +Sound card support should be enabled as a module (chose m). +Answer 'm' for these items: + Generic OPL2/OPL3 FM synthesizer support (CONFIG_SOUND_ADLIB) + Microsoft Sound System support (CONFIG_SOUND_MSS) + Support for OPTi MAD16 and/or Mozart based cards (CONFIG_SOUND_MAD16) + FM synthesizer (YM3812/OPL-3) support (CONFIG_SOUND_YM3812) + +The configuration menu may ask for addresses, IRQ lines or DMA +channels. If the card is used as a module the module loading +options will override these values. + +For the OPTi 931 you can answer 'n' to: + Support MIDI in older MAD16 based cards (requires SB) (CONFIG_SOUND_MAD16_OLDCARD) +If you do need MIDI support in a Mozart or C928 based card you +need to answer 'm' to the above question. In that case you will +also need to answer 'm' to: + '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' (CONFIG_SOUND_SB) + +Go on and compile your kernel and modules. Install the modules. Run depmod -a. + +Using isapnptools +----------------- +In most systems with a PnP BIOS you do not need to use isapnp. The +initialization provided by the BIOS is sufficient for the driver +to pick up the card and continue initialization. + +If that fails, or if you have other PnP cards, you need to use isapnp +to initialize the card. +This was tested with isapnptools-1.11 but I recommend that you use +isapnptools-1.13 (or newer). Run pnpdump to dump the information +about your PnP cards. Then edit the resulting file and select +the options of your choice. This file is normally installed as +/etc/isapnp.conf. + +The driver has one limitation with respect to I/O port resources: +IO3 base must be 0x0E0C. Although isapnp allows other ports, this +address is hard-coded into the driver. + +Using kmod and autoloading the sound driver +------------------------------------------- +Comment: as of linux-2.1.90 kmod is replacing kerneld. +The config file '/etc/modprobe.conf' is used as before. + +This is the sound part of my /etc/modprobe.conf file. +Following that I will explain each line. + +alias mixer0 mad16 +alias audio0 mad16 +alias midi0 mad16 +alias synth0 opl3 +options sb mad16=1 +options mad16 irq=10 dma=0 dma16=1 io=0x530 joystick=1 cdtype=0 +options opl3 io=0x388 +install mad16 /sbin/modprobe -i mad16 && /sbin/ad1848_mixer_reroute 14 8 15 3 16 6 + +If you have an MPU daughtercard or onboard MPU you will want to add to the +"options mad16" line - eg + +options mad16 irq=5 dma=0 dma16=3 io=0x530 mpu_io=0x330 mpu_irq=9 + +To set the I/O and IRQ of the MPU. + + +Explain: + +alias mixer0 mad16 +alias audio0 mad16 +alias midi0 mad16 +alias synth0 opl3 + +When any sound device is opened the kernel requests auto-loading +of char-major-14. There is a built-in alias that translates this +request to loading the main sound module. + +The sound module in its turn will request loading of a sub-driver +for mixer, audio, midi or synthesizer device. The first 3 are +supported by the mad16 driver. The synth device is supported +by the opl3 driver. + +There is currently no way to autoload the sound device driver +if more than one card is installed. + +options sb mad16=1 + +This is left for historical reasons. If you enable the +config option 'Support MIDI in older MAD16 based cards (requires SB)' +or if you use an older mad16 driver it will force loading of the +SoundBlaster driver. This option tells the SB driver not to look +for a SB card but to wait for the mad16 driver. + +options mad16 irq=10 dma=0 dma16=1 io=0x530 joystick=1 cdtype=0 +options opl3 io=0x388 + +post-install mad16 /sbin/ad1848_mixer_reroute 14 8 15 3 16 6 + +This sets resources and options for the mad16 and opl3 drivers. +I use two DMA channels (only one is required) to enable full duplex. +joystick=1 enables the joystick port. cdtype=0 disables the cd port. +You can also set mpu_io and mpu_irq in the mad16 options for the +uart401 driver. + +This tells modprobe to run /sbin/ad1848_mixer_reroute after +mad16 is successfully loaded and initialized. The source +for ad1848_mixer_reroute is appended to the end of this readme +file. It is impossible for the sound driver to know the actual +connections to the mixer. The 3 inputs intended for cd, synth +and line-in are mapped to the generic inputs line1, line2 and +line3. This program reroutes these mixer channels to their +right names (note the right mapping depends on the actual sound +card that you use). +The numeric parameters mean: + 14=line1 8=cd - reroute line1 to the CD input. + 15=line2 3=synth - reroute line2 to the synthesizer input. + 16=line3 6=line - reroute line3 to the line input. +For reference on other input names look at the file +/usr/include/linux/soundcard.h. + +Using a joystick +----------------- +You must enable a joystick in the mad16 options. (also +in /etc/isapnp.conf if you use it). +Tested with regular analog joysticks. + +A CDROM drive connected to the sound card +----------------------------------------- +The 82C931 chip has support only for secondary ATAPI cdrom. +(cdtype=8). Loading the mad16 driver resets the C931 chip +and if a cdrom was already mounted it may cause a complete +system hang. Do not use the sound card if you have an alternative. +If you do use the sound card it is important that you load +the mad16 driver (use "modprobe mad16" to prevent auto-unloading) +before the cdrom is accessed the first time. + +Using the sound driver built-in to the kernel may help here, but... +Most new systems have a PnP BIOS and also two IDE controllers. +The IDE controller on the sound card may be needed only on older +systems (which have only one IDE controller) but these systems +also do not have a PnP BIOS - requiring isapnptools and a modularized +driver. + +Known problems +-------------- +1. See the section on "A CDROM drive connected to the sound card". + +2. On my system the codec cannot capture companded sound samples. + (eg., recording from /dev/audio). When any companded capture is + requested I get stereo-16 bit samples instead. Playback of + companded samples works well. Apparently this problem is not common + to all C931 based cards. I do not know how to identify cards that + have this problem. + +Source for ad1848_mixer_reroute.c +--------------------------------- +#include <stdio.h> +#include <fcntl.h> +#include <linux/soundcard.h> + +static char *mixer_names[SOUND_MIXER_NRDEVICES] = + SOUND_DEVICE_LABELS; + +int +main(int argc, char **argv) { + int val, from, to; + int i, fd; + + fd = open("/dev/mixer", O_RDWR); + if(fd < 0) { + perror("/dev/mixer"); + return 1; + } + + for(i = 2; i < argc; i += 2) { + from = atoi(argv[i-1]); + to = atoi(argv[i]); + + if(to == SOUND_MIXER_NONE) + fprintf(stderr, "%s: turning off mixer %s\n", + argv[0], mixer_names[to]); + else + fprintf(stderr, "%s: rerouting mixer %s to %s\n", + argv[0], mixer_names[from], mixer_names[to]); + + val = from << 8 | to; + + if(ioctl(fd, SOUND_MIXER_PRIVATE2, &val)) { + perror("AD1848 mixer reroute"); + return 1; + } + } + + return 0; +} + diff --git a/Documentation/sound/oss/PAS16 b/Documentation/sound/oss/PAS16 new file mode 100644 index 000000000000..951b3dce51b4 --- /dev/null +++ b/Documentation/sound/oss/PAS16 @@ -0,0 +1,163 @@ +Pro Audio Spectrum 16 for 2.3.99 and later +========================================= +by Thomas Molina (tmolina@home.com) +last modified 3 Mar 2001 +Acknowledgement to Axel Boldt (boldt@math.ucsb.edu) for stuff taken +from Configure.help, Riccardo Facchetti for stuff from README.OSS, +and others whose names I could not find. + +This documentation is relevant for the PAS16 driver (pas2_card.c and +friends) under kernel version 2.3.99 and later. If you are +unfamiliar with configuring sound under Linux, please read the +Sound-HOWTO, Documentation/sound/oss/Introduction and other +relevant docs first. + +The following information is relevant information from README.OSS +and legacy docs for the Pro Audio Spectrum 16 (PAS16): +================================================================== + +The pas2_card.c driver supports the following cards -- +Pro Audio Spectrum 16 (PAS16) and compatibles: + Pro Audio Spectrum 16 + Pro Audio Studio 16 + Logitech Sound Man 16 + NOTE! The original Pro Audio Spectrum as well as the PAS+ are not + and will not be supported by the driver. + +The sound driver configuration dialog +------------------------------------- + +Sound configuration starts by making some yes/no questions. Be careful +when answering to these questions since answering y to a question may +prevent some later ones from being asked. For example don't answer y to +the question about (PAS16) if you don't really have a PAS16. Sound +configuration may also be made modular by answering m to configuration +options presented. + +Note also that all questions may not be asked. The configuration program +may disable some questions depending on the earlier choices. It may also +select some options automatically as well. + + "ProAudioSpectrum 16 support", + - Answer 'y'_ONLY_ if you have a Pro Audio Spectrum _16_, + Pro Audio Studio 16 or Logitech SoundMan 16 (be sure that + you read the above list correctly). Don't answer 'y' if you + have some other card made by Media Vision or Logitech since they + are not PAS16 compatible. + NOTE! Since 3.5-beta10 you need to enable SB support (next question) + if you want to use the SB emulation of PAS16. It's also possible to + the emulation if you want to use a true SB card together with PAS16 + (there is another question about this that is asked later). + + "Generic OPL2/OPL3 FM synthesizer support", + - Answer 'y' if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). + The PAS16 has an OPL3-compatible FM chip. + +With PAS16 you can use two audio device files at the same time. /dev/dsp (and +/dev/audio) is connected to the 8/16 bit native codec and the /dev/dsp1 (and +/dev/audio1) is connected to the SB emulation (8 bit mono only). + + +The new stuff for 2.3.99 and later +============================================================================ +The following configuration options from Documentation/Configure.help +are relevant to configuring the PAS16: + +Sound card support +CONFIG_SOUND + If you have a sound card in your computer, i.e. if it can say more + than an occasional beep, say Y. Be sure to have all the information + about your sound card and its configuration down (I/O port, + interrupt and DMA channel), because you will be asked for it. + + You want to read the Sound-HOWTO, available from + http://www.tldp.org/docs.html#howto . General information + about the modular sound system is contained in the files + Documentation/sound/oss/Introduction. The file + Documentation/sound/oss/README.OSS contains some slightly outdated but + still useful information as well. + +OSS sound modules +CONFIG_SOUND_OSS + OSS is the Open Sound System suite of sound card drivers. They make + sound programming easier since they provide a common API. Say Y or M + here (the module will be called sound.o) if you haven't found a + driver for your sound card above, then pick your driver from the + list below. + +Persistent DMA buffers +CONFIG_SOUND_DMAP + Linux can often have problems allocating DMA buffers for ISA sound + cards on machines with more than 16MB of RAM. This is because ISA + DMA buffers must exist below the 16MB boundary and it is quite + possible that a large enough free block in this region cannot be + found after the machine has been running for a while. If you say Y + here the DMA buffers (64Kb) will be allocated at boot time and kept + until the shutdown. This option is only useful if you said Y to + "OSS sound modules", above. If you said M to "OSS sound modules" + then you can get the persistent DMA buffer functionality by passing + the command-line argument "dmabuf=1" to the sound.o module. + + Say y here for PAS16. + +ProAudioSpectrum 16 support +CONFIG_SOUND_PAS + Answer Y only if you have a Pro Audio Spectrum 16, ProAudio Studio + 16 or Logitech SoundMan 16 sound card. Don't answer Y if you have + some other card made by Media Vision or Logitech since they are not + PAS16 compatible. It is not necessary to enable the separate + Sound Blaster support; it is included in the PAS driver. + + If you compile the driver into the kernel, you have to add + "pas2=<io>,<irq>,<dma>,<dma2>,<sbio>,<sbirq>,<sbdma>,<sbdma2> + to the kernel command line. + +FM Synthesizer (YM3812/OPL-3) support +CONFIG_SOUND_YM3812 + Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). + Answering Y is usually a safe and recommended choice, however some + cards may have software (TSR) FM emulation. Enabling FM support with + these cards may cause trouble (I don't currently know of any such + cards, however). + Please read the file Documentation/sound/oss/OPL3 if your card has an + OPL3 chip. + If you compile the driver into the kernel, you have to add + "opl3=<io>" to the kernel command line. + + If you compile your drivers into the kernel, you MUST configure + OPL3 support as a module for PAS16 support to work properly. + You can then get OPL3 functionality by issuing the command: + insmod opl3 + In addition, you must either add the following line to + /etc/modprobe.conf: + options opl3 io=0x388 + or else add the following line to /etc/lilo.conf: + opl3=0x388 + + +EXAMPLES +=================================================================== +To use the PAS16 in my computer I have enabled the following sound +configuration options: + +CONFIG_SOUND=y +CONFIG_SOUND_OSS=y +CONFIG_SOUND_TRACEINIT=y +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_PAS=y +CONFIG_SOUND_SB=n +CONFIG_SOUND_YM3812=m + +I have also included the following append line in /etc/lilo.conf: +append="pas2=0x388,10,3,-1,0x220,5,1,-1 sb=0x220,5,1,-1 opl3=0x388" + +The io address of 0x388 is default configuration on the PAS16. The +irq of 10 and dma of 3 may not match your installation. The above +configuration enables PAS16, 8-bit Soundblaster and OPL3 +functionality. If Soundblaster functionality is not desired, the +following line would be appropriate: +append="pas2=0x388,10,3,-1,0,-1,-1,-1 opl3=0x388" + +If sound is built totally modular, the above options may be +specified in /etc/modprobe.conf for pas2, sb and opl3 +respectively. diff --git a/Documentation/sound/oss/PSS b/Documentation/sound/oss/PSS new file mode 100644 index 000000000000..187b9525e1f6 --- /dev/null +++ b/Documentation/sound/oss/PSS @@ -0,0 +1,41 @@ +The PSS cards and other ECHO based cards provide an onboard DSP with +downloadable programs and also has an AD1848 "Microsoft Sound System" +device. The PSS driver enables MSS and MPU401 modes of the card. SB +is not enabled since it doesn't work concurrently with MSS. + +If you build this driver as a module then the driver takes the following +parameters + +pss_io. The I/O base the PSS card is configured at (normally 0x220 + or 0x240) + +mss_io The base address of the Microsoft Sound System interface. + This is normally 0x530, but may be 0x604 or other addresses. + +mss_irq The interrupt assigned to the Microsoft Sound System + emulation. IRQ's 3,5,7,9,10,11 and 12 are available. If you + get IRQ errors be sure to check the interrupt is set to + "ISA/Legacy" in the BIOS on modern machines. + +mss_dma The DMA channel used by the Microsoft Sound System. + This can be 0, 1, or 3. DMA 0 is not available on older + machines and will cause a crash on them. + +mpu_io The MPU emulation base address. This sets the base of the + synthesizer. It is typically 0x330 but can be altered. + +mpu_irq The interrupt to use for the synthesizer. It must differ + from the IRQ used by the Microsoft Sound System port. + + +The mpu_io/mpu_irq fields are optional. If they are not specified the +synthesizer parts are not configured. + +When the module is loaded it looks for a file called +/etc/sound/pss_synth. This is the firmware file from the DOS install disks. +This fil holds a general MIDI emulation. The file expected is called +genmidi.ld on newer DOS driver install disks and synth.ld on older ones. + +You can also load alternative DSP algorithms into the card if you wish. One +alternative driver can be found at http://www.mpg123.de/ + diff --git a/Documentation/sound/oss/PSS-updates b/Documentation/sound/oss/PSS-updates new file mode 100644 index 000000000000..c84dd7597e64 --- /dev/null +++ b/Documentation/sound/oss/PSS-updates @@ -0,0 +1,88 @@ + This file contains notes for users of PSS sound cards who wish to use the +newly added features of the newest version of this driver. + + The major enhancements present in this new revision of this driver is the +addition of two new module parameters that allow you to take full advantage of +all the features present on your PSS sound card. These features include the +ability to enable both the builtin CDROM and joystick ports. + +pss_enable_joystick + + This parameter is basically a flag. A 0 will leave the joystick port +disabled, while a non-zero value would enable the joystick port. The default +setting is pss_enable_joystick=0 as this keeps this driver fully compatible +with systems that were using previous versions of this driver. If you wish to +enable the joystick port you will have to add pss_enable_joystick=1 as an +argument to the driver. To actually use the joystick port you will then have +to load the joystick driver itself. Just remember to load the joystick driver +AFTER the pss sound driver. + +pss_cdrom_port + + This parameter takes a port address as its parameter. Any available port +address can be specified to enable the CDROM port, except for 0x0 and -1 as +these values would leave the port disabled. Like the joystick port, the cdrom +port will require that an appropriate CDROM driver be loaded before you can make +use of the newly enabled CDROM port. Like the joystick port option above, +remember to load the CDROM driver AFTER the pss sound driver. While it may +differ on some PSS sound cards, all the PSS sound cards that I have seen have a +builtin Wearnes CDROM port. If this is the case with your PSS sound card you +should load aztcd with the appropriate port option that matches the port you +assigned to the CDROM port when you loaded your pss sound driver. (ex. +modprobe pss pss_cdrom_port=0x340 && modprobe aztcd aztcd=0x340) The default +setting of this parameter leaves the CDROM port disabled to maintain full +compatibility with systems using previous versions of this driver. + + Other options have also been added for the added convenience and utility +of the user. These options are only available if this driver is loaded as a +module. + +pss_no_sound + + This module parameter is a flag that can be used to tell the driver to +just configure non-sound components. 0 configures all components, a non-0 +value will only attept to configure the CDROM and joystick ports. This +parameter can be used by a user who only wished to use the builtin joystick +and/or CDROM port(s) of his PSS sound card. If this driver is loaded with this +parameter and with the parameter below set to true then a user can safely unload +this driver with the following command "rmmod pss && rmmod ad1848 && rmmod +mpu401 && rmmod sound && rmmod soundcore" and retain the full functionality of +his CDROM and/or joystick port(s) while gaining back the memory previously used +by the sound drivers. This default setting of this parameter is 0 to retain +full behavioral compatibility with previous versions of this driver. + +pss_keep_settings + + This parameter can be used to specify whether you want the driver to reset +all emulations whenever its unloaded. This can be useful for those who are +sharing resources (io ports, IRQ's, DMA's) between different ISA cards. This +flag can also be useful in that future versions of this driver may reset all +emulations by default on the driver's unloading (as it probably should), so +specifying it now will ensure that all future versions of this driver will +continue to work as expected. The default value of this parameter is 1 to +retain full behavioral compatibility with previous versions of this driver. + +pss_firmware + + This parameter can be used to specify the file containing the firmware +code so that a user could tell the driver where that file is located instead +of having to put it in a predefined location with a predefined name. The +default setting of this parameter is "/etc/sound/pss_synth" as this was the +path and filename the hardcoded value in the previous versions of this driver. + +Examples: + +# Normal PSS sound card system, loading of drivers. +# Should be specified in an rc file (ex. Slackware uses /etc/rc.d/rc.modules). + +/sbin/modprobe pss pss_io=0x220 mpu_io=0x338 mpu_irq=9 mss_io=0x530 mss_irq=10 mss_dma=1 pss_cdrom_port=0x340 pss_enable_joystick=1 +/sbin/modprobe aztcd aztcd=0x340 +/sbin/modprobe joystick + +# System using the PSS sound card just for its CDROM and joystick ports. +# Should be specified in an rc file (ex. Slackware uses /etc/rc.d/rc.modules). + +/sbin/modprobe pss pss_io=0x220 pss_cdrom_port=0x340 pss_enable_joystick=1 pss_no_sound=1 +/sbin/rmmod pss && /sbin/rmmod ad1848 && /sbin/rmmod mpu401 && /sbin/rmmod sound && /sbin/rmmod soundcore # This line not needed, but saves memory. +/sbin/modprobe aztcd aztcd=0x340 +/sbin/modprobe joystick diff --git a/Documentation/sound/oss/README.OSS b/Documentation/sound/oss/README.OSS new file mode 100644 index 000000000000..fd42b05b2f55 --- /dev/null +++ b/Documentation/sound/oss/README.OSS @@ -0,0 +1,1456 @@ +Introduction +------------ + +This file is a collection of all the old Readme files distributed with +OSS/Lite by Hannu Savolainen. Since the new Linux sound driver is founded +on it I think these information may still be interesting for users that +have to configure their sound system. + +Be warned: Alan Cox is the current maintainer of the Linux sound driver so if +you have problems with it, please contact him or the current device-specific +driver maintainer (e.g. for aedsp16 specific problems contact me). If you have +patches, contributions or suggestions send them to Alan: I'm sure they are +welcome. + +In this document you will find a lot of references about OSS/Lite or ossfree: +they are gone forever. Keeping this in mind and with a grain of salt this +document can be still interesting and very helpful. + +[ File edited 17.01.1999 - Riccardo Facchetti ] +[ Edited miroSOUND section 19.04.2001 - Robert Siemer ] + +OSS/Free version 3.8 release notes +---------------------------------- + +Please read the SOUND-HOWTO (available from sunsite.unc.edu and other Linux FTP +sites). It gives instructions about using sound with Linux. It's bit out of +date but still very useful. Information about bug fixes and such things +is available from the web page (see above). + +Please check http://www.opensound.com/pguide for more info about programming +with OSS API. + + ==================================================== +- THIS VERSION ____REQUIRES____ Linux 2.1.57 OR LATER. + ==================================================== + +Packages "snd-util-3.8.tar.gz" and "snd-data-0.1.tar.Z" +contain useful utilities to be used with this driver. +See http://www.opensound.com/ossfree/getting.html for +download instructions. + +If you are looking for the installation instructions, please +look forward into this document. + +Supported sound cards +--------------------- + +See below. + +Contributors +------------ + +This driver contains code by several contributors. In addition several other +persons have given useful suggestions. The following is a list of major +contributors. (I could have forgotten some names.) + + Craig Metz 1/2 of the PAS16 Mixer and PCM support + Rob Hooft Volume computation algorithm for the FM synth. + Mika Liljeberg uLaw encoding and decoding routines + Jeff Tranter Linux SOUND HOWTO document + Greg Lee Volume computation algorithm for the GUS and + lots of valuable suggestions. + Andy Warner ISC port + Jim Lowe, + Amancio Hasty Jr FreeBSD/NetBSD port + Anders Baekgaard Bug hunting and valuable suggestions. + Joerg Schubert SB16 DSP support (initial version). + Andrew Robinson Improvements to the GUS driver + Megens SA MIDI recording for SB and SB Pro (initial version). + Mikael Nordqvist Linear volume support for GUS and + nonblocking /dev/sequencer. + Ian Hartas SVR4.2 port + Markus Aroharju and + Risto Kankkunen Major contributions to the mixer support + of GUS v3.7. + Hunyue Yau Mixer support for SG NX Pro. + Marc Hoffman PSS support (initial version). + Rainer Vranken Initialization for Jazz16 (initial version). + Peter Trattler Initial version of loadable module support for Linux. + JRA Gibson 16 bit mode for Jazz16 (initial version) + Davor Jadrijevic MAD16 support (initial version) + Gregor Hoffleit Mozart support (initial version) + Riccardo Facchetti Audio Excel DSP 16 (aedsp16) support + James Hightower Spotting a tiny but important bug in CS423x support. + Denis Sablic OPTi 82C924 specific enhancements (non PnP mode) + Tim MacKenzie Full duplex support for OPTi 82C930. + + Please look at lowlevel/README for more contributors. + +There are probably many other names missing. If you have sent me some +patches and your name is not in the above list, please inform me. + +Sending your contributions or patches +------------------------------------- + +First of all it's highly recommended to contact me before sending anything +or before even starting to do any work. Tell me what you suggest to be +changed or what you have planned to do. Also ensure you are using the +very latest (development) version of OSS/Free since the change may already be +implemented there. In general it's a major waste of time to try to improve a +several months old version. Information about the latest version can be found +from http://www.opensound.com/ossfree. In general there is no point in +sending me patches relative to production kernels. + +Sponsors etc. +------------- + +The following companies have greatly helped development of this driver +in form of a free copy of their product: + +Novell, Inc. UnixWare personal edition + SDK +The Santa Cruz Operation, Inc. A SCO OpenServer + SDK +Ensoniq Corp, a SoundScape card and extensive amount of assistance +MediaTrix Peripherals Inc, a AudioTrix Pro card + SDK +Acer, Inc. a pair of AcerMagic S23 cards. + +In addition the following companies have provided me sufficient amount +of technical information at least some of their products (free or $$$): + +Advanced Gravis Computer Technology Ltd. +Media Vision Inc. +Analog Devices Inc. +Logitech Inc. +Aztech Labs Inc. +Crystal Semiconductor Corporation, +Integrated Circuit Systems Inc. +OAK Technology +OPTi +Turtle Beach +miro +Ad Lib Inc. ($$) +Music Quest Inc. ($$) +Creative Labs ($$$) + +If you have some problems +========================= + +Read the sound HOWTO (sunsite.unc.edu:/pub/Linux/docs/...?). +Also look at the home page (http://www.opensound.com/ossfree). It may +contain info about some recent bug fixes. + +It's likely that you have some problems when trying to use the sound driver +first time. Sound cards don't have standard configuration so there are no +good default configuration to use. Please try to use same I/O, DMA and IRQ +values for the sound card than with DOS. + +If you get an error message when trying to use the driver, please look +at /var/adm/messages for more verbose error message. + + +The following errors are likely with /dev/dsp and /dev/audio. + + - "No such device or address". + This error indicates that there are no suitable hardware for the + device file or the sound driver has been compiled without support for + this particular device. For example /dev/audio and /dev/dsp will not + work if "digitized voice support" was not enabled during "make config". + + - "Device or resource busy". Probably the IRQ (or DMA) channel + required by the sound card is in use by some other device/driver. + + - "I/O error". Almost certainly (99%) it's an IRQ or DMA conflict. + Look at the kernel messages in /var/adm/notice for more info. + + - "Invalid argument". The application is calling ioctl() + with impossible parameters. Check that the application is + for sound driver version 2.X or later. + +Linux installation +================== + +IMPORTANT! Read this if you are installing a separately + distributed version of this driver. + + Check that your kernel version works with this + release of the driver (see Readme). Also verify + that your current kernel version doesn't have more + recent sound driver version than this one. IT'S HIGHLY + RECOMMENDED THAT YOU USE THE SOUND DRIVER VERSION THAT + IS DISTRIBUTED WITH KERNEL SOURCES. + +- When installing separately distributed sound driver you should first + read the above notice. Then try to find proper directory where and how + to install the driver sources. You should not try to install a separately + distributed driver version if you are not able to find the proper way + yourself (in this case use the version that is distributed with kernel + sources). Remove old version of linux/drivers/sound directory before + installing new files. + +- To build the device files you need to run the enclosed shell script + (see below). You need to do this only when installing sound driver + first time or when upgrading to much recent version than the earlier + one. + +- Configure and compile Linux as normally (remember to include the + sound support during "make config"). Please refer to kernel documentation + for instructions about configuring and compiling kernel. File Readme.cards + contains card specific instructions for configuring this driver for + use with various sound cards. + +Boot time configuration (using lilo and insmod) +----------------------------------------------- + +This information has been removed. Too many users didn't believe +that it's really not necessary to use this method. Please look at +Readme of sound driver version 3.0.1 if you still want to use this method. + +Problems +-------- + +Common error messages: + +- /dev/???????: No such file or directory. +Run the script at the end of this file. + +- /dev/???????: No such device. +You are not running kernel which contains the sound driver. When using +modularized sound driver this error means that the sound driver is not +loaded. + +- /dev/????: No such device or address. +Sound driver didn't detect suitable card when initializing. Please look at +Readme.cards for info about configuring the driver with your card. Also +check for possible boot (insmod) time error messages in /var/adm/messages. + +- Other messages or problems +Please check http://www.opensound.com/ossfree for more info. + +Configuring version 3.8 (for Linux) with some common sound cards +================================================================ + +This document describes configuring sound cards with the freeware version of +Open Sound Systems (OSS/Free). Information about the commercial version +(OSS/Linux) and its configuration is available from +http://www.opensound.com/linux.html. Information presented here is +not valid for OSS/Linux. + +If you are unsure about how to configure OSS/Free +you can download the free evaluation version of OSS/Linux from the above +address. There is a chance that it can autodetect your sound card. In this case +you can use the information included in soundon.log when configuring OSS/Free. + + +IMPORTANT! This document covers only cards that were "known" when + this driver version was released. Please look at + http://www.opensound.com/ossfree for info about + cards introduced recently. + + When configuring the sound driver, you should carefully + check each sound configuration option (particularly + "Support for /dev/dsp and /dev/audio"). The default values + offered by these programs are not necessarily valid. + + +THE BIGGEST MISTAKES YOU CAN MAKE +================================= + +1. Assuming that the card is Sound Blaster compatible when it's not. +-------------------------------------------------------------------- + +The number one mistake is to assume that your card is compatible with +Sound Blaster. Only the cards made by Creative Technology or which have +one or more chips labeled by Creative are SB compatible. In addition there +are few sound chipsets which are SB compatible in Linux such as ESS1688 or +Jazz16. Note that SB compatibility in DOS/Windows does _NOT_ mean anything +in Linux. + +IF YOU REALLY ARE 150% SURE YOU HAVE A SOUND BLASTER YOU CAN SKIP THE REST OF +THIS CHAPTER. + +For most other "supposed to be SB compatible" cards you have to use other +than SB drivers (see below). It is possible to get most sound cards to work +in SB mode but in general it's a complete waste of time. There are several +problems which you will encounter by using SB mode with cards that are not +truly SB compatible: + +- The SB emulation is at most SB Pro (DSP version 3.x) which means that +you get only 8 bit audio (there is always an another ("native") mode which +gives the 16 bit capability). The 8 bit only operation is the reason why +many users claim that sound quality in Linux is much worse than in DOS. +In addition some applications require 16 bit mode and they produce just +noise with a 8 bit only device. +- The card may work only in some cases but refuse to work most of the +time. The SB compatible mode always requires special initialization which is +done by the DOS/Windows drivers. This kind of cards work in Linux after +you have warm booted it after DOS but they don't work after cold boot +(power on or reset). +- You get the famous "DMA timed out" messages. Usually all SB clones have +software selectable IRQ and DMA settings. If the (power on default) values +currently used by the card don't match configuration of the driver you will +get the above error message whenever you try to record or play. There are +few other reasons to the DMA timeout message but using the SB mode seems +to be the most common cause. + +2. Trying to use a PnP (Plug & Play) card just like an ordinary sound card +-------------------------------------------------------------------------- + +Plug & Play is a protocol defined by Intel and Microsoft. It lets operating +systems to easily identify and reconfigure I/O ports, IRQs and DMAs of ISA +cards. The problem with PnP cards is that the standard Linux doesn't currently +(versions 2.1.x and earlier) don't support PnP. This means that you will have +to use some special tricks (see later) to get a PnP card alive. Many PnP cards +work after they have been initialized but this is not always the case. + +There are sometimes both PnP and non-PnP versions of the same sound card. +The non-PnP version is the original model which usually has been discontinued +more than an year ago. The PnP version has the same name but with "PnP" +appended to it (sometimes not). This causes major confusion since the non-PnP +model works with Linux but the PnP one doesn't. + +You should carefully check if "Plug & Play" or "PnP" is mentioned in the name +of the card or in the documentation or package that came with the card. +Everything described in the rest of this document is not necessarily valid for +PnP models of sound cards even you have managed to wake up the card properly. +Many PnP cards are simply too different from their non-PnP ancestors which are +covered by this document. + + +Cards that are not (fully) supported by this driver +=================================================== + +See http://www.opensound.com/ossfree for information about sound cards +to be supported in future. + + +How to use sound without recompiling kernel and/or sound driver +=============================================================== + +There is a commercial sound driver which comes in precompiled form and doesn't +require recompiling of the kernel. See http://www.4Front-tech.com/oss.html for +more info. + + +Configuring PnP cards +===================== + +New versions of most sound cards use the so-called ISA PnP protocol for +soft configuring their I/O, IRQ, DMA and shared memory resources. +Currently at least cards made by Creative Technology (SB32 and SB32AWE +PnP), Gravis (GUS PnP and GUS PnP Pro), Ensoniq (Soundscape PnP) and +Aztech (some Sound Galaxy models) use PnP technology. The CS4232/4236 audio +chip by Crystal Semiconductor (Intel Atlantis, HP Pavilion and many other +motherboards) is also based on PnP technology but there is a "native" driver +available for it (see information about CS4232 later in this document). + +PnP sound cards (as well as most other PnP ISA cards) are not supported +by this version of the driver . Proper +support for them should be released during 97 once the kernel level +PnP support is available. + +There is a method to get most of the PnP cards to work. The basic method +is the following: + +1) Boot DOS so the card's DOS drivers have a chance to initialize it. +2) _Cold_ boot to Linux by using "loadlin.exe". Hitting ctrl-alt-del +works with older machines but causes a hard reset of all cards on recent +(Pentium) machines. +3) If you have the sound driver in Linux configured properly, the card should +work now. "Proper" means that I/O, IRQ and DMA settings are the same as in +DOS. The hard part is to find which settings were used. See the documentation of +your card for more info. + +Windows 95 could work as well as DOS but running loadlin may be difficult. +Probably you should "shut down" your machine to MS-DOS mode before running it. + +Some machines have a BIOS utility for setting PnP resources. This is a good +way to configure some cards. In this case you don't need to boot DOS/Win95 +before starting Linux. + +Another way to initialize PnP cards without DOS/Win95 is a Linux based +PnP isolation tool. When writing this there is a pre alpha test version +of such a tool available from ftp://ftp.demon.co.uk/pub/unix/linux/utils. The +file is called isapnptools-*. Please note that this tool is just a temporary +solution which may be incompatible with future kernel versions having proper +support for PnP cards. There are bugs in setting DMA channels in earlier +versions of isapnptools so at least version 1.6 is required with sound cards. + +Yet another way to use PnP cards is to use (commercial) OSS/Linux drivers. See +http://www.opensound.com/linux.html for more info. This is probably the way you +should do it if you don't want to spend time recompiling the kernel and +required tools. + + +Read this before trying to configure the driver +=============================================== + +There are currently many cards that work with this driver. Some of the cards +have native support while others work since they emulate some other +card (usually SB, MSS/WSS and/or MPU401). The following cards have native +support in the driver. Detailed instructions for configuring these cards +will be given later in this document. + +Pro Audio Spectrum 16 (PAS16) and compatibles: + Pro Audio Spectrum 16 + Pro Audio Studio 16 + Logitech Sound Man 16 + NOTE! The original Pro Audio Spectrum as well as the PAS+ are not + and will not be supported by the driver. + +Media Vision Jazz16 based cards + Pro Sonic 16 + Logitech SoundMan Wave + (Other Jazz based cards should work but I don't have any reports + about them). + +Sound Blasters + SB 1.0 to 2.0 + SB Pro + SB 16 + SB32/64/AWE + Configure SB32/64/AWE just like SB16. See lowlevel/README.awe + for information about using the wave table synth. + NOTE! AWE63/Gold and 16/32/AWE "PnP" cards need to be activated + using isapnptools before they work with OSS/Free. + SB16 compatible cards by other manufacturers than Creative. + You have been fooled since there are _no_ SB16 compatible + cards on the market (as of May 1997). It's likely that your card + is compatible just with SB Pro but there is also a non-SB- + compatible 16 bit mode. Usually it's MSS/WSS but it could also + be a proprietary one like MV Jazz16 or ESS ES688. OPTi + MAD16 chips are very common in so called "SB 16 bit cards" + (try with the MAD16 driver). + + ====================================================================== + "Supposed to be SB compatible" cards. + Forget the SB compatibility and check for other alternatives + first. The only cards that work with the SB driver in + Linux have been made by Creative Technology (there is at least + one chip on the card with "CREATIVE" printed on it). The + only other SB compatible chips are ESS and Jazz16 chips + (maybe ALSxxx chips too but they probably don't work). + Most other "16 bit SB compatible" cards such as "OPTi/MAD16" or + "Crystal" are _NOT_ SB compatible in Linux. + + Practically all sound cards have some kind of SB emulation mode + in addition to their native (16 bit) mode. In most cases this + (8 bit only) SB compatible mode doesn't work with Linux. If + you get it working it may cause problems with games and + applications which require 16 bit audio. Some 16 bit only + applications don't check if the card actually supports 16 bits. + They just dump 16 bit data to a 8 bit card which produces just + noise. + + In most cases the 16 bit native mode is supported by Linux. + Use the SB mode with "clones" only if you don't find anything + better from the rest of this doc. + ====================================================================== + +Gravis Ultrasound (GUS) + GUS + GUS + the 16 bit option + GUS MAX + GUS ACE (No MIDI port and audio recording) + GUS PnP (with RAM) + +MPU-401 and compatibles + The driver works both with the full (intelligent mode) MPU-401 + cards (such as MPU IPC-T and MQX-32M) and with the UART only + dumb MIDI ports. MPU-401 is currently the most common MIDI + interface. Most sound cards are compatible with it. However, + don't enable MPU401 mode blindly. Many cards with native support + in the driver have their own MPU401 driver. Enabling the standard one + will cause a conflict with these cards. So check if your card is + in the list of supported cards before enabling MPU401. + +Windows Sound System (MSS/WSS) + Even when Microsoft has discontinued their own Sound System card + they managed to make it a standard. MSS compatible cards are based on + a codec chip which is easily available from at least two manufacturers + (AD1848 by Analog Devices and CS4231/CS4248 by Crystal Semiconductor). + Currently most sound cards are based on one of the MSS compatible codec + chips. The CS4231 is used in the high quality cards such as GUS MAX, + MediaTrix AudioTrix Pro and TB Tropez (GUS MAX is not MSS compatible). + + Having a AD1848, CS4248 or CS4231 codec chip on the card is a good + sign. Even if the card is not MSS compatible, it could be easy to write + support for it. Note also that most MSS compatible cards + require special boot time initialization which may not be present + in the driver. Also, some MSS compatible cards have native support. + Enabling the MSS support with these cards is likely to + cause a conflict. So check if your card is listed in this file before + enabling the MSS support. + +Yamaha FM synthesizers (OPL2, OPL3 (not OPL3-SA) and OPL4) + Most sound cards have a FM synthesizer chip. The OPL2 is a 2 + operator chip used in the original AdLib card. Currently it's used + only in the cheapest (8 bit mono) cards. The OPL3 is a 4 operator + FM chip which provides better sound quality and/or more available + voices than the OPL2. The OPL4 is a new chip that has an OPL3 and + a wave table synthesizer packed onto the same chip. The driver supports + just the OPL3 mode directly. Most cards with an OPL4 (like + SM Wave and AudioTrix Pro) support the OPL4 mode using MPU401 + emulation. Writing a native OPL4 support is difficult + since Yamaha doesn't give information about their sample ROM chip. + + Enable the generic OPL2/OPL3 FM synthesizer support if your + card has a FM chip made by Yamaha. Don't enable it if your card + has a software (TRS) based FM emulator. + + ---------------------------------------------------------------- + NOTE! OPL3-SA is different chip than the ordinary OPL3. In addition + to the FM synth this chip has also digital audio (WSS) and + MIDI (MPU401) capabilities. Support for OPL3-SA is described below. + ---------------------------------------------------------------- + +Yamaha OPL3-SA1 + + Yamaha OPL3-SA1 (YMF701) is an audio controller chip used on some + (Intel) motherboards and on cheap sound cards. It should not be + confused with the original OPL3 chip (YMF278) which is entirely + different chip. OPL3-SA1 has support for MSS, MPU401 and SB Pro + (not used in OSS/Free) in addition to the OPL3 FM synth. + + There are also chips called OPL3-SA2, OPL3-SA3, ..., OPL3SA-N. They + are PnP chips and will not work with the OPL3-SA1 driver. You should + use the standard MSS, MPU401 and OPL3 options with these chips and to + activate the card using isapnptools. + +4Front Technologies SoftOSS + + SoftOSS is a software based wave table emulation which works with + any 16 bit stereo sound card. Due to its nature a fast CPU is + required (P133 is minimum). Although SoftOSS does _not_ use MMX + instructions it has proven out that recent processors (which appear + to have MMX) perform significantly better with SoftOSS than earlier + ones. For example a P166MMX beats a PPro200. SoftOSS should not be used + on 486 or 386 machines. + + The amount of CPU load caused by SoftOSS can be controlled by + selecting the CONFIG_SOFTOSS_RATE and CONFIG_SOFTOSS_VOICES + parameters properly (they will be prompted by make config). It's + recommended to set CONFIG_SOFTOSS_VOICES to 32. If you have a + P166MMX or faster (PPro200 is not faster) you can set + CONFIG_SOFTOSS_RATE to 44100 (kHz). However with slower systems it + recommended to use sampling rates around 22050 or even 16000 kHz. + Selecting too high values for these parameters may hang your + system when playing MIDI files with hight degree of polyphony + (number of concurrently playing notes). It's also possible to + decrease CONFIG_SOFTOSS_VOICES. This makes it possible to use + higher sampling rates. However using fewer voices decreases + playback quality more than decreasing the sampling rate. + + SoftOSS keeps the samples loaded on the system's RAM so much RAM is + required. SoftOSS should never be used on machines with less than 16 MB + of RAM since this is potentially dangerous (you may accidentally run out + of memory which probably crashes the machine). + + SoftOSS implements the wave table API originally designed for GUS. For + this reason all applications designed for GUS should work (at least + after minor modifications). For example gmod/xgmod and playmidi -g are + known to work. + + To work SoftOSS will require GUS compatible + patch files to be installed on the system (in /dos/ultrasnd/midi). You + can use the public domain MIDIA patchset available from several ftp + sites. + + ********************************************************************* + IMPORTANT NOTICE! The original patch set distributed with the Gravis + Ultrasound card is not in public domain (even though it's available from + some FTP sites). You should contact Voice Crystal (www.voicecrystal.com) + if you like to use these patches with SoftOSS included in OSS/Free. + ********************************************************************* + +PSS based cards (AD1848 + ADSP-2115 + Echo ESC614 ASIC) + Analog Devices and Echo Speech have together defined a sound card + architecture based on the above chips. The DSP chip is used + for emulation of SB Pro, FM and General MIDI/MT32. + + There are several cards based on this architecture. The most known + ones are Orchid SW32 and Cardinal DSP16. + + The driver supports downloading DSP algorithms to these cards. + + NOTE! You will have to use the "old" config script when configuring + PSS cards. + +MediaTrix AudioTrix Pro + The ATP card is built around a CS4231 codec and an OPL4 synthesizer + chips. The OPL4 mode is supported by a microcontroller running a + General MIDI emulator. There is also a SB 1.5 compatible playback mode. + +Ensoniq SoundScape and compatibles + Ensoniq has designed a sound card architecture based on the + OTTO synthesizer chip used in their professional MIDI synthesizers. + Several companies (including Ensoniq, Reveal and Spea) are selling + cards based on this architecture. + + NOTE! The SoundScape PnP is not supported by OSS/Free. Ensoniq VIVO and + VIVO90 cards are not compatible with Soundscapes so the Soundscape + driver will not work with them. You may want to use OSS/Linux with these + cards. + +OPTi MAD16 and Mozart based cards + The Mozart (OAK OTI-601), MAD16 (OPTi 82C928), MAD16 Pro (OPTi 82C929), + OPTi 82C924/82C925 (in _non_ PnP mode) and OPTi 82C930 interface + chips are used in many different sound cards, including some + cards by Reveal miro and Turtle Beach (Tropez). The purpose of these + chips is to connect other audio components to the PC bus. The + interface chip performs address decoding for the other chips. + NOTE! Tropez Plus is not MAD16 but CS4232 based. + NOTE! MAD16 PnP cards (82C924, 82C925, 82C931) are not MAD16 compatible + in the PnP mode. You will have to use them in MSS mode after having + initialized them using isapnptools or DOS. 82C931 probably requires + initialization using DOS/Windows (running isapnptools is not enough). + It's possible to use 82C931 with OSS/Free by jumpering it to non-PnP + mode (provided that the card has a jumper for this). In non-PnP mode + 82C931 is compatible with 82C930 and should work with the MAD16 driver + (without need to use isapnptools or DOS to initialize it). All OPTi + chips are supported by OSS/Linux (both in PnP and non-PnP modes). + +Audio Excel DSP16 + Support for this card was written by Riccardo Faccetti + (riccardo@cdc8g5.cdc.polimi.it). The AEDSP16 driver included in + the lowlevel/ directory. To use it you should enable the + "Additional low level drivers" option. + +Crystal CS4232 and CS4236 based cards such as AcerMagic S23, TB Tropez _Plus_ and + many PC motherboards (Compaq, HP, Intel, ...) + CS4232 is a PnP multimedia chip which contains a CS3231A codec, + SB and MPU401 emulations. There is support for OPL3 too. + Unfortunately the MPU401 mode doesn't work (I don't know how to + initialize it). CS4236 is an enhanced (compatible) version of CS4232. + NOTE! Don't ever try to use isapnptools with CS4232 since this will just + freeze your machine (due to chip bugs). If you have problems in getting + CS4232 working you could try initializing it with DOS (CS4232C.EXE) and + then booting Linux using loadlin. CS4232C.EXE loads a secret firmware + patch which is not documented by Crystal. + +Turtle Beach Maui and Tropez "classic" + This driver version supports sample, patch and program loading commands + described in the Maui/Tropez User's manual. + There is now full initialization support too. The audio side of + the Tropez is based on the MAD16 chip (see above). + NOTE! Tropez Plus is different card than Tropez "classic" and will not + work fully in Linux. You can get audio features working by configuring + the card as a CS4232 based card (above). + + +Jumpers and software configuration +================================== + +Some of the earliest sound cards were jumper configurable. You have to +configure the driver use I/O, IRQ and DMA settings +that match the jumpers. Just few 8 bit cards are fully jumper +configurable (SB 1.x/2.x, SB Pro and clones). +Some cards made by Aztech have an EEPROM which contains the +config info. These cards behave much like hardware jumpered cards. + +Most cards have jumper for the base I/O address but other parameters +are software configurable. Sometimes there are few other jumpers too. + +Latest cards are fully software configurable or they are PnP ISA +compatible. There are no jumpers on the board. + +The driver handles software configurable cards automatically. Just configure +the driver to use I/O, IRQ and DMA settings which are known to work. +You could usually use the same values than with DOS and/or Windows. +Using different settings is possible but not recommended since it may cause +some trouble (for example when warm booting from an OS to another or +when installing new hardware to the machine). + +Sound driver sets the soft configurable parameters of the card automatically +during boot. Usually you don't need to run any extra initialization +programs when booting Linux but there are some exceptions. See the +card-specific instructions below for more info. + +The drawback of software configuration is that the driver needs to know +how the card must be initialized. It cannot initialize unknown cards +even if they are otherwise compatible with some other cards (like SB, +MPU401 or Windows Sound System). + + +What if your card was not listed above? +======================================= + +The first thing to do is to look at the major IC chips on the card. +Many of the latest sound cards are based on some standard chips. If you +are lucky, all of them could be supported by the driver. The most common ones +are the OPTi MAD16, Mozart, SoundScape (Ensoniq) and the PSS architectures +listed above. Also look at the end of this file for list of unsupported +cards and the ones which could be supported later. + +The last resort is to send _exact_ name and model information of the card +to me together with a list of the major IC chips (manufactured, model) to +me. I could then try to check if your card looks like something familiar. + +There are many more cards in the world than listed above. The first thing to +do with these cards is to check if they emulate some other card or interface +such as SB, MSS and/or MPU401. In this case there is a chance to get the +card to work by booting DOS before starting Linux (boot DOS, hit ctrl-alt-del +and boot Linux without hard resetting the machine). In this method the +DOS based driver initializes the hardware to use known I/O, IRQ and DMA +settings. If sound driver is configured to use the same settings, everything +should work OK. + + +Configuring sound driver (with Linux) +===================================== + +The sound driver is currently distributed as part of the Linux kernel. The +files are in /usr/src/linux/drivers/sound/. + +**************************************************************************** +* ALWAYS USE THE SOUND DRIVER VERSION WHICH IS DISTRIBUTED WITH * +* THE KERNEL SOURCE PACKAGE YOU ARE USING. SOME ALPHA AND BETA TEST * +* VERSIONS CAN BE INSTALLED FROM A SEPARATELY DISTRIBUTED PACKAGE * +* BUT CHECK THAT THE PACKAGE IS NOT MUCH OLDER (OR NEWER) THAN THE * +* KERNEL YOU ARE USING. IT'S POSSIBLE THAT THE KERNEL/DRIVER * +* INTERFACE CHANGES BETWEEN KERNEL RELEASES WHICH MAY CAUSE SOME * +* INCOMPATIBILITY PROBLEMS. * +* * +* IN CASE YOU INSTALL A SEPARATELY DISTRIBUTED SOUND DRIVER VERSION, * +* BE SURE TO REMOVE OR RENAME THE OLD SOUND DRIVER DIRECTORY BEFORE * +* INSTALLING THE NEW ONE. LEAVING OLD FILES TO THE SOUND DRIVER * +* DIRECTORY _WILL_ CAUSE PROBLEMS WHEN THE DRIVER IS USED OR * +* COMPILED. * +**************************************************************************** + +To configure the driver, run "make config" in the kernel source directory +(/usr/src/linux). Answer "y" or "m" to the question about Sound card support +(after the questions about mouse, CD-ROM, ftape, etc. support). Questions +about options for sound will then be asked. + +After configuring the kernel and sound driver and compile the kernel +following instructions in the kernel README. + +The sound driver configuration dialog +------------------------------------- + +Sound configuration starts by making some yes/no questions. Be careful +when answering to these questions since answering y to a question may +prevent some later ones from being asked. For example don't answer y to +the first question (PAS16) if you don't really have a PAS16. Don't enable +more cards than you really need since they just consume memory. Also +some drivers (like MPU401) may conflict with your SCSI controller and +prevent kernel from booting. If you card was in the list of supported +cards (above), please look at the card specific config instructions +(later in this file) before starting to configure. Some cards must be +configured in way which is not obvious. + +So here is the beginning of the config dialog. Answer 'y' or 'n' to these +questions. The default answer is shown so that (y/n) means 'y' by default and +(n/y) means 'n'. To use the default value, just hit ENTER. But be careful +since using the default _doesn't_ guarantee anything. + +Note also that all questions may not be asked. The configuration program +may disable some questions depending on the earlier choices. It may also +select some options automatically as well. + + "ProAudioSpectrum 16 support", + - Answer 'y'_ONLY_ if you have a Pro Audio Spectrum _16_, + Pro Audio Studio 16 or Logitech SoundMan 16 (be sure that + you read the above list correctly). Don't answer 'y' if you + have some other card made by Media Vision or Logitech since they + are not PAS16 compatible. + NOTE! Since 3.5-beta10 you need to enable SB support (next question) + if you want to use the SB emulation of PAS16. It's also possible to + the emulation if you want to use a true SB card together with PAS16 + (there is another question about this that is asked later). + "Sound Blaster support", + - Answer 'y' if you have an original SB card made by Creative Labs + or a full 100% hardware compatible clone (like Thunderboard or + SM Games). If your card was in the list of supported cards (above), + please look at the card specific instructions later in this file + before answering this question. For an unknown card you may answer + 'y' if the card claims to be SB compatible. + Enable this option also with PAS16 (changed since v3.5-beta9). + + Don't enable SB if you have a MAD16 or Mozart compatible card. + + "Generic OPL2/OPL3 FM synthesizer support", + - Answer 'y' if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). + Answering 'y' is usually a safe and recommended choice. However some + cards may have software (TSR) FM emulation. Enabling FM support + with these cards may cause trouble. However I don't currently know + such cards. + "Gravis Ultrasound support", + - Answer 'y' if you have GUS or GUS MAX. Answer 'n' if you don't + have GUS since the GUS driver consumes much memory. + Currently I don't have experiences with the GUS ACE so I don't + know what to answer with it. + "MPU-401 support (NOT for SB16)", + - Be careful with this question. The MPU401 interface is supported + by almost any sound card today. However some natively supported cards + have their own driver for MPU401. Enabling the MPU401 option with + these cards will cause a conflict. Also enabling MPU401 on a system + that doesn't really have a MPU401 could cause some trouble. If your + card was in the list of supported cards (above), please look at + the card specific instructions later in this file. + + In MOST cases this MPU401 driver should only be used with "true" + MIDI-only MPU401 professional cards. In most other cases there + is another way to get the MPU401 compatible interface of a + sound card to work. + Support for the MPU401 compatible MIDI port of SB16, ESS1688 + and MV Jazz16 cards is included in the SB driver. Use it instead + of this separate MPU401 driver with these cards. As well + Soundscape, PSS and Maui drivers include their own MPU401 + options. + + It's safe to answer 'y' if you have a true MPU401 MIDI interface + card. + "6850 UART Midi support", + - It's safe to answer 'n' to this question in all cases. The 6850 + UART interface is so rarely used. + "PSS (ECHO-ADI2111) support", + - Answer 'y' only if you have Orchid SW32, Cardinal DSP16 or some + other card based on the PSS chipset (AD1848 codec + ADSP-2115 + DSP chip + Echo ESC614 ASIC CHIP). + "16 bit sampling option of GUS (_NOT_ GUS MAX)", + - Answer 'y' if you have installed the 16 bit sampling daughtercard + to your GUS. Answer 'n' if you have GUS MAX. Enabling this option + disables GUS MAX support. + "GUS MAX support", + - Answer 'y' only if you have a GUS MAX. + "Microsoft Sound System support", + - Again think carefully before answering 'y' to this question. It's + safe to answer 'y' in case you have the original Windows Sound + System card made by Microsoft or Aztech SG 16 Pro (or NX16 Pro). + Also you may answer 'y' in case your card was not listed earlier + in this file. For cards having native support in the driver, consult + the card specific instructions later in this file. Some drivers + have their own MSS support and enabling this option will cause a + conflict. + Note! The MSS driver permits configuring two DMA channels. This is a + "nonstandard" feature and works only with very few cards (if any). + In most cases the second DMA channel should be disabled or set to + the same channel than the first one. Trying to configure two separate + channels with cards that don't support this feature will prevent + audio (at least recording) from working. + "Ensoniq Soundscape support", + - Answer 'y' if you have a sound card based on the Ensoniq SoundScape + chipset. Such cards are being manufactured at least by Ensoniq, + Spea and Reveal (note that Reveal makes other cards also). The oldest + cards made by Spea don't work properly with Linux. + Soundscape PnP as well as Ensoniq VIVO work only with the commercial + OSS/Linux version. + "MediaTrix AudioTrix Pro support", + - Answer 'y' if you have the AudioTrix Pro. + "Support for MAD16 and/or Mozart based cards", + - Answer y if your card has a Mozart (OAK OTI-601) or MAD16 + (OPTi 82C928, 82C929, 82C924/82C925 or 82C930) audio interface chip. + These chips are + currently quite common so it's possible that many no-name cards + have one of them. In addition the MAD16 chip is used in some + cards made by known manufacturers such as Turtle Beach (Tropez), + Reveal (some models) and Diamond (some recent models). + Note OPTi 82C924 and 82C925 are MAD16 compatible only in non PnP + mode (jumper selectable on many cards). + "Support for TB Maui" + - This enables TB Maui specific initialization. Works with TB Maui + and TB Tropez (may not work with Tropez Plus). + + +Then the configuration program asks some y/n questions about the higher +level services. It's recommended to answer 'y' to each of these questions. +Answer 'n' only if you know you will not need the option. + + "MIDI interface support", + - Answering 'n' disables /dev/midi## devices and access to any + MIDI ports using /dev/sequencer and /dev/music. This option + also affects any MPU401 and/or General MIDI compatible devices. + "FM synthesizer (YM3812/OPL-3) support", + - Answer 'y' here. + "/dev/sequencer support", + - Answering 'n' disables /dev/sequencer and /dev/music. + +Entering the I/O, IRQ and DMA config parameters +----------------------------------------------- + +After the above questions the configuration program prompts for the +card specific configuration information. Usually just a set of +I/O address, IRQ and DMA numbers are asked. With some cards the program +asks for some files to be used during initialization of the card. For example +many cards have a DSP chip or microprocessor which must be initialized by +downloading a program (microcode) file to the card. + +Instructions for answering these questions are given in the next section. + + +Card specific information +========================= + +This section gives additional instructions about configuring some cards. +Please refer manual of your card for valid I/O, IRQ and DMA numbers. Using +the same settings with DOS/Windows and Linux is recommended. Using +different values could cause some problems when switching between +different operating systems. + +Sound Blasters (the original ones by Creative) +--------------------------------------------- + +NOTE! Check if you have a PnP Sound Blaster (cards sold after summer 1995 + are almost certainly PnP ones). With PnP cards you should use isapnptools + to activate them (see above). + +It's possible to configure these cards to use different I/O, IRQ and +DMA settings. Since the possible/default settings have changed between various +models, you have to consult manual of your card for the proper ones. It's +a good idea to use the same values than with DOS/Windows. With SB and SB Pro +it's the only choice. SB16 has software selectable IRQ and DMA channels but +using different values with DOS and Linux is likely to cause troubles. The +DOS driver is not able to reset the card properly after warm boot from Linux +if Linux has used different IRQ or DMA values. + +The original (steam) Sound Blaster (versions 1.x and 2.x) use always +DMA1. There is no way to change it. + +The SB16 needs two DMA channels. A 8 bit one (1 or 3) is required for +8 bit operation and a 16 bit one (5, 6 or 7) for the 16 bit mode. In theory +it's possible to use just one (8 bit) DMA channel by answering the 8 bit +one when the configuration program asks for the 16 bit one. This may work +in some systems but is likely to cause terrible noise on some other systems. + +It's possible to use two SB16/32/64 at the same time. To do this you should +first configure OSS/Free for one card. Then edit local.h manually and define +SB2_BASE, SB2_IRQ, SB2_DMA and SB2_DMA2 for the second one. You can't get +the OPL3, MIDI and EMU8000 devices of the second card to work. If you are +going to use two PnP Sound Blasters, ensure that they are of different model +and have different PnP IDs. There is no way to get two cards with the same +card ID and serial number to work. The easiest way to check this is trying +if isapnptools can see both cards or just one. + +NOTE! Don't enable the SM Games option (asked by the configuration program) + if you are not 101% sure that your card is a Logitech Soundman Games + (not a SM Wave or SM16). + +SB Clones +--------- + +First of all: There are no SB16 clones. There are SB Pro clones with a +16 bit mode which is not SB16 compatible. The most likely alternative is that +the 16 bit mode means MSS/WSS. + +There are just a few fully 100% hardware SB or SB Pro compatible cards. +I know just Thunderboard and SM Games. Other cards require some kind of +hardware initialization before they become SB compatible. Check if your card +was listed in the beginning of this file. In this case you should follow +instructions for your card later in this file. + +For other not fully SB clones you may try initialization using DOS in +the following way: + + - Boot DOS so that the card specific driver gets run. + - Hit ctrl-alt-del (or use loadlin) to boot Linux. Don't + switch off power or press the reset button. + - If you use the same I/O, IRQ and DMA settings in Linux, the + card should work. + +If your card is both SB and MSS compatible, I recommend using the MSS mode. +Most cards of this kind are not able to work in the SB and the MSS mode +simultaneously. Using the MSS mode provides 16 bit recording and playback. + +ProAudioSpectrum 16 and compatibles +----------------------------------- + +PAS16 has a SB emulation chip which can be used together with the native +(16 bit) mode of the card. To enable this emulation you should configure +the driver to have SB support too (this has been changed since version +3.5-beta9 of this driver). + +With current driver versions it's also possible to use PAS16 together with +another SB compatible card. In this case you should configure SB support +for the other card and to disable the SB emulation of PAS16 (there is a +separate questions about this). + +With PAS16 you can use two audio device files at the same time. /dev/dsp (and +/dev/audio) is connected to the 8/16 bit native codec and the /dev/dsp1 (and +/dev/audio1) is connected to the SB emulation (8 bit mono only). + +Gravis Ultrasound +----------------- + +There are many different revisions of the Ultrasound card (GUS). The +earliest ones (pre 3.7) don't have a hardware mixer. With these cards +the driver uses a software emulation for synth and pcm playbacks. It's +also possible to switch some of the inputs (line in, mic) off by setting +mixer volume of the channel level below 10%. For recording you have +to select the channel as a recording source and to use volume above 10%. + +GUS 3.7 has a hardware mixer. + +GUS MAX and the 16 bit sampling daughtercard have a CS4231 codec chip which +also contains a mixer. + +Configuring GUS is simple. Just enable the GUS support and GUS MAX or +the 16 bit daughtercard if you have them. Note that enabling the daughter +card disables GUS MAX driver. + +NOTE for owners of the 16 bit daughtercard: By default the daughtercard +uses /dev/dsp (and /dev/audio). Command "ln -sf /dev/dsp1 /dev/dsp" +selects the daughter card as the default device. + +With just the standard GUS enabled the configuration program prompts +for the I/O, IRQ and DMA numbers for the card. Use the same values than +with DOS. + +With the daughter card option enabled you will be prompted for the I/O, +IRQ and DMA numbers for the daughter card. You have to use different I/O +and DMA values than for the standard GUS. The daughter card permits +simultaneous recording and playback. Use /dev/dsp (the daughtercard) for +recording and /dev/dsp1 (GUS GF1) for playback. + +GUS MAX uses the same I/O address and IRQ settings than the original GUS +(GUS MAX = GUS + a CS4231 codec). In addition an extra DMA channel may be used. +Using two DMA channels permits simultaneous playback using two devices +(dev/dsp0 and /dev/dsp1). The second DMA channel is required for +full duplex audio. +To enable the second DMA channels, give a valid DMA channel when the config +program asks for the GUS MAX DMA (entering -1 disables the second DMA). +Using 16 bit DMA channels (5,6 or 7) is recommended. + +If you have problems in recording with GUS MAX, you could try to use +just one 8 bit DMA channel. Recording will not work with one DMA +channel if it's a 16 bit one. + +Microphone input of GUS MAX is connected to mixer in little bit nonstandard +way. There is actually two microphone volume controls. Normal "mic" controls +only recording level. Mixer control "speaker" is used to control volume of +microphone signal connected directly to line/speaker out. So just decrease +volume of "speaker" if you have problems with microphone feedback. + +GUS ACE works too but any attempt to record or to use the MIDI port +will fail. + +GUS PnP (with RAM) is partially supported but it needs to be initialized using +DOS or isapnptools before starting the driver. + +MPU401 and Windows Sound System +------------------------------- + +Again. Don't enable these options in case your card is listed +somewhere else in this file. + +Configuring these cards is obvious (or it should be). With MSS +you should probably enable the OPL3 synth also since +most MSS compatible cards have it. However check that this is true +before enabling OPL3. + +Sound driver supports more than one MPU401 compatible cards at the same time +but the config program asks config info for just the first of them. +Adding the second or third MPU interfaces must be done manually by +editing sound/local.h (after running the config program). Add defines for +MPU2_BASE & MPU2_IRQ (and MPU3_BASE & MPU3_IRQ) to the file. + +CAUTION! + +The default I/O base of Adaptec AHA-1542 SCSI controller is 0x330 which +is also the default of the MPU401 driver. Don't configure the sound driver to +use 0x330 as the MPU401 base if you have a AHA1542. The kernel will not boot +if you make this mistake. + +PSS +--- + +Even the PSS cards are compatible with SB, MSS and MPU401, you must not +enable these options when configuring the driver. The configuration +program handles these options itself. (You may use the SB, MPU and MSS options +together with PSS if you have another card on the system). + +The PSS driver enables MSS and MPU401 modes of the card. SB is not enabled +since it doesn't work concurrently with MSS. The driver loads also a +DSP algorithm which is used to for the general MIDI emulation. The +algorithm file (.ld) is read by the config program and written to a +file included when the pss.c is compiled. For this reason the config +program asks if you want to download the file. Use the genmidi.ld file +distributed with the DOS/Windows drivers of the card (don't use the mt32.ld). +With some cards the file is called 'synth.ld'. You must have access to +the file when configuring the driver. The easiest way is to mount the DOS +partition containing the file with Linux. + +It's possible to load your own DSP algorithms and run them with the card. +Look at the directory pss_test of snd-util-3.0.tar.gz for more info. + +AudioTrix Pro +------------- + +You have to enable the OPL3 and SB (not SB Pro or SB16) drivers in addition +to the native AudioTrix driver. Don't enable MSS or MPU drivers. + +Configuring ATP is little bit tricky since it uses so many I/O, IRQ and +DMA numbers. Using the same values than with DOS/Win is a good idea. Don't +attempt to use the same IRQ or DMA channels twice. + +The SB mode of ATP is implemented so the ATP driver just enables SB +in the proper address. The SB driver handles the rest. You have to configure +both the SB driver and the SB mode of ATP to use the same IRQ, DMA and I/O +settings. + +Also the ATP has a microcontroller for the General MIDI emulation (OPL4). +For this reason the driver asks for the name of a file containing the +microcode (TRXPRO.HEX). This file is usually located in the directory +where the DOS drivers were installed. You must have access to this file +when configuring the driver. + +If you have the effects daughtercard, it must be initialized by running +the setfx program of snd-util-3.0.tar.gz package. This step is not required +when using the (future) binary distribution version of the driver. + +Ensoniq SoundScape +------------------ + +NOTE! The new PnP SoundScape is not supported yet. Soundscape compatible + cards made by Reveal don't work with Linux. They use older revision + of the Soundscape chipset which is not fully compatible with + newer cards made by Ensoniq. + +The SoundScape driver handles initialization of MSS and MPU supports +itself so you don't need to enable other drivers than SoundScape +(enable also the /dev/dsp, /dev/sequencer and MIDI supports). + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!!!! !!!! +!!!!! NOTE! Before version 3.5-beta6 there WERE two sets of audio !!!! +!!!!! device files (/dev/dsp0 and /dev/dsp1). The first one WAS !!!! +!!!!! used only for card initialization and the second for audio !!!! +!!!!! purposes. It WAS required to change /dev/dsp (a symlink) to !!!! +!!!!! point to /dev/dsp1. !!!! +!!!!! !!!! +!!!!! This is not required with OSS versions 3.5-beta6 and later !!!! +!!!!! since there is now just one audio device file. Please !!!! +!!!!! change /dev/dsp to point back to /dev/dsp0 if you are !!!! +!!!!! upgrading from an earlier driver version using !!!! +!!!!! (cd /dev;rm dsp;ln -s dsp0 dsp). !!!! +!!!!! !!!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +The configuration program asks one DMA channel and two interrupts. One IRQ +and one DMA is used by the MSS codec. The second IRQ is required for the +MPU401 mode (you have to use different IRQs for both purposes). +There were earlier two DMA channels for SoundScape but the current driver +version requires just one. + +The SoundScape card has a Motorola microcontroller which must initialized +_after_ boot (the driver doesn't initialize it during boot). +The initialization is done by running the 'ssinit' program which is +distributed in the snd-util-3.0.tar.gz package. You have to edit two +defines in the ssinit.c and then compile the program. You may run ssinit +manually (after each boot) or add it to /etc/rc.d/rc.local. + +The ssinit program needs the microcode file that comes with the DOS/Windows +driver of the card. You will need to use version 1.30.00 or later +of the microcode file (sndscape.co0 or sndscape.co1 depending on +your card model). THE OLD sndscape.cod WILL NOT WORK. IT WILL HANG YOUR +MACHINE. The only way to get the new microcode file is to download +and install the DOS/Windows driver from ftp://ftp.ensoniq.com/pub. + +Then you have to select the proper microcode file to use: soundscape.co0 +is the right one for most cards and sndscape.co1 is for few (older) cards +made by Reveal and/or Spea. The driver has capability to detect the card +version during boot. Look at the boot log messages in /var/adm/messages +and locate the sound driver initialization message for the SoundScape +card. If the driver displays string <Ensoniq Soundscape (old)>, you have +an old card and you will need to use sndscape.co1. For other cards use +soundscape.co0. New Soundscape revisions such as Elite and PnP use +code files with higher numbers (.co2, .co3, etc.). + +NOTE! Ensoniq Soundscape VIVO is not compatible with other Soundscape cards. + Currently it's possible to use it in Linux only with OSS/Linux + drivers. + +Check /var/adm/messages after running ssinit. The driver prints +the board version after downloading the microcode file. That version +number must match the number in the name of the microcode file (extension). + +Running ssinit with a wrong version of the sndscape.co? file is not +dangerous as long as you don't try to use a file called sndscape.cod. +If you have initialized the card using a wrong microcode file (sounds +are terrible), just modify ssinit.c to use another microcode file and try +again. It's possible to use an earlier version of sndscape.co[01] but it +may sound weird. + +MAD16 (Pro) and Mozart +---------------------- + +You need to enable just the MAD16 /Mozart support when configuring +the driver. _Don't_ enable SB, MPU401 or MSS. However you will need the +/dev/audio, /dev/sequencer and MIDI supports. + +Mozart and OPTi 82C928 (the original MAD16) chips don't support +MPU401 mode so enter just 0 when the configuration program asks the +MPU/MIDI I/O base. The MAD16 Pro (OPTi 82C929) and 82C930 chips have MPU401 +mode. + +TB Tropez is based on the 82C929 chip. It has two MIDI ports. +The one connected to the MAD16 chip is the second one (there is a second +MIDI connector/pins somewhere??). If you have not connected the second MIDI +port, just disable the MIDI port of MAD16. The 'Maui' compatible synth of +Tropez is jumper configurable and not connected to the MAD16 chip (the +Maui driver can be used with it). + +Some MAD16 based cards may cause feedback, whistle or terrible noise if the +line3 mixer channel is turned too high. This happens at least with Shuttle +Sound System. Current driver versions set volume of line3 low enough so +this should not be a problem. + +If you have a MAD16 card which have an OPL4 (FM + Wave table) synthesizer +chip (_not_ an OPL3), you have to append a line containing #define MAD16_OPL4 +to the file linux/drivers/sound/local.h (after running make config). + +MAD16 cards having a CS4231 codec support full duplex mode. This mode +can be enabled by configuring the card to use two DMA channels. Possible +DMA channel pairs are: 0&1, 1&0 and 3&0. + +NOTE! Cards having an OPTi 82C924/82C925 chip work with OSS/Free only in +non-PnP mode (usually jumper selectable). The PnP mode is supported only +by OSS/Linux. + +MV Jazz (ProSonic) +------------------ + +The Jazz16 driver is just a hack made to the SB Pro driver. However it works +fairly well. You have to enable SB, SB Pro (_not_ SB16) and MPU401 supports +when configuring the driver. The configuration program asks later if you +want support for MV Jazz16 based cards (after asking SB base address). Answer +'y' here and the driver asks the second (16 bit) DMA channel. + +The Jazz16 driver uses the MPU401 driver in a way which will cause +problems if you have another MPU401 compatible card. In this case you must +give address of the Jazz16 based MPU401 interface when the config +program prompts for the MPU401 information. Then look at the MPU401 +specific section for instructions about configuring more than one MPU401 cards. + +Logitech Soundman Wave +---------------------- + +Read the above MV Jazz specific instructions first. + +The Logitech SoundMan Wave (don't confuse this with the SM16 or SM Games) is +a MV Jazz based card which has an additional OPL4 based wave table +synthesizer. The OPL4 chip is handled by an on board microcontroller +which must be initialized during boot. The config program asks if +you have a SM Wave immediately after asking the second DMA channel of jazz16. +If you answer 'y', the config program will ask name of the file containing +code to be loaded to the microcontroller. The file is usually called +MIDI0001.BIN and it's located in the DOS/Windows driver directory. The file +may also be called as TSUNAMI.BIN or something else (older cards?). + +The OPL4 synth will be inaccessible without loading the microcontroller code. + +Also remember to enable SB MPU401 support if you want to use the OPL4 mode. +(Don't enable the 'normal' MPU401 device as with some earlier driver +versions (pre 3.5-alpha8)). + +NOTE! Don't answer 'y' when the driver asks about SM Games support + (the next question after the MIDI0001.BIN name). However + answering 'y' doesn't cause damage your computer so don't panic. + +Sound Galaxies +-------------- + +There are many different Sound Galaxy cards made by Aztech. The 8 bit +ones are fully SB or SB Pro compatible and there should be no problems +with them. + +The older 16 bit cards (SG Pro16, SG NX Pro16, Nova and Lyra) have +an EEPROM chip for storing the configuration data. There is a microcontroller +which initializes the card to match the EEPROM settings when the machine +is powered on. These cards actually behave just like they have jumpers +for all of the settings. Configure driver for MSS, MPU, SB/SB Pro and OPL3 +supports with these cards. + +There are some new Sound Galaxies in the market. I have no experience with +them so read the card's manual carefully. + +ESS ES1688 and ES688 'AudioDrive' based cards +--------------------------------------------- + +Support for these two ESS chips is embedded in the SB driver. +Configure these cards just like SB. Enable the 'SB MPU401 MIDI port' +if you want to use MIDI features of ES1688. ES688 doesn't have MPU mode +so you don't need to enable it (the driver uses normal SB MIDI automatically +with ES688). + +NOTE! ESS cards are not compatible with MSS/WSS so don't worry if MSS support +of OSS doesn't work with it. + +There are some ES1688/688 based sound cards and (particularly) motherboards +which use software configurable I/O port relocation feature of the chip. +This ESS proprietary feature is supported only by OSS/Linux. + +There are ES1688 based cards which use different interrupt pin assignment than +recommended by ESS (5, 7, 9/2 and 10). In this case all IRQs don't work. +At least a card called (Pearl?) Hypersound 16 supports IRQ 15 but it doesn't +work. + +ES1868 is a PnP chip which is (supposed to be) compatible with ESS1688 +probably works with OSS/Free after initialization using isapnptools. + +Reveal cards +------------ + +There are several different cards made/marketed by Reveal. Some of them +are compatible with SoundScape and some use the MAD16 chip. You may have +to look at the card and try to identify its origin. + +Diamond +------- + +The oldest (Sierra Aria based) sound cards made by Diamond are not supported +(they may work if the card is initialized using DOS). The recent (LX?) +models are based on the MAD16 chip which is supported by the driver. + +Audio Excel DSP16 +----------------- + +Support for this card is currently not functional. A new driver for it +should be available later this year. + +PCMCIA cards +------------ + +Sorry, can't help. Some cards may work and some don't. + +TI TM4000M notebooks +-------------------- + +These computers have a built in sound support based on the Jazz chipset. +Look at the instructions for MV Jazz (above). It's also important to note +that there is something wrong with the mouse port and sound at least on +some TM models. Don't enable the "C&T 82C710 mouse port support" when +configuring Linux. Having it enabled is likely to cause mysterious problems +and kernel failures when sound is used. + +miroSOUND +--------- + +The miroSOUND PCM1-pro, PCM12 and PCM20 radio has been used +successfully. These cards are based on the MAD16, OPL4, and CS4231A chips +and everything said in the section about MAD16 cards applies here, +too. The only major difference between the PCMxx and other MAD16 cards +is that instead of the mixer in the CS4231 codec a separate mixer +controlled by an on-board 80C32 microcontroller is used. Control of +the mixer takes place via the ACI (miro's audio control interface) +protocol that is implemented in a separate lowlevel driver. Make sure +you compile this ACI driver together with the normal MAD16 support +when you use a miroSOUND PCMxx card. The ACI mixer is controlled by +/dev/mixer and the CS4231 mixer by /dev/mixer1 (depends on load +time). Only in special cases you want to change something regularly on +the CS4231 mixer. + +The miroSOUND PCM12 and PCM20 radio is capable of full duplex +operation (simultaneous PCM replay and recording), which allows you to +implement nice real-time signal processing audio effect software and +network telephones. The ACI mixer has to be switched into the "solo" +mode for duplex operation in order to avoid feedback caused by the +mixer (input hears output signal). You can de-/activate this mode +through toggleing the record button for the wave controller with an +OSS-mixer. + +The PCM20 contains a radio tuner, which is also controlled by +ACI. This radio tuner is supported by the ACI driver together with the +miropcm20.o module. Also the 7-band equalizer is integrated +(limited by the OSS-design). Developement has started and maybe +finished for the RDS decoder on this card, too. You will be able to +read RadioText, the Programme Service name, Programme TYpe and +others. Even the v4l radio module benefits from it with a refined +strength value. See aci.[ch] and miropcm20*.[ch] for more details. + +The following configuration parameters have worked fine for the PCM12 +in Markus Kuhn's system, many other configurations might work, too: +CONFIG_MAD16_BASE=0x530, CONFIG_MAD16_IRQ=11, CONFIG_MAD16_DMA=3, +CONFIG_MAD16_DMA2=0, CONFIG_MAD16_MPU_BASE=0x330, CONFIG_MAD16_MPU_IRQ=10, +DSP_BUFFSIZE=65536, SELECTED_SOUND_OPTIONS=0x00281000. + +Bas van der Linden is using his PCM1-pro with a configuration that +differs in: CONFIG_MAD16_IRQ=7, CONFIG_MAD16_DMA=1, CONFIG_MAD16_MPU_IRQ=9 + +Compaq Deskpro XL +----------------- + +The builtin sound hardware of Compaq Deskpro XL is now supported. +You need to configure the driver with MSS and OPL3 supports enabled. +In addition you need to manually edit linux/drivers/sound/local.h and +to add a line containing "#define DESKPROXL" if you used +make menuconfig/xconfig. + +Others? +------- + +Since there are so many different sound cards, it's likely that I have +forgotten to mention many of them. Please inform me if you know yet another +card which works with Linux, please inform me (or is anybody else +willing to maintain a database of supported cards (just like in XF86)?). + +Cards not supported yet +======================= + +Please check the version of sound driver you are using before +complaining that your card is not supported. It's possible you are +using a driver version which was released months before your card was +introduced. + +First of all, there is an easy way to make most sound cards work with Linux. +Just use the DOS based driver to initialize the card to a known state, then use +loadlin.exe to boot Linux. If Linux is configured to use the same I/O, IRQ and +DMA numbers as DOS, the card could work. +(ctrl-alt-del can be used in place of loadlin.exe but it doesn't work with +new motherboards). This method works also with all/most PnP sound cards. + +Don't get fooled with SB compatibility. Most cards are compatible with +SB but that may require a TSR which is not possible with Linux. If +the card is compatible with MSS, it's a better choice. Some cards +don't work in the SB and MSS modes at the same time. + +Then there are cards which are no longer manufactured and/or which +are relatively rarely used (such as the 8 bit ProAudioSpectrum +models). It's extremely unlikely that such cards ever get supported. +Adding support for a new card requires much work and increases time +required in maintaining the driver (some changes need to be done +to all low level drivers and be tested too, maybe with multiple +operating systems). For this reason I have made a decision to not support +obsolete cards. It's possible that someone else makes a separately +distributed driver (diffs) for the card. + +Writing a driver for a new card is not possible if there are no +programming information available about the card. If you don't +find your new card from this file, look from the home page +(http://www.opensound.com/ossfree). Then please contact +manufacturer of the card and ask if they have (or are willing to) +released technical details of the card. Do this before contacting me. I +can only answer 'no' if there are no programming information available. + +I have made decision to not accept code based on reverse engineering +to the driver. There are three main reasons: First I don't want to break +relationships to sound card manufacturers. The second reason is that +maintaining and supporting a driver without any specs will be a pain. +The third reason is that companies have freedom to refuse selling their +products to other than Windows users. + +Some companies don't give low level technical information about their +products to public or at least their require signing a NDA. It's not +possible to implement a freeware driver for them. However it's possible +that support for such cards become available in the commercial version +of this driver (see http://www.4Front-tech.com/oss.html for more info). + +There are some common audio chipsets that are not supported yet. For example +Sierra Aria and IBM Mwave. It's possible that these architectures +get some support in future but I can't make any promises. Just look +at the home page (http://www.opensound.com/ossfree/new_cards.html) +for latest info. + +Information about unsupported sound cards and chipsets is welcome as well +as free copies of sound cards, SDKs and operating systems. + +If you have any corrections and/or comments, please contact me. + +Hannu Savolainen +hannu@opensound.com + +Personal home page: http://www.compusonic.fi/~hannu +home page of OSS/Free: http://www.opensound.com/ossfree + +home page of commercial OSS +(Open Sound System) drivers: http://www.opensound.com/oss.html diff --git a/Documentation/sound/oss/README.awe b/Documentation/sound/oss/README.awe new file mode 100644 index 000000000000..80054cd8fcde --- /dev/null +++ b/Documentation/sound/oss/README.awe @@ -0,0 +1,218 @@ +================================================================ + AWE32 Sound Driver for Linux / FreeBSD + version 0.4.3; Nov. 1, 1998 + + Takashi Iwai <iwai@ww.uni-erlangen.de> +================================================================ + +* GENERAL NOTES + +This is a sound driver extension for SoundBlaster AWE32 and other +compatible cards (AWE32-PnP, SB32, SB32-PnP, AWE64 & etc) to enable +the wave synth operations. The driver is provided for Linux 1.2.x +and 2.[012].x kernels, as well as FreeBSD, on Intel x86 and DEC +Alpha systems. + +This driver was written by Takashi Iwai <iwai@ww.uni-erlangen.de>, +and provided "as is". The original source (awedrv-0.4.3.tar.gz) and +binary packages are available on the following URL: + http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/ +Note that since the author is apart from this web site, the update is +not frequent now. + + +* NOTE TO LINUX USERS + +To enable this driver on linux-2.[01].x kernels, you need turn on +"AWE32 synth" options in sound menu when configure your linux kernel +and modules. The precise installation procedure is described in the +AWE64-Mini-HOWTO and linux-kernel/Documetation/sound/AWE32. + +If you're using PnP cards, the card must be initialized before loading +the sound driver. There're several options to do this: + - Initialize the card via ISA PnP tools, and load the sound module. + - Initialize the card on DOS, and load linux by loadlin.exe + - Use PnP kernel driver (for Linux-2.x.x) +The detailed instruction for the solution using isapnp tools is found +in many documents like above. A brief instruction is also included in +the installation document of this package. +For PnP driver project, please refer to the following URL: + http://www-jcr.lmh.ox.ac.uk/~pnp/ + + +* USING THE DRIVER + +The awedrv has several different playing modes to realize easy channel +allocation for MIDI songs. To hear the exact sound quality, you need +to obtain the extended sequencer program, drvmidi or playmidi-2.5. + +For playing MIDI files, you *MUST* load the soundfont file on the +driver previously by sfxload utility. Otherwise you'll here no sounds +at all! All the utilities and driver source packages are found in the +above URL. The sfxload program is included in the package +awesfx-0.4.3.tgz. Binary packages are available there, too. See the +instruction in each package for installation. + +Loading a soundfont file is very simple. Just execute the command + + % sfxload synthgm.sbk + +Then, sfxload transfers the file "synthgm.sbk" to the driver. +Both SF1 and SF2 formats are accepted. + +Now you can hear midi musics by a midi player. + + % drvmidi foo.mid + +If you run MIDI player after MOD player, you need to load soundfont +files again, since MOD player programs clear the previous loaded +samples by their own data. + +If you have only 512kb on the sound card, I recommend to use dynamic +sample loading via -L option of drvmidi. 2MB GM/GS soundfont file is +available in most midi files. + + % sfxload synthgm + % drvmidi -L 2mbgmgs foo.mid + +This makes a big difference (believe me)! For more details, please +refer to the FAQ list which is available on the URL above. + +The current chorus, reverb and equalizer status can be changed by +aweset utility program (included in awesfx package). Note that +some awedrv-native programs (like drvmidi and xmp) will change the +current settings by themselves. The aweset program is effective +only for other programs like playmidi. + +Enjoy. + + +* COMPILE FLAGS + +Compile conditions are defined in awe_config.h. + +[Compatibility Conditions] +The following flags are defined automatically when using installation +shell script. + +- AWE_MODULE_SUPPORT + indicates your Linux kernel supports module for each sound card + (in recent 2.1 or 2.2 kernels and unofficial patched 2.0 kernels + as distributed in the RH5.0 package). + This flag is automatically set when you're using 2.1.x kernels. + You can pass the base address and memory size via the following + module options, + io = base I/O port address (eg. 0x620) + memsize = DRAM size in kilobytes (eg. 512) + As default, AWE driver probes these values automatically. + + +[Hardware Conditions] +You DON'T have to define the following two values. +Define them only when the driver couldn't detect the card properly. + +- AWE_DEFAULT_BASE_ADDR (default: not defined) + specifies the base port address of your AWE32 card. + 0 means to autodetect the address. + +- AWE_DEFAULT_MEM_SIZE (default: not defined) + specifies the memory size of your AWE32 card in kilobytes. + -1 means to autodetect its size. + + +[Sample Table Size] +From ver.0.4.0, sample tables are allocated dynamically (except +Linux-1.2.x system), so you need NOT to touch these parameters. +Linux-1.2.x users may need to increase these values to appropriate size +if the sound card is equipped with more DRAM. + +- AWE_MAX_SF_LISTS, AWE_MAX_SAMPLES, AWE_MAX_INFOS + + +[Other Conditions] + +- AWE_ALWAYS_INIT_FM (default: not defined) + indicates the AWE driver always initialize FM passthrough even + without DRAM on board. Emu8000 chip has a restriction for playing + samples on DRAM that at least two channels must be occupied as + passthrough channels. + +- AWE_DEBUG_ON (default: defined) + turns on debugging messages if defined. + +- AWE_HAS_GUS_COMPATIBILITY (default: defined) + Enables GUS compatibility mode if defined, reading GUS patches and + GUS control commands. Define this option to use GMOD or other + GUS module players. + +- CONFIG_AWE32_MIDIEMU (default: defined) + Adds a MIDI emulation device by Emu8000 wavetable. The emulation + device can be accessed as an external MIDI, and sends the MIDI + control codes directly. XG and GS sysex/NRPN are accepted. + No MIDI input is supported. + +- CONFIG_AWE32_MIXER (default: not defined) + Adds a mixer device for AWE32 bass/treble equalizer control. + You can access this device using /dev/mixer?? (usually mixer01). + +- AWE_USE_NEW_VOLUME_CALC (default: defined) + Use the new method to calculate the volume change as compatible + with DOS/Win drivers. This option can be toggled via aweset + program, or drvmidi player. + +- AWE_CHECK_VTARGET (default: defined) + Check the current volume target value when searching for an + empty channel to allocate a new voice. This is experimentally + implemented in this version. (probably, this option doesn't + affect the sound quality severely...) + +- AWE_ALLOW_SAMPLE_SHARING (default: defined) + Allow sample sharing for differently loaded patches. + This function is available only together with awesfx-0.4.3p3. + Note that this is still an experimental option. + +- DEF_FM_CHORUS_DEPTH (default: 0x10) + The default strength to be sent to the chorus effect engine. + From 0 to 0xff. Larger numbers may often cause weird sounds. + +- DEF_FM_REVERB_DEPTH (default: 0x10) + The default strength to be sent to the reverb effect engine. + From 0 to 0xff. Larger numbers may often cause weird sounds. + + +* ACKNOWLEDGMENTS + +Thanks to Witold Jachimczyk (witek@xfactor.wpi.edu) for much advice +on programming of AWE32. Much code is brought from his AWE32-native +MOD player, ALMP. +The port of awedrv to FreeBSD is done by Randall Hopper +(rhh@ct.picker.com). +The new volume calculation routine was derived from Mark Weaver's +ADIP compatible routines. +I also thank linux-awe-ml members for their efforts +to reboot their system many times :-) + + +* TODO'S + +- Complete DOS/Win compatibility +- DSP-like output + + +* COPYRIGHT + +Copyright (C) 1996-1998 Takashi Iwai + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/Documentation/sound/oss/README.modules b/Documentation/sound/oss/README.modules new file mode 100644 index 000000000000..e691d74e1e5e --- /dev/null +++ b/Documentation/sound/oss/README.modules @@ -0,0 +1,106 @@ +Building a modular sound driver +================================ + + The following information is current as of linux-2.1.85. Check the other +readme files, especially README.OSS, for information not specific to +making sound modular. + + First, configure your kernel. This is an idea of what you should be +setting in the sound section: + +<M> Sound card support + +<M> 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support + + I have SoundBlaster. Select your card from the list. + +<M> Generic OPL2/OPL3 FM synthesizer support +<M> FM synthesizer (YM3812/OPL-3) support + + If you don't set these, you will probably find you can play .wav files +but not .midi. As the help for them says, set them unless you know your +card does not use one of these chips for FM support. + + Once you are configured, make zlilo, modules, modules_install; reboot. +Note that it is no longer necessary or possible to configure sound in the +drivers/sound dir. Now one simply configures and makes one's kernel and +modules in the usual way. + + Then, add to your /etc/modprobe.conf something like: + +alias char-major-14-* sb +install sb /sbin/modprobe -i sb && /sbin/modprobe adlib_card +options sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330 +options adlib_card io=0x388 # FM synthesizer + + Alternatively, if you have compiled in kernel level ISAPnP support: + +alias char-major-14 sb +post-install sb /sbin/modprobe "-k" "adlib_card" +options adlib_card io=0x388 + + The effect of this is that the sound driver and all necessary bits and +pieces autoload on demand, assuming you use kerneld (a sound choice) and +autoclean when not in use. Also, options for the device drivers are +set. They will not work without them. Change as appropriate for your card. +If you are not yet using the very cool kerneld, you will have to "modprobe +-k sb" yourself to get things going. Eventually things may be fixed so +that this kludgery is not necessary; for the time being, it seems to work +well. + + Replace 'sb' with the driver for your card, and give it the right +options. To find the filename of the driver, look in +/lib/modules/<kernel-version>/misc. Mine looks like: + +adlib_card.o # This is the generic OPLx driver +opl3.o # The OPL3 driver +sb.o # <<The SoundBlaster driver. Yours may differ.>> +sound.o # The sound driver +uart401.o # Used by sb, maybe other cards + + Whichever card you have, try feeding it the options that would be the +default if you were making the driver wired, not as modules. You can +look at function referred to by module_init() for the card to see what +args are expected. + + Note that at present there is no way to configure the io, irq and other +parameters for the modular drivers as one does for the wired drivers.. One +needs to pass the modules the necessary parameters as arguments, either +with /etc/modprobe.conf or with command-line args to modprobe, e.g. + +modprobe sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330 +modprobe adlib_card io=0x388 + + recommend using /etc/modprobe.conf. + +Persistent DMA Buffers: + +The sound modules normally allocate DMA buffers during open() and +deallocate them during close(). Linux can often have problems allocating +DMA buffers for ISA cards on machines with more than 16MB RAM. This is +because ISA DMA buffers must exist below the 16MB boundary and it is quite +possible that we can't find a large enough free block in this region after +the machine has been running for any amount of time. The way to avoid this +problem is to allocate the DMA buffers during module load and deallocate +them when the module is unloaded. For this to be effective we need to load +the sound modules right after the kernel boots, either manually or by an +init script, and keep them around until we shut down. This is a little +wasteful of RAM, but it guarantees that sound always works. + +To make the sound driver use persistent DMA buffers we need to pass the +sound.o module a "dmabuf=1" command-line argument. This is normally done +in /etc/modprobe.conf like so: + +options sound dmabuf=1 + +If you have 16MB or less RAM or a PCI sound card, this is wasteful and +unnecessary. It is possible that machine with 16MB or less RAM will find +this option useful, but if your machine is so memory-starved that it +cannot find a 64K block free, you will be wasting even more RAM by keeping +the sound modules loaded and the DMA buffers allocated when they are not +needed. The proper solution is to upgrade your RAM. But you do also have +this improper solution as well. Use it wisely. + + I'm afraid I know nothing about anything but my setup, being more of a +text-mode guy anyway. If you have options for other cards or other helpful +hints, send them to me, Jim Bray, jb@as220.org, http://as220.org/jb. diff --git a/Documentation/sound/oss/README.ymfsb b/Documentation/sound/oss/README.ymfsb new file mode 100644 index 000000000000..af8a7d3a4e8e --- /dev/null +++ b/Documentation/sound/oss/README.ymfsb @@ -0,0 +1,107 @@ +Legacy audio driver for YMF7xx PCI cards. + + +FIRST OF ALL +============ + + This code references YAMAHA's sample codes and data sheets. + I respect and thank for all people they made open the informations + about YMF7xx cards. + + And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s + old VIA 82Cxxx driver (via82cxxx.c). I also respect him. + + +DISCLIMER +========= + + This driver is currently at early ALPHA stage. It may cause serious + damage to your computer when used. + PLEASE USE IT AT YOUR OWN RISK. + + +ABOUT THIS DRIVER +================= + + This code enables you to use your YMF724[A-F], YMF740[A-C], YMF744, YMF754 + cards. When enabled, your card acts as "SoundBlaster Pro" compatible card. + It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI + port. + If you want to use your card as recent "16-bit" card, you should use + Alsa or OSS/Linux driver. Of course you can write native PCI driver for + your cards :) + + +USAGE +===== + + # modprobe ymfsb (options) + + +OPTIONS FOR MODULE +================== + + io : SB base address (0x220, 0x240, 0x260, 0x280) + synth_io : OPL3 base address (0x388, 0x398, 0x3a0, 0x3a8) + dma : DMA number (0,1,3) + master_volume: AC'97 PCM out Vol (0-100) + spdif_out : SPDIF-out flag (0:disable 1:enable) + + These options will change in future... + + +FREQUENCY +========= + + When playing sounds via this driver, you will hear its pitch is slightly + lower than original sounds. Since this driver recognizes your card acts + with 21.739kHz sample rates rather than 22.050kHz (I think it must be + hardware restriction). So many players become tone deafness. + To prevent this, you should express some options to your sound player + that specify correct sample frequency. For example, to play your MP3 file + correctly with mpg123, specify the frequency like following: + + % mpg123 -r 21739 foo.mp3 + + +SPDIF OUT +========= + + With installing modules with option 'spdif_out=1', you can enjoy your + sounds from SPDIF-out of your card (if it had). + Its Fs is fixed to 48kHz (It never means the sample frequency become + up to 48kHz. All sounds via SPDIF-out also 22kHz samples). So your + digital-in capable components has to be able to handle 48kHz Fs. + + +COPYING +======= + + 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + +TODO +==== + * support for multiple cards + (set the different SB_IO,MPU_IO,OPL_IO for each cards) + + * support for OPL (dmfm) : There will be no requirements... :-< + + +AUTHOR +====== + + Daisuke Nagano <breeze.nagano@nifty.ne.jp> + diff --git a/Documentation/sound/oss/SoundPro b/Documentation/sound/oss/SoundPro new file mode 100644 index 000000000000..9d4db1f29d3c --- /dev/null +++ b/Documentation/sound/oss/SoundPro @@ -0,0 +1,105 @@ +Documentation for the SoundPro CMI8330 extensions in the WSS driver (ad1848.o) +------------------------------------------------------------------------------ + +( Be sure to read Documentation/sound/oss/CMI8330 too ) + +Ion Badulescu, ionut@cs.columbia.edu +February 24, 1999 + +(derived from the OPL3-SA2 documentation by Scott Murray) + +The SoundPro CMI8330 (ISA) is a chip usually found on some Taiwanese +motherboards. The official name in the documentation is CMI8330, SoundPro +is the nickname and the big inscription on the chip itself. + +The chip emulates a WSS as well as a SB16, but it has certain differences +in the mixer section which require separate support. It also emulates an +MPU401 and an OPL3 synthesizer, so you probably want to enable support +for these, too. + +The chip identifies itself as an AD1848, but its mixer is significantly +more advanced than the original AD1848 one. If your system works with +either WSS or SB16 and you are having problems with some mixer controls +(no CD audio, no line-in, etc), you might want to give this driver a try. +Detection should work, but it hasn't been widely tested, so it might still +mis-identify the chip. You can still force soundpro=1 in the modprobe +parameters for ad1848. Please let me know if it happens to you, so I can +adjust the detection routine. + +The chip is capable of doing full-duplex, but since the driver sees it as an +AD1848, it cannot take advantage of this. Moreover, the full-duplex mode is +not achievable through the WSS interface, b/c it needs a dma16 line which is +assigned only to the SB16 subdevice (with isapnp). Windows documentation +says the user must use WSS Playback and SB16 Recording for full-duplex, so +it might be possible to do the same thing under Linux. You can try loading +up both ad1848 and sb then use one for playback and the other for +recording. I don't know if this works, b/c I haven't tested it. Anyway, if +you try it, be very careful: the SB16 mixer *mostly* works, but certain +settings can have unexpected effects. Use the WSS mixer for best results. + +There is also a PCI SoundPro chip. I have not seen this chip, so I have +no idea if the driver will work with it. I suspect it won't. + +As with PnP cards, some configuration is required. There are two ways +of doing this. The most common is to use the isapnptools package to +initialize the card, and use the kernel module form of the sound +subsystem and sound drivers. Alternatively, some BIOS's allow manual +configuration of installed PnP devices in a BIOS menu, which should +allow using the non-modular sound drivers, i.e. built into the kernel. +Since in this latter case you cannot use module parameters, you will +have to enable support for the SoundPro at compile time. + +The IRQ and DMA values can be any that are considered acceptable for a +WSS. Assuming you've got isapnp all happy, then you should be able to +do something like the following (which *must* match the isapnp/BIOS +configuration): + +modprobe ad1848 io=0x530 irq=11 dma=0 soundpro=1 +-and maybe- +modprobe sb io=0x220 irq=5 dma=1 dma16=5 + +-then- +modprobe mpu401 io=0x330 irq=9 +modprobe opl3 io=0x388 + +If all goes well and you see no error messages, you should be able to +start using the sound capabilities of your system. If you get an +error message while trying to insert the module(s), then make +sure that the values of the various arguments match what you specified +in your isapnp configuration file, and that there is no conflict with +another device for an I/O port or interrupt. Checking the contents of +/proc/ioports and /proc/interrupts can be useful to see if you're +butting heads with another device. + +If you do not see the chipset version message, and none of the other +messages present in the system log are helpful, try adding 'debug=1' +to the ad1848 parameters, email me the syslog results and I'll do +my best to help. + +Lastly, if you're using modules and want to set up automatic module +loading with kmod, the kernel module loader, here is the section I +currently use in my conf.modules file: + +# Sound +post-install sound modprobe -k ad1848; modprobe -k mpu401; modprobe -k opl3 +options ad1848 io=0x530 irq=11 dma=0 +options sb io=0x220 irq=5 dma=1 dma16=5 +options mpu401 io=0x330 irq=9 +options opl3 io=0x388 + +The above ensures that ad1848 will be loaded whenever the sound system +is being used. + +Good luck. + +Ion + +NOT REALLY TESTED: +- recording +- recording device selection +- full-duplex + +TODO: +- implement mixer support for surround, loud, digital CD switches. +- come up with a scheme which allows recording volumes for each subdevice. +This is a major OSS API change. diff --git a/Documentation/sound/oss/Soundblaster b/Documentation/sound/oss/Soundblaster new file mode 100644 index 000000000000..b288d464ba8b --- /dev/null +++ b/Documentation/sound/oss/Soundblaster @@ -0,0 +1,53 @@ +modprobe sound +insmod uart401 +insmod sb ... + +This loads the driver for the Sound Blaster and assorted clones. Cards that +are covered by other drivers should not be using this driver. + +The Sound Blaster module takes the following arguments + +io I/O address of the Sound Blaster chip (0x220,0x240,0x260,0x280) +irq IRQ of the Sound Blaster chip (5,7,9,10) +dma 8-bit DMA channel for the Sound Blaster (0,1,3) +dma16 16-bit DMA channel for SB16 and equivalent cards (5,6,7) +mpu_io I/O for MPU chip if present (0x300,0x330) + +sm_games=1 Set if you have a Logitech soundman games +acer=1 Set this to detect cards in some ACER notebooks +mwave_bug=1 Set if you are trying to use this driver with mwave (see on) +type Use this to specify a specific card type + +The following arguments are taken if ISAPnP support is compiled in + +isapnp=0 Set this to disable ISAPnP detection (use io=0xXXX etc. above) +multiple=0 Set to disable detection of multiple Soundblaster cards. + Consider it a bug if this option is needed, and send in a + report. +pnplegacy=1 Set this to be able to use a PnP card(s) along with a single + non-PnP (legacy) card. Above options for io, irq, etc. are + needed, and will apply only to the legacy card. +reverse=1 Reverses the order of the search in the PnP table. +uart401=1 Set to enable detection of mpu devices on some clones. +isapnpjump=n Jumps to slot n in the driver's PnP table. Use the source, + Luke. + +You may well want to load the opl3 driver for synth music on most SB and +clone SB devices + +insmod opl3 io=0x388 + +Using Mwave + +To make this driver work with Mwave you must set mwave_bug. You also need +to warm boot from DOS/Windows with the required firmware loaded under this +OS. IBM are being difficult about documenting how to load this firmware. + +Avance Logic ALS007 + +This card is supported; see the separate file ALS007 for full details. + +Avance Logic ALS100 + +This card is supported; setup should be as for a standard Sound Blaster 16. +The driver will identify the audio device as a "Sound Blaster 16 (ALS-100)". diff --git a/Documentation/sound/oss/Tropez+ b/Documentation/sound/oss/Tropez+ new file mode 100644 index 000000000000..b93a6b734fc0 --- /dev/null +++ b/Documentation/sound/oss/Tropez+ @@ -0,0 +1,26 @@ +From: Paul Barton-Davis <pbd@op.net> + +Here is the configuration I use with a Tropez+ and my modular +driver: + + alias char-major-14 wavefront + alias synth0 wavefront + alias mixer0 cs4232 + alias audio0 cs4232 + pre-install wavefront modprobe "-k" "cs4232" + post-install wavefront modprobe "-k" "opl3" + options wavefront io=0x200 irq=9 + options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0 + options opl3 io=0x388 + +Things to note: + + the wavefront options "io" and "irq" ***MUST*** match the "synthio" + and "synthirq" cs4232 options. + + you can do without the opl3 module if you don't + want to use the OPL/[34] synth on the soundcard + + the opl3 io parameter is conventionally not adjustable. + +Please see drivers/sound/README.wavefront for more details. diff --git a/Documentation/sound/oss/VIA-chipset b/Documentation/sound/oss/VIA-chipset new file mode 100644 index 000000000000..37865234e54d --- /dev/null +++ b/Documentation/sound/oss/VIA-chipset @@ -0,0 +1,43 @@ +Running sound cards on VIA chipsets + +o There are problems with VIA chipsets and sound cards that appear to + lock the hardware solidly. Test programs under DOS have verified the + problem exists on at least some (but apparently not all) VIA boards + +o VIA have so far failed to bother to answer support mail on the subject + so if you are a VIA engineer feeling aggrieved as you read this + document go chase your own people. If there is a workaround please + let us know so we can implement it. + + +Certain patterns of ISA DMA access used for most PC sound cards cause the +VIA chipsets to lock up. From the collected reports this appears to cover a +wide range of boards. Some also lock up with sound cards under Win* as well. + +Linux implements a workaround providing your chipset is PCI and you compiled +with PCI Quirks enabled. If so you will see a message + "Activating ISA DMA bug workarounds" + +during booting. If you have a VIA PCI chipset that hangs when you use the +sound and is not generating this message even with PCI quirks enabled +please report the information to the linux-kernel list (see REPORTING-BUGS). + +If you are one of the tiny number of unfortunates with a 486 ISA/VLB VIA +chipset board you need to do the following to build a special kernel for +your board + + edit linux/include/asm-i386/dma.h + +change + +#define isa_dma_bridge_buggy (0) + +to + +#define isa_dma_bridge_buggy (1) + +and rebuild a kernel without PCI quirk support. + + +Other than this particular glitch the VIA [M]VP* chipsets appear to work +perfectly with Linux. diff --git a/Documentation/sound/oss/VIBRA16 b/Documentation/sound/oss/VIBRA16 new file mode 100644 index 000000000000..68a5a46beb88 --- /dev/null +++ b/Documentation/sound/oss/VIBRA16 @@ -0,0 +1,80 @@ +Sound Blaster 16X Vibra addendum +-------------------------------- +by Marius Ilioaea <mariusi@protv.ro> + Stefan Laudat <stefan@asit.ro> + +Sat Mar 6 23:55:27 EET 1999 + + Hello again, + + Playing with a SB Vibra 16x soundcard we found it very difficult +to setup because the kernel reported a lot of DMA errors and wouldn't +simply play any sound. + A good starting point is that the vibra16x chip full-duplex facility +is neither still exploited by the sb driver found in the linux kernel +(tried it with a 2.2.2-ac7), nor in the commercial OSS package (it reports +it as half-duplex soundcard). Oh, I almost forgot, the RedHat sndconfig +failed detecting it ;) + So, the big problem still remains, because the sb module wants a +8-bit and a 16-bit dma, which we could not allocate for vibra... it supports +only two 8-bit dma channels, the second one will be passed to the module +as a 16 bit channel, the kernel will yield about that but everything will +be okay, trust us. + The only inconvenient you may find is that you will have +some sound playing jitters if you have HDD dma support enabled - but this +will happen with almost all soundcards... + + A fully working isapnp.conf is just here: + +<snip here> + +(READPORT 0x0203) +(ISOLATE PRESERVE) +(IDENTIFY *) +(VERBOSITY 2) +(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING +# SB 16 and OPL3 devices +(CONFIGURE CTL00f0/-1 (LD 0 +(INT 0 (IRQ 5 (MODE +E))) +(DMA 0 (CHANNEL 1)) +(DMA 1 (CHANNEL 3)) +(IO 0 (SIZE 16) (BASE 0x0220)) +(IO 2 (SIZE 4) (BASE 0x0388)) +(NAME "CTL00f0/-1[0]{Audio }") +(ACT Y) +)) + +# Joystick device - only if you need it :-/ + +(CONFIGURE CTL00f0/-1 (LD 1 +(IO 0 (SIZE 1) (BASE 0x0200)) +(NAME "CTL00f0/-1[1]{Game }") +(ACT Y) +)) +(WAITFORKEY) + +<end of snipping> + + So, after a good kernel modules compilation and a 'depmod -a kernel_ver' +you may want to: + +modprobe sb io=0x220 irq=5 dma=1 dma16=3 + + Or, take the hard way: + +modprobe soundcore +modprobe sound +modprobe uart401 +modprobe sb io=0x220 irq=5 dma=1 dma16=3 +# do you need MIDI? +modprobe opl3=0x388 + + Just in case, the kernel sound support should be: + +CONFIG_SOUND=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_SB=m + + Enjoy your new noisy Linux box! ;) + + diff --git a/Documentation/sound/oss/WaveArtist b/Documentation/sound/oss/WaveArtist new file mode 100644 index 000000000000..f4f3407cd818 --- /dev/null +++ b/Documentation/sound/oss/WaveArtist @@ -0,0 +1,170 @@ + + (the following is from the armlinux CVS) + + WaveArtist mixer and volume levels can be accessed via these commands: + + nn30 read registers nn, where nn = 00 - 09 for mixer settings + 0a - 13 for channel volumes + mm31 write the volume setting in pairs, where mm = (nn - 10) / 2 + rr32 write the mixer settings in pairs, where rr = nn/2 + xx33 reset all settings to default + 0y34 select mono source, y=0 = left, y=1 = right + + bits + nn 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 00 | 0 | 0 0 1 1 | left line mixer gain | left aux1 mixer gain |lmute| +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 01 | 0 | 0 1 0 1 | left aux2 mixer gain | right 2 left mic gain |mmute| +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 02 | 0 | 0 1 1 1 | left mic mixer gain | left mic | left mixer gain |dith | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 03 | 0 | 1 0 0 1 | left mixer input select |lrfg | left ADC gain | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 04 | 0 | 1 0 1 1 | right line mixer gain | right aux1 mixer gain |rmute| +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 05 | 0 | 1 1 0 1 | right aux2 mixer gain | left 2 right mic gain |test | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 06 | 0 | 1 1 1 1 | right mic mixer gain | right mic |right mixer gain |rbyps| +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 07 | 1 | 0 0 0 1 | right mixer select |rrfg | right ADC gain | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 08 | 1 | 0 0 1 1 | mono mixer gain |right ADC mux sel|left ADC mux sel | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 09 | 1 | 0 1 0 1 |loopb|left linout|loop|ADCch|TxFch|OffCD|test |loopb|loopb|osamp| +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 0a | 0 | left PCM channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 0b | 0 | right PCM channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 0c | 0 | left FM channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 0d | 0 | right FM channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 0e | 0 | left wavetable channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 0f | 0 | right wavetable channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 10 | 0 | left PCM expansion channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 11 | 0 | right PCM expansion channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 12 | 0 | left FM expansion channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + 13 | 0 | right FM expansion channel volume | +----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+ + + lmute: left mute + mmute: mono mute + dith: dithds + lrfg: + rmute: right mute + rbyps: right bypass + rrfg: + ADCch: + TxFch: + OffCD: + osamp: + + And the following diagram is derived from the description in the CVS archive: + + MIC L (mouthpiece) + +------+ + -->PreAmp>-\ + +--^---+ | + | | + r2b4-5 | +--------+ + /----*-------------------------------->5 | + | | | + | /----------------------------------->4 | + | | | | + | | /--------------------------------->3 1of5 | +---+ + | | | | mux >-->AMP>--> ADC L + | | | /------------------------------->2 | +-^-+ + | | | | | | | + Line | | | | +----+ +------+ +---+ /---->1 | r3b3-0 + ------------*->mute>--> Gain >--> | | | | + L | | | +----+ +------+ | | | *->0 | + | | | | | | +---^----+ + Aux2 | | | +----+ +------+ | | | | + ----------*--->mute>--> Gain >--> M | | r8b0-2 + L | | +----+ +------+ | | | + | | | | \------\ + Aux1 | | +----+ +------+ | | | + --------*----->mute>--> Gain >--> I | | + L | +----+ +------+ | | | + | | | | + | +----+ +------+ | | +---+ | + *------->mute>--> Gain >--> X >-->AMP>--* + | +----+ +------+ | | +-^-+ | + | | | | | + | +----+ +------+ | | r2b1-3 | + | /----->mute>--> Gain >--> E | | + | | +----+ +------+ | | | + | | | | | + | | +----+ +------+ | | | + | | /--->mute>--> Gain >--> R | | + | | | +----+ +------+ | | | + | | | | | | r9b8-9 + | | | +----+ +------+ | | | | + | | | /->mute>--> Gain >--> | | +---v---+ + | | | | +----+ +------+ +---+ /-*->0 | + DAC | | | | | | | + ------------*----------------------------------->? | +----+ + L | | | | | Mux >-->mute>--> L output + | | | | /->? | +--^-+ + | | | | | | | | + | | | /--------->? | r0b0 + | | | | | | +-------+ + | | | | | | + Mono | | | | | | +-------+ + ----------* | \---> | +----+ + | | | | | | Mix >-->mute>--> Mono output + | | | | *-> | +--^-+ + | | | | | +-------+ | + | | | | | r1b0 + DAC | | | | | +-------+ + ------------*-------------------------*--------->1 | +----+ + R | | | | | | Mux >-->mute>--> R output + | | | | +----+ +------+ +---+ *->0 | +--^-+ + | | | \->mute>--> Gain >--> | | +---^---+ | + | | | +----+ +------+ | | | | r5b0 + | | | | | | r6b0 + | | | +----+ +------+ | | | + | | \--->mute>--> Gain >--> M | | + | | +----+ +------+ | | | + | | | | | + | | +----+ +------+ | | | + | *----->mute>--> Gain >--> I | | + | | +----+ +------+ | | | + | | | | | + | | +----+ +------+ | | +---+ | + \------->mute>--> Gain >--> X >-->AMP>--* + | +----+ +------+ | | +-^-+ | + /--/ | | | | + Aux1 | +----+ +------+ | | r6b1-3 | + -------*------>mute>--> Gain >--> E | | + R | | +----+ +------+ | | | + | | | | | + Aux2 | | +----+ +------+ | | /------/ + ---------*---->mute>--> Gain >--> R | | + R | | | +----+ +------+ | | | + | | | | | | +--------+ + Line | | | +----+ +------+ | | | *->0 | + -----------*-->mute>--> Gain >--> | | | | + R | | | | +----+ +------+ +---+ \---->1 | + | | | | | | + | | | \-------------------------------->2 | +---+ + | | | | Mux >-->AMP>--> ADC R + | | \---------------------------------->3 | +-^-+ + | | | | | + | \------------------------------------>4 | r7b3-0 + | | | + \-----*-------------------------------->5 | + | +---^----+ + r6b4-5 | | + | | r8b3-5 + +--v---+ | + -->PreAmp>-/ + +------+ + MIC R (electret mic) diff --git a/Documentation/sound/oss/Wavefront b/Documentation/sound/oss/Wavefront new file mode 100644 index 000000000000..16f57ea43052 --- /dev/null +++ b/Documentation/sound/oss/Wavefront @@ -0,0 +1,339 @@ + An OSS/Free Driver for WaveFront soundcards + (Turtle Beach Maui, Tropez, Tropez Plus) + + Paul Barton-Davis, July 1998 + + VERSION 0.2.5 + +Driver Status +------------- + +Requires: Kernel 2.1.106 or later (the driver is included with kernels +2.1.109 and above) + +As of 7/22/1998, this driver is currently in *BETA* state. This means +that it compiles and runs, and that I use it on my system (Linux +2.1.106) with some reasonably demanding applications and uses. I +believe the code is approaching an initial "finished" state that +provides bug-free support for the Tropez Plus. + +Please note that to date, the driver has ONLY been tested on a Tropez +Plus. I would very much like to hear (and help out) people with Tropez +and Maui cards, since I think the driver can support those cards as +well. + +Finally, the driver has not been tested (or even compiled) as a static +(non-modular) part of the kernel. Alan Cox's good work in modularizing +OSS/Free for Linux makes this rather unnecessary. + +Some Questions +-------------- + +********************************************************************** +0) What does this driver do that the maui driver did not ? +********************************************************************** + +* can fully initialize a WaveFront card from cold boot - no DOS + utilities needed +* working patch/sample/program loading and unloading (the maui + driver didn't document how to make this work, and assumed + user-level preparation of the patch data for writing + to the board. ick.) +* full user-level access to all WaveFront commands +* for the Tropez Plus, (primitive) control of the YSS225 FX processor +* Virtual MIDI mode supported - 2 MIDI devices accessible via the + WaveFront's MPU401/UART emulation. One + accesses the WaveFront synth, the other accesses the + external MIDI connector. Full MIDI read/write semantics + for both devices. +* OSS-compliant /dev/sequencer interface for the WaveFront synth, + including native and GUS-format patch downloading. +* semi-intelligent patch management (prototypical at this point) + +********************************************************************** +1) What to do about MIDI interfaces ? +********************************************************************** + +The Tropez Plus (and perhaps other WF cards) can in theory support up +to 2 physical MIDI interfaces. One of these is connected to the +ICS2115 chip (the WaveFront synth itself) and is controlled by +MPU/UART-401 emulation code running as part of the WaveFront OS. The +other is controlled by the CS4232 chip present on the board. However, +physical access to the CS4232 connector is difficult, and it is +unlikely (though not impossible) that you will want to use it. + +An older version of this driver introduced an additional kernel config +variable which controlled whether or not the CS4232 MIDI interface was +configured. Because of Alan Cox's work on modularizing the sound +drivers, and now backporting them to 2.0.34 kernels, there seems to be +little reason to support "static" configuration variables, and so this +has been abandoned in favor of *only* module parameters. Specifying +"mpuio" and "mpuirq" for the cs4232 parameter will result in the +CS4232 MIDI interface being configured; leaving them unspecified will +leave it unconfigured (and thus unusable). + +BTW, I have heard from one Tropez+ user that the CS4232 interface is +more reliable than the ICS2115 one. I have had no problems with the +latter, and I don't have the right cable to test the former one +out. Reports welcome. + +********************************************************************** +2) Why does line XXX of the code look like this .... ? +********************************************************************** + +Either because it's not finished yet, or because you're a better coder +than I am, or because you don't understand some aspect of how the card +or the code works. + +I absolutely welcome comments, criticisms and suggestions about the +design and implementation of the driver. + +********************************************************************** +3) What files are included ? +********************************************************************** + + drivers/sound/README.wavefront -- this file + + drivers/sound/wavefront.patch -- patches for the 2.1.106 sound drivers + needed to make the rest of this work + DO NOT USE IF YOU'VE APPLIED THEM + BEFORE, OR HAVE 2.1.109 OR ABOVE + + drivers/sound/wavfront.c -- the driver + drivers/sound/ys225.h -- data declarations for FX config + drivers/sound/ys225.c -- data definitions for FX config + drivers/sound/wf_midi.c -- the "uart401" driver + to support virtual MIDI mode. + include/wavefront.h -- the header file + Documentation/sound/oss/Tropez+ -- short docs on configuration + +********************************************************************** +4) How do I compile/install/use it ? +********************************************************************** + +PART ONE: install the source code into your sound driver directory + + cd <top-of-your-2.1.106-code-base-e.g.-/usr/src/linux> + tar -zxvf <where-you-put/wavefront.tar.gz> + +PART TWO: apply the patches + + DO THIS ONLY IF YOU HAVE A KERNEL VERSION BELOW 2.1.109 + AND HAVE NOT ALREADY INSTALLED THE PATCH(ES). + + cd drivers/sound + patch < wavefront.patch + +PART THREE: configure your kernel + + cd <top of your kernel tree> + make xconfig (or whichever config option you use) + + - choose YES for Sound Support + - choose MODULE (M) for OSS Sound Modules + - choose MODULE(M) to YM3812/OPL3 support + - choose MODULE(M) for WaveFront support + - choose MODULE(M) for CS4232 support + + - choose "N" for everything else (unless you have other + soundcards you want support for) + + + make boot + . + . + . + <whatever you normally do for a kernel install> + make modules + . + . + . + make modules_install + +Here's my autoconf.h SOUND section: + +/* + * Sound + */ +#define CONFIG_SOUND 1 +#undef CONFIG_SOUND_OSS +#define CONFIG_SOUND_OSS_MODULE 1 +#undef CONFIG_SOUND_PAS +#undef CONFIG_SOUND_SB +#undef CONFIG_SOUND_ADLIB +#undef CONFIG_SOUND_GUS +#undef CONFIG_SOUND_MPU401 +#undef CONFIG_SOUND_PSS +#undef CONFIG_SOUND_MSS +#undef CONFIG_SOUND_SSCAPE +#undef CONFIG_SOUND_TRIX +#undef CONFIG_SOUND_MAD16 +#undef CONFIG_SOUND_WAVEFRONT +#define CONFIG_SOUND_WAVEFRONT_MODULE 1 +#undef CONFIG_SOUND_CS4232 +#define CONFIG_SOUND_CS4232_MODULE 1 +#undef CONFIG_SOUND_MAUI +#undef CONFIG_SOUND_SGALAXY +#undef CONFIG_SOUND_OPL3SA1 +#undef CONFIG_SOUND_SOFTOSS +#undef CONFIG_SOUND_YM3812 +#define CONFIG_SOUND_YM3812_MODULE 1 +#undef CONFIG_SOUND_VMIDI +#undef CONFIG_SOUND_UART6850 +/* + * Additional low level sound drivers + */ +#undef CONFIG_LOWLEVEL_SOUND + +************************************************************ +6) How do I configure my card ? +************************************************************ + +You need to edit /etc/modprobe.conf. Here's mine (edited to show the +relevant details): + + # Sound system + alias char-major-14-* wavefront + alias synth0 wavefront + alias mixer0 cs4232 + alias audio0 cs4232 + install wavefront /sbin/modprobe cs4232 && /sbin/modprobe -i wavefront && /sbin/modprobe opl3 + options wavefront io=0x200 irq=9 + options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0 + options opl3 io=0x388 + +Things to note: + + the wavefront options "io" and "irq" ***MUST*** match the "synthio" + and "synthirq" cs4232 options. + + you can do without the opl3 module if you don't + want to use the OPL/[34] FM synth on the soundcard + + the opl3 io parameter is conventionally not adjustable. + In theory, any not-in-use IO port address would work, but + just use 0x388 and stick with the crowd. + +********************************************************************** +7) What about firmware ? +********************************************************************** + +Turtle Beach have not given me permission to distribute their firmware +for the ICS2115. However, if you have a WaveFront card, then you +almost certainly have the firmware, and if not, its freely available +on their website, at: + + http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus + +The file is called WFOS2001.MOT (for the Tropez+). + +This driver, however, doesn't use the pure firmware as distributed, +but instead relies on a somewhat processed form of it. You can +generate this very easily. Following an idea from Andrew Veliath's +Pinnacle driver, the following flex program will generate the +processed version: + +---- cut here ------------------------- +%option main +%% +^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext); +<<EOF>> { fputc ('\0', stdout); return; } +\n {} +. {} +---- cut here ------------------------- + +To use it, put the above in file (say, ws.l) compile it like this: + + shell> flex -ows.c ws.l + shell> cc -o ws ws.c + +and then use it like this: + + ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os + +If you put it somewhere else, you'll always have to use the wf_ospath +module parameter (see below) or alter the source code. + +********************************************************************** +7) How do I get it working ? +********************************************************************** + +Optionally, you can reboot with the "new" kernel (even though the only +changes have really been made to a module). + +Then, as root do: + + modprobe wavefront + +You should get something like this in /var/log/messages: + + WaveFront: firmware 1.20 already loaded. + +or + + WaveFront: no response to firmware probe, assume raw. + +then: + + WaveFront: waiting for memory configuration ... + WaveFront: hardware version 1.64 + WaveFront: available DRAM 8191k + WaveFront: 332 samples used (266 real, 13 aliases, 53 multi), 180 empty + WaveFront: 128 programs slots in use + WaveFront: 256 patch slots filled, 142 in use + +The whole process takes about 16 seconds, the longest waits being +after reporting the hardware version (during the firmware download), +and after reporting program status (during patch status inquiry). Its +shorter (about 10 secs) if the firmware is already loaded (i.e. only +warm reboots since the last firmware load). + +The "available DRAM" line will vary depending on how much added RAM +your card has. Mine has 8MB. + +To check basically functionality, use play(1) or splay(1) to send a +.WAV or other audio file through the audio portion. Then use playmidi +to play a General MIDI file. Try the "-D 0" to hear the +difference between sending MIDI to the WaveFront and using the OPL/3, +which is the default (I think ...). If you have an external synth(s) +hooked to the soundcard, you can use "-e" to route to the +external synth(s) (in theory, -D 1 should work as well, but I think +there is a bug in playmidi which prevents this from doing what it +should). + +********************************************************************** +8) What are the module parameters ? +********************************************************************** + +Its best to read wavefront.c for this, but here is a summary: + +integers: + wf_raw - if set, ignore apparent presence of firmware + loaded onto the ICS2115, reset the whole + board, and initialize it from scratch. (default = 0) + + fx_raw - if set, always initialize the YSS225 processor + on the Tropez plus. (default = 1) + + < The next 4 are basically for kernel hackers to allow + tweaking the driver for testing purposes. > + + wait_usecs - loop timer used when waiting for + status conditions on the board. + The default is 150. + + debug_default - debugging flags. See sound/wavefront.h + for WF_DEBUG_* values. Default is zero. + Setting this allows you to debug the + driver during module installation. +strings: + ospath - path to get to the pre-processed OS firmware. + (default: /etc/sound/wavefront.os) + +********************************************************************** +9) Who should I contact if I have problems? +********************************************************************** + +Just me: Paul Barton-Davis <pbd@op.net> + + diff --git a/Documentation/sound/oss/btaudio b/Documentation/sound/oss/btaudio new file mode 100644 index 000000000000..1a693e69d44b --- /dev/null +++ b/Documentation/sound/oss/btaudio @@ -0,0 +1,92 @@ + +Intro +===== + +people start bugging me about this with questions, looks like I +should write up some documentation for this beast. That way I +don't have to answer that much mails I hope. Yes, I'm lazy... + + +You might have noticed that the bt878 grabber cards have actually +_two_ PCI functions: + +$ lspci +[ ... ] +00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02) +00:0a.1 Multimedia controller: Brooktree Corporation Bt878 (rev 02) +[ ... ] + +The first does video, it is backward compatible to the bt848. The second +does audio. btaudio is a driver for the second function. It's a sound +driver which can be used for recording sound (and _only_ recording, no +playback). As most TV cards come with a short cable which can be plugged +into your sound card's line-in you probably don't need this driver if all +you want to do is just watching TV... + + +Driver Status +============= + +Still somewhat experimental. The driver should work stable, i.e. it +should'nt crash your box. It might not work as expected, have bugs, +not being fully OSS API compilant, ... + +Latest versions are available from http://bytesex.org/bttv/, the +driver is in the bttv tarball. Kernel patches might be available too, +have a look at http://bytesex.org/bttv/listing.html. + +The chip knows two different modes. btaudio registers two dsp +devices, one for each mode. They can not be used at the same time. + + +Digital audio mode +================== + +The chip gives you 16 bit stereo sound. The sample rate depends on +the external source which feeds the bt878 with digital sound via I2S +interface. There is a insmod option (rate) to tell the driver which +sample rate the hardware uses (32000 is the default). + +One possible source for digital sound is the msp34xx audio processor +chip which provides digital sound via I2S with 32 kHz sample rate. My +Hauppauge board works this way. + +The Osprey-200 reportly gives you digital sound with 44100 Hz sample +rate. It is also possible that you get no sound at all. + + +analog mode (A/D) +================= + +You can tell the driver to use this mode with the insmod option "analog=1". +The chip has three analog inputs. Consequently you'll get a mixer device +to control these. + +The analog mode supports mono only. Both 8 + 16 bit. Both are _signed_ +int, which is uncommon for the 8 bit case. Sample rate range is 119 kHz +to 448 kHz. Yes, the number of digits is correct. The driver supports +downsampling by powers of two, so you can ask for more usual sample rates +like 44 kHz too. + +With my Hauppauge I get noisy sound on the second input (mapped to line2 +by the mixer device). Others get a useable signal on line1. + + +some examples +============= + +* read audio data from btaudio (dsp2), send to es1730 (dsp,dsp1): + $ sox -w -r 32000 -t ossdsp /dev/dsp2 -t ossdsp /dev/dsp + +* read audio data from btaudio, send to esound daemon (which might be + running on another host): + $ sox -c 2 -w -r 32000 -t ossdsp /dev/dsp2 -t sw - | esdcat -r 32000 + $ sox -c 1 -w -r 32000 -t ossdsp /dev/dsp2 -t sw - | esdcat -m -r 32000 + + +Have fun, + + Gerd + +-- +Gerd Knorr <kraxel@bytesex.org> diff --git a/Documentation/sound/oss/cs46xx b/Documentation/sound/oss/cs46xx new file mode 100644 index 000000000000..88d6cf8b39f3 --- /dev/null +++ b/Documentation/sound/oss/cs46xx @@ -0,0 +1,138 @@ + +Documentation for the Cirrus Logic/Crystal SoundFusion cs46xx/cs4280 audio +controller chips (2001/05/11) + +The cs46xx audio driver supports the DSP line of Cirrus controllers. +Specifically, the cs4610, cs4612, cs4614, cs4622, cs4624, cs4630 and the cs4280 +products. This driver uses the generic ac97_codec driver for AC97 codec +support. + + +Features: + +Full Duplex Playback/Capture supported from 8k-48k. +16Bit Signed LE & 8Bit Unsigned, with Mono or Stereo supported. + +APM/PM - 2.2.x PM is enabled and functional. APM can also +be enabled for 2.4.x by modifying the CS46XX_ACPI_SUPPORT macro +definition. + +DMA playback buffer size is configurable from 16k (defaultorder=2) up to 2Meg +(defaultorder=11). DMA capture buffer size is fixed at a single 4k page as +two 2k fragments. + +MMAP seems to work well with QuakeIII, and test XMMS plugin. + +Myth2 works, but the polling logic is not fully correct, but is functional. + +The 2.4.4-ac6 gameport code in the cs461x joystick driver has been tested +with a Microsoft Sidewinder joystick (cs461x.o and sidewinder.o). This +audio driver must be loaded prior to the joystick driver to enable the +DSP task image supporting the joystick device. + + +Limitations: + +SPDIF is currently not supported. + +Primary codec support only. No secondary codec support is implemented. + + + +NOTES: + +Hercules Game Theatre XP - the EGPIO2 pin controls the external Amp, +and has been tested. +Module parameter hercules_egpio_disable set to 1, will force a 0 to EGPIODR +to disable the external amplifier. + +VTB Santa Cruz - the GPIO7/GPIO8 on the Secondary Codec control +the external amplifier for the "back" speakers, since we do not +support the secondary codec then this external amp is not +turned on. The primary codec external amplifier is supported but +note that the AC97 EAPD bit is inverted logic (amp_voyetra()). + +DMA buffer size - there are issues with many of the Linux applications +concerning the optimal buffer size. Several applications request a +certain fragment size and number and then do not verify that the driver +has the ability to support the requested configuration. +SNDCTL_DSP_SETFRAGMENT ioctl is used to request a fragment size and +number of fragments. Some applications exit if an error is returned +on this particular ioctl. Therefore, in alignment with the other OSS audio +drivers, no error is returned when a SETFRAGs IOCTL is received, but the +values passed from the app are not used in any buffer calculation +(ossfragshift/ossmaxfrags are not used). +Use the "defaultorder=N" module parameter to change the buffer size if +you have an application that requires a specific number of fragments +or a specific buffer size (see below). + +Debug Interface +--------------- +There is an ioctl debug interface to allow runtime modification of the +debug print levels. This debug interface code can be disabled from the +compilation process with commenting the following define: +#define CSDEBUG_INTERFACE 1 +There is also a debug print methodolgy to select printf statements from +different areas of the driver. A debug print level is also used to allow +additional printfs to be active. Comment out the following line in the +driver to disable compilation of the CS_DBGOUT print statements: +#define CSDEBUG 1 + +Please see the definitions for cs_debuglevel and cs_debugmask for additional +information on the debug levels and sections. + +There is also a csdbg executable to allow runtime manipulation of these +parameters. for a copy email: twoller@crystal.cirrus.com + + + +MODULE_PARMS definitions +------------------------ +MODULE_PARM(defaultorder, "i"); +defaultorder=N +where N is a value from 1 to 12 +The buffer order determines the size of the dma buffer for the driver. +under Linux, a smaller buffer allows more responsiveness from many of the +applications (e.g. games). A larger buffer allows some of the apps (esound) +to not underrun the dma buffer as easily. As default, use 32k (order=3) +rather than 64k as some of the games work more responsively. +(2^N) * PAGE_SIZE = allocated buffer size + +MODULE_PARM(cs_debuglevel, "i"); +MODULE_PARM(cs_debugmask, "i"); +cs_debuglevel=N +cs_debugmask=0xMMMMMMMM +where N is a value from 0 (no debug printfs), to 9 (maximum) +0xMMMMMMMM is a debug mask corresponding to the CS_xxx bits (see driver source). + +MODULE_PARM(hercules_egpio_disable, "i"); +hercules_egpio_disable=N +where N is a 0 (enable egpio), or a 1 (disable egpio support) + +MODULE_PARM(initdelay, "i"); +initdelay=N +This value is used to determine the millescond delay during the initialization +code prior to powering up the PLL. On laptops this value can be used to +assist with errors on resume, mostly with IBM laptops. Basically, if the +system is booted under battery power then the mdelay()/udelay() functions fail to +properly delay the required time. Also, if the system is booted under AC power +and then the power removed, the mdelay()/udelay() functions will not delay properly. + +MODULE_PARM(powerdown, "i"); +powerdown=N +where N is 0 (disable any powerdown of the internal blocks) or 1 (enable powerdown) + + +MODULE_PARM(external_amp, "i"); +external_amp=1 +if N is set to 1, then force enabling the EAPD support in the primary AC97 codec. +override the detection logic and force the external amp bit in the AC97 0x26 register +to be reset (0). EAPD should be 0 for powerup, and 1 for powerdown. The VTB Santa Cruz +card has inverted logic, so there is a special function for these cards. + +MODULE_PARM(thinkpad, "i"); +thinkpad=1 +if N is set to 1, then force enabling the clkrun functionality. +Currently, when the part is being used, then clkrun is disabled for the entire system, +but re-enabled when the driver is released or there is no outstanding open count. + diff --git a/Documentation/sound/oss/es1370 b/Documentation/sound/oss/es1370 new file mode 100644 index 000000000000..7b38b1a096a3 --- /dev/null +++ b/Documentation/sound/oss/es1370 @@ -0,0 +1,70 @@ +/proc/sound, /dev/sndstat +------------------------- + +/proc/sound and /dev/sndstat is not supported by the +driver. To find out whether the driver succeeded loading, +check the kernel log (dmesg). + + +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +This soundcard does not have any hardware MIDI synthesizer; +MIDI synthesis has to be done in software. To allow this +the driver/soundcard supports two PCM (/dev/dsp) interfaces. +The second one goes to the mixer "synth" setting and supports +only a limited set of sampling rates (44100, 22050, 11025, 5512). +By setting lineout to 1 on the driver command line +(eg. insmod es1370 lineout=1) it is even possible on some +cards to convert the LINEIN jack into a second LINEOUT jack, thus +making it possible to output four independent audio channels! + +There is a freely available software package that allows +MIDI file playback on this soundcard called Timidity. +See http://www.cgs.fi/~tt/timidity/. + + + +Thomas Sailer +t.sailer@alumni.ethz.ch diff --git a/Documentation/sound/oss/es1371 b/Documentation/sound/oss/es1371 new file mode 100644 index 000000000000..c3151266771c --- /dev/null +++ b/Documentation/sound/oss/es1371 @@ -0,0 +1,64 @@ +/proc/sound, /dev/sndstat +------------------------- + +/proc/sound and /dev/sndstat is not supported by the +driver. To find out whether the driver succeeded loading, +check the kernel log (dmesg). + + +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +This soundcard does not have any hardware MIDI synthesizer; +MIDI synthesis has to be done in software. To allow this +the driver/soundcard supports two PCM (/dev/dsp) interfaces. + +There is a freely available software package that allows +MIDI file playback on this soundcard called Timidity. +See http://www.cgs.fi/~tt/timidity/. + + + +Thomas Sailer +t.sailer@alumni.ethz.ch diff --git a/Documentation/sound/oss/mwave b/Documentation/sound/oss/mwave new file mode 100644 index 000000000000..858334bb46b0 --- /dev/null +++ b/Documentation/sound/oss/mwave @@ -0,0 +1,185 @@ + How to try to survive an IBM Mwave under Linux SB drivers + + ++ IBM have now released documentation of sorts and Torsten is busy + trying to make the Mwave work. This is not however a trivial task. + +---------------------------------------------------------------------------- + +OK, first thing - the IRQ problem IS a problem, whether the test is bypassed or +not. It is NOT a Linux problem, but an MWAVE problem that is fixed with the +latest MWAVE patches. So, in other words, don't bypass the test for MWAVES! + +I have Windows 95 on /dev/hda1, swap on /dev/hda2, and Red Hat 5 on /dev/hda3. + +The steps, then: + + Boot to Linux. + Mount Windows 95 file system (assume mount point = /dos95). + mkdir /dos95/linux + mkdir /dos95/linux/boot + mkdir /dos95/linux/boot/parms + + Copy the kernel, any initrd image, and loadlin to /dos95/linux/boot/. + + Reboot to Windows 95. + + Edit C:/msdos.sys and add or change the following: + + Logo=0 + BootGUI=0 + + Note that msdos.sys is a text file but it needs to be made 'unhidden', + readable and writable before it can be edited. This can be done with + DOS' "attrib" command. + + Edit config.sys to have multiple config menus. I have one for windows 95 and + five for Linux, like this: +------------ +[menu] +menuitem=W95, Windows 95 +menuitem=LINTP, Linux - ThinkPad +menuitem=LINTP3, Linux - ThinkPad Console +menuitem=LINDOC, Linux - Docked +menuitem=LINDOC3, Linux - Docked Console +menuitem=LIN1, Linux - Single User Mode +REM menudefault=W95,10 + +[W95] + +[LINTP] + +[LINDOC] + +[LINTP3] + +[LINDOC3] + +[LIN1] + +[COMMON] +FILES=30 +REM Please read README.TXT in C:\MWW subdirectory before changing the DOS= statement. +DOS=HIGH,UMB +DEVICE=C:\MWW\MANAGER\MWD50430.EXE +SHELL=c:\command.com /e:2048 +------------------- + +The important things are the SHELL and DEVICE statements. + + Then change autoexec.bat. Basically everything in there originally should be + done ONLY when Windows 95 is booted. Then you add new things specifically + for Linux. Mine is as follows + +--------------- +@ECHO OFF +if "%CONFIG%" == "W95" goto W95 + +REM +REM Linux stuff +REM +SET MWPATH=C:\MWW\DLL;C:\MWW\MWGAMES;C:\MWW\DSP +SET BLASTER=A220 I5 D1 +SET MWROOT=C:\MWW +SET LIBPATH=C:\MWW\DLL +SET PATH=C:\WINDOWS;C:\MWW\DLL; +CALL MWAVE START NOSHOW +c:\linux\boot\loadlin.exe @c:\linux\boot\parms\%CONFIG%.par + +:W95 +REM +REM Windows 95 stuff +REM +c:\toolkit\guard +SET MSINPUT=C:\MSINPUT +SET MWPATH=C:\MWW\DLL;C:\MWW\MWGAMES;C:\MWW\DSP +REM The following is used by DOS games to recognize Sound Blaster hardware. +REM If hardware settings are changed, please change this line as well. +REM See the Mwave README file for instructions. +SET BLASTER=A220 I5 D1 +SET MWROOT=C:\MWW +SET LIBPATH=C:\MWW\DLL +SET PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;E:\ORAWIN95\BIN;f:\msdev\bin;e:\v30\bin.dbg;v:\devt\v30\bin;c:\JavaSDK\Bin;C:\MWW\DLL; +SET INCLUDE=f:\MSDEV\INCLUDE;F:\MSDEV\MFC\INCLUDE +SET LIB=F:\MSDEV\LIB;F:\MSDEV\MFC\LIB +win + +------------------------ + +Now build a file in c:\linux\boot\parms for each Linux config that you have. + +For example, my LINDOC3 config is for a docked Thinkpad at runlevel 3 with no +initrd image, and has a parameter file named LINDOC3.PAR in c:\linux\boot\parms: + +----------------------- +# LOADLIN @param_file image=other_image root=/dev/other +# +# Linux Console in docking station +# +c:\linux\boot\zImage.krn # First value must be filename of Linux kernel. +root=/dev/hda3 # device which gets mounted as root FS +ro # Other kernel arguments go here. +apm=off +doc=yes +3 +----------------------- + +The doc=yes parameter is an environment variable used by my init scripts, not +a kernel argument. + +However, the apm=off parameter IS a kernel argument! APM, at least in my setup, +causes the kernel to crash when loaded via loadlin (but NOT when loaded via +LILO). The APM stuff COULD be forced out of the kernel via the kernel compile +options. Instead, I got an unofficial patch to the APM drivers that allows them +to be dynamically deactivated via kernel arguments. Whatever you chose to +document, APM, it seems, MUST be off for setups like mine. + +Now make sure C:\MWW\MWCONFIG.REF looks like this: + +---------------------- +[NativeDOS] +Default=SB1.5 +SBInputSource=CD +SYNTH=FM +QSound=OFF +Reverb=OFF +Chorus=OFF +ReverbDepth=5 +ChorusDepth=5 +SBInputVolume=5 +SBMainVolume=10 +SBWaveVolume=10 +SBSynthVolume=10 +WaveTableVolume=10 +AudioPowerDriver=ON + +[FastCFG] +Show=No +HideOption=Off +----------------------------- + +OR the Default= line COULD be + +Default=SBPRO + +Reboot to Windows 95 and choose Linux. When booted, use sndconfig to configure +the sound modules and voilà - ThinkPad sound with Linux. + +Now the gotchas - you can either have CD sound OR Mixers but not both. That's a +problem with the SB1.5 (CD sound) or SBPRO (Mixers) settings. No one knows why +this is! + +For some reason MPEG3 files, when played through mpg123, sound like they +are playing at 1/8th speed - not very useful! If you have ANY insight +on why this second thing might be happening, I would be grateful. + +=========================================================== + _/ _/_/_/_/ + _/_/ _/_/ _/ + _/ _/_/ _/_/_/_/ Martin John Bartlett + _/ _/ _/ _/ (martin@nitram.demon.co.uk) +_/ _/_/_/_/ + _/ +_/ _/ + _/_/ +=========================================================== diff --git a/Documentation/sound/oss/rme96xx b/Documentation/sound/oss/rme96xx new file mode 100644 index 000000000000..87d7b7b65fa1 --- /dev/null +++ b/Documentation/sound/oss/rme96xx @@ -0,0 +1,767 @@ +Beta release of the rme96xx (driver for RME 96XX cards like the +"Hammerfall" and the "Hammerfall light") + +Important: The driver module has to be installed on a freshly rebooted system, +otherwise the driver might not be able to acquire its buffers. + +features: + + - OSS programming interface (i.e. runs with standard OSS soundsoftware) + - OSS/Multichannel interface (OSS multichannel is done by just aquiring + more than 2 channels). The driver does not use more than one device + ( yet .. this feature may be implemented later ) + - more than one RME card supported + +The driver uses a specific multichannel interface, which I will document +when the driver gets stable. (take a look at the defines in rme96xx.h, +which adds blocked multichannel formats i.e instead of +lrlrlrlr --> llllrrrr etc. + +Use the "rmectrl" programm to look at the status of the card .. +or use xrmectrl, a GUI interface for the ctrl program. + +What you can do with the rmectrl program is to set the stereo device for +OSS emulation (e.g. if you use SPDIF out). + +You do: + +./ctrl offset 24 24 + +which makes the stereo device use channels 25 and 26. + +Guenter Geiger <geiger@epy.co.at> + +copy the first part of the attached source code into rmectrl.c +and the second part into xrmectrl (or get the program from +http://gige.xdv.org/pages/soft/pages/rme) + +to compile: gcc -o rmectrl rmectrl.c +------------------------------ snip ------------------------------------ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <linux/soundcard.h> +#include <math.h> +#include <unistd.h> +#include <stdlib.h> +#include "rme96xx.h" + +/* + remctrl.c + (C) 2000 Guenter Geiger <geiger@debian.org> + HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de> +*/ + +/* # define DEVICE_NAME "/dev/mixer" */ +# define DEVICE_NAME "/dev/mixer1" + + +void usage(void) +{ + fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n"); + fprintf(stderr,"where command is one of:\n"); + fprintf(stderr," help show this help\n"); + fprintf(stderr," status show status bits\n"); + fprintf(stderr," control show control bits\n"); + fprintf(stderr," mix show mixer/offset status\n"); + fprintf(stderr," master <n> set sync master\n"); + fprintf(stderr," pro <n> set spdif out pro\n"); + fprintf(stderr," emphasis <n> set spdif out emphasis\n"); + fprintf(stderr," dolby <n> set spdif out no audio\n"); + fprintf(stderr," optout <n> set spdif out optical\n"); + fprintf(stderr," wordclock <n> set sync wordclock\n"); + fprintf(stderr," spdifin <n> set spdif in (0=optical,1=coax,2=intern)\n"); + fprintf(stderr," syncref <n> set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n"); + fprintf(stderr," adat1cd <n> set ADAT1 on internal CD\n"); + fprintf(stderr," offset <devnr> <in> <out> set dev (0..3) offset (0..25)\n"); + exit(-1); +} + + +int main(int argc, char* argv[]) +{ + int cards; + int ret; + int i; + double ft; + int fd, fdwr; + int param,orig; + rme_status_t stat; + rme_ctrl_t ctrl; + char *device; + int argidx; + + if (argc < 2) + usage(); + + if (*argv[1]=='/') { + device = argv[1]; + argidx = 2; + } + else { + device = DEVICE_NAME; + argidx = 1; + } + + fprintf(stdout,"mixer device %s\n",device); + if ((fd = open(device,O_RDONLY)) < 0) { + fprintf(stdout,"opening device failed\n"); + exit(-1); + } + + if ((fdwr = open(device,O_WRONLY)) < 0) { + fprintf(stdout,"opening device failed\n"); + exit(-1); + } + + if (argc < argidx+1) + usage(); + + if (!strcmp(argv[argidx],"help")) + usage(); + if (!strcmp(argv[argidx],"-h")) + usage(); + if (!strcmp(argv[argidx],"--help")) + usage(); + + if (!strcmp(argv[argidx],"status")) { + ioctl(fd,SOUND_MIXER_PRIVATE2,&stat); + fprintf(stdout,"stat.irq %d\n",stat.irq); + fprintf(stdout,"stat.lockmask %d\n",stat.lockmask); + fprintf(stdout,"stat.sr48 %d\n",stat.sr48); + fprintf(stdout,"stat.wclock %d\n",stat.wclock); + fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint); + fprintf(stdout,"stat.syncmask %d\n",stat.syncmask); + fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed); + fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy); + fprintf(stdout,"stat.tc_out %d\n",stat.tc_out); + fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate); + fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error); + fprintf(stdout,"stat.bufid %d\n",stat.bufid); + fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid); + exit (0); + } + + if (!strcmp(argv[argidx],"control")) { + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + fprintf(stdout,"ctrl.start %d\n",ctrl.start); + fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency); + fprintf(stdout,"ctrl.master %d\n",ctrl.master); + fprintf(stdout,"ctrl.ie %d\n",ctrl.ie); + fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48); + fprintf(stdout,"ctrl.spare %d\n",ctrl.spare); + fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed); + fprintf(stdout,"ctrl.pro %d\n",ctrl.pro); + fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis); + fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby); + fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out); + fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock); + fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in); + fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref); + fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset); + fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select); + fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock); + fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write); + fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd); + exit (0); + } + + if (!strcmp(argv[argidx],"mix")) { + rme_mixer mix; + int i; + + for (i=0; i<4; i++) { + mix.devnr = i; + ioctl(fd,SOUND_MIXER_PRIVATE1,&mix); + if (mix.devnr == i) { + fprintf(stdout,"devnr %d\n",mix.devnr); + fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset); + fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset); + } + } + exit (0); + } + +/* the control flags */ + + if (argc < argidx+2) + usage(); + + if (!strcmp(argv[argidx],"master")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("master = %d\n",val); + ctrl.master = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"pro")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("pro = %d\n",val); + ctrl.pro = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"emphasis")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("emphasis = %d\n",val); + ctrl.emphasis = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"dolby")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("dolby = %d\n",val); + ctrl.dolby = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"optout")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("optout = %d\n",val); + ctrl.opt_out = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"wordclock")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("wordclock = %d\n",val); + ctrl.wordclock = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"spdifin")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("spdifin = %d\n",val); + ctrl.spdif_in = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"syncref")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("syncref = %d\n",val); + ctrl.sync_ref = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + + if (!strcmp(argv[argidx],"adat1cd")) { + int val = atoi(argv[argidx+1]); + ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl); + printf("adat1cd = %d\n",val); + ctrl.adat1_cd = val; + ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl); + exit (0); + } + +/* setting offset */ + + if (argc < argidx+4) + usage(); + + if (!strcmp(argv[argidx],"offset")) { + rme_mixer mix; + + mix.devnr = atoi(argv[argidx+1]); + + mix.i_offset = atoi(argv[argidx+2]); + mix.o_offset = atoi(argv[argidx+3]); + ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix); + fprintf(stdout,"devnr %d\n",mix.devnr); + fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset); + fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset); + exit (0); + } + + usage(); + exit (0); /* to avoid warning */ +} + + +---------------------------- <snip> -------------------------------- +#!/usr/bin/wish + +# xrmectrl +# (C) 2000 Guenter Geiger <geiger@debian.org> +# HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de> + +#set defaults "-relief ridged" +set CTRLPROG "./rmectrl" +if {$argc} { + set CTRLPROG "$CTRLPROG $argv" +} +puts "CTRLPROG $CTRLPROG" + +frame .butts +button .butts.exit -text "Exit" -command "exit" -relief ridge +#button .butts.state -text "State" -command "get_all" + +pack .butts.exit -side left +pack .butts -side bottom + + +# +# STATUS +# + +frame .status + +# Sampling Rate + +frame .status.sr +label .status.sr.text -text "Sampling Rate" -justify left +radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times +radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times +radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times +radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw -variable srate -value 96000 -font times + +pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3 + +# Lock + +frame .status.lock +label .status.lock.text -text "Lock" -justify left +checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times +checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times +checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times + +pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 + +# Sync + +frame .status.sync +label .status.sync.text -text "Sync" -justify left +checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times +checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times +checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times + +pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 + +# Timecode + +frame .status.tc +label .status.tc.text -text "Timecode" -justify left +checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times +checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times +checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times + +pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 + +# SPDIF In + +frame .status.spdif +label .status.spdif.text -text "SPDIF In" -justify left +label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times +checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times + +pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 + +pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1 + + +# +# CONTROL +# + +proc setprof {} { + global CTRLPROG + global spprof + exec $CTRLPROG pro $spprof +} + +proc setemph {} { + global CTRLPROG + global spemph + exec $CTRLPROG emphasis $spemph +} + +proc setnoaud {} { + global CTRLPROG + global spnoaud + exec $CTRLPROG dolby $spnoaud +} + +proc setoptical {} { + global CTRLPROG + global spoptical + exec $CTRLPROG optout $spoptical +} + +proc setspdifin {} { + global CTRLPROG + global spdifin + exec $CTRLPROG spdifin [expr $spdifin - 1] +} + +proc setsyncsource {} { + global CTRLPROG + global syncsource + exec $CTRLPROG syncref [expr $syncsource -1] +} + + +proc setmaster {} { + global CTRLPROG + global master + exec $CTRLPROG master $master +} + +proc setwordclock {} { + global CTRLPROG + global wordclock + exec $CTRLPROG wordclock $wordclock +} + +proc setadat1cd {} { + global CTRLPROG + global adat1cd + exec $CTRLPROG adat1cd $adat1cd +} + + +frame .control + +# SPDIF In & SPDIF Out + + +frame .control.spdif + +frame .control.spdif.in +label .control.spdif.in.text -text "SPDIF In" -justify left +radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times +radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times +radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times + +checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times + +pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd + +label .control.spdif.space + +frame .control.spdif.out +label .control.spdif.out.text -text "SPDIF Out" -justify left +checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times +checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times +checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times +checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times + +pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom + +pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1 + +# Sync Mode & Sync Source + +frame .control.sync +frame .control.sync.mode +label .control.sync.mode.text -text "Sync Mode" -justify left +checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times +checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times + +pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc + +label .control.sync.space + +frame .control.sync.src +label .control.sync.src.text -text "Sync Source" -justify left +radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times +radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times +radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times +radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times + +pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom + +pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1 + +label .control.space -text "" -width 10 + +# Buffer Size + +frame .control.buf +label .control.buf.text -text "Buffer Size (Latency)" -justify left +radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times +radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times +radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times +radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times +radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times +radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times +radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times +radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times + +pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 + +# Offset + +frame .control.offset + +frame .control.offset.in +label .control.offset.in.text -text "Offset In" -justify left +label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times +label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times +label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times +label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times + +pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3 + +label .control.offset.space + +frame .control.offset.out +label .control.offset.out.text -text "Offset Out" -justify left +label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times +label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times +label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times +label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times + +pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom + +pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1 + + +pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1 + + +label .statustext -text Status -justify center -relief ridge +label .controltext -text Control -justify center -relief ridge + +label .statusspace +label .controlspace + +pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1 + + +proc get_bit {output sstr} { + set idx1 [string last [concat $sstr 1] $output] + set idx1 [expr $idx1 != -1] + return $idx1 +} + +proc get_val {output sstr} { + set val [string wordend $output [string last $sstr $output]] + set val [string range $output $val [expr $val+1]] + return $val +} + +proc get_val2 {output sstr} { + set val [string wordend $output [string first $sstr $output]] + set val [string range $output $val [expr $val+2]] + return $val +} + +proc get_control {} { + global spprof + global spemph + global spnoaud + global spoptical + global spdifin + global ssrate + global master + global wordclock + global syncsource + global CTRLPROG + + set f [open "| $CTRLPROG control" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + + set spprof [ get_bit $ooo "pro"] + set spemph [ get_bit $ooo "emphasis"] + set spnoaud [ get_bit $ooo "dolby"] + set spoptical [ get_bit $ooo "opt_out"] + set spdifin [ expr [ get_val $ooo "spdif_in"] + 1] + set ssrate [ expr [ get_val $ooo "latency"] + 1] + set master [ expr [ get_val $ooo "master"]] + set wordclock [ expr [ get_val $ooo "wordclock"]] + set syncsource [ expr [ get_val $ooo "sync_ref"] + 1] +} + +proc get_status {} { + global srate + global ctrlcom + + global adatlock1 + global adatlock2 + global adatlock3 + + global adatsync1 + global adatsync2 + global adatsync3 + + global tcbusy + global tcout + global tcvalid + + global spdiferr + global crystal + global .status.spdif.text + global CTRLPROG + + + set f [open "| $CTRLPROG status" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + +# samplerate + + set idx1 [string last "sr48 1" $ooo] + set idx2 [string last "doublespeed 1" $ooo] + if {$idx1 >= 0} { + set fact1 48000 + } else { + set fact1 44100 + } + + if {$idx2 >= 0} { + set fact2 2 + } else { + set fact2 1 + } + set srate [expr $fact1 * $fact2] +# ADAT lock + + set val [get_val $ooo lockmask] + set adatlock1 0 + set adatlock2 0 + set adatlock3 0 + if {[expr $val & 1]} { + set adatlock3 1 + } + if {[expr $val & 2]} { + set adatlock2 1 + } + if {[expr $val & 4]} { + set adatlock1 1 + } + +# ADAT sync + set val [get_val $ooo syncmask] + set adatsync1 0 + set adatsync2 0 + set adatsync3 0 + + if {[expr $val & 1]} { + set adatsync3 1 + } + if {[expr $val & 2]} { + set adatsync2 1 + } + if {[expr $val & 4]} { + set adatsync1 1 + } + +# TC busy + + set tcbusy [get_bit $ooo "busy"] + set tcout [get_bit $ooo "out"] + set tcvalid [get_bit $ooo "valid"] + set spdiferr [expr [get_bit $ooo "spdif_error"] == 0] + +# 000=64kHz, 100=88.2kHz, 011=96kHz +# 111=32kHz, 110=44.1kHz, 101=48kHz + + set val [get_val $ooo crystalrate] + + set crystal "--.- kHz" + if {$val == 0} { + set crystal "64 kHz" + } + if {$val == 4} { + set crystal "88.2 kHz" + } + if {$val == 3} { + set crystal "96 kHz" + } + if {$val == 7} { + set crystal "32 kHz" + } + if {$val == 6} { + set crystal "44.1 kHz" + } + if {$val == 5} { + set crystal "48 kHz" + } + .status.spdif.sr configure -text $crystal +} + +proc get_offset {} { + global inoffset + global outoffset + global CTRLPROG + + set f [open "| $CTRLPROG mix" r+] + set ooo [read $f 1000] + close $f +# puts $ooo + + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off0 configure -text "dev\#0: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off0 configure -text "dev\#0: $val" + } else { + .control.offset.in.off0 configure -text "dev\#0: -" + .control.offset.out.off0 configure -text "dev\#0: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off1 configure -text "dev\#1: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off1 configure -text "dev\#1: $val" + } else { + .control.offset.in.off1 configure -text "dev\#1: -" + .control.offset.out.off1 configure -text "dev\#1: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off2 configure -text "dev\#2: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off2 configure -text "dev\#2: $val" + } else { + .control.offset.in.off2 configure -text "dev\#2: -" + .control.offset.out.off2 configure -text "dev\#2: -" + } + if { [string match "*devnr*" $ooo] } { + set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end] + set val [get_val2 $ooo i_offset] + .control.offset.in.off3 configure -text "dev\#3: $val" + set val [get_val2 $ooo o_offset] + .control.offset.out.off3 configure -text "dev\#3: $val" + } else { + .control.offset.in.off3 configure -text "dev\#3: -" + .control.offset.out.off3 configure -text "dev\#3: -" + } +} + + +proc get_all {} { +get_status +get_control +get_offset +} + +# main +while {1} { + after 200 + get_all + update +} diff --git a/Documentation/sound/oss/solo1 b/Documentation/sound/oss/solo1 new file mode 100644 index 000000000000..6f53d407d027 --- /dev/null +++ b/Documentation/sound/oss/solo1 @@ -0,0 +1,70 @@ +Recording +--------- + +Recording does not work on the author's card, but there +is at least one report of it working on later silicon. +The chip behaves differently than described in the data sheet, +likely due to a chip bug. Working around this would require +the help of ESS (for example by publishing an errata sheet), +but ESS has not done so so far. + +Also, the chip only supports 24 bit addresses for recording, +which means it cannot work on some Alpha mainboards. + + +/proc/sound, /dev/sndstat +------------------------- + +/proc/sound and /dev/sndstat is not supported by the +driver. To find out whether the driver succeeded loading, +check the kernel log (dmesg). + + +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (or later, available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +The card has an OPL compatible FM synthesizer. + +Thomas Sailer +t.sailer@alumni.ethz.ch diff --git a/Documentation/sound/oss/sonicvibes b/Documentation/sound/oss/sonicvibes new file mode 100644 index 000000000000..84dee2e0b37d --- /dev/null +++ b/Documentation/sound/oss/sonicvibes @@ -0,0 +1,81 @@ +/proc/sound, /dev/sndstat +------------------------- + +/proc/sound and /dev/sndstat is not supported by the +driver. To find out whether the driver succeeded loading, +check the kernel log (dmesg). + + +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +The card both has an OPL compatible FM synthesizer as well as +a wavetable synthesizer. + +I haven't managed so far to get the OPL synth running. + +Using the wavetable synthesizer requires allocating +1-4MB of physically contiguous memory, which isn't possible +currently on Linux without ugly hacks like the bigphysarea +patch. Therefore, the driver doesn't support wavetable +synthesis. + + +No support from S3 +------------------ + +I do not get any support from S3. Therefore, the driver +still has many problems. For example, although the manual +states that the chip should be able to access the sample +buffer anywhere in 32bit address space, I haven't managed to +get it working with buffers above 16M. Therefore, the card +has the same disadvantages as ISA soundcards. + +Given that the card is also very noisy, and if you haven't +already bought it, you should strongly opt for one of the +comparatively priced Ensoniq products. + + +Thomas Sailer +t.sailer@alumni.ethz.ch diff --git a/Documentation/sound/oss/ultrasound b/Documentation/sound/oss/ultrasound new file mode 100644 index 000000000000..32cd50478b36 --- /dev/null +++ b/Documentation/sound/oss/ultrasound @@ -0,0 +1,30 @@ +modprobe sound +insmod ad1848 +insmod gus io=* irq=* dma=* ... + +This loads the driver for the Gravis Ultrasound family of sound cards. + +The gus module takes the following arguments + +io I/O address of the Ultrasound card (eg. io=0x220) +irq IRQ of the Sound Blaster card +dma DMA channel for the Sound Blaster +dma16 2nd DMA channel, only needed for full duplex operation +type 1 for PnP card +gus16 1 for using 16 bit sampling daughter board +no_wave_dma Set to disable DMA usage for wavetable (see note) +db16 ??? + + +no_wave_dma option + +This option defaults to a value of 0, which allows the Ultrasound wavetable +DSP to use DMA for for playback and downloading samples. This is the same +as the old behaviour. If set to 1, no DMA is needed for downloading samples, +and allows owners of a GUS MAX to make use of simultaneous digital audio +(/dev/dsp), MIDI, and wavetable playback. + + +If you have problems in recording with GUS MAX, you could try to use +just one 8 bit DMA channel. Recording will not work with one DMA +channel if it's a 16 bit one. diff --git a/Documentation/sound/oss/vwsnd b/Documentation/sound/oss/vwsnd new file mode 100644 index 000000000000..a6ea0a1df9e4 --- /dev/null +++ b/Documentation/sound/oss/vwsnd @@ -0,0 +1,293 @@ +vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual +Workstations' onboard audio. + +Copyright 1999 Silicon Graphics, Inc. All rights reserved. + + +At the time of this writing, March 1999, there are two models of +Visual Workstation, the 320 and the 540. This document only describes +those models. Future Visual Workstation models may have different +sound capabilities, and this driver will probably not work on those +boxes. + +The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio +codec chip. The AD1843 is accessed through the Cobalt I/O ASIC, also +known as Lithium. This driver programs both both chips. + +============================================================================== +QUICK CONFIGURATION + + # insmod soundcore + # insmod vwsnd + +============================================================================== +I/O CONNECTIONS + +On the Visual Workstation, only three of the AD1843 inputs are hooked +up. The analog line in jacks are connected to the AD1843's AUX1 +input. The CD audio lines are connected to the AD1843's AUX2 input. +The microphone jack is connected to the AD1843's MIC input. The mic +jack is mono, but the signal is delivered to both the left and right +MIC inputs. You can record in stereo from the mic input, but you will +get the same signal on both channels (within the limits of A/D +accuracy). Full scale on the Line input is +/- 2.0 V. Full scale on +the MIC input is 20 dB less, or +/- 0.2 V. + +The AD1843's LOUT1 outputs are connected to the Line Out jacks. The +AD1843's HPOUT outputs are connected to the speaker/headphone jack. +LOUT2 is not connected. Line out's maximum level is +/- 2.0 V peak to +peak. The speaker/headphone out's maximum is +/- 4.0 V peak to peak. + +The AD1843's PCM input channel and one of its output channels (DAC1) +are connected to Lithium. The other output channel (DAC2) is not +connected. + +============================================================================== +CAPABILITIES + +The AD1843 has PCM input and output (Pulse Code Modulation, also known +as wavetable). PCM input and output can be mono or stereo in any of +four formats. The formats are 16 bit signed and 8 bit unsigned, +u-Law, and A-Law format. Any sample rate from 4 KHz to 49 KHz is +available, in 1 Hz increments. + +The AD1843 includes an analog mixer that can mix all three input +signals (line, mic and CD) into the analog outputs. The mixer has a +separate gain control and mute switch for each input. + +There are two outputs, line out and speaker/headphone out. They +always produce the same signal, and the speaker always has 3 dB more +gain than the line out. The speaker/headphone output can be muted, +but this driver does not export that function. + +The hardware can sync audio to the video clock, but this driver does +not have a way to specify syncing to video. + +============================================================================== +PROGRAMMING + +This section explains the API supported by the driver. Also see the +Open Sound Programming Guide at http://www.opensound.com/pguide/ . +This section assumes familiarity with that document. + +The driver has two interfaces, an I/O interface and a mixer interface. +There is no MIDI or sequencer capability. + +============================================================================== +PROGRAMMING PCM I/O + +The I/O interface is usually accessed as /dev/audio or /dev/dsp. +Using the standard Open Sound System (OSS) ioctl calls, the sample +rate, number of channels, and sample format may be set within the +limitations described above. The driver supports triggering. It also +supports getting the input and output pointers with one-sample +accuracy. + +The SNDCTL_DSP_GETCAP ioctl returns these capabilities. + + DSP_CAP_DUPLEX - driver supports full duplex. + + DSP_CAP_TRIGGER - driver supports triggering. + + DSP_CAP_REALTIME - values returned by SNDCTL_DSP_GETIPTR + and SNDCTL_DSP_GETOPTR are accurate to a few samples. + +Memory mapping (mmap) is not implemented. + +The driver permits subdivided fragment sizes from 64 to 4096 bytes. +The number of fragments can be anything from 3 fragments to however +many fragments fit into 124 kilobytes. It is up to the user to +determine how few/small fragments can be used without introducing +glitches with a given workload. Linux is not realtime, so we can't +promise anything. (sigh...) + +When this driver is switched into or out of mu-Law or A-Law mode on +output, it may produce an audible click. This is unavoidable. To +prevent clicking, use signed 16-bit mode instead, and convert from +mu-Law or A-Law format in software. + +============================================================================== +PROGRAMMING THE MIXER INTERFACE + +The mixer interface is usually accessed as /dev/mixer. It is accessed +through ioctls. The mixer allows the application to control gain or +mute several audio signal paths, and also allows selection of the +recording source. + +Each of the constants described here can be read using the +MIXER_READ(SOUND_MIXER_xxx) ioctl. Those that are not read-only can +also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl. In most +cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and +SOUND_MIXER_WRITE_xxx which work just as well. + +SOUND_MIXER_CAPS Read-only + +This is a mask of optional driver capabilities that are implemented. +This driver's only capability is SOUND_CAP_EXCL_INPUT, which means +that only one recording source can be active at a time. + +SOUND_MIXER_DEVMASK Read-only + +This is a mask of the sound channels. This driver's channels are PCM, +LINE, MIC, CD, and RECLEV. + +SOUND_MIXER_STEREODEVS Read-only + +This is a mask of which sound channels are capable of stereo. All +channels are capable of stereo. (But see caveat on MIC input in I/O +CONNECTIONS section above). + +SOUND_MIXER_OUTMASK Read-only + +This is a mask of channels that route inputs through to outputs. +Those are LINE, MIC, and CD. + +SOUND_MIXER_RECMASK Read-only + +This is a mask of channels that can be recording sources. Those are +PCM, LINE, MIC, CD. + +SOUND_MIXER_PCM Default: 0x5757 (0 dB) + +This is the gain control for PCM output. The left and right channel +gain are controlled independently. This gain control has 64 levels, +which range from -82.5 dB to +12.0 dB in 1.5 dB steps. Those 64 +levels are mapped onto 100 levels at the ioctl, see below. + +SOUND_MIXER_LINE Default: 0x4a4a (0 dB) + +This is the gain control for mixing the Line In source into the +outputs. The left and right channel gain are controlled +independently. This gain control has 32 levels, which range from +-34.5 dB to +12.0 dB in 1.5 dB steps. Those 32 levels are mapped onto +100 levels at the ioctl, see below. + +SOUND_MIXER_MIC Default: 0x4a4a (0 dB) + +This is the gain control for mixing the MIC source into the outputs. +The left and right channel gain are controlled independently. This +gain control has 32 levels, which range from -34.5 dB to +12.0 dB in +1.5 dB steps. Those 32 levels are mapped onto 100 levels at the +ioctl, see below. + +SOUND_MIXER_CD Default: 0x4a4a (0 dB) + +This is the gain control for mixing the CD audio source into the +outputs. The left and right channel gain are controlled +independently. This gain control has 32 levels, which range from +-34.5 dB to +12.0 dB in 1.5 dB steps. Those 32 levels are mapped onto +100 levels at the ioctl, see below. + +SOUND_MIXER_RECLEV Default: 0 (0 dB) + +This is the gain control for PCM input (RECording LEVel). The left +and right channel gain are controlled independently. This gain +control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB +steps. Those 16 levels are mapped onto 100 levels at the ioctl, see +below. + +SOUND_MIXER_RECSRC Default: SOUND_MASK_LINE + +This is a mask of currently selected PCM input sources (RECording +SouRCes). Because the AD1843 can only have a single recording source +at a time, only one bit at a time can be set in this mask. The +allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC, +or SOUND_MASK_CD. Selecting SOUND_MASK_PCM sets up internal +resampling which is useful for loopback testing and for hardware +sample rate conversion. But software sample rate conversion is +probably faster, so I don't know how useful that is. + +SOUND_MIXER_OUTSRC DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD + +This is a mask of sources that are currently passed through to the +outputs. Those sources whose bits are not set are muted. + +============================================================================== +GAIN CONTROL + +There are five gain controls listed above. Each has 16, 32, or 64 +steps. Each control has 1.5 dB of gain per step. Each control is +stereo. + +The OSS defines the argument to a channel gain ioctl as having two +components, left and right, each of which ranges from 0 to 100. The +two components are packed into the same word, with the left side gain +in the least significant byte, and the right side gain in the second +least significant byte. In C, we would say this. + + #include <assert.h> + + ... + + assert(leftgain >= 0 && leftgain <= 100); + assert(rightgain >= 0 && rightgain <= 100); + arg = leftgain | rightgain << 8; + +So each OSS gain control has 101 steps. But the hardware has 16, 32, +or 64 steps. The hardware steps are spread across the 101 OSS steps +nearly evenly. The conversion formulas are like this, given N equals +16, 32, or 64. + + int round = N/2 - 1; + OSS_gain_steps = (hw_gain_steps * 100 + round) / (N - 1); + hw_gain_steps = (OSS_gain_steps * (N - 1) + round) / 100; + +Here is a snippet of C code that will return the left and right gain +of any channel in dB. Pass it one of the predefined gain_desc_t +structures to access any of the five channels' gains. + + typedef struct gain_desc { + float min_gain; + float gain_step; + int nbits; + int chan; + } gain_desc_t; + + const gain_desc_t gain_pcm = { -82.5, 1.5, 6, SOUND_MIXER_PCM }; + const gain_desc_t gain_line = { -34.5, 1.5, 5, SOUND_MIXER_LINE }; + const gain_desc_t gain_mic = { -34.5, 1.5, 5, SOUND_MIXER_MIC }; + const gain_desc_t gain_cd = { -34.5, 1.5, 5, SOUND_MIXER_CD }; + const gain_desc_t gain_reclev = { 0.0, 1.5, 4, SOUND_MIXER_RECLEV }; + + int get_gain_dB(int fd, const gain_desc_t *gp, + float *left, float *right) + { + int word; + int lg, rg; + int mask = (1 << gp->nbits) - 1; + + if (ioctl(fd, MIXER_READ(gp->chan), &word) != 0) + return -1; /* fail */ + lg = word & 0xFF; + rg = word >> 8 & 0xFF; + lg = (lg * mask + mask / 2) / 100; + rg = (rg * mask + mask / 2) / 100; + *left = gp->min_gain + gp->gain_step * lg; + *right = gp->min_gain + gp->gain_step * rg; + return 0; + } + +And here is the corresponding routine to set a channel's gain in dB. + + int set_gain_dB(int fd, const gain_desc_t *gp, float left, float right) + { + float max_gain = + gp->min_gain + (1 << gp->nbits) * gp->gain_step; + float round = gp->gain_step / 2; + int mask = (1 << gp->nbits) - 1; + int word; + int lg, rg; + + if (left < gp->min_gain || right < gp->min_gain) + return EINVAL; + lg = (left - gp->min_gain + round) / gp->gain_step; + rg = (right - gp->min_gain + round) / gp->gain_step; + if (lg >= (1 << gp->nbits) || rg >= (1 << gp->nbits)) + return EINVAL; + lg = (100 * lg + mask / 2) / mask; + rg = (100 * rg + mask / 2) / mask; + word = lg | rg << 8; + + return ioctl(fd, MIXER_WRITE(gp->chan), &word); + } + |