diff options
Diffstat (limited to 'Documentation/sound')
67 files changed, 4823 insertions, 9860 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d2578013e82..7ccf933bfbe 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -57,12 +57,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. - 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 - + slots - Reserve the slot index for the given driver. + This option takes multiple strings. + See "Module Autoloading Support" section for details. + debug - Specifies the debug message level + (0 = disable debug prints, 1 = normal debug messages, + 2 = verbose debug messages) + This option appears only when CONFIG_SND_DEBUG=y. + This option can be dynamically changed via sysfs + /sys/modules/snd/parameters/debug file. Module snd-pcm-oss ------------------ @@ -120,18 +123,39 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. enable - enable card - Default: enabled, for PCI and ISA PnP cards + Module snd-adlib + ---------------- + + Module for AdLib FM cards. + + port - port # for OPL chip + + This module supports multiple cards. It does not support autoprobe, so + the port must be specified. For actual AdLib FM cards it will be 0x388. + Note that this card does not have PCM support and no mixer; only FM + synthesis. + + Make sure you have "sbiload" from the alsa-tools package available and, + after loading the module, find out the assigned ALSA sequencer port + number through "sbiload -l". Example output: + + Port Client name Port name + 64:0 OPL2 FM synth OPL2 FM Port + + Load the std.sb and drums.sb patches also supplied by sbiload: + + sbiload -p 64:0 std.sb drums.sb + + If you use this driver to drive an OPL3, you can use std.o3 and drums.o3 + instead. To have the card produce sound, use aplaymidi from alsa-utils: + + aplaymidi -p 64:0 foo.mid + 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) clockfreq - Clock frequency for AD1816A chip (default = 0, 33000Hz) This module supports multiple cards, autoprobe and PnP. @@ -178,18 +202,19 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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) - This module supports multiple cards, autoprobe and PnP. The power-management is supported. + Module snd-als300 + ----------------- + + Module for Avance Logic ALS300 and ALS300+ + + This module supports multiple cards. + + The power-management is supported. + Module snd-als4000 ------------------ @@ -202,6 +227,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + Module snd-asihpi + ----------------- + + Module for AudioScience ASI soundcards + + enable_hpi_hwdep - enable HPI hwdep for AudioScience soundcard + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + Module snd-atiixp ----------------- @@ -210,6 +245,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ac97_clock - AC'97 clock (default = 48000) ac97_quirk - AC'97 workaround for strange hardware See "AC97 Quirk Option" section below. + ac97_codec - Workaround to specify which AC'97 codec + instead of probing. If this works for you + file a bug with your `lspci -vn` output. + -2 -- Force probing. + -1 -- Default behavior. + 0-2 -- Use the specified codec. spdif_aclink - S/PDIF transfer over AC-link (default = 1) This module supports one card and autoprobe. @@ -259,20 +300,86 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. control correctly. If you have problems regarding this, try another ALSA compliant mixer (alsamixer works). + Module snd-azt1605 + ------------------ + + Module for Aztech Sound Galaxy soundcards based on the Aztech AZT1605 + chipset. + + port - port # for BASE (0x220,0x240,0x260,0x280) + wss_port - port # for WSS (0x530,0x604,0xe80,0xf40) + irq - IRQ # for WSS (7,9,10,11) + dma1 - DMA # for WSS playback (0,1,3) + dma2 - DMA # for WSS capture (0,1), -1 = disabled (default) + mpu_port - port # for MPU-401 UART (0x300,0x330), -1 = disabled (default) + mpu_irq - IRQ # for MPU-401 UART (3,5,7,9), -1 = disabled (default) + fm_port - port # for OPL3 (0x388), -1 = disabled (default) + + This module supports multiple cards. It does not support autoprobe: port, + wss_port, irq and dma1 have to be specified. The other values are + optional. + + "port" needs to match the BASE ADDRESS jumper on the card (0x220 or 0x240) + or the value stored in the card's EEPROM for cards that have an EEPROM and + their "CONFIG MODE" jumper set to "EEPROM SETTING". The other values can + be chosen freely from the options enumerated above. + + If dma2 is specified and different from dma1, the card will operate in + full-duplex mode. When dma1=3, only dma2=0 is valid and the only way to + enable capture since only channels 0 and 1 are available for capture. + + Generic settings are "port=0x220 wss_port=0x530 irq=10 dma1=1 dma2=0 + mpu_port=0x330 mpu_irq=9 fm_port=0x388". + + Whatever IRQ and DMA channels you pick, be sure to reserve them for + legacy ISA in your BIOS. + + Module snd-azt2316 + ------------------ + + Module for Aztech Sound Galaxy soundcards based on the Aztech AZT2316 + chipset. + + port - port # for BASE (0x220,0x240,0x260,0x280) + wss_port - port # for WSS (0x530,0x604,0xe80,0xf40) + irq - IRQ # for WSS (7,9,10,11) + dma1 - DMA # for WSS playback (0,1,3) + dma2 - DMA # for WSS capture (0,1), -1 = disabled (default) + mpu_port - port # for MPU-401 UART (0x300,0x330), -1 = disabled (default) + mpu_irq - IRQ # for MPU-401 UART (5,7,9,10), -1 = disabled (default) + fm_port - port # for OPL3 (0x388), -1 = disabled (default) + + This module supports multiple cards. It does not support autoprobe: port, + wss_port, irq and dma1 have to be specified. The other values are + optional. + + "port" needs to match the BASE ADDRESS jumper on the card (0x220 or 0x240) + or the value stored in the card's EEPROM for cards that have an EEPROM and + their "CONFIG MODE" jumper set to "EEPROM SETTING". The other values can + be chosen freely from the options enumerated above. + + If dma2 is specified and different from dma1, the card will operate in + full-duplex mode. When dma1=3, only dma2=0 is valid and the only way to + enable capture since only channels 0 and 1 are available for capture. + + Generic settings are "port=0x220 wss_port=0x530 irq=10 dma1=1 dma2=0 + mpu_port=0x330 mpu_irq=9 fm_port=0x388". + + Whatever IRQ and DMA channels you pick, be sure to reserve them for + legacy ISA in your BIOS. + + Module snd-aw2 + -------------- + + Module for Audiowerk2 sound card + + This module supports multiple cards. + 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) - This module supports multiple cards, PnP and autoprobe. The power-management is supported. @@ -312,6 +419,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for sound cards based on C-Media CMI8330 ISA chips. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + wssport - port # for CMI8330 chip (WSS) wssirq - IRQ # for CMI8330 chip (WSS) wssdma - first DMA # for CMI8330 chip (WSS) @@ -319,6 +430,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. sbirq - IRQ # for CMI8330 chip (SB16) sbdma8 - 8bit DMA # for CMI8330 chip (SB16) sbdma16 - 16bit DMA # for CMI8330 chip (SB16) + fmport - (optional) OPL3 I/O port + mpuport - (optional) MPU401 I/O port + mpuirq - (optional) MPU401 irq # This module supports multiple cards and autoprobe. @@ -327,10 +441,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-cmipci ----------------- - Module for C-Media CMI8338 and 8738 PCI sound cards. + Module for C-Media CMI8338/8738/8768/8770 PCI sound cards. - mpu_port - 0x300,0x310,0x320,0x330, 0 = disable (default) - fm_port - 0x388 (default), 0 = disable (default) + mpu_port - port address of MIDI interface (8338 only): + 0x300,0x310,0x320,0x330 = legacy port, + 0 = disable (default) + fm_port - port address of OPL-3 FM synthesizer (8x38 only): + 0x388 = legacy port, + 1 = integrated PCI port (default on 8738), + 0 = disable soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only) (default = 1) joystick_port - Joystick port address (0 = disable, 1 = auto-detect) @@ -356,31 +475,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. - Module snd-cs4232 + Module snd-cs4236 ----------------- - Module for sound cards based on CS4232/CS4232A ISA chips. + Module for sound cards based on CS4232/CS4232A, + CS4235/CS4236/CS4236B/CS4237B/ + CS4238B/CS4239 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) - - This module supports multiple 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. + with isapnp=0, the following options are available: port - port # for CS4236 chip (PnP setup - 0x534) cport - control port # for CS4236 chip (PnP setup - 0x120,0x210,0xf00) @@ -390,7 +494,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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) This module supports multiple cards. This module does not support autoprobe (if ISA PnP is not used) thus main port and control port must be @@ -398,6 +501,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + This module is aliased as snd-cs4232 since it provides the old + snd-cs4232 functionality, too. + Module snd-cs4281 ----------------- @@ -425,27 +531,63 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. above explicitly. The power-management is supported. - + + Module snd-cs5530 + _________________ + + Module for Cyrix/NatSemi Geode 5530 chip. + Module snd-cs5535audio ---------------------- Module for multifunction CS5535 companion PCI device + The power-management is supported. + + Module snd-ctxfi + ---------------- + + Module for Creative Sound Blaster X-Fi boards (20k1 / 20k2 chips) + * Creative Sound Blaster X-Fi Titanium Fatal1ty Champion Series + * Creative Sound Blaster X-Fi Titanium Fatal1ty Professional Series + * Creative Sound Blaster X-Fi Titanium Professional Audio + * Creative Sound Blaster X-Fi Titanium + * Creative Sound Blaster X-Fi Elite Pro + * Creative Sound Blaster X-Fi Platinum + * Creative Sound Blaster X-Fi Fatal1ty + * Creative Sound Blaster X-Fi XtremeGamer + * Creative Sound Blaster X-Fi XtremeMusic + + reference_rate - reference sample rate, 44100 or 48000 (default) + multiple - multiple to ref. sample rate, 1 or 2 (default) + subsystem - override the PCI SSID for probing; the value + consists of SSVID << 16 | SSDID. The default is + zero, which means no override. + This module supports multiple cards. + Module snd-darla20 + ------------------ + + Module for Echoaudio Darla20 + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-darla24 + ------------------ + + Module for Echoaudio Darla24 + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + 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) - This module supports multiple cards. This module is enabled only with ISA PnP support. @@ -458,8 +600,36 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. or input, but you may use this module for any application which requires a sound card (like RealPlayer). + pcm_devs - Number of PCM devices assigned to each card + (default = 1, up to 4) + pcm_substreams - Number of PCM substreams assigned to each PCM + (default = 8, up to 128) + hrtimer - Use hrtimer (=1, default) or system timer (=0) + fake_buffer - Fake buffer allocations (default = 1) + + When multiple PCM devices are created, snd-dummy gives different + behavior to each PCM device: + 0 = interleaved with mmap support + 1 = non-interleaved with mmap support + 2 = interleaved without mmap + 3 = non-interleaved without mmap + + As default, snd-dummy drivers doesn't allocate the real buffers + but either ignores read/write or mmap a single dummy page to all + buffer pages, in order to save the resources. If your apps need + the read/ written buffer data to be consistent, pass fake_buffer=0 + option. + The power-management is supported. + Module snd-echo3g + ----------------- + + Module for Echoaudio 3G cards (Gina3G/Layla3G) + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + Module snd-emu10k1 ------------------ @@ -513,6 +683,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards and autoprobe. + The power-management is supported. + Module snd-ens1371 ------------------ @@ -526,17 +698,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple 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) - - This module supports multiple cards, PnP and autoprobe. - The power-management is supported. Module snd-es1688 @@ -544,26 +705,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for ESS AudioDrive ES-1688 and ES-688 sound cards. - port - port # for ES-1688 chip (0x220,0x240,0x260) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) 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) + fm_port - port # for OPL3 (option; share the same port as default) + + with isapnp=0, the following additional options are available: + port - port # for ES-1688 chip (0x220,0x240,0x260) + irq - IRQ # for ES-1688 chip (5,7,9,10) dma8 - DMA # for ES-1688 chip (0,1,3) - This module supports multiple cards and autoprobe (without MPU-401 port). + This module supports multiple cards and autoprobe (without MPU-401 port) + and PnP with the ES968 chip. Module snd-es18xx ----------------- Module for ESS AudioDrive ES-18xx sound cards. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + 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) This module supports multiple cards, ISA PnP and autoprobe (without MPU-401 port if native ISA PnP routines are not used). @@ -614,6 +783,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + Module snd-gina20 + ----------------- + + Module for Echoaudio Gina20 + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-gina24 + ----------------- + + Module for Echoaudio Gina24 + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + Module snd-gusclassic --------------------- @@ -666,63 +851,113 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-hda-intel -------------------- - Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450, - VIA VT8251/VT8237A + Module for Intel HD Audio (ICH6, ICH6M, ESB2, ICH7, ICH8, ICH9, ICH10, + PCH, SCH), + ATI SB450, SB600, R600, RS600, RS690, RS780, RV610, RV620, + RV630, RV635, RV670, RV770, + VIA VT8251/VT8237A, + SIS966, ULI M5461 + [Multiple options for each card instance] model - force the model name - position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) + position_fix - Fix DMA pointer + -1 = system default: choose appropriate one per controller + hardware + 0 = auto: falls back to LPIB when POSBUF doesn't work + 1 = use LPIB + 2 = POSBUF: use position buffer + 3 = VIACOMBO: VIA-specific workaround for capture + 4 = COMBO: use LPIB for playback, auto for capture stream + probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) + When the bit 8 (0x100) is set, the lower 8 bits are used + as the "fixed" codec slots; i.e. the driver probes the + slots regardless what hardware reports back + probe_only - Only probing and no codec initialization (default=off); + Useful to check the initial codec status for debugging + bdl_pos_adj - Specifies the DMA IRQ timing delay in samples. + Passing -1 will make the driver to choose the appropriate + value based on the controller chip. + patch - Specifies the early "patch" files to modify the HD-audio + setup before initializing the codecs. This option is + available only when CONFIG_SND_HDA_PATCH_LOADER=y is set. + See HD-Audio.txt for details. + beep_mode - Selects the beep registration mode (0=off, 1=on); default + value is set via CONFIG_SND_HDA_INPUT_BEEP_MODE kconfig. + + [Single (global) options] + single_cmd - Use single immediate commands to communicate with + codecs (for debugging only) + enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) + power_save - Automatic power-saving timeout (in second, 0 = + disable) + power_save_controller - Reset HD-audio controller in power-saving mode + (default = on) + align_buffer_size - Force rounding of buffer/period sizes to multiples + of 128 bytes. This is more efficient in terms of memory + access but isn't required by the HDA spec and prevents + users from specifying exact period/buffer sizes. + (default = on) + snoop - Enable/disable snooping (default = on) - This module supports one card and autoprobe. + This module supports multiple cards and autoprobe. + + See Documentation/sound/alsa/HD-Audio.txt for more details about + HD-audio driver. 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 - 6stack 6-jack in back, 2-jack in front - 6stack-digout 6-jack with a SPDIF out - w810 3-jack - z71v 3-jack (HP shared SPDIF) - asus 3-jack - uniwill 3-jack - F1734 2-jack - test for testing/debugging purpose, almost all controls can be - adjusted. Appearing only when compiled with - $CONFIG_SND_DEBUG=y - - ALC260 - hp HP machines - fujitsu Fujitsu S7020 - - 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 - auto auto-config reading BIOS (default) + models depending on the codec chip. The list of available models + is found in HD-Audio-Models.txt + + The model name "generic" is treated as a special case. When this + model is given, the driver uses the generic codec parser without + "codec-patch". It's sometimes good for testing and debugging. If the default configuration doesn't work and one of the above - matches with your device, report it together with the PCI - subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel + matches with your device, report it together with alsa-info.sh + output (with --no-upload option) to kernel bugzilla or alsa-devel ML (see the section "Links and Addresses"). + power_save and power_save_controller options are for power-saving + mode. See powersave.txt for details. + Note 2: If you get click noises on output, try the module option position_fix=1 or 2. position_fix=1 will use the SD_LPIB register value without FIFO size correction as the current DMA pointer. position_fix=2 will make the driver to use the position buffer instead of reading SD_LPIB register. - (Usually SD_LPLIB register is more accurate than the + (Usually SD_LPIB register is more accurate than the position buffer.) + position_fix=3 is specific to VIA devices. The position + of the capture stream is checked from both LPIB and POSBUF + values. position_fix=4 is a combination mode, using LPIB + for playback and POSBUF for capture. + + NB: If you get many "azx_get_response timeout" messages at + loading, it's likely a problem of interrupts (e.g. ACPI irq + routing). Try to boot with options like "pci=noacpi". Also, you + can try "single_cmd=1" module option. This will switch the + communication method between HDA controller and codecs to the + single immediate commands instead of CORB/RIRB. Basically, the + single command mode is provided only for BIOS, and you won't get + unsolicited events, too. But, at least, this works independently + from the irq. Remember this is a last resort, and should be + avoided as much as possible... + + MORE NOTES ON "azx_get_response timeout" PROBLEMS: + On some hardware, you may need to add a proper probe_mask option + to avoid the "azx_get_response timeout" problem above, instead. + This occurs when the access to non-existing or non-working codec slot + (likely a modem one) causes a stall of the communication via HD-audio + bus. You can see which codec slots are probed by enabling + CONFIG_SND_DEBUG_VERBOSE, or simply from the file name of the codec + proc files. Then limit the slots to probe by probe_mask option. + For example, probe_mask=1 means to probe only the first slot, and + probe_mask=4 means only the third slot. + The power-management is supported. Module snd-hdsp @@ -778,6 +1013,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * Event Electronics, EZ8 * Digigram VX442 * Lionstracs, Mediastaton + * Terrasoniq TS 88 model - Use the given board model, one of the following: delta1010, dio2496, delta66, delta44, audiophile, delta410, @@ -785,7 +1021,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. dmx6fire, dsp24, dsp24_value, dsp24_71, ez8, phase88, mediastation omni - Omni I/O support for MidiMan M-Audio Delta44/66 - cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever) + cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transceiver) in msec resolution, default value is 500 (0.5 sec) This module supports multiple cards and autoprobe. Note: The consumer part @@ -802,7 +1038,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ------------------ Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. + * MidiMan M Audio Revolution 5.1 * MidiMan M Audio Revolution 7.1 + * MidiMan M Audio Audiophile 192 * AMP Ltd AUDIO2000 * TerraTec Aureon 5.1 Sky * TerraTec Aureon 7.1 Space @@ -810,6 +1048,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * TerraTec Phase 22 * TerraTec Phase 28 * AudioTrak Prodigy 7.1 + * AudioTrak Prodigy 7.1 LT + * AudioTrak Prodigy 7.1 XT + * AudioTrak Prodigy 7.1 HIFI + * AudioTrak Prodigy 7.1 HD2 * AudioTrak Prodigy 192 * Pontis MS300 * Albatron K8X800 Pro II @@ -818,11 +1060,19 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * Chaintech 9CJS * Chaintech AV-710 * Shuttle SN25P + * Onkyo SE-90PCI + * Onkyo SE-200PCI + * ESI Juli@ + * ESI Maya44 + * Hercules Fortissimo IV + * EGO-SYS WaveTerminal 192M model - Use the given board model, one of the following: - revo71, amp2000, prodigy71, prodigy192, aureon51, - aureon71, universe, k8x800, phase22, phase28, ms300, - av710 + revo51, revo71, amp2000, prodigy71, prodigy71lt, + prodigy71xt, prodigy71hifi, prodigyhd2, prodigy192, + juli, aureon51, aureon71, universe, ap192, k8x800, + phase22, phase28, ms300, av710, se200pci, se90pci, + fortissimo4, sn25p, WT192M, maya44 This module supports multiple cards and autoprobe. @@ -832,13 +1082,39 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. driver isn't configured properly or you want to try another type for testing. + Module snd-indigo + ----------------- + + Module for Echoaudio Indigo + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-indigodj + ------------------- + + Module for Echoaudio Indigo DJ + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-indigoio + ------------------- + + Module for Echoaudio Indigo IO + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + Module snd-intel8x0 ------------------- Module for AC'97 motherboards from Intel and compatibles. * Intel i810/810E, i815, i820, i830, i84x, MX440 + ICH5, ICH6, ICH7, 6300ESB, ESB2 * SiS 7012 (SiS 735) - * NVidia NForce, NForce2 + * NVidia NForce, NForce2, NForce3, MCP04, CK804 + CK8, CK8S, MCP501 * AMD AMD768, AMD8111 * ALi m5455 @@ -848,9 +1124,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. buggy_irq - Enable workaround for buggy interrupts on some motherboards (default yes on nForce chips, otherwise off) - buggy_semaphore - Enable workaround for hardwares with buggy + buggy_semaphore - Enable workaround for hardware with buggy semaphores (e.g. on some ASUS laptops) (default off) + spdif_aclink - Use S/PDIF over AC-link instead of direct connection + from the controller chip + (0 = off, 1 = on, -1 = default) This module supports one chip and autoprobe. @@ -868,6 +1147,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. -------------------- Module for Intel ICH (i8x0) chipset MC97 modems. + * Intel i810/810E, i815, i820, i830, i84x, MX440 + ICH5, ICH6, ICH7 + * SiS 7013 (SiS 735) + * NVidia NForce, NForce2, NForce2s, NForce3 + * AMD AMD8111 + * ALi m5455 ac97_clock - AC'97 codec clock base (0 = auto-detect) @@ -884,15 +1169,19 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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 + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + + 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) This module supports multiple cards, autoprobe and ISA PnP. @@ -903,19 +1192,38 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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 + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + + 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) This module supports multiple cards, autoprobe and ISA PnP. + Module snd-jazz16 + ------------------- + + Module for Media Vision Jazz16 chipset. The chipset consists of 3 chips: + MVD1216 + MVA416 + MVA514. + + port - port # for SB DSP chip (0x210,0x220,0x230,0x240,0x250,0x260) + irq - IRQ # for SB DSP chip (3,5,7,9,10,15) + dma8 - DMA # for SB DSP chip (1,3) + dma16 - DMA # for SB DSP chip (5,7) + mpu_port - MPU-401 port # (0x300,0x310,0x320,0x330) + mpu_irq - MPU-401 irq # (2,3,5,7) + + This module supports multiple cards. + Module snd-korg1212 ------------------- @@ -923,6 +1231,36 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards. + Module snd-layla20 + ------------------ + + Module for Echoaudio Layla20 + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-layla24 + ------------------ + + Module for Echoaudio Layla24 + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-lola + --------------- + + Module for Digigram Lola PCI-e boards + + This module supports multiple cards. + + Module snd-lx6464es + ------------------- + + Module for Digigram LX6464ES boards + + This module supports multiple cards. + Module snd-maestro3 ------------------- @@ -943,6 +1281,31 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + Module snd-mia + --------------- + + Module for Echoaudio Mia + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + + Module snd-miro + --------------- + + Module for Miro soundcards: miroSOUND PCM 1 pro, + miroSOUND PCM 12, + miroSOUND PCM 20 Radio. + + port - Port # (0x530,0x604,0xe80,0xf40) + irq - IRQ # (5,7,9,10,11) + dma1 - 1st dma # (0,1,3) + dma2 - 2nd dma # (0,1) + mpu_port - MPU-401 port # (0x300,0x310,0x320,0x330) + mpu_irq - MPU-401 irq # (5,7,9,10) + fm_port - FM Port # (0x388) + wss - enable WSS mode + ide - enable onboard ide support + Module snd-mixart ----------------- @@ -958,6 +1321,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. When no hotplug fw loader is available, you need to load the firmware via mixartloader utility in alsa-tools package. + Module snd-mona + --------------- + + Module for Echoaudio Mona + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + Module snd-mpu401 ----------------- @@ -969,6 +1340,54 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple devices and PnP. + Module snd-msnd-classic + ----------------------- + + Module for Turtle Beach MultiSound Classic, Tahiti or Monterey + soundcards. + + io - Port # for msnd-classic card + irq - IRQ # for msnd-classic card + mem - Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000, + 0xe0000 or 0xe8000) + write_ndelay - enable write ndelay (default = 1) + calibrate_signal - calibrate signal (default = 0) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + digital - Digital daughterboard present (default = 0) + cfg - Config port (0x250, 0x260 or 0x270) default = PnP + reset - Reset all devices + mpu_io - MPU401 I/O port + mpu_irq - MPU401 irq# + ide_io0 - IDE port #0 + ide_io1 - IDE port #1 + ide_irq - IDE irq# + joystick_io - Joystick I/O port + + The driver requires firmware files "turtlebeach/msndinit.bin" and + "turtlebeach/msndperm.bin" in the proper firmware directory. + + See Documentation/sound/oss/MultiSound for important information + about this driver. Note that it has been discontinued, but the + Voyetra Turtle Beach knowledge base entry for it is still available + at + http://www.turtlebeach.com + + Module snd-msnd-pinnacle + ------------------------ + + Module for Turtle Beach MultiSound Pinnacle/Fiji soundcards. + + io - Port # for pinnacle/fiji card + irq - IRQ # for pinnalce/fiji card + mem - Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000, + 0xe0000 or 0xe8000) + write_ndelay - enable write ndelay (default = 1) + calibrate_signal - calibrate signal (default = 0) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + The driver requires firmware files "turtlebeach/pndspini.bin" and + "turtlebeach/pndsperm.bin" in the proper firmware directory. + Module snd-mtpav ---------------- @@ -981,6 +1400,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module supports only 1 card. This module has no enable option. + Module snd-mts64 + ---------------- + + Module for Ego Systems (ESI) Miditerminal 4140 + + This module supports multiple devices. + Requires parport (CONFIG_PARPORT). + Module snd-nm256 ---------------- @@ -1002,8 +1429,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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. + In such a case, specify the buffer top address explicitly via + the buffer_top option. For example, Sony F250: buffer_top=0x25a800 Sony F270: buffer_top=0x272800 @@ -1043,6 +1470,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for Yamaha OPL3-SA2/SA3 sound cards. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + 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) @@ -1051,7 +1482,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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) This module supports multiple cards and ISA PnP. It does not support autoprobe (if ISA PnP is not used) thus all ports must be specified!!! @@ -1064,6 +1494,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for sound cards based on OPTi 82c92x and Analog Devices AD1848 chips. Module works with OAK Mozart cards as well. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + 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) @@ -1078,6 +1512,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for sound cards based on OPTi 82c92x and Crystal CS4231 chips. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + 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) @@ -1093,6 +1531,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for sound cards based on OPTi 82c93x chips. + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + 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) @@ -1103,6 +1545,37 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports only one card, autoprobe and PnP. + Module snd-oxygen + ----------------- + + Module for sound cards based on the C-Media CMI8786/8787/8788 chip: + * Asound A-8788 + * Asus Xonar DG/DGX + * AuzenTech X-Meridian + * AuzenTech X-Meridian 2G + * Bgears b-Enspirer + * Club3D Theatron DTS + * HT-Omega Claro (plus) + * HT-Omega Claro halo (XT) + * Kuroutoshikou CMI8787-HG2PCI + * Razer Barracuda AC-1 + * Sondigo Inferno + * TempoTec HiFier Fantasia + * TempoTec HiFier Serenade + + This module supports autoprobe and multiple cards. + + Module snd-pcsp + ----------------- + + Module for internal PC-Speaker. + + nopcm - Disable PC-Speaker PCM sound. Only beeps remain. + nforce_wa - enable NForce chipset workaround. Expect bad sound. + + This module supports system beeps, some kind of PCM playback and + even a few mixer controls. + Module snd-pcxhr ---------------- @@ -1110,6 +1583,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards. + Module snd-portman2x4 + --------------------- + + Module for Midiman Portman 2x4 parallel port MIDI interface + + This module supports multiple cards. + Module snd-powermac (on ppc only) --------------------------------- @@ -1119,7 +1599,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module supports autoprobe a chip. - Note: the driver may have problems regarding endianess. + Note: the driver may have problems regarding endianness. The power-management is supported. @@ -1132,6 +1612,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + Module snd-riptide + ------------------ + + Module for Conexant Riptide chip + + joystick_port - Joystick port # (default: 0x200) + mpu_port - MPU401 port # (default: 0x330) + opl3_port - OPL3 port # (default: 0x388) + + This module supports multiple cards. + The driver requires the firmware loader support on kernel. + You need to install the firmware file "riptide.hex" to the standard + firmware path (e.g. /lib/firmware). + Module snd-rme32 ---------------- @@ -1196,6 +1690,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. SoundBlaster AWE 32 (PnP), SoundBlaster AWE 64 PnP + 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) + + with isapnp=0, the following options are available: + 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) @@ -1203,9 +1703,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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) This module supports multiple cards, autoprobe and ISA PnP. @@ -1217,33 +1714,39 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. - Module snd-sgalaxy - ------------------ + Module snd-sc6000 + ----------------- - Module for Aztech Sound Galaxy sound card. + Module for Gallant SC-6000 soundcard and later models: SC-6600 + and SC-7000. - sbport - Port # for SB16 interface (0x220,0x240) - wssport - Port # for WSS interface (0x530,0xe80,0xf40,0x604) - irq - IRQ # (7,9,10,11) - dma1 - DMA # + port - Port # (0x220 or 0x240) + mss_port - MSS Port # (0x530 or 0xe80) + irq - IRQ # (5,7,9,10,11) + mpu_irq - MPU-401 IRQ # (5,7,9,10) ,0 - no MPU-401 irq + dma - DMA # (1,3,0) + joystick - Enable gameport - 0 = disable (default), 1 = enable This module supports multiple cards. - The power-management is supported. + This card is also known as Audio Excel DSP 16 or Zoltrix AV302. Module snd-sscape ----------------- - Module for ENSONIQ SoundScape PnP cards. + Module for ENSONIQ SoundScape cards. port - Port # (PnP setup) + wss_port - WSS Port # (PnP setup) irq - IRQ # (PnP setup) mpu_irq - MPU-401 IRQ # (PnP setup) dma - DMA # (PnP setup) + dma2 - 2nd DMA # (PnP setup, -1 to disable) + joystick - Enable gameport - 0 = disable (default), 1 = enable + + This module supports multiple cards. - This module supports multiple cards. ISA PnP must be enabled. - You need sscape_ctl tool in alsa-tools package for loading - the microcode. + The driver requires the firmware loader support on kernel. Module snd-sun-amd7930 (on sparc only) -------------------------------------- @@ -1271,21 +1774,68 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for Turtle Beach Maui, Tropez and Tropez+ sound cards. + use_cs4232_midi - Use CS4232 MPU-401 interface + (inaccessibly located inside your computer) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) + + with isapnp=0, the following options are available: + 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) + + The below are options for wavefront_synth features: + wf_raw - Assume that we need to boot the OS (default:no) + If yes, then during driver loading, the state of the board is + ignored, and we reset the board and load the firmware anyway. + fx_raw - Assume that the FX process needs help (default:yes) + If false, we'll leave the FX processor in whatever state it is + when the driver is loaded. The default is to download the + microprogram and associated coefficients to set it up for + "default" operation, whatever that means. + debug_default - Debug parameters for card initialization + wait_usecs - How long to wait without sleeping, usecs + (default:150) + This magic number seems to give pretty optimal throughput + based on my limited experimentation. + If you want to play around with it and find a better value, be + my guest. Remember, the idea is to get a number that causes us + to just busy wait for as many WaveFront commands as possible, + without coming up with a number so large that we hog the whole + CPU. + Specifically, with this number, out of about 134,000 status + waits, only about 250 result in a sleep. + sleep_interval - How long to sleep when waiting for reply + (default: 100) + sleep_tries - How many times to try sleeping during a wait + (default: 50) + ospath - Pathname to processed ICS2115 OS firmware + (default:wavefront.os) + The path name of the ISC2115 OS firmware. In the recent + version, it's handled via firmware loader framework, so it + must be installed in the proper path, typically, + /lib/firmware. + reset_time - How long to wait for a reset to take effect + (default:2) + ramcheck_time - How many seconds to wait for the RAM test + (default:20) + osrun_time - How many seconds to wait for the ICS2115 OS + (default:10) This module supports multiple cards and ISA PnP. + Note: the firmware file "wavefront.os" was located in the earlier + version in /etc. Now it's loaded via firmware loader, and + must be in the proper firmware path, such as /lib/firmware. + Copy (or symlink) the file appropriately if you get an error + regarding firmware downloading after upgrading the kernel. + Module snd-sonicvibes --------------------- @@ -1330,6 +1880,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * CHIC True Sound 4Dwave * Shark Predator4D-PCI * Jaton SonicWave 4D + * SiS SI7018 PCI Audio + * Hoontech SoundTrack Digital 4DWave NX pcm_channels - max channels (voices) reserved for PCM wavetable_size - max wavetable size in kB (4-?kb) @@ -1338,6 +1890,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. + Module snd-ua101 + ---------------- + + Module for the Edirol UA-101/UA-1000 audio/MIDI interfaces. + + This module supports multiple devices, autoprobe and hotplugging. + Module snd-usb-audio -------------------- @@ -1345,6 +1904,30 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. vid - Vendor ID for the device (optional) pid - Product ID for the device (optional) + nrpacks - Max. number of packets per URB (default: 8) + device_setup - Device specific magic number (optional) + - Influence depends on the device + - Default: 0x0000 + ignore_ctl_error - Ignore any USB-controller regarding mixer + interface (default: no) + + This module supports multiple devices, autoprobe and hotplugging. + + NB: nrpacks parameter can be modified dynamically via sysfs. + Don't put the value over 20. Changing via sysfs has no sanity + check. + NB: ignore_ctl_error=1 may help when you get an error at accessing + the mixer element such as URB error -22. This happens on some + buggy USB device or the controller. + + Module snd-usb-caiaq + -------------------- + + Module for caiaq UB audio interfaces, + * Native Instruments RigKontrol2 + * Native Instruments Kore Controller + * Native Instruments Audio Kontrol 1 + * Native Instruments Audio 8 DJ This module supports multiple devices, autoprobe and hotplugging. @@ -1439,6 +2022,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards. + Module snd-virtuoso + ------------------- + + Module for sound cards based on the Asus AV66/AV100/AV200 chips, + i.e., Xonar D1, DX, D2, D2X, DS, Essence ST (Deluxe), Essence STX, + HDAV1.3 (Deluxe), and HDAV1.3 Slim. + + This module supports autoprobe and multiple cards. + Module snd-vx222 ---------------- @@ -1454,7 +2046,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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 + vxloader automatically, add the following to /etc/modprobe.d/alsa.conf install snd-vx222 /sbin/modprobe --first-time -i snd-vx222 && /usr/bin/vxloader @@ -1491,9 +2083,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. About capture IBL, see the description of snd-vx222 module. - Note: the driver is build only when CONFIG_ISA is set. - - Note2: snd-vxp440 driver is merged to snd-vxpocket driver since + Note: snd-vxp440 driver is merged to snd-vxpocket driver since ALSA 1.0.10. The power-management is supported. @@ -1520,8 +2110,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module for Sound Core PDAudioCF sound card. - Note: the driver is build only when CONFIG_ISA is set. - The power-management is supported. @@ -1582,10 +2170,10 @@ corresponds to the card index of ALSA. Usually, define this as the same card module. An example configuration for a single emu10k1 card is like below: ------ /etc/modprobe.conf +----- /etc/modprobe.d/alsa.conf alias snd-card-0 snd-emu10k1 alias sound-slot-0 snd-emu10k1 ------ /etc/modprobe.conf +----- /etc/modprobe.d/alsa.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. @@ -1598,7 +2186,7 @@ cards is kept consistent. An example configuration for two sound cards is like below: ------ /etc/modprobe.conf +----- /etc/modprobe.d/alsa.conf # ALSA portion options snd cards_limit=2 alias snd-card-0 snd-interwave @@ -1608,11 +2196,32 @@ options snd-ens1371 index=1 # OSS/Free portion alias sound-slot-0 snd-interwave alias sound-slot-1 snd-ens1371 ------ /etc/moprobe.conf +----- /etc/modprobe.d/alsa.conf In this example, the interwave card is always loaded as the first card (index 0) and ens1371 as the second (index 1). +Alternative (and new) way to fixate the slot assignment is to use +"slots" option of snd module. In the case above, specify like the +following: + +options snd slots=snd-interwave,snd-ens1371 + +Then, the first slot (#0) is reserved for snd-interwave driver, and +the second (#1) for snd-ens1371. You can omit index option in each +driver if slots option is used (although you can still have them at +the same time as long as they don't conflict). + +The slots option is especially useful for avoiding the possible +hot-plugging and the resultant slot conflict. For example, in the +case above again, the first two slots are already reserved. If any +other driver (e.g. snd-usb-audio) is loaded before snd-interwave or +snd-ens1371, it will be assigned to the third or later slot. + +When a module name is given with '!', the slot will be given for any +modules but that name. For example, "slots=!snd-pcsp" will reserve +the first slot for any modules but snd-pcsp. + ALSA PCM devices to OSS devices mapping ======================================= @@ -1636,27 +2245,12 @@ 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 "erase" - erase all additional information about OSS applications String "<app_name> <fragments> <fragment_size> [<options>]" <app_name> - name of application with (higher priority) or without path @@ -1717,8 +2311,11 @@ Links and Addresses ALSA project homepage http://www.alsa-project.org - ALSA Bug Tracking System - https://bugtrack.alsa-project.org/bugs/ + Kernel Bugzilla + http://bugzilla.kernel.org/ ALSA Developers ML - mailto:alsa-devel@lists.sourceforge.net + mailto:alsa-devel@alsa-project.org + + alsa-info.sh script + http://www.alsa-project.org/alsa-info.sh diff --git a/Documentation/sound/alsa/Audigy-mixer.txt b/Documentation/sound/alsa/Audigy-mixer.txt index 5132fd95e07..7f10dc6ff28 100644 --- a/Documentation/sound/alsa/Audigy-mixer.txt +++ b/Documentation/sound/alsa/Audigy-mixer.txt @@ -6,7 +6,7 @@ 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 +(This article 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 diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt new file mode 100644 index 00000000000..e7a5ed4dcae --- /dev/null +++ b/Documentation/sound/alsa/Audiophile-Usb.txt @@ -0,0 +1,442 @@ + Guide to using M-Audio Audiophile USB with ALSA and Jack v1.5 + ======================================================== + + Thibault Le Meur <Thibault.LeMeur@supelec.fr> + +This document is a guide to using the M-Audio Audiophile USB (tm) device with +ALSA and JACK. + +History +======= +* v1.4 - Thibault Le Meur (2007-07-11) + - Added Low Endianness nature of 16bits-modes + found by Hakan Lennestal <Hakan.Lennestal@brfsodrahamn.se> + - Modifying document structure +* v1.5 - Thibault Le Meur (2007-07-12) + - Added AC3/DTS passthru info + + +1 - Audiophile USB Specs and correct usage +========================================== + +This part is a reminder of important facts about the functions and limitations +of the device. + +The device has 4 audio interfaces, and 2 MIDI ports: + * Analog Stereo Input (Ai) + - This port supports 2 pairs of line-level audio inputs (1/4" TS and RCA) + - When the 1/4" TS (jack) connectors are connected, the RCA connectors + are disabled + * Analog Stereo Output (Ao) + * Digital Stereo Input (Di) + * Digital Stereo Output (Do) + * Midi In (Mi) + * Midi Out (Mo) + +The internal DAC/ADC has the following characteristics: +* sample depth of 16 or 24 bits +* sample rate from 8kHz to 96kHz +* Two interfaces can't use different sample depths at the same time. +Moreover, the Audiophile USB documentation gives the following Warning: +"Please exit any audio application running before switching between bit depths" + +Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be +activated at the same time depending on the audio mode selected: + * 16-bit/48kHz ==> 4 channels in + 4 channels out + - Ai+Ao+Di+Do + * 24-bit/48kHz ==> 4 channels in + 2 channels out, + or 2 channels in + 4 channels out + - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do + * 24-bit/96kHz ==> 2 channels in _or_ 2 channels out (half duplex only) + - Ai or Ao or Di or Do + +Important facts about the Digital interface: +-------------------------------------------- + * The Do port additionally supports surround-encoded AC-3 and DTS passthrough, +though I haven't tested it under Linux + - Note that in this setup only the Do interface can be enabled + * Apart from recording an audio digital stream, enabling the Di port is a way +to synchronize the device to an external sample clock + - As a consequence, the Di port must be enable only if an active Digital +source is connected + - Enabling Di when no digital source is connected can result in a +synchronization error (for instance sound played at an odd sample rate) + + +2 - Audiophile USB MIDI support in ALSA +======================================= + +The Audiophile USB MIDI ports will be automatically supported once the +following modules have been loaded: + * snd-usb-audio + * snd-seq-midi + +No additional setting is required. + + +3 - Audiophile USB Audio support in ALSA +======================================== + +Audio functions of the Audiophile USB device are handled by the snd-usb-audio +module. This module can work in a default mode (without any device-specific +parameter), or in an "advanced" mode with the device-specific parameter called +"device_setup". + +3.1 - Default Alsa driver mode +------------------------------ + +The default behavior of the snd-usb-audio driver is to list the device +capabilities at startup and activate the required mode when required +by the applications: for instance if the user is recording in a +24bit-depth-mode and immediately after wants to switch to a 16bit-depth mode, +the snd-usb-audio module will reconfigure the device on the fly. + +This approach has the advantage to let the driver automatically switch from sample +rates/depths automatically according to the user's needs. However, those who +are using the device under windows know that this is not how the device is meant to +work: under windows applications must be closed before using the m-audio control +panel to switch the device working mode. Thus as we'll see in next section, this +Default Alsa driver mode can lead to device misconfigurations. + +Let's get back to the Default Alsa driver mode for now. In this case the +Audiophile interfaces are mapped to alsa pcm devices in the following +way (I suppose the device's index is 1): + * hw:1,0 is Ao in playback and Di in capture + * hw:1,1 is Do in playback and Ai in capture + * hw:1,2 is Do in AC3/DTS passthrough mode + +In this mode, the device uses Big Endian byte-encoding so that +supported audio format are S16_BE for 16-bit depth modes and S24_3BE for +24-bits depth mode. + +One exception is the hw:1,2 port which was reported to be Little Endian +compliant (supposedly supporting S16_LE) but processes in fact only S16_BE streams. +This has been fixed in kernel 2.6.23 and above and now the hw:1,2 interface +is reported to be big endian in this default driver mode. + +Examples: + * playing a S24_3BE encoded raw file to the Ao port + % aplay -D hw:1,0 -c2 -t raw -r48000 -fS24_3BE test.raw + * recording a S24_3BE encoded raw file from the Ai port + % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw + * playing a S16_BE encoded raw file to the Do port + % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw + * playing an ac3 sample file to the Do port + % aplay -D hw:1,2 --channels=6 ac3_S16_BE_encoded_file.raw + +If you're happy with the default Alsa driver mode and don't experience any +issue with this mode, then you can skip the following chapter. + +3.2 - Advanced module setup +--------------------------- + +Due to the hardware constraints described above, the device initialization made +by the Alsa driver in default mode may result in a corrupted state of the +device. For instance, a particularly annoying issue is that the sound captured +from the Ai interface sounds distorted (as if boosted with an excessive high +volume gain). + +For people having this problem, the snd-usb-audio module has a new module +parameter called "device_setup" (this parameter was introduced in kernel +release 2.6.17) + +3.2.1 - Initializing the working mode of the Audiophile USB + +As far as the Audiophile USB device is concerned, this value let the user +specify: + * the sample depth + * the sample rate + * whether the Di port is used or not + +When initialized with "device_setup=0x00", the snd-usb-audio module has +the same behaviour as when the parameter is omitted (see paragraph "Default +Alsa driver mode" above) + +Others modes are described in the following subsections. + +3.2.1.1 - 16-bit modes + +The two supported modes are: + + * device_setup=0x01 + - 16bits 48kHz mode with Di disabled + - Ai,Ao,Do can be used at the same time + - hw:1,0 is not available in capture mode + - hw:1,2 is not available + + * device_setup=0x11 + - 16bits 48kHz mode with Di enabled + - Ai,Ao,Di,Do can be used at the same time + - hw:1,0 is available in capture mode + - hw:1,2 is not available + +In this modes the device operates only at 16bits-modes. Before kernel 2.6.23, +the devices where reported to be Big-Endian when in fact they were Little-Endian +so that playing a file was a matter of using: + % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw +where "test_S16_LE.raw" was in fact a little-endian sample file. + +Thanks to Hakan Lennestal (who discovered the Little-Endiannes of the device in +these modes) a fix has been committed (expected in kernel 2.6.23) and +Alsa now reports Little-Endian interfaces. Thus playing a file now is as simple as +using: + % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw + +3.2.1.2 - 24-bit modes + +The three supported modes are: + + * device_setup=0x09 + - 24bits 48kHz mode with Di disabled + - Ai,Ao,Do can be used at the same time + - hw:1,0 is not available in capture mode + - hw:1,2 is not available + + * device_setup=0x19 + - 24bits 48kHz mode with Di enabled + - 3 ports from {Ai,Ao,Di,Do} can be used at the same time + - hw:1,0 is available in capture mode and an active digital source must be + connected to Di + - hw:1,2 is not available + + * device_setup=0x0D or 0x10 + - 24bits 96kHz mode + - Di is enabled by default for this mode but does not need to be connected + to an active source + - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time + - hw:1,0 is available in captured mode + - hw:1,2 is not available + +In these modes the device is only Big-Endian compliant (see "Default Alsa driver +mode" above for an aplay command example) + +3.2.1.3 - AC3 w/ DTS passthru mode + +Thanks to Hakan Lennestal, I now have a report saying that this mode works. + + * device_setup=0x03 + - 16bits 48kHz mode with only the Do port enabled + - AC3 with DTS passthru + - Caution with this setup the Do port is mapped to the pcm device hw:1,0 + +The command line used to playback the AC3/DTS encoded .wav-files in this mode: + % aplay -D hw:1,0 --channels=6 ac3_S16_LE_encoded_file.raw + +3.2.2 - How to use the device_setup parameter +---------------------------------------------- + +The parameter can be given: + + * By manually probing the device (as root): + # modprobe -r snd-usb-audio + # modprobe snd-usb-audio index=1 device_setup=0x09 + + * Or while configuring the modules options in your modules configuration file + (typically a .conf file in /etc/modprobe.d/ directory: + alias snd-card-1 snd-usb-audio + options snd-usb-audio index=1 device_setup=0x09 + +CAUTION when initializing the device +------------------------------------- + + * Correct initialization on the device requires that device_setup is given to + the module BEFORE the device is turned on. So, if you use the "manual probing" + method described above, take care to power-on the device AFTER this initialization. + + * Failing to respect this will lead to a misconfiguration of the device. In this case + turn off the device, unprobe the snd-usb-audio module, then probe it again with + correct device_setup parameter and then (and only then) turn on the device again. + + * If you've correctly initialized the device in a valid mode and then want to switch + to another mode (possibly with another sample-depth), please use also the following + procedure: + - first turn off the device + - de-register the snd-usb-audio module (modprobe -r) + - change the device_setup parameter by changing the device_setup + option in /etc/modprobe.d/*.conf + - turn on the device + * A workaround for this last issue has been applied to kernel 2.6.23, but it may not + be enough to ensure the 'stability' of the device initialization. + +3.2.3 - Technical details for hackers +------------------------------------- +This section is for hackers, wanting to understand details about the device +internals and how Alsa supports it. + +3.2.3.1 - Audiophile USB's device_setup structure + +If you want to understand the device_setup magic numbers for the Audiophile +USB, you need some very basic understanding of binary computation. However, +this is not required to use the parameter and you may skip this section. + +The device_setup is one byte long and its structure is the following: + + +---+---+---+---+---+---+---+---+ + | b7| b6| b5| b4| b3| b2| b1| b0| + +---+---+---+---+---+---+---+---+ + | 0 | 0 | 0 | Di|24B|96K|DTS|SET| + +---+---+---+---+---+---+---+---+ + +Where: + * b0 is the "SET" bit + - it MUST be set if device_setup is initialized + * b1 is the "DTS" bit + - it is set only for Digital output with DTS/AC3 + - this setup is not tested + * b2 is the Rate selection flag + - When set to "1" the rate range is 48.1-96kHz + - Otherwise the sample rate range is 8-48kHz + * b3 is the bit depth selection flag + - When set to "1" samples are 24bits long + - Otherwise they are 16bits long + - Note that b2 implies b3 as the 96kHz mode is only supported for 24 bits + samples + * b4 is the Digital input flag + - When set to "1" the device assumes that an active digital source is + connected + - You shouldn't enable Di if no source is seen on the port (this leads to + synchronization issues) + - b4 is implied by b2 (since only one port is enabled at a time no synch + error can occur) + * b5 to b7 are reserved for future uses, and must be set to "0" + - might become Ao, Do, Ai, for b7, b6, b4 respectively + +Caution: + * there is no check on the value you will give to device_setup + - for instance choosing 0x05 (16bits 96kHz) will fail back to 0x09 since + b2 implies b3. But _there_will_be_no_warning_ in /var/log/messages + * Hardware constraints due to the USB bus limitation aren't checked + - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll + only be able to use one at the same time + +3.2.3.2 - USB implementation details for this device + +You may safely skip this section if you're not interested in driver +hacking. + +This section describes some internal aspects of the device and summarizes the +data I got by usb-snooping the windows and Linux drivers. + +The M-Audio Audiophile USB has 7 USB Interfaces: +a "USB interface": + * USB Interface nb.0 + * USB Interface nb.1 + - Audio Control function + * USB Interface nb.2 + - Analog Output + * USB Interface nb.3 + - Digital Output + * USB Interface nb.4 + - Analog Input + * USB Interface nb.5 + - Digital Input + * USB Interface nb.6 + - MIDI interface compliant with the MIDIMAN quirk + +Each interface has 5 altsettings (AltSet 1,2,3,4,5) except: + * Interface 3 (Digital Out) has an extra Alset nb.6 + * Interface 5 (Digital In) does not have Alset nb.3 and 5 + +Here is a short description of the AltSettings capabilities: + * AltSettings 1 corresponds to + - 24-bit depth, 48.1-96kHz sample mode + - Adaptive playback (Ao and Do), Synch capture (Ai), or Asynch capture (Di) + * AltSettings 2 corresponds to + - 24-bit depth, 8-48kHz sample mode + - Asynch capture and playback (Ao,Ai,Do,Di) + * AltSettings 3 corresponds to + - 24-bit depth, 8-48kHz sample mode + - Synch capture (Ai) and Adaptive playback (Ao,Do) + * AltSettings 4 corresponds to + - 16-bit depth, 8-48kHz sample mode + - Asynch capture and playback (Ao,Ai,Do,Di) + * AltSettings 5 corresponds to + - 16-bit depth, 8-48kHz sample mode + - Synch capture (Ai) and Adaptive playback (Ao,Do) + * AltSettings 6 corresponds to + - 16-bit depth, 8-48kHz sample mode + - Synch playback (Do), audio format type III IEC1937_AC-3 + +In order to ensure a correct initialization of the device, the driver +_must_know_ how the device will be used: + * if DTS is chosen, only Interface 2 with AltSet nb.6 must be + registered + * if 96KHz only AltSets nb.1 of each interface must be selected + * if samples are using 24bits/48KHz then AltSet 2 must me used if + Digital input is connected, and only AltSet nb.3 if Digital input + is not connected + * if samples are using 16bits/48KHz then AltSet 4 must me used if + Digital input is connected, and only AltSet nb.5 if Digital input + is not connected + +When device_setup is given as a parameter to the snd-usb-audio module, the +parse_audio_endpoints function uses a quirk called +"audiophile_skip_setting_quirk" in order to prevent AltSettings not +corresponding to device_setup from being registered in the driver. + +4 - Audiophile USB and Jack support +=================================== + +This section deals with support of the Audiophile USB device in Jack. + +There are 2 main potential issues when using Jackd with the device: +* support for Big-Endian devices in 24-bit modes +* support for 4-in / 4-out channels + +4.1 - Direct support in Jackd +----------------------------- + +Jack supports big endian devices only in recent versions (thanks to +Andreas Steinmetz for his first big-endian patch). I can't remember +exactly when this support was released into jackd, let's just say that +with jackd version 0.103.0 it's almost ok (just a small bug is affecting +16bits Big-Endian devices, but since you've read carefully the above +paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices +are now Little Endians ;-) ). + +You can run jackd with the following command for playback with Ao and +record with Ai: + % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 + +4.2 - Using Alsa plughw +----------------------- +If you don't have a recent Jackd installed, you can downgrade to using +the Alsa "plug" converter. + +For instance here is one way to run Jack with 2 playback channels on Ao and 2 +capture channels from Ai: + % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 + +However you may see the following warning message: +"You appear to be using the ALSA software "plug" layer, probably a result of +using the "default" ALSA device. This is less efficient than it could be. +Consider using a hardware device instead rather than using the plug layer." + +4.3 - Getting 2 input and/or output interfaces in Jack +------------------------------------------------------ + +As you can see, starting the Jack server this way will only enable 1 stereo +input (Di or Ai) and 1 stereo output (Ao or Do). + +This is due to the following restrictions: +* Jack can only open one capture device and one playback device at a time +* The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1 + (and optionally hw:1,2) + +If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to +combine the Alsa devices into one logical "complex" device. + +If you want to give it a try, I recommend reading the information from +this page: http://www.sound-man.co.uk/linuxaudio/ice1712multi.html +It is related to another device (ice1712) but can be adapted to suit +the Audiophile USB. + +Enabling multiple Audiophile USB interfaces for Jackd will certainly require: +* Making sure your Jackd version has the MMAP_COMPLEX patch (see the ice1712 page) +* (maybe) patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) +* define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc + file +* start jackd with this device + +I had no success in testing this for now, if you have any success with this kind +of setup, please drop me an email. diff --git a/Documentation/sound/alsa/Bt87x.txt b/Documentation/sound/alsa/Bt87x.txt index 11edb2fd2a5..f158cde8b06 100644 --- a/Documentation/sound/alsa/Bt87x.txt +++ b/Documentation/sound/alsa/Bt87x.txt @@ -36,8 +36,8 @@ 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. +<alsa-devel@alsa-project.org>, regardless of whether audio capture works +or not, so that future versions of this driver know about your card. Audio modes diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt index 1872e24442a..4e36e6e809c 100644 --- a/Documentation/sound/alsa/CMIPCI.txt +++ b/Documentation/sound/alsa/CMIPCI.txt @@ -1,5 +1,5 @@ - Brief Notes on C-Media 8738/8338 Driver - ======================================= + Brief Notes on C-Media 8338/8738/8768/8770 Driver + ================================================= Takashi Iwai <tiwai@suse.de> @@ -16,11 +16,11 @@ 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. +There are slight differences between the 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. +- The second DAC supports only two channel stereo. Please note that the CM8x38 DAC doesn't support continuous playback rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000, @@ -76,7 +76,7 @@ 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 +For programming 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, @@ -87,7 +87,7 @@ with 4 channels, and use the interleaved 4 channel data. -There are some control switchs affecting to the speaker connections: +There are some control switches affecting to the speaker connections: "Line-In Mode" - an enum control to change the behavior of line-in jack. Either "Line-In", "Rear Output" or "Bass Output" can @@ -209,10 +209,13 @@ In addition to the standard SB mixer, CM8x38 provides more functions. MIDI CONTROLLER --------------- -The MPU401-UART interface is disabled as default. You need to set -module option "mpu_port" with a valid I/O port address to enable the -MIDI support. The valid I/O ports are 0x300, 0x310, 0x320 and 0x330. -Choose the value which doesn't conflict with other cards. +With CMI8338 chips, the MPU401-UART interface is disabled as default. +You need to set the module option "mpu_port" to a valid I/O port address +to enable MIDI support. Valid I/O ports are 0x300, 0x310, 0x320 and +0x330. Choose a value that doesn't conflict with other cards. + +With CMI8738 and newer chips, the MIDI interface is enabled by default +and the driver automatically chooses a port address. There is _no_ hardware wavetable function on this chip (except for OPL3 synth below). @@ -230,6 +233,8 @@ Set "fm_port" module option for more cards. The output quality of FM OPL/3 is, however, very weird. I don't know why.. +CMI8768 and newer chips do not have the FM synth. + Joystick and Modem ------------------ diff --git a/Documentation/sound/alsa/Channel-Mapping-API.txt b/Documentation/sound/alsa/Channel-Mapping-API.txt new file mode 100644 index 00000000000..3c43d1a4ca0 --- /dev/null +++ b/Documentation/sound/alsa/Channel-Mapping-API.txt @@ -0,0 +1,153 @@ +ALSA PCM channel-mapping API +============================ + Takashi Iwai <tiwai@suse.de> + +GENERAL +------- + +The channel mapping API allows user to query the possible channel maps +and the current channel map, also optionally to modify the channel map +of the current stream. + +A channel map is an array of position for each PCM channel. +Typically, a stereo PCM stream has a channel map of + { front_left, front_right } +while a 4.0 surround PCM stream has a channel map of + { front left, front right, rear left, rear right }. + +The problem, so far, was that we had no standard channel map +explicitly, and applications had no way to know which channel +corresponds to which (speaker) position. Thus, applications applied +wrong channels for 5.1 outputs, and you hear suddenly strange sound +from rear. Or, some devices secretly assume that center/LFE is the +third/fourth channels while others that C/LFE as 5th/6th channels. + +Also, some devices such as HDMI are configurable for different speaker +positions even with the same number of total channels. However, there +was no way to specify this because of lack of channel map +specification. These are the main motivations for the new channel +mapping API. + + +DESIGN +------ + +Actually, "the channel mapping API" doesn't introduce anything new in +the kernel/user-space ABI perspective. It uses only the existing +control element features. + +As a ground design, each PCM substream may contain a control element +providing the channel mapping information and configuration. This +element is specified by: + iface = SNDRV_CTL_ELEM_IFACE_PCM + name = "Playback Channel Map" or "Capture Channel Map" + device = the same device number for the assigned PCM substream + index = the same index number for the assigned PCM substream + +Note the name is different depending on the PCM substream direction. + +Each control element provides at least the TLV read operation and the +read operation. Optionally, the write operation can be provided to +allow user to change the channel map dynamically. + +* TLV + +The TLV operation gives the list of available channel +maps. A list item of a channel map is usually a TLV of + type data-bytes ch0 ch1 ch2... +where type is the TLV type value, the second argument is the total +bytes (not the numbers) of channel values, and the rest are the +position value for each channel. + +As a TLV type, either SNDRV_CTL_TLVT_CHMAP_FIXED, +SNDRV_CTL_TLV_CHMAP_VAR or SNDRV_CTL_TLVT_CHMAP_PAIRED can be used. +The _FIXED type is for a channel map with the fixed channel position +while the latter two are for flexible channel positions. _VAR type is +for a channel map where all channels are freely swappable and _PAIRED +type is where pair-wise channels are swappable. For example, when you +have {FL/FR/RL/RR} channel map, _PAIRED type would allow you to swap +only {RL/RR/FL/FR} while _VAR type would allow even swapping FL and +RR. + +These new TLV types are defined in sound/tlv.h. + +The available channel position values are defined in sound/asound.h, +here is a cut: + +/* channel positions */ +enum { + SNDRV_CHMAP_UNKNOWN = 0, + SNDRV_CHMAP_NA, /* N/A, silent */ + SNDRV_CHMAP_MONO, /* mono stream */ + /* this follows the alsa-lib mixer channel value + 3 */ + SNDRV_CHMAP_FL, /* front left */ + SNDRV_CHMAP_FR, /* front right */ + SNDRV_CHMAP_RL, /* rear left */ + SNDRV_CHMAP_RR, /* rear right */ + SNDRV_CHMAP_FC, /* front center */ + SNDRV_CHMAP_LFE, /* LFE */ + SNDRV_CHMAP_SL, /* side left */ + SNDRV_CHMAP_SR, /* side right */ + SNDRV_CHMAP_RC, /* rear center */ + /* new definitions */ + SNDRV_CHMAP_FLC, /* front left center */ + SNDRV_CHMAP_FRC, /* front right center */ + SNDRV_CHMAP_RLC, /* rear left center */ + SNDRV_CHMAP_RRC, /* rear right center */ + SNDRV_CHMAP_FLW, /* front left wide */ + SNDRV_CHMAP_FRW, /* front right wide */ + SNDRV_CHMAP_FLH, /* front left high */ + SNDRV_CHMAP_FCH, /* front center high */ + SNDRV_CHMAP_FRH, /* front right high */ + SNDRV_CHMAP_TC, /* top center */ + SNDRV_CHMAP_TFL, /* top front left */ + SNDRV_CHMAP_TFR, /* top front right */ + SNDRV_CHMAP_TFC, /* top front center */ + SNDRV_CHMAP_TRL, /* top rear left */ + SNDRV_CHMAP_TRR, /* top rear right */ + SNDRV_CHMAP_TRC, /* top rear center */ + SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC, +}; + +When a PCM stream can provide more than one channel map, you can +provide multiple channel maps in a TLV container type. The TLV data +to be returned will contain such as: + SNDRV_CTL_TLVT_CONTAINER 96 + SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC + SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR + SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \ + SNDRV_CHMAP_RL SNDRV_CHMAP_RR + +The channel position is provided in LSB 16bits. The upper bits are +used for bit flags. + +#define SNDRV_CHMAP_POSITION_MASK 0xffff +#define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16) +#define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16) + +SNDRV_CHMAP_PHASE_INVERSE indicates the channel is phase inverted, +(thus summing left and right channels would result in almost silence). +Some digital mic devices have this. + +When SNDRV_CHMAP_DRIVER_SPEC is set, all the channel position values +don't follow the standard definition above but driver-specific. + +* READ OPERATION + +The control read operation is for providing the current channel map of +the given stream. The control element returns an integer array +containing the position of each channel. + +When this is performed before the number of the channel is specified +(i.e. hw_params is set), it should return all channels set to +UNKNOWN. + +* WRITE OPERATION + +The control write operation is optional, and only for devices that can +change the channel configuration on the fly, such as HDMI. User needs +to pass an integer value containing the valid channel positions for +all channels of the assigned PCM substream. + +This operation is allowed only at PCM PREPARED state. When called in +other states, it shall return an error. diff --git a/Documentation/sound/alsa/ControlNames.txt b/Documentation/sound/alsa/ControlNames.txt index 5b18298e949..fea65bb6269 100644 --- a/Documentation/sound/alsa/ControlNames.txt +++ b/Documentation/sound/alsa/ControlNames.txt @@ -18,8 +18,9 @@ SOURCE: Master Master Mono Hardware Master + Speaker (internal speaker) Headphone - PC Speaker + Beep (beep generator) Phone Phone Input Phone Output diff --git a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl deleted file mode 100644 index 1f3ae3e32d6..00000000000 --- a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl +++ /dev/null @@ -1,100 +0,0 @@ -<!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 deleted file mode 100644 index e651ed8d1e6..00000000000 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ /dev/null @@ -1,6128 +0,0 @@ -<!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>November 17, 2005</date> - <edition>0.3.6</edition> - - <abstract> - <para> - This document describes how to write an ALSA (Advanced Linux - Sound Architecture) driver. - </para> - </abstract> - - <legalnotice> - <para> - Copyright (c) 2002-2005 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_register_driver()</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 */ - struct mychip { - struct snd_card *card; - // rest of implementation will be in the section - // "PCI Resource Managements" - }; - - /* chip-specific destructor - * (see "PCI Resource Managements") - */ - static int snd_mychip_free(struct mychip *chip) - { - .... // will be implemented later... - } - - /* component-destructor - * (see "Management of Cards and Components") - */ - static int snd_mychip_dev_free(struct snd_device *device) - { - return snd_mychip_free(device->device_data); - } - - /* chip-specific constructor - * (see "Management of Cards and Components") - */ - static int __devinit snd_mychip_create(struct snd_card *card, - struct pci_dev *pci, - struct mychip **rchip) - { - struct mychip *chip; - int err; - static struct snd_device_ops 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 = kzalloc(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; - struct snd_card *card; - struct mychip *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[ - struct snd_card *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[ - struct mychip *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[ - struct snd_card *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 struct <structname>snd_device</structname> 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. - - <informalexample> - <programlisting> -<![CDATA[ - struct 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(struct mychip)); -]]> - </programlisting> - </informalexample> - - whether struct <structname>mychip</structname> is the type of the chip record. - </para> - - <para> - In return, the allocated record can be accessed as - - <informalexample> - <programlisting> -<![CDATA[ - struct mychip *chip = (struct mychip *)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>kzalloc()</function>. - - <informalexample> - <programlisting> -<![CDATA[ - struct snd_card *card; - struct mychip *chip; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL); - ..... - chip = kzalloc(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 mychip { - struct snd_card *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 struct snd_device_ops 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(struct snd_device *device) - { - return snd_mychip_free(device->device_data); - } -]]> - </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 mychip { - struct snd_card *card; - struct pci_dev *pci; - - unsigned long port; - int irq; - }; - - static int snd_mychip_free(struct mychip *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(struct snd_card *card, - struct pci_dev *pci, - struct mychip **rchip) - { - struct mychip *chip; - int err; - static struct snd_device_ops 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 = kzalloc(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", 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_register_driver(&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 struct <structname>mychip</structname> will have the - following fields: - - <informalexample> - <programlisting> -<![CDATA[ - struct mychip { - struct snd_card *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>kzalloc()</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", 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) - { - struct mychip *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[ - release_and_free_resource(chip->res_port); -]]> - </programlisting> - </informalexample> - </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 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(struct mychip *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 struct <structname>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_register_driver(&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 struct snd_pcm_hardware 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 struct snd_pcm_hardware 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(struct snd_pcm_substream *substream) - { - struct mychip *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *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(struct snd_pcm_substream *substream) - { - struct mychip *chip = snd_pcm_substream_chip(substream); - // the hardware-specific codes will be here - return 0; - - } - - /* open callback */ - static int snd_mychip_capture_open(struct snd_pcm_substream *substream) - { - struct mychip *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *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(struct snd_pcm_substream *substream) - { - struct mychip *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(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) - { - return snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - } - - /* hw_free callback */ - static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream) - { - return snd_pcm_lib_free_pages(substream); - } - - /* prepare callback */ - static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream) - { - struct mychip *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *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(struct snd_pcm_substream *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(struct snd_pcm_substream *substream) - { - struct mychip *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 struct snd_pcm_ops 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 struct snd_pcm_ops 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(struct mychip *chip) - { - struct snd_pcm *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(struct mychip *chip) - { - struct snd_pcm *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 - struct <structname>snd_pcm_substream</structname> data passed to each callback - as follows: - - <informalexample> - <programlisting> -<![CDATA[ - struct snd_pcm_substream *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 struct snd_pcm_ops 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(struct snd_pcm *pcm) - { - struct mychip *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(struct mychip *chip) - { - struct snd_pcm *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 -- */ - struct snd_pcm_substream *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 -- */ - struct timespec 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 struct snd_pcm_mmap_status *status; - volatile struct snd_pcm_mmap_control *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)(struct snd_pcm_runtime *runtime); - - /* -- hardware description -- */ - struct snd_pcm_hardware hw; - struct snd_pcm_hw_constraints hw_constraints; - - /* -- interrupt callbacks -- */ - void (*transfer_ack_begin)(struct snd_pcm_substream *substream); - void (*transfer_ack_end)(struct snd_pcm_substream *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 -- */ - struct snd_pcm_oss_runtime 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 (struct <structname>snd_pcm_hardware</structname>) - 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[ - struct snd_pcm_runtime *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 struct snd_pcm_hardware 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 full <quote>suspend/resume</quote> operation. - If <constant>PAUSE</constant> flag is set, - the <structfield>trigger</structfield> callback below - must handle the corresponding (pause push/release) commands. - The suspend/resume trigger commands can be defined even without - <constant>RESUME</constant> flag. See <link - linkend="power-management"><citetitle> - Power Management</citetitle></link> section for details. - </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 struct <structname>snd_pcm_mmap_status</structname> - 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 - struct <structname>snd_pcm_mmap_control</structname> 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(struct snd_pcm_substream *substream) - { - struct my_pcm_data *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 - <structname>snd_pcm_substream</structname> pointer. For retrieving the - chip record from the given substream instance, you can use the - following macro. - - <informalexample> - <programlisting> -<![CDATA[ - int xxx() { - struct mychip *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(struct snd_pcm_substream *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(struct snd_pcm_substream *substream) - { - struct mychip *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *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(struct snd_pcm_substream *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(struct snd_pcm_substream *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(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *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(struct snd_pcm_substream *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(struct snd_pcm_substream *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(struct snd_pcm_substream *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, - regardless of full or partial suspend/resume support, - <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. - See <link linkend="power-management"><citetitle> - Power Management</citetitle></link> section for details. - </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(struct snd_pcm_substream *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) - { - struct mychip *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) - { - struct mychip *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 struct snd_pcm_hw_constraint_list constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, - }; - - static int snd_mychip_pcm_open(struct snd_pcm_substream *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 <structname>snd_pcm_hardware</structname> 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(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) - { - struct snd_interval *c = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_mask 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(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) - { - struct snd_interval *c = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_interval 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 - struct <structname>snd_kcontrol_new</structname> record, such as: - - <example> - <title>Definition of a Control</title> - <programlisting> -<![CDATA[ - static struct snd_kcontrol_new 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>, which - is usually <constant>MIXER</constant>. - Use <constant>CARD</constant> for global controls that are not - logically part of the mixer. - If the control is closely associated with some specific device on - the sound card, use <constant>HWDEP</constant>, - <constant>PCM</constant>, <constant>RAWMIDI</constant>, - <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and - specify the device number with the - <structfield>device</structfield> and - <structfield>subdevice</structfield> fields. - </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 struct <structname>snd_ctl_elem_info</structname> - 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(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *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(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *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(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { - struct mychip *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 - just accesses to kcontrol->private_data. 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(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *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(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { - struct mychip *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 - struct <structname>snd_kcontrol_new</structname> 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 - <structname>snd_kcontrol</structname> 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 struct <structname>snd_ctl_elem_id</structname> - 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 mychip { - .... - struct snd_ac97 *ac97; - .... - }; - - static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) - { - struct mychip *chip = ac97->private_data; - .... - // read a register value here from the codec - return the_register_value; - } - - static void snd_mychip_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, unsigned short val) - { - struct mychip *chip = ac97->private_data; - .... - // write the given register value to the codec - } - - static int snd_mychip_ac97(struct mychip *chip) - { - struct snd_ac97_bus *bus; - struct snd_ac97_template ac97; - int err; - static struct snd_ac97_bus_ops 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[ - struct snd_ac97_bus *bus; - static struct snd_ac97_bus_ops 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 - struct <structname>snd_ac97_template</structname> - record together with the bus pointer created above. - - <informalexample> - <programlisting> -<![CDATA[ - struct snd_ac97_template 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(struct snd_ac97 *ac97, - unsigned short reg) - { - struct mychip *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(struct snd_ac97 *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_mixer()</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[ - struct snd_rawmidi *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 - struct <structname>snd_mpu401</structname> manually - afterward. However, <structname>snd_mpu401</structname> pointer is not - returned explicitly by - <function>snd_mpu401_uart_new()</function>. You need to cast - rmidi->private_data to - <structname>snd_mpu401</structname> explicitly, - - <informalexample> - <programlisting> -<![CDATA[ - struct snd_mpu401 *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[ - struct snd_rawmidi *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 struct snd_rawmidi_ops 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; - struct snd_rawmidi_substream *substream; - list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { - substream = list_entry(list, struct snd_rawmidi_substream, 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 struct snd_rawmidi_substream data passed to each - callback: - <informalexample> - <programlisting> -<![CDATA[ - struct snd_rawmidi_substream *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(struct snd_rawmidi_substream *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(struct snd_rawmidi_substream *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(struct snd_rawmidi_substream *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 (snd_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 (snd_mychip_transmit_possible()) { - unsigned char data; - if (snd_rawmidi_transmit(substream, &data, 1) != 1) - break; /* no more data */ - snd_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(struct snd_rawmidi_substream *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(struct snd_rawmidi_substream *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 struct snd_rawmidi_ops - 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[ - struct snd_opl3 *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[ - struct snd_opl3 *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[ - struct snd_hwdep *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[ - struct snd_hwdep *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[ - struct mydata *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(struct snd_hwdep *hw) - { - struct mydata *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(struct snd_pcm_substream *substream, int channel, - snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count); - static int capture_copy(struct snd_pcm_substream *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(struct snd_pcm_substream *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[ - struct snd_sg_buf *sgbuf = (struct snd_sg_buf_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(struct snd_pcm_substream *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[ - struct snd_info_entry *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(struct snd_info_entry *entry, - struct snd_info_buffer *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(struct snd_info_entry *entry, - struct snd_info_buffer *buffer) - { - struct my_chip *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(struct snd_info_entry *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> - If the driver supports the suspend/resume - <emphasis>fully</emphasis>, that is, the device can be - properly resumed to the status at the suspend is called, - you can set <constant>SNDRV_PCM_INFO_RESUME</constant> flag - to pcm info field. Usually, this is possible when the - registers of ths chip can be safely saved and restored to the - RAM. If this is set, the trigger callback is called with - <constant>SNDRV_PCM_TRIGGER_RESUME</constant> after resume - callback is finished. - </para> - - <para> - Even if the driver doesn't support PM fully but only the - partial suspend/resume is possible, it's still worthy to - implement suspend/resume callbacks. In such a case, applications - would reset the status by calling - <function>snd_pcm_prepare()</function> and restart the stream - appropriately. Hence, you can define suspend/resume callbacks - below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant> - info flag to the PCM. - </para> - - <para> - Note that the trigger with SUSPEND can be always called when - <function>snd_pcm_suspend_all</function> is called, - regardless of <constant>SNDRV_PCM_INFO_RESUME</constant> flag. - The <constant>RESUME</constant> flag affects only the behavior - of <function>snd_pcm_resume()</function>. - (Thus, in theory, - <constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed - to be handled in the trigger callback when no - <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set. But, - it's better to keep it for compatibility reason.) - </para> - <para> - In the earlier version of ALSA drivers, a common - power-management layer was provided, but it has been removed. - The driver needs to define the suspend/resume hooks according to - the bus the device is assigned. In the case of PCI driver, the - callbacks look like below: - - <informalexample> - <programlisting> -<![CDATA[ - #ifdef CONFIG_PM - static int snd_my_suspend(struct pci_dev *pci, pm_message_t state) - { - .... /* do things for suspsend */ - return 0; - } - static int snd_my_resume(struct pci_dev *pci) - { - .... /* 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 card and the chip data.</para></listitem> - <listitem><para>Call <function>snd_power_change_state()</function> with - <constant>SNDRV_CTL_POWER_D3hot</constant> to change the - power status.</para></listitem> - <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem> - <listitem><para>If AC97 codecs are used, call - <function>snd_ac97_resume()</function> for each codec.</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>. Then, call - <function>pci_save_state()</function> at last.</para></listitem> - </orderedlist> - </para> - - <para> - A typical code would be like: - - <informalexample> - <programlisting> -<![CDATA[ - static int mychip_suspend(struct pci_dev *pci, pm_message_t state) - { - /* (1) */ - struct snd_card *card = pci_get_drvdata(pci); - struct mychip *chip = card->private_data; - /* (2) */ - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - /* (3) */ - snd_pcm_suspend_all(chip->pcm); - /* (4) */ - snd_ac97_suspend(chip->ac97); - /* (5) */ - snd_mychip_save_registers(chip); - /* (6) */ - snd_mychip_stop_hardware(chip); - /* (7) */ - pci_disable_device(pci); - pci_save_state(pci); - return 0; - } -]]> - </programlisting> - </informalexample> - </para> - - <para> - The scheme of the real resume job is as following. - - <orderedlist> - <listitem><para>Retrieve the card and the chip data.</para></listitem> - <listitem><para>Set up PCI. First, call <function>pci_restore_state()</function>. - Then enable the pci device again by calling <function>pci_enable_device()</function>. - Call <function>pci_set_master()</function> if necessary, too.</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> - <listitem><para>Call <function>snd_power_change_state()</function> with - <constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem> - </orderedlist> - </para> - - <para> - A typical code would be like: - - <informalexample> - <programlisting> -<![CDATA[ - static int mychip_resume(struct pci_dev *pci) - { - /* (1) */ - struct snd_card *card = pci_get_drvdata(pci); - struct mychip *chip = card->private_data; - /* (2) */ - pci_restore_state(pci); - pci_enable_device(pci); - pci_set_master(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); - /* (7) */ - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; - } -]]> - </programlisting> - </informalexample> - </para> - - <para> - As shown in the above, it's better to save registers after - suspending the PCM operations via - <function>snd_pcm_suspend_all()</function> or - <function>snd_pcm_suspend()</function>. It means that the PCM - streams are already stoppped when the register snapshot is - taken. But, remind that you don't have to restart the PCM - stream in the resume callback. It'll be restarted via - trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant> - when necessary. - </para> - - <para> - OK, we have all callbacks now. Let's set them up. In the - initialization of the card, make sure that you can get the chip - data from the card instance, typically via - <structfield>private_data</structfield> field, in case you - created the chip data individually. - - <informalexample> - <programlisting> -<![CDATA[ - static int __devinit snd_mychip_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) - { - .... - struct snd_card *card; - struct mychip *chip; - .... - card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL); - .... - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - .... - card->private_data = chip; - .... - } -]]> - </programlisting> - </informalexample> - - When you created the chip data with - <function>snd_card_new()</function>, it's anyway accessible - via <structfield>private_data</structfield> field. - - <informalexample> - <programlisting> -<![CDATA[ - static int __devinit snd_mychip_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) - { - .... - struct snd_card *card; - struct mychip *chip; - .... - card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof(struct mychip)); - .... - chip = card->private_data; - .... - } -]]> - </programlisting> - </informalexample> - - </para> - - <para> - If you need a space for saving the registers, 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. - - <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), - #ifdef CONFIG_PM - .suspend = snd_my_suspend, - .resume = snd_my_resume, - #endif - }; -]]> - </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)</computeroutput> - together with stack trace. - </para> - <para> - When no debug flag is set, this macro is ignored. - </para> - </section> - - <section id="useful-functions-snd-bug"> - <title><function>snd_BUG()</function></title> - <para> - It shows <computeroutput>BUG?</computeroutput> message and - stack trace as well as <function>snd_assert</function> at the point. - It's useful to show that a fatal error happens there. - </para> - <para> - When no debug flag is set, this macro is ignored. - </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/HD-Audio-Controls.txt b/Documentation/sound/alsa/HD-Audio-Controls.txt new file mode 100644 index 00000000000..e9621e349e1 --- /dev/null +++ b/Documentation/sound/alsa/HD-Audio-Controls.txt @@ -0,0 +1,116 @@ +This file explains the codec-specific mixer controls. + +Realtek codecs +-------------- + +* Channel Mode + This is an enum control to change the surround-channel setup, + appears only when the surround channels are available. + It gives the number of channels to be used, "2ch", "4ch", "6ch", + and "8ch". According to the configuration, this also controls the + jack-retasking of multi-I/O jacks. + +* Auto-Mute Mode + This is an enum control to change the auto-mute behavior of the + headphone and line-out jacks. If built-in speakers and headphone + and/or line-out jacks are available on a machine, this controls + appears. + When there are only either headphones or line-out jacks, it gives + "Disabled" and "Enabled" state. When enabled, the speaker is muted + automatically when a jack is plugged. + + When both headphone and line-out jacks are present, it gives + "Disabled", "Speaker Only" and "Line-Out+Speaker". When + speaker-only is chosen, plugging into a headphone or a line-out jack + mutes the speakers, but not line-outs. When line-out+speaker is + selected, plugging to a headphone jack mutes both speakers and + line-outs. + + +IDT/Sigmatel codecs +------------------- + +* Analog Loopback + This control enables/disables the analog-loopback circuit. This + appears only when "loopback" is set to true in a codec hint + (see HD-Audio.txt). Note that on some codecs the analog-loopback + and the normal PCM playback are exclusive, i.e. when this is on, you + won't hear any PCM stream. + +* Swap Center/LFE + Swaps the center and LFE channel order. Normally, the left + corresponds to the center and the right to the LFE. When this is + ON, the left to the LFE and the right to the center. + +* Headphone as Line Out + When this control is ON, treat the headphone jacks as line-out + jacks. That is, the headphone won't auto-mute the other line-outs, + and no HP-amp is set to the pins. + +* Mic Jack Mode, Line Jack Mode, etc + These enum controls the direction and the bias of the input jack + pins. Depending on the jack type, it can set as "Mic In" and "Line + In", for determining the input bias, or it can be set to "Line Out" + when the pin is a multi-I/O jack for surround channels. + + +VIA codecs +---------- + +* Smart 5.1 + An enum control to re-task the multi-I/O jacks for surround outputs. + When it's ON, the corresponding input jacks (usually a line-in and a + mic-in) are switched as the surround and the CLFE output jacks. + +* Independent HP + When this enum control is enabled, the headphone output is routed + from an individual stream (the third PCM such as hw:0,2) instead of + the primary stream. In the case the headphone DAC is shared with a + side or a CLFE-channel DAC, the DAC is switched to the headphone + automatically. + +* Loopback Mixing + An enum control to determine whether the analog-loopback route is + enabled or not. When it's enabled, the analog-loopback is mixed to + the front-channel. Also, the same route is used for the headphone + and speaker outputs. As a side-effect, when this mode is set, the + individual volume controls will be no longer available for + headphones and speakers because there is only one DAC connected to a + mixer widget. + +* Dynamic Power-Control + This control determines whether the dynamic power-control per jack + detection is enabled or not. When enabled, the widgets power state + (D0/D3) are changed dynamically depending on the jack plugging + state for saving power consumptions. However, if your system + doesn't provide a proper jack-detection, this won't work; in such a + case, turn this control OFF. + +* Jack Detect + This control is provided only for VT1708 codec which gives no proper + unsolicited event per jack plug. When this is on, the driver polls + the jack detection so that the headphone auto-mute can work, while + turning this off would reduce the power consumption. + + +Conexant codecs +--------------- + +* Auto-Mute Mode + See Reatek codecs. + + +Analog codecs +-------------- + +* Channel Mode + This is an enum control to change the surround-channel setup, + appears only when the surround channels are available. + It gives the number of channels to be used, "2ch", "4ch" and "6ch". + According to the configuration, this also controls the + jack-retasking of multi-I/O jacks. + +* Independent HP + When this enum control is enabled, the headphone output is routed + from an individual stream (the third PCM such as hw:0,2) instead of + the primary stream. diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt new file mode 100644 index 00000000000..d1ab5e17eb1 --- /dev/null +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -0,0 +1,313 @@ + 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 + 6stack 6-jack in back, 2-jack in front + 6stack-digout 6-jack with a SPDIF out + +ALC260 +====== + N/A + +ALC262 +====== + inv-dmic Inverted internal mic workaround + +ALC267/268 +========== + inv-dmic Inverted internal mic workaround + +ALC269/270/275/276/28x/29x +====== + laptop-amic Laptops with analog-mic input + laptop-dmic Laptops with digital-mic input + alc269-dmic Enable ALC269(VA) digital mic workaround + alc271-dmic Enable ALC271X digital mic workaround + inv-dmic Inverted internal mic workaround + headset-mic Indicates a combined headset (headphone+mic) jack + lenovo-dock Enables docking station I/O for some Lenovos + dell-headset-multi Headset jack, which can also be used as mic-in + dell-headset-dock Headset jack (without mic-in), and also dock I/O + +ALC66x/67x/892 +============== + mario Chromebook mario model fixup + asus-mode1 ASUS + asus-mode2 ASUS + asus-mode3 ASUS + asus-mode4 ASUS + asus-mode5 ASUS + asus-mode6 ASUS + asus-mode7 ASUS + asus-mode8 ASUS + inv-dmic Inverted internal mic workaround + dell-headset-multi Headset jack, which can also be used as mic-in + +ALC680 +====== + N/A + +ALC88x/898/1150 +====================== + acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G + acer-aspire-8930g Acer Aspire 8330G/6935G + acer-aspire Acer Aspire others + inv-dmic Inverted internal mic workaround + no-primary-hp VAIO Z/VGC-LN51JGB workaround (for fixed speaker DAC) + +ALC861/660 +========== + N/A + +ALC861VD/660VD +============== + N/A + +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 + auto auto-config reading BIOS (default) + +AD1882 / AD1882A +================ + 3stack 3-stack mode + 3stack-automute 3-stack with automute front HP (default) + 6stack 6-stack mode + +AD1884A / AD1883 / AD1984A / AD1984B +==================================== + desktop 3-stack desktop (default) + laptop laptop with HP jack sensing + mobile mobile devices with HP jack sensing + thinkpad Lenovo Thinkpad X300 + touchsmart HP Touchsmart + +AD1884 +====== + N/A + +AD1981 +====== + basic 3-jack (default) + hp HP nx6320 + thinkpad Lenovo Thinkpad T60/X60/Z60 + toshiba Toshiba U205 + +AD1983 +====== + N/A + +AD1984 +====== + basic default configuration + thinkpad Lenovo Thinkpad T61/X61 + dell_desktop Dell T3400 + +AD1986A +======= + 6stack 6-jack, separate surrounds (default) + 3stack 3-stack, shared surrounds + laptop 2-channel only (FSC V2060, Samsung M50) + laptop-eapd 2-channel with EAPD (ASUS A6J) + laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) + ultra 2-channel with EAPD (Samsung Ultra tablet PC) + samsung 2-channel with EAPD (Samsung R65) + samsung-p50 2-channel with HP-automute (Samsung P50) + +AD1988/AD1988B/AD1989A/AD1989B +============================== + 6stack 6-jack + 6stack-dig ditto with SPDIF + 3stack 3-jack + 3stack-dig ditto with SPDIF + laptop 3-jack with hp-jack automute + laptop-dig ditto with SPDIF + auto auto-config reading BIOS (default) + +Conexant 5045 +============= + laptop-hpsense Laptop with HP sense (old model laptop) + laptop-micsense Laptop with Mic sense (old model fujitsu) + laptop-hpmicsense Laptop with HP and Mic senses + benq Benq R55E + laptop-hp530 HP 530 laptop + test for testing/debugging purpose, almost all controls + can be adjusted. Appearing only when compiled with + $CONFIG_SND_DEBUG=y + +Conexant 5047 +============= + laptop Basic Laptop config + laptop-hp Laptop config for some HP models (subdevice 30A5) + laptop-eapd Laptop config with EAPD support + test for testing/debugging purpose, almost all controls + can be adjusted. Appearing only when compiled with + $CONFIG_SND_DEBUG=y + +Conexant 5051 +============= + laptop Basic Laptop config (default) + hp HP Spartan laptop + hp-dv6736 HP dv6736 + hp-f700 HP Compaq Presario F700 + ideapad Lenovo IdeaPad laptop + toshiba Toshiba Satellite M300 + +Conexant 5066 +============= + laptop Basic Laptop config (default) + hp-laptop HP laptops, e g G60 + asus Asus K52JU, Lenovo G560 + dell-laptop Dell laptops + dell-vostro Dell Vostro + olpc-xo-1_5 OLPC XO 1.5 + ideapad Lenovo IdeaPad U150 + thinkpad Lenovo Thinkpad + +STAC9200 +======== + ref Reference board + oqo OQO Model 2 + dell-d21 Dell (unknown) + dell-d22 Dell (unknown) + dell-d23 Dell (unknown) + dell-m21 Dell Inspiron 630m, Dell Inspiron 640m + dell-m22 Dell Latitude D620, Dell Latitude D820 + dell-m23 Dell XPS M1710, Dell Precision M90 + dell-m24 Dell Latitude 120L + dell-m25 Dell Inspiron E1505n + dell-m26 Dell Inspiron 1501 + dell-m27 Dell Inspiron E1705/9400 + gateway-m4 Gateway laptops with EAPD control + gateway-m4-2 Gateway laptops with EAPD control + panasonic Panasonic CF-74 + auto BIOS setup (default) + +STAC9205/9254 +============= + ref Reference board + dell-m42 Dell (unknown) + dell-m43 Dell Precision + dell-m44 Dell Inspiron + eapd Keep EAPD on (e.g. Gateway T1616) + auto BIOS setup (default) + +STAC9220/9221 +============= + ref Reference board + 3stack D945 3stack + 5stack D945 5stack + SPDIF + intel-mac-v1 Intel Mac Type 1 + intel-mac-v2 Intel Mac Type 2 + intel-mac-v3 Intel Mac Type 3 + intel-mac-v4 Intel Mac Type 4 + intel-mac-v5 Intel Mac Type 5 + intel-mac-auto Intel Mac (detect type according to subsystem id) + macmini Intel Mac Mini (equivalent with type 3) + macbook Intel Mac Book (eq. type 5) + macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) + macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3) + imac-intel Intel iMac (eq. type 2) + imac-intel-20 Intel iMac (newer version) (eq. type 3) + ecs202 ECS/PC chips + dell-d81 Dell (unknown) + dell-d82 Dell (unknown) + dell-m81 Dell (unknown) + dell-m82 Dell XPS M1210 + auto BIOS setup (default) + +STAC9202/9250/9251 +================== + ref Reference board, base config + m1 Some Gateway MX series laptops (NX560XL) + m1-2 Some Gateway MX series laptops (MX6453) + m2 Some Gateway MX series laptops (M255) + m2-2 Some Gateway MX series laptops + m3 Some Gateway MX series laptops + m5 Some Gateway MX series laptops (MP6954) + m6 Some Gateway NX series laptops + auto BIOS setup (default) + +STAC9227/9228/9229/927x +======================= + ref Reference board + ref-no-jd Reference board without HP/Mic jack detection + 3stack D965 3stack + 5stack D965 5stack + SPDIF + 5stack-no-fp D965 5stack without front panel + dell-3stack Dell Dimension E520 + dell-bios Fixes with Dell BIOS setup + dell-bios-amic Fixes with Dell BIOS setup including analog mic + volknob Fixes with volume-knob widget 0x24 + auto BIOS setup (default) + +STAC92HD71B* +============ + ref Reference board + dell-m4-1 Dell desktops + dell-m4-2 Dell desktops + dell-m4-3 Dell desktops + hp-m4 HP mini 1000 + hp-dv5 HP dv series + hp-hdx HP HDX series + hp-dv4-1222nr HP dv4-1222nr (with LED support) + auto BIOS setup (default) + +STAC92HD73* +=========== + ref Reference board + no-jd BIOS setup but without jack-detection + intel Intel DG45* mobos + dell-m6-amic Dell desktops/laptops with analog mics + dell-m6-dmic Dell desktops/laptops with digital mics + dell-m6 Dell desktops/laptops with both type of mics + dell-eq Dell desktops/laptops + alienware Alienware M17x + auto BIOS setup (default) + +STAC92HD83* +=========== + ref Reference board + mic-ref Reference board with power management for ports + dell-s14 Dell laptop + dell-vostro-3500 Dell Vostro 3500 laptop + hp-dv7-4000 HP dv-7 4000 + hp_cNB11_intquad HP CNB models with 4 speakers + hp-zephyr HP Zephyr + hp-led HP with broken BIOS for mute LED + hp-inv-led HP with broken BIOS for inverted mute LED + auto BIOS setup (default) + +STAC92HD95 +========== + hp-led LED support for HP laptops + hp-bass Bass HPF setup for HP Spectre 13 + +STAC9872 +======== + vaio VAIO laptop without SPDIF + auto BIOS setup (default) + +Cirrus Logic CS4206/4207 +======================== + mbp55 MacBook Pro 5,5 + imac27 IMac 27 Inch + auto BIOS setup (default) + +Cirrus Logic CS4208 +=================== + mba6 MacBook Air 6,1 and 6,2 + gpio0 Enable GPIO 0 amp + auto BIOS setup (default) + +VIA VT17xx/VT18xx/VT20xx +======================== + auto BIOS setup (default) diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt new file mode 100644 index 00000000000..42a0a39b77e --- /dev/null +++ b/Documentation/sound/alsa/HD-Audio.txt @@ -0,0 +1,859 @@ +MORE NOTES ON HD-AUDIO DRIVER +============================= + Takashi Iwai <tiwai@suse.de> + + +GENERAL +------- + +HD-audio is the new standard on-board audio component on modern PCs +after AC97. Although Linux has been supporting HD-audio since long +time ago, there are often problems with new machines. A part of the +problem is broken BIOS, and the rest is the driver implementation. +This document explains the brief trouble-shooting and debugging +methods for the HD-audio hardware. + +The HD-audio component consists of two parts: the controller chip and +the codec chips on the HD-audio bus. Linux provides a single driver +for all controllers, snd-hda-intel. Although the driver name contains +a word of a well-known hardware vendor, it's not specific to it but for +all controller chips by other companies. Since the HD-audio +controllers are supposed to be compatible, the single snd-hda-driver +should work in most cases. But, not surprisingly, there are known +bugs and issues specific to each controller type. The snd-hda-intel +driver has a bunch of workarounds for these as described below. + +A controller may have multiple codecs. Usually you have one audio +codec and optionally one modem codec. In theory, there might be +multiple audio codecs, e.g. for analog and digital outputs, and the +driver might not work properly because of conflict of mixer elements. +This should be fixed in future if such hardware really exists. + +The snd-hda-intel driver has several different codec parsers depending +on the codec. It has a generic parser as a fallback, but this +functionality is fairly limited until now. Instead of the generic +parser, usually the codec-specific parser (coded in patch_*.c) is used +for the codec-specific implementations. The details about the +codec-specific problems are explained in the later sections. + +If you are interested in the deep debugging of HD-audio, read the +HD-audio specification at first. The specification is found on +Intel's web page, for example: + +- http://www.intel.com/standards/hdaudio/ + + +HD-AUDIO CONTROLLER +------------------- + +DMA-Position Problem +~~~~~~~~~~~~~~~~~~~~ +The most common problem of the controller is the inaccurate DMA +pointer reporting. The DMA pointer for playback and capture can be +read in two ways, either via a LPIB register or via a position-buffer +map. As default the driver tries to read from the io-mapped +position-buffer, and falls back to LPIB if the position-buffer appears +dead. However, this detection isn't perfect on some devices. In such +a case, you can change the default method via `position_fix` option. + +`position_fix=1` means to use LPIB method explicitly. +`position_fix=2` means to use the position-buffer. +`position_fix=3` means to use a combination of both methods, needed +for some VIA controllers. The capture stream position is corrected +by comparing both LPIB and position-buffer values. +`position_fix=4` is another combination available for all controllers, +and uses LPIB for the playback and the position-buffer for the capture +streams. +0 is the default value for all other +controllers, the automatic check and fallback to LPIB as described in +the above. If you get a problem of repeated sounds, this option might +help. + +In addition to that, every controller is known to be broken regarding +the wake-up timing. It wakes up a few samples before actually +processing the data on the buffer. This caused a lot of problems, for +example, with ALSA dmix or JACK. Since 2.6.27 kernel, the driver puts +an artificial delay to the wake up timing. This delay is controlled +via `bdl_pos_adj` option. + +When `bdl_pos_adj` is a negative value (as default), it's assigned to +an appropriate value depending on the controller chip. For Intel +chips, it'd be 1 while it'd be 32 for others. Usually this works. +Only in case it doesn't work and you get warning messages, you should +change this parameter to other values. + + +Codec-Probing Problem +~~~~~~~~~~~~~~~~~~~~~ +A less often but a more severe problem is the codec probing. When +BIOS reports the available codec slots wrongly, the driver gets +confused and tries to access the non-existing codec slot. This often +results in the total screw-up, and destructs the further communication +with the codec chips. The symptom appears usually as error messages +like: +------------------------------------------------------------------------ + hda_intel: azx_get_response timeout, switching to polling mode: + last cmd=0x12345678 + hda_intel: azx_get_response timeout, switching to single_cmd mode: + last cmd=0x12345678 +------------------------------------------------------------------------ + +The first line is a warning, and this is usually relatively harmless. +It means that the codec response isn't notified via an IRQ. The +driver uses explicit polling method to read the response. It gives +very slight CPU overhead, but you'd unlikely notice it. + +The second line is, however, a fatal error. If this happens, usually +it means that something is really wrong. Most likely you are +accessing a non-existing codec slot. + +Thus, if the second error message appears, try to narrow the probed +codec slots via `probe_mask` option. It's a bitmask, and each bit +corresponds to the codec slot. For example, to probe only the first +slot, pass `probe_mask=1`. For the first and the third slots, pass +`probe_mask=5` (where 5 = 1 | 4), and so on. + +Since 2.6.29 kernel, the driver has a more robust probing method, so +this error might happen rarely, though. + +On a machine with a broken BIOS, sometimes you need to force the +driver to probe the codec slots the hardware doesn't report for use. +In such a case, turn the bit 8 (0x100) of `probe_mask` option on. +Then the rest 8 bits are passed as the codec slots to probe +unconditionally. For example, `probe_mask=0x103` will force to probe +the codec slots 0 and 1 no matter what the hardware reports. + + +Interrupt Handling +~~~~~~~~~~~~~~~~~~ +HD-audio driver uses MSI as default (if available) since 2.6.33 +kernel as MSI works better on some machines, and in general, it's +better for performance. However, Nvidia controllers showed bad +regressions with MSI (especially in a combination with AMD chipset), +thus we disabled MSI for them. + +There seem also still other devices that don't work with MSI. If you +see a regression wrt the sound quality (stuttering, etc) or a lock-up +in the recent kernel, try to pass `enable_msi=0` option to disable +MSI. If it works, you can add the known bad device to the blacklist +defined in hda_intel.c. In such a case, please report and give the +patch back to the upstream developer. + + +HD-AUDIO CODEC +-------------- + +Model Option +~~~~~~~~~~~~ +The most common problem regarding the HD-audio driver is the +unsupported codec features or the mismatched device configuration. +Most of codec-specific code has several preset models, either to +override the BIOS setup or to provide more comprehensive features. + +The driver checks PCI SSID and looks through the static configuration +table until any matching entry is found. If you have a new machine, +you may see a message like below: +------------------------------------------------------------------------ + hda_codec: ALC880: BIOS auto-probing. +------------------------------------------------------------------------ +Meanwhile, in the earlier versions, you would see a message like: +------------------------------------------------------------------------ + hda_codec: Unknown model for ALC880, trying auto-probe from BIOS... +------------------------------------------------------------------------ +Even if you see such a message, DON'T PANIC. Take a deep breath and +keep your towel. First of all, it's an informational message, no +warning, no error. This means that the PCI SSID of your device isn't +listed in the known preset model (white-)list. But, this doesn't mean +that the driver is broken. Many codec-drivers provide the automatic +configuration mechanism based on the BIOS setup. + +The HD-audio codec has usually "pin" widgets, and BIOS sets the default +configuration of each pin, which indicates the location, the +connection type, the jack color, etc. The HD-audio driver can guess +the right connection judging from these default configuration values. +However -- some codec-support codes, such as patch_analog.c, don't +support the automatic probing (yet as of 2.6.28). And, BIOS is often, +yes, pretty often broken. It sets up wrong values and screws up the +driver. + +The preset model (or recently called as "fix-up") is provided +basically to overcome such a situation. When the matching preset +model is found in the white-list, the driver assumes the static +configuration of that preset with the correct pin setup, etc. +Thus, if you have a newer machine with a slightly different PCI SSID +(or codec SSID) from the existing one, you may have a good chance to +re-use the same model. You can pass the `model` option to specify the +preset model instead of PCI (and codec-) SSID look-up. + +What `model` option values are available depends on the codec chip. +Check your codec chip from the codec proc file (see "Codec Proc-File" +section below). It will show the vendor/product name of your codec +chip. Then, see Documentation/sound/alsa/HD-Audio-Models.txt file, +the section of HD-audio driver. You can find a list of codecs +and `model` options belonging to each codec. For example, for Realtek +ALC262 codec chip, pass `model=ultra` for devices that are compatible +with Samsung Q1 Ultra. + +Thus, the first thing you can do for any brand-new, unsupported and +non-working HD-audio hardware is to check HD-audio codec and several +different `model` option values. If you have any luck, some of them +might suit with your device well. + +There are a few special model option values: +- when 'nofixup' is passed, the device-specific fixups in the codec + parser are skipped. +- when `generic` is passed, the codec-specific parser is skipped and + only the generic parser is used. + + +Speaker and Headphone Output +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +One of the most frequent (and obvious) bugs with HD-audio is the +silent output from either or both of a built-in speaker and a +headphone jack. In general, you should try a headphone output at +first. A speaker output often requires more additional controls like +the external amplifier bits. Thus a headphone output has a slightly +better chance. + +Before making a bug report, double-check whether the mixer is set up +correctly. The recent version of snd-hda-intel driver provides mostly +"Master" volume control as well as "Front" volume (where Front +indicates the front-channels). In addition, there can be individual +"Headphone" and "Speaker" controls. + +Ditto for the speaker output. There can be "External Amplifier" +switch on some codecs. Turn on this if present. + +Another related problem is the automatic mute of speaker output by +headphone plugging. This feature is implemented in most cases, but +not on every preset model or codec-support code. + +In anyway, try a different model option if you have such a problem. +Some other models may match better and give you more matching +functionality. If none of the available models works, send a bug +report. See the bug report section for details. + +If you are masochistic enough to debug the driver problem, note the +following: + +- The speaker (and the headphone, too) output often requires the + external amplifier. This can be set usually via EAPD verb or a + certain GPIO. If the codec pin supports EAPD, you have a better + chance via SET_EAPD_BTL verb (0x70c). On others, GPIO pin (mostly + it's either GPIO0 or GPIO1) may turn on/off EAPD. +- Some Realtek codecs require special vendor-specific coefficients to + turn on the amplifier. See patch_realtek.c. +- IDT codecs may have extra power-enable/disable controls on each + analog pin. See patch_sigmatel.c. +- Very rare but some devices don't accept the pin-detection verb until + triggered. Issuing GET_PIN_SENSE verb (0xf09) may result in the + codec-communication stall. Some examples are found in + patch_realtek.c. + + +Capture Problems +~~~~~~~~~~~~~~~~ +The capture problems are often because of missing setups of mixers. +Thus, before submitting a bug report, make sure that you set up the +mixer correctly. For example, both "Capture Volume" and "Capture +Switch" have to be set properly in addition to the right "Capture +Source" or "Input Source" selection. Some devices have "Mic Boost" +volume or switch. + +When the PCM device is opened via "default" PCM (without pulse-audio +plugin), you'll likely have "Digital Capture Volume" control as well. +This is provided for the extra gain/attenuation of the signal in +software, especially for the inputs without the hardware volume +control such as digital microphones. Unless really needed, this +should be set to exactly 50%, corresponding to 0dB -- neither extra +gain nor attenuation. When you use "hw" PCM, i.e., a raw access PCM, +this control will have no influence, though. + +It's known that some codecs / devices have fairly bad analog circuits, +and the recorded sound contains a certain DC-offset. This is no bug +of the driver. + +Most of modern laptops have no analog CD-input connection. Thus, the +recording from CD input won't work in many cases although the driver +provides it as the capture source. Use CDDA instead. + +The automatic switching of the built-in and external mic per plugging +is implemented on some codec models but not on every model. Partly +because of my laziness but mostly lack of testers. Feel free to +submit the improvement patch to the author. + + +Direct Debugging +~~~~~~~~~~~~~~~~ +If no model option gives you a better result, and you are a tough guy +to fight against evil, try debugging via hitting the raw HD-audio +codec verbs to the device. Some tools are available: hda-emu and +hda-analyzer. The detailed description is found in the sections +below. You'd need to enable hwdep for using these tools. See "Kernel +Configuration" section. + + +OTHER ISSUES +------------ + +Kernel Configuration +~~~~~~~~~~~~~~~~~~~~ +In general, I recommend you to enable the sound debug option, +`CONFIG_SND_DEBUG=y`, no matter whether you are debugging or not. +This enables snd_printd() macro and others, and you'll get additional +kernel messages at probing. + +In addition, you can enable `CONFIG_SND_DEBUG_VERBOSE=y`. But this +will give you far more messages. Thus turn this on only when you are +sure to want it. + +Don't forget to turn on the appropriate `CONFIG_SND_HDA_CODEC_*` +options. Note that each of them corresponds to the codec chip, not +the controller chip. Thus, even if lspci shows the Nvidia controller, +you may need to choose the option for other vendors. If you are +unsure, just select all yes. + +`CONFIG_SND_HDA_HWDEP` is a useful option for debugging the driver. +When this is enabled, the driver creates hardware-dependent devices +(one per each codec), and you have a raw access to the device via +these device files. For example, `hwC0D2` will be created for the +codec slot #2 of the first card (#0). For debug-tools such as +hda-verb and hda-analyzer, the hwdep device has to be enabled. +Thus, it'd be better to turn this on always. + +`CONFIG_SND_HDA_RECONFIG` is a new option, and this depends on the +hwdep option above. When enabled, you'll have some sysfs files under +the corresponding hwdep directory. See "HD-audio reconfiguration" +section below. + +`CONFIG_SND_HDA_POWER_SAVE` option enables the power-saving feature. +See "Power-saving" section below. + + +Codec Proc-File +~~~~~~~~~~~~~~~ +The codec proc-file is a treasure-chest for debugging HD-audio. +It shows most of useful information of each codec widget. + +The proc file is located in /proc/asound/card*/codec#*, one file per +each codec slot. You can know the codec vendor, product id and +names, the type of each widget, capabilities and so on. +This file, however, doesn't show the jack sensing state, so far. This +is because the jack-sensing might be depending on the trigger state. + +This file will be picked up by the debug tools, and also it can be fed +to the emulator as the primary codec information. See the debug tools +section below. + +This proc file can be also used to check whether the generic parser is +used. When the generic parser is used, the vendor/product ID name +will appear as "Realtek ID 0262", instead of "Realtek ALC262". + + +HD-Audio Reconfiguration +~~~~~~~~~~~~~~~~~~~~~~~~ +This is an experimental feature to allow you re-configure the HD-audio +codec dynamically without reloading the driver. The following sysfs +files are available under each codec-hwdep device directory (e.g. +/sys/class/sound/hwC0D0): + +vendor_id:: + Shows the 32bit codec vendor-id hex number. You can change the + vendor-id value by writing to this file. +subsystem_id:: + Shows the 32bit codec subsystem-id hex number. You can change the + subsystem-id value by writing to this file. +revision_id:: + Shows the 32bit codec revision-id hex number. You can change the + revision-id value by writing to this file. +afg:: + Shows the AFG ID. This is read-only. +mfg:: + Shows the MFG ID. This is read-only. +name:: + Shows the codec name string. Can be changed by writing to this + file. +modelname:: + Shows the currently set `model` option. Can be changed by writing + to this file. +init_verbs:: + The extra verbs to execute at initialization. You can add a verb by + writing to this file. Pass three numbers: nid, verb and parameter + (separated with a space). +hints:: + Shows / stores hint strings for codec parsers for any use. + Its format is `key = value`. For example, passing `jack_detect = no` + will disable the jack detection of the machine completely. +init_pin_configs:: + Shows the initial pin default config values set by BIOS. +driver_pin_configs:: + Shows the pin default values set by the codec parser explicitly. + This doesn't show all pin values but only the changed values by + the parser. That is, if the parser doesn't change the pin default + config values by itself, this will contain nothing. +user_pin_configs:: + Shows the pin default config values to override the BIOS setup. + Writing this (with two numbers, NID and value) appends the new + value. The given will be used instead of the initial BIOS value at + the next reconfiguration time. Note that this config will override + even the driver pin configs, too. +reconfig:: + Triggers the codec re-configuration. When any value is written to + this file, the driver re-initialize and parses the codec tree + again. All the changes done by the sysfs entries above are taken + into account. +clear:: + Resets the codec, removes the mixer elements and PCM stuff of the + specified codec, and clear all init verbs and hints. + +For example, when you want to change the pin default configuration +value of the pin widget 0x14 to 0x9993013f, and let the driver +re-configure based on that state, run like below: +------------------------------------------------------------------------ + # echo 0x14 0x9993013f > /sys/class/sound/hwC0D0/user_pin_configs + # echo 1 > /sys/class/sound/hwC0D0/reconfig +------------------------------------------------------------------------ + + +Hint Strings +~~~~~~~~~~~~ +The codec parser have several switches and adjustment knobs for +matching better with the actual codec or device behavior. Many of +them can be adjusted dynamically via "hints" strings as mentioned in +the section above. For example, by passing `jack_detect = no` string +via sysfs or a patch file, you can disable the jack detection, thus +the codec parser will skip the features like auto-mute or mic +auto-switch. As a boolean value, either `yes`, `no`, `true`, `false`, +`1` or `0` can be passed. + +The generic parser supports the following hints: + +- jack_detect (bool): specify whether the jack detection is available + at all on this machine; default true +- inv_jack_detect (bool): indicates that the jack detection logic is + inverted +- trigger_sense (bool): indicates that the jack detection needs the + explicit call of AC_VERB_SET_PIN_SENSE verb +- inv_eapd (bool): indicates that the EAPD is implemented in the + inverted logic +- pcm_format_first (bool): sets the PCM format before the stream tag + and channel ID +- sticky_stream (bool): keep the PCM format, stream tag and ID as long + as possible; default true +- spdif_status_reset (bool): reset the SPDIF status bits at each time + the SPDIF stream is set up +- pin_amp_workaround (bool): the output pin may have multiple amp + values +- single_adc_amp (bool): ADCs can have only single input amps +- auto_mute (bool): enable/disable the headphone auto-mute feature; + default true +- auto_mic (bool): enable/disable the mic auto-switch feature; default + true +- line_in_auto_switch (bool): enable/disable the line-in auto-switch + feature; default false +- need_dac_fix (bool): limits the DACs depending on the channel count +- primary_hp (bool): probe headphone jacks as the primary outputs; + default true +- multi_io (bool): try probing multi-I/O config (e.g. shared + line-in/surround, mic/clfe jacks) +- multi_cap_vol (bool): provide multiple capture volumes +- inv_dmic_split (bool): provide split internal mic volume/switch for + phase-inverted digital mics +- indep_hp (bool): provide the independent headphone PCM stream and + the corresponding mixer control, if available +- add_stereo_mix_input (bool): add the stereo mix (analog-loopback + mix) to the input mux if available +- add_jack_modes (bool): add "xxx Jack Mode" enum controls to each + I/O jack for allowing to change the headphone amp and mic bias VREF + capabilities +- power_down_unused (bool): power down the unused widgets +- add_hp_mic (bool): add the headphone to capture source if possible +- hp_mic_detect (bool): enable/disable the hp/mic shared input for a + single built-in mic case; default true +- mixer_nid (int): specifies the widget NID of the analog-loopback + mixer + + +Early Patching +~~~~~~~~~~~~~~ +When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a +firmware file for modifying the HD-audio setup before initializing the +codec. This can work basically like the reconfiguration via sysfs in +the above, but it does it before the first codec configuration. + +A patch file is a plain text file which looks like below: + +------------------------------------------------------------------------ + [codec] + 0x12345678 0xabcd1234 2 + + [model] + auto + + [pincfg] + 0x12 0x411111f0 + + [verb] + 0x20 0x500 0x03 + 0x20 0x400 0xff + + [hint] + jack_detect = no +------------------------------------------------------------------------ + +The file needs to have a line `[codec]`. The next line should contain +three numbers indicating the codec vendor-id (0x12345678 in the +example), the codec subsystem-id (0xabcd1234) and the address (2) of +the codec. The rest patch entries are applied to this specified codec +until another codec entry is given. Passing 0 or a negative number to +the first or the second value will make the check of the corresponding +field be skipped. It'll be useful for really broken devices that don't +initialize SSID properly. + +The `[model]` line allows to change the model name of the each codec. +In the example above, it will be changed to model=auto. +Note that this overrides the module option. + +After the `[pincfg]` line, the contents are parsed as the initial +default pin-configurations just like `user_pin_configs` sysfs above. +The values can be shown in user_pin_configs sysfs file, too. + +Similarly, the lines after `[verb]` are parsed as `init_verbs` +sysfs entries, and the lines after `[hint]` are parsed as `hints` +sysfs entries, respectively. + +Another example to override the codec vendor id from 0x12345678 to +0xdeadbeef is like below: +------------------------------------------------------------------------ + [codec] + 0x12345678 0xabcd1234 2 + + [vendor_id] + 0xdeadbeef +------------------------------------------------------------------------ + +In the similar way, you can override the codec subsystem_id via +`[subsystem_id]`, the revision id via `[revision_id]` line. +Also, the codec chip name can be rewritten via `[chip_name]` line. +------------------------------------------------------------------------ + [codec] + 0x12345678 0xabcd1234 2 + + [subsystem_id] + 0xffff1111 + + [revision_id] + 0x10 + + [chip_name] + My-own NEWS-0002 +------------------------------------------------------------------------ + +The hd-audio driver reads the file via request_firmware(). Thus, +a patch file has to be located on the appropriate firmware path, +typically, /lib/firmware. For example, when you pass the option +`patch=hda-init.fw`, the file /lib/firmware/hda-init.fw must be +present. + +The patch module option is specific to each card instance, and you +need to give one file name for each instance, separated by commas. +For example, if you have two cards, one for an on-board analog and one +for an HDMI video board, you may pass patch option like below: +------------------------------------------------------------------------ + options snd-hda-intel patch=on-board-patch,hdmi-patch +------------------------------------------------------------------------ + + +Power-Saving +~~~~~~~~~~~~ +The power-saving is a kind of auto-suspend of the device. When the +device is inactive for a certain time, the device is automatically +turned off to save the power. The time to go down is specified via +`power_save` module option, and this option can be changed dynamically +via sysfs. + +The power-saving won't work when the analog loopback is enabled on +some codecs. Make sure that you mute all unneeded signal routes when +you want the power-saving. + +The power-saving feature might cause audible click noises at each +power-down/up depending on the device. Some of them might be +solvable, but some are hard, I'm afraid. Some distros such as +openSUSE enables the power-saving feature automatically when the power +cable is unplugged. Thus, if you hear noises, suspect first the +power-saving. See /sys/module/snd_hda_intel/parameters/power_save to +check the current value. If it's non-zero, the feature is turned on. + +The recent kernel supports the runtime PM for the HD-audio controller +chip, too. It means that the HD-audio controller is also powered up / +down dynamically. The feature is enabled only for certain controller +chips like Intel LynxPoint. You can enable/disable this feature +forcibly by setting `power_save_controller` option, which is also +available at /sys/module/snd_hda_intel/parameters directory. + + +Tracepoints +~~~~~~~~~~~ +The hd-audio driver gives a few basic tracepoints. +`hda:hda_send_cmd` traces each CORB write while `hda:hda_get_response` +traces the response from RIRB (only when read from the codec driver). +`hda:hda_bus_reset` traces the bus-reset due to fatal error, etc, +`hda:hda_unsol_event` traces the unsolicited events, and +`hda:hda_power_down` and `hda:hda_power_up` trace the power down/up +via power-saving behavior. + +Enabling all tracepoints can be done like +------------------------------------------------------------------------ + # echo 1 > /sys/kernel/debug/tracing/events/hda/enable +------------------------------------------------------------------------ +then after some commands, you can traces from +/sys/kernel/debug/tracing/trace file. For example, when you want to +trace what codec command is sent, enable the tracepoint like: +------------------------------------------------------------------------ + # cat /sys/kernel/debug/tracing/trace + # tracer: nop + # + # TASK-PID CPU# TIMESTAMP FUNCTION + # | | | | | + <...>-7807 [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019 + <...>-7807 [002] 105147.774893: hda_send_cmd: [0:0] val=e39019 + <...>-7807 [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a + <...>-7807 [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a + <...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019 + <...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019 + <...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a + <...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a +------------------------------------------------------------------------ +Here `[0:0]` indicates the card number and the codec address, and +`val` shows the value sent to the codec, respectively. The value is +a packed value, and you can decode it via hda-decode-verb program +included in hda-emu package below. For example, the value e3a019 is +to set the left output-amp value to 25. +------------------------------------------------------------------------ + % hda-decode-verb 0xe3a019 + raw value = 0x00e3a019 + cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19 + raw value: verb = 0x3a0, parm = 0x19 + verbname = set_amp_gain_mute + amp raw val = 0xa019 + output, left, idx=0, mute=0, val=25 +------------------------------------------------------------------------ + + +Development Tree +~~~~~~~~~~~~~~~~ +The latest development codes for HD-audio are found on sound git tree: + +- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git + +The master branch or for-next branches can be used as the main +development branches in general while the development for the current +and next kernels are found in for-linus and for-next branches, +respectively. + +If you are using the latest Linus tree, it'd be better to pull the +above GIT tree onto it. If you are using the older kernels, an easy +way to try the latest ALSA code is to build from the snapshot +tarball. There are daily tarballs and the latest snapshot tarball. +All can be built just like normal alsa-driver release packages, that +is, installed via the usual spells: configure, make and make +install(-modules). See INSTALL in the package. The snapshot tarballs +are found at: + +- ftp://ftp.suse.com/pub/people/tiwai/snapshot/ + + +Sending a Bug Report +~~~~~~~~~~~~~~~~~~~~ +If any model or module options don't work for your device, it's time +to send a bug report to the developers. Give the following in your +bug report: + +- Hardware vendor, product and model names +- Kernel version (and ALSA-driver version if you built externally) +- `alsa-info.sh` output; run with `--no-upload` option. See the + section below about alsa-info + +If it's a regression, at best, send alsa-info outputs of both working +and non-working kernels. This is really helpful because we can +compare the codec registers directly. + +Send a bug report either the followings: + +kernel-bugzilla:: + https://bugzilla.kernel.org/ +alsa-devel ML:: + alsa-devel@alsa-project.org + + +DEBUG TOOLS +----------- + +This section describes some tools available for debugging HD-audio +problems. + +alsa-info +~~~~~~~~~ +The script `alsa-info.sh` is a very useful tool to gather the audio +device information. You can fetch the latest version from: + +- http://www.alsa-project.org/alsa-info.sh + +Run this script as root, and it will gather the important information +such as the module lists, module parameters, proc file contents +including the codec proc files, mixer outputs and the control +elements. As default, it will store the information onto a web server +on alsa-project.org. But, if you send a bug report, it'd be better to +run with `--no-upload` option, and attach the generated file. + +There are some other useful options. See `--help` option output for +details. + +When a probe error occurs or when the driver obviously assigns a +mismatched model, it'd be helpful to load the driver with +`probe_only=1` option (at best after the cold reboot) and run +alsa-info at this state. With this option, the driver won't configure +the mixer and PCM but just tries to probe the codec slot. After +probing, the proc file is available, so you can get the raw codec +information before modified by the driver. Of course, the driver +isn't usable with `probe_only=1`. But you can continue the +configuration via hwdep sysfs file if hda-reconfig option is enabled. +Using `probe_only` mask 2 skips the reset of HDA codecs (use +`probe_only=3` as module option). The hwdep interface can be used +to determine the BIOS codec initialization. + + +hda-verb +~~~~~~~~ +hda-verb is a tiny program that allows you to access the HD-audio +codec directly. You can execute a raw HD-audio codec verb with this. +This program accesses the hwdep device, thus you need to enable the +kernel config `CONFIG_SND_HDA_HWDEP=y` beforehand. + +The hda-verb program takes four arguments: the hwdep device file, the +widget NID, the verb and the parameter. When you access to the codec +on the slot 2 of the card 0, pass /dev/snd/hwC0D2 to the first +argument, typically. (However, the real path name depends on the +system.) + +The second parameter is the widget number-id to access. The third +parameter can be either a hex/digit number or a string corresponding +to a verb. Similarly, the last parameter is the value to write, or +can be a string for the parameter type. + +------------------------------------------------------------------------ + % hda-verb /dev/snd/hwC0D0 0x12 0x701 2 + nid = 0x12, verb = 0x701, param = 0x2 + value = 0x0 + + % hda-verb /dev/snd/hwC0D0 0x0 PARAMETERS VENDOR_ID + nid = 0x0, verb = 0xf00, param = 0x0 + value = 0x10ec0262 + + % hda-verb /dev/snd/hwC0D0 2 set_a 0xb080 + nid = 0x2, verb = 0x300, param = 0xb080 + value = 0x0 +------------------------------------------------------------------------ + +Although you can issue any verbs with this program, the driver state +won't be always updated. For example, the volume values are usually +cached in the driver, and thus changing the widget amp value directly +via hda-verb won't change the mixer value. + +The hda-verb program is included now in alsa-tools: + +- git://git.alsa-project.org/alsa-tools.git + +Also, the old stand-alone package is found in the ftp directory: + +- ftp://ftp.suse.com/pub/people/tiwai/misc/ + +Also a git repository is available: + +- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-verb.git + +See README file in the tarball for more details about hda-verb +program. + + +hda-analyzer +~~~~~~~~~~~~ +hda-analyzer provides a graphical interface to access the raw HD-audio +control, based on pyGTK2 binding. It's a more powerful version of +hda-verb. The program gives you an easy-to-use GUI stuff for showing +the widget information and adjusting the amp values, as well as the +proc-compatible output. + +The hda-analyzer: + +- http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer + +is a part of alsa.git repository in alsa-project.org: + +- git://git.alsa-project.org/alsa.git + +Codecgraph +~~~~~~~~~~ +Codecgraph is a utility program to generate a graph and visualizes the +codec-node connection of a codec chip. It's especially useful when +you analyze or debug a codec without a proper datasheet. The program +parses the given codec proc file and converts to SVG via graphiz +program. + +The tarball and GIT trees are found in the web page at: + +- http://helllabs.org/codecgraph/ + + +hda-emu +~~~~~~~ +hda-emu is an HD-audio emulator. The main purpose of this program is +to debug an HD-audio codec without the real hardware. Thus, it +doesn't emulate the behavior with the real audio I/O, but it just +dumps the codec register changes and the ALSA-driver internal changes +at probing and operating the HD-audio driver. + +The program requires a codec proc-file to simulate. Get a proc file +for the target codec beforehand, or pick up an example codec from the +codec proc collections in the tarball. Then, run the program with the +proc file, and the hda-emu program will start parsing the codec file +and simulates the HD-audio driver: + +------------------------------------------------------------------------ + % hda-emu codecs/stac9200-dell-d820-laptop + # Parsing.. + hda_codec: Unknown model for STAC9200, using BIOS defaults + hda_codec: pin nid 08 bios pin config 40c003fa + .... +------------------------------------------------------------------------ + +The program gives you only a very dumb command-line interface. You +can get a proc-file dump at the current state, get a list of control +(mixer) elements, set/get the control element value, simulate the PCM +operation, the jack plugging simulation, etc. + +The package is found in: + +- ftp://ftp.suse.com/pub/people/tiwai/misc/ + +A git repository is available: + +- git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-emu.git + +See README file in the tarball for more details about hda-emu +program. + + +hda-jack-retask +~~~~~~~~~~~~~~~ +hda-jack-retask is a user-friendly GUI program to manipulate the +HD-audio pin control for jack retasking. If you have a problem about +the jack assignment, try this program and check whether you can get +useful results. Once when you figure out the proper pin assignment, +it can be fixed either in the driver code statically or via passing a +firmware patch file (see "Early Patching" section). + +The program is included in alsa-tools now: + +- git://git.alsa-project.org/alsa-tools.git + diff --git a/Documentation/sound/alsa/MIXART.txt b/Documentation/sound/alsa/MIXART.txt index 5cb97061287..4ee35b4fbe4 100644 --- a/Documentation/sound/alsa/MIXART.txt +++ b/Documentation/sound/alsa/MIXART.txt @@ -31,7 +31,7 @@ With a miXart8AES/EBU there is in addition 1 stereo digital input Formats ------- U8, S16_LE, S16_BE, S24_3LE, S24_3BE, FLOAT_LE, FLOAT_BE -Sample rates : 8000 - 48000 Hz continously +Sample rates : 8000 - 48000 Hz continuously Playback -------- @@ -39,7 +39,7 @@ 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. +can be muted for each stream to use 8 analog/digital outputs separately. Capture ------- @@ -76,9 +76,9 @@ FIRMWARE 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: +For loading the firmware automatically after the module is loaded, use a +install command. For example, add the following entry to +/etc/modprobe.d/mixart.conf for miXart driver: install snd-mixart /sbin/modprobe --first-time -i snd-mixart && \ /usr/bin/mixartloader @@ -97,4 +97,4 @@ COPYRIGHT ========= Copyright (c) 2003 Digigram SA <alsa@digigram.com> -Distributalbe under GPL. +Distributable under GPL. diff --git a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt index ec2a02541d5..152ca2a3f1b 100644 --- a/Documentation/sound/alsa/OSS-Emulation.txt +++ b/Documentation/sound/alsa/OSS-Emulation.txt @@ -19,7 +19,7 @@ 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 +card alias in /etc/modprobe.d/alsa.conf, such as alias sound-slot-0 snd-emu10k1 @@ -278,6 +278,21 @@ current mixer configuration by reading and writing the whole file image. +Duplex Streams +============== + +Note that when attempting to use a single device file for playback and +capture, the OSS API provides no way to set the format, sample rate or +number of channels different in each direction. Thus + io_handle = open("device", O_RDWR) +will only function correctly if the values are the same in each direction. + +To use different values in the two directions, use both + input_handle = open("device", O_RDONLY) + output_handle = open("device", O_WRONLY) +and set the values for the corresponding handle. + + Unsupported Features ==================== @@ -288,10 +303,3 @@ ICE1712 supports only the unconventional format, interleaved 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 index 1fe48846d78..7fcd1ad96fc 100644 --- a/Documentation/sound/alsa/Procfile.txt +++ b/Documentation/sound/alsa/Procfile.txt @@ -71,7 +71,7 @@ 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). +subdirectories (described 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 @@ -88,21 +88,47 @@ card*/pcm*/info 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 + This file appears when CONFIG_SND_DEBUG=y and + CONFIG_PCM_XRUN_DEBUG=y. + This shows the status of xrun (= buffer overrun/xrun) and + invalid PCM position debug/check of ALSA PCM middle layer. + It takes an integer value, can be changed by writing to this + file, such as + + # echo 5 > /proc/asound/card0/pcm0p/xrun_debug + + The value consists of the following bit flags: + bit 0 = Enable XRUN/jiffies debug messages + bit 1 = Show stack trace at XRUN / jiffies check + bit 2 = Enable additional jiffies check + bit 3 = Log hwptr update at each period interrupt + bit 4 = Log hwptr update at each snd_pcm_update_hw_ptr() + bit 5 = Show last 10 positions on error + bit 6 = Do above only once + + When the bit 0 is set, 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). - # cat 2 > /proc/asound/card0/pcm0p/xrun_debug + When the bit 1 is set, the driver will show the stack trace + additionally. This may help the debugging. - 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). + Since 2.6.30, this option can enable the hwptr check using + jiffies. This detects spontaneous invalid pointer callback + values, but can be lead to too much corrections for a (mostly + buggy) hardware that doesn't give smooth pointer updates. + This feature is enabled via the bit 2. + + Bits 3 and 4 are for logging the hwptr records. Note that + these will give flood of kernel messages. - When this value is greater than 1, the driver will show the - stack trace additionally. This may help the debugging. + When bit 5 is set, the driver logs the last 10 xrun errors and + the proc file shows each jiffies, position, period_size, + buffer_size, old_hw_ptr, and hw_ptr_base values. + + When bit 6 is set, the full xrun log is shown only once. card*/pcm*/sub*/info The general information of this PCM sub-stream. @@ -153,6 +179,16 @@ card*/codec#* Shows the general codec information and the attribute of each widget node. +card*/eld#* + Available for HDMI or DisplayPort interfaces. + Shows ELD(EDID Like Data) info retrieved from the attached HDMI sink, + and describes its audio capabilities and configurations. + + Some ELD fields may be modified by doing `echo name hex_value > eld#*`. + Only do this if you are sure the HDMI sink provided value is wrong. + And if that makes your HDMI audio work, please report to us so that we + can fix it in future kernel releases. + Sequencer Information --------------------- @@ -161,12 +197,12 @@ seq/drivers Lists the currently available ALSA sequencer drivers. seq/clients - Shows the list of currently available sequencer clinets and + Shows the list of currently available sequencer clients and ports. The connection status and the running status are shown in this file, too. seq/queues - Lists the currently allocated/running sequener queues. + Lists the currently allocated/running sequencer queues. seq/timer Lists the currently allocated/running sequencer timers. @@ -182,10 +218,10 @@ 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 +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) + - the register dump, if available (e.g. card*/cmipci) when it's a PCM problem, diff --git a/Documentation/sound/alsa/README.maya44 b/Documentation/sound/alsa/README.maya44 new file mode 100644 index 00000000000..67b2ea1cc31 --- /dev/null +++ b/Documentation/sound/alsa/README.maya44 @@ -0,0 +1,163 @@ +NOTE: The following is the original document of Rainer's patch that the +current maya44 code based on. Some contents might be obsoleted, but I +keep here as reference -- tiwai + +---------------------------------------------------------------- + +STATE OF DEVELOPMENT: + +This driver is being developed on the initiative of Piotr Makowski (oponek@gmail.com) and financed by Lars Bergmann. +Development is carried out by Rainer Zimmermann (mail@lightshed.de). + +ESI provided a sample Maya44 card for the development work. + +However, unfortunately it has turned out difficult to get detailed programming information, so I (Rainer Zimmermann) had to find out some card-specific information by experiment and conjecture. Some information (in particular, several GPIO bits) is still missing. + +This is the first testing version of the Maya44 driver released to the alsa-devel mailing list (Feb 5, 2008). + + +The following functions work, as tested by Rainer Zimmermann and Piotr Makowski: + +- playback and capture at all sampling rates +- input/output level +- crossmixing +- line/mic switch +- phantom power switch +- analogue monitor a.k.a bypass + + +The following functions *should* work, but are not fully tested: + +- Channel 3+4 analogue - S/PDIF input switching +- S/PDIF output +- all inputs/outputs on the M/IO/DIO extension card +- internal/external clock selection + + +*In particular, we would appreciate testing of these functions by anyone who has access to an M/IO/DIO extension card.* + + +Things that do not seem to work: + +- The level meters ("multi track") in 'alsamixer' do not seem to react to signals in (if this is a bug, it would probably be in the existing ICE1724 code). + +- Ardour 2.1 seems to work only via JACK, not using ALSA directly or via OSS. This still needs to be tracked down. + + +DRIVER DETAILS: + +the following files were added: + +pci/ice1724/maya44.c - Maya44 specific code +pci/ice1724/maya44.h +pci/ice1724/ice1724.patch +pci/ice1724/ice1724.h.patch - PROPOSED patch to ice1724.h (see SAMPLING RATES) +i2c/other/wm8776.c - low-level access routines for Wolfson WM8776 codecs +include/wm8776.h + + +Note that the wm8776.c code is meant to be card-independent and does not actually register the codec with the ALSA infrastructure. +This is done in maya44.c, mainly because some of the WM8776 controls are used in Maya44-specific ways, and should be named appropriately. + + +the following files were created in pci/ice1724, simply #including the corresponding file from the alsa-kernel tree: + +wtm.h +vt1720_mobo.h +revo.h +prodigy192.h +pontis.h +phase.h +maya44.h +juli.h +aureon.h +amp.h +envy24ht.h +se.h +prodigy_hifi.h + + +*I hope this is the correct way to do things.* + + +SAMPLING RATES: + +The Maya44 card (or more exactly, the Wolfson WM8776 codecs) allow a maximum sampling rate of 192 kHz for playback and 92 kHz for capture. + +As the ICE1724 chip only allows one global sampling rate, this is handled as follows: + +* setting the sampling rate on any open PCM device on the maya44 card will always set the *global* sampling rate for all playback and capture channels. + +* In the current state of the driver, setting rates of up to 192 kHz is permitted even for capture devices. + +*AVOID CAPTURING AT RATES ABOVE 96kHz*, even though it may appear to work. The codec cannot actually capture at such rates, meaning poor quality. + + +I propose some additional code for limiting the sampling rate when setting on a capture pcm device. However because of the global sampling rate, this logic would be somewhat problematic. + +The proposed code (currently deactivated) is in ice1712.h.patch, ice1724.c and maya44.c (in pci/ice1712). + + +SOUND DEVICES: + +PCM devices correspond to inputs/outputs as follows (assuming Maya44 is card #0): + +hw:0,0 input - stereo, analog input 1+2 +hw:0,0 output - stereo, analog output 1+2 +hw:0,1 input - stereo, analog input 3+4 OR S/PDIF input +hw:0,1 output - stereo, analog output 3+4 (and SPDIF out) + + +NAMING OF MIXER CONTROLS: + +(for more information about the signal flow, please refer to the block diagram on p.24 of the ESI Maya44 manual, or in the ESI windows software). + + +PCM: (digital) output level for channel 1+2 +PCM 1: same for channel 3+4 + +Mic Phantom+48V: switch for +48V phantom power for electrostatic microphones on input 1/2. + Make sure this is not turned on while any other source is connected to input 1/2. + It might damage the source and/or the maya44 card. + +Mic/Line input: if switch is on, input jack 1/2 is microphone input (mono), otherwise line input (stereo). + +Bypass: analogue bypass from ADC input to output for channel 1+2. Same as "Monitor" in the windows driver. +Bypass 1: same for channel 3+4. + +Crossmix: cross-mixer from channels 1+2 to channels 3+4 +Crossmix 1: cross-mixer from channels 3+4 to channels 1+2 + +IEC958 Output: switch for S/PDIF output. + This is not supported by the ESI windows driver. + S/PDIF should output the same signal as channel 3+4. [untested!] + + +Digitial output selectors: + + These switches allow a direct digital routing from the ADCs to the DACs. + Each switch determines where the digital input data to one of the DACs comes from. + They are not supported by the ESI windows driver. + For normal operation, they should all be set to "PCM out". + +H/W: Output source channel 1 +H/W 1: Output source channel 2 +H/W 2: Output source channel 3 +H/W 3: Output source channel 4 + +H/W 4 ... H/W 9: unknown function, left in to enable testing. + Possibly some of these control S/PDIF output(s). + If these turn out to be unused, they will go away in later driver versions. + +Selectable values for each of the digital output selectors are: + "PCM out" -> DAC output of the corresponding channel (default setting) + "Input 1"... + "Input 4" -> direct routing from ADC output of the selected input channel + + +-------- + +Feb 14, 2008 +Rainer Zimmermann +mail@lightshed.de + diff --git a/Documentation/sound/alsa/SB-Live-mixer.txt b/Documentation/sound/alsa/SB-Live-mixer.txt index 651adaf6047..f4b5988f450 100644 --- a/Documentation/sound/alsa/SB-Live-mixer.txt +++ b/Documentation/sound/alsa/SB-Live-mixer.txt @@ -5,7 +5,7 @@ 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 +(This article 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 @@ -87,14 +87,14 @@ 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 +name='Synth 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 +name='Synth Capture Volume',index=0 +name='Synth 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. diff --git a/Documentation/sound/alsa/alsa-parameters.txt b/Documentation/sound/alsa/alsa-parameters.txt new file mode 100644 index 00000000000..0fa40679b08 --- /dev/null +++ b/Documentation/sound/alsa/alsa-parameters.txt @@ -0,0 +1,135 @@ + ALSA Kernel Parameters + ~~~~~~~~~~~~~~~~~~~~~~ + +See Documentation/kernel-parameters.txt for general information on +specifying module parameters. + +This document may not be entirely up to date and comprehensive. The command +"modinfo -p ${modulename}" shows a current list of all parameters of a loadable +module. Loadable modules, after being loaded into the running kernel, also +reveal their parameters in /sys/module/${modulename}/parameters/. Some of these +parameters may be changed at runtime by the command +"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}". + + + snd-ad1816a= [HW,ALSA] + + snd-ad1848= [HW,ALSA] + + snd-ali5451= [HW,ALSA] + + snd-als100= [HW,ALSA] + + snd-als4000= [HW,ALSA] + + snd-azt2320= [HW,ALSA] + + snd-cmi8330= [HW,ALSA] + + snd-cmipci= [HW,ALSA] + + snd-cs4231= [HW,ALSA] + + snd-cs4232= [HW,ALSA] + + snd-cs4236= [HW,ALSA] + + snd-cs4281= [HW,ALSA] + + snd-cs46xx= [HW,ALSA] + + snd-dt019x= [HW,ALSA] + + snd-dummy= [HW,ALSA] + + snd-emu10k1= [HW,ALSA] + + snd-ens1370= [HW,ALSA] + + snd-ens1371= [HW,ALSA] + + snd-es968= [HW,ALSA] + + snd-es1688= [HW,ALSA] + + snd-es18xx= [HW,ALSA] + + snd-es1938= [HW,ALSA] + + snd-es1968= [HW,ALSA] + + snd-fm801= [HW,ALSA] + + snd-gusclassic= [HW,ALSA] + + snd-gusextreme= [HW,ALSA] + + snd-gusmax= [HW,ALSA] + + snd-hdsp= [HW,ALSA] + + snd-ice1712= [HW,ALSA] + + snd-intel8x0= [HW,ALSA] + + snd-interwave= [HW,ALSA] + + snd-interwave-stb= + [HW,ALSA] + + snd-korg1212= [HW,ALSA] + + snd-maestro3= [HW,ALSA] + + snd-mpu401= [HW,ALSA] + + snd-mtpav= [HW,ALSA] + + snd-nm256= [HW,ALSA] + + snd-opl3sa2= [HW,ALSA] + + snd-opti92x-ad1848= + [HW,ALSA] + + snd-opti92x-cs4231= + [HW,ALSA] + + snd-opti93x= [HW,ALSA] + + snd-pmac= [HW,ALSA] + + snd-rme32= [HW,ALSA] + + snd-rme96= [HW,ALSA] + + snd-rme9652= [HW,ALSA] + + snd-sb8= [HW,ALSA] + + snd-sb16= [HW,ALSA] + + snd-sbawe= [HW,ALSA] + + snd-serial= [HW,ALSA] + + snd-sgalaxy= [HW,ALSA] + + snd-sonicvibes= [HW,ALSA] + + snd-sun-amd7930= + [HW,ALSA] + + snd-sun-cs4231= [HW,ALSA] + + snd-trident= [HW,ALSA] + + snd-usb-audio= [HW,ALSA,USB] + + snd-via82xx= [HW,ALSA] + + snd-virmidi= [HW,ALSA] + + snd-wavefront= [HW,ALSA] + + snd-ymfpci= [HW,ALSA] diff --git a/Documentation/sound/alsa/compress_offload.txt b/Documentation/sound/alsa/compress_offload.txt new file mode 100644 index 00000000000..630c492c3dc --- /dev/null +++ b/Documentation/sound/alsa/compress_offload.txt @@ -0,0 +1,234 @@ + compress_offload.txt + ===================== + Pierre-Louis.Bossart <pierre-louis.bossart@linux.intel.com> + Vinod Koul <vinod.koul@linux.intel.com> + +Overview + +Since its early days, the ALSA API was defined with PCM support or +constant bitrates payloads such as IEC61937 in mind. Arguments and +returned values in frames are the norm, making it a challenge to +extend the existing API to compressed data streams. + +In recent years, audio digital signal processors (DSP) were integrated +in system-on-chip designs, and DSPs are also integrated in audio +codecs. Processing compressed data on such DSPs results in a dramatic +reduction of power consumption compared to host-based +processing. Support for such hardware has not been very good in Linux, +mostly because of a lack of a generic API available in the mainline +kernel. + +Rather than requiring a compatibility break with an API change of the +ALSA PCM interface, a new 'Compressed Data' API is introduced to +provide a control and data-streaming interface for audio DSPs. + +The design of this API was inspired by the 2-year experience with the +Intel Moorestown SOC, with many corrections required to upstream the +API in the mainline kernel instead of the staging tree and make it +usable by others. + +Requirements + +The main requirements are: + +- separation between byte counts and time. Compressed formats may have + a header per file, per frame, or no header at all. The payload size + may vary from frame-to-frame. As a result, it is not possible to + estimate reliably the duration of audio buffers when handling + compressed data. Dedicated mechanisms are required to allow for + reliable audio-video synchronization, which requires precise + reporting of the number of samples rendered at any given time. + +- Handling of multiple formats. PCM data only requires a specification + of the sampling rate, number of channels and bits per sample. In + contrast, compressed data comes in a variety of formats. Audio DSPs + may also provide support for a limited number of audio encoders and + decoders embedded in firmware, or may support more choices through + dynamic download of libraries. + +- Focus on main formats. This API provides support for the most + popular formats used for audio and video capture and playback. It is + likely that as audio compression technology advances, new formats + will be added. + +- Handling of multiple configurations. Even for a given format like + AAC, some implementations may support AAC multichannel but HE-AAC + stereo. Likewise WMA10 level M3 may require too much memory and cpu + cycles. The new API needs to provide a generic way of listing these + formats. + +- Rendering/Grabbing only. This API does not provide any means of + hardware acceleration, where PCM samples are provided back to + user-space for additional processing. This API focuses instead on + streaming compressed data to a DSP, with the assumption that the + decoded samples are routed to a physical output or logical back-end. + + - Complexity hiding. Existing user-space multimedia frameworks all + have existing enums/structures for each compressed format. This new + API assumes the existence of a platform-specific compatibility layer + to expose, translate and make use of the capabilities of the audio + DSP, eg. Android HAL or PulseAudio sinks. By construction, regular + applications are not supposed to make use of this API. + + +Design + +The new API shares a number of concepts with the PCM API for flow +control. Start, pause, resume, drain and stop commands have the same +semantics no matter what the content is. + +The concept of memory ring buffer divided in a set of fragments is +borrowed from the ALSA PCM API. However, only sizes in bytes can be +specified. + +Seeks/trick modes are assumed to be handled by the host. + +The notion of rewinds/forwards is not supported. Data committed to the +ring buffer cannot be invalidated, except when dropping all buffers. + +The Compressed Data API does not make any assumptions on how the data +is transmitted to the audio DSP. DMA transfers from main memory to an +embedded audio cluster or to a SPI interface for external DSPs are +possible. As in the ALSA PCM case, a core set of routines is exposed; +each driver implementer will have to write support for a set of +mandatory routines and possibly make use of optional ones. + +The main additions are + +- get_caps +This routine returns the list of audio formats supported. Querying the +codecs on a capture stream will return encoders, decoders will be +listed for playback streams. + +- get_codec_caps For each codec, this routine returns a list of +capabilities. The intent is to make sure all the capabilities +correspond to valid settings, and to minimize the risks of +configuration failures. For example, for a complex codec such as AAC, +the number of channels supported may depend on a specific profile. If +the capabilities were exposed with a single descriptor, it may happen +that a specific combination of profiles/channels/formats may not be +supported. Likewise, embedded DSPs have limited memory and cpu cycles, +it is likely that some implementations make the list of capabilities +dynamic and dependent on existing workloads. In addition to codec +settings, this routine returns the minimum buffer size handled by the +implementation. This information can be a function of the DMA buffer +sizes, the number of bytes required to synchronize, etc, and can be +used by userspace to define how much needs to be written in the ring +buffer before playback can start. + +- set_params +This routine sets the configuration chosen for a specific codec. The +most important field in the parameters is the codec type; in most +cases decoders will ignore other fields, while encoders will strictly +comply to the settings + +- get_params +This routines returns the actual settings used by the DSP. Changes to +the settings should remain the exception. + +- get_timestamp +The timestamp becomes a multiple field structure. It lists the number +of bytes transferred, the number of samples processed and the number +of samples rendered/grabbed. All these values can be used to determine +the average bitrate, figure out if the ring buffer needs to be +refilled or the delay due to decoding/encoding/io on the DSP. + +Note that the list of codecs/profiles/modes was derived from the +OpenMAX AL specification instead of reinventing the wheel. +Modifications include: +- Addition of FLAC and IEC formats +- Merge of encoder/decoder capabilities +- Profiles/modes listed as bitmasks to make descriptors more compact +- Addition of set_params for decoders (missing in OpenMAX AL) +- Addition of AMR/AMR-WB encoding modes (missing in OpenMAX AL) +- Addition of format information for WMA +- Addition of encoding options when required (derived from OpenMAX IL) +- Addition of rateControlSupported (missing in OpenMAX AL) + +Gapless Playback +================ +When playing thru an album, the decoders have the ability to skip the encoder +delay and padding and directly move from one track content to another. The end +user can perceive this as gapless playback as we dont have silence while +switching from one track to another + +Also, there might be low-intensity noises due to encoding. Perfect gapless is +difficult to reach with all types of compressed data, but works fine with most +music content. The decoder needs to know the encoder delay and encoder padding. +So we need to pass this to DSP. This metadata is extracted from ID3/MP4 headers +and are not present by default in the bitstream, hence the need for a new +interface to pass this information to the DSP. Also DSP and userspace needs to +switch from one track to another and start using data for second track. + +The main additions are: + +- set_metadata +This routine sets the encoder delay and encoder padding. This can be used by +decoder to strip the silence. This needs to be set before the data in the track +is written. + +- set_next_track +This routine tells DSP that metadata and write operation sent after this would +correspond to subsequent track + +- partial drain +This is called when end of file is reached. The userspace can inform DSP that +EOF is reached and now DSP can start skipping padding delay. Also next write +data would belong to next track + +Sequence flow for gapless would be: +- Open +- Get caps / codec caps +- Set params +- Set metadata of the first track +- Fill data of the first track +- Trigger start +- User-space finished sending all, +- Indicaite next track data by sending set_next_track +- Set metadata of the next track +- then call partial_drain to flush most of buffer in DSP +- Fill data of the next track +- DSP switches to second track +(note: order for partial_drain and write for next track can be reversed as well) + +Not supported: + +- Support for VoIP/circuit-switched calls is not the target of this + API. Support for dynamic bit-rate changes would require a tight + coupling between the DSP and the host stack, limiting power savings. + +- Packet-loss concealment is not supported. This would require an + additional interface to let the decoder synthesize data when frames + are lost during transmission. This may be added in the future. + +- Volume control/routing is not handled by this API. Devices exposing a + compressed data interface will be considered as regular ALSA devices; + volume changes and routing information will be provided with regular + ALSA kcontrols. + +- Embedded audio effects. Such effects should be enabled in the same + manner, no matter if the input was PCM or compressed. + +- multichannel IEC encoding. Unclear if this is required. + +- Encoding/decoding acceleration is not supported as mentioned + above. It is possible to route the output of a decoder to a capture + stream, or even implement transcoding capabilities. This routing + would be enabled with ALSA kcontrols. + +- Audio policy/resource management. This API does not provide any + hooks to query the utilization of the audio DSP, nor any preemption + mechanisms. + +- No notion of underrun/overrun. Since the bytes written are compressed + in nature and data written/read doesn't translate directly to + rendered output in time, this does not deal with underrun/overrun and + maybe dealt in user-library + +Credits: +- Mark Brown and Liam Girdwood for discussions on the need for this API +- Harsha Priya for her work on intel_sst compressed API +- Rakesh Ughreja for valuable feedback +- Sing Nallasellan, Sikkandar Madar and Prasanna Samaga for + demonstrating and quantifying the benefits of audio offload on a + real platform. diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt index 0be57ed8130..de8efbc7e4b 100644 --- a/Documentation/sound/alsa/hda_codec.txt +++ b/Documentation/sound/alsa/hda_codec.txt @@ -49,6 +49,9 @@ struct hda_bus_ops { unsigned int verb, unsigned int parm); unsigned int (*get_response)(struct hda_codec *codec); void (*private_free)(struct hda_bus *); +#ifdef CONFIG_SND_HDA_POWER_SAVE + void (*pm_notify)(struct hda_codec *codec); +#endif }; The command callback is called when the codec module needs to send a @@ -56,9 +59,16 @@ 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 +The third, private_free callback, is optional. It's called in the destructor to release any necessary data in the lowlevel driver. +The pm_notify callback is available only with +CONFIG_SND_HDA_POWER_SAVE kconfig. It's called when the codec needs +to power up or may power down. The controller should check the all +belonging codecs on the bus whether they are actually powered off +(check codec->power_on), and optionally the driver may power down the +controller side, too. + 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. @@ -86,10 +96,8 @@ 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); + list_for_each_entry(codec, &bus->codec_list, list) { ... } @@ -100,10 +108,15 @@ initialization sequence is called when the controls are built later. Codec Access ============ -To access codec, use snd_codec_read() and snd_codec_write(). +To access codec, use snd_hda_codec_read() and snd_hda_codec_write(). snd_hda_param_read() is for reading parameters. For writing a sequence of verbs, use snd_hda_sequence_write(). +There are variants of cached read/write, snd_hda_codec_write_cache(), +snd_hda_sequence_write_cache(). These are used for recording the +register states for the power-management resume. When no PM is needed, +these are equivalent with non-cached version. + 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. @@ -239,6 +252,10 @@ set the codec->patch_ops field. This is defined as below: int (*suspend)(struct hda_codec *codec, pm_message_t state); int (*resume)(struct hda_codec *codec); #endif + #ifdef CONFIG_SND_HDA_POWER_SAVE + int (*check_power_status)(struct hda_codec *codec, + hda_nid_t nid); + #endif }; The build_controls callback is called from snd_hda_build_controls(). @@ -251,6 +268,18 @@ The unsol_event callback is called when an unsolicited event is received. The suspend and resume callbacks are for power management. +They can be NULL if no special sequence is required. When the resume +callback is NULL, the driver calls the init callback and resumes the +registers from the cache. If other handling is needed, you'd need to +write your own resume callback. There, the amp values can be resumed +via + void snd_hda_codec_resume_amp(struct hda_codec *codec); +and the other codec registers via + void snd_hda_codec_resume_cache(struct hda_codec *codec); + +The check_power_status callback is called when the amp value of the +given widget NID is changed. The codec code can turn on/off the power +appropriately from this information. Each entry can be NULL if not necessary to be called. @@ -267,8 +296,7 @@ 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(). +related with SPDIF out. Helper Functions @@ -277,19 +305,14 @@ 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. +information matching with the device. Define the model string table +and the table with struct snd_pci_quirk 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 struct snd_kcontrol_new. 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. +Pass the zero-terminated array of struct snd_kcontrol_new Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be used for the entry of struct snd_kcontrol_new. diff --git a/Documentation/sound/alsa/hdspm.txt b/Documentation/sound/alsa/hdspm.txt index 7a67ff71a9f..7ba31948dea 100644 --- a/Documentation/sound/alsa/hdspm.txt +++ b/Documentation/sound/alsa/hdspm.txt @@ -359,4 +359,4 @@ Calling Parameter: enable_monitor int array (min = 1, max = 8), "Enable Analog Out on Channel 63/64 by default." - note: here the analog output is enabled (but not routed).
\ No newline at end of file + note: here the analog output is enabled (but not routed). diff --git a/Documentation/sound/alsa/powersave.txt b/Documentation/sound/alsa/powersave.txt new file mode 100644 index 00000000000..9657e809922 --- /dev/null +++ b/Documentation/sound/alsa/powersave.txt @@ -0,0 +1,41 @@ +Notes on Power-Saving Mode +========================== + +AC97 and HD-audio drivers have the automatic power-saving mode. +This feature is enabled via Kconfig CONFIG_SND_AC97_POWER_SAVE +and CONFIG_SND_HDA_POWER_SAVE options, respectively. + +With the automatic power-saving, the driver turns off the codec power +appropriately when no operation is required. When no applications use +the device and/or no analog loopback is set, the power disablement is +done fully or partially. It'll save a certain power consumption, thus +good for laptops (even for desktops). + +The time-out for automatic power-off can be specified via power_save +module option of snd-ac97-codec and snd-hda-intel modules. Specify +the time-out value in seconds. 0 means to disable the automatic +power-saving. The default value of timeout is given via +CONFIG_SND_AC97_POWER_SAVE_DEFAULT and +CONFIG_SND_HDA_POWER_SAVE_DEFAULT Kconfig options. Setting this to 1 +(the minimum value) isn't recommended because many applications try to +reopen the device frequently. 10 would be a good choice for normal +operations. + +The power_save option is exported as writable. This means you can +adjust the value via sysfs on the fly. For example, to turn on the +automatic power-save mode with 10 seconds, write to +/sys/modules/snd_ac97_codec/parameters/power_save (usually as root): + + # echo 10 > /sys/modules/snd_ac97_codec/parameters/power_save + + +Note that you might hear click noise/pop when changing the power +state. Also, it often takes certain time to wake up from the +power-down to the active state. These are often hardly to fix, so +don't report extra bug reports unless you have a fix patch ;-) + +For HD-audio interface, there is another module option, +power_save_controller. This enables/disables the power-save mode of +the controller side. Setting this on may reduce a bit more power +consumption, but might result in longer wake-up time and click noise. +Try to turn it off when you experience such a thing too often. diff --git a/Documentation/sound/alsa/seq_oss.html b/Documentation/sound/alsa/seq_oss.html index d9776cf60c0..9663b45f6fd 100644 --- a/Documentation/sound/alsa/seq_oss.html +++ b/Documentation/sound/alsa/seq_oss.html @@ -285,7 +285,7 @@ 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 +application. 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> diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt new file mode 100644 index 00000000000..c9679264c55 --- /dev/null +++ b/Documentation/sound/alsa/soc/DAI.txt @@ -0,0 +1,56 @@ +ASoC currently supports the three main Digital Audio Interfaces (DAI) found on +SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM. + + +AC97 +==== + + AC97 is a five wire interface commonly found on many PC sound cards. It is +now also popular in many portable devices. This DAI has a reset line and time +multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines. +The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the +frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97 +frame is 21uS long and is divided into 13 time slots. + +The AC97 specification can be found at :- +http://www.intel.com/p/en_US/business/design + + +I2S +=== + + I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and +Rx lines are used for audio transmission, whilst the bit clock (BCLK) and +left/right clock (LRC) synchronise the link. I2S is flexible in that either the +controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock +usually varies depending on the sample rate and the master system clock +(SYSCLK). LRCLK is the same as the sample rate. A few devices support separate +ADC and DAC LRCLKs, this allows for simultaneous capture and playback at +different sample rates. + +I2S has several different operating modes:- + + o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC + transition. + + o Left Justified - MSB is transmitted on transition of LRC. + + o Right Justified - MSB is transmitted sample size BCLKs before LRC + transition. + +PCM +=== + +PCM is another 4 wire interface, very similar to I2S, which can support a more +flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used +to synchronise the link whilst the Tx and Rx lines are used to transmit and +receive the audio data. Bit clock usually varies depending on sample rate +whilst sync runs at the sample rate. PCM also supports Time Division +Multiplexing (TDM) in that several devices can use the bus simultaneously (this +is sometimes referred to as network mode). + +Common PCM operating modes:- + + o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC. + + o Mode B - MSB is transmitted on rising edge of FRAME/SYNC. diff --git a/Documentation/sound/alsa/soc/DPCM.txt b/Documentation/sound/alsa/soc/DPCM.txt new file mode 100644 index 00000000000..0110180b7ac --- /dev/null +++ b/Documentation/sound/alsa/soc/DPCM.txt @@ -0,0 +1,380 @@ +Dynamic PCM +=========== + +1. Description +============== + +Dynamic PCM allows an ALSA PCM device to digitally route its PCM audio to +various digital endpoints during the PCM stream runtime. e.g. PCM0 can route +digital audio to I2S DAI0, I2S DAI1 or PDM DAI2. This is useful for on SoC DSP +drivers that expose several ALSA PCMs and can route to multiple DAIs. + +The DPCM runtime routing is determined by the ALSA mixer settings in the same +way as the analog signal is routed in an ASoC codec driver. DPCM uses a DAPM +graph representing the DSP internal audio paths and uses the mixer settings to +determine the patch used by each ALSA PCM. + +DPCM re-uses all the existing component codec, platform and DAI drivers without +any modifications. + + +Phone Audio System with SoC based DSP +------------------------------------- + +Consider the following phone audio subsystem. This will be used in this +document for all examples :- + +| Front End PCMs | SoC DSP | Back End DAIs | Audio devices | + + ************* +PCM0 <------------> * * <----DAI0-----> Codec Headset + * * +PCM1 <------------> * * <----DAI1-----> Codec Speakers + * DSP * +PCM2 <------------> * * <----DAI2-----> MODEM + * * +PCM3 <------------> * * <----DAI3-----> BT + * * + * * <----DAI4-----> DMIC + * * + * * <----DAI5-----> FM + ************* + +This diagram shows a simple smart phone audio subsystem. It supports Bluetooth, +FM digital radio, Speakers, Headset Jack, digital microphones and cellular +modem. This sound card exposes 4 DSP front end (FE) ALSA PCM devices and +supports 6 back end (BE) DAIs. Each FE PCM can digitally route audio data to any +of the BE DAIs. The FE PCM devices can also route audio to more than 1 BE DAI. + + + +Example - DPCM Switching playback from DAI0 to DAI1 +--------------------------------------------------- + +Audio is being played to the Headset. After a while the user removes the headset +and audio continues playing on the speakers. + +Playback on PCM0 to Headset would look like :- + + ************* +PCM0 <============> * * <====DAI0=====> Codec Headset + * * +PCM1 <------------> * * <----DAI1-----> Codec Speakers + * DSP * +PCM2 <------------> * * <----DAI2-----> MODEM + * * +PCM3 <------------> * * <----DAI3-----> BT + * * + * * <----DAI4-----> DMIC + * * + * * <----DAI5-----> FM + ************* + +The headset is removed from the jack by user so the speakers must now be used :- + + ************* +PCM0 <============> * * <----DAI0-----> Codec Headset + * * +PCM1 <------------> * * <====DAI1=====> Codec Speakers + * DSP * +PCM2 <------------> * * <----DAI2-----> MODEM + * * +PCM3 <------------> * * <----DAI3-----> BT + * * + * * <----DAI4-----> DMIC + * * + * * <----DAI5-----> FM + ************* + +The audio driver processes this as follows :- + + 1) Machine driver receives Jack removal event. + + 2) Machine driver OR audio HAL disables the Headset path. + + 3) DPCM runs the PCM trigger(stop), hw_free(), shutdown() operations on DAI0 + for headset since the path is now disabled. + + 4) Machine driver or audio HAL enables the speaker path. + + 5) DPCM runs the PCM ops for startup(), hw_params(), prepapre() and + trigger(start) for DAI1 Speakers since the path is enabled. + +In this example, the machine driver or userspace audio HAL can alter the routing +and then DPCM will take care of managing the DAI PCM operations to either bring +the link up or down. Audio playback does not stop during this transition. + + + +DPCM machine driver +=================== + +The DPCM enabled ASoC machine driver is similar to normal machine drivers +except that we also have to :- + + 1) Define the FE and BE DAI links. + + 2) Define any FE/BE PCM operations. + + 3) Define widget graph connections. + + +1 FE and BE DAI links +--------------------- + +| Front End PCMs | SoC DSP | Back End DAIs | Audio devices | + + ************* +PCM0 <------------> * * <----DAI0-----> Codec Headset + * * +PCM1 <------------> * * <----DAI1-----> Codec Speakers + * DSP * +PCM2 <------------> * * <----DAI2-----> MODEM + * * +PCM3 <------------> * * <----DAI3-----> BT + * * + * * <----DAI4-----> DMIC + * * + * * <----DAI5-----> FM + ************* + +For the example above we have to define 4 FE DAI links and 6 BE DAI links. The +FE DAI links are defined as follows :- + +static struct snd_soc_dai_link machine_dais[] = { + { + .name = "PCM0 System", + .stream_name = "System Playback", + .cpu_dai_name = "System Pin", + .platform_name = "dsp-audio", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .dynamic = 1, + .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_playback = 1, + }, + .....< other FE and BE DAI links here > +}; + +This FE DAI link is pretty similar to a regular DAI link except that we also +set the DAI link to a DPCM FE with the "dynamic = 1". The supported FE stream +directions should also be set with the "dpcm_playback" and "dpcm_capture" +flags. There is also an option to specify the ordering of the trigger call for +each FE. This allows the ASoC core to trigger the DSP before or after the other +components (as some DSPs have strong requirements for the ordering DAI/DSP +start and stop sequences). + +The FE DAI above sets the codec and code DAIs to dummy devices since the BE is +dynamic and will change depending on runtime config. + +The BE DAIs are configured as follows :- + +static struct snd_soc_dai_link machine_dais[] = { + .....< FE DAI links here > + { + .name = "Codec Headset", + .cpu_dai_name = "ssp-dai.0", + .platform_name = "snd-soc-dummy", + .no_pcm = 1, + .codec_name = "rt5640.0-001c", + .codec_dai_name = "rt5640-aif1", + .ignore_suspend = 1, + .ignore_pmdown_time = 1, + .be_hw_params_fixup = hswult_ssp0_fixup, + .ops = &haswell_ops, + .dpcm_playback = 1, + .dpcm_capture = 1, + }, + .....< other BE DAI links here > +}; + +This BE DAI link connects DAI0 to the codec (in this case RT5460 AIF1). It sets +the "no_pcm" flag to mark it has a BE and sets flags for supported stream +directions using "dpcm_playback" and "dpcm_capture" above. + +The BE has also flags set for ignoring suspend and PM down time. This allows +the BE to work in a hostless mode where the host CPU is not transferring data +like a BT phone call :- + + ************* +PCM0 <------------> * * <----DAI0-----> Codec Headset + * * +PCM1 <------------> * * <----DAI1-----> Codec Speakers + * DSP * +PCM2 <------------> * * <====DAI2=====> MODEM + * * +PCM3 <------------> * * <====DAI3=====> BT + * * + * * <----DAI4-----> DMIC + * * + * * <----DAI5-----> FM + ************* + +This allows the host CPU to sleep whilst the DSP, MODEM DAI and the BT DAI are +still in operation. + +A BE DAI link can also set the codec to a dummy device if the code is a device +that is managed externally. + +Likewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the +DSP firmware. + + +2 FE/BE PCM operations +---------------------- + +The BE above also exports some PCM operations and a "fixup" callback. The fixup +callback is used by the machine driver to (re)configure the DAI based upon the +FE hw params. i.e. the DSP may perform SRC or ASRC from the FE to BE. + +e.g. DSP converts all FE hw params to run at fixed rate of 48k, 16bit, stereo for +DAI0. This means all FE hw_params have to be fixed in the machine driver for +DAI0 so that the DAI is running at desired configuration regardless of the FE +configuration. + +static int dai0_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + /* The DSP will covert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set DAI0 to 16 bit */ + snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - + SNDRV_PCM_HW_PARAM_FIRST_MASK], + SNDRV_PCM_FORMAT_S16_LE); + return 0; +} + +The other PCM operation are the same as for regular DAI links. Use as necessary. + + +3 Widget graph connections +-------------------------- + +The BE DAI links will normally be connected to the graph at initialisation time +by the ASoC DAPM core. However, if the BE codec or BE DAI is a dummy then this +has to be set explicitly in the driver :- + +/* BE for codec Headset - DAI0 is dummy and managed by DSP FW */ +{"DAI0 CODEC IN", NULL, "AIF1 Capture"}, +{"AIF1 Playback", NULL, "DAI0 CODEC OUT"}, + + +Writing a DPCM DSP driver +========================= + +The DPCM DSP driver looks much like a standard platform class ASoC driver +combined with elements from a codec class driver. A DSP platform driver must +implement :- + + 1) Front End PCM DAIs - i.e. struct snd_soc_dai_driver. + + 2) DAPM graph showing DSP audio routing from FE DAIs to BEs. + + 3) DAPM widgets from DSP graph. + + 4) Mixers for gains, routing, etc. + + 5) DMA configuration. + + 6) BE AIF widgets. + +Items 6 is important for routing the audio outside of the DSP. AIF need to be +defined for each BE and each stream direction. e.g for BE DAI0 above we would +have :- + +SND_SOC_DAPM_AIF_IN("DAI0 RX", NULL, 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("DAI0 TX", NULL, 0, SND_SOC_NOPM, 0, 0), + +The BE AIF are used to connect the DSP graph to the graphs for the other +component drivers (e.g. codec graph). + + +Hostless PCM streams +==================== + +A hostless PCM stream is a stream that is not routed through the host CPU. An +example of this would be a phone call from handset to modem. + + + ************* +PCM0 <------------> * * <----DAI0-----> Codec Headset + * * +PCM1 <------------> * * <====DAI1=====> Codec Speakers/Mic + * DSP * +PCM2 <------------> * * <====DAI2=====> MODEM + * * +PCM3 <------------> * * <----DAI3-----> BT + * * + * * <----DAI4-----> DMIC + * * + * * <----DAI5-----> FM + ************* + +In this case the PCM data is routed via the DSP. The host CPU in this use case +is only used for control and can sleep during the runtime of the stream. + +The host can control the hostless link either by :- + + 1) Configuring the link as a CODEC <-> CODEC style link. In this case the link + is enabled or disabled by the state of the DAPM graph. This usually means + there is a mixer control that can be used to connect or disconnect the path + between both DAIs. + + 2) Hostless FE. This FE has a virtual connection to the BE DAI links on the DAPM + graph. Control is then carried out by the FE as regular PCM operations. + This method gives more control over the DAI links, but requires much more + userspace code to control the link. Its recommended to use CODEC<->CODEC + unless your HW needs more fine grained sequencing of the PCM ops. + + +CODEC <-> CODEC link +-------------------- + +This DAI link is enabled when DAPM detects a valid path within the DAPM graph. +The machine driver sets some additional parameters to the DAI link i.e. + +static const struct snd_soc_pcm_stream dai_params = { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 2, + .channels_max = 2, +}; + +static struct snd_soc_dai_link dais[] = { + < ... more DAI links above ... > + { + .name = "MODEM", + .stream_name = "MODEM", + .cpu_dai_name = "dai2", + .codec_dai_name = "modem-aif1", + .codec_name = "modem", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM, + .params = &dai_params, + } + < ... more DAI links here ... > + +These parameters are used to configure the DAI hw_params() when DAPM detects a +valid path and then calls the PCM operations to start the link. DAPM will also +call the appropriate PCM operations to disable the DAI when the path is no +longer valid. + + +Hostless FE +----------- + +The DAI link(s) are enabled by a FE that does not read or write any PCM data. +This means creating a new FE that is connected with a virtual path to both +DAI links. The DAI links will be started when the FE PCM is started and stopped +when the FE PCM is stopped. Note that the FE PCM cannot read or write data in +this configuration. + + diff --git a/Documentation/sound/alsa/soc/clocking.txt b/Documentation/sound/alsa/soc/clocking.txt new file mode 100644 index 00000000000..b1300162e01 --- /dev/null +++ b/Documentation/sound/alsa/soc/clocking.txt @@ -0,0 +1,51 @@ +Audio Clocking +============== + +This text describes the audio clocking terms in ASoC and digital audio in +general. Note: Audio clocking can be complex! + + +Master Clock +------------ + +Every audio subsystem is driven by a master clock (sometimes referred to as MCLK +or SYSCLK). This audio master clock can be derived from a number of sources +(e.g. crystal, PLL, CPU clock) and is responsible for producing the correct +audio playback and capture sample rates. + +Some master clocks (e.g. PLLs and CPU based clocks) are configurable in that +their speed can be altered by software (depending on the system use and to save +power). Other master clocks are fixed at a set frequency (i.e. crystals). + + +DAI Clocks +---------- +The Digital Audio Interface is usually driven by a Bit Clock (often referred to +as BCLK). This clock is used to drive the digital audio data across the link +between the codec and CPU. + +The DAI also has a frame clock to signal the start of each audio frame. This +clock is sometimes referred to as LRC (left right clock) or FRAME. This clock +runs at exactly the sample rate (LRC = Rate). + +Bit Clock can be generated as follows:- + +BCLK = MCLK / x + + or + +BCLK = LRC * x + + or + +BCLK = LRC * Channels * Word Size + +This relationship depends on the codec or SoC CPU in particular. In general +it is best to configure BCLK to the lowest possible speed (depending on your +rate, number of channels and word size) to save on power. + +It is also desirable to use the codec (if possible) to drive (or master) the +audio clocks as it usually gives more accurate sample rates than the CPU. + + + diff --git a/Documentation/sound/alsa/soc/codec.txt b/Documentation/sound/alsa/soc/codec.txt new file mode 100644 index 00000000000..db5f9c9ae14 --- /dev/null +++ b/Documentation/sound/alsa/soc/codec.txt @@ -0,0 +1,179 @@ +ASoC Codec Class Driver +======================= + +The codec class driver is generic and hardware independent code that configures +the codec, FM, MODEM, BT or external DSP to provide audio capture and playback. +It should contain no code that is specific to the target platform or machine. +All platform and machine specific code should be added to the platform and +machine drivers respectively. + +Each codec class driver *must* provide the following features:- + + 1) Codec DAI and PCM configuration + 2) Codec control IO - using RegMap API + 3) Mixers and audio controls + 4) Codec audio operations + 5) DAPM description. + 6) DAPM event handler. + +Optionally, codec drivers can also provide:- + + 7) DAC Digital mute control. + +Its probably best to use this guide in conjunction with the existing codec +driver code in sound/soc/codecs/ + +ASoC Codec driver breakdown +=========================== + +1 - Codec DAI and PCM configuration +----------------------------------- +Each codec driver must have a struct snd_soc_dai_driver to define its DAI and +PCM capabilities and operations. This struct is exported so that it can be +registered with the core by your machine driver. + +e.g. + +static struct snd_soc_dai_ops wm8731_dai_ops = { + .prepare = wm8731_pcm_prepare, + .hw_params = wm8731_hw_params, + .shutdown = wm8731_shutdown, + .digital_mute = wm8731_mute, + .set_sysclk = wm8731_set_dai_sysclk, + .set_fmt = wm8731_set_dai_fmt, +}; + +struct snd_soc_dai_driver wm8731_dai = { + .name = "wm8731-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8731_RATES, + .formats = WM8731_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8731_RATES, + .formats = WM8731_FORMATS,}, + .ops = &wm8731_dai_ops, + .symmetric_rates = 1, +}; + + +2 - Codec control IO +-------------------- +The codec can usually be controlled via an I2C or SPI style interface +(AC97 combines control with data in the DAI). The codec driver should use the +Regmap API for all codec IO. Please see include/linux/regmap.h and existing +codec drivers for example regmap usage. + + +3 - Mixers and audio controls +----------------------------- +All the codec mixers and audio controls can be defined using the convenience +macros defined in soc.h. + + #define SOC_SINGLE(xname, reg, shift, mask, invert) + +Defines a single control as follows:- + + xname = Control name e.g. "Playback Volume" + reg = codec register + shift = control bit(s) offset in register + mask = control bit size(s) e.g. mask of 7 = 3 bits + invert = the control is inverted + +Other macros include:- + + #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) + +A stereo control + + #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) + +A stereo control spanning 2 registers + + #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) + +Defines an single enumerated control as follows:- + + xreg = register + xshift = control bit(s) offset in register + xmask = control bit(s) size + xtexts = pointer to array of strings that describe each setting + + #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) + +Defines a stereo enumerated control + + +4 - Codec Audio Operations +-------------------------- +The codec driver also supports the following ALSA PCM operations:- + +/* SoC audio ops */ +struct snd_soc_ops { + int (*startup)(struct snd_pcm_substream *); + void (*shutdown)(struct snd_pcm_substream *); + int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); + int (*hw_free)(struct snd_pcm_substream *); + int (*prepare)(struct snd_pcm_substream *); +}; + +Please refer to the ALSA driver PCM documentation for details. +http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ + + +5 - DAPM description. +--------------------- +The Dynamic Audio Power Management description describes the codec power +components and their relationships and registers to the ASoC core. +Please read dapm.txt for details of building the description. + +Please also see the examples in other codec drivers. + + +6 - DAPM event handler +---------------------- +This function is a callback that handles codec domain PM calls and system +domain PM calls (e.g. suspend and resume). It is used to put the codec +to sleep when not in use. + +Power states:- + + SNDRV_CTL_POWER_D0: /* full On */ + /* vref/mid, clk and osc on, active */ + + SNDRV_CTL_POWER_D1: /* partial On */ + SNDRV_CTL_POWER_D2: /* partial On */ + + SNDRV_CTL_POWER_D3hot: /* Off, with power */ + /* everything off except vref/vmid, inactive */ + + SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ + + +7 - Codec DAC digital mute control +---------------------------------- +Most codecs have a digital mute before the DACs that can be used to +minimise any system noise. The mute stops any digital data from +entering the DAC. + +A callback can be created that is called by the core for each codec DAI +when the mute is applied or freed. + +i.e. + +static int wm8974_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf; + + if (mute) + snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40); + else + snd_soc_write(codec, WM8974_DAC, mute_reg); + return 0; +} diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt new file mode 100644 index 00000000000..6faab488000 --- /dev/null +++ b/Documentation/sound/alsa/soc/dapm.txt @@ -0,0 +1,305 @@ +Dynamic Audio Power Management for Portable Devices +=================================================== + +1. Description +============== + +Dynamic Audio Power Management (DAPM) is designed to allow portable +Linux devices to use the minimum amount of power within the audio +subsystem at all times. It is independent of other kernel PM and as +such, can easily co-exist with the other PM systems. + +DAPM is also completely transparent to all user space applications as +all power switching is done within the ASoC core. No code changes or +recompiling are required for user space applications. DAPM makes power +switching decisions based upon any audio stream (capture/playback) +activity and audio mixer settings within the device. + +DAPM spans the whole machine. It covers power control within the entire +audio subsystem, this includes internal codec power blocks and machine +level power systems. + +There are 4 power domains within DAPM + + 1. Codec bias domain - VREF, VMID (core codec and audio power) + Usually controlled at codec probe/remove and suspend/resume, although + can be set at stream time if power is not needed for sidetone, etc. + + 2. Platform/Machine domain - physically connected inputs and outputs + Is platform/machine and user action specific, is configured by the + machine driver and responds to asynchronous events e.g when HP + are inserted + + 3. Path domain - audio subsystem signal paths + Automatically set when mixer and mux settings are changed by the user. + e.g. alsamixer, amixer. + + 4. Stream domain - DACs and ADCs. + Enabled and disabled when stream playback/capture is started and + stopped respectively. e.g. aplay, arecord. + +All DAPM power switching decisions are made automatically by consulting an audio +routing map of the whole machine. This map is specific to each machine and +consists of the interconnections between every audio component (including +internal codec components). All audio components that effect power are called +widgets hereafter. + + +2. DAPM Widgets +=============== + +Audio DAPM widgets fall into a number of types:- + + o Mixer - Mixes several analog signals into a single analog signal. + o Mux - An analog switch that outputs only one of many inputs. + o PGA - A programmable gain amplifier or attenuation widget. + o ADC - Analog to Digital Converter + o DAC - Digital to Analog Converter + o Switch - An analog switch + o Input - A codec input pin + o Output - A codec output pin + o Headphone - Headphone (and optional Jack) + o Mic - Mic (and optional Jack) + o Line - Line Input/Output (and optional Jack) + o Speaker - Speaker + o Supply - Power or clock supply widget used by other widgets. + o Regulator - External regulator that supplies power to audio components. + o Clock - External clock that supplies clock to audio components. + o AIF IN - Audio Interface Input (with TDM slot mask). + o AIF OUT - Audio Interface Output (with TDM slot mask). + o Siggen - Signal Generator. + o DAI IN - Digital Audio Interface Input. + o DAI OUT - Digital Audio Interface Output. + o DAI Link - DAI Link between two DAI structures */ + o Pre - Special PRE widget (exec before all others) + o Post - Special POST widget (exec after all others) + +(Widgets are defined in include/sound/soc-dapm.h) + +Widgets can be added to the sound card by any of the component driver types. +There are convenience macros defined in soc-dapm.h that can be used to quickly +build a list of widgets of the codecs and machines DAPM widgets. + +Most widgets have a name, register, shift and invert. Some widgets have extra +parameters for stream name and kcontrols. + + +2.1 Stream Domain Widgets +------------------------- + +Stream Widgets relate to the stream power domain and only consist of ADCs +(analog to digital converters), DACs (digital to analog converters), +AIF IN and AIF OUT. + +Stream widgets have the following format:- + +SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert), +SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert) + +NOTE: the stream name must match the corresponding stream name in your codec +snd_soc_codec_dai. + +e.g. stream widgets for HiFi playback and capture + +SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1), +SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1), + +e.g. stream widgets for AIF + +SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + + +2.2 Path Domain Widgets +----------------------- + +Path domain widgets have a ability to control or affect the audio signal or +audio paths within the audio subsystem. They have the following form:- + +SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls) + +Any widget kcontrols can be set using the controls and num_controls members. + +e.g. Mixer widget (the kcontrols are declared first) + +/* Output Mixer */ +static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = { +SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), +SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), +SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), +}; + +SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls, + ARRAY_SIZE(wm8731_output_mixer_controls)), + +If you dont want the mixer elements prefixed with the name of the mixer widget, +you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same +as for SND_SOC_DAPM_MIXER. + + +2.3 Machine domain Widgets +-------------------------- + +Machine widgets are different from codec widgets in that they don't have a +codec register bit associated with them. A machine widget is assigned to each +machine audio component (non codec or DSP) that can be independently +powered. e.g. + + o Speaker Amp + o Microphone Bias + o Jack connectors + +A machine widget can have an optional call back. + +e.g. Jack connector widget for an external Mic that enables Mic Bias +when the Mic is inserted:- + +static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event) +{ + gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event)); + return 0; +} + +SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias), + + +2.4 Codec (BIAS) Domain +----------------------- + +The codec bias power domain has no widgets and is handled by the codecs DAPM +event handler. This handler is called when the codec powerstate is changed wrt +to any stream event or by kernel PM events. + + +2.5 Virtual Widgets +------------------- + +Sometimes widgets exist in the codec or machine audio map that don't have any +corresponding soft power control. In this case it is necessary to create +a virtual widget - a widget with no control bits e.g. + +SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), + +This can be used to merge to signal paths together in software. + +After all the widgets have been defined, they can then be added to the DAPM +subsystem individually with a call to snd_soc_dapm_new_control(). + + +3. Codec/DSP Widget Interconnections +==================================== + +Widgets are connected to each other within the codec, platform and machine by +audio paths (called interconnections). Each interconnection must be defined in +order to create a map of all audio paths between widgets. + +This is easiest with a diagram of the codec or DSP (and schematic of the machine +audio system), as it requires joining widgets together via their audio signal +paths. + +e.g., from the WM8731 output mixer (wm8731.c) + +The WM8731 output mixer has 3 inputs (sources) + + 1. Line Bypass Input + 2. DAC (HiFi playback) + 3. Mic Sidetone Input + +Each input in this example has a kcontrol associated with it (defined in example +above) and is connected to the output mixer via its kcontrol name. We can now +connect the destination widget (wrt audio signal) with its source widgets. + + /* output mixer */ + {"Output Mixer", "Line Bypass Switch", "Line Input"}, + {"Output Mixer", "HiFi Playback Switch", "DAC"}, + {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, + +So we have :- + + Destination Widget <=== Path Name <=== Source Widget + +Or:- + + Sink, Path, Source + +Or :- + + "Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch". + +When there is no path name connecting widgets (e.g. a direct connection) we +pass NULL for the path name. + +Interconnections are created with a call to:- + +snd_soc_dapm_connect_input(codec, sink, path, source); + +Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and +interconnections have been registered with the core. This causes the core to +scan the codec and machine so that the internal DAPM state matches the +physical state of the machine. + + +3.1 Machine Widget Interconnections +----------------------------------- +Machine widget interconnections are created in the same way as codec ones and +directly connect the codec pins to machine level widgets. + +e.g. connects the speaker out codec pins to the internal speaker. + + /* ext speaker connected to codec pins LOUT2, ROUT2 */ + {"Ext Spk", NULL , "ROUT2"}, + {"Ext Spk", NULL , "LOUT2"}, + +This allows the DAPM to power on and off pins that are connected (and in use) +and pins that are NC respectively. + + +4 Endpoint Widgets +=================== +An endpoint is a start or end point (widget) of an audio signal within the +machine and includes the codec. e.g. + + o Headphone Jack + o Internal Speaker + o Internal Mic + o Mic Jack + o Codec Pins + +Endpoints are added to the DAPM graph so that their usage can be determined in +order to save power. e.g. NC codecs pins will be switched OFF, unconnected +jacks can also be switched OFF. + + +5 DAPM Widget Events +==================== + +Some widgets can register their interest with the DAPM core in PM events. +e.g. A Speaker with an amplifier registers a widget so the amplifier can be +powered only when the spk is in use. + +/* turn speaker amplifier on/off depending on use */ +static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) +{ + gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event)); + return 0; +} + +/* corgi machine dapm widgets */ +static const struct snd_soc_dapm_widget wm8731_dapm_widgets = + SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event); + +Please see soc-dapm.h for all other widgets that support events. + + +5.1 Event types +--------------- + +The following event types are supported by event widgets. + +/* dapm event types */ +#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */ +#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */ +#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */ +#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ +#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ +#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ diff --git a/Documentation/sound/alsa/soc/jack.txt b/Documentation/sound/alsa/soc/jack.txt new file mode 100644 index 00000000000..fcf82a41729 --- /dev/null +++ b/Documentation/sound/alsa/soc/jack.txt @@ -0,0 +1,71 @@ +ASoC jack detection +=================== + +ALSA has a standard API for representing physical jacks to user space, +the kernel side of which can be seen in include/sound/jack.h. ASoC +provides a version of this API adding two additional features: + + - It allows more than one jack detection method to work together on one + user visible jack. In embedded systems it is common for multiple + to be present on a single jack but handled by separate bits of + hardware. + + - Integration with DAPM, allowing DAPM endpoints to be updated + automatically based on the detected jack status (eg, turning off the + headphone outputs if no headphones are present). + +This is done by splitting the jacks up into three things working +together: the jack itself represented by a struct snd_soc_jack, sets of +snd_soc_jack_pins representing DAPM endpoints to update and blocks of +code providing jack reporting mechanisms. + +For example, a system may have a stereo headset jack with two reporting +mechanisms, one for the headphone and one for the microphone. Some +systems won't be able to use their speaker output while a headphone is +connected and so will want to make sure to update both speaker and +headphone when the headphone jack status changes. + +The jack - struct snd_soc_jack +============================== + +This represents a physical jack on the system and is what is visible to +user space. The jack itself is completely passive, it is set up by the +machine driver and updated by jack detection methods. + +Jacks are created by the machine driver calling snd_soc_jack_new(). + +snd_soc_jack_pin +================ + +These represent a DAPM pin to update depending on some of the status +bits supported by the jack. Each snd_soc_jack has zero or more of these +which are updated automatically. They are created by the machine driver +and associated with the jack using snd_soc_jack_add_pins(). The status +of the endpoint may configured to be the opposite of the jack status if +required (eg, enabling a built in microphone if a microphone is not +connected via a jack). + +Jack detection methods +====================== + +Actual jack detection is done by code which is able to monitor some +input to the system and update a jack by calling snd_soc_jack_report(), +specifying a subset of bits to update. The jack detection code should +be set up by the machine driver, taking configuration for the jack to +update and the set of things to report when the jack is connected. + +Often this is done based on the status of a GPIO - a handler for this is +provided by the snd_soc_jack_add_gpio() function. Other methods are +also available, for example integrated into CODECs. One example of +CODEC integrated jack detection can be see in the WM8350 driver. + +Each jack may have multiple reporting mechanisms, though it will need at +least one to be useful. + +Machine drivers +=============== + +These are all hooked together by the machine driver depending on the +system hardware. The machine driver will set up the snd_soc_jack and +the list of pins to update then set up one or more jack detection +mechanisms to update that jack based on their current status. diff --git a/Documentation/sound/alsa/soc/machine.txt b/Documentation/sound/alsa/soc/machine.txt new file mode 100644 index 00000000000..74056dba52b --- /dev/null +++ b/Documentation/sound/alsa/soc/machine.txt @@ -0,0 +1,93 @@ +ASoC Machine Driver +=================== + +The ASoC machine (or board) driver is the code that glues together all the +component drivers (e.g. codecs, platforms and DAIs). It also describes the +relationships between each componnent which include audio paths, GPIOs, +interrupts, clocking, jacks and voltage regulators. + +The machine driver can contain codec and platform specific code. It registers +the audio subsystem with the kernel as a platform device and is represented by +the following struct:- + +/* SoC machine */ +struct snd_soc_card { + char *name; + + ... + + int (*probe)(struct platform_device *pdev); + int (*remove)(struct platform_device *pdev); + + /* the pre and post PM functions are used to do any PM work before and + * after the codec and DAIs do any PM work. */ + int (*suspend_pre)(struct platform_device *pdev, pm_message_t state); + int (*suspend_post)(struct platform_device *pdev, pm_message_t state); + int (*resume_pre)(struct platform_device *pdev); + int (*resume_post)(struct platform_device *pdev); + + ... + + /* CPU <--> Codec DAI links */ + struct snd_soc_dai_link *dai_link; + int num_links; + + ... +}; + +probe()/remove() +---------------- +probe/remove are optional. Do any machine specific probe here. + + +suspend()/resume() +------------------ +The machine driver has pre and post versions of suspend and resume to take care +of any machine audio tasks that have to be done before or after the codec, DAIs +and DMA is suspended and resumed. Optional. + + +Machine DAI Configuration +------------------------- +The machine DAI configuration glues all the codec and CPU DAIs together. It can +also be used to set up the DAI system clock and for any machine related DAI +initialisation e.g. the machine audio map can be connected to the codec audio +map, unconnected codec pins can be set as such. + +struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. + +/* corgi digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link corgi_dai = { + .name = "WM8731", + .stream_name = "WM8731", + .cpu_dai_name = "pxa-is2-dai", + .codec_dai_name = "wm8731-hifi", + .platform_name = "pxa-pcm-audio", + .codec_name = "wm8713-codec.0-001a", + .init = corgi_wm8731_init, + .ops = &corgi_ops, +}; + +struct snd_soc_card then sets up the machine with its DAIs. e.g. + +/* corgi audio machine driver */ +static struct snd_soc_card snd_soc_corgi = { + .name = "Corgi", + .dai_link = &corgi_dai, + .num_links = 1, +}; + + +Machine Power Map +----------------- + +The machine driver can optionally extend the codec power map and to become an +audio power map of the audio subsystem. This allows for automatic power up/down +of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack +sockets in the machine init function. + + +Machine Controls +---------------- + +Machine specific audio mixer controls can be added in the DAI init function. diff --git a/Documentation/sound/alsa/soc/overview.txt b/Documentation/sound/alsa/soc/overview.txt new file mode 100644 index 00000000000..ff88f52eec9 --- /dev/null +++ b/Documentation/sound/alsa/soc/overview.txt @@ -0,0 +1,95 @@ +ALSA SoC Layer +============== + +The overall project goal of the ALSA System on Chip (ASoC) layer is to +provide better ALSA support for embedded system-on-chip processors (e.g. +pxa2xx, au1x00, iMX, etc) and portable audio codecs. Prior to the ASoC +subsystem there was some support in the kernel for SoC audio, however it +had some limitations:- + + * Codec drivers were often tightly coupled to the underlying SoC + CPU. This is not ideal and leads to code duplication - for example, + Linux had different wm8731 drivers for 4 different SoC platforms. + + * There was no standard method to signal user initiated audio events (e.g. + Headphone/Mic insertion, Headphone/Mic detection after an insertion + event). These are quite common events on portable devices and often require + machine specific code to re-route audio, enable amps, etc., after such an + event. + + * Drivers tended to power up the entire codec when playing (or + recording) audio. This is fine for a PC, but tends to waste a lot of + power on portable devices. There was also no support for saving + power via changing codec oversampling rates, bias currents, etc. + + +ASoC Design +=========== + +The ASoC layer is designed to address these issues and provide the following +features :- + + * Codec independence. Allows reuse of codec drivers on other platforms + and machines. + + * Easy I2S/PCM audio interface setup between codec and SoC. Each SoC + interface and codec registers its audio interface capabilities with the + core and are subsequently matched and configured when the application + hardware parameters are known. + + * Dynamic Audio Power Management (DAPM). DAPM automatically sets the codec to + its minimum power state at all times. This includes powering up/down + internal power blocks depending on the internal codec audio routing and any + active streams. + + * Pop and click reduction. Pops and clicks can be reduced by powering the + codec up/down in the correct sequence (including using digital mute). ASoC + signals the codec when to change power states. + + * Machine specific controls: Allow machines to add controls to the sound card + (e.g. volume control for speaker amplifier). + +To achieve all this, ASoC basically splits an embedded audio system into +multiple re-usable component drivers :- + + * Codec class drivers: The codec class driver is platform independent and + contains audio controls, audio interface capabilities, codec DAPM + definition and codec IO functions. This class extends to BT, FM and MODEM + ICs if required. Codec class drivers should be generic code that can run + on any architecture and machine. + + * Platform class drivers: The platform class driver includes the audio DMA + engine driver, digital audio interface (DAI) drivers (e.g. I2S, AC97, PCM) + and any audio DSP drivers for that platform. + + * Machine class driver: The machine driver class acts as the glue that + decribes and binds the other component drivers together to form an ALSA + "sound card device". It handles any machine specific controls and + machine level audio events (e.g. turning on an amp at start of playback). + + +Documentation +============= + +The documentation is spilt into the following sections:- + +overview.txt: This file. + +codec.txt: Codec driver internals. + +DAI.txt: Description of Digital Audio Interface standards and how to configure +a DAI within your codec and CPU DAI drivers. + +dapm.txt: Dynamic Audio Power Management + +platform.txt: Platform audio DMA and DAI. + +machine.txt: Machine driver internals. + +pop_clicks.txt: How to minimise audio artifacts. + +clocking.txt: ASoC clocking for best power performance. + +jack.txt: ASoC jack detection. + +DPCM.txt: Dynamic PCM - Describes DPCM with DSP examples. diff --git a/Documentation/sound/alsa/soc/platform.txt b/Documentation/sound/alsa/soc/platform.txt new file mode 100644 index 00000000000..3a08a2c9150 --- /dev/null +++ b/Documentation/sound/alsa/soc/platform.txt @@ -0,0 +1,79 @@ +ASoC Platform Driver +==================== + +An ASoC platform driver class can be divided into audio DMA drivers, SoC DAI +drivers and DSP drivers. The platform drivers only target the SoC CPU and must +have no board specific code. + +Audio DMA +========= + +The platform DMA driver optionally supports the following ALSA operations:- + +/* SoC audio ops */ +struct snd_soc_ops { + int (*startup)(struct snd_pcm_substream *); + void (*shutdown)(struct snd_pcm_substream *); + int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); + int (*hw_free)(struct snd_pcm_substream *); + int (*prepare)(struct snd_pcm_substream *); + int (*trigger)(struct snd_pcm_substream *, int); +}; + +The platform driver exports its DMA functionality via struct +snd_soc_platform_driver:- + +struct snd_soc_platform_driver { + char *name; + + int (*probe)(struct platform_device *pdev); + int (*remove)(struct platform_device *pdev); + int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); + int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); + + /* pcm creation and destruction */ + int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *); + void (*pcm_free)(struct snd_pcm *); + + /* + * For platform caused delay reporting. + * Optional. + */ + snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *, + struct snd_soc_dai *); + + /* platform stream ops */ + struct snd_pcm_ops *pcm_ops; +}; + +Please refer to the ALSA driver documentation for details of audio DMA. +http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ + +An example DMA driver is soc/pxa/pxa2xx-pcm.c + + +SoC DAI Drivers +=============== + +Each SoC DAI driver must provide the following features:- + + 1) Digital audio interface (DAI) description + 2) Digital audio interface configuration + 3) PCM's description + 4) SYSCLK configuration + 5) Suspend and resume (optional) + +Please see codec.txt for a description of items 1 - 4. + + +SoC DSP Drivers +=============== + +Each SoC DSP driver usually supplies the following features :- + + 1) DAPM graph + 2) Mixer controls + 3) DMA IO to/from DSP buffers (if applicable) + 4) Definition of DSP front end (FE) PCM devices. + +Please see DPCM.txt for a description of item 4. diff --git a/Documentation/sound/alsa/soc/pops_clicks.txt b/Documentation/sound/alsa/soc/pops_clicks.txt new file mode 100644 index 00000000000..e1e74daa449 --- /dev/null +++ b/Documentation/sound/alsa/soc/pops_clicks.txt @@ -0,0 +1,52 @@ +Audio Pops and Clicks +===================== + +Pops and clicks are unwanted audio artifacts caused by the powering up and down +of components within the audio subsystem. This is noticeable on PCs when an +audio module is either loaded or unloaded (at module load time the sound card is +powered up and causes a popping noise on the speakers). + +Pops and clicks can be more frequent on portable systems with DAPM. This is +because the components within the subsystem are being dynamically powered +depending on the audio usage and this can subsequently cause a small pop or +click every time a component power state is changed. + + +Minimising Playback Pops and Clicks +=================================== + +Playback pops in portable audio subsystems cannot be completely eliminated +currently, however future audio codec hardware will have better pop and click +suppression. Pops can be reduced within playback by powering the audio +components in a specific order. This order is different for startup and +shutdown and follows some basic rules:- + + Startup Order :- DAC --> Mixers --> Output PGA --> Digital Unmute + + Shutdown Order :- Digital Mute --> Output PGA --> Mixers --> DAC + +This assumes that the codec PCM output path from the DAC is via a mixer and then +a PGA (programmable gain amplifier) before being output to the speakers. + + +Minimising Capture Pops and Clicks +================================== + +Capture artifacts are somewhat easier to get rid as we can delay activating the +ADC until all the pops have occurred. This follows similar power rules to +playback in that components are powered in a sequence depending upon stream +startup or shutdown. + + Startup Order - Input PGA --> Mixers --> ADC + + Shutdown Order - ADC --> Mixers --> Input PGA + + +Zipper Noise +============ +An unwanted zipper noise can occur within the audio playback or capture stream +when a volume control is changed near its maximum gain value. The zipper noise +is heard when the gain increase or decrease changes the mean audio signal +amplitude too quickly. It can be minimised by enabling the zero cross setting +for each volume control. The ZC forces the gain change to occur when the signal +crosses the zero amplitude line. diff --git a/Documentation/sound/oss/AD1816 b/Documentation/sound/oss/AD1816 deleted file mode 100644 index 14bd8f25d52..00000000000 --- a/Documentation/sound/oss/AD1816 +++ /dev/null @@ -1,84 +0,0 @@ -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 index d01ffbfd580..bf10bed4574 100644 --- a/Documentation/sound/oss/ALS +++ b/Documentation/sound/oss/ALS @@ -57,10 +57,10 @@ The resulting sound driver will provide the following capabilities: DSP/PCM/audio out (L&R), FM (L&R) and Mic in (mono). Jonathan Woithe -jwoithe@physics.adelaide.edu.au +jwoithe@just42.net 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 +Modified 2000-11-19 by Jonathan Woithe, jwoithe@just42.net - updated information for kernel 2.4.x. diff --git a/Documentation/sound/oss/AWE32 b/Documentation/sound/oss/AWE32 deleted file mode 100644 index cb179bfeb52..00000000000 --- a/Documentation/sound/oss/AWE32 +++ /dev/null @@ -1,76 +0,0 @@ - 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 index c0f08922993..ea8549faede 100644 --- a/Documentation/sound/oss/AudioExcelDSP16 +++ b/Documentation/sound/oss/AudioExcelDSP16 @@ -1,10 +1,10 @@ Driver ------ -Informations about Audio Excel DSP 16 driver can be found in the source +Information 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. +information. Configuration ------------- @@ -41,7 +41,7 @@ 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: +A configuration file in /etc/modprobe.d/ directory will have lines like this: options opl3 io=0x388 options ad1848 io=0x530 irq=11 dma=3 @@ -51,11 +51,11 @@ 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: +the sound card. Installation dependencies must be written in configuration +files under /etc/modprobe.d/ directory: -install ad1848 /sbin/modprobe aedsp16 && /sbin/modprobe -i ad1848 -install opl3 /sbin/modprobe aedsp16 && /sbin/modprobe -i opl3 +softdep ad1848 pre: aedsp16 +softdep opl3 pre: aedsp16 Then you must load the sound modules stack in this order: sound -> aedsp16 -> [ ad1848, opl3 ] @@ -68,7 +68,7 @@ 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. +information 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. diff --git a/Documentation/sound/oss/CMI8330 b/Documentation/sound/oss/CMI8330 index 9c439f1a6db..8a5fd1611c6 100644 --- a/Documentation/sound/oss/CMI8330 +++ b/Documentation/sound/oss/CMI8330 @@ -143,11 +143,10 @@ CONFIG_SOUND_MSS=m -Alma Chao <elysian@ethereal.torsion.org> suggests the following /etc/modprobe.conf: +Alma Chao <elysian@ethereal.torsion.org> suggests the following in +a /etc/modprobe.d/*conf file: 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 deleted file mode 100644 index 387d058c3f9..00000000000 --- a/Documentation/sound/oss/CMI8338 +++ /dev/null @@ -1,85 +0,0 @@ -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 deleted file mode 100644 index 7d6af7a5c1c..00000000000 --- a/Documentation/sound/oss/CS4232 +++ /dev/null @@ -1,23 +0,0 @@ -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/INSTALL.awe b/Documentation/sound/oss/INSTALL.awe deleted file mode 100644 index 310f42ca1e8..00000000000 --- a/Documentation/sound/oss/INSTALL.awe +++ /dev/null @@ -1,134 +0,0 @@ -================================================================ - 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 index 15d4fb975ac..42da2d8fa37 100644 --- a/Documentation/sound/oss/Introduction +++ b/Documentation/sound/oss/Introduction @@ -69,7 +69,7 @@ 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). +resort, inspect the code (search for module_param). Notes: @@ -80,7 +80,7 @@ Notes: additional features. 2. The commercial OSS driver may be obtained from the site: - http://www/opensound.com. This may be used for cards that + 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. @@ -167,8 +167,8 @@ 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: +If loading via modprobe, these common files are automatically loaded when +requested by modprobe. For example, my /etc/modprobe.d/oss.conf contains: alias sound sb options sb io=0x240 irq=9 dma=3 dma16=5 mpu_io=0x300 @@ -228,7 +228,7 @@ 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 +2. remove the sound modules from /etc/modprobe.d/*.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 @@ -265,7 +265,7 @@ twice, you need to do the following: 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, +2. Make a second entry in /etc/modprobe.d/*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. @@ -369,7 +369,7 @@ There are several ways of configuring your sound: 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. +3) In /etc/modprobe.d/*conf when using modprobe. 4) Via Red Hat's GPL'd /usr/sbin/sndconfig program (text based). diff --git a/Documentation/sound/oss/MAD16 b/Documentation/sound/oss/MAD16 deleted file mode 100644 index 865dbd84874..00000000000 --- a/Documentation/sound/oss/MAD16 +++ /dev/null @@ -1,56 +0,0 @@ -(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 deleted file mode 100644 index 4a80eb3f8e0..00000000000 --- a/Documentation/sound/oss/Maestro +++ /dev/null @@ -1,123 +0,0 @@ - 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 deleted file mode 100644 index a113718e803..00000000000 --- a/Documentation/sound/oss/Maestro3 +++ /dev/null @@ -1,92 +0,0 @@ - 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/NEWS b/Documentation/sound/oss/NEWS deleted file mode 100644 index a81e0ef72ae..00000000000 --- a/Documentation/sound/oss/NEWS +++ /dev/null @@ -1,42 +0,0 @@ -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 deleted file mode 100644 index b503217488b..00000000000 --- a/Documentation/sound/oss/NM256 +++ /dev/null @@ -1,280 +0,0 @@ -======================================================= -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-SA b/Documentation/sound/oss/OPL3-SA deleted file mode 100644 index 66a91835d91..00000000000 --- a/Documentation/sound/oss/OPL3-SA +++ /dev/null @@ -1,52 +0,0 @@ -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 deleted file mode 100644 index d8b6d2bbada..00000000000 --- a/Documentation/sound/oss/OPL3-SA2 +++ /dev/null @@ -1,210 +0,0 @@ -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 index c15af3c07d4..4cd5d9ab358 100644 --- a/Documentation/sound/oss/Opti +++ b/Documentation/sound/oss/Opti @@ -18,7 +18,7 @@ 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 +Also, it is recommended that resources specified in /etc/modprobe.d/*.conf and resources specified in /etc/isapnp.conf agree. Compiling the sound driver @@ -67,11 +67,7 @@ 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. +Config files in '/etc/modprobe.d/' are used as below: alias mixer0 mad16 alias audio0 mad16 diff --git a/Documentation/sound/oss/PAS16 b/Documentation/sound/oss/PAS16 index 951b3dce51b..5c27229eec8 100644 --- a/Documentation/sound/oss/PAS16 +++ b/Documentation/sound/oss/PAS16 @@ -60,8 +60,7 @@ With PAS16 you can use two audio device files at the same time. /dev/dsp (and The new stuff for 2.3.99 and later ============================================================================ -The following configuration options from Documentation/Configure.help -are relevant to configuring the PAS16: +The following configuration options are relevant to configuring the PAS16: Sound card support CONFIG_SOUND @@ -129,7 +128,7 @@ CONFIG_SOUND_YM3812 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: + /etc/modprobe.d/*.conf: options opl3 io=0x388 or else add the following line to /etc/lilo.conf: opl3=0x388 @@ -159,5 +158,5 @@ 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 +specified in /etc/modprobe.d/*.conf for pas2, sb and opl3 respectively. diff --git a/Documentation/sound/oss/README.OSS b/Documentation/sound/oss/README.OSS index fd42b05b2f5..4be259428a1 100644 --- a/Documentation/sound/oss/README.OSS +++ b/Documentation/sound/oss/README.OSS @@ -36,7 +36,7 @@ with OSS API. 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 +See http://www.opensound.com/ossfree/ for download instructions. If you are looking for the installation instructions, please @@ -1352,7 +1352,7 @@ 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 +(limited by the OSS-design). Development 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 @@ -1438,7 +1438,7 @@ 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) +at the home page (http://www.opensound.com/ossfree/) for latest info. Information about unsupported sound cards and chipsets is welcome as well @@ -1449,7 +1449,6 @@ 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 diff --git a/Documentation/sound/oss/README.awe b/Documentation/sound/oss/README.awe deleted file mode 100644 index 80054cd8fcd..00000000000 --- a/Documentation/sound/oss/README.awe +++ /dev/null @@ -1,218 +0,0 @@ -================================================================ - 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 index e691d74e1e5..cdc039421a4 100644 --- a/Documentation/sound/oss/README.modules +++ b/Documentation/sound/oss/README.modules @@ -26,7 +26,7 @@ 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: + Then, add to your /etc/modprobe.d/oss.conf something like: alias char-major-14-* sb install sb /sbin/modprobe -i sb && /sbin/modprobe adlib_card @@ -36,7 +36,7 @@ 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" +softdep sb post: adlib_card options adlib_card io=0x388 The effect of this is that the sound driver and all necessary bits and @@ -66,12 +66,12 @@ 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. +with /etc/modprobe.d/*.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. + recommend using /etc/modprobe.d/*.conf. Persistent DMA Buffers: @@ -89,7 +89,7 @@ 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: +in /etc/modprobe.d/*.conf files like so: options sound dmabuf=1 diff --git a/Documentation/sound/oss/README.ymfsb b/Documentation/sound/oss/README.ymfsb index af8a7d3a4e8..b6b77906b58 100644 --- a/Documentation/sound/oss/README.ymfsb +++ b/Documentation/sound/oss/README.ymfsb @@ -5,7 +5,7 @@ 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 + I respect and thank for all people they made open the information about YMF7xx cards. And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s diff --git a/Documentation/sound/oss/VIA-chipset b/Documentation/sound/oss/VIA-chipset deleted file mode 100644 index 37865234e54..00000000000 --- a/Documentation/sound/oss/VIA-chipset +++ /dev/null @@ -1,43 +0,0 @@ -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/Wavefront b/Documentation/sound/oss/Wavefront deleted file mode 100644 index 16f57ea4305..00000000000 --- a/Documentation/sound/oss/Wavefront +++ /dev/null @@ -1,339 +0,0 @@ - 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/cs46xx b/Documentation/sound/oss/cs46xx deleted file mode 100644 index 88d6cf8b39f..00000000000 --- a/Documentation/sound/oss/cs46xx +++ /dev/null @@ -1,138 +0,0 @@ - -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 deleted file mode 100644 index 7b38b1a096a..00000000000 --- a/Documentation/sound/oss/es1370 +++ /dev/null @@ -1,70 +0,0 @@ -/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 deleted file mode 100644 index c3151266771..00000000000 --- a/Documentation/sound/oss/es1371 +++ /dev/null @@ -1,64 +0,0 @@ -/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 index 858334bb46b..5fbcb160927 100644 --- a/Documentation/sound/oss/mwave +++ b/Documentation/sound/oss/mwave @@ -163,7 +163,7 @@ 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. +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 diff --git a/Documentation/sound/oss/oss-parameters.txt b/Documentation/sound/oss/oss-parameters.txt new file mode 100644 index 00000000000..3ab391e7c29 --- /dev/null +++ b/Documentation/sound/oss/oss-parameters.txt @@ -0,0 +1,51 @@ + OSS Kernel Parameters + ~~~~~~~~~~~~~~~~~~~~~ + +See Documentation/kernel-parameters.txt for general information on +specifying module parameters. + +This document may not be entirely up to date and comprehensive. The command +"modinfo -p ${modulename}" shows a current list of all parameters of a loadable +module. Loadable modules, after being loaded into the running kernel, also +reveal their parameters in /sys/module/${modulename}/parameters/. Some of these +parameters may be changed at runtime by the command +"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}". + + + ad1848= [HW,OSS] + Format: <io>,<irq>,<dma>,<dma2>,<type> + + aedsp16= [HW,OSS] Audio Excel DSP 16 + Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq> + See also header of sound/oss/aedsp16.c. + + dmasound= [HW,OSS] Sound subsystem buffers + + mpu401= [HW,OSS] + Format: <io>,<irq> + + opl3= [HW,OSS] + Format: <io> + + pas2= [HW,OSS] Format: + <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16> + + pss= [HW,OSS] Personal Sound System (ECHO ESC614) + Format: + <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq> + + sscape= [HW,OSS] + Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq> + + trix= [HW,OSS] MediaTrix AudioTrix Pro + Format: + <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq> + + uart401= [HW,OSS] + Format: <io>,<irq> + + uart6850= [HW,OSS] + Format: <io>,<irq> + + waveartist= [HW,OSS] + Format: <io>,<irq>,<dma>,<dma2> diff --git a/Documentation/sound/oss/rme96xx b/Documentation/sound/oss/rme96xx deleted file mode 100644 index 87d7b7b65fa..00000000000 --- a/Documentation/sound/oss/rme96xx +++ /dev/null @@ -1,767 +0,0 @@ -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 deleted file mode 100644 index 6f53d407d02..00000000000 --- a/Documentation/sound/oss/solo1 +++ /dev/null @@ -1,70 +0,0 @@ -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 deleted file mode 100644 index 84dee2e0b37..00000000000 --- a/Documentation/sound/oss/sonicvibes +++ /dev/null @@ -1,81 +0,0 @@ -/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 index 32cd50478b3..eed331c738a 100644 --- a/Documentation/sound/oss/ultrasound +++ b/Documentation/sound/oss/ultrasound @@ -19,7 +19,7 @@ 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 +DSP to use DMA 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. diff --git a/Documentation/sound/oss/vwsnd b/Documentation/sound/oss/vwsnd deleted file mode 100644 index a6ea0a1df9e..00000000000 --- a/Documentation/sound/oss/vwsnd +++ /dev/null @@ -1,293 +0,0 @@ -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); - } - |
