Merge branch 'build':

Release v1.0.18a
    9a1d3353b3dda666f88fe8bdd19d267ccc108ac4
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a8f8b6f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+scripts/*.o
+scripts/docproc
+*~
+.*~
+*.orig
+*.rej
diff --git a/Documentation/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl
new file mode 100644
index 0000000..9d644f7
--- /dev/null
+++ b/Documentation/DocBook/alsa-driver-api.tmpl
@@ -0,0 +1,100 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<book>
+<?dbhtml filename="index.html">
+
+<!-- ****************************************************** -->
+<!-- Header  -->
+<!-- ****************************************************** -->
+  <bookinfo>
+    <title>The ALSA Driver API</title>
+
+    <legalnotice>
+    <para>
+    This document is free; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version. 
+    </para>
+
+    <para>
+    This document is distributed in the hope that it will be useful,
+    but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
+    implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
+    PARTICULAR PURPOSE</emphasis>. See the GNU General Public License
+    for more details.
+    </para>
+
+    <para>
+    You should have received a copy of the GNU General Public
+    License along with this program; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+    MA 02111-1307 USA
+    </para>
+    </legalnotice>
+
+  </bookinfo>
+
+  <chapter><title>Management of Cards and Devices</title>
+     <sect1><title>Card Management</title>
+!Esound/core/init.c
+     </sect1>
+     <sect1><title>Device Components</title>
+!Esound/core/device.c
+     </sect1>
+     <sect1><title>Module requests 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 Management</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/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
new file mode 100644
index 0000000..3ab5fb1
--- /dev/null
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -0,0 +1,2415 @@
+
+		Advanced Linux Sound Architecture - Driver
+		==========================================
+			    Configuration guide
+
+
+Kernel Configuration
+====================
+
+To enable ALSA support you need at least to build the kernel with
+primary sound card support (CONFIG_SOUND).  Since ALSA can emulate OSS,
+you don't have to choose any of the OSS modules.
+
+Enable "OSS API emulation" (CONFIG_SND_OSSEMUL) and both OSS mixer and
+PCM supports if you want to run OSS applications with ALSA.
+
+If you want to support the WaveTable functionality on cards such as
+SB Live! then you need to enable "Sequencer support"
+(CONFIG_SND_SEQUENCER).
+
+To make ALSA debug messages more verbose, enable the "Verbose printk"
+and "Debug" options.  To check for memory leaks, turn on "Debug memory"
+too.  "Debug detection" will add checks for the detection of cards.
+
+Please note that all the ALSA ISA drivers support the Linux isapnp API
+(if the card supports ISA PnP).  You don't need to configure the cards
+using isapnptools.
+
+
+Creating ALSA devices
+=====================
+
+This depends on your distribution, but normally you use the /dev/MAKEDEV
+script to create the necessary device nodes.  On some systems you use a
+script named 'snddevices'.
+
+
+Module parameters
+=================
+
+The user can load modules with options. If the module supports more than
+one card and you have more than one card of the same type then you can
+specify multiple values for the option separated by commas.
+
+Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
+
+  Module snd
+  ----------
+
+    The core ALSA module.  It is used by all ALSA card drivers.
+    It takes the following options which have global effects.
+
+    major	- major number for sound driver
+		- Default: 116
+    cards_limit
+		- limiting card index for auto-loading (1-8)
+		- Default: 1
+		- For auto-loading more than one card, specify this
+		  option together with snd-card-X aliases.
+    slots	- Reserve the slot index for the given driver.
+		  This option takes multiple strings.		
+		  See "Module Autoloading Support" section for details.
+  
+  Module snd-pcm-oss
+  ------------------
+
+    The PCM OSS emulation module.
+    This module takes options which change the mapping of devices.
+
+    dsp_map	- PCM device number maps assigned to the 1st OSS device.
+		- Default: 0
+    adsp_map	- PCM device number maps assigned to the 2st OSS device.
+		- Default: 1
+    nonblock_open
+		- Don't block opening busy PCM devices.  Default: 1
+
+    For example, when dsp_map=2, /dev/dsp will be mapped to PCM #2 of
+    the card #0.  Similarly, when adsp_map=0, /dev/adsp will be mapped
+    to PCM #0 of the card #0.
+    For changing the second or later card, specify the option with
+    commas, such like "dsp_map=0,1".
+
+    nonblock_open option is used to change the behavior of the PCM
+    regarding opening the device.  When this option is non-zero,
+    opening a busy OSS PCM device won't be blocked but return
+    immediately with EAGAIN (just like O_NONBLOCK flag).
+    
+  Module snd-rawmidi
+  ------------------
+
+    This module takes options which change the mapping of devices.
+    similar to those of the snd-pcm-oss module.
+
+    midi_map	- MIDI device number maps assigned to the 1st OSS device.
+		- Default: 0
+    amidi_map	- MIDI device number maps assigned to the 2st OSS device.
+		- Default: 1
+
+  Common parameters for top sound card modules
+  --------------------------------------------
+
+    Each of top level sound card module takes the following options.
+
+    index	- index (slot #) of sound card
+		- Values: 0 through 31 or negative
+		- If nonnegative, assign that index number
+                - if negative, interpret as a bitmask of permissible
+		  indices; the first free permitted index is assigned
+		- Default: -1
+    id		- card ID (identifier or name)
+		- Can be up to 15 characters long
+		- Default: the card type
+		- A directory by this name is created under /proc/asound/
+		  containing information about the card
+		- This ID can be used instead of the index number in
+		  identifying the card
+    enable  	- enable card
+		- Default: enabled, for PCI and ISA PnP cards
+
+  Module snd-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.
+
+    clockfreq   - Clock frequency for AD1816A chip (default = 0, 33000Hz)
+    
+    This module supports multiple cards, autoprobe and PnP.
+    
+  Module snd-ad1848
+  -----------------
+
+    Module for sound cards based on AD1848/AD1847/CS4248 ISA chips.
+
+    port	- port # for AD1848 chip
+    irq		- IRQ # for AD1848  chip
+    dma1	- DMA # for AD1848 chip (0,1,3)
+    
+    This module supports multiple cards.  It does not support autoprobe
+    thus main port must be specified!!! Other ports are optional.
+    
+    The power-management is supported.
+
+  Module snd-ad1889
+  -----------------
+
+    Module for Analog Devices AD1889 chips.
+
+    ac97_quirk  - AC'97 workaround for strange hardware
+                  See the description of intel8x0 module for details.
+
+    This module supports multiple cards.
+
+  Module snd-ali5451
+  ------------------
+
+    Module for ALi M5451 PCI chip.
+
+    pcm_channels    - Number of hardware channels assigned for PCM
+    spdif           - Support SPDIF I/O
+    		    - Default: disabled
+
+    This module supports one chip and autoprobe.
+
+    The power-management is supported.
+
+  Module snd-als100
+  -----------------
+
+    Module for sound cards based on Avance Logic ALS100/ALS120 ISA chips.
+
+    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
+  ------------------
+
+    Module for sound cards based on Avance Logic ALS4000 PCI chip.
+
+    joystick_port - port # for legacy joystick support.
+                    0 = disabled (default), 1 = auto-detect
+    
+    This module supports multiple cards, autoprobe and PnP.
+
+    The power-management is supported.
+
+  Module snd-atiixp
+  -----------------
+
+    Module for ATI IXP 150/200/250/400 AC97 controllers.
+
+    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.
+
+    ATI IXP has two different methods to control SPDIF output.  One is
+    over AC-link and another is over the "direct" SPDIF output.  The
+    implementation depends on the motherboard, and you'll need to
+    choose the correct one via spdif_aclink module option.
+
+    The power-management is supported.
+
+  Module snd-atiixp-modem
+  -----------------------
+
+    Module for ATI IXP 150/200/250 AC97 modem controllers.
+
+    This module supports one card and autoprobe.
+
+    Note: The default index value of this module is -2, i.e. the first
+          slot is excluded.
+
+    The power-management is supported.
+
+  Module snd-au8810, snd-au8820, snd-au8830
+  -----------------------------------------
+
+    Module for Aureal Vortex, Vortex2 and Advantage device.
+
+    pcifix	- Control PCI workarounds
+		  0 = Disable all workarounds
+		  1 = Force the PCI latency of the Aureal card to 0xff
+		  2 = Force the Extend PCI#2 Internal Master for Efficient
+		      Handling of Dummy Requests on the VIA KT133 AGP Bridge
+		  3 = Force both settings
+		  255 = Autodetect what is required (default)
+
+    This module supports all ADB PCM channels, ac97 mixer, SPDIF, hardware
+    EQ, mpu401, gameport. A3D and wavetable support are still in development.
+    Development and reverse engineering work is being coordinated at
+    http://savannah.nongnu.org/projects/openvortex/
+    SPDIF output has a copy of the AC97 codec output, unless you use the
+    "spdif" pcm device, which allows raw data passthru.
+    The hardware EQ hardware and SPDIF is only present in the Vortex2 and 
+    Advantage.
+
+    Note: Some ALSA mixer applications don't handle the SPDIF sample rate 
+           control correctly. If you have problems regarding this, try
+           another ALSA compliant mixer (alsamixer works).
+
+  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).
+
+    This module supports multiple cards, PnP and autoprobe.
+    
+    The power-management is supported.
+
+  Module snd-azt3328
+  ------------------
+
+    Module for sound cards based on Aztech AZF3328 PCI chip.
+
+    joystick	- Enable joystick (default off)
+
+    This module supports multiple cards.
+
+  Module snd-bt87x
+  ----------------
+
+    Module for video cards based on Bt87x chips.
+
+    digital_rate - Override the default digital rate (Hz)
+    load_all	- Load the driver even if the card model isn't known
+
+    This module supports multiple cards.
+
+    Note: The default index value of this module is -2, i.e. the first
+          slot is excluded.
+
+  Module snd-ca0106
+  -----------------
+
+    Module for Creative Audigy LS and SB Live 24bit
+
+    This module supports multiple cards.
+
+
+  Module snd-cmi8330
+  ------------------
+
+    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)
+    sbport	- port # for CMI8330 chip (SB16)
+    sbirq	- IRQ # for CMI8330 chip (SB16)
+    sbdma8	- 8bit DMA # for CMI8330 chip (SB16)
+    sbdma16	- 16bit DMA # for CMI8330 chip (SB16)
+
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
+
+  Module snd-cmipci
+  -----------------
+
+    Module for C-Media CMI8338/8738/8768/8770 PCI sound cards.
+
+    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)
+
+    This module supports autoprobe and multiple cards.
+    
+    The power-management is supported.
+
+  Module snd-cs4231
+  -----------------
+
+    Module for sound cards based on CS4231 ISA chips.
+
+    port	- port # for CS4231 chip
+    mpu_port	- port # for MPU-401 UART (optional), -1 = disable
+    irq		- IRQ # for CS4231 chip
+    mpu_irq	- IRQ # for MPU-401 UART
+    dma1	- first DMA # for CS4231 chip
+    dma2	- second DMA # for CS4231 chip
+    
+    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-cs4232
+  -----------------
+
+    Module for sound cards based on CS4232/CS4232A ISA chips.
+
+    isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
+
+    with isapnp=0, the following options are available:
+
+    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
+    
+    This module supports multiple cards. This module does not support autoprobe
+    (if ISA PnP is not used) 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.
+
+    isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
+
+    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)
+    mpu_port	- port # for MPU-401 UART (PnP setup - 0x300), -1 = disable
+    fm_port	- FM port # for CS4236 chip (PnP setup - 0x388), -1 = disable
+    irq		- IRQ # for CS4236 chip (5,7,9,11,12,15)
+    mpu_irq	- IRQ # for MPU-401 UART (9,11,12,15)
+    dma1	- first DMA # for CS4236 chip (0,1,3)
+    dma2	- second DMA # for CS4236 chip (0,1,3), -1 = disable
+    
+    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
+    specified!!! Other ports are optional.
+
+    The power-management is supported.
+
+  Module snd-cs4281
+  -----------------
+
+    Module for Cirrus Logic CS4281 soundchip.
+
+    dual_codec	- Secondary codec ID (0 = disable, default)
+
+    This module supports multiple cards.
+
+    The power-management is supported.
+
+  Module snd-cs46xx
+  -----------------
+
+    Module for PCI sound cards based on CS4610/CS4612/CS4614/CS4615/CS4622/
+				       CS4624/CS4630/CS4280 PCI chips.
+
+    external_amp     - Force to enable external amplifier.
+    thinkpad         - Force to enable Thinkpad's CLKRUN control.
+    mmap_valid       - Support OSS mmap mode (default = 0).
+
+    This module supports multiple cards and autoprobe.
+    Usually external amp and CLKRUN controls are detected automatically
+    from PCI sub vendor/device ids.  If they don't work, give the options
+    above explicitly.
+
+    The power-management is supported.
+
+  Module snd-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-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)
+
+    This module supports multiple cards.  This module is enabled only with
+    ISA PnP support.
+
+    The power-management is supported.
+
+  Module snd-dummy
+  ----------------
+
+    Module for the dummy sound card. This "card" doesn't do any output
+    or input, but you may use this module for any application which
+    requires a sound card (like RealPlayer).
+
+    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
+  ------------------
+
+    Module for EMU10K1/EMU10k2 based PCI sound cards.
+			* Sound Blaster Live!
+			* Sound Blaster PCI 512
+			* Emu APS (partially supported)
+			* Sound Blaster Audigy
+
+    extin   - bitmap of available external inputs for FX8010 (see bellow)
+    extout  - bitmap of available external outputs for FX8010 (see bellow)
+    seq_ports - allocated sequencer ports (4 by default)
+    max_synth_voices - limit of voices used for wavetable (64 by default)
+    max_buffer_size  - specifies the maximum size of wavetable/pcm buffers
+                       given in MB unit.  Default value is 128.
+    enable_ir - enable IR
+
+    This module supports multiple cards and autoprobe.
+
+    Input & Output configurations 			[extin/extout]
+	* Creative Card wo/Digital out			[0x0003/0x1f03]
+	* Creative Card w/Digital out			[0x0003/0x1f0f]
+	* Creative Card w/Digital CD in			[0x000f/0x1f0f]
+	* Creative Card wo/Digital out + LiveDrive	[0x3fc3/0x1fc3]
+	* Creative Card w/Digital out + LiveDrive	[0x3fc3/0x1fcf]
+	* Creative Card w/Digital CD in + LiveDrive	[0x3fcf/0x1fcf]
+	* Creative Card wo/Digital out + Digital I/O 2  [0x0fc3/0x1f0f]
+	* Creative Card w/Digital out + Digital I/O 2	[0x0fc3/0x1f0f]
+	* Creative Card w/Digital CD in + Digital I/O 2	[0x0fcf/0x1f0f]
+        * Creative Card 5.1/w Digital out + LiveDrive	[0x3fc3/0x1fff]
+	* Creative Card 5.1 (c) 2003			[0x3fc3/0x7cff]
+        * Creative Card all ins and outs		[0x3fff/0x7fff]
+    
+    The power-management is supported.
+
+  Module snd-emu10k1x
+  -------------------
+
+    Module for Creative Emu10k1X (SB Live Dell OEM version)
+
+    This module supports multiple cards.
+
+  Module snd-ens1370
+  ------------------
+
+    Module for Ensoniq AudioPCI ES1370 PCI sound cards.
+			* SoundBlaster PCI 64
+			* SoundBlaster PCI 128
+
+    joystick		- Enable joystick (default off)
+
+    This module supports multiple cards and autoprobe.
+    
+    The power-management is supported.
+
+  Module snd-ens1371
+  ------------------
+
+    Module for Ensoniq AudioPCI ES1371 PCI sound cards.
+			* SoundBlaster PCI 64
+			* SoundBlaster PCI 128
+			* SoundBlaster Vibra PCI
+
+    joystick_port	- port # for joystick (0x200,0x208,0x210,0x218),
+			  0 = disable (default), 1 = auto-detect
+
+    This module supports multiple cards and autoprobe.
+    
+    The power-management is supported.
+
+  Module snd-es968
+  ----------------
+
+    Module for sound cards based on ESS ES968 chip (PnP only).
+
+    This module supports multiple cards, PnP and autoprobe.
+    
+    The power-management is supported.
+
+  Module snd-es1688
+  -----------------
+
+    Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
+
+    port	- port # for ES-1688 chip (0x220,0x240,0x260)
+    mpu_port	- port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
+    irq		- IRQ # for ES-1688 chip (5,7,9,10)
+    mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
+    dma8	- DMA # for ES-1688 chip (0,1,3)
+
+    This module supports multiple cards and autoprobe (without MPU-401 port).
+
+  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)
+
+    This module supports multiple cards, ISA PnP and autoprobe (without MPU-401
+    port if native ISA PnP routines are not used).
+    When dma2 is equal with dma1, the driver works as half-duplex.
+
+    The power-management is supported.
+
+  Module snd-es1938
+  -----------------
+
+    Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips.
+
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
+
+  Module snd-es1968
+  -----------------
+
+    Module for sound cards based on ESS Maestro-1/2/2E (ES1968/ES1978) chips.
+
+    total_bufsize	- total buffer size in kB (1-4096kB)
+    pcm_substreams_p	- playback channels (1-8, default=2)
+    pcm_substreams_c	- capture channels (1-8, default=0)
+    clock		- clock (0 = auto-detection)
+    use_pm		- support the power-management (0 = off, 1 = on,
+			  2 = auto (default))
+    enable_mpu		- enable MPU401 (0 = off, 1 = on, 2 = auto (default))
+    joystick		- enable joystick (default off)       
+
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
+
+  Module snd-fm801
+  ----------------
+
+    Module for ForteMedia FM801 based PCI sound cards.
+
+    tea575x_tuner       - Enable TEA575x tuner
+                          - 1 = MediaForte 256-PCS
+                          - 2 = MediaForte 256-PCPR
+                          - 3 = MediaForte 64-PCR  
+                          - High 16-bits are video (radio) device number + 1
+                          - example: 0x10002 (MediaForte 256-PCPR, device 1)
+
+    This module supports multiple cards and autoprobe.
+    
+    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
+  ---------------------
+
+    Module for Gravis UltraSound Classic sound card.
+
+    port	- port # for GF1 chip (0x220,0x230,0x240,0x250,0x260)
+    irq		- IRQ # for GF1 chip (3,5,9,11,12,15)
+    dma1	- DMA # for GF1 chip (1,3,5,6,7)
+    dma2	- DMA # for GF1 chip (1,3,5,6,7,-1=disable)
+    joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V)
+    voices	- GF1 voices limit (14-32)
+    pcm_voices	- reserved PCM voices
+
+    This module supports multiple cards and autoprobe.
+
+  Module snd-gusextreme
+  ---------------------
+
+    Module for Gravis UltraSound Extreme (Synergy ViperMax) sound card.
+
+    port	- port # for ES-1688 chip (0x220,0x230,0x240,0x250,0x260)
+    gf1_port	- port # for GF1 chip (0x210,0x220,0x230,0x240,0x250,0x260,0x270)
+    mpu_port	- port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable
+    irq		- IRQ # for ES-1688 chip (5,7,9,10)
+    gf1_irq	- IRQ # for GF1 chip (3,5,9,11,12,15)
+    mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
+    dma8	- DMA # for ES-1688 chip (0,1,3)
+    dma1	- DMA # for GF1 chip (1,3,5,6,7)
+    joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V)
+    voices	- GF1 voices limit (14-32)
+    pcm_voices	- reserved PCM voices
+
+    This module supports multiple cards and autoprobe (without MPU-401 port).
+
+  Module snd-gusmax
+  -----------------
+
+    Module for Gravis UltraSound MAX sound card.
+
+    port	- port # for GF1 chip (0x220,0x230,0x240,0x250,0x260)
+    irq		- IRQ # for GF1 chip (3,5,9,11,12,15)
+    dma1	- DMA # for GF1 chip (1,3,5,6,7)
+    dma2	- DMA # for GF1 chip (1,3,5,6,7,-1=disable)
+    joystick_dac - 0 to 31, (0.59V-4.52V or 0.389V-2.98V)
+    voices	- GF1 voices limit (14-32)
+    pcm_voices	- reserved PCM voices
+
+    This module supports multiple cards and autoprobe.
+    
+  Module snd-hda-intel
+  --------------------
+
+    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 = use LPIB, 2 = POSBUF)
+    probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
+    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.
+    
+    [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 timtout (in second, 0 =
+		disable)
+    power_save_controller - Reset HD-audio controller in power-saving mode
+		(default = on)
+
+    This module supports multiple cards and autoprobe.
+    
+    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 (ASUS Mobo)
+	  asus-w1v	ASUS W1V
+	  asus-dig	ASUS with SPDIF out
+	  asus-dig2	ASUS with SPDIF out (using GPIO2)
+	  uniwill	3-jack
+	  fujitsu	Fujitsu Laptops (Pi1536)
+	  F1734		2-jack
+	  lg		LG laptop (m1 express dual)
+	  lg-lw		LG LW20/LW25 laptop
+	  tcl		TCL S700
+	  clevo		Clevo laptops (m520G, m665n)
+	  medion	Medion Rim 2150
+	  test		for testing/debugging purpose, almost all controls can be
+			adjusted.  Appearing only when compiled with
+			$CONFIG_SND_DEBUG=y
+	  auto		auto-config reading BIOS (default)
+
+	ALC260
+	  hp		HP machines
+	  hp-3013	HP machines (3013-variant)
+	  hp-dc7600	HP DC7600
+	  fujitsu	Fujitsu S7020
+	  acer		Acer TravelMate
+	  will		Will laptops (PB V7900)
+	  replacer	Replacer 672V
+	  basic		fixed pin assignment (old default model)
+	  test		for testing/debugging purpose, almost all controls can
+			adjusted.  Appearing only when compiled with
+			$CONFIG_SND_DEBUG=y
+	  auto		auto-config reading BIOS (default)
+
+	ALC262
+	  fujitsu	Fujitsu Laptop
+	  hp-bpc	HP xw4400/6400/8400/9400 laptops
+	  hp-bpc-d7000	HP BPC D7000
+	  hp-tc-t5735	HP Thin Client T5735
+	  hp-rp5700	HP RP5700
+	  benq		Benq ED8
+	  benq-t31	Benq T31
+	  hippo		Hippo (ATI) with jack detection, Sony UX-90s
+	  hippo_1	Hippo (Benq) with jack detection
+	  sony-assamd	Sony ASSAMD
+	  toshiba-s06	Toshiba S06
+	  toshiba-rx1	Toshiba RX1
+	  ultra		Samsung Q1 Ultra Vista model
+	  lenovo-3000	Lenovo 3000 y410
+	  nec		NEC Versa S9100
+	  basic		fixed pin assignment w/o SPDIF
+	  auto		auto-config reading BIOS (default)
+
+	ALC267/268
+	  quanta-il1	Quanta IL1 mini-notebook
+	  3stack	3-stack model
+	  toshiba	Toshiba A205
+	  acer		Acer laptops
+	  acer-dmic	Acer laptops with digital-mic
+	  acer-aspire	Acer Aspire One
+	  dell		Dell OEM laptops (Vostro 1200)
+	  zepto		Zepto laptops
+	  test		for testing/debugging purpose, almost all controls can
+			adjusted.  Appearing only when compiled with
+			$CONFIG_SND_DEBUG=y
+	  auto		auto-config reading BIOS (default)
+
+	ALC269
+	  basic		Basic preset
+	  quanta	Quanta FL1
+	  eeepc-p703	ASUS Eeepc P703 P900A
+	  eeepc-p901	ASUS Eeepc P901 S101
+	  fujitsu	FSC Amilo
+	  auto		auto-config reading BIOS (default)
+
+	ALC662/663
+	  3stack-dig	3-stack (2-channel) with SPDIF
+	  3stack-6ch	 3-stack (6-channel)
+	  3stack-6ch-dig 3-stack (6-channel) with SPDIF
+	  6stack-dig	 6-stack with SPDIF
+	  lenovo-101e	 Lenovo laptop
+	  eeepc-p701	ASUS Eeepc P701
+	  eeepc-ep20	ASUS Eeepc EP20
+	  ecs		ECS/Foxconn mobo
+	  m51va		ASUS M51VA
+	  g71v		ASUS G71V
+	  h13		ASUS H13
+	  g50v		ASUS G50V
+	  asus-mode1	ASUS
+	  asus-mode2	ASUS
+	  asus-mode3	ASUS
+	  asus-mode4	ASUS
+	  asus-mode5	ASUS
+	  asus-mode6	ASUS
+	  auto		auto-config reading BIOS (default)
+
+	ALC882/885
+	  3stack-dig	3-jack with SPDIF I/O
+	  6stack-dig	6-jack digital with SPDIF I/O
+	  arima		Arima W820Di1
+	  targa		Targa T8, MSI-1049 T8
+	  asus-a7j	ASUS A7J
+	  asus-a7m	ASUS A7M
+	  macpro	MacPro support
+	  mbp3		Macbook Pro rev3
+	  imac24	iMac 24'' with jack detection
+	  w2jc		ASUS W2JC
+	  auto		auto-config reading BIOS (default)
+
+	ALC883/888
+	  3stack-dig	3-jack with SPDIF I/O
+	  6stack-dig	6-jack digital with SPDIF I/O
+	  3stack-6ch    3-jack 6-channel
+	  3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
+	  6stack-dig-demo  6-jack digital for Intel demo board
+	  acer		Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
+	  acer-aspire	Acer Aspire 9810
+	  medion	Medion Laptops
+	  medion-md2	Medion MD2
+	  targa-dig	Targa/MSI
+	  targa-2ch-dig	Targs/MSI with 2-channel
+	  laptop-eapd   3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
+	  lenovo-101e	Lenovo 101E
+	  lenovo-nb0763	Lenovo NB0763
+	  lenovo-ms7195-dig Lenovo MS7195
+	  lenovo-sky	Lenovo Sky
+	  haier-w66	Haier W66
+	  3stack-hp	HP machines with 3stack (Lucknow, Samba boards)
+	  6stack-dell	Dell machines with 6stack (Inspiron 530)
+	  mitac		Mitac 8252D
+	  clevo-m720	Clevo M720 laptop series
+	  fujitsu-pi2515 Fujitsu AMILO Pi2515
+	  3stack-6ch-intel Intel DG33* boards
+	  auto		auto-config reading BIOS (default)
+
+	ALC861/660
+	  3stack	3-jack
+	  3stack-dig	3-jack with SPDIF I/O
+	  6stack-dig	6-jack with SPDIF I/O
+	  3stack-660	3-jack (for ALC660)
+	  uniwill-m31	Uniwill M31 laptop
+	  toshiba	Toshiba laptop support
+	  asus		Asus laptop support
+	  asus-laptop	ASUS F2/F3 laptops
+	  auto		auto-config reading BIOS (default)
+
+	ALC861VD/660VD
+	  3stack	3-jack
+	  3stack-dig	3-jack with SPDIF OUT
+	  6stack-dig	6-jack with SPDIF OUT
+	  3stack-660	3-jack (for ALC660VD)
+	  3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
+	  lenovo	Lenovo 3000 C200
+	  dallas	Dallas laptops
+	  hp		HP TX1000
+	  asus-v1s	ASUS V1Sn
+	  auto		auto-config reading BIOS (default)
+
+	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 (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
+
+	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		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 (Samsung R65, ASUS A6J)
+	  laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
+	  ultra		2-channel with EAPD (Samsung Ultra tablet PC)
+
+	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
+	  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
+
+	STAC9200
+	  ref		Reference board
+	  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	Gateway laptops with EAPD control
+	  panasonic	Panasonic CF-74
+
+	STAC9205/9254
+	  ref		Reference board
+	  dell-m42	Dell (unknown)
+	  dell-m43	Dell Precision
+	  dell-m44	Dell Inspiron
+
+	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)
+	  dell-d81	Dell (unknown)
+	  dell-d82	Dell (unknown)
+	  dell-m81	Dell (unknown)
+	  dell-m82	Dell XPS M1210
+
+	STAC9202/9250/9251
+	  ref		Reference board, base config
+	  m2-2		Some Gateway MX series laptops
+	  m6		Some Gateway NX series laptops
+	  pa6		Gateway NX860 series
+
+	STAC9227/9228/9229/927x
+	  ref		Reference board
+	  3stack	D965 3stack
+	  5stack	D965 5stack + SPDIF
+	  dell-3stack	Dell Dimension E520
+	  dell-bios	Fixes with Dell BIOS setup
+
+	STAC92HD71B*
+	  ref		Reference board
+	  dell-m4-1	Dell desktops
+	  dell-m4-2	Dell desktops
+
+	STAC92HD73*
+	  ref		Reference board
+	  dell-m6	Dell desktops
+
+	STAC9872
+	  vaio		Setup for VAIO FE550G/SZ110
+	  vaio-ar Setup for VAIO AR
+
+    The model name "genric" 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
+    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_LPIB register is more accurate than the
+	    position buffer.)
+
+    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 hardwares, 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
+  ---------------
+
+    Module for RME Hammerfall DSP audio interface(s)
+
+    This module supports multiple cards.
+
+    Note: The firmware data can be automatically loaded via hotplug
+          when CONFIG_FW_LOADER is set.  Otherwise, you need to load
+          the firmware via hdsploader utility included in alsa-tools
+          package.
+          The firmware data is found in alsa-firmware package.
+
+    Note: snd-page-alloc module does the job which snd-hammerfall-mem
+          module did formerly.  It will allocate the buffers in advance
+          when any HDSP cards are found.  To make the buffer
+          allocation sure, load snd-page-alloc module in the early
+          stage of boot sequence.  See "Early Buffer Allocation"
+	  section.
+
+  Module snd-hdspm
+  ----------------
+
+    Module for RME HDSP MADI board.
+
+    precise_ptr		- Enable precise pointer, or disable.
+    line_outs_monitor	- Send playback streams to analog outs by default.
+    enable_monitor	- Enable Analog Out on Channel 63/64 by default.
+
+    See hdspm.txt for details.
+
+  Module snd-hifier
+  -----------------
+
+    Module for the MediaTek/TempoTec HiFier Fantasia sound card.
+
+    This module supports autoprobe and multiple cards.
+
+  Module snd-ice1712
+  ------------------
+
+    Module for Envy24 (ICE1712) based PCI sound cards.
+			* MidiMan M Audio Delta 1010
+			* MidiMan M Audio Delta 1010LT
+			* MidiMan M Audio Delta DiO 2496
+			* MidiMan M Audio Delta 66
+			* MidiMan M Audio Delta 44
+			* MidiMan M Audio Delta 410
+			* MidiMan M Audio Audiophile 2496
+                        * TerraTec EWS 88MT
+                        * TerraTec EWS 88D
+                        * TerraTec EWX 24/96
+                        * TerraTec DMX 6Fire
+			* TerraTec Phase 88
+                        * Hoontech SoundTrack DSP 24
+                        * Hoontech SoundTrack DSP 24 Value
+                        * Hoontech SoundTrack DSP 24 Media 7.1
+			* 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,
+		  delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d,
+		  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 transceiver)
+                     in msec resolution, default value is 500 (0.5 sec)
+
+    This module supports multiple cards and autoprobe. Note: The consumer part
+    is not used with all Envy24 based cards (for example in the MidiMan Delta
+    serie).
+
+    Note: The supported board is detected by reading EEPROM or PCI
+	  SSID (if EEPROM isn't available).  You can override the
+	  model by passing "model" module option in case that the
+	  driver isn't configured properly or you want to try another
+	  type for testing.
+
+  Module snd-ice1724
+  ------------------
+
+    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
+			* TerraTec Aureon 7.1 Universe
+			* 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 
+			* Chaintech ZNF3-150
+			* Chaintech ZNF3-250
+			* Chaintech 9CJS
+			* Chaintech AV-710
+			* Shuttle SN25P
+			* Onkyo SE-90PCI
+			* Onkyo SE-200PCI
+			* ESI Juli@
+			* Hercules Fortissimo IV
+			* EGO-SYS WaveTerminal 192M
+
+    model       - Use the given board model, one of the following:
+		  revo51, revo71, amp2000, prodigy71, prodigy71lt,
+		  prodigy71xt, prodigy71hifi, prodigyhd2, prodigy192,
+		  juli, aureon51, aureon71, universe, ap192, k8x800,
+		  phase22, phase28, ms300, av710, se200pci, se90pci,
+		  fortissimo4, sn25p, WT192M
+
+    This module supports multiple cards and autoprobe.
+
+    Note: The supported board is detected by reading EEPROM or PCI
+	  SSID (if EEPROM isn't available).  You can override the
+	  model by passing "model" module option in case that the
+	  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, NForce3, MCP04, CK804
+				 CK8, CK8S, MCP501
+			* AMD AMD768, AMD8111
+			* ALi m5455
+
+    ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
+    ac97_quirk    - AC'97 workaround for strange hardware
+		    See "AC97 Quirk Option" section below.
+    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
+		    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.
+
+    Note: the latest driver supports auto-detection of chip clock.
+    if you still encounter too fast playback, specify the clock
+    explicitly via the module option "ac97_clock=41194".
+
+    Joystick/MIDI ports are not supported by this driver.  If your
+    motherboard has these devices, use the ns558 or snd-mpu401
+    modules, respectively.
+
+    The power-management is supported.
+    
+  Module snd-intel8x0m
+  --------------------
+
+    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)
+
+    This module supports one card and autoprobe.
+
+    Note: The default index value of this module is -2, i.e. the first
+          slot is excluded.
+
+    The power-management is supported.
+
+  Module snd-interwave
+  --------------------
+
+    Module for Gravis UltraSound PnP, Dynasonic 3-D/Pro, STB Sound Rage 32
+    and other sound cards based on AMD InterWave (tm) chip.
+  
+    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.
+
+  Module snd-interwave-stb
+  ------------------------
+
+    Module for UltraSound 32-Pro (sound card from STB used by Compaq)
+    and other sound cards based on AMD InterWave (tm) chip with TEA6330T
+    circuit for extended control of bass, treble and master volume.
+  
+    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-korg1212
+  -------------------
+
+    Module for Korg 1212 IO PCI card
+
+    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-maestro3
+  -------------------
+
+    Module for Allegro/Maestro3 chips
+
+    external_amp     - enable external amp (enabled by default)
+    amp_gpio         - GPIO pin number for external amp (0-15) or
+                       -1 for default pin (8 for allegro, 1 for
+                       others) 
+
+    This module supports autoprobe and multiple chips.
+
+    Note: the binding of amplifier is dependent on hardware.
+    If there is no sound even though all channels are unmuted, try to
+    specify other gpio connection via amp_gpio option. 
+    For example, a Panasonic notebook might need "amp_gpio=0x0d"
+    option.
+
+    The power-management is supported.
+
+  Module snd-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
+  -----------------
+
+    Module for Digigram miXart8 sound cards.
+
+    This module supports multiple cards.
+    Note: One miXart8 board will be represented as 4 alsa cards.
+          See MIXART.txt for details.
+
+    When the driver is compiled as a module and the hotplug firmware
+    is supported, the firmware data is loaded via hotplug automatically.
+    Install the necessary firmware files in alsa-firmware package.
+    When no hotplug fw loader is available, you need to load the
+    firmware via mixartloader utility in alsa-tools package.
+
+  Module snd-mona
+  ---------------
+
+    Module for Echoaudio Mona
+
+    This module supports multiple cards.
+    The driver requires the firmware loader support on kernel.
+
+  Module snd-mpu401
+  -----------------
+
+    Module for MPU-401 UART devices.
+
+    port	- port number or -1 (disable)
+    irq		- IRQ number or -1 (disable)
+    pnp		- PnP detection - 0 = disable, 1 = enable (default)
+
+    This module supports multiple devices and PnP.
+    
+  Module snd-mtpav
+  ----------------
+
+    Module for MOTU MidiTimePiece AV multiport MIDI (on the parallel
+    port).
+
+    port	- I/O port # for MTPAV (0x378,0x278, default=0x378)
+    irq		- IRQ # for MTPAV (7,5, default=7)
+    hwports	- number of supported hardware ports, default=8.
+    
+    Module supports only 1 card.  This module has no enable option.
+
+  Module snd-mts64
+  ----------------
+
+    Module for Ego Systems (ESI) Miditerminal 4140
+
+    This module supports multiple devices.
+    Requires parport (CONFIG_PARPORT).
+
+  Module snd-nm256
+  ----------------
+
+    Module for NeoMagic NM256AV/ZX chips
+
+    playback_bufsize - max playback frame size in kB (4-128kB)
+    capture_bufsize  - max capture frame size in kB (4-128kB)
+    force_ac97       - 0 or 1 (disabled by default)
+    buffer_top       - specify buffer top address
+    use_cache        - 0 or 1 (disabled by default)
+    vaio_hack        - alias buffer_top=0x25a800
+    reset_workaround - enable AC97 RESET workaround for some laptops
+    reset_workaround2 - enable extended AC97 RESET workaround for some
+		      other laptops
+
+    This module supports one chip and autoprobe.
+
+    The power-management is supported.
+
+    Note: on some notebooks the buffer address cannot be detected
+    automatically, or causes hang-up during initialization.
+    In such a case, specify the buffer top address explicitly via
+    the buffer_top option.
+    For example,
+      Sony F250: buffer_top=0x25a800
+      Sony F270: buffer_top=0x272800
+    The driver supports only ac97 codec.  It's possible to force
+    to initialize/use ac97 although it's not detected.  In such a
+    case, use force_ac97=1 option - but *NO* guarantee whether it
+    works!
+
+    Note: The NM256 chip can be linked internally with non-AC97
+    codecs.  This driver supports only the AC97 codec, and won't work
+    with machines with other (most likely CS423x or OPL3SAx) chips,
+    even though the device is detected in lspci.  In such a case, try
+    other drivers, e.g. snd-cs4232 or snd-opl3sa2.  Some has ISA-PnP
+    but some doesn't have ISA PnP.  You'll need to specify isapnp=0
+    and proper hardware parameters in the case without ISA PnP.
+
+    Note: some laptops need a workaround for AC97 RESET.  For the
+    known hardware like Dell Latitude LS and Sony PCG-F305, this
+    workaround is enabled automatically.  For other laptops with a
+    hard freeze, you can try reset_workaround=1 option.
+
+    Note: Dell Latitude CSx laptops have another problem regarding
+    AC97 RESET.  On these laptops, reset_workaround2 option is
+    turned on as default.  This option is worth to try if the
+    previous reset_workaround option doesn't help.
+
+    Note: This driver is really crappy.  It's a porting from the
+    OSS driver, which is a result of black-magic reverse engineering.
+    The detection of codec will fail if the driver is loaded *after*
+    X-server as described above.  You might be able to force to load
+    the module, but it may result in hang-up.   Hence, make sure that
+    you load this module *before* X if you encounter this kind of
+    problem.
+
+  Module snd-opl3sa2
+  ------------------
+
+    Module for Yamaha OPL3-SA2/SA3 sound cards.
+
+    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)
+    midi_port	- port # for MPU-401 UART (0x300,0x330), -1 = disable
+    fm_port	- FM port # for OPL3-SA chip (0x388), -1 = disable
+    irq		- IRQ # for OPL3-SA chip (5,7,9,10)
+    dma1	- first DMA # for Yamaha OPL3-SA chip (0,1,3)
+    dma2	- second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable
+    
+    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!!!
+    
+    The power-management is supported.
+
+  Module snd-opti92x-ad1848
+  -------------------------
+
+    Module for sound cards based on OPTi 82c92x and Analog Devices AD1848 chips.
+    Module works with OAK Mozart cards as well.
+    
+    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)
+    irq       - IRQ # for WSS chip (5,7,9,10,11)
+    mpu_irq   - IRQ # for MPU-401 UART (5,7,9,10)
+    dma1      - first DMA # for WSS chip (0,1,3)
+
+    This module supports only one card, autoprobe and PnP.
+
+  Module snd-opti92x-cs4231
+  -------------------------
+
+    Module for sound cards based on OPTi 82c92x and Crystal CS4231 chips.
+    
+    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)
+    irq       - IRQ # for WSS chip (5,7,9,10,11)
+    mpu_irq   - IRQ # for MPU-401 UART (5,7,9,10)
+    dma1      - first DMA # for WSS chip (0,1,3)
+    dma2      - second DMA # for WSS chip (0,1,3)
+
+    This module supports only one card, autoprobe and PnP.
+
+  Module snd-opti93x
+  ------------------
+
+    Module for sound cards based on OPTi 82c93x chips.
+    
+    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)
+    irq       - IRQ # for WSS chip (5,7,9,10,11)
+    mpu_irq   - IRQ # for MPU-401 UART (5,7,9,10)
+    dma1      - first DMA # for WSS chip (0,1,3)
+    dma2      - second DMA # for WSS chip (0,1,3)
+
+    This module supports only one card, autoprobe and PnP.
+
+  Module snd-oxygen
+  -----------------
+
+    Module for sound cards based on the C-Media CMI8788 chip:
+    * Asound A-8788
+    * AuzenTech X-Meridian
+    * Bgears b-Enspirer
+    * Club3D Theatron DTS
+    * HT-Omega Claro
+    * Razer Barracuda AC-1
+    * Sondigo Inferno
+
+    This module supports autoprobe and multiple cards.
+
+  Module snd-pcsp
+  -----------------
+
+    Module for internal PC-Speaker.
+
+    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
+  ----------------
+
+    Module for Digigram PCXHR boards
+
+    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)
+  ---------------------------------
+
+    Module for PowerMac, iMac and iBook on-board soundchips
+
+    enable_beep     - enable beep using PCM (enabled as default)
+
+    Module supports autoprobe a chip.
+
+    Note: the driver may have problems regarding endianess.
+
+    The power-management is supported.
+
+  Module snd-pxa2xx-ac97 (on arm only)
+  ------------------------------------
+
+    Module for AC97 driver for the Intel PXA2xx chip
+
+    For ARM architecture only.
+
+    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
+  ----------------
+
+    Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, 
+    Prodif96 and Prodif Gold) sound cards.
+
+    This module supports multiple cards.
+
+  Module snd-rme96
+  ----------------
+
+    Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards.
+
+    This module supports multiple cards.
+
+  Module snd-rme9652
+  ------------------
+
+    Module for RME Digi9652 (Hammerfall, Hammerfall-Light) sound cards.
+
+    precise_ptr	- Enable precise pointer (doesn't work reliably).
+		  (default = 0)
+
+    This module supports multiple cards.
+
+    Note: snd-page-alloc module does the job which snd-hammerfall-mem
+          module did formerly.  It will allocate the buffers in advance
+          when any RME9652 cards are found.  To make the buffer
+          allocation sure, load snd-page-alloc module in the early
+          stage of boot sequence.  See "Early Buffer Allocation"
+	  section.
+
+  Module snd-sa11xx-uda1341 (on arm only)
+  ---------------------------------------
+
+    Module for Philips UDA1341TS on Compaq iPAQ H3600 sound card.
+
+    Module supports only one card.
+    Module has no enable and index options.
+
+    The power-management is supported.
+
+  Module snd-sb8
+  --------------
+
+    Module for 8-bit SoundBlaster cards: SoundBlaster 1.0,
+					 SoundBlaster 2.0,
+					 SoundBlaster Pro
+
+    port	- port # for SB DSP chip (0x220,0x240,0x260)
+    irq		- IRQ # for SB DSP chip (5,7,9,10)
+    dma8	- DMA # for SB DSP chip (1,3)
+
+    This module supports multiple cards and autoprobe.
+    
+    The power-management is supported.
+
+  Module snd-sb16 and snd-sbawe
+  -----------------------------
+
+    Module for 16-bit SoundBlaster cards: SoundBlaster 16 (PnP),
+					  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)
+                   (snd-sbawe module only)
+    irq		- IRQ # for SB DSP 4.x chip (5,7,9,10)
+    dma8	- 8-bit DMA # for SB DSP 4.x chip (0,1,3)
+    dma16	- 16-bit DMA # for SB DSP 4.x chip (5,6,7)
+    
+    This module supports multiple cards, autoprobe and ISA PnP.
+
+    Note: To use Vibra16X cards in 16-bit half duplex mode, you must
+          disable 16bit DMA with dma16 = -1 module parameter.
+          Also, all Sound Blaster 16 type cards can operate in 16-bit
+          half duplex mode through 8-bit DMA channel by disabling their
+          16-bit DMA channel.
+    
+    The power-management is supported.
+
+  Module snd-sc6000
+  -----------------
+
+    Module for Gallant SC-6000 soundcard.
+
+    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)
+
+    This module supports multiple cards.
+
+    This card is also known as Audio Excel DSP 16 or Zoltrix AV302.
+
+  Module snd-sgalaxy
+  ------------------
+
+    Module for Aztech Sound Galaxy sound card.
+
+    sbport	- Port # for SB16 interface (0x220,0x240)
+    wssport	- Port # for WSS interface (0x530,0xe80,0xf40,0x604)
+    irq		- IRQ # (7,9,10,11)
+    dma1	- DMA #
+
+    This module supports multiple cards.
+
+    The power-management is supported.
+
+  Module snd-sscape
+  -----------------
+
+    Module for ENSONIQ SoundScape PnP 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)
+
+    This module supports multiple cards.  ISA PnP must be enabled.
+    You need sscape_ctl tool in alsa-tools package for loading
+    the microcode.
+
+  Module snd-sun-amd7930 (on sparc only)
+  --------------------------------------
+
+    Module for AMD7930 sound chips found on Sparcs.
+
+    This module supports multiple cards.
+
+  Module snd-sun-cs4231 (on sparc only)
+  -------------------------------------
+
+    Module for CS4231 sound chips found on Sparcs.
+
+    This module supports multiple cards.
+
+  Module snd-sun-dbri (on sparc only)
+  -----------------------------------
+
+    Module for DBRI sound chips found on Sparcs.
+
+    This module supports multiple cards.
+
+  Module snd-wavefront
+  --------------------
+
+    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).
+    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.
+
+    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
+  ---------------------
+
+    Module for S3 SonicVibes PCI sound cards.
+			* PINE Schubert 32 PCI
+
+    reverb    - Reverb Enable - 1 = enable, 0 = disable (default)
+                  - SoundCard must have onboard SRAM for this.
+    mge       - Mic Gain Enable - 1 = enable, 0 = disable (default)
+    
+    This module supports multiple cards and autoprobe.
+
+  Module snd-serial-u16550
+  ------------------------
+
+    Module for UART16550A serial MIDI ports.
+
+    port	- port # for UART16550A chip
+    irq		- IRQ # for UART16550A chip, -1 = poll mode
+    speed	- speed in bauds (9600,19200,38400,57600,115200)
+		  38400 = default
+    base	- base for divisor in bauds (57600,115200,230400,460800)
+		  115200 = default
+    outs	- number of MIDI ports in a serial port (1-4)
+		  1 = default
+    adaptor	- Type of adaptor.
+                  0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A,
+		  3 = MS-124W M/B, 4 = Generic
+    
+    This module supports multiple cards. This module does not support autoprobe
+    thus the main port must be specified!!! Other options are optional.
+
+  Module snd-trident
+  ------------------
+
+    Module for Trident 4DWave DX/NX sound cards.
+			* Best Union  Miss Melody 4DWave PCI
+			* HIS  4DWave PCI
+			* Warpspeed  ONSpeed 4DWave PCI
+			* AzTech  PCI 64-Q3D
+			* Addonics  SV 750
+			* CHIC  True Sound 4Dwave
+			* Shark  Predator4D-PCI
+			* Jaton  SonicWave 4D
+			* 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)
+
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
+
+  Module snd-usb-audio
+  --------------------
+
+    Module for USB audio and USB MIDI devices.
+
+    vid             - Vendor ID for the device (optional)
+    pid             - Product ID for the device (optional)
+    nrpacks	    - Max. number of packets per URB (default: 8)
+    async_unlink    - Use async unlink mode (default: yes)
+    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: async_unlink=0 would cause Oops.  It remains just for
+        debugging purpose (if any).
+    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.
+
+  Module snd-usb-usx2y
+  --------------------
+
+    Module for Tascam USB US-122, US-224 and US-428 devices.
+
+    This module supports multiple devices, autoprobe and hotplugging.
+
+    Note: you need to load the firmware via usx2yloader utility included
+          in alsa-tools and alsa-firmware packages.
+
+  Module snd-via82xx
+  ------------------
+
+    Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
+    8233A, 8233C, 8235, 8237 (south) bridge.
+
+    mpu_port	- 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
+		  [VIA686A/686B only]
+    joystick	- Enable joystick (default off) [VIA686A/686B only]
+    ac97_clock	- AC'97 codec clock base (default 48000Hz)
+    dxs_support	- support DXS channels,
+		  0 = auto (default), 1 = enable, 2 = disable,
+		  3 = 48k only, 4 = no VRA, 5 = enable any sample
+		  rate and different sample rates on different
+		  channels
+		  [VIA8233/C, 8235, 8237 only]
+    ac97_quirk  - AC'97 workaround for strange hardware
+		  See "AC97 Quirk Option" section below.
+
+    This module supports one chip and autoprobe.
+
+    Note: on some SMP motherboards like MSI 694D the interrupts might
+          not be generated properly.  In such a case, please try to
+          set the SMP (or MPS) version on BIOS to 1.1 instead of
+          default value 1.4.  Then the interrupt number will be
+          assigned under 15. You might also upgrade your BIOS.
+    
+    Note: VIA8233/5/7 (not VIA8233A) can support DXS (direct sound)
+	  channels as the first PCM.  On these channels, up to 4
+	  streams can be played at the same time, and the controller
+	  can perform sample rate conversion with separate rates for
+	  each channel.
+	  As default (dxs_support = 0), 48k fixed rate is chosen
+	  except for the known devices since the output is often
+	  noisy except for 48k on some mother boards due to the
+	  bug of BIOS.
+	  Please try once dxs_support=5 and if it works on other
+	  sample rates (e.g. 44.1kHz of mp3 playback), please let us
+	  know the PCI subsystem vendor/device id's (output of
+	  "lspci -nv").
+	  If dxs_support=5 does not work, try dxs_support=4; if it
+	  doesn't work too, try dxs_support=1.  (dxs_support=1 is
+	  usually for old motherboards.  The correct implemented
+	  board should work with 4 or 5.)  If it still doesn't
+	  work and the default setting is ok, dxs_support=3 is the
+	  right choice.  If the default setting doesn't work at all,
+	  try dxs_support=2 to disable the DXS channels.
+	  In any cases, please let us know the result and the
+	  subsystem vendor/device ids.  See "Links and Addresses"
+	  below.
+
+    Note: for the MPU401 on VIA823x, use snd-mpu401 driver
+	  additionally.  The mpu_port option is for VIA686 chips only.
+
+    The power-management is supported.
+
+  Module snd-via82xx-modem
+  ------------------------
+
+    Module for VIA82xx AC97 modem
+
+    ac97_clock	- AC'97 codec clock base (default 48000Hz)
+
+    This module supports one card and autoprobe.
+
+    Note: The default index value of this module is -2, i.e. the first
+          slot is excluded.
+
+    The power-management is supported.
+
+  Module snd-virmidi
+  ------------------
+
+    Module for virtual rawmidi devices.
+    This module creates virtual rawmidi devices which communicate
+    to the corresponding ALSA sequencer ports.
+
+    midi_devs	- MIDI devices # (1-4, default=4)
+    
+    This module supports multiple cards.
+
+  Module snd-virtuoso
+  -------------------
+
+    Module for sound cards based on the Asus AV100/AV200 chips,
+    i.e., Xonar D1, DX, D2, D2X and HDAV1.3 (Deluxe).
+
+    This module supports autoprobe and multiple cards.
+
+  Module snd-vx222
+  ----------------
+
+    Module for Digigram VX-Pocket VX222, V222 v2 and Mic cards.
+
+    mic		- Enable Microphone on V222 Mic (NYI)
+    ibl		- Capture IBL size. (default = 0, minimum size)
+
+    This module supports multiple cards.
+
+    When the driver is compiled as a module and the hotplug firmware
+    is supported, the firmware data is loaded via hotplug automatically.
+    Install the necessary firmware files in alsa-firmware package.
+    When no hotplug fw loader is available, you need to load the
+    firmware via vxloader utility in alsa-tools package.  To invoke
+    vxloader automatically, add the following to /etc/modprobe.conf
+
+	install snd-vx222 /sbin/modprobe --first-time -i snd-vx222 && /usr/bin/vxloader
+
+    (for 2.2/2.4 kernels, add "post-install /usr/bin/vxloader" to
+     /etc/modules.conf, instead.)
+    IBL size defines the interrupts period for PCM.  The smaller size
+    gives smaller latency but leads to more CPU consumption, too.
+    The size is usually aligned to 126.  As default (=0), the smallest
+    size is chosen.  The possible IBL values can be found in
+    /proc/asound/cardX/vx-status proc file.
+
+    The power-management is supported.
+
+  Module snd-vxpocket
+  -------------------
+
+    Module for Digigram VX-Pocket VX2 and 440 PCMCIA cards.
+
+    ibl      - Capture IBL size. (default = 0, minimum size)
+
+    This module supports multiple cards.  The module is compiled only when
+    PCMCIA is supported on kernel.
+
+    With the older 2.6.x kernel, to activate the driver via the card
+    manager, you'll need to set up /etc/pcmcia/vxpocket.conf.  See the
+    sound/pcmcia/vx/vxpocket.c.  2.6.13 or later kernel requires no
+    longer require a config file.
+
+    When the driver is compiled as a module and the hotplug firmware
+    is supported, the firmware data is loaded via hotplug automatically.
+    Install the necessary firmware files in alsa-firmware package.
+    When no hotplug fw loader is available, you need to load the
+    firmware via vxloader utility in alsa-tools package.
+
+    About capture IBL, see the description of snd-vx222 module.
+
+    Note: snd-vxp440 driver is merged to snd-vxpocket driver since
+           ALSA 1.0.10.
+
+    The power-management is supported.
+
+  Module snd-ymfpci
+  -----------------
+
+    Module for Yamaha PCI chips (YMF72x, YMF74x & YMF75x).
+
+    mpu_port      - 0x300,0x330,0x332,0x334, 0 (disable) by default,
+                    1 (auto-detect for YMF744/754 only)
+    fm_port       - 0x388,0x398,0x3a0,0x3a8, 0 (disable) by default
+                    1 (auto-detect for YMF744/754 only)
+    joystick_port - 0x201,0x202,0x204,0x205, 0 (disable) by default,
+                    1 (auto-detect)
+    rear_switch   - enable shared rear/line-in switch (bool)
+
+    This module supports autoprobe and multiple chips.
+
+    The power-management is supported.
+
+  Module snd-pdaudiocf
+  --------------------
+
+    Module for Sound Core PDAudioCF sound card.
+
+    The power-management is supported.
+
+
+AC97 Quirk Option
+=================
+
+The ac97_quirk option is used to enable/override the workaround for
+specific devices on drivers for on-board AC'97 controllers like
+snd-intel8x0.  Some hardware have swapped output pins between Master
+and Headphone, or Surround (thanks to confusion of AC'97
+specifications from version to version :-)
+
+The driver provides the auto-detection of known problematic devices,
+but some might be unknown or wrongly detected.  In such a case, pass
+the proper value with this option.
+
+The following strings are accepted:
+    - default	Don't override the default setting
+    - none	Disable the quirk
+    - hp_only	Bind Master and Headphone controls as a single control
+    - swap_hp	Swap headphone and master controls
+    - swap_surround  Swap master and surround controls
+    - ad_sharing  For AD1985, turn on OMS bit and use headphone
+    - alc_jack	For ALC65x, turn on the jack sense mode
+    - inv_eapd	Inverted EAPD implementation
+    - mute_led	Bind EAPD bit for turning on/off mute LED
+
+For backward compatibility, the corresponding integer value -1, 0,
+... are  accepted, too.
+
+For example, if "Master" volume control has no effect on your device
+but only "Headphone" does, pass ac97_quirk=hp_only module option.
+
+
+Configuring Non-ISAPNP Cards
+============================
+
+When the kernel is configured with ISA-PnP support, the modules
+supporting the isapnp cards will have module options "isapnp".
+If this option is set, *only* the ISA-PnP devices will be probed.
+For probing the non ISA-PnP cards, you have to pass "isapnp=0" option
+together with the proper i/o and irq configuration.
+
+When the kernel is configured without ISA-PnP support, isapnp option
+will be not built in.
+
+
+Module Autoloading Support
+==========================
+
+The ALSA drivers can be loaded automatically on demand by defining
+module aliases.  The string 'snd-card-%1' is requested for ALSA native
+devices where %i is sound card number from zero to seven.
+
+To auto-load an ALSA driver for OSS services, define the string
+'sound-slot-%i' where %i means the slot number for OSS, which
+corresponds to the card index of ALSA.  Usually, define this
+as the same card module.
+
+An example configuration for a single emu10k1 card is like below:
+----- /etc/modprobe.conf
+alias snd-card-0 snd-emu10k1
+alias sound-slot-0 snd-emu10k1
+----- /etc/modprobe.conf
+
+The available number of auto-loaded sound cards depends on the module
+option "cards_limit" of snd module.  As default it's set to 1.
+To enable the auto-loading of multiple cards, specify the number of
+sound cards in that option.
+
+When multiple cards are available, it'd better to specify the index
+number for each card via module option, too, so that the order of
+cards is kept consistent.
+
+An example configuration for two sound cards is like below:
+
+----- /etc/modprobe.conf
+# ALSA portion
+options snd cards_limit=2
+alias snd-card-0 snd-interwave
+alias snd-card-1 snd-ens1371
+options snd-interwave index=0
+options snd-ens1371 index=1
+# OSS/Free portion
+alias sound-slot-0 snd-interwave
+alias sound-slot-1 snd-ens1371
+----- /etc/modprobe.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
+=======================================
+
+/dev/snd/pcmC0D0[c|p]  -> /dev/audio0 (/dev/audio) -> minor 4
+/dev/snd/pcmC0D0[c|p]  -> /dev/dsp0 (/dev/dsp)     -> minor 3
+/dev/snd/pcmC0D1[c|p]  -> /dev/adsp0 (/dev/adsp)   -> minor 12
+/dev/snd/pcmC1D0[c|p]  -> /dev/audio1              -> minor 4+16 = 20
+/dev/snd/pcmC1D0[c|p]  -> /dev/dsp1                -> minor 3+16 = 19
+/dev/snd/pcmC1D1[c|p]  -> /dev/adsp1               -> minor 12+16 = 28
+/dev/snd/pcmC2D0[c|p]  -> /dev/audio2              -> minor 4+32 = 36
+/dev/snd/pcmC2D0[c|p]  -> /dev/dsp2                -> minor 3+32 = 39
+/dev/snd/pcmC2D1[c|p]  -> /dev/adsp2               -> minor 12+32 = 44
+
+The first number from /dev/snd/pcmC{X}D{Y}[c|p] expression means
+sound card number and second means device number.  The ALSA devices
+have either 'c' or 'p' suffix indicating the direction, capture and
+playback, respectively.
+
+Please note that the device mapping above may be varied via the module
+options of snd-pcm-oss module.
+
+
+Proc interfaces (/proc/asound)
+==============================
+
+/proc/asound/card#/pcm#[cp]/oss
+-------------------------------
+  String "erase" - erase all additional informations about OSS applications
+  String "<app_name> <fragments> <fragment_size> [<options>]"
+
+   <app_name> - name of application with (higher priority) or without path
+   <fragments> - number of fragments or zero if auto
+   <fragment_size> - size of fragment in bytes or zero if auto
+   <options> - optional parameters
+	  - disable   the application tries to open a pcm device for
+		      this channel but does not want to use it.
+		      (Cause a bug or mmap needs)
+		      It's good for Quake etc...
+	  - direct    don't use plugins
+	  - block     force block mode (rvplayer)
+	  - non-block force non-block mode
+	  - whole-frag  write only whole fragments (optimization affecting
+			playback only)
+	  - no-silence  do not fill silence ahead to avoid clicks
+	  - buggy-ptr	Returns the whitespace blocks in GETOPTR ioctl
+			instead of filled blocks
+
+  Example: echo "x11amp 128 16384" > /proc/asound/card0/pcm0p/oss
+           echo "squake 0 0 disable" > /proc/asound/card0/pcm0c/oss
+	   echo "rvplayer 0 0 block" > /proc/asound/card0/pcm0p/oss
+
+
+Early Buffer Allocation
+=======================
+
+Some drivers (e.g. hdsp) require the large contiguous buffers, and
+sometimes it's too late to find such spaces when the driver module is
+actually loaded due to memory fragmentation.  You can pre-allocate the
+PCM buffers by loading snd-page-alloc module and write commands to its
+proc file in prior, for example, in the early boot stage like
+/etc/init.d/*.local scripts.
+
+Reading the proc file /proc/drivers/snd-page-alloc shows the current
+usage of page allocation.  In writing, you can send the following
+commands to the snd-page-alloc driver:
+
+  - add VENDOR DEVICE MASK SIZE BUFFERS
+
+    VENDOR and DEVICE are PCI vendor and device IDs.  They take
+    integer numbers (0x prefix is needed for the hex).
+    MASK is the PCI DMA mask.  Pass 0 if not restricted.
+    SIZE is the size of each buffer to allocate.  You can pass
+    k and m suffix for KB and MB.  The max number is 16MB.
+    BUFFERS is the number of buffers to allocate.  It must be greater
+    than 0.  The max number is 4.
+
+  - erase
+
+    This will erase the all pre-allocated buffers which are not in
+    use.
+
+
+Links and Addresses
+===================
+
+  ALSA project homepage
+       http://www.alsa-project.org
+
+  ALSA Bug Tracking System
+       https://bugtrack.alsa-project.org/bugs/
+
+  ALSA Developers ML
+       mailto:alsa-devel@alsa-project.org
diff --git a/Documentation/sound/alsa/Audigy-mixer.txt b/Documentation/sound/alsa/Audigy-mixer.txt
new file mode 100644
index 0000000..7f10dc6
--- /dev/null
+++ b/Documentation/sound/alsa/Audigy-mixer.txt
@@ -0,0 +1,345 @@
+
+		Sound Blaster Audigy mixer / default DSP code
+		===========================================
+
+This is based on SB-Live-mixer.txt.
+
+The EMU10K2 chips have a DSP part which can be programmed to support 
+various ways of sample processing, which is described here.
+(This 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
+(can be altered later) which offers the following functionality:
+
+
+1) Digital mixer controls
+-------------------------
+
+These controls are built using the DSP instructions. They offer extended
+functionality. Only the default build-in code in the ALSA driver is described
+here. Note that the controls work as attenuators: the maximum value is the 
+neutral position leaving the signal unchanged. Note that if the  same destination 
+is mentioned in multiple controls, the signal is accumulated and can be wrapped 
+(set to maximal or minimal value without checking of overflow).
+
+
+Explanation of used abbreviations:
+
+DAC    - digital to analog converter
+ADC    - analog to digital converter
+I2S    - one-way three wire serial bus for digital sound by Philips Semiconductors
+         (this standard is used for connecting standalone DAC and ADC converters)
+LFE    - low frequency effects (subwoofer signal)
+AC97   - a chip containing an analog mixer, DAC and ADC converters
+IEC958 - S/PDIF
+FX-bus - the EMU10K2 chip has an effect bus containing 64 accumulators.
+         Each of the synthesizer voices can feed its output to these accumulators
+         and the DSP microcontroller can operate with the resulting sum.
+
+name='PCM Front Playback Volume',index=0
+
+This control is used to attenuate samples for left and right front PCM FX-bus
+accumulators. ALSA uses accumulators 8 and 9 for left and right front PCM 
+samples for 5.1 playback. The result samples are forwarded to the front DAC PCM 
+slots of the Philips DAC.
+
+name='PCM Surround Playback Volume',index=0
+
+This control is used to attenuate samples for left and right surround PCM FX-bus
+accumulators. ALSA uses accumulators 2 and 3 for left and right surround PCM 
+samples for 5.1 playback. The result samples are forwarded to the surround DAC PCM 
+slots of the Philips DAC.
+
+name='PCM Center Playback Volume',index=0
+
+This control is used to attenuate samples for center PCM FX-bus accumulator.
+ALSA uses accumulator 6 for center PCM sample for 5.1 playback. The result sample
+is forwarded to the center DAC PCM slot of the Philips DAC.
+
+name='PCM LFE Playback Volume',index=0
+
+This control is used to attenuate sample for LFE PCM FX-bus accumulator. 
+ALSA uses accumulator 7 for LFE PCM sample for 5.1 playback. The result sample 
+is forwarded to the LFE DAC PCM slot of the Philips DAC.
+
+name='PCM Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples for
+stereo playback. The result samples are forwarded to the front DAC PCM slots 
+of the Philips DAC.
+
+name='PCM Capture Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Music Playback Volume',index=0
+
+This control is used to attenuate samples for left and right MIDI FX-bus
+accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
+The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Music Capture Volume',index=0
+
+These controls are used to attenuate samples for left and right MIDI FX-bus
+accumulator. ALSA uses accumulators 4 and 5 for left and right PCM.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Mic Playback Volume',index=0
+
+This control is used to attenuate samples for left and right Mic input.
+For Mic input is used AC97 codec. The result samples are forwarded to 
+the front DAC PCM slots of the Philips DAC. Samples are forwarded to Mic
+capture FIFO (device 1 - 16bit/8KHz mono) too without volume control.
+
+name='Mic Capture Volume',index=0
+
+This control is used to attenuate samples for left and right Mic input.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Audigy CD Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 TTL
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the front DAC PCM slots of the Philips DAC.
+
+name='Audigy CD Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 TTL
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the ADC capture FIFO (thus to the standard capture PCM device).
+
+name='IEC958 Optical Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 optical
+digital input. The result samples are forwarded to the front DAC PCM slots
+of the Philips DAC.
+
+name='IEC958 Optical Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 optical
+digital inputs. The result samples are forwarded to the ADC capture FIFO
+(thus to the standard capture PCM device).
+
+name='Line2 Playback Volume',index=0
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the AudigyDrive). The result samples are forwarded to the front
+DAC PCM slots of the Philips DAC.
+
+name='Line2 Capture Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the AudigyDrive). The result samples are forwarded to the ADC
+capture FIFO (thus to the standard capture PCM device).
+
+name='Analog Mix Playback Volume',index=0
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs from Philips ADC. The result samples are forwarded to the front
+DAC PCM slots of the Philips DAC. This contains mix from analog sources
+like CD, Line In, Aux, ....
+
+name='Analog Mix Capture Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs Philips ADC. The result samples are forwarded to the ADC
+capture FIFO (thus to the standard capture PCM device).
+
+name='Aux2 Playback Volume',index=0
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the AudigyDrive). The result samples are forwarded to the front
+DAC PCM slots of the Philips DAC.
+
+name='Aux2 Capture Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the AudigyDrive). The result samples are forwarded to the ADC
+capture FIFO (thus to the standard capture PCM device).
+
+name='Front Playback Volume',index=0
+
+All stereo signals are mixed together and mirrored to surround, center and LFE.
+This control is used to attenuate samples for left and right front speakers of
+this mix.
+
+name='Surround Playback Volume',index=0
+
+All stereo signals are mixed together and mirrored to surround, center and LFE.
+This control is used to attenuate samples for left and right surround speakers of
+this mix.
+
+name='Center Playback Volume',index=0
+
+All stereo signals are mixed together and mirrored to surround, center and LFE.
+This control is used to attenuate sample for center speaker of this mix.
+
+name='LFE Playback Volume',index=0
+
+All stereo signals are mixed together and mirrored to surround, center and LFE.
+This control is used to attenuate sample for LFE speaker of this mix.
+
+name='Tone Control - Switch',index=0
+
+This control turns the tone control on or off. The samples for front, rear
+and center / LFE outputs are affected.
+
+name='Tone Control - Bass',index=0
+
+This control sets the bass intensity. There is no neutral value!!
+When the tone control code is activated, the samples are always modified.
+The closest value to pure signal is 20.
+
+name='Tone Control - Treble',index=0
+
+This control sets the treble intensity. There is no neutral value!!
+When the tone control code is activated, the samples are always modified.
+The closest value to pure signal is 20.
+
+name='Master Playback Volume',index=0
+
+This control is used to attenuate samples for front, surround, center and 
+LFE outputs.
+
+name='IEC958 Optical Raw Playback Switch',index=0
+
+If this switch is on, then the samples for the IEC958 (S/PDIF) digital
+output are taken only from the raw FX8010 PCM, otherwise standard front
+PCM samples are taken.
+
+
+2) PCM stream related controls
+------------------------------
+
+name='EMU10K1 PCM Volume',index 0-31
+
+Channel volume attenuation in range 0-0xffff. The maximum value (no
+attenuation) is default. The channel mapping for three values is
+as follows:
+
+	0 - mono, default 0xffff (no attenuation)
+	1 - left, default 0xffff (no attenuation)
+	2 - right, default 0xffff (no attenuation)
+
+name='EMU10K1 PCM Send Routing',index 0-31
+
+This control specifies the destination - FX-bus accumulators. There 24
+values with this mapping:
+
+	 0 -  mono, A destination (FX-bus 0-63), default 0
+	 1 -  mono, B destination (FX-bus 0-63), default 1
+	 2 -  mono, C destination (FX-bus 0-63), default 2
+	 3 -  mono, D destination (FX-bus 0-63), default 3
+	 4 -  mono, E destination (FX-bus 0-63), default 0
+	 5 -  mono, F destination (FX-bus 0-63), default 0
+	 6 -  mono, G destination (FX-bus 0-63), default 0
+	 7 -  mono, H destination (FX-bus 0-63), default 0
+	 8 -  left, A destination (FX-bus 0-63), default 0
+	 9 -  left, B destination (FX-bus 0-63), default 1
+	10 -  left, C destination (FX-bus 0-63), default 2
+	11 -  left, D destination (FX-bus 0-63), default 3
+	12 -  left, E destination (FX-bus 0-63), default 0
+	13 -  left, F destination (FX-bus 0-63), default 0
+	14 -  left, G destination (FX-bus 0-63), default 0
+	15 -  left, H destination (FX-bus 0-63), default 0
+	16 - right, A destination (FX-bus 0-63), default 0
+	17 - right, B destination (FX-bus 0-63), default 1
+	18 - right, C destination (FX-bus 0-63), default 2
+	19 - right, D destination (FX-bus 0-63), default 3
+	20 - right, E destination (FX-bus 0-63), default 0
+	21 - right, F destination (FX-bus 0-63), default 0
+	22 - right, G destination (FX-bus 0-63), default 0
+	23 - right, H destination (FX-bus 0-63), default 0
+
+Don't forget that it's illegal to assign a channel to the same FX-bus accumulator 
+more than once (it means 0=0 && 1=0 is an invalid combination).
+ 
+name='EMU10K1 PCM Send Volume',index 0-31
+
+It specifies the attenuation (amount) for given destination in range 0-255.
+The channel mapping is following:
+
+	 0 -  mono, A destination attn, default 255 (no attenuation)
+	 1 -  mono, B destination attn, default 255 (no attenuation)
+	 2 -  mono, C destination attn, default 0 (mute)
+	 3 -  mono, D destination attn, default 0 (mute)
+	 4 -  mono, E destination attn, default 0 (mute)
+	 5 -  mono, F destination attn, default 0 (mute)
+	 6 -  mono, G destination attn, default 0 (mute)
+	 7 -  mono, H destination attn, default 0 (mute)
+	 8 -  left, A destination attn, default 255 (no attenuation)
+	 9 -  left, B destination attn, default 0 (mute)
+	10 -  left, C destination attn, default 0 (mute)
+	11 -  left, D destination attn, default 0 (mute)
+	12 -  left, E destination attn, default 0 (mute)
+	13 -  left, F destination attn, default 0 (mute)
+	14 -  left, G destination attn, default 0 (mute)
+	15 -  left, H destination attn, default 0 (mute)
+	16 - right, A destination attn, default 0 (mute)
+	17 - right, B destination attn, default 255 (no attenuation)
+	18 - right, C destination attn, default 0 (mute)
+	19 - right, D destination attn, default 0 (mute)
+	20 - right, E destination attn, default 0 (mute)
+	21 - right, F destination attn, default 0 (mute)
+	22 - right, G destination attn, default 0 (mute)
+	23 - right, H destination attn, default 0 (mute)
+
+
+
+4) MANUALS/PATENTS:
+-------------------
+
+ftp://opensource.creative.com/pub/doc
+-------------------------------------
+
+        Files:
+        LM4545.pdf      AC97 Codec
+
+        m2049.pdf       The EMU10K1 Digital Audio Processor
+
+        hog63.ps        FX8010 - A DSP Chip Architecture for Audio Effects
+
+
+WIPO Patents
+------------
+        Patent numbers:
+        WO 9901813 (A1) Audio Effects Processor with multiple asynchronous (Jan. 14, 1999)
+                        streams
+
+        WO 9901814 (A1) Processor with Instruction Set for Audio Effects (Jan. 14, 1999)
+
+        WO 9901953 (A1) Audio Effects Processor having Decoupled Instruction
+                        Execution and Audio Data Sequencing (Jan. 14, 1999)
+
+
+US Patents (http://www.uspto.gov/)
+----------------------------------
+
+        US 5925841      Digital Sampling Instrument employing cache memory (Jul. 20, 1999)
+
+        US 5928342      Audio Effects Processor integrated on a single chip (Jul. 27, 1999)
+                        with a multiport memory onto which multiple asynchronous
+                        digital sound samples can be concurrently loaded
+
+        US 5930158      Processor with Instruction Set for Audio Effects (Jul. 27, 1999)
+
+        US 6032235      Memory initialization circuit (Tram) (Feb. 29, 2000)
+
+        US 6138207      Interpolation looping of audio samples in cache connected to    (Oct. 24, 2000)
+                        system bus with prioritization and modification of bus transfers
+                        in accordance with loop ends and minimum block sizes
+
+        US 6151670      Method for conserving memory storage using a (Nov. 21, 2000)
+                        pool of  short term memory registers
+
+        US 6195715      Interrupt control for multiple programs communicating with      (Feb. 27, 2001)
+                        a common interrupt by associating programs to GP registers,
+                        defining interrupt register, polling GP registers, and invoking
+                        callback routine associated with defined interrupt register
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt
new file mode 100644
index 0000000..a4c53d8
--- /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
+   - For Fedora distributions, edit the /etc/modprobe.conf file:
+       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.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
new file mode 100644
index 0000000..f158cde
--- /dev/null
+++ b/Documentation/sound/alsa/Bt87x.txt
@@ -0,0 +1,78 @@
+Intro
+=====
+
+You might have noticed that the bt878 grabber cards have actually
+_two_ PCI functions:
+
+$ lspci
+[ ... ]
+00:0a.0 Multimedia video controller: Brooktree Corporation Bt878 (rev 02)
+00:0a.1 Multimedia controller: Brooktree Corporation Bt878 (rev 02)
+[ ... ]
+
+The first does video, it is backward compatible to the bt848.  The second
+does audio.  snd-bt87x is a driver for the second function.  It's a sound
+driver which can be used for recording sound (and _only_ recording, no
+playback).  As most TV cards come with a short cable which can be plugged
+into your sound card's line-in you probably don't need this driver if all
+you want to do is just watching TV...
+
+Some cards do not bother to connect anything to the audio input pins of
+the chip, and some other cards use the audio function to transport MPEG
+video data, so it's quite possible that audio recording may not work
+with your card.
+
+
+Driver Status
+=============
+
+The driver is now stable.  However, it doesn't know about many TV cards,
+and it refuses to load for cards it doesn't know.
+
+If the driver complains ("Unknown TV card found, the audio driver will
+not load"), you can specify the load_all=1 option to force the driver to
+try to use the audio capture function of your card.  If the frequency of
+recorded data is not right, try to specify the digital_rate option with
+other values than the default 32000 (often it's 44100 or 64000).
+
+If you have an unknown card, please mail the ID and board name to
+<alsa-devel@alsa-project.org>, regardless of whether audio capture works
+or not, so that future versions of this driver know about your card.
+
+
+Audio modes
+===========
+
+The chip knows two different modes (digital/analog).  snd-bt87x
+registers two PCM devices, one for each mode.  They cannot be used at
+the same time.
+
+
+Digital audio mode
+==================
+
+The first device (hw:X,0) gives you 16 bit stereo sound.  The sample
+rate depends on the external source which feeds the Bt87x with digital
+sound via I2S interface.
+
+
+Analog audio mode (A/D)
+=======================
+
+The second device (hw:X,1) gives you 8 or 16 bit mono sound.  Supported
+sample rates are between 119466 and 448000 Hz (yes, these numbers are
+that high).  If you've set the CONFIG_SND_BT87X_OVERCLOCK option, the
+maximum sample rate is 1792000 Hz, but audio data becomes unusable
+beyond 896000 Hz on my card.
+
+The chip has three analog inputs.  Consequently you'll get a mixer
+device to control these.
+
+
+Have fun,
+
+  Clemens
+
+
+Written by Clemens Ladisch <clemens@ladisch.de>
+big parts copied from btaudio.txt by Gerd Knorr <kraxel@bytesex.org>
diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
new file mode 100644
index 0000000..16935c8
--- /dev/null
+++ b/Documentation/sound/alsa/CMIPCI.txt
@@ -0,0 +1,254 @@
+         Brief Notes on C-Media 8338/8738/8768/8770 Driver
+         =================================================
+
+                   Takashi Iwai <tiwai@suse.de>
+
+
+Front/Rear Multi-channel Playback
+---------------------------------
+
+CM8x38 chip can use ADC as the second DAC so that two different stereo
+channels can be used for front/rear playbacks.  Since there are two
+DACs, both streams are handled independently unlike the 4/6ch multi-
+channel playbacks in the section below.
+
+As default, ALSA driver assigns the first PCM device (i.e. hw:0,0 for
+card#0) for front and 4/6ch playbacks, while the second PCM device
+(hw:0,1) is assigned to the second DAC for rear playback.
+
+There are slight differences between the two DACs:
+
+- The first DAC supports U8 and S16LE formats, while the second DAC
+  supports only S16LE.
+- The second DAC supports only two channel stereo.
+
+Please note that the CM8x38 DAC doesn't support continuous playback
+rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000,
+44100 and 48000 Hz.
+
+The rear output can be heard only when "Four Channel Mode" switch is
+disabled.  Otherwise no signal will be routed to the rear speakers.
+As default it's turned on.
+
+*** WARNING ***
+When "Four Channel Mode" switch is off, the output from rear speakers
+will be FULL VOLUME regardless of Master and PCM volumes.
+This might damage your audio equipment.  Please disconnect speakers
+before your turn off this switch.
+*** WARNING ***
+
+[ Well.. I once got the output with correct volume (i.e. same with the
+  front one) and was so excited.  It was even with "Four Channel" bit
+  on and "double DAC" mode.  Actually I could hear separate 4 channels
+  from front and rear speakers!  But.. after reboot, all was gone.
+  It's a very pity that I didn't save the register dump at that
+  time..  Maybe there is an unknown register to achieve this... ]
+
+If your card has an extra output jack for the rear output, the rear
+playback should be routed there as default.  If not, there is a
+control switch in the driver "Line-In As Rear", which you can change
+via alsamixer or somewhat else.  When this switch is on, line-in jack
+is used as rear output.
+
+There are two more controls regarding to the rear output.
+The "Exchange DAC" switch is used to exchange front and rear playback
+routes, i.e. the 2nd DAC is output from front output.
+
+
+4/6 Multi-Channel Playback
+--------------------------
+
+The recent CM8738 chips support for the 4/6 multi-channel playback
+function.  This is useful especially for AC3 decoding.
+
+When the multi-channel is supported, the driver name has a suffix
+"-MC" such like "CMI8738-MC6".  You can check this name from
+/proc/asound/cards.
+
+When the 4/6-ch output is enabled, the second DAC accepts up to 6 (or
+4) channels.  While the dual DAC supports two different rates or
+formats, the 4/6-ch playback supports only the same condition for all
+channels.  Since the multi-channel playback mode uses both DACs, you
+cannot operate with full-duplex.
+
+The 4.0 and 5.1 modes are defined as the pcm "surround40" and "surround51"
+in alsa-lib.  For example, you can play a WAV file with 6 channels like
+
+	% aplay -Dsurround51 sixchannels.wav
+
+For 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,
+
+	snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED);
+	    // or mmap if you like
+	snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_S16_LE);
+	snd_pcm_hw_params_set_channels(pcm, hw, 4);
+
+and use the interleaved 4 channel data.
+
+There are some control switchs affecting to the speaker connections:
+
+"Line-In Mode"	- an enum control to change the behavior of line-in
+	jack.  Either "Line-In", "Rear Output" or "Bass Output" can
+	be selected.  The last item is available only with model 039
+	or newer. 
+	When "Rear Output" is chosen, the surround channels 3 and 4
+	are output to line-in jack.
+"Mic-In Mode"	- an enum control to change the behavior of mic-in
+	jack.  Either "Mic-In" or "Center/LFE Output" can be
+	selected. 
+	When "Center/LFE Output" is chosen, the center and bass
+	channels (channels 5 and 6) are output to mic-in jack. 
+
+Digital I/O
+-----------
+
+The CM8x38 provides the excellent SPDIF capability with very cheap
+price (yes, that's the reason I bought the card :)
+
+The SPDIF playback and capture are done via the third PCM device
+(hw:0,2).  Usually this is assigned to the PCM device "spdif".
+The available rates are 44100 and 48000 Hz.
+For playback with aplay, you can run like below:
+
+	% aplay -Dhw:0,2 foo.wav
+
+or
+
+	% aplay -Dspdif foo.wav
+
+24bit format is also supported experimentally.
+
+The playback and capture over SPDIF use normal DAC and ADC,
+respectively, so you cannot playback both analog and digital streams
+simultaneously.
+
+To enable SPDIF output, you need to turn on "IEC958 Output Switch"
+control via mixer or alsactl ("IEC958" is the official name of
+so-called S/PDIF).  Then you'll see the red light on from the card so
+you know that's working obviously :)
+The SPDIF input is always enabled, so you can hear SPDIF input data
+from line-out with "IEC958 In Monitor" switch at any time (see
+below).
+
+You can play via SPDIF even with the first device (hw:0,0),
+but SPDIF is enabled only when the proper format (S16LE), sample rate
+(441100 or 48000) and channels (2) are used.  Otherwise it's turned
+off.  (Also don't forget to turn on "IEC958 Output Switch", too.)
+
+
+Additionally there are relevant control switches:
+
+"IEC958 Mix Analog" - Mix analog PCM playback and FM-OPL/3 streams and
+	output through SPDIF.  This switch appears only on old chip
+	models (CM8738 033 and 037).
+	Note: without this control you can output PCM to SPDIF.
+	This is "mixing" of streams, so e.g. it's not for AC3 output
+	(see the next section).
+
+"IEC958 In Select"  - Select SPDIF input, the internal CD-in (false)
+	and the external input (true).
+
+"IEC958 Loop"       - SPDIF input data is loop back into SPDIF
+	output (aka bypass)
+
+"IEC958 Copyright"  - Set the copyright bit.
+
+"IEC958 5V"         - Select 0.5V (coax) or 5V (optical) interface.
+	On some cards this doesn't work and you need to change the
+	configuration with hardware dip-switch.
+
+"IEC958 In Monitor" - SPDIF input is routed to DAC.
+
+"IEC958 In Phase Inverse" - Set SPDIF input format as inverse.
+	[FIXME: this doesn't work on all chips..]
+
+"IEC958 In Valid"   - Set input validity flag detection.
+
+Note: When "PCM Playback Switch" is on, you'll hear the digital output
+stream through analog line-out.
+
+
+The AC3 (RAW DIGITAL) OUTPUT
+----------------------------
+
+The driver supports raw digital (typically AC3) i/o over SPDIF.  This
+can be toggled via IEC958 playback control, but usually you need to
+access it via alsa-lib.  See alsa-lib documents for more details.
+
+On the raw digital mode, the "PCM Playback Switch" is automatically
+turned off so that non-audio data is heard from the analog line-out.
+Similarly the following switches are off: "IEC958 Mix Analog" and
+"IEC958 Loop".  The switches are resumed after closing the SPDIF PCM
+device automatically to the previous state.
+
+On the model 033, AC3 is implemented by the software conversion in
+the alsa-lib.  If you need to bypass the software conversion of IEC958
+subframes, pass the "soft_ac3=0" module option.  This doesn't matter
+on the newer models.
+
+
+ANALOG MIXER INTERFACE
+----------------------
+
+The mixer interface on CM8x38 is similar to SB16.
+There are Master, PCM, Synth, CD, Line, Mic and PC Speaker playback
+volumes.  Synth, CD, Line and Mic have playback and capture switches,
+too, as well as SB16.
+
+In addition to the standard SB mixer, CM8x38 provides more functions.
+- PCM playback switch
+- PCM capture switch (to capture the data sent to DAC)
+- Mic Boost switch
+- Mic capture volume
+- Aux playback volume/switch and capture switch
+- 3D control switch
+
+
+MIDI CONTROLLER
+---------------
+
+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).
+What's said as MIDI synth on Windows is a software synthesizer
+emulation.  On Linux use TiMidity or other softsynth program for
+playing MIDI music.
+
+
+FM OPL/3 Synth
+--------------
+
+The FM OPL/3 is also enabled as default only for the first card.
+Set "fm_port" module option for more cards.
+
+The output quality of FM OPL/3 is, however, very weird.
+I don't know why..
+
+CMI8768 and newer chips do not have the FM synth.
+
+
+Joystick and Modem
+------------------
+
+The legacy joystick is supported.  To enable the joystick support, pass
+joystick_port=1 module option.  The value 1 means the auto-detection.
+If the auto-detection fails, try to pass the exact I/O address.
+
+The modem is enabled dynamically via a card control switch "Modem".
+
+
+Debugging Information
+---------------------
+
+The registers are shown in /proc/asound/cardX/cmipci.  If you have any
+problem (especially unexpected behavior of mixer), please attach the
+output of this proc file together with the bug report.
diff --git a/Documentation/sound/alsa/ControlNames.txt b/Documentation/sound/alsa/ControlNames.txt
new file mode 100644
index 0000000..5b18298
--- /dev/null
+++ b/Documentation/sound/alsa/ControlNames.txt
@@ -0,0 +1,84 @@
+This document describes standard names of mixer controls.
+
+Syntax: SOURCE [DIRECTION] FUNCTION
+
+DIRECTION:
+  <nothing>	(both directions)
+  Playback
+  Capture
+  Bypass Playback
+  Bypass Capture
+
+FUNCTION:
+  Switch	(on/off switch)
+  Volume
+  Route		(route control, hardware specific)
+
+SOURCE:
+  Master
+  Master Mono
+  Hardware Master
+  Headphone
+  PC Speaker
+  Phone
+  Phone Input
+  Phone Output
+  Synth
+  FM
+  Mic
+  Line
+  CD
+  Video
+  Zoom Video
+  Aux
+  PCM
+  PCM Front
+  PCM Rear
+  PCM Pan
+  Loopback
+  Analog Loopback	(D/A -> A/D loopback)
+  Digital Loopback	(playback -> capture loopback - without analog path)
+  Mono
+  Mono Output
+  Multi
+  ADC
+  Wave
+  Music
+  I2S
+  IEC958
+
+Exceptions:
+  [Digital] Capture Source
+  [Digital] Capture Switch	(aka input gain switch)
+  [Digital] Capture Volume	(aka input gain volume)
+  [Digital] Playback Switch	(aka output gain switch)
+  [Digital] Playback Volume	(aka output gain volume)
+  Tone Control - Switch
+  Tone Control - Bass
+  Tone Control - Treble
+  3D Control - Switch
+  3D Control - Center
+  3D Control - Depth
+  3D Control - Wide
+  3D Control - Space
+  3D Control - Level
+  Mic Boost [(?dB)]
+
+PCM interface:
+
+  Sample Clock Source	{ "Word", "Internal", "AutoSync" }
+  Clock Sync Status	{ "Lock", "Sync", "No Lock" }
+  External Rate		/* external capture rate */
+  Capture Rate		/* capture rate taken from external source */
+
+IEC958 (S/PDIF) interface:
+
+  IEC958 [...] [Playback|Capture] Switch	/* turn on/off the IEC958 interface */
+  IEC958 [...] [Playback|Capture] Volume	/* digital volume control */
+  IEC958 [...] [Playback|Capture] Default	/* default or global value - read/write */
+  IEC958 [...] [Playback|Capture] Mask		/* consumer and professional mask */
+  IEC958 [...] [Playback|Capture] Con Mask	/* consumer mask */
+  IEC958 [...] [Playback|Capture] Pro Mask	/* professional mask */
+  IEC958 [...] [Playback|Capture] PCM Stream	/* the settings assigned to a PCM stream */
+  IEC958 Q-subcode [Playback|Capture] Default	/* Q-subcode bits */
+  IEC958 Preamble [Playback|Capture] Default	/* burst preamble words (4*16bits) */
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
new file mode 100644
index 0000000..87a7c07
--- /dev/null
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -0,0 +1,6210 @@
+<!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>Oct 15, 2007</date>
+     <edition>0.3.7</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 PCI soundcards.
+      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>
+    This document targets people who already have enough
+    C language skills and have basic linux kernel programming
+    knowledge.  This document doesn't explain the general
+    topic of linux kernel coding and doesn't cover low-level
+    driver implementation details. It only describes
+    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 API, you
+    can check the drivers such as <filename>sound/pci/es1938.c</filename> or
+    <filename>sound/pci/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 feedback 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 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 code 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 ALSA drivers outside of the Linux kernel tree,
+      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 (and eventually to the 2.6 kernel tree) 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 which 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 <filename>core/seq/oss</filename> 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 directory 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 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 reasons :) 
+      </para>
+    </section>
+
+    <section id="file-tree-drivers-directory">
+      <title>drivers directory</title>
+      <para>
+        This directory contains code shared among different drivers
+      on 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 is code 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 code 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
+        the <filename>synth/emux</filename> sub-directory. 
+        </para>
+    </section>
+
+    <section id="file-tree-pci-directory">
+      <title>pci directory</title>
+      <para>
+        This directory and its sub-directories hold the top-level card modules
+      for PCI soundcards and the code specific to the PCI BUS.
+      </para>
+
+      <para>
+        The drivers compiled from a single file are stored directly
+      in the pci directory, while the drivers with several source files are
+      stored on their own sub-directory (e.g. emu10k1, ice1712). 
+      </para>
+    </section>
+
+    <section id="file-tree-isa-directory">
+      <title>isa directory</title>
+      <para>
+        This directory 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>
+        They are used for top-level card modules which are
+      specific to one of these architectures. 
+      </para>
+    </section>
+
+    <section id="file-tree-usb-directory">
+      <title>usb directory</title>
+      <para>
+        This directory contains the USB-audio driver. In the latest version, the
+      USB MIDI driver is integrated in the 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 in the pci directory, because their API is identical
+      to that of standard PCI cards. 
+      </para>
+    </section>
+
+    <section id="file-tree-oss-directory">
+      <title>oss directory</title>
+      <para>
+        The OSS/Lite source files are stored here in Linux 2.6 (or
+      later) tree. In the ALSA driver tarball, this directory is 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 for PCI soundcards is as follows:
+
+        <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 a <structname>pci_driver</structname> structure
+	  containing the three pointers above.</para></listitem>
+          <listitem><para>create an <function>init()</function> function just calling
+	  the <function>pci_register_driver()</function> to register the pci_driver table
+	  defined above.</para></listitem>
+          <listitem><para>create an <function>exit()</function> function to call
+	  the <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
+      next sections. The numbers in the comment lines of the
+      <function>snd_mychip_probe()</function> function
+      refer to details explained in the following section. 
+
+        <example>
+          <title>Basic Flow for PCI Drivers - Example</title>
+          <programlisting>
+<![CDATA[
+  #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") */
+  /* SNDRV_CARDS: maximum number of cards supported by this module */
+  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;
+          /* the rest of the implementation will be in section
+           * "PCI Resource Management"
+           */
+  };
+
+  /* chip-specific destructor
+   * (see "PCI Resource Management")
+   */
+  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 Management")
+           */
+          ....
+
+          /* 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 Management"
+           */
+          ....
+
+          err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+          if (err < 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) */
+          err = snd_mychip_create(card, pci, &chip);
+          if (err < 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) */
+          err = snd_card_register(card);
+          if (err < 0) {
+                  snd_card_free(card);
+                  return err;
+          }
+
+          /* (7) */
+          pci_set_drvdata(pci, card);
+          dev++;
+          return 0;
+  }
+
+  /* destructor -- see the "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 the <function>probe</function> callback.
+      The <function>probe</function> callback and other component-constructors which are called
+      from the <function>probe</function> callback should be defined with
+      the <parameter>__devinit</parameter> prefix. You 
+      cannot use the <parameter>__init</parameter> prefix for them,
+      because any PCI device could be a hotplug device. 
+      </para>
+
+      <para>
+        In the <function>probe</function> 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>
+          Each time the <function>probe</function> 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 details 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;
+  ....
+  err = snd_mychip_create(card, pci, &chip);
+  if (err < 0) {
+          snd_card_free(card);
+          return err;
+  }
+]]>
+            </programlisting>
+          </informalexample>
+
+          The details will be explained in the section <link
+        linkend="pci-resource"><citetitle>PCI Resource
+        Management</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 used 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
+        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[
+  err = snd_card_register(card);
+  if (err < 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
+        used 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 <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 code is split into several
+      files, the files without module options don't need them.
+      </para>
+
+      <para>
+        In addition to these headers, you'll need
+      <filename>&lt;linux/interrupt.h&gt;</filename> for interrupt
+      handling, and <filename>&lt;asm/io.h&gt;</filename> for I/O
+      access. If you use the <function>mdelay()</function> or
+      <function>udelay()</function> functions, you'll need to include
+      <filename>&lt;linux/delay.h&gt;</filename> too. 
+      </para>
+
+      <para>
+      The ALSA interfaces like the PCM and control APIs are defined in other
+      <filename>&lt;sound/xxx.h&gt;</filename> header files.
+      They have to be included after
+      <filename>&lt;sound/core.h&gt;</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 whole list of 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 correct release 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-&gt;private_data for the
+        chip-specific data.  Note that these data
+        are 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. In an 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 such instance 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>&amp;ops</parameter>). The
+      device-level defines the type of components and the order of
+      registration and de-registration.  For most 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
+      (<parameter>chip</parameter> identifier in the above example)
+      for the instance. 
+      </para>
+
+      <para>
+        Each pre-defined ALSA component such as ac97 and 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 wish to create your own component, you need to
+      set the destructor function to the dev_free callback in
+      the <parameter>ops</parameter>, so that it can be released
+      automatically via <function>snd_card_free()</function>.
+      The next example will show an implementation of chip-specific
+      data.
+      </para>
+    </section>
+
+    <section id="card-management-chip-specific">
+      <title>Chip-Specific Data</title>
+      <para>
+      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 of allocating 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>
+
+          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 = 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>. Access
+      to the device files is 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 mentioned earlier, 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
+      the <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_when_closed</function>.  This one will
+      postpone the destruction until all devices are closed.
+      </para>
+
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- PCI Resource Management  -->
+<!-- ****************************************************** -->
+  <chapter id="pci-resource">
+    <title>PCI Resource Management</title>
+
+    <section id="pci-resource-example">
+      <title>Full Code Example</title>
+      <para>
+        In this section, we'll complete the chip-specific constructor,
+      destructor and PCI entries. Example code is shown first,
+      below. 
+
+        <example>
+          <title>PCI Resource Management 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, 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 */
+          err = pci_enable_device(pci);
+          if (err < 0)
+                  return err;
+          /* check PCI availability (28bit DMA) */
+          if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
+              pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 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 */
+          err = pci_request_regions(pci, "My Chip");
+          if (err < 0) {
+                  kfree(chip);
+                  pci_disable_device(pci);
+                  return err;
+          }
+          chip->port = pci_resource_start(pci, 0);
+          if (request_irq(pci->irq, snd_mychip_interrupt,
+                          IRQF_SHARED, "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) */
+
+          err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+          if (err < 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),
+  };
+
+  /* module initialization */
+  static int __init alsa_card_mychip_init(void)
+  {
+          return pci_register_driver(&driver);
+  }
+
+  /* module clean up */
+  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 first have to call
+      the <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[
+  err = pci_enable_device(pci);
+  if (err < 0)
+          return err;
+  if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
+      pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 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 is 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 in ALSA 0.5.x.
+      </para>
+
+      <para>
+        Now assume that the 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[
+  err = pci_request_regions(pci, "My Chip");
+  if (err < 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-&gt;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 a
+      problem with this. This issue will be explained later.
+      </para>
+
+      <para>
+        The allocation of an interrupt source is done like this:
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (request_irq(pci->irq, snd_mychip_interrupt,
+                  IRQF_SHARED, "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-&gt;irq should be defined
+      only when <function>request_irq()</function> succeeded.
+      </para>
+
+      <para>
+      On the PCI bus, interrupts can be shared. Thus,
+      <constant>IRQF_SHARED</constant> is used 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 give details about 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 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 code is not written here. 
+      </para>
+
+      <para>
+        To release the resources, the <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, chip);
+]]>
+          </programlisting>
+        </informalexample>
+
+        Since the irq number can start from 0, you should initialize
+        chip-&gt;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 in 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-&gt;res_port, the release procedure looks like:
+
+        <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 the end.
+      </para>
+
+      <para>
+        And finally, release the chip-specific record.
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  kfree(chip);
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+      Again, remember that you cannot
+      use the <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 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 already been released.
+      You don't have to stop PCMs, etc. explicitly, but just
+      call low-level hardware stopping.
+      </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 missing PCI
+      stuff. 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
+      the <structname>pci_device_id</structname> structure are the vendor and
+      device IDs. If you have no reason to filter the matching
+      devices, you can leave the remaining fields as above. The last
+      field of the <structname>pci_device_id</structname> struct contains
+      private data for this entry. You can specify any value here, for
+      example, to define specific operations for supported device IDs.
+      Such an example is found in the 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 have already
+      been defined in the previous sections.
+      The <structfield>remove</structfield> function should
+      be defined with the 
+      <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 in 2.2 or 2.4 kernels (it's not necessary in 2.6 kernels).
+
+        <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>&lt;sound/pcm.h&gt;</filename> first. In addition,
+      <filename>&lt;sound/pcm_params.h&gt;</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 numbers. Once when 64bit device number is
+      used, we'll have more pcm instances available. 
+      </para>
+
+      <para>
+        A pcm instance consists of pcm playback and capture streams,
+      and each pcm stream consists of one or more pcm substreams. Some
+      soundcards support multiple playback functions. 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 successful open will either block
+      or error with <constant>EAGAIN</constant> according to the
+      file open mode. But you don't have to care about such details in your
+      driver. The PCM middle layer will take care of such work.
+      </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_addr,
+                               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;
+
+          err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
+          if (err < 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 the <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;
+
+          err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
+          if (err < 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 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. If
+      you 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 1 is used for
+      both arguments. When no playback or capture substreams are 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>
+
+        All the callbacks are described in the
+        <link linkend="pcm-interface-operators"><citetitle>
+        Operators</citetitle></link> subsection.
+      </para>
+
+      <para>
+        After setting the operators, you probably will want 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 a buffer up to 64kB as default.
+      Buffer management details 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-&gt;info_flags.
+        The available values are defined as
+        <constant>SNDRV_PCM_INFO_XXX</constant> in
+        <filename>&lt;sound/asound.h&gt;</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 the destructor
+      explicitly.
+      </para>
+
+      <para>
+        The destructor would be necessary if you created
+        special records internally and needed to release them. In such a
+        case, set the destructor function to
+        pcm-&gt;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-&gt;runtime</constant>.
+	This runtime pointer holds most information you need
+	to control the PCM: the copy of hw_params and sw_params configurations, the buffer
+	pointers, mmap records, spinlocks, etc.
+	</para>
+
+	<para>
+	The definition of runtime instance is found in
+	<filename>&lt;sound/pcm.h&gt;</filename>.  Here are
+       the contents of this 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 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 them.  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-&gt;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 as 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>&lt;sound/asound.h&gt;</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 is supported, add the
+        <constant>SNDRV_PCM_INFO_MMAP</constant> flag here. When the
+        hardware supports the interleaved or the non-interleaved
+        formats, <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 the 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 the <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
+	the <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,
+	synchronized 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
+        the <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 minimum and
+	maximum 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 minimum and maximum
+	number of channels.
+	</para>
+	</listitem>
+
+	<listitem>
+	<para>
+	<structfield>buffer_bytes_max</structfield> defines the
+	maximum buffer size in bytes.  There is no
+	<structfield>buffer_bytes_min</structfield> field, since
+	it can be calculated from the minimum period size and the
+	minimum number of periods.
+	Meanwhile, <structfield>period_bytes_min</structfield> and
+	define the minimum and maximum size of the period in bytes.
+	<structfield>periods_max</structfield> and
+	<structfield>periods_min</structfield> define the maximum and
+	minimum number of periods in the buffer.
+        </para>
+
+	<para>
+	The <quote>period</quote> is a term that corresponds to
+	a fragment in the OSS world. The period defines the size at
+	which a 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 currently it
+	is neither used 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 in the 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
+	<function>frames_to_bytes()</function> and
+          <function>bytes_to_frames()</function> helper functions. 
+          <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 optional.  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-&gt;status</constant>.
+	This is the pointer to the struct <structname>snd_pcm_mmap_status</structname>
+	record.  For example, you can get the current DMA hardware
+	pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
+	</para>
+
+	<para>
+	The DMA application pointer can be referred via
+	<constant>runtime-&gt;control</constant>, which points to the
+	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-&gt;private_data</constant>.  Usually, this
+	is done in
+	<link linkend="pcm-interface-operators-open-callback"><citetitle>
+	the open callback</citetitle></link>.
+	Don't mix this with <constant>pcm-&gt;private_data</constant>.
+	The <constant>pcm-&gt;private_data</constant> usually points to the
+	chip instance assigned statically at the creation of PCM, while the 
+	<constant>runtime-&gt;private_data</constant> points to a dynamic
+	data structure 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 at 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 give details about each pcm callback
+      (<parameter>ops</parameter>). In general, every callback must
+      return 0 if successful, or a negative error number
+      such as <constant>-EINVAL</constant>. To choose an appropriate
+      error number, it is advised to check what value other parts of
+      the kernel return when the same kind of request fails.
+      </para>
+
+      <para>
+        The callback function takes at least the argument with
+        <structname>snd_pcm_substream</structname> pointer. To retrieve
+        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-&gt;private_data</constant>,
+	which is a copy of <constant>pcm-&gt;private_data</constant>.
+	You can override the former if you need to assign different data
+	records per PCM substream.  For example, the 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-&gt;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 call 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>
+        </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 setups 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. To allocate
+          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 be careful not to allocate the same buffers
+        many times, which will lead to memory leaks!  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, mutexes 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 each
+        time 
+        <function>snd_pcm_prepare()</function> is called, i.e. when
+        recovering after underruns, etc. 
+        </para>
+
+        <para>
+	Note that this callback is now non-atomic.
+	You can use schedule-related functions safely in this callback.
+        </para>
+
+        <para>
+          In this and the following callbacks, you can refer to the
+        values via the runtime record,
+        substream-&gt;runtime.
+        For example, to get the current
+        rate, format or channels, access to
+        runtime-&gt;rate,
+        runtime-&gt;format or
+        runtime-&gt;channels, respectively. 
+        The physical address of the allocated buffer is set to
+	runtime-&gt;dma_area.  The buffer and period sizes are
+	in runtime-&gt;buffer_size and runtime-&gt;period_size,
+	respectively.
+        </para>
+
+        <para>
+          Be careful that this callback will be called many times at
+        each setup, 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>&lt;sound/pcm.h&gt;</filename>. At least,
+          the <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 the info
+        field of the hardware table), the <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,
+        the <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> commands
+        suspend and resume the pcm substream, and usually, they
+        are identical to the <constant>STOP</constant> and
+        <constant>START</constant> commands, respectively.
+	  See the <link linkend="power-management"><citetitle>
+	Power Management</citetitle></link> section for details.
+        </para>
+
+        <para>
+          As mentioned, this callback is atomic.  You cannot call
+	  functions which may 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,
+        ranging 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 in 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 optional too. This callback is used
+        mainly for non-contiguous buffers. 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 the <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 acquire 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>
+          Typical code would be like:
+
+          <example>
+	    <title>Interrupt Handler Case #1</title>
+            <programlisting>
+<![CDATA[
+  static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
+  {
+          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 frequency timer interrupts</title>
+        <para>
+	This happense when the hardware doesn't generate interrupts
+        at the period boundary but issues timer interrupts at a fixed
+        timer rate (e.g. es1968 or ymfpci drivers). 
+        In this case, you need to check the current hardware
+        position and accumulate the processed sample length at each
+        interrupt.  When the accumulated size exceeds the period
+        size, call 
+        <function>snd_pcm_period_elapsed()</function> and reset the
+        accumulator. 
+        </para>
+
+        <para>
+          Typical code 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 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) problems
+      in kernel programming are race conditions.
+      In the Linux kernel, they are usually avoided via spin-locks, mutexes
+      or semaphores.  In general, if a race condition can happen
+      in an interrupt handler, it has to be managed atomically, and you
+      have to use a spinlock to protect the critical session. If the
+      critical section is not in interrupt handler code and
+      if taking a relatively long time to execute is acceptable, you
+      should use mutexes or semaphores instead.
+      </para>
+
+      <para>
+      As already seen, some pcm callbacks are atomic and some are
+      not.  For example, the <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 choose a locking scheme 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>.  Semaphores and mutexes can sleep,
+      and hence they cannot be used inside the atomic callbacks
+      (e.g. <parameter>trigger</parameter> callback).
+      To implement some 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 at <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> structure (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 give 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 user-space. Its most
+      important use is the mixer interface. In other words, since ALSA
+      0.9.x, all the mixer stuff is implemented on the control kernel API.
+      </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>&lt;sound/control.h&gt;</filename>.
+      Include this file if you want to add your own controls.
+      </para>
+    </section>
+
+    <section id="control-interface-definition">
+      <title>Definition of Controls</title>
+      <para>
+        To create a new control, you need to define the
+	following 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_value = 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 the <parameter>__devinitdata</parameter> prefix to the
+      definition as above. 
+      </para>
+
+      <para>
+        The <structfield>iface</structfield> field specifies the control
+      type, <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. Since 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 <link linkend="control-interface-control-names"><citetitle>
+      Control Names</citetitle></link> subsection.
+      </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 details will be explained in
+      the <link linkend="control-interface-access-flags"><citetitle>
+      Access Flags</citetitle></link> subsection.
+      </para>
+
+      <para>
+        The <structfield>private_value</structfield> field contains
+      an arbitrary long integer value for this record. When using
+      the 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 <structfield>tlv</structfield> field can be used to provide
+      metadata about the control; see the
+      <link linkend="control-interface-tlv">
+      <citetitle>Metadata</citetitle></link> subsection.
+      </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 to define 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> and
+      <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 bitmask 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
+      considered 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
+      the <structfield>put</structfield> callback.
+      Similarly, when the control is write-only (although it's a rare
+      case), you can use the <constant>WRITE</constant> flag instead, and
+      you don't need the <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
+      the <constant>INACTIVE</constant> flag, too.
+      There are <constant>LOCK</constant> and
+      <constant>OWNER</constant> flags to change 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
+        detailed information on 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: 
+
+          <example>
+	    <title>Example of info callback</title>
+            <programlisting>
+<![CDATA[
+  static int snd_myctl_mono_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 types 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_enum_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>
+
+        <para>
+	  Some common info callbacks are available for your convenience:
+	<function>snd_ctl_boolean_mono_info()</function> and
+	<function>snd_ctl_boolean_stereo_info()</function>.
+	Obviously, the former is an info callback for a mono channel
+	boolean item, just like <function>snd_myctl_mono_info</function>
+	above, and the latter is for a stereo channel boolean item.
+	</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 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>
+	The <structfield>value</structfield> field depends on 
+        the type of control as well as on the 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> field is set as follows:
+          <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 the <structfield>get</structfield> callback,
+	you have to fill all the elements if the
+        control has more than one elements,
+        i.e. <structfield>count</structfield> &gt; 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 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>
+	As in the <structfield>get</structfield> callback,
+	when the control has more than one elements,
+	all elements 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. To create 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[
+  err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
+  if (err < 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-&gt;private_data 
+      which can be referred to 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
+      the <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>
+
+    <section id="control-interface-tlv">
+      <title>Metadata</title>
+      <para>
+      To provide information about the dB values of a mixer control, use
+      on of the <constant>DECLARE_TLV_xxx</constant> macros from
+      <filename>&lt;sound/tlv.h&gt;</filename> to define a variable
+      containing this information, set the<structfield>tlv.p
+      </structfield> field to point to this variable, and include the
+      <constant>SNDRV_CTL_ELEM_ACCESS_TLV_READ</constant> flag in the
+      <structfield>access</structfield> field; like this:
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
+
+  static struct snd_kcontrol_new my_control __devinitdata = {
+          ...
+          .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                    SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+          ...
+          .tlv.p = db_scale_my_control,
+  };
+]]>
+        </programlisting>
+      </informalexample>
+      </para>
+
+      <para>
+      The <function>DECLARE_TLV_DB_SCALE</function> macro defines
+      information about a mixer control where each step in the control's
+      value changes the dB value by a constant dB amount.
+      The first parameter is the name of the variable to be defined.
+      The second parameter is the minimum value, in units of 0.01 dB.
+      The third parameter is the step size, in units of 0.01 dB.
+      Set the fourth parameter to 1 if the minimum value actually mutes
+      the control.
+      </para>
+
+      <para>
+      The <function>DECLARE_TLV_DB_LINEAR</function> macro defines
+      information about a mixer control where the control's value affects
+      the output linearly.
+      The first parameter is the name of the variable to be defined.
+      The second parameter is the minimum value, in units of 0.01 dB.
+      The third parameter is the maximum value, in units of 0.01 dB.
+      If the minimum value mutes the control, set the second parameter to
+      <constant>TLV_DB_GAIN_MUTE</constant>.
+      </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 much code to control it. Only low-level control
+      routines are necessary. The AC97 codec API is defined in
+      <filename>&lt;sound/ac97_codec.h&gt;</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,
+          };
+
+          err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
+          if (err < 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>
+        To create 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-&gt;ac97 is a pointer to 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.  If 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-&gt;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 control API callbacks.
+      </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 kind of reset, you can
+      define this callback. 
+      </para>
+
+      <para>
+        The <structfield>wait</structfield> callback is used to
+      add some waiting time in the standard initialization of the codec. If the
+      chip requires the extra waiting 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 in 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
+        given 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 to set 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
+      <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>
+        In some chips, the clock of the codec isn't 48000 but using a
+      PCI clock (to save a quartz!). In this case, change the field
+      bus-&gt;clock to the corresponding
+      value. For example, intel8x0 
+      and es1968 drivers have their own function to read from 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 set up multiple codecs, you either need to write
+      different callbacks for each codec or check
+      ac97-&gt;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>&lt;sound/mpu401.h&gt;</filename>. 
+      </para>
+
+      <para>
+        Some soundchips have a similar but slightly different
+      implementation of mpu401 stuff. For example, emu10k1 has its own
+      mpu401 routines. 
+      </para>
+    </section>
+
+    <section id="midi-interface-constructor">
+      <title>Constructor</title>
+      <para>
+        To create 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, info_flags,
+                      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 have 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>
+	The 5th argument is a bitflag for additional information.
+        When the I/O port address above is 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 a bit flag
+      <constant>MPU401_INFO_INTEGRATED</constant>,
+      and the mpu401-uart layer will allocate the I/O ports by itself. 
+      </para>
+
+	<para>
+	When the controller supports only the input or output MIDI stream,
+	pass the <constant>MPU401_INFO_INPUT</constant> or
+	<constant>MPU401_INFO_OUTPUT</constant> bitflag, respectively.
+	Then the rawmidi instance is created as a single stream.
+	</para>
+
+	<para>
+	<constant>MPU401_INFO_MMIO</constant> bitflag is used to change
+	the access method to MMIO (via readb and writeb) instead of
+	iob and outb. In this case, you have to pass the iomapped address
+	to <function>snd_mpu401_uart_new()</function>.
+	</para>
+
+	<para>
+	When <constant>MPU401_INFO_TX_IRQ</constant> is set, the output
+	stream isn't checked in the default interrupt handler.  The driver
+	needs to call <function>snd_mpu401_uart_interrupt_tx()</function>
+	by itself to start processing the output stream in the irq handler.
+	</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-&gt;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 generate
+      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 anything else to do
+      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>&lt;sound/rawmidi.h&gt;</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 the substreams 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 are more than one substream, you should give a
+      unique name to each of them:
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_rawmidi_substream *substream;
+  list_for_each_entry(substream,
+                      &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
+                      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 the callbacks, the private data that you've set for the
+      rawmidi device can be accessed as
+      substream-&gt;rmidi-&gt;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 shouldn't
+        start transmitting/receiving data yet.
+        </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 are no more
+        data in the buffer.
+        After the data have 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 them 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 have 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&nbsp;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 in many chips (mainly for backward
+      compatibility). ALSA has a nice OPL3 FM control layer, too. The
+      OPL3 API is defined in
+      <filename>&lt;sound/opl3.h&gt;</filename>. 
+      </para>
+
+      <para>
+        FM registers can be directly accessed through the direct-FM API,
+      defined in <filename>&lt;sound/asound_fm.h&gt;</filename>. In
+      ALSA native mode, FM registers are accessed through
+      the Hardware-Dependant Device direct-FM extension API, whereas in
+      OSS compatible mode, FM registers can be accessed with the OSS
+      direct-FM compatible API in <filename>/dev/dmfmX</filename> device. 
+      </para>
+
+      <para>
+        To create the OPL3 component, you have two functions to
+        call. The first one is a constructor for the <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, the opl3 module will
+      allocate the specified ports by itself. 
+      </para>
+
+      <para>
+        When the accessing 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 the opl3-&gt;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 user-space access 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>&lt;sound/hwdep.h&gt;</filename>. You can
+      find examples in opl3 driver or
+      <filename>isa/sb/sb16_csp.c</filename>. 
+      </para>
+
+      <para>
+        The 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 in
+        the <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 the 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
+        the <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
+      the control interface. There is a macro to compose a name string for
+      IEC958 controls, <function>SNDRV_CTL_NAME_IEC958()</function>
+      defined in <filename>&lt;include/asound.h&gt;</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 the <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
+      the <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
+      enough space is found.
+      </para>
+
+      <para>
+      The release the pages, 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 
+       pcm instance construction time (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 maximum
+      size to be changed via the <filename>prealloc</filename> proc file.
+      The allocator will try to get an area as large 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 the 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,
+      where <constant>GFP_KERNEL</constant> is the kernel allocation flag to
+      use.
+      For the PCI scatter-gather buffers, use
+      <constant>SNDRV_DMA_TYPE_DEV_SG</constant> with
+      <function>snd_dma_pci_data(pci)</function>
+      (see the 
+          <link linkend="buffer-and-memory-non-contiguous"><citetitle>Non-Contiguous Buffers
+          </citetitle></link> section).
+      </para>
+
+      <para>
+        Once 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 large
+      enough.  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 for mmap on the buffer, although you have
+      to handle an interrupt or a tasklet to transfer the data
+      from the intermediate buffer to the hardware buffer. You can find an
+      example in the vxpocket driver. 
+      </para>
+
+      <para>
+        Another case is when 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 the Intel one.
+      In non-mmap mode, the data cannot be transferred as in the normal
+      way. Thus you need to define the <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 the <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
+        playback case, you 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 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 the position and the amount of data 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 the same as in 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 as in emu10k1 or the
+      buffer descriptors as in via82xx, you can use the scatter-gather
+      (SG) DMA. ALSA provides an interface for handling SG-buffers.
+      The API is provided in <filename>&lt;sound/pcm.h&gt;</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 <function>snd_dma_pci_data(pci)</function>,
+        where pci is the struct <structname>pci_dev</structname> pointer
+        of the chip as well.
+        The <type>struct snd_sg_buf</type> instance is created as
+        substream-&gt;dma_private. You can cast
+        the pointer like: 
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
+]]>
+          </programlisting>
+        </informalexample>
+      </para>
+
+      <para>
+        Then call <function>snd_pcm_lib_malloc_pages()</function>
+      in the <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-&gt;dma_area.
+      The physical address (runtime-&gt;dma_addr) is set to zero,
+      because the buffer is physically non-contigous.
+      The physical address table is set up in sgbuf-&gt;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>
+        To release 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>&lt;sound/info.h&gt;</filename>. 
+    </para>
+
+    <para>
+      To create 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 name of the proc file 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 in the pointer given in the third argument.
+    It is initialized as a text proc file for read only.  To use
+    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, 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 permissions can be changed afterwards.  As default, it's
+    set as read only for all users.  If you want to add write
+    permission for the user (root as default), do as follows:
+
+      <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 = my_proc_write;
+]]>
+        </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 as follows:
+
+      <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 suspend/resume
+      functions, you need to add power-management code to the
+      driver. The additional code for power-management should be
+      <function>ifdef</function>'ed with
+      <constant>CONFIG_PM</constant>. 
+    </para>
+
+	<para>
+	If the driver <emphasis>fully</emphasis> supports suspend/resume
+	that is, the device can be
+	properly resumed to its state when suspend was called,
+	you can set the <constant>SNDRV_PCM_INFO_RESUME</constant> flag
+	in the pcm info field.  Usually, this is possible when the
+	registers of the chip can be safely saved and restored to
+	RAM. If this is set, the trigger callback is called with
+	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> after the resume
+	callback completes. 
+	</para>
+
+	<para>
+	Even if the driver doesn't support PM fully but 
+	partial suspend/resume is still 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 always be called when
+	<function>snd_pcm_suspend_all</function> is called,
+	regardless of the <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 reasons.)
+	</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 connected to.  In the case of PCI drivers, 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 suspend */
+          return 0;
+  }
+  static int snd_my_resume(struct pci_dev *pci)
+  {
+          .... /* do things for suspend */
+          return 0;
+  }
+  #endif
+]]>
+        </programlisting>
+      </informalexample>
+    </para>
+
+    <para>
+      The scheme of the real suspend job is as follows.
+
+      <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_suspend()</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 follows.
+
+    <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, remember 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 to save 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 the <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 easier 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 would be better 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 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 the 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 the alsa-kernel tree (to the corresponding directory,
+	such as <filename>alsa-kernel/pci</filename>) and eventually
+ 	will be integrated into the 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 covered:
+	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> as 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 the
+      <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_VERBOSE</constant> is set. Please note
+      that <constant>CONFIG_SND_DEBUG_VERBOSE</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-bug">
+      <title><function>snd_BUG()</function></title>
+      <para>
+        It shows the <computeroutput>BUG?</computeroutput> message and
+      stack trace as well as <function>snd_BUG_ON</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>
+
+    <section id="useful-functions-snd-bug-on">
+      <title><function>snd_BUG_ON()</function></title>
+      <para>
+        <function>snd_BUG_ON()</function> macro is similar with
+	<function>WARN_ON()</function> macro. For example,  
+
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  snd_BUG_ON(!pointer);
+]]>
+          </programlisting>
+        </informalexample>
+
+	or it can be used as the condition,
+        <informalexample>
+          <programlisting>
+<![CDATA[
+  if (snd_BUG_ON(non_zero_is_bug))
+          return -EINVAL;
+]]>
+          </programlisting>
+        </informalexample>
+
+      </para>
+
+      <para>
+        The macro takes an conditional expression to evaluate.
+	When <constant>CONFIG_SND_DEBUG</constant>, is set, the
+	expression is actually evaluated. If it's non-zero, it shows
+	the warning message such as
+	<computeroutput>BUG? (xxx)</computeroutput>
+	normally followed by stack trace.  It returns the evaluated
+	value.
+	When no <constant>CONFIG_SND_DEBUG</constant> is set, this
+	macro always returns zero.
+      </para>
+
+    </section>
+
+  </chapter>
+
+
+<!-- ****************************************************** -->
+<!-- Acknowledgments  -->
+<!-- ****************************************************** -->
+  <chapter id="acknowledgments">
+    <title>Acknowledgments</title>
+    <para>
+      I would like to thank Phil Kerr for his help for improvement and
+      corrections of this document. 
+    </para>
+    <para>
+    Kevin Conder reformatted the original plain-text to the
+    DocBook format.
+    </para>
+    <para>
+    Giuliano Pochini corrected typos and contributed the example codes
+    in the hardware constraints section.
+    </para>
+  </chapter>
+</book>
diff --git a/Documentation/sound/alsa/Joystick.txt b/Documentation/sound/alsa/Joystick.txt
new file mode 100644
index 0000000..ccda41b
--- /dev/null
+++ b/Documentation/sound/alsa/Joystick.txt
@@ -0,0 +1,86 @@
+Analog Joystick Support on ALSA Drivers
+=======================================
+                          Oct. 14, 2003
+           Takashi Iwai <tiwai@suse.de>
+
+General
+-------
+
+First of all, you need to enable GAMEPORT support on Linux kernel for
+using a joystick with the ALSA driver.  For the details of gameport
+support, refer to Documentation/input/joystick.txt.
+
+The joystick support of ALSA drivers is different between ISA and PCI
+cards.  In the case of ISA (PnP) cards, it's usually handled by the
+independent module (ns558).  Meanwhile, the ALSA PCI drivers have the
+built-in gameport support.  Hence, when the ALSA PCI driver is built
+in the kernel, CONFIG_GAMEPORT must be 'y', too.  Otherwise, the
+gameport support on that card will be (silently) disabled.
+
+Some adapter modules probe the physical connection of the device at
+the load time.  It'd be safer to plug in the joystick device before
+loading the module.
+
+
+PCI Cards
+---------
+
+For PCI cards, the joystick is enabled when the appropriate module
+option is specified.  Some drivers don't need options, and the
+joystick support is always enabled.  In the former ALSA version, there
+was a dynamic control API for the joystick activation.  It was
+changed, however, to the static module options because of the system
+stability and the resource management.
+
+The following PCI drivers support the joystick natively.
+
+    Driver	Module Option	Available Values
+    ---------------------------------------------------------------------------
+    als4000	joystick_port	0 = disable (default), 1 = auto-detect,
+                                manual: any address (e.g. 0x200)
+    au88x0	N/A		N/A
+    azf3328	joystick	0 = disable, 1 = enable, -1 = auto (default)
+    ens1370	joystick	0 = disable (default), 1 = enable
+    ens1371	joystick_port	0 = disable (default), 1 = auto-detect,
+                                manual: 0x200, 0x208, 0x210, 0x218
+    cmipci	joystick_port	0 = disable (default), 1 = auto-detect,
+                                manual: any address (e.g. 0x200)
+    cs4281	N/A		N/A
+    cs46xx	N/A		N/A
+    es1938	N/A		N/A
+    es1968	joystick	0 = disable (default), 1 = enable
+    sonicvibes	N/A		N/A
+    trident	N/A		N/A
+    via82xx(*1)	joystick	0 = disable (default), 1 = enable
+    ymfpci	joystick_port	0 = disable (default), 1 = auto-detect,
+                                manual: 0x201, 0x202, 0x204, 0x205(*2)
+    ---------------------------------------------------------------------------
+
+    *1)  VIA686A/B only
+    *2)  With YMF744/754 chips, the port address can be chosen arbitrarily
+
+The following drivers don't support gameport natively, but there are
+additional modules.  Load the corresponding module to add the gameport
+support.
+
+    Driver	Additional Module
+    -----------------------------
+    emu10k1	emu10k1-gp
+    fm801	fm801-gp
+    -----------------------------
+
+Note: the "pcigame" and "cs461x" modules are for the OSS drivers only.
+      These ALSA drivers (cs46xx, trident and au88x0) have the
+      built-in gameport support.
+
+As mentioned above, ALSA PCI drivers have the built-in gameport
+support, so you don't have to load ns558 module.  Just load "joydev"
+and the appropriate adapter module (e.g. "analog").
+
+
+ISA Cards
+---------
+
+ALSA ISA drivers don't have the built-in gameport support.
+Instead, you need to load "ns558" module in addition to "joydev" and
+the adapter module (e.g. "analog").
diff --git a/Documentation/sound/alsa/MIXART.txt b/Documentation/sound/alsa/MIXART.txt
new file mode 100644
index 0000000..ef42c44
--- /dev/null
+++ b/Documentation/sound/alsa/MIXART.txt
@@ -0,0 +1,100 @@
+    Alsa driver for Digigram miXart8 and miXart8AES/EBU soundcards
+	    Digigram <alsa@digigram.com>
+
+
+GENERAL
+=======
+
+The miXart8 is a multichannel audio processing and mixing soundcard
+that has 4 stereo audio inputs and 4 stereo audio outputs.
+The miXart8AES/EBU is the same with a add-on card that offers further
+4 digital stereo audio inputs and outputs.
+Furthermore the add-on card offers external clock synchronisation
+(AES/EBU, Word Clock, Time Code and Video Synchro)
+
+The mainboard has a PowerPC that offers onboard mpeg encoding and
+decoding, samplerate conversions and various effects.
+
+The driver don't work properly at all until the certain firmwares
+are loaded, i.e. no PCM nor mixer devices will appear.
+Use the mixartloader that can be found in the alsa-tools package.
+
+
+VERSION 0.1.0
+=============
+
+One miXart8 board will be represented as 4 alsa cards, each with 1
+stereo analog capture 'pcm0c' and 1 stereo analog playback 'pcm0p' device.
+With a miXart8AES/EBU there is in addition 1 stereo digital input
+'pcm1c' and 1 stereo digital output 'pcm1p' per card.
+
+Formats
+-------
+U8, S16_LE, S16_BE, S24_3LE, S24_3BE, FLOAT_LE, FLOAT_BE
+Sample rates : 8000 - 48000 Hz continuously
+
+Playback
+--------
+For instance the playback devices are configured to have max. 4
+substreams performing hardware mixing. This could be changed to a
+maximum of 24 substreams if wished.
+Mono files will be played on the left and right channel. Each channel
+can be muted for each stream to use 8 analog/digital outputs separately.
+
+Capture
+-------
+There is one substream per capture device. For instance only stereo
+formats are supported.
+
+Mixer
+-----
+<Master> and <Master Capture> : analog volume control of playback and capture PCM.
+<PCM 0-3> and <PCM Capture> : digital volume control of each analog substream.
+<AES 0-3> and <AES Capture> : digital volume control of each AES/EBU substream.
+<Monitoring> : Loopback from 'pcm0c' to 'pcm0p' with digital volume
+and mute control.
+
+Rem : for best audio quality try to keep a 0 attenuation on the PCM
+and AES volume controls which is set by 219 in the range from 0 to 255
+(about 86% with alsamixer)
+
+
+NOT YET IMPLEMENTED
+===================
+
+- external clock support (AES/EBU, Word Clock, Time Code, Video Sync)
+- MPEG audio formats
+- mono record
+- on-board effects and samplerate conversions
+- linked streams
+
+
+FIRMWARE
+========
+
+[As of 2.6.11, the firmware can be loaded automatically with hotplug
+ when CONFIG_FW_LOADER is set.  The mixartloader is necessary only
+ for older versions or when you build the driver into kernel.]
+ 
+For loading the firmware automatically after the module is loaded, use
+the post-install command.  For example, add the following entry to
+/etc/modprobe.conf for miXart driver:
+
+	install snd-mixart /sbin/modprobe --first-time -i snd-mixart && \
+			   /usr/bin/mixartloader
+(for 2.2/2.4 kernels, add "post-install snd-mixart /usr/bin/vxloader" to
+ /etc/modules.conf, instead.)
+
+The firmware binaries are installed on /usr/share/alsa/firmware
+(or /usr/local/share/alsa/firmware, depending to the prefix option of
+configure).  There will be a miXart.conf file, which define the dsp image
+files.
+
+The firmware files are copyright by Digigram SA
+
+
+COPYRIGHT
+=========
+
+Copyright (c) 2003 Digigram SA <alsa@digigram.com>
+Distributable under GPL.
diff --git a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt
new file mode 100644
index 0000000..022aaeb
--- /dev/null
+++ b/Documentation/sound/alsa/OSS-Emulation.txt
@@ -0,0 +1,305 @@
+		NOTES ON KERNEL OSS-EMULATION
+		=============================
+
+		Jan. 22, 2004  Takashi Iwai <tiwai@suse.de>
+
+
+Modules
+=======
+
+ALSA provides a powerful OSS emulation on the kernel.
+The OSS emulation for PCM, mixer and sequencer devices is implemented
+as add-on kernel modules, snd-pcm-oss, snd-mixer-oss and snd-seq-oss.
+When you need to access the OSS PCM, mixer or sequencer devices, the
+corresponding module has to be loaded.
+
+These modules are loaded automatically when the corresponding service
+is called.  The alias is defined sound-service-x-y, where x and y are
+the card number and the minor unit number.  Usually you don't have to
+define these aliases by yourself.
+
+Only necessary step for auto-loading of OSS modules is to define the
+card alias in /etc/modprobe.conf, such as
+
+	alias sound-slot-0 snd-emu10k1
+
+As the second card, define sound-slot-1 as well.
+Note that you can't use the aliased name as the target name (i.e.
+"alias sound-slot-0 snd-card-0" doesn't work any more like the old
+modutils).
+
+The currently available OSS configuration is shown in
+/proc/asound/oss/sndstat.  This shows in the same syntax of
+/dev/sndstat, which is available on the commercial OSS driver.
+On ALSA, you can symlink /dev/sndstat to this proc file.
+
+Please note that the devices listed in this proc file appear only
+after the corresponding OSS-emulation module is loaded.  Don't worry
+even if "NOT ENABLED IN CONFIG" is shown in it.
+
+
+Device Mapping
+==============
+
+ALSA supports the following OSS device files:
+
+	PCM:
+		/dev/dspX
+		/dev/adspX
+
+	Mixer:
+		/dev/mixerX
+
+	MIDI:
+		/dev/midi0X
+		/dev/amidi0X
+
+	Sequencer:
+		/dev/sequencer
+		/dev/sequencer2 (aka /dev/music)
+
+where X is the card number from 0 to 7.
+
+(NOTE: Some distributions have the device files like /dev/midi0 and
+       /dev/midi1.  They are NOT for OSS but for tclmidi, which is
+       a totally different thing.)
+
+Unlike the real OSS, ALSA cannot use the device files more than the
+assigned ones.  For example, the first card cannot use /dev/dsp1 or
+/dev/dsp2, but only /dev/dsp0 and /dev/adsp0.
+
+As seen above, PCM and MIDI may have two devices.  Usually, the first
+PCM device (hw:0,0 in ALSA) is mapped to /dev/dsp and the secondary
+device (hw:0,1) to /dev/adsp (if available).  For MIDI, /dev/midi and
+/dev/amidi, respectively.
+
+You can change this device mapping via the module options of
+snd-pcm-oss and snd-rawmidi.  In the case of PCM, the following
+options are available for snd-pcm-oss:
+
+	dsp_map		PCM device number assigned to /dev/dspX
+			(default = 0)
+	adsp_map	PCM device number assigned to /dev/adspX
+			(default = 1)
+
+For example, to map the third PCM device (hw:0,2) to /dev/adsp0,
+define like this:
+
+	options snd-pcm-oss adsp_map=2
+
+The options take arrays.  For configuring the second card, specify
+two entries separated by comma.  For example, to map the third PCM
+device on the second card to /dev/adsp1, define like below:
+
+	options snd-pcm-oss adsp_map=0,2
+
+To change the mapping of MIDI devices, the following options are
+available for snd-rawmidi:
+
+	midi_map	MIDI device number assigned to /dev/midi0X
+			(default = 0)
+	amidi_map	MIDI device number assigned to /dev/amidi0X
+			(default = 1)
+
+For example, to assign the third MIDI device on the first card to
+/dev/midi00, define as follows:
+
+	options snd-rawmidi midi_map=2
+
+
+PCM Mode
+========
+
+As default, ALSA emulates the OSS PCM with so-called plugin layer,
+i.e. tries to convert the sample format, rate or channels
+automatically when the card doesn't support it natively.
+This will lead to some problems for some applications like quake or
+wine, especially if they use the card only in the MMAP mode.
+
+In such a case, you can change the behavior of PCM per application by
+writing a command to the proc file.  There is a proc file for each PCM
+stream, /proc/asound/cardX/pcmY[cp]/oss, where X is the card number
+(zero-based), Y the PCM device number (zero-based), and 'p' is for
+playback and 'c' for capture, respectively.  Note that this proc file
+exists only after snd-pcm-oss module is loaded.
+
+The command sequence has the following syntax:
+
+	app_name fragments fragment_size [options]
+
+app_name is the name of application with (higher priority) or without
+path.
+fragments specifies the number of fragments or zero if no specific
+number is given.
+fragment_size is the size of fragment in bytes or zero if not given.
+options is the optional parameters.  The following options are
+available:
+
+	disable		the application tries to open a pcm device for
+			this channel but does not want to use it.
+	direct		don't use plugins
+	block		force block open mode
+	non-block	force non-block open mode
+	partial-frag	write also partial fragments (affects playback only)
+	no-silence	do not fill silence ahead to avoid clicks
+
+The disable option is useful when one stream direction (playback or
+capture) is not handled correctly by the application although the
+hardware itself does support both directions.
+The direct option is used, as mentioned above, to bypass the automatic
+conversion and useful for MMAP-applications.
+For example, to playback the first PCM device without plugins for
+quake, send a command via echo like the following:
+
+	% echo "quake 0 0 direct" > /proc/asound/card0/pcm0p/oss
+
+While quake wants only playback, you may append the second command
+to notify driver that only this direction is about to be allocated:
+
+	% echo "quake 0 0 disable" > /proc/asound/card0/pcm0c/oss
+
+The permission of proc files depend on the module options of snd.
+As default it's set as root, so you'll likely need to be superuser for
+sending the command above.
+
+The block and non-block options are used to change the behavior of
+opening the device file.
+
+As default, ALSA behaves as original OSS drivers, i.e. does not block
+the file when it's busy. The -EBUSY error is returned in this case.
+
+This blocking behavior can be changed globally via nonblock_open
+module option of snd-pcm-oss.  For using the blocking mode as default
+for OSS devices, define like the following:
+
+	options snd-pcm-oss nonblock_open=0
+
+The partial-frag and no-silence commands have been added recently.
+Both commands are for optimization use only.  The former command
+specifies to invoke the write transfer only when the whole fragment is
+filled.  The latter stops writing the silence data ahead
+automatically.  Both are disabled as default.
+
+You can check the currently defined configuration by reading the proc
+file.  The read image can be sent to the proc file again, hence you
+can save the current configuration
+
+	% cat /proc/asound/card0/pcm0p/oss > /somewhere/oss-cfg
+
+and restore it like
+
+	% cat /somewhere/oss-cfg > /proc/asound/card0/pcm0p/oss
+
+Also, for clearing all the current configuration, send "erase" command
+as below:
+
+	% echo "erase" > /proc/asound/card0/pcm0p/oss
+
+
+Mixer Elements
+==============
+
+Since ALSA has completely different mixer interface, the emulation of
+OSS mixer is relatively complicated.  ALSA builds up a mixer element
+from several different ALSA (mixer) controls based on the name
+string.  For example, the volume element SOUND_MIXER_PCM is composed
+from "PCM Playback Volume" and "PCM Playback Switch" controls for the
+playback direction and from "PCM Capture Volume" and "PCM Capture
+Switch" for the capture directory (if exists).  When the PCM volume of
+OSS is changed, all the volume and switch controls above are adjusted
+automatically.
+
+As default, ALSA uses the following control for OSS volumes:
+
+	OSS volume		ALSA control		Index
+	-----------------------------------------------------
+	SOUND_MIXER_VOLUME 	Master			0
+	SOUND_MIXER_BASS	Tone Control - Bass	0
+	SOUND_MIXER_TREBLE	Tone Control - Treble	0
+	SOUND_MIXER_SYNTH	Synth			0
+	SOUND_MIXER_PCM		PCM			0
+	SOUND_MIXER_SPEAKER	PC Speaker 		0
+	SOUND_MIXER_LINE	Line			0
+	SOUND_MIXER_MIC		Mic 			0
+	SOUND_MIXER_CD		CD 			0
+	SOUND_MIXER_IMIX	Monitor Mix 		0
+	SOUND_MIXER_ALTPCM	PCM			1
+	SOUND_MIXER_RECLEV	(not assigned)
+	SOUND_MIXER_IGAIN	Capture			0
+	SOUND_MIXER_OGAIN	Playback		0
+	SOUND_MIXER_LINE1	Aux			0
+	SOUND_MIXER_LINE2	Aux			1
+	SOUND_MIXER_LINE3	Aux			2
+	SOUND_MIXER_DIGITAL1	Digital			0
+	SOUND_MIXER_DIGITAL2	Digital			1
+	SOUND_MIXER_DIGITAL3	Digital			2
+	SOUND_MIXER_PHONEIN	Phone			0
+	SOUND_MIXER_PHONEOUT	Phone			1
+	SOUND_MIXER_VIDEO	Video			0
+	SOUND_MIXER_RADIO	Radio			0
+	SOUND_MIXER_MONITOR	Monitor			0
+
+The second column is the base-string of the corresponding ALSA
+control.  In fact, the controls with "XXX [Playback|Capture]
+[Volume|Switch]" will be checked in addition.
+
+The current assignment of these mixer elements is listed in the proc
+file, /proc/asound/cardX/oss_mixer, which will be like the following
+
+	VOLUME "Master" 0
+	BASS "" 0
+	TREBLE "" 0
+	SYNTH "" 0
+	PCM "PCM" 0
+	...
+
+where the first column is the OSS volume element, the second column
+the base-string of the corresponding ALSA control, and the third the
+control index.  When the string is empty, it means that the
+corresponding OSS control is not available.
+
+For changing the assignment, you can write the configuration to this
+proc file.  For example, to map "Wave Playback" to the PCM volume,
+send the command like the following:
+
+	% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/oss_mixer
+
+The command is exactly as same as listed in the proc file.  You can
+change one or more elements, one volume per line.  In the last
+example, both "Wave Playback Volume" and "Wave Playback Switch" will
+be affected when PCM volume is changed.
+
+Like the case of PCM proc file, the permission of proc files depend on
+the module options of snd.  you'll likely need to be superuser for
+sending the command above.
+
+As well as in the case of PCM proc file, you can save and restore the
+current mixer configuration by reading and writing the whole file
+image.
+
+
+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
+====================
+
+MMAP on ICE1712 driver
+----------------------
+ICE1712 supports only the unconventional format, interleaved
+10-channels 24bit (packed in 32bit) format.  Therefore you cannot mmap
+the buffer as the conventional (mono or 2-channels, 8 or 16bit) format
+on OSS.
+
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
new file mode 100644
index 0000000..f738b29
--- /dev/null
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -0,0 +1,207 @@
+		Proc Files of ALSA Drivers
+		==========================
+		Takashi Iwai <tiwai@suse.de>
+
+General
+-------
+
+ALSA has its own proc tree, /proc/asound.  Many useful information are
+found in this tree.  When you encounter a problem and need debugging,
+check the files listed in the following sections.
+
+Each card has its subtree cardX, where X is from 0 to 7. The
+card-specific files are stored in the card* subdirectories.
+
+
+Global Information
+------------------
+
+cards
+	Shows the list of currently configured ALSA drivers,
+	index, the id string, short and long descriptions.
+
+version
+	Shows the version string and compile date.
+
+modules
+	Lists the module of each card
+
+devices
+	Lists the ALSA native device mappings.
+
+meminfo
+	Shows the status of allocated pages via ALSA drivers.
+	Appears only when CONFIG_SND_DEBUG=y.
+
+hwdep
+	Lists the currently available hwdep devices in format of
+	<card>-<device>: <name>
+
+pcm
+	Lists the currently available PCM devices in format of
+	<card>-<device>: <id>: <name> : <sub-streams>
+
+timer
+	Lists the currently available timer devices
+
+
+oss/devices
+	Lists the OSS device mappings.
+
+oss/sndstat
+	Provides the output compatible with /dev/sndstat.
+	You can symlink this to /dev/sndstat.
+
+
+Card Specific Files
+-------------------
+
+The card-specific files are found in /proc/asound/card* directories.
+Some drivers (e.g. cmipci) have their own proc entries for the
+register dump, etc (e.g. /proc/asound/card*/cmipci shows the register
+dump).  These files would be really helpful for debugging.
+
+When PCM devices are available on this card, you can see directories
+like pcm0p or pcm1c.  They hold the PCM information for each PCM
+stream.  The number after 'pcm' is the PCM device number from 0, and
+the last 'p' or 'c' means playback or capture direction.  The files in
+this subtree is described later.
+
+The status of MIDI I/O is found in midi* files.  It shows the device
+name and the received/transmitted bytes through the MIDI device.
+
+When the card is equipped with AC97 codecs, there are codec97#*
+subdirectories (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
+OSS mixer elements to the ALSA control elements.  You can change the
+mapping by writing to this device.  Read OSS-Emulation.txt for
+details.
+
+
+PCM Proc Files
+--------------
+
+card*/pcm*/info
+	The general information of this PCM device: card #, device #,
+	substreams, etc.
+
+card*/pcm*/xrun_debug
+	This file appears when CONFIG_SND_DEBUG=y.
+	This shows the status of xrun (= buffer overrun/xrun) debug of
+	ALSA PCM middle layer, as an integer from 0 to 2.  The value
+	can be changed by writing to this file, such as
+
+		 # cat 2 > /proc/asound/card0/pcm0p/xrun_debug
+
+	When this value is greater than 0, the driver will show the
+	messages to kernel log when an xrun is detected.  The debug
+	message is shown also when the invalid H/W pointer is detected
+	at the update of periods (usually called from the interrupt
+	handler).
+
+	When this value is greater than 1, the driver will show the
+	stack trace additionally.  This may help the debugging.
+
+card*/pcm*/sub*/info
+	The general information of this PCM sub-stream.
+
+card*/pcm*/sub*/status
+	The current status of this PCM sub-stream, elapsed time,
+	H/W position, etc.
+
+card*/pcm*/sub*/hw_params
+	The hardware parameters set for this sub-stream.
+
+card*/pcm*/sub*/sw_params
+	The soft parameters set for this sub-stream.
+
+card*/pcm*/sub*/prealloc
+	The buffer pre-allocation information.
+
+
+AC97 Codec Information
+----------------------
+
+card*/codec97#*/ac97#?-?
+	Shows the general information of this AC97 codec chip, such as
+	name, capabilities, set up.
+
+card*/codec97#0/ac97#?-?+regs
+	Shows the AC97 register dump.  Useful for debugging.
+
+	When CONFIG_SND_DEBUG is enabled, you can write to this file for
+	changing an AC97 register directly.  Pass two hex numbers.
+	For example,
+
+	# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
+
+
+USB Audio Streams
+-----------------
+
+card*/stream*
+	Shows the assignment and the current status of each audio stream
+	of the given card.  This information is very useful for debugging.
+
+
+HD-Audio Codecs
+---------------
+
+card*/codec#*
+	Shows the general codec information and the attribute of each
+	widget node.
+
+
+Sequencer Information
+---------------------
+
+seq/drivers
+	Lists the currently available ALSA sequencer drivers.
+
+seq/clients
+	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 sequencer queues.
+
+seq/timer
+	Lists the currently allocated/running sequencer timers.
+
+seq/oss
+	Lists the OSS-compatible sequencer stuffs.
+
+
+Help For Debugging?
+-------------------
+
+When the problem is related with PCM, first try to turn on xrun_debug
+mode.  This will give you the kernel messages when and where xrun
+happened.
+
+If it's really a bug, report it with the following information:
+
+  - the name of the driver/card, show in /proc/asound/cards
+  - the register dump, if available (e.g. card*/cmipci)
+
+when it's a PCM problem,
+
+  - set-up of PCM, shown in hw_parms, sw_params, and status in the PCM
+    sub-stream directory
+
+when it's a mixer problem,
+
+  - AC97 proc files, codec97#*/* files
+
+for USB audio/midi,
+
+  - output of lsusb -v
+  - stream* files in card directory
+
+
+The ALSA bug-tracking system is found at:
+
+    https://bugtrack.alsa-project.org/alsa-bug/
diff --git a/Documentation/sound/alsa/SB-Live-mixer.txt b/Documentation/sound/alsa/SB-Live-mixer.txt
new file mode 100644
index 0000000..f5639d4
--- /dev/null
+++ b/Documentation/sound/alsa/SB-Live-mixer.txt
@@ -0,0 +1,356 @@
+
+		Sound Blaster Live mixer / default DSP code
+		===========================================
+
+
+The EMU10K1 chips have a DSP part which can be programmed to support
+various ways of sample processing, which is described here.
+(This 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
+(can be altered later) which offers the following functionality:
+
+
+1) IEC958 (S/PDIF) raw PCM
+--------------------------
+
+This PCM device (it's the 4th PCM device (index 3!) and first subdevice
+(index 0) for a given card) allows to forward 48kHz, stereo, 16-bit
+little endian streams without any modifications to the digital output
+(coaxial or optical). The universal interface allows the creation of up
+to 8 raw PCM devices operating at 48kHz, 16-bit little endian. It would
+be easy to add support for multichannel devices to the current code,
+but the conversion routines exist only for stereo (2-channel streams)
+at the time. 
+
+Look to tram_poke routines in lowlevel/emu10k1/emufx.c for more details.
+
+
+2) Digital mixer controls
+-------------------------
+
+These controls are built using the DSP instructions. They offer extended
+functionality. Only the default build-in code in the ALSA driver is described
+here. Note that the controls work as attenuators: the maximum value is the 
+neutral position leaving the signal unchanged. Note that if the  same destination 
+is mentioned in multiple controls, the signal is accumulated and can be wrapped 
+(set to maximal or minimal value without checking of overflow).
+
+
+Explanation of used abbreviations:
+
+DAC    - digital to analog converter
+ADC    - analog to digital converter
+I2S    - one-way three wire serial bus for digital sound by Philips Semiconductors
+         (this standard is used for connecting standalone DAC and ADC converters)
+LFE    - low frequency effects (subwoofer signal)
+AC97   - a chip containing an analog mixer, DAC and ADC converters
+IEC958 - S/PDIF
+FX-bus - the EMU10K1 chip has an effect bus containing 16 accumulators.
+         Each of the synthesizer voices can feed its output to these accumulators
+         and the DSP microcontroller can operate with the resulting sum.
+
+
+name='Wave Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
+The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Wave Surround Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
+The result samples are forwarded to the rear I2S DACs. These DACs operates
+separately (they are not inside the AC97 codec).
+
+name='Wave Center Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
+The result is mixed to mono signal (single channel) and forwarded to
+the ??rear?? right DAC PCM slot of the AC97 codec.
+
+name='Wave LFE Playback Volume',index=0
+
+This control is used to attenuate samples for left and right PCM FX-bus
+accumulators. ALSA uses accumulators 0 and 1 for left and right PCM.
+The result is mixed to mono signal (single channel) and forwarded to
+the ??rear?? left DAC PCM slot of the AC97 codec.
+
+name='Wave Capture Volume',index=0
+name='Wave Capture Switch',index=0
+
+These controls are used to attenuate samples for left and right PCM FX-bus
+accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Music Playback Volume',index=0
+
+This control is used to attenuate samples for left and right MIDI FX-bus
+accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
+The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Music Capture Volume',index=0
+name='Music Capture Switch',index=0
+
+These controls are used to attenuate samples for left and right MIDI FX-bus
+accumulator. ALSA uses accumulators 4 and 5 for left and right PCM.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Surround Playback Volume',index=0
+
+This control is used to attenuate samples for left and right rear PCM FX-bus
+accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.
+The result samples are forwarded to the rear I2S DACs. These DACs operate
+separately (they are not inside the AC97 codec).
+
+name='Surround Capture Volume',index=0
+name='Surround Capture Switch',index=0
+
+These controls are used to attenuate samples for left and right rear PCM FX-bus
+accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.
+The result is forwarded to the ADC capture FIFO (thus to the standard capture
+PCM device).
+
+name='Center Playback Volume',index=0
+
+This control is used to attenuate sample for center PCM FX-bus accumulator.
+ALSA uses accumulator 6 for center PCM sample. The result sample is forwarded
+to the ??rear?? right DAC PCM slot of the AC97 codec.
+
+name='LFE Playback Volume',index=0
+
+This control is used to attenuate sample for center PCM FX-bus accumulator.
+ALSA uses accumulator 6 for center PCM sample. The result sample is forwarded
+to the ??rear?? left DAC PCM slot of the AC97 codec.
+
+name='AC97 Playback Volume',index=0
+
+This control is used to attenuate samples for left and right front ADC PCM slots
+of the AC97 codec. The result samples are forwarded to the front DAC PCM
+slots of the AC97 codec.
+********************************************************************************
+*** Note: This control should be zero for the standard operations, otherwise ***
+*** a digital loopback is activated.                                         ***
+********************************************************************************
+
+name='AC97 Capture Volume',index=0
+
+This control is used to attenuate samples for left and right front ADC PCM slots
+of the AC97 codec. The result is forwarded to the ADC capture FIFO (thus to
+the standard capture PCM device).
+********************************************************************************
+*** Note: This control should be 100 (maximal value), otherwise no analog    ***
+*** inputs of the AC97 codec can be captured (recorded).                     ***
+********************************************************************************
+
+name='IEC958 TTL Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 TTL
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='IEC958 TTL Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 TTL
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the ADC capture FIFO (thus to the standard capture PCM device).
+
+name='Zoom Video Playback Volume',index=0
+
+This control is used to attenuate samples from left and right zoom video
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the front DAC PCM slots of the AC97 codec.
+
+name='Zoom Video Capture Volume',index=0
+
+This control is used to attenuate samples from left and right zoom video
+digital inputs (usually used by a CDROM drive). The result samples are
+forwarded to the ADC capture FIFO (thus to the standard capture PCM device).
+
+name='IEC958 LiveDrive Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 optical
+digital input. The result samples are forwarded to the front DAC PCM slots
+of the AC97 codec.
+
+name='IEC958 LiveDrive Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 optical
+digital inputs. The result samples are forwarded to the ADC capture FIFO
+(thus to the standard capture PCM device).
+
+name='IEC958 Coaxial Playback Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 coaxial
+digital inputs. The result samples are forwarded to the front DAC PCM slots
+of the AC97 codec.
+
+name='IEC958 Coaxial Capture Volume',index=0
+
+This control is used to attenuate samples from left and right IEC958 coaxial
+digital inputs. The result samples are forwarded to the ADC capture FIFO
+(thus to the standard capture PCM device).
+
+name='Line LiveDrive Playback Volume',index=0
+name='Line LiveDrive Playback Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the LiveDrive). The result samples are forwarded to the front
+DAC PCM slots of the AC97 codec.
+
+name='Line LiveDrive Capture Volume',index=1
+name='Line LiveDrive Capture Volume',index=1
+
+This control is used to attenuate samples from left and right I2S ADC
+inputs (on the LiveDrive). The result samples are forwarded to the ADC
+capture FIFO (thus to the standard capture PCM device).
+
+name='Tone Control - Switch',index=0
+
+This control turns the tone control on or off. The samples for front, rear
+and center / LFE outputs are affected.
+
+name='Tone Control - Bass',index=0
+
+This control sets the bass intensity. There is no neutral value!!
+When the tone control code is activated, the samples are always modified.
+The closest value to pure signal is 20.
+
+name='Tone Control - Treble',index=0
+
+This control sets the treble intensity. There is no neutral value!!
+When the tone control code is activated, the samples are always modified.
+The closest value to pure signal is 20.
+
+name='IEC958 Optical Raw Playback Switch',index=0
+
+If this switch is on, then the samples for the IEC958 (S/PDIF) digital
+output are taken only from the raw FX8010 PCM, otherwise standard front
+PCM samples are taken.
+
+name='Headphone Playback Volume',index=1
+
+This control attenuates the samples for the headphone output.
+
+name='Headphone Center Playback Switch',index=1
+
+If this switch is on, then the sample for the center PCM is put to the
+left headphone output (useful for SB Live cards without separate center/LFE
+output).
+
+name='Headphone LFE Playback Switch',index=1
+
+If this switch is on, then the sample for the center PCM is put to the
+right headphone output (useful for SB Live cards without separate center/LFE
+output).
+
+
+3) PCM stream related controls
+------------------------------
+
+name='EMU10K1 PCM Volume',index 0-31
+
+Channel volume attenuation in range 0-0xffff. The maximum value (no
+attenuation) is default. The channel mapping for three values is
+as follows:
+
+	0 - mono, default 0xffff (no attenuation)
+	1 - left, default 0xffff (no attenuation)
+	2 - right, default 0xffff (no attenuation)
+
+name='EMU10K1 PCM Send Routing',index 0-31
+
+This control specifies the destination - FX-bus accumulators. There are
+twelve values with this mapping:
+
+	 0 -  mono, A destination (FX-bus 0-15), default 0
+	 1 -  mono, B destination (FX-bus 0-15), default 1
+	 2 -  mono, C destination (FX-bus 0-15), default 2
+	 3 -  mono, D destination (FX-bus 0-15), default 3
+	 4 -  left, A destination (FX-bus 0-15), default 0
+	 5 -  left, B destination (FX-bus 0-15), default 1
+	 6 -  left, C destination (FX-bus 0-15), default 2
+	 7 -  left, D destination (FX-bus 0-15), default 3
+	 8 - right, A destination (FX-bus 0-15), default 0
+	 9 - right, B destination (FX-bus 0-15), default 1
+	10 - right, C destination (FX-bus 0-15), default 2
+	11 - right, D destination (FX-bus 0-15), default 3
+
+Don't forget that it's illegal to assign a channel to the same FX-bus accumulator 
+more than once (it means 0=0 && 1=0 is an invalid combination).
+ 
+name='EMU10K1 PCM Send Volume',index 0-31
+
+It specifies the attenuation (amount) for given destination in range 0-255.
+The channel mapping is following:
+
+	 0 -  mono, A destination attn, default 255 (no attenuation)
+	 1 -  mono, B destination attn, default 255 (no attenuation)
+	 2 -  mono, C destination attn, default 0 (mute)
+	 3 -  mono, D destination attn, default 0 (mute)
+	 4 -  left, A destination attn, default 255 (no attenuation)
+	 5 -  left, B destination attn, default 0 (mute)
+	 6 -  left, C destination attn, default 0 (mute)
+	 7 -  left, D destination attn, default 0 (mute)
+	 8 - right, A destination attn, default 0 (mute)
+	 9 - right, B destination attn, default 255 (no attenuation)
+	10 - right, C destination attn, default 0 (mute)
+	11 - right, D destination attn, default 0 (mute)
+
+
+
+4) MANUALS/PATENTS:
+-------------------
+
+ftp://opensource.creative.com/pub/doc
+-------------------------------------
+
+        Files:
+        LM4545.pdf      AC97 Codec
+
+        m2049.pdf       The EMU10K1 Digital Audio Processor
+
+        hog63.ps        FX8010 - A DSP Chip Architecture for Audio Effects
+
+
+WIPO Patents
+------------
+        Patent numbers:
+        WO 9901813 (A1) Audio Effects Processor with multiple asynchronous (Jan. 14, 1999)
+                        streams
+
+        WO 9901814 (A1) Processor with Instruction Set for Audio Effects (Jan. 14, 1999)
+
+        WO 9901953 (A1) Audio Effects Processor having Decoupled Instruction
+                        Execution and Audio Data Sequencing (Jan. 14, 1999)
+
+
+US Patents (http://www.uspto.gov/)
+----------------------------------
+
+        US 5925841      Digital Sampling Instrument employing cache memory (Jul. 20, 1999)
+
+        US 5928342      Audio Effects Processor integrated on a single chip (Jul. 27, 1999)
+                        with a multiport memory onto which multiple asynchronous
+                        digital sound samples can be concurrently loaded
+
+        US 5930158      Processor with Instruction Set for Audio Effects (Jul. 27, 1999)
+
+        US 6032235      Memory initialization circuit (Tram) (Feb. 29, 2000)
+
+        US 6138207      Interpolation looping of audio samples in cache connected to    (Oct. 24, 2000)
+                        system bus with prioritization and modification of bus transfers
+                        in accordance with loop ends and minimum block sizes
+
+        US 6151670      Method for conserving memory storage using a (Nov. 21, 2000)
+                        pool of  short term memory registers
+
+        US 6195715      Interrupt control for multiple programs communicating with      (Feb. 27, 2001)
+                        a common interrupt by associating programs to GP registers,
+                        defining interrupt register, polling GP registers, and invoking
+                        callback routine associated with defined interrupt register
diff --git a/Documentation/sound/alsa/VIA82xx-mixer.txt b/Documentation/sound/alsa/VIA82xx-mixer.txt
new file mode 100644
index 0000000..1b0ac06
--- /dev/null
+++ b/Documentation/sound/alsa/VIA82xx-mixer.txt
@@ -0,0 +1,8 @@
+
+				VIA82xx mixer
+				=============
+
+On many VIA82xx boards, the 'Input Source Select' mixer control does not work.
+Setting it to 'Input2' on such boards will cause recording to hang, or fail
+with EIO (input/output error) via OSS emulation.  This control should be left
+at 'Input1' for such cards.
diff --git a/Documentation/sound/alsa/emu10k1-jack.txt b/Documentation/sound/alsa/emu10k1-jack.txt
new file mode 100644
index 0000000..751d450
--- /dev/null
+++ b/Documentation/sound/alsa/emu10k1-jack.txt
@@ -0,0 +1,74 @@
+This document is a guide to using the emu10k1 based devices with JACK for low
+latency, multichannel recording functionality.  All of my recent work to allow
+Linux users to use the full capabilities of their hardware has been inspired 
+by the kX Project.  Without their work I never would have discovered the true
+power of this hardware.
+
+	http://www.kxproject.com
+						- Lee Revell, 2005.03.30
+
+Low latency, multichannel audio with JACK and the emu10k1/emu10k2
+-----------------------------------------------------------------
+
+Until recently, emu10k1 users on Linux did not have access to the same low
+latency, multichannel features offered by the "kX ASIO" feature of their
+Windows driver.  As of ALSA 1.0.9 this is no more!
+
+For those unfamiliar with kX ASIO, this consists of 16 capture and 16 playback
+channels.  With a post 2.6.9 Linux kernel, latencies down to 64 (1.33 ms) or
+even 32 (0.66ms) frames should work well.
+
+The configuration is slightly more involved than on Windows, as you have to
+select the correct device for JACK to use.  Actually, for qjackctl users it's
+fairly self explanatory - select Duplex, then for capture and playback select
+the multichannel devices, set the in and out channels to 16, and the sample
+rate to 48000Hz.  The command line looks like this:
+
+/usr/local/bin/jackd -R -dalsa -r48000 -p64 -n2 -D -Chw:0,2 -Phw:0,3 -S
+
+This will give you 16 input ports and 16 output ports.
+
+The 16 output ports map onto the 16 FX buses (or the first 16 of 64, for the
+Audigy).  The mapping from FX bus to physical output is described in
+SB-Live-mixer.txt (or Audigy-mixer.txt).
+
+The 16 input ports are connected to the 16 physical inputs.  Contrary to
+popular belief, all emu10k1 cards are multichannel cards.  Which of these
+input channels have physical inputs connected to them depends on the card
+model.  Trial and error is highly recommended; the pinout diagrams
+for the card have been reverse engineered by some enterprising kX users and are 
+available on the internet.  Meterbridge is helpful here, and the kX forums are
+packed with useful information.
+
+Each input port will either correspond to a digital (SPDIF) input, an analog
+input, or nothing.  The one exception is the SBLive! 5.1.  On these devices,
+the second and third input ports are wired to the center/LFE output.  You will
+still see 16 capture channels, but only 14 are available for recording inputs.
+
+This chart, borrowed from kxfxlib/da_asio51.cpp, describes the mapping of JACK
+ports to FXBUS2 (multitrack recording input) and EXTOUT (physical output)
+channels.
+
+/*JACK (& ASIO) mappings on 10k1 5.1 SBLive cards:
+--------------------------------------------
+JACK		Epilog		FXBUS2(nr)
+--------------------------------------------
+capture_1	asio14		FXBUS2(0xe)
+capture_2	asio15		FXBUS2(0xf)
+capture_3	asio0		FXBUS2(0x0)	
+~capture_4	Center		EXTOUT(0x11)	// mapped to by Center
+~capture_5	LFE		EXTOUT(0x12)	// mapped to by LFE
+capture_6	asio3		FXBUS2(0x3)
+capture_7	asio4		FXBUS2(0x4)
+capture_8	asio5		FXBUS2(0x5)
+capture_9	asio6		FXBUS2(0x6)
+capture_10	asio7		FXBUS2(0x7)
+capture_11	asio8		FXBUS2(0x8)
+capture_12	asio9		FXBUS2(0x9)
+capture_13	asio10		FXBUS2(0xa)
+capture_14	asio11		FXBUS2(0xb)
+capture_15	asio12		FXBUS2(0xc)
+capture_16	asio13		FXBUS2(0xd)
+*/
+
+TODO: describe use of ld10k1/qlo10k1 in conjunction with JACK
diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt
new file mode 100644
index 0000000..34e87ec
--- /dev/null
+++ b/Documentation/sound/alsa/hda_codec.txt
@@ -0,0 +1,322 @@
+Notes on Universal Interface for Intel High Definition Audio Codec
+------------------------------------------------------------------
+
+Takashi Iwai <tiwai@suse.de>
+
+
+[Still a draft version]
+
+
+General
+=======
+
+The snd-hda-codec module supports the generic access function for the
+High Definition (HD) audio codecs.  It's designed to be independent
+from the controller code like ac97 codec module.  The real accessors
+from/to the controller must be implemented in the lowlevel driver.
+
+The structure of this module is similar with ac97_codec module.
+Each codec chip belongs to a bus class which communicates with the
+controller.
+
+
+Initialization of Bus Instance
+==============================
+
+The card driver has to create struct hda_bus at first.  The template
+struct should be filled and passed to the constructor:
+
+struct hda_bus_template {
+	void *private_data;
+	struct pci_dev *pci;
+	const char *modelname;
+	struct hda_bus_ops ops;
+};
+
+The card driver can set and use the private_data field to retrieve its
+own data in callback functions.  The pci field is used when the patch
+needs to check the PCI subsystem IDs, so on.  For non-PCI system, it
+doesn't have to be set, of course.
+The modelname field specifies the board's specific configuration.  The
+string is passed to the codec parser, and it depends on the parser how
+the string is used.
+These fields, private_data, pci and modelname are all optional.
+
+The ops field contains the callback functions as the following:
+
+struct hda_bus_ops {
+	int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct,
+		       unsigned int verb, unsigned int parm);
+	unsigned int (*get_response)(struct hda_codec *codec);
+	void (*private_free)(struct hda_bus *);
+#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
+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 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.
+
+int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
+		    struct hda_bus **busp);
+
+It returns zero if successful.  A negative return value means any
+error during creation.
+
+
+Creation of Codec Instance
+==========================
+
+Each codec chip on the board is then created on the BUS instance.
+To create a codec instance, call snd_hda_codec_new().
+
+int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+		      struct hda_codec **codecp);
+
+The first argument is the BUS instance, the second argument is the
+address of the codec, and the last one is the pointer to store the
+resultant codec instance (can be NULL if not needed).
+
+The codec is stored in a linked list of bus instance.  You can follow
+the codec list like:
+
+	struct hda_codec *codec;
+	list_for_each_entry(codec, &bus->codec_list, list) {
+		...
+	}
+
+The codec isn't initialized at this stage properly.  The
+initialization sequence is called when the controls are built later.
+
+
+Codec Access
+============
+
+To access codec, use snd_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-mangement 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.
+
+When an unsolicited event happens, pass the event via
+snd_hda_queue_unsol_event() so that the codec routines will process it
+later.
+
+
+(Mixer) Controls
+================
+
+To create mixer controls of all codecs, call
+snd_hda_build_controls().  It then builds the mixers and does
+initialization stuff on each codec.
+
+
+PCM Stuff
+=========
+
+snd_hda_build_pcms() gives the necessary information to create PCM
+streams.  When it's called, each codec belonging to the bus stores 
+codec->num_pcms and codec->pcm_info fields.  The num_pcms indicates
+the number of elements in pcm_info array.  The card driver is supposed
+to traverse the codec linked list, read the pcm information in
+pcm_info array, and build pcm instances according to them. 
+
+The pcm_info array contains the following record:
+
+/* PCM information for each substream */
+struct hda_pcm_stream {
+	unsigned int substreams;	/* number of substreams, 0 = not exist */
+	unsigned int channels_min;	/* min. number of channels */
+	unsigned int channels_max;	/* max. number of channels */
+	hda_nid_t nid;	/* default NID to query rates/formats/bps, or set up */
+	u32 rates;	/* supported rates */
+	u64 formats;	/* supported formats (SNDRV_PCM_FMTBIT_) */
+	unsigned int maxbps;	/* supported max. bit per sample */
+	struct hda_pcm_ops ops;
+};
+
+/* for PCM creation */
+struct hda_pcm {
+	char *name;
+	struct hda_pcm_stream stream[2];
+};
+
+The name can be passed to snd_pcm_new().  The stream field contains
+the information  for playback (SNDRV_PCM_STREAM_PLAYBACK = 0) and
+capture (SNDRV_PCM_STREAM_CAPTURE = 1) directions.  The card driver
+should pass substreams to snd_pcm_new() for the number of substreams
+to create.
+
+The channels_min, channels_max, rates and formats should be copied to
+runtime->hw record.  They and maxbps fields are used also to compute
+the format value for the HDA codec and controller.  Call
+snd_hda_calc_stream_format() to get the format value.
+
+The ops field contains the following callback functions:
+
+struct hda_pcm_ops {
+	int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
+		    struct snd_pcm_substream *substream);
+	int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
+		     struct snd_pcm_substream *substream);
+	int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
+		       unsigned int stream_tag, unsigned int format,
+		       struct snd_pcm_substream *substream);
+	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
+		       struct snd_pcm_substream *substream);
+};
+
+All are non-NULL, so you can call them safely without NULL check.
+
+The open callback should be called in PCM open after runtime->hw is
+set up.  It may override some setting and constraints additionally.
+Similarly, the close callback should be called in the PCM close.
+
+The prepare callback should be called in PCM prepare.  This will set
+up the codec chip properly for the operation.  The cleanup should be
+called in hw_free to clean up the configuration.
+
+The caller should check the return value, at least for open and
+prepare callbacks.  When a negative value is returned, some error
+occurred.
+
+
+Proc Files
+==========
+
+Each codec dumps the widget node information in
+/proc/asound/card*/codec#* file.  This information would be really
+helpful for debugging.  Please provide its contents together with the
+bug report.
+
+
+Power Management
+================
+
+It's simple:
+Call snd_hda_suspend() in the PM suspend callback.
+Call snd_hda_resume() in the PM resume callback.
+
+
+Codec Preset (Patch)
+====================
+
+To set up and handle the codec functionality fully, each codec may
+have a codec preset (patch).  It's defined in struct hda_codec_preset:
+
+	struct hda_codec_preset {
+		unsigned int id;
+		unsigned int mask;
+		unsigned int subs;
+		unsigned int subs_mask;
+		unsigned int rev;
+		const char *name;
+		int (*patch)(struct hda_codec *codec);
+	};
+
+When the codec id and codec subsystem id match with the given id and
+subs fields bitwise (with bitmask mask and subs_mask), the callback
+patch is called.  The patch callback should initialize the codec and
+set the codec->patch_ops field.  This is defined as below:
+
+	struct hda_codec_ops {
+		int (*build_controls)(struct hda_codec *codec);
+		int (*build_pcms)(struct hda_codec *codec);
+		int (*init)(struct hda_codec *codec);
+		void (*free)(struct hda_codec *codec);
+		void (*unsol_event)(struct hda_codec *codec, unsigned int res);
+	#ifdef CONFIG_PM
+		int (*suspend)(struct hda_codec *codec, pm_message_t state);
+		int (*resume)(struct hda_codec *codec);
+	#endif
+	#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().
+Similarly, the build_pcms callback is called from
+snd_hda_build_pcms().  The init callback is called after
+build_controls to initialize the hardware.
+The free callback is called as a destructor.
+
+The unsol_event callback is called when an unsolicited event is
+received.
+
+The suspend and resume callbacks are for power management.
+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.
+
+
+Generic Parser
+==============
+
+When the device doesn't match with any given presets, the widgets are
+parsed via th generic parser (hda_generic.c).  Its support is
+limited: no multi-channel support, for example.
+
+
+Digital I/O
+===========
+
+Call snd_hda_create_spdif_out_ctls() from the patch to create controls
+related with SPDIF out.
+
+
+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 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
+
+Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
+used for the entry of struct snd_kcontrol_new.
+
+The input MUX helper callbacks for such a control are provided, too:
+snd_hda_input_mux_info() and snd_hda_input_mux_put().  See
+patch_realtek.c for example.
diff --git a/Documentation/sound/alsa/hdspm.txt b/Documentation/sound/alsa/hdspm.txt
new file mode 100644
index 0000000..7a67ff7
--- /dev/null
+++ b/Documentation/sound/alsa/hdspm.txt
@@ -0,0 +1,362 @@
+Software Interface ALSA-DSP MADI Driver 
+
+(translated from German, so no good English ;-), 
+2004 - winfried ritsch
+
+
+
+ Full functionality has been added to the driver. Since some of
+ the Controls and startup-options  are ALSA-Standard and only the
+ special Controls are described and discussed below.
+
+
+ hardware functionality:
+
+   
+   Audio transmission:
+
+     number of channels --  depends on transmission mode
+
+		The number of channels chosen is from 1..Nmax. The reason to
+		use for a lower number of channels is only resource allocation,
+		since unused DMA channels are disabled and less memory is
+		allocated. So also the throughput of the PCI system can be
+		scaled. (Only important for low performance boards).
+
+       Single Speed -- 1..64 channels 
+
+		 (Note: Choosing the 56channel mode for transmission or as
+		 receiver, only 56 are transmitted/received over the MADI, but
+		 all 64 channels are available for the mixer, so channel count
+		 for the driver)
+
+       Double Speed -- 1..32 channels
+
+		 Note: Choosing the 56-channel mode for
+		 transmission/receive-mode , only 28 are transmitted/received
+		 over the MADI, but all 32 channels are available for the mixer,
+		 so channel count for the driver
+
+
+       Quad Speed -- 1..16 channels 
+
+		 Note: Choosing the 56-channel mode for
+		 transmission/receive-mode , only 14 are transmitted/received
+		 over the MADI, but all 16 channels are available for the mixer,
+		 so channel count for the driver
+
+     Format -- signed 32 Bit Little Endian (SNDRV_PCM_FMTBIT_S32_LE)
+
+     Sample Rates --
+
+       Single Speed -- 32000, 44100, 48000
+
+       Double Speed -- 64000, 88200, 96000 (untested)
+
+       Quad Speed -- 128000, 176400, 192000 (untested)
+
+     access-mode -- MMAP (memory mapped), Not interleaved
+     (PCM_NON-INTERLEAVED)
+
+     buffer-sizes -- 64,128,256,512,1024,2048,8192 Samples
+
+     fragments -- 2
+
+     Hardware-pointer -- 2 Modi
+
+
+		 The Card supports the readout of the actual Buffer-pointer,
+		 where DMA reads/writes. Since of the bulk mode of PCI it is only
+		 64 Byte accurate. SO it is not really usable for the
+		 ALSA-mid-level functions (here the buffer-ID gives a better
+		 result), but if MMAP is used by the application. Therefore it
+		 can be configured at load-time with the parameter
+		 precise-pointer.
+
+
+		 (Hint: Experimenting I found that the pointer is maximum 64 to
+		 large never to small. So if you subtract 64 you always have a
+		 safe pointer for writing, which is used on this mode inside
+		 ALSA. In theory now you can get now a latency as low as 16
+		 Samples, which is a quarter of the interrupt possibilities.)
+
+       Precise Pointer -- off
+					interrupt used for pointer-calculation
+
+       Precise Pointer -- on
+					hardware pointer used.
+
+   Controller:
+
+
+	  Since DSP-MADI-Mixer has 8152 Fader, it does not make sense to
+	  use the standard mixer-controls, since this would break most of
+	  (especially graphic) ALSA-Mixer GUIs. So Mixer control has be
+	  provided by a 2-dimensional controller using the
+	  hwdep-interface. 
+
+     Also all 128+256 Peak and RMS-Meter can be accessed via the
+     hwdep-interface. Since it could be a performance problem always
+     copying and converting Peak and RMS-Levels even if you just need
+     one, I decided to export the hardware structure, so that of
+     needed some driver-guru can implement a memory-mapping of mixer
+     or peak-meters over ioctl, or also to do only copying and no
+     conversion. A test-application shows the usage of the controller.
+
+    Latency Controls --- not implemented !!!
+
+
+	   Note: Within the windows-driver the latency is accessible of a
+	   control-panel, but buffer-sizes are controlled with ALSA from
+	   hwparams-calls and should not be changed in run-state, I did not
+	   implement it here.
+
+
+    System Clock -- suspended !!!!
+
+        Name -- "System Clock Mode"
+
+        Access -- Read Write
+
+        Values -- "Master" "Slave"
+
+
+		  !!!! This is a hardware-function but is in conflict with the
+		  Clock-source controller, which is a kind of ALSA-standard. I
+		  makes sense to set the card to a special mode (master at some
+		  frequency or slave), since even not using an Audio-application
+		  a studio should have working synchronisations setup. So use
+		  Clock-source-controller instead !!!!
+
+    Clock Source  
+
+       Name -- "Sample Clock Source"
+
+       Access -- Read Write
+
+       Values -- "AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz",
+       "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz",
+       "Internal 96.0 kHz"
+
+		 Choose between Master at a specific Frequency and so also the
+		 Speed-mode or Slave (Autosync). Also see  "Preferred Sync Ref"
+
+
+       !!!! This is no pure hardware function but was implemented by
+       ALSA by some ALSA-drivers before, so I use it also. !!!
+
+
+    Preferred Sync Ref
+
+       Name -- "Preferred Sync Reference"
+
+       Access -- Read Write
+
+       Values -- "Word" "MADI"
+
+
+		 Within the Auto-sync-Mode the preferred Sync Source can be
+		 chosen. If it is not available another is used if possible.
+
+		 Note: Since MADI has a much higher bit-rate than word-clock, the
+		 card should synchronise better in MADI Mode. But since the
+		 RME-PLL is very good, there are almost no problems with
+		 word-clock too. I never found a difference.
+
+
+    TX 64 channel --- 
+
+       Name -- "TX 64 channels mode"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+		 Using 64-channel-modus (1) or 56-channel-modus for
+		 MADI-transmission (0).
+
+
+		 Note: This control is for output only. Input-mode is detected
+		 automatically from hardware sending MADI.
+
+
+    Clear TMS ---
+
+       Name -- "Clear Track Marker"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+
+		 Don't use to lower 5 Audio-bits on AES as additional Bits.
+        
+
+    Safe Mode oder Auto Input --- 
+
+       Name -- "Safe Mode"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+       (default on)
+
+		 If on (1), then if either the optical or coaxial connection
+		 has a failure, there is a takeover to the working one, with no
+		 sample failure. Its only useful if you use the second as a
+		 backup connection.
+
+    Input --- 
+
+       Name -- "Input Select"
+
+       Access -- Read Write
+
+       Values -- optical coaxial
+
+
+		 Choosing the Input, optical or coaxial. If Safe-mode is active,
+		 this is the preferred Input.
+
+-------------- Mixer ----------------------
+
+    Mixer
+
+       Name -- "Mixer"
+
+       Access -- Read Write
+
+       Values - <channel-number 0-127> <Value 0-65535>
+
+
+		 Here as a first value the channel-index is taken to get/set the
+		 corresponding mixer channel, where 0-63 are the input to output
+		 fader and 64-127 the playback to outputs fader. Value 0
+		 is channel muted 0 and 32768 an amplification of  1.
+
+    Chn 1-64
+
+       fast mixer for the ALSA-mixer utils. The diagonal of the
+       mixer-matrix is implemented from playback to output.
+       
+
+    Line Out
+
+       Name  -- "Line Out"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+		 Switching on and off the analog out, which has nothing to do
+		 with mixing or routing. the analog outs reflects channel 63,64.
+
+
+--- information (only read access):
+ 
+    Sample Rate
+
+       Name -- "System Sample Rate"
+
+       Access -- Read-only
+
+		 getting the sample rate.
+
+
+    External Rate measured
+
+       Name -- "External Rate"
+
+       Access -- Read only
+
+
+		 Should be "Autosync Rate", but Name used is
+		 ALSA-Scheme. External Sample frequency liked used on Autosync is
+		 reported.
+
+
+    MADI Sync Status
+
+       Name -- "MADI Sync Lock Status"
+
+       Access -- Read
+
+       Values -- 0,1,2
+
+       MADI-Input is 0=Unlocked, 1=Locked, or 2=Synced.
+
+
+    Word Clock Sync Status
+
+       Name -- "Word Clock Lock Status"
+
+       Access -- Read
+
+       Values -- 0,1,2
+
+       Word Clock Input is 0=Unlocked, 1=Locked, or 2=Synced.
+
+    AutoSync
+
+       Name -- "AutoSync Reference"
+
+       Access -- Read
+
+       Values -- "WordClock", "MADI", "None"
+
+		 Sync-Reference is either "WordClock", "MADI" or none.
+
+   RX 64ch --- noch nicht implementiert
+
+       MADI-Receiver is in 64 channel mode oder 56 channel mode.
+
+
+   AB_inp   --- not tested 
+
+		 Used input for Auto-Input.
+
+
+   actual Buffer Position --- not implemented
+
+	   !!! this is a ALSA internal function, so no control is used !!!
+
+
+
+Calling Parameter:
+
+   index int array (min = 1, max = 8), 
+     "Index value for RME HDSPM interface." card-index within ALSA
+
+     note: ALSA-standard
+
+   id string array (min = 1, max = 8), 
+     "ID string for RME HDSPM interface."
+
+     note: ALSA-standard
+
+   enable int array (min = 1, max = 8), 
+     "Enable/disable specific HDSPM sound-cards."
+
+     note: ALSA-standard
+
+   precise_ptr int array (min = 1, max = 8), 
+     "Enable precise pointer, or disable."
+
+     note: Use only when the application supports this (which is a special case).
+
+   line_outs_monitor int array (min = 1, max = 8), 
+     "Send playback streams to analog outs by default."
+
+
+	  note: each playback channel is mixed to the same numbered output
+	  channel (routed). This is against the ALSA-convention, where all
+	  channels have to be muted on after loading the driver, but was
+	  used before on other cards, so i historically use it again)
+
+
+
+   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
diff --git a/Documentation/sound/alsa/powersave.txt b/Documentation/sound/alsa/powersave.txt
new file mode 100644
index 0000000..9657e80
--- /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
new file mode 100644
index 0000000..d9776cf
--- /dev/null
+++ b/Documentation/sound/alsa/seq_oss.html
@@ -0,0 +1,409 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+   <TITLE>OSS Sequencer Emulation on ALSA</TITLE>
+</HEAD>
+<BODY>
+
+<CENTER>
+<H1>
+
+<HR WIDTH="100%"></H1></CENTER>
+
+<CENTER>
+<H1>
+OSS Sequencer Emulation on ALSA</H1></CENTER>
+
+<HR WIDTH="100%">
+<P>Copyright (c) 1998,1999 by Takashi Iwai
+<TT><A HREF="mailto:iwai@ww.uni-erlangen.de">&lt;iwai@ww.uni-erlangen.de></A></TT>
+<P>ver.0.1.8; Nov. 16, 1999
+<H2>
+
+<HR WIDTH="100%"></H2>
+
+<H2>
+1. Description</H2>
+This directory contains the OSS sequencer emulation driver on ALSA. Note
+that this program is still in the development state.
+<P>What this does - it provides the emulation of the OSS sequencer, access
+via
+<TT>/dev/sequencer</TT> and <TT>/dev/music</TT> devices.
+The most of applications using OSS can run if the appropriate ALSA
+sequencer is prepared.
+<P>The following features are emulated by this driver:
+<UL>
+<LI>
+Normal sequencer and MIDI events:</LI>
+
+<BR>They are converted to the ALSA sequencer events, and sent to the corresponding
+port.
+<LI>
+Timer events:</LI>
+
+<BR>The timer is not selectable by ioctl. The control rate is fixed to
+100 regardless of HZ. That is, even on Alpha system, a tick is always
+1/100 second. The base rate and tempo can be changed in <TT>/dev/music</TT>.
+
+<LI>
+Patch loading:</LI>
+
+<BR>It purely depends on the synth drivers whether it's supported since
+the patch loading is realized by callback to the synth driver.
+<LI>
+I/O controls:</LI>
+
+<BR>Most of controls are accepted. Some controls
+are dependent on the synth driver, as well as even on original OSS.</UL>
+Furthermore, you can find the following advanced features:
+<UL>
+<LI>
+Better queue mechanism:</LI>
+
+<BR>The events are queued before processing them.
+<LI>
+Multiple applications:</LI>
+
+<BR>You can run two or more applications simultaneously (even for OSS sequencer)!
+However, each MIDI device is exclusive - that is, if a MIDI device is opened
+once by some application, other applications can't use it. No such a restriction
+in synth devices.
+<LI>
+Real-time event processing:</LI>
+
+<BR>The events can be processed in real time without using out of bound
+ioctl. To switch to real-time mode, send ABSTIME 0 event. The followed
+events will be processed in real-time without queued. To switch off the
+real-time mode, send RELTIME 0 event.
+<LI>
+<TT>/proc</TT> interface:</LI>
+
+<BR>The status of applications and devices can be shown via <TT>/proc/asound/seq/oss</TT>
+at any time. In the later version, configuration will be changed via <TT>/proc</TT>
+interface, too.</UL>
+
+<H2>
+2. Installation</H2>
+Run configure script with both sequencer support (<TT>--with-sequencer=yes</TT>)
+and OSS emulation (<TT>--with-oss=yes</TT>) options. A module <TT>snd-seq-oss.o</TT>
+will be created. If the synth module of your sound card supports for OSS
+emulation (so far, only Emu8000 driver), this module will be loaded automatically.
+Otherwise, you need to load this module manually.
+<P>At beginning, this module probes all the MIDI ports which have been
+already connected to the sequencer. Once after that, the creation and deletion
+of ports are watched by announcement mechanism of ALSA sequencer.
+<P>The available synth and MIDI devices can be found in proc interface.
+Run "<TT>cat /proc/asound/seq/oss</TT>", and check the devices. For example,
+if you use an AWE64 card, you'll see like the following:
+<PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OSS sequencer emulation version 0.1.8
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALSA client number 63
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ALSA receiver port 0
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of applications: 0
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of synth devices: 1
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synth 0: [EMU8000]
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type 0x1 : subtype 0x20 : voices 32
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capabilties : ioctl enabled / load_patch enabled
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of MIDI devices: 3
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; midi 0: [Emu8000 Port-0] ALSA port 65:0
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capability write / opened none
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; midi 1: [Emu8000 Port-1] ALSA port 65:1
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capability write / opened none
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; midi 2: [0: MPU-401 (UART)] ALSA port 64:0
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capability read/write / opened none</PRE>
+Note that the device number may be different from the information of
+<TT>/proc/asound/oss-devices</TT>
+or ones of the original OSS driver. Use the device number listed in <TT>/proc/asound/seq/oss</TT>
+to play via OSS sequencer emulation.
+<H2>
+3. Using Synthesizer Devices</H2>
+Run your favorite program. I've tested playmidi-2.4, awemidi-0.4.3, gmod-3.1
+and xmp-1.1.5. You can load samples via <TT>/dev/sequencer</TT> like sfxload,
+too.
+<P>If the lowlevel driver supports multiple access to synth devices (like
+Emu8000 driver), two or more applications are allowed to run at the same
+time.
+<H2>
+4. Using MIDI Devices</H2>
+So far, only MIDI output was tested. MIDI input was not checked at all,
+but hopefully it will work. Use the device number listed in <TT>/proc/asound/seq/oss</TT>.
+Be aware that these numbers are mostly different from the list in
+<TT>/proc/asound/oss-devices</TT>.
+<H2>
+5. Module Options</H2>
+The following module options are available:
+<UL>
+<LI>
+<TT>maxqlen</TT></LI>
+
+<BR>specifies the maximum read/write queue length. This queue is private
+for OSS sequencer, so that it is independent from the queue length of ALSA
+sequencer. Default value is 1024.
+<LI>
+<TT>seq_oss_debug</TT></LI>
+
+<BR>specifies the debug level and accepts zero (= no debug message) or
+positive integer. Default value is 0.</UL>
+
+<H2>
+6. Queue Mechanism</H2>
+OSS sequencer emulation uses an ALSA priority queue. The
+events from <TT>/dev/sequencer</TT> are processed and put onto the queue
+specified by module option.
+<P>All the events from <TT>/dev/sequencer</TT> are parsed at beginning.
+The timing events are also parsed at this moment, so that the events may
+be processed in real-time. Sending an event ABSTIME 0 switches the operation
+mode to real-time mode, and sending an event RELTIME 0 switches it off.
+In the real-time mode, all events are dispatched immediately.
+<P>The queued events are dispatched to the corresponding ALSA sequencer
+ports after scheduled time by ALSA sequencer dispatcher.
+<P>If the write-queue is full, the application sleeps until a certain amount
+(as default one half) becomes empty in blocking mode. The synchronization
+to write timing was implemented, too.
+<P>The input from MIDI devices or echo-back events are stored on read FIFO
+queue. If application reads <TT>/dev/sequencer</TT> in blocking mode, the
+process will be awaked.
+
+<H2>
+7. Interface to Synthesizer Device</H2>
+
+<H3>
+7.1. Registration</H3>
+To register an OSS synthesizer device, use <TT>snd_seq_oss_synth_register</TT>
+function.
+<PRE>int snd_seq_oss_synth_register(char *name, int type, int subtype, int nvoices,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snd_seq_oss_callback_t *oper, void *private_data)</PRE>
+The arguments <TT>name</TT>, <TT>type</TT>, <TT>subtype</TT> and
+<TT>nvoices</TT>
+are used for making the appropriate synth_info structure for ioctl. The
+return value is an index number of this device. This index must be remembered
+for unregister. If registration is failed, -errno will be returned.
+<P>To release this device, call <TT>snd_seq_oss_synth_unregister function</TT>:
+<PRE>int snd_seq_oss_synth_unregister(int index),</PRE>
+where the <TT>index</TT> is the index number returned by register function.
+<H3>
+7.2. Callbacks</H3>
+OSS synthesizer devices have capability for sample downloading and ioctls
+like sample reset. In OSS emulation, these special features are realized
+by using callbacks. The registration argument oper is used to specify these
+callbacks. The following callback functions must be defined:
+<PRE>snd_seq_oss_callback_t:
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*open)(snd_seq_oss_arg_t *p, void *closure);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*close)(snd_seq_oss_arg_t *p);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char *buf, int offs, int count);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*reset)(snd_seq_oss_arg_t *p);
+Except for <TT>open</TT> and <TT>close</TT> callbacks, they are allowed
+to be NULL.
+<P>Each callback function takes the argument type snd_seq_oss_arg_t as the
+first argument.
+<PRE>struct snd_seq_oss_arg_t {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int app_index;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int file_mode;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int seq_mode;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snd_seq_addr_t addr;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *private_data;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int event_passing;
+};</PRE>
+The first three fields, <TT>app_index</TT>, <TT>file_mode</TT> and
+<TT>seq_mode</TT>
+are initialized by OSS sequencer. The <TT>app_index</TT> is the application
+index which is unique to each application opening OSS sequencer. The
+<TT>file_mode</TT>
+is bit-flags indicating the file operation mode. See
+<TT>seq_oss.h</TT>
+for its meaning. The <TT>seq_mode</TT> is sequencer operation mode. In
+the current version, only <TT>SND_OSSSEQ_MODE_SYNTH</TT> is used.
+<P>The next two fields, <TT>addr</TT> and <TT>private_data</TT>, must be
+filled by the synth driver at open callback. The <TT>addr</TT> contains
+the address of ALSA sequencer port which is assigned to this device. If
+the driver allocates memory for <TT>private_data</TT>, it must be released
+in close callback by itself.
+<P>The last field, <TT>event_passing</TT>, indicates how to translate note-on
+/ off events. In <TT>PROCESS_EVENTS</TT> mode, the note 255 is regarded
+as velocity change, and key pressure event is passed to the port. In <TT>PASS_EVENTS</TT>
+mode, all note on/off events are passed to the port without modified. <TT>PROCESS_KEYPRESS</TT>
+mode checks the note above 128 and regards it as key pressure event (mainly
+for Emu8000 driver).
+<H4>
+7.2.1. Open Callback</H4>
+The <TT>open</TT> is called at each time this device is opened by an application
+using OSS sequencer. This must not be NULL. Typically, the open callback
+does the following procedure:
+<OL>
+<LI>
+Allocate private data record.</LI>
+
+<LI>
+Create an ALSA sequencer port.</LI>
+
+<LI>
+Set the new port address on arg->addr.</LI>
+
+<LI>
+Set the private data record pointer on arg->private_data.</LI>
+</OL>
+Note that the type bit-flags in port_info of this synth port must NOT contain
+<TT>TYPE_MIDI_GENERIC</TT>
+bit. Instead, <TT>TYPE_SPECIFIC</TT> should be used. Also, <TT>CAP_SUBSCRIPTION</TT>
+bit should NOT be included, too. This is necessary to tell it from other
+normal MIDI devices. If the open procedure succeeded, return zero. Otherwise,
+return -errno.
+<H4>
+7.2.2 Ioctl Callback</H4>
+The <TT>ioctl</TT> callback is called when the sequencer receives device-specific
+ioctls. The following two ioctls should be processed by this callback:
+<UL>
+<LI>
+<TT>IOCTL_SEQ_RESET_SAMPLES</TT></LI>
+
+<BR>reset all samples on memory -- return 0
+<LI>
+<TT>IOCTL_SYNTH_MEMAVL</TT></LI>
+
+<BR>return the available memory size
+<LI>
+<TT>FM_4OP_ENABLE</TT></LI>
+
+<BR>can be ignored usually</UL>
+The other ioctls are processed inside the sequencer without passing to
+the lowlevel driver.
+<H4>
+7.2.3 Load_Patch Callback</H4>
+The <TT>load_patch</TT> callback is used for sample-downloading. This callback
+must read the data on user-space and transfer to each device. Return 0
+if succeeded, and -errno if failed. The format argument is the patch key
+in patch_info record. The buf is user-space pointer where patch_info record
+is stored. The offs can be ignored. The count is total data size of this
+sample data.
+<H4>
+7.2.4 Close Callback</H4>
+The <TT>close</TT> callback is called when this device is closed by the
+applicaion. If any private data was allocated in open callback, it must
+be released in the close callback. The deletion of ALSA port should be
+done here, too. This callback must not be NULL.
+<H4>
+7.2.5 Reset Callback</H4>
+The <TT>reset</TT> callback is called when sequencer device is reset or
+closed by applications. The callback should turn off the sounds on the
+relevant port immediately, and initialize the status of the port. If this
+callback is undefined, OSS seq sends a <TT>HEARTBEAT</TT> event to the
+port.
+<H3>
+7.3 Events</H3>
+Most of the events are processed by sequencer and translated to the adequate
+ALSA sequencer events, so that each synth device can receive by input_event
+callback of ALSA sequencer port. The following ALSA events should be implemented
+by the driver:
+<BR>&nbsp;
+<TABLE BORDER WIDTH="75%" NOSAVE >
+<TR NOSAVE>
+<TD NOSAVE><B>ALSA event</B></TD>
+
+<TD><B>Original OSS events</B></TD>
+</TR>
+
+<TR>
+<TD>NOTEON</TD>
+
+<TD>SEQ_NOTEON
+<BR>MIDI_NOTEON</TD>
+</TR>
+
+<TR>
+<TD>NOTE</TD>
+
+<TD>SEQ_NOTEOFF
+<BR>MIDI_NOTEOFF</TD>
+</TR>
+
+<TR NOSAVE>
+<TD NOSAVE>KEYPRESS</TD>
+
+<TD>MIDI_KEY_PRESSURE</TD>
+</TR>
+
+<TR NOSAVE>
+<TD>CHANPRESS</TD>
+
+<TD NOSAVE>SEQ_AFTERTOUCH
+<BR>MIDI_CHN_PRESSURE</TD>
+</TR>
+
+<TR NOSAVE>
+<TD NOSAVE>PGMCHANGE</TD>
+
+<TD NOSAVE>SEQ_PGMCHANGE
+<BR>MIDI_PGM_CHANGE</TD>
+</TR>
+
+<TR>
+<TD>PITCHBEND</TD>
+
+<TD>SEQ_CONTROLLER(CTRL_PITCH_BENDER)
+<BR>MIDI_PITCH_BEND</TD>
+</TR>
+
+<TR>
+<TD>CONTROLLER</TD>
+
+<TD>MIDI_CTL_CHANGE
+<BR>SEQ_BALANCE (with CTL_PAN)</TD>
+</TR>
+
+<TR>
+<TD>CONTROL14</TD>
+
+<TD>SEQ_CONTROLLER</TD>
+</TR>
+
+<TR>
+<TD>REGPARAM</TD>
+
+<TD>SEQ_CONTROLLER(CTRL_PITCH_BENDER_RANGE)</TD>
+</TR>
+
+<TR>
+<TD>SYSEX</TD>
+
+<TD>SEQ_SYSEX</TD>
+</TR>
+</TABLE>
+
+<P>The most of these behavior can be realized by MIDI emulation driver
+included in the Emu8000 lowlevel driver. In the future release, this module
+will be independent.
+<P>Some OSS events (<TT>SEQ_PRIVATE</TT> and <TT>SEQ_VOLUME</TT> events) are passed as event
+type SND_SEQ_OSS_PRIVATE.  The OSS sequencer passes these event 8 byte
+packets without any modification. The lowlevel driver should process these
+events appropriately.
+<H2>
+8. Interface to MIDI Device</H2>
+Since the OSS emulation probes the creation and deletion of ALSA MIDI sequencer
+ports automatically by receiving announcement from ALSA sequencer, the
+MIDI devices don't need to be registered explicitly like synth devices.
+However, the MIDI port_info registered to ALSA sequencer must include a group
+name <TT>SND_SEQ_GROUP_DEVICE</TT> and a capability-bit <TT>CAP_READ</TT> or
+<TT>CAP_WRITE</TT>. Also, subscription capabilities, <TT>CAP_SUBS_READ</TT> or <TT>CAP_SUBS_WRITE</TT>,
+must be defined, too. If these conditions are not satisfied, the port is not
+registered as OSS sequencer MIDI device.
+<P>The events via MIDI devices are parsed in OSS sequencer and converted
+to the corresponding ALSA sequencer events. The input from MIDI sequencer
+is also converted to MIDI byte events by OSS sequencer. This works just
+a reverse way of seq_midi module.
+<H2>
+9. Known Problems / TODO's</H2>
+
+<UL>
+<LI>
+Patch loading via ALSA instrument layer is not implemented yet.</LI>
+</UL>
+
+</BODY>
+</HTML>
diff --git a/Documentation/sound/alsa/serial-u16550.txt b/Documentation/sound/alsa/serial-u16550.txt
new file mode 100644
index 0000000..c191955
--- /dev/null
+++ b/Documentation/sound/alsa/serial-u16550.txt
@@ -0,0 +1,88 @@
+
+			Serial UART 16450/16550 MIDI driver
+			===================================
+
+The adaptor module parameter allows you to select either:
+
+  0 - Roland Soundcanvas support (default)
+  1 - Midiator MS-124T support (1)
+  2 - Midiator MS-124W S/A mode (2)
+  3 - MS-124W M/B mode support (3)
+  4 - Generic device with multiple input support (4)
+
+For the Midiator MS-124W, you must set the physical M-S and A-B
+switches on the Midiator to match the driver mode you select.
+
+In Roland Soundcanvas mode, multiple ALSA raw MIDI substreams are supported
+(midiCnD0-midiCnD15).  Whenever you write to a different substream, the driver
+sends the nonstandard MIDI command sequence F5 NN, where NN is the substream
+number plus 1.  Roland modules use this command to switch between different
+"parts", so this feature lets you treat each part as a distinct raw MIDI
+substream. The driver provides no way to send F5 00 (no selection) or to not
+send the F5 NN command sequence at all; perhaps it ought to.
+
+Usage example for simple serial converter:
+
+	/sbin/setserial /dev/ttyS0 uart none
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 speed=115200
+
+Usage example for Roland SoundCanvas with 4 MIDI ports:
+
+	/sbin/setserial /dev/ttyS0 uart none
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 outs=4
+
+In MS-124T mode, one raw MIDI substream is supported (midiCnD0); the outs
+module parameter is automatically set to 1. The driver sends the same data to
+all four MIDI Out connectors.  Set the A-B switch and the speed module
+parameter to match (A=19200, B=9600).
+
+Usage example for MS-124T, with A-B switch in A position:
+
+	/sbin/setserial /dev/ttyS0 uart none
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=1 \
+			speed=19200
+
+In MS-124W S/A mode, one raw MIDI substream is supported (midiCnD0);
+the outs module parameter is automatically set to 1. The driver sends
+the same data to all four MIDI Out connectors at full MIDI speed.
+
+Usage example for S/A mode:
+
+	/sbin/setserial /dev/ttyS0 uart none
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=2
+
+In MS-124W M/B mode, the driver supports 16 ALSA raw MIDI substreams;
+the outs module parameter is automatically set to 16.  The substream
+number gives a bitmask of which MIDI Out connectors the data should be
+sent to, with midiCnD1 sending to Out 1, midiCnD2 to Out 2, midiCnD4 to
+Out 3, and midiCnD8 to Out 4.  Thus midiCnD15 sends the data to all 4 ports.
+As a special case, midiCnD0 also sends to all ports, since it is not useful
+to send the data to no ports.  M/B mode has extra overhead to select the MIDI
+Out for each byte, so the aggregate data rate across all four MIDI Outs is
+at most one byte every 520 us, as compared with the full MIDI data rate of
+one byte every 320 us per port.
+
+Usage example for M/B mode:
+
+	/sbin/setserial /dev/ttyS0 uart none
+	/sbin/modprobe snd-serial-u16550 port=0x3f8 irq=4 adaptor=3
+
+The MS-124W hardware's M/A mode is currently not supported. This mode allows
+the MIDI Outs to act independently at double the aggregate throughput of M/B,
+but does not allow sending the same byte simultaneously to multiple MIDI Outs. 
+The M/A protocol requires the driver to twiddle the modem control lines under
+timing constraints, so it would be a bit more complicated to implement than
+the other modes.
+
+Midiator models other than MS-124W and MS-124T are currently not supported. 
+Note that the suffix letter is significant; the MS-124 and MS-124B are not
+compatible, nor are the other known models MS-101, MS-101B, MS-103, and MS-114.
+I do have documentation (tim.mann@compaq.com) that partially covers these models,
+but no units to experiment with.  The MS-124W support is tested with a real unit.
+The MS-124T support is untested, but should work.
+
+The Generic driver supports multiple input and output substreams over a single
+serial port.  Similar to Roland Soundcanvas mode, F5 NN is used to select the
+appropriate input or output stream (depending on the data direction).
+Additionally, the CTS signal is used to regulate the data flow.  The number of
+inputs is specified by the ins parameter.
diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt
new file mode 100644
index 0000000..0ebd7ea
--- /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/design/chipsets/audio/ac97_r23.pdf
+
+
+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/clocking.txt b/Documentation/sound/alsa/soc/clocking.txt
new file mode 100644
index 0000000..b130016
--- /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 0000000..1e95342
--- /dev/null
+++ b/Documentation/sound/alsa/soc/codec.txt
@@ -0,0 +1,198 @@
+ASoC Codec Driver
+=================
+
+The codec driver is generic and hardware independent code that configures the
+codec 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 driver *must* provide the following features:-
+
+ 1) Codec DAI and PCM configuration
+ 2) Codec control IO - using I2C, 3 Wire(SPI) or both APIs
+ 3) Mixers and audio controls
+ 4) Codec audio operations
+
+Optionally, codec drivers can also provide:-
+
+ 5) DAPM description.
+ 6) DAPM event handler.
+ 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_codec_dai 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.
+
+struct snd_soc_codec_dai wm8731_dai = {
+	.name = "WM8731",
+	/* playback capabilities */
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = WM8731_RATES,
+		.formats = WM8731_FORMATS,},
+	/* capture capabilities */
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = WM8731_RATES,
+		.formats = WM8731_FORMATS,},
+	/* pcm operations - see section 4 below */
+	.ops = {
+		.prepare = wm8731_pcm_prepare,
+		.hw_params = wm8731_hw_params,
+		.shutdown = wm8731_shutdown,
+	},
+	/* DAI operations - see DAI.txt */
+	.dai_ops = {
+		.digital_mute = wm8731_mute,
+		.set_sysclk = wm8731_set_dai_sysclk,
+		.set_fmt = wm8731_set_dai_fmt,
+	}
+};
+EXPORT_SYMBOL_GPL(wm8731_dai);
+
+
+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 drivers provide
+functions to read and write the codec registers along with supplying a
+register cache:-
+
+	/* IO control data and register cache */
+	void *control_data; /* codec control (i2c/3wire) data */
+	void *reg_cache;
+
+Codec read/write should do any data formatting and call the hardware
+read write below to perform the IO. These functions are called by the
+core and ALSA when performing DAPM or changing the mixer:-
+
+    unsigned int (*read)(struct snd_soc_codec *, unsigned int);
+    int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
+
+Codec hardware IO functions - usually points to either the I2C, SPI or AC97
+read/write:-
+
+	hw_write_t hw_write;
+	hw_read_t hw_read;
+
+
+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 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/c436.htm
+
+
+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_codec *codec,
+	struct snd_soc_codec_dai *dai, int mute)
+{
+	u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf;
+	if(mute)
+		wm8974_write(codec, WM8974_DAC, mute_reg | 0x40);
+	else
+		wm8974_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 0000000..46f9684
--- /dev/null
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -0,0 +1,290 @@
+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 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 susbsystem 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 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 are usually added in the codec driver and the machine driver. 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) and DACs (digital to analog converters).
+
+Stream widgets have the following format:-
+
+SND_SOC_DAPM_DAC(name, stream name, 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),
+
+
+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)),
+
+
+2.3 Platform/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) 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 Domain
+----------------
+
+The codec 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 Widget Interconnections
+================================
+
+Widgets are connected to each other within the codec 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 (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 it's kcontrol name. We can now
+connect the destination widget (wrt audio signal) with it's 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
+
+When a codec pin is NC it can be marked as not used with a call to
+
+snd_soc_dapm_set_endpoint(codec, "Widget Name", 0);
+
+The last argument is 0 for inactive and 1 for active. This way the pin and its
+input widget will never be powered up and consume power.
+
+This also applies to machine widgets. e.g. if a headphone is connected to a
+jack then the jack can be marked active. If the headphone is removed, then
+the headphone jack can be marked inactive.
+
+
+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/machine.txt b/Documentation/sound/alsa/soc/machine.txt
new file mode 100644
index 0000000..f370e7d
--- /dev/null
+++ b/Documentation/sound/alsa/soc/machine.txt
@@ -0,0 +1,113 @@
+ASoC Machine Driver
+===================
+
+The ASoC machine (or board) driver is the code that glues together the platform
+and codec drivers.
+
+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_machine {
+	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);
+
+	/* machine stream operations */
+	struct snd_soc_ops *ops;
+
+	/* 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 operations
+------------------
+The machine specific audio operations can be set here. Again this is 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. Please see corgi.c, spitz.c
+for examples.
+
+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 = &pxa_i2s_dai,
+	.codec_dai = &wm8731_dai,
+	.init = corgi_wm8731_init,
+	.ops = &corgi_ops,
+};
+
+struct snd_soc_machine then sets up the machine with it's DAIs. e.g.
+
+/* corgi audio machine driver */
+static struct snd_soc_machine snd_soc_machine_corgi = {
+	.name = "Corgi",
+	.dai_link = &corgi_dai,
+	.num_links = 1,
+};
+
+
+Machine Audio Subsystem
+-----------------------
+
+The machine soc device glues the platform, machine and codec driver together.
+Private data can also be set here. e.g.
+
+/* corgi audio private data */
+static struct wm8731_setup_data corgi_wm8731_setup = {
+	.i2c_address = 0x1b,
+};
+
+/* corgi audio subsystem */
+static struct snd_soc_device corgi_snd_devdata = {
+	.machine = &snd_soc_machine_corgi,
+	.platform = &pxa2xx_soc_platform,
+	.codec_dev = &soc_codec_dev_wm8731,
+	.codec_data = &corgi_wm8731_setup,
+};
+
+
+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. See soc/pxa/spitz.c and dapm.txt for
+details.
+
+
+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 0000000..1e4c6d3
--- /dev/null
+++ b/Documentation/sound/alsa/soc/overview.txt
@@ -0,0 +1,86 @@
+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 it's 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 3
+components :-
+
+  * Codec driver: The codec driver is platform independent and contains audio
+    controls, audio interface capabilities, codec DAPM definition and codec IO
+    functions.
+
+  * Platform driver: The platform driver contains the audio DMA engine and audio
+    interface drivers (e.g. I2S, AC97, PCM) for that platform.
+
+  * Machine driver: The machine driver handles any machine specific controls and
+    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.
diff --git a/Documentation/sound/alsa/soc/platform.txt b/Documentation/sound/alsa/soc/platform.txt
new file mode 100644
index 0000000..b681d17
--- /dev/null
+++ b/Documentation/sound/alsa/soc/platform.txt
@@ -0,0 +1,58 @@
+ASoC Platform Driver
+====================
+
+An ASoC platform driver can be divided into audio DMA and SoC DAI configuration
+and control. 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:-
+
+struct snd_soc_platform {
+	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 *);
+
+	/* 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/c436.htm
+
+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.
diff --git a/Documentation/sound/alsa/soc/pops_clicks.txt b/Documentation/sound/alsa/soc/pops_clicks.txt
new file mode 100644
index 0000000..e1e74da
--- /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/include/sound/Kbuild b/include/sound/Kbuild
new file mode 100644
index 0000000..fd054a3
--- /dev/null
+++ b/include/sound/Kbuild
@@ -0,0 +1,10 @@
+header-y += asound_fm.h
+header-y += hdsp.h
+header-y += hdspm.h
+header-y += sfnt_info.h
+header-y += sscape_ioctl.h
+
+unifdef-y += asequencer.h
+unifdef-y += asound.h
+unifdef-y += emu10k1.h
+unifdef-y += sb16_csp.h
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
new file mode 100644
index 0000000..251fc1c
--- /dev/null
+++ b/include/sound/ac97_codec.h
@@ -0,0 +1,645 @@
+#ifndef __SOUND_AC97_CODEC_H
+#define __SOUND_AC97_CODEC_H
+
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Universal interface for Audio Codec '97
+ *
+ *  For more details look to AC '97 component specification revision 2.1
+ *  by Intel Corporation (http://developer.intel.com).
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include "pcm.h"
+#include "control.h"
+#include "info.h"
+
+/*
+ *  AC'97 codec registers
+ */
+
+#define AC97_RESET		0x00	/* Reset */
+#define AC97_MASTER		0x02	/* Master Volume */
+#define AC97_HEADPHONE		0x04	/* Headphone Volume (optional) */
+#define AC97_MASTER_MONO	0x06	/* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE	0x08	/* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP		0x0a	/* PC Beep Volume (optinal) */
+#define AC97_PHONE		0x0c	/* Phone Volume (optional) */
+#define AC97_MIC		0x0e	/* MIC Volume */
+#define AC97_LINE		0x10	/* Line In Volume */
+#define AC97_CD			0x12	/* CD Volume */
+#define AC97_VIDEO		0x14	/* Video Volume (optional) */
+#define AC97_AUX		0x16	/* AUX Volume (optional) */
+#define AC97_PCM		0x18	/* PCM Volume */
+#define AC97_REC_SEL		0x1a	/* Record Select */
+#define AC97_REC_GAIN		0x1c	/* Record Gain */
+#define AC97_REC_GAIN_MIC	0x1e	/* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE	0x20	/* General Purpose (optional) */
+#define AC97_3D_CONTROL		0x22	/* 3D Control (optional) */
+#define AC97_INT_PAGING		0x24	/* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN		0x26	/* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID	0x28	/* Extended Audio ID */
+#define AC97_EXTENDED_STATUS	0x2a	/* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER	0x36	/* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER	0x38	/* Surround (Rear) Master Volume */
+#define AC97_SPDIF		0x3a	/* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID	0x3c	/* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS	0x3e	/* Extended Modem Status and Control */
+#define AC97_LINE1_RATE		0x40	/* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE		0x42	/* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE	0x44	/* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL	0x46	/* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL	0x48	/* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL	0x4a	/* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG		0x4c	/* GPIO Configuration */
+#define AC97_GPIO_POLARITY	0x4e	/* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY	0x50	/* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP	0x52	/* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS	0x54	/* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE		0x56	/* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1		0x7c	/* Vendor ID1 */
+#define AC97_VENDOR_ID2		0x7e	/* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV	0x60	/* Codec Class/Revision */
+#define AC97_PCI_SVID		0x62	/* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID		0x64	/* PCI Subsystem ID */
+#define AC97_FUNC_SELECT	0x66	/* Function Select */
+#define AC97_FUNC_INFO		0x68	/* Function Information */
+#define AC97_SENSE_INFO		0x6a	/* Sense Details */
+
+/* slot allocation */
+#define AC97_SLOT_TAG		0
+#define AC97_SLOT_CMD_ADDR	1
+#define AC97_SLOT_CMD_DATA	2
+#define AC97_SLOT_PCM_LEFT	3
+#define AC97_SLOT_PCM_RIGHT	4
+#define AC97_SLOT_MODEM_LINE1	5
+#define AC97_SLOT_PCM_CENTER	6
+#define AC97_SLOT_MIC		6	/* input */
+#define AC97_SLOT_SPDIF_LEFT1	6
+#define AC97_SLOT_PCM_SLEFT	7	/* surround left */
+#define AC97_SLOT_PCM_LEFT_0	7	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT	7
+#define AC97_SLOT_PCM_SRIGHT	8	/* surround right */
+#define AC97_SLOT_PCM_RIGHT_0	8	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT	8
+#define AC97_SLOT_LFE		9
+#define AC97_SLOT_SPDIF_RIGHT1	9
+#define AC97_SLOT_MODEM_LINE2	10
+#define AC97_SLOT_PCM_LEFT_1	10	/* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2	10
+#define AC97_SLOT_HANDSET	11	/* output */
+#define AC97_SLOT_PCM_RIGHT_1	11	/* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2	11
+#define AC97_SLOT_MODEM_GPIO	12	/* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1	12	/* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC	0x0001	/* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1	0x0002	/* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE	0x0004	/* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO	0x0008	/* Simulated stereo */
+#define AC97_BC_HEADPHONE	0x0010	/* Headphone Out Support */
+#define AC97_BC_LOUDNESS	0x0020	/* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC	0x0000	/* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC	0x0040	/* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC	0x0080	/* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK	0x00c0
+#define AC97_BC_16BIT_ADC	0x0000	/* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC	0x0100	/* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC	0x0200	/* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK	0x0300
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK	0x0c00	/* double rate slot select */
+#define AC97_GP_DRSS_1011	0x0000	/* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78		0x0400	/* LR 7+8 */
+
+/* powerdown bits */
+#define AC97_PD_ADC_STATUS	0x0001	/* ADC status (RO) */
+#define AC97_PD_DAC_STATUS	0x0002	/* DAC status (RO) */
+#define AC97_PD_MIXER_STATUS	0x0004	/* Analog mixer status (RO) */
+#define AC97_PD_VREF_STATUS	0x0008	/* Vref status (RO) */
+#define AC97_PD_PR0		0x0100	/* Power down PCM ADCs and input MUX */
+#define AC97_PD_PR1		0x0200	/* Power down PCM front DAC */
+#define AC97_PD_PR2		0x0400	/* Power down Mixer (Vref still on) */
+#define AC97_PD_PR3		0x0800	/* Power down Mixer (Vref off) */
+#define AC97_PD_PR4		0x1000	/* Power down AC-Link */
+#define AC97_PD_PR5		0x2000	/* Disable internal clock usage */
+#define AC97_PD_PR6		0x4000	/* Headphone amplifier */
+#define AC97_PD_EAPD		0x8000	/* External Amplifer Power Down (EAPD) */
+
+/* extended audio ID bit defines */
+#define AC97_EI_VRA		0x0001	/* Variable bit rate supported */
+#define AC97_EI_DRA		0x0002	/* Double rate supported */
+#define AC97_EI_SPDIF		0x0004	/* S/PDIF out supported */
+#define AC97_EI_VRM		0x0008	/* Variable bit rate supported for MIC */
+#define AC97_EI_DACS_SLOT_MASK	0x0030	/* DACs slot assignment */
+#define AC97_EI_DACS_SLOT_SHIFT	4
+#define AC97_EI_CDAC		0x0040	/* PCM Center DAC available */
+#define AC97_EI_SDAC		0x0080	/* PCM Surround DACs available */
+#define AC97_EI_LDAC		0x0100	/* PCM LFE DAC available */
+#define AC97_EI_AMAP		0x0200	/* indicates optional slot/DAC mapping based on codec ID */
+#define AC97_EI_REV_MASK	0x0c00	/* AC'97 revision mask */
+#define AC97_EI_REV_22		0x0400	/* AC'97 revision 2.2 */
+#define AC97_EI_REV_23		0x0800	/* AC'97 revision 2.3 */
+#define AC97_EI_REV_SHIFT	10
+#define AC97_EI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_EI_ADDR_SHIFT	14
+
+/* extended audio status and control bit defines */
+#define AC97_EA_VRA		0x0001	/* Variable bit rate enable bit */
+#define AC97_EA_DRA		0x0002	/* Double-rate audio enable bit */
+#define AC97_EA_SPDIF		0x0004	/* S/PDIF out enable bit */
+#define AC97_EA_VRM		0x0008	/* Variable bit rate for MIC enable bit */
+#define AC97_EA_SPSA_SLOT_MASK	0x0030	/* Mask for slot assignment bits */
+#define AC97_EA_SPSA_SLOT_SHIFT 4
+#define AC97_EA_SPSA_3_4	0x0000	/* Slot assigned to 3 & 4 */
+#define AC97_EA_SPSA_7_8	0x0010	/* Slot assigned to 7 & 8 */
+#define AC97_EA_SPSA_6_9	0x0020	/* Slot assigned to 6 & 9 */
+#define AC97_EA_SPSA_10_11	0x0030	/* Slot assigned to 10 & 11 */
+#define AC97_EA_CDAC		0x0040	/* PCM Center DAC is ready (Read only) */
+#define AC97_EA_SDAC		0x0080	/* PCM Surround DACs are ready (Read only) */
+#define AC97_EA_LDAC		0x0100	/* PCM LFE DAC is ready (Read only) */
+#define AC97_EA_MDAC		0x0200	/* MIC ADC is ready (Read only) */
+#define AC97_EA_SPCV		0x0400	/* S/PDIF configuration valid (Read only) */
+#define AC97_EA_PRI		0x0800	/* Turns the PCM Center DAC off */
+#define AC97_EA_PRJ		0x1000	/* Turns the PCM Surround DACs off */
+#define AC97_EA_PRK		0x2000	/* Turns the PCM LFE DAC off */
+#define AC97_EA_PRL		0x4000	/* Turns the MIC ADC off */
+
+/* S/PDIF control bit defines */
+#define AC97_SC_PRO		0x0001	/* Professional status */
+#define AC97_SC_NAUDIO		0x0002	/* Non audio stream */
+#define AC97_SC_COPY		0x0004	/* Copyright status */
+#define AC97_SC_PRE		0x0008	/* Preemphasis status */
+#define AC97_SC_CC_MASK		0x07f0	/* Category Code mask */
+#define AC97_SC_CC_SHIFT	4
+#define AC97_SC_L		0x0800	/* Generation Level status */
+#define AC97_SC_SPSR_MASK	0x3000	/* S/PDIF Sample Rate bits */
+#define AC97_SC_SPSR_SHIFT	12
+#define AC97_SC_SPSR_44K	0x0000	/* Use 44.1kHz Sample rate */
+#define AC97_SC_SPSR_48K	0x2000	/* Use 48kHz Sample rate */
+#define AC97_SC_SPSR_32K	0x3000	/* Use 32kHz Sample rate */
+#define AC97_SC_DRS		0x4000	/* Double Rate S/PDIF */
+#define AC97_SC_V		0x8000	/* Validity status */
+
+/* Interrupt and Paging bit defines (AC'97 2.3) */
+#define AC97_PAGE_MASK		0x000f	/* Page Selector */
+#define AC97_PAGE_VENDOR	0	/* Vendor-specific registers */
+#define AC97_PAGE_1		1	/* Extended Codec Registers page 1 */
+#define AC97_INT_ENABLE		0x0800	/* Interrupt Enable */
+#define AC97_INT_SENSE		0x1000	/* Sense Cycle */
+#define AC97_INT_CAUSE_SENSE	0x2000	/* Sense Cycle Completed (RO) */
+#define AC97_INT_CAUSE_GPIO	0x4000	/* GPIO bits changed (RO) */
+#define AC97_INT_STATUS		0x8000	/* Interrupt Status */
+
+/* extended modem ID bit defines */
+#define AC97_MEI_LINE1		0x0001	/* Line1 present */
+#define AC97_MEI_LINE2		0x0002	/* Line2 present */
+#define AC97_MEI_HANDSET	0x0004	/* Handset present */
+#define AC97_MEI_CID1		0x0008	/* caller ID decode for Line1 is supported */
+#define AC97_MEI_CID2		0x0010	/* caller ID decode for Line2 is supported */
+#define AC97_MEI_ADDR_MASK	0xc000	/* physical codec ID (address) */
+#define AC97_MEI_ADDR_SHIFT	14
+
+/* extended modem status and control bit defines */
+#define AC97_MEA_GPIO		0x0001	/* GPIO is ready (ro) */
+#define AC97_MEA_MREF		0x0002	/* Vref is up to nominal level (ro) */
+#define AC97_MEA_ADC1		0x0004	/* ADC1 operational (ro) */
+#define AC97_MEA_DAC1		0x0008	/* DAC1 operational (ro) */
+#define AC97_MEA_ADC2		0x0010	/* ADC2 operational (ro) */
+#define AC97_MEA_DAC2		0x0020	/* DAC2 operational (ro) */
+#define AC97_MEA_HADC		0x0040	/* HADC operational (ro) */
+#define AC97_MEA_HDAC		0x0080	/* HDAC operational (ro) */
+#define AC97_MEA_PRA		0x0100	/* GPIO power down (high) */
+#define AC97_MEA_PRB		0x0200	/* reserved */
+#define AC97_MEA_PRC		0x0400	/* ADC1 power down (high) */
+#define AC97_MEA_PRD		0x0800	/* DAC1 power down (high) */
+#define AC97_MEA_PRE		0x1000	/* ADC2 power down (high) */
+#define AC97_MEA_PRF		0x2000	/* DAC2 power down (high) */
+#define AC97_MEA_PRG		0x4000	/* HADC power down (high) */
+#define AC97_MEA_PRH		0x8000	/* HDAC power down (high) */
+
+/* modem gpio status defines */
+#define AC97_GPIO_LINE1_OH      0x0001  /* Off Hook Line1 */
+#define AC97_GPIO_LINE1_RI      0x0002  /* Ring Detect Line1 */
+#define AC97_GPIO_LINE1_CID     0x0004  /* Caller ID path enable Line1 */
+#define AC97_GPIO_LINE1_LCS     0x0008  /* Loop Current Sense Line1 */
+#define AC97_GPIO_LINE1_PULSE   0x0010  /* Opt./ Pulse Dial Line1 (out) */
+#define AC97_GPIO_LINE1_HL1R    0x0020  /* Opt./ Handset to Line1 relay control (out) */
+#define AC97_GPIO_LINE1_HOHD    0x0040  /* Opt./ Handset off hook detect Line1 (in) */
+#define AC97_GPIO_LINE12_AC     0x0080  /* Opt./ Int.bit 1 / Line1/2 AC (out) */
+#define AC97_GPIO_LINE12_DC     0x0100  /* Opt./ Int.bit 2 / Line1/2 DC (out) */
+#define AC97_GPIO_LINE12_RS     0x0200  /* Opt./ Int.bit 3 / Line1/2 RS (out) */
+#define AC97_GPIO_LINE2_OH      0x0400  /* Off Hook Line2 */
+#define AC97_GPIO_LINE2_RI      0x0800  /* Ring Detect Line2 */
+#define AC97_GPIO_LINE2_CID     0x1000  /* Caller ID path enable Line2 */
+#define AC97_GPIO_LINE2_LCS     0x2000  /* Loop Current Sense Line2 */
+#define AC97_GPIO_LINE2_PULSE   0x4000  /* Opt./ Pulse Dial Line2 (out) */
+#define AC97_GPIO_LINE2_HL1R    0x8000  /* Opt./ Handset to Line2 relay control (out) */
+
+/* specific - SigmaTel */
+#define AC97_SIGMATEL_OUTSEL	0x64	/* Output Select, STAC9758 */
+#define AC97_SIGMATEL_INSEL	0x66	/* Input Select, STAC9758 */
+#define AC97_SIGMATEL_IOMISC	0x68	/* STAC9758 */
+#define AC97_SIGMATEL_ANALOG	0x6c	/* Analog Special */
+#define AC97_SIGMATEL_DAC2INVERT 0x6e
+#define AC97_SIGMATEL_BIAS1	0x70
+#define AC97_SIGMATEL_BIAS2	0x72
+#define AC97_SIGMATEL_VARIOUS	0x72	/* STAC9758 */
+#define AC97_SIGMATEL_MULTICHN	0x74	/* Multi-Channel programming */
+#define AC97_SIGMATEL_CIC1	0x76
+#define AC97_SIGMATEL_CIC2	0x78
+
+/* specific - Analog Devices */
+#define AC97_AD_TEST		0x5a	/* test register */
+#define AC97_AD_TEST2		0x5c	/* undocumented test register 2 */
+#define AC97_AD_HPFD_SHIFT	12	/* High Pass Filter Disable */
+#define AC97_AD_CODEC_CFG	0x70	/* codec configuration */
+#define AC97_AD_JACK_SPDIF	0x72	/* Jack Sense & S/PDIF */
+#define AC97_AD_SERIAL_CFG	0x74	/* Serial Configuration */
+#define AC97_AD_MISC		0x76	/* Misc Control Bits */
+#define AC97_AD_VREFD_SHIFT	2	/* V_REFOUT Disable (AD1888) */
+
+/* specific - Cirrus Logic */
+#define AC97_CSR_ACMODE		0x5e	/* AC Mode Register */
+#define AC97_CSR_MISC_CRYSTAL	0x60	/* Misc Crystal Control */
+#define AC97_CSR_SPDIF		0x68	/* S/PDIF Register */
+#define AC97_CSR_SERIAL		0x6a	/* Serial Port Control */
+#define AC97_CSR_SPECF_ADDR	0x6c	/* Special Feature Address */
+#define AC97_CSR_SPECF_DATA	0x6e	/* Special Feature Data */
+#define AC97_CSR_BDI_STATUS	0x7a	/* BDI Status */
+
+/* specific - Conexant */
+#define AC97_CXR_AUDIO_MISC	0x5c
+#define AC97_CXR_SPDIFEN	(1<<3)
+#define AC97_CXR_COPYRGT	(1<<2)
+#define AC97_CXR_SPDIF_MASK	(3<<0)
+#define AC97_CXR_SPDIF_PCM	0x0
+#define AC97_CXR_SPDIF_AC3	0x2
+
+/* specific - ALC */
+#define AC97_ALC650_SPDIF_INPUT_STATUS1	0x60
+/* S/PDIF input status 1 bit defines */
+#define AC97_ALC650_PRO             0x0001  /* Professional status */
+#define AC97_ALC650_NAUDIO          0x0002  /* Non audio stream */
+#define AC97_ALC650_COPY            0x0004  /* Copyright status */
+#define AC97_ALC650_PRE             0x0038  /* Preemphasis status */
+#define AC97_ALC650_PRE_SHIFT       3
+#define AC97_ALC650_MODE            0x00C0  /* Preemphasis status */
+#define AC97_ALC650_MODE_SHIFT      6
+#define AC97_ALC650_CC_MASK         0x7f00  /* Category Code mask */
+#define AC97_ALC650_CC_SHIFT        8
+#define AC97_ALC650_L               0x8000  /* Generation Level status */
+
+#define AC97_ALC650_SPDIF_INPUT_STATUS2	0x62
+/* S/PDIF input status 2 bit defines */
+#define AC97_ALC650_SOUCE_MASK      0x000f  /* Source number */
+#define AC97_ALC650_CHANNEL_MASK    0x00f0  /* Channel number */
+#define AC97_ALC650_CHANNEL_SHIFT   4 
+#define AC97_ALC650_SPSR_MASK       0x0f00  /* S/PDIF Sample Rate bits */
+#define AC97_ALC650_SPSR_SHIFT      8
+#define AC97_ALC650_SPSR_44K        0x0000  /* Use 44.1kHz Sample rate */
+#define AC97_ALC650_SPSR_48K        0x0200  /* Use 48kHz Sample rate */
+#define AC97_ALC650_SPSR_32K        0x0300  /* Use 32kHz Sample rate */
+#define AC97_ALC650_CLOCK_ACCURACY  0x3000  /* Clock accuracy */
+#define AC97_ALC650_CLOCK_SHIFT     12
+#define AC97_ALC650_CLOCK_LOCK      0x4000  /* Clock locked status */
+#define AC97_ALC650_V               0x8000  /* Validity status */
+
+#define AC97_ALC650_SURR_DAC_VOL	0x64
+#define AC97_ALC650_LFE_DAC_VOL		0x66
+#define AC97_ALC650_UNKNOWN1		0x68
+#define AC97_ALC650_MULTICH		0x6a
+#define AC97_ALC650_UNKNOWN2		0x6c
+#define AC97_ALC650_REVISION		0x6e
+#define AC97_ALC650_UNKNOWN3		0x70
+#define AC97_ALC650_UNKNOWN4		0x72
+#define AC97_ALC650_MISC		0x74
+#define AC97_ALC650_GPIO_SETUP		0x76
+#define AC97_ALC650_GPIO_STATUS		0x78
+#define AC97_ALC650_CLOCK		0x7a
+
+/* specific - Yamaha YMF7x3 */
+#define AC97_YMF7X3_DIT_CTRL	0x66	/* DIT Control (YMF743) / 2 (YMF753) */
+#define AC97_YMF7X3_3D_MODE_SEL	0x68	/* 3D Mode Select */
+
+/* specific - C-Media */
+#define AC97_CM9738_VENDOR_CTRL	0x5a
+#define AC97_CM9739_MULTI_CHAN	0x64
+#define AC97_CM9739_SPDIF_IN_STATUS	0x68 /* 32bit */
+#define AC97_CM9739_SPDIF_CTRL	0x6c
+
+/* specific - wolfson */
+#define AC97_WM97XX_FMIXER_VOL  0x72
+#define AC97_WM9704_RMIXER_VOL  0x74
+#define AC97_WM9704_TEST        0x5a
+#define AC97_WM9704_RPCM_VOL    0x70
+#define AC97_WM9711_OUT3VOL     0x16
+
+
+/* ac97->scaps */
+#define AC97_SCAP_AUDIO		(1<<0)	/* audio codec 97 */
+#define AC97_SCAP_MODEM		(1<<1)	/* modem codec 97 */
+#define AC97_SCAP_SURROUND_DAC	(1<<2)	/* surround L&R DACs are present */
+#define AC97_SCAP_CENTER_LFE_DAC (1<<3)	/* center and LFE DACs are present */
+#define AC97_SCAP_SKIP_AUDIO	(1<<4)	/* skip audio part of codec */
+#define AC97_SCAP_SKIP_MODEM	(1<<5)	/* skip modem part of codec */
+#define AC97_SCAP_INDEP_SDIN	(1<<6)	/* independent SDIN */
+#define AC97_SCAP_INV_EAPD	(1<<7)	/* inverted EAPD */
+#define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */
+#define AC97_SCAP_NO_SPDIF	(1<<9)	/* don't build SPDIF controls */
+#define AC97_SCAP_EAPD_LED	(1<<10)	/* EAPD as mute LED */
+#define AC97_SCAP_POWER_SAVE	(1<<11)	/* capable for aggresive power-saving */
+
+/* ac97->flags */
+#define AC97_HAS_PC_BEEP	(1<<0)	/* force PC Speaker usage */
+#define AC97_AD_MULTI		(1<<1)	/* Analog Devices - multi codecs */
+#define AC97_CS_SPDIF		(1<<2)	/* Cirrus Logic uses funky SPDIF */
+#define AC97_CX_SPDIF		(1<<3)	/* Conexant's spdif interface */
+#define AC97_STEREO_MUTES	(1<<4)	/* has stereo mute bits */
+#define AC97_DOUBLE_RATE	(1<<5)	/* supports double rate playback */
+#define AC97_HAS_NO_MASTER_VOL	(1<<6)	/* no Master volume */
+#define AC97_HAS_NO_PCM_VOL	(1<<7)	/* no PCM volume */
+#define AC97_DEFAULT_POWER_OFF	(1<<8)	/* no RESET write */
+#define AC97_MODEM_PATCH	(1<<9)	/* modem patch */
+#define AC97_HAS_NO_REC_GAIN	(1<<10) /* no Record gain */
+#define AC97_HAS_NO_PHONE	(1<<11) /* no PHONE volume */
+#define AC97_HAS_NO_PC_BEEP	(1<<12) /* no PC Beep volume */
+#define AC97_HAS_NO_VIDEO	(1<<13) /* no Video volume */
+#define AC97_HAS_NO_CD		(1<<14) /* no CD volume */
+#define AC97_HAS_NO_MIC	(1<<15) /* no MIC volume */
+#define AC97_HAS_NO_TONE	(1<<16) /* no Tone volume */
+#define AC97_HAS_NO_STD_PCM	(1<<17)	/* no standard AC97 PCM volume and mute */
+#define AC97_HAS_NO_AUX		(1<<18) /* no standard AC97 AUX volume and mute */
+#define AC97_HAS_8CH		(1<<19) /* supports 8-channel output */
+
+/* rates indexes */
+#define AC97_RATES_FRONT_DAC	0
+#define AC97_RATES_SURR_DAC	1
+#define AC97_RATES_LFE_DAC	2
+#define AC97_RATES_ADC		3
+#define AC97_RATES_MIC_ADC	4
+#define AC97_RATES_SPDIF	5
+
+/*
+ *
+ */
+
+struct snd_ac97;
+
+struct snd_ac97_build_ops {
+	int (*build_3d) (struct snd_ac97 *ac97);
+	int (*build_specific) (struct snd_ac97 *ac97);
+	int (*build_spdif) (struct snd_ac97 *ac97);
+	int (*build_post_spdif) (struct snd_ac97 *ac97);
+#ifdef CONFIG_PM
+	void (*suspend) (struct snd_ac97 *ac97);
+	void (*resume) (struct snd_ac97 *ac97);
+#endif
+	void (*update_jacks) (struct snd_ac97 *ac97);	/* for jack-sharing */
+};
+
+struct snd_ac97_bus_ops {
+	void (*reset) (struct snd_ac97 *ac97);
+	void (*warm_reset)(struct snd_ac97 *ac97);
+	void (*write) (struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
+	unsigned short (*read) (struct snd_ac97 *ac97, unsigned short reg);
+	void (*wait) (struct snd_ac97 *ac97);
+	void (*init) (struct snd_ac97 *ac97);
+};
+
+struct snd_ac97_bus {
+	/* -- lowlevel (hardware) driver specific -- */
+	struct snd_ac97_bus_ops *ops;
+	void *private_data;
+	void (*private_free) (struct snd_ac97_bus *bus);
+	/* --- */
+	struct snd_card *card;
+	unsigned short num;	/* bus number */
+	unsigned short no_vra: 1, /* bridge doesn't support VRA */
+		       dra: 1,	/* bridge supports double rate */
+		       isdin: 1;/* independent SDIN */
+	unsigned int clock;	/* AC'97 base clock (usually 48000Hz) */
+	spinlock_t bus_lock;	/* used mainly for slot allocation */
+	unsigned short used_slots[2][4]; /* actually used PCM slots */
+	unsigned short pcms_count; /* count of PCMs */
+	struct ac97_pcm *pcms;
+	struct snd_ac97 *codec[4];
+	struct snd_info_entry *proc;
+};
+
+/* static resolution table */
+struct snd_ac97_res_table {
+	unsigned short reg;	/* register */
+	unsigned short bits;	/* resolution bitmask */
+};
+
+struct snd_ac97_template {
+	void *private_data;
+	void (*private_free) (struct snd_ac97 *ac97);
+	struct pci_dev *pci;	/* assigned PCI device - used for quirks */
+	unsigned short num;	/* number of codec: 0 = primary, 1 = secondary */
+	unsigned short addr;	/* physical address of codec [0-3] */
+	unsigned int scaps;	/* driver capabilities */
+	const struct snd_ac97_res_table *res_table;	/* static resolution */
+};
+
+struct snd_ac97 {
+	/* -- lowlevel (hardware) driver specific -- */
+	struct snd_ac97_build_ops * build_ops;
+	void *private_data;
+	void (*private_free) (struct snd_ac97 *ac97);
+	/* --- */
+	struct snd_ac97_bus *bus;
+	struct pci_dev *pci;	/* assigned PCI device - used for quirks */
+	struct snd_info_entry *proc;
+	struct snd_info_entry *proc_regs;
+	unsigned short subsystem_vendor;
+	unsigned short subsystem_device;
+	struct mutex reg_mutex;
+	struct mutex page_mutex;	/* mutex for AD18xx multi-codecs and paging (2.3) */
+	unsigned short num;	/* number of codec: 0 = primary, 1 = secondary */
+	unsigned short addr;	/* physical address of codec [0-3] */
+	unsigned int id;	/* identification of codec */
+	unsigned short caps;	/* capabilities (register 0) */
+	unsigned short ext_id;	/* extended feature identification (register 28) */
+	unsigned short ext_mid;	/* extended modem ID (register 3C) */
+	const struct snd_ac97_res_table *res_table;	/* static resolution */
+	unsigned int scaps;	/* driver capabilities */
+	unsigned int flags;	/* specific code */
+	unsigned int rates[6];	/* see AC97_RATES_* defines */
+	unsigned int spdif_status;
+	unsigned short regs[0x80]; /* register cache */
+	DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
+	union {			/* vendor specific code */
+		struct {
+			unsigned short unchained[3];	// 0 = C34, 1 = C79, 2 = C69
+			unsigned short chained[3];	// 0 = C34, 1 = C79, 2 = C69
+			unsigned short id[3];		// codec IDs (lower 16-bit word)
+			unsigned short pcmreg[3];	// PCM registers
+			unsigned short codec_cfg[3];	// CODEC_CFG bits
+			unsigned char swap_mic_linein;	// AD1986/AD1986A only
+			unsigned char lo_as_master;	/* LO as master */
+		} ad18xx;
+		unsigned int dev_flags;		/* device specific */
+	} spec;
+	/* jack-sharing info */
+	unsigned char indep_surround;
+	unsigned char channel_mode;
+
+#ifdef CONFIG_SND_AC97_POWER_SAVE
+	unsigned int power_up;	/* power states */
+	struct delayed_work power_work;
+#endif
+	struct device dev;
+};
+
+#define to_ac97_t(d) container_of(d, struct snd_ac97, dev)
+
+/* conditions */
+static inline int ac97_is_audio(struct snd_ac97 * ac97)
+{
+	return (ac97->scaps & AC97_SCAP_AUDIO);
+}
+static inline int ac97_is_modem(struct snd_ac97 * ac97)
+{
+	return (ac97->scaps & AC97_SCAP_MODEM);
+}
+static inline int ac97_is_rev22(struct snd_ac97 * ac97)
+{
+	return (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_22;
+}
+static inline int ac97_can_amap(struct snd_ac97 * ac97)
+{
+	return (ac97->ext_id & AC97_EI_AMAP) != 0;
+}
+static inline int ac97_can_spdif(struct snd_ac97 * ac97)
+{
+	return (ac97->ext_id & AC97_EI_SPDIF) != 0;
+}
+
+/* functions */
+/* create new AC97 bus */
+int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
+		 void *private_data, struct snd_ac97_bus **rbus);
+/* create mixer controls */
+int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
+		   struct snd_ac97 **rac97);
+const char *snd_ac97_get_short_name(struct snd_ac97 *ac97);
+
+void snd_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short value);
+unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
+void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned short value);
+int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value);
+int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value);
+#ifdef CONFIG_SND_AC97_POWER_SAVE
+int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup);
+#else
+static inline int snd_ac97_update_power(struct snd_ac97 *ac97, int reg,
+					int powerup)
+{
+	return 0;
+}
+#endif
+#ifdef CONFIG_PM
+void snd_ac97_suspend(struct snd_ac97 *ac97);
+void snd_ac97_resume(struct snd_ac97 *ac97);
+#endif
+
+/* quirk types */
+enum {
+	AC97_TUNE_DEFAULT = -1,	/* use default from quirk list (not valid in list) */
+	AC97_TUNE_NONE = 0,	/* nothing extra to do */
+	AC97_TUNE_HP_ONLY,	/* headphone (true line-out) control as master only */
+	AC97_TUNE_SWAP_HP,	/* swap headphone and master controls */
+	AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */
+	AC97_TUNE_AD_SHARING,	/* for AD1985, turn on OMS bit and use headphone */
+	AC97_TUNE_ALC_JACK,	/* for Realtek, enable JACK detection */
+	AC97_TUNE_INV_EAPD,	/* inverted EAPD implementation */
+	AC97_TUNE_MUTE_LED,	/* EAPD bit works as mute LED */
+	AC97_TUNE_HP_MUTE_LED,  /* EAPD bit works as mute LED, use headphone control as master */
+};
+
+struct ac97_quirk {
+	unsigned short subvendor; /* PCI subsystem vendor id */
+	unsigned short subdevice; /* PCI sybsystem device id */
+	unsigned short mask;	/* device id bit mask, 0 = accept all */
+	unsigned int codec_id;	/* codec id (if any), 0 = accept all */
+	const char *name;	/* name shown as info */
+	int type;		/* quirk type above */
+};
+
+int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override);
+int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate);
+
+/*
+ * PCM allocation
+ */
+
+enum ac97_pcm_cfg {
+	AC97_PCM_CFG_FRONT = 2,
+	AC97_PCM_CFG_REAR = 10,		/* alias surround */
+	AC97_PCM_CFG_LFE = 11,		/* center + lfe */
+	AC97_PCM_CFG_40 = 4,		/* front + rear */
+	AC97_PCM_CFG_51 = 6,		/* front + rear + center/lfe */
+	AC97_PCM_CFG_SPDIF = 20
+};
+
+struct ac97_pcm {
+	struct snd_ac97_bus *bus;
+	unsigned int stream: 1,	   	   /* stream type: 1 = capture */
+		     exclusive: 1,	   /* exclusive mode, don't override with other pcms */
+		     copy_flag: 1,	   /* lowlevel driver must fill all entries */
+		     spdif: 1;		   /* spdif pcm */
+	unsigned short aslots;		   /* active slots */
+	unsigned short cur_dbl;		   /* current double-rate state */
+	unsigned int rates;		   /* available rates */
+	struct {
+		unsigned short slots;	   /* driver input: requested AC97 slot numbers */
+		unsigned short rslots[4];  /* allocated slots per codecs */
+		unsigned char rate_table[4];
+		struct snd_ac97 *codec[4];	   /* allocated codecs */
+	} r[2];				   /* 0 = standard rates, 1 = double rates */
+	unsigned long private_value;	   /* used by the hardware driver */
+};
+
+int snd_ac97_pcm_assign(struct snd_ac97_bus *ac97,
+			unsigned short pcms_count,
+			const struct ac97_pcm *pcms);
+int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
+		      enum ac97_pcm_cfg cfg, unsigned short slots);
+int snd_ac97_pcm_close(struct ac97_pcm *pcm);
+int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
+
+/* ad hoc AC97 device driver access */
+extern struct bus_type ac97_bus_type;
+
+#endif /* __SOUND_AC97_CODEC_H */
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
new file mode 100644
index 0000000..b3aa62e
--- /dev/null
+++ b/include/sound/ad1816a.h
@@ -0,0 +1,173 @@
+#ifndef __SOUND_AD1816A_H
+#define __SOUND_AD1816A_H
+
+/*
+    ad1816a.h - definitions for ADI SoundPort AD1816A chip.
+    Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include "control.h"
+#include "pcm.h"
+#include "timer.h"
+
+#define AD1816A_REG(r)			(chip->port + r)
+
+#define AD1816A_CHIP_STATUS		0x00
+#define AD1816A_INDIR_ADDR		0x00
+#define AD1816A_INTERRUPT_STATUS	0x01
+#define AD1816A_INDIR_DATA_LOW		0x02
+#define AD1816A_INDIR_DATA_HIGH		0x03
+#define AD1816A_PIO_DEBUG		0x04
+#define AD1816A_PIO_STATUS		0x05
+#define AD1816A_PIO_DATA		0x06
+#define AD1816A_RESERVED_7		0x07
+#define AD1816A_PLAYBACK_CONFIG		0x08
+#define AD1816A_CAPTURE_CONFIG		0x09
+#define AD1816A_RESERVED_10		0x0a
+#define AD1816A_RESERVED_11		0x0b
+#define AD1816A_JOYSTICK_RAW_DATA	0x0c
+#define AD1816A_JOYSTICK_CTRL		0x0d
+#define AD1816A_JOY_POS_DATA_LOW	0x0e
+#define AD1816A_JOY_POS_DATA_HIGH	0x0f
+
+#define AD1816A_LOW_BYTE_TMP		0x00
+#define AD1816A_INTERRUPT_ENABLE	0x01
+#define AD1816A_EXTERNAL_CTRL		0x01
+#define AD1816A_PLAYBACK_SAMPLE_RATE	0x02
+#define AD1816A_CAPTURE_SAMPLE_RATE	0x03
+#define AD1816A_VOICE_ATT		0x04
+#define AD1816A_FM_ATT			0x05
+#define AD1816A_I2S_1_ATT		0x06
+#define AD1816A_I2S_0_ATT		0x07
+#define AD1816A_PLAYBACK_BASE_COUNT	0x08
+#define AD1816A_PLAYBACK_CURR_COUNT	0x09
+#define AD1816A_CAPTURE_BASE_COUNT	0x0a
+#define AD1816A_CAPTURE_CURR_COUNT	0x0b
+#define AD1816A_TIMER_BASE_COUNT	0x0c
+#define AD1816A_TIMER_CURR_COUNT	0x0d
+#define AD1816A_MASTER_ATT		0x0e
+#define AD1816A_CD_GAIN_ATT		0x0f
+#define AD1816A_SYNTH_GAIN_ATT		0x10
+#define AD1816A_VID_GAIN_ATT		0x11
+#define AD1816A_LINE_GAIN_ATT		0x12
+#define AD1816A_MIC_GAIN_ATT		0x13
+#define AD1816A_PHONE_IN_GAIN_ATT	0x13
+#define AD1816A_ADC_SOURCE_SEL		0x14
+#define AD1816A_ADC_PGA			0x14
+#define AD1816A_CHIP_CONFIG		0x20
+#define AD1816A_DSP_CONFIG		0x21
+#define AD1816A_FM_SAMPLE_RATE		0x22
+#define AD1816A_I2S_1_SAMPLE_RATE	0x23
+#define AD1816A_I2S_0_SAMPLE_RATE	0x24
+#define AD1816A_RESERVED_37		0x25
+#define AD1816A_PROGRAM_CLOCK_RATE	0x26
+#define AD1816A_3D_PHAT_CTRL		0x27
+#define AD1816A_PHONE_OUT_ATT		0x27
+#define AD1816A_RESERVED_40		0x28
+#define AD1816A_HW_VOL_BUT		0x29
+#define AD1816A_DSP_MAILBOX_0		0x2a
+#define AD1816A_DSP_MAILBOX_1		0x2b
+#define AD1816A_POWERDOWN_CTRL		0x2c
+#define AD1816A_TIMER_CTRL		0x2c
+#define AD1816A_VERSION_ID		0x2d
+#define AD1816A_RESERVED_46		0x2e
+
+#define AD1816A_READY			0x80
+
+#define AD1816A_PLAYBACK_IRQ_PENDING	0x80
+#define AD1816A_CAPTURE_IRQ_PENDING	0x40
+#define AD1816A_TIMER_IRQ_PENDING	0x20
+
+#define AD1816A_PLAYBACK_ENABLE		0x01
+#define AD1816A_PLAYBACK_PIO		0x02
+#define AD1816A_CAPTURE_ENABLE		0x01
+#define AD1816A_CAPTURE_PIO		0x02
+
+#define AD1816A_FMT_LINEAR_8		0x00
+#define AD1816A_FMT_ULAW_8		0x08
+#define AD1816A_FMT_LINEAR_16_LIT	0x10
+#define AD1816A_FMT_ALAW_8		0x18
+#define AD1816A_FMT_LINEAR_16_BIG	0x30
+#define AD1816A_FMT_ALL			0x38
+#define AD1816A_FMT_STEREO		0x04
+
+#define AD1816A_PLAYBACK_IRQ_ENABLE	0x8000
+#define AD1816A_CAPTURE_IRQ_ENABLE	0x4000
+#define AD1816A_TIMER_IRQ_ENABLE	0x2000
+#define AD1816A_TIMER_ENABLE		0x0080
+
+#define AD1816A_SRC_LINE		0x00
+#define AD1816A_SRC_OUT			0x10
+#define AD1816A_SRC_CD			0x20
+#define AD1816A_SRC_SYNTH		0x30
+#define AD1816A_SRC_VIDEO		0x40
+#define AD1816A_SRC_MIC			0x50
+#define AD1816A_SRC_MONO		0x50
+#define AD1816A_SRC_PHONE_IN		0x60
+#define AD1816A_SRC_MASK		0x70
+
+#define AD1816A_CAPTURE_NOT_EQUAL	0x1000
+#define AD1816A_WSS_ENABLE		0x8000
+
+struct snd_ad1816a {
+	unsigned long port;
+	struct resource *res_port;
+	int irq;
+	int dma1;
+	int dma2;
+
+	unsigned short hardware;
+	unsigned short version;
+
+	spinlock_t lock;
+
+	unsigned short mode;
+	unsigned int clock_freq;
+
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	unsigned int p_dma_size;
+	unsigned int c_dma_size;
+
+	struct snd_timer *timer;
+};
+
+
+#define AD1816A_HW_AUTO		0
+#define AD1816A_HW_AD1816A	1
+#define AD1816A_HW_AD1815	2
+#define AD1816A_HW_AD18MAX10	3
+
+#define AD1816A_MODE_PLAYBACK	0x01
+#define AD1816A_MODE_CAPTURE	0x02
+#define AD1816A_MODE_TIMER	0x04
+#define AD1816A_MODE_OPEN	(AD1816A_MODE_PLAYBACK |	\
+				AD1816A_MODE_CAPTURE |		\
+				AD1816A_MODE_TIMER)
+
+
+extern int snd_ad1816a_create(struct snd_card *card, unsigned long port,
+			      int irq, int dma1, int dma2,
+			      struct snd_ad1816a **chip);
+
+extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm);
+extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
+
+#endif	/* __SOUND_AD1816A_H */
diff --git a/include/sound/ad1843.h b/include/sound/ad1843.h
new file mode 100644
index 0000000..b236a9d
--- /dev/null
+++ b/include/sound/ad1843.h
@@ -0,0 +1,46 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
+ * Copyright 2008 Thomas Bogendoerfer <tsbogend@franken.de>
+ */
+
+#ifndef __SOUND_AD1843_H
+#define __SOUND_AD1843_H
+
+struct snd_ad1843 {
+	void *chip;
+	int (*read)(void *chip, int reg);
+	int (*write)(void *chip, int reg, int val);
+};
+
+#define AD1843_GAIN_RECLEV 0
+#define AD1843_GAIN_LINE   1
+#define AD1843_GAIN_LINE_2 2
+#define AD1843_GAIN_MIC    3
+#define AD1843_GAIN_PCM_0  4
+#define AD1843_GAIN_PCM_1  5
+#define AD1843_GAIN_SIZE   (AD1843_GAIN_PCM_1+1)
+
+int ad1843_get_gain_max(struct snd_ad1843 *ad1843, int id);
+int ad1843_get_gain(struct snd_ad1843 *ad1843, int id);
+int ad1843_set_gain(struct snd_ad1843 *ad1843, int id, int newval);
+int ad1843_get_recsrc(struct snd_ad1843 *ad1843);
+int ad1843_set_recsrc(struct snd_ad1843 *ad1843, int newsrc);
+void ad1843_setup_dac(struct snd_ad1843 *ad1843,
+		      unsigned int id,
+		      unsigned int framerate,
+		      snd_pcm_format_t fmt,
+		      unsigned int channels);
+void ad1843_shutdown_dac(struct snd_ad1843 *ad1843,
+			 unsigned int id);
+void ad1843_setup_adc(struct snd_ad1843 *ad1843,
+		      unsigned int framerate,
+		      snd_pcm_format_t fmt,
+		      unsigned int channels);
+void ad1843_shutdown_adc(struct snd_ad1843 *ad1843);
+int ad1843_init(struct snd_ad1843 *ad1843);
+
+#endif /* __SOUND_AD1843_H */
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
new file mode 100644
index 0000000..d293d36
--- /dev/null
+++ b/include/sound/ak4114.h
@@ -0,0 +1,203 @@
+#ifndef __SOUND_AK4114_H
+#define __SOUND_AK4114_H
+
+/*
+ *  Routines for Asahi Kasei AK4114
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/* AK4114 registers */
+#define AK4114_REG_PWRDN	0x00	/* power down */
+#define AK4114_REG_FORMAT	0x01	/* format control */
+#define AK4114_REG_IO0		0x02	/* input/output control */
+#define AK4114_REG_IO1		0x03	/* input/output control */
+#define AK4114_REG_INT0_MASK	0x04	/* interrupt0 mask */
+#define AK4114_REG_INT1_MASK	0x05	/* interrupt1 mask */
+#define AK4114_REG_RCS0		0x06	/* receiver status 0 */
+#define AK4114_REG_RCS1		0x07	/* receiver status 1 */
+#define AK4114_REG_RXCSB0	0x08	/* RX channel status byte 0 */
+#define AK4114_REG_RXCSB1	0x09	/* RX channel status byte 1 */
+#define AK4114_REG_RXCSB2	0x0a	/* RX channel status byte 2 */
+#define AK4114_REG_RXCSB3	0x0b	/* RX channel status byte 3 */
+#define AK4114_REG_RXCSB4	0x0c	/* RX channel status byte 4 */
+#define AK4114_REG_TXCSB0	0x0d	/* TX channel status byte 0 */
+#define AK4114_REG_TXCSB1	0x0e	/* TX channel status byte 1 */
+#define AK4114_REG_TXCSB2	0x0f	/* TX channel status byte 2 */
+#define AK4114_REG_TXCSB3	0x10	/* TX channel status byte 3 */
+#define AK4114_REG_TXCSB4	0x11	/* TX channel status byte 4 */
+#define AK4114_REG_Pc0		0x12	/* burst preamble Pc byte 0 */
+#define AK4114_REG_Pc1		0x13	/* burst preamble Pc byte 1 */
+#define AK4114_REG_Pd0		0x14	/* burst preamble Pd byte 0 */
+#define AK4114_REG_Pd1		0x15	/* burst preamble Pd byte 1 */
+#define AK4114_REG_QSUB_ADDR	0x16	/* Q-subcode address + control */
+#define AK4114_REG_QSUB_TRACK	0x17	/* Q-subcode track */
+#define AK4114_REG_QSUB_INDEX	0x18	/* Q-subcode index */
+#define AK4114_REG_QSUB_MINUTE	0x19	/* Q-subcode minute */
+#define AK4114_REG_QSUB_SECOND	0x1a	/* Q-subcode second */
+#define AK4114_REG_QSUB_FRAME	0x1b	/* Q-subcode frame */
+#define AK4114_REG_QSUB_ZERO	0x1c	/* Q-subcode zero */
+#define AK4114_REG_QSUB_ABSMIN	0x1d	/* Q-subcode absolute minute */
+#define AK4114_REG_QSUB_ABSSEC	0x1e	/* Q-subcode absolute second */
+#define AK4114_REG_QSUB_ABSFRM	0x1f	/* Q-subcode absolute frame */
+
+/* sizes */
+#define AK4114_REG_RXCSB_SIZE	((AK4114_REG_RXCSB4-AK4114_REG_RXCSB0)+1)
+#define AK4114_REG_TXCSB_SIZE	((AK4114_REG_TXCSB4-AK4114_REG_TXCSB0)+1)
+#define AK4114_REG_QSUB_SIZE	((AK4114_REG_QSUB_ABSFRM-AK4114_REG_QSUB_ADDR)+1)
+
+/* AK4117_REG_PWRDN bits */
+#define AK4114_CS12		(1<<7)	/* Channel Status Select */
+#define AK4114_BCU		(1<<6)	/* Block Start & C/U Output Mode */
+#define AK4114_CM1		(1<<5)	/* Master Clock Operation Select */
+#define AK4114_CM0		(1<<4)	/* Master Clock Operation Select */
+#define AK4114_OCKS1		(1<<3)	/* Master Clock Frequency Select */
+#define AK4114_OCKS0		(1<<2)	/* Master Clock Frequency Select */
+#define AK4114_PWN		(1<<1)	/* 0 = power down, 1 = normal operation */
+#define AK4114_RST		(1<<0)	/* 0 = reset & initialize (except this register), 1 = normal operation */
+
+/* AK4114_REQ_FORMAT bits */
+#define AK4114_MONO		(1<<7)	/* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */
+#define AK4114_DIF2		(1<<6)	/* Audio Data Control */
+#define AK4114_DIF1		(1<<5)	/* Audio Data Control */
+#define AK4114_DIF0		(1<<4)	/* Audio Data Control */
+#define AK4114_DIF_16R		(0)				/* STDO: 16-bit, right justified */
+#define AK4114_DIF_18R		(AK4114_DIF0)			/* STDO: 18-bit, right justified */
+#define AK4114_DIF_20R		(AK4114_DIF1)			/* STDO: 20-bit, right justified */
+#define AK4114_DIF_24R		(AK4114_DIF1|AK4114_DIF0)	/* STDO: 24-bit, right justified */
+#define AK4114_DIF_24L		(AK4114_DIF2)			/* STDO: 24-bit, left justified */
+#define AK4114_DIF_24I2S	(AK4114_DIF2|AK4114_DIF0)	/* STDO: I2S */
+#define AK4114_DIF_I24L		(AK4114_DIF2|AK4114_DIF1)	/* STDO: 24-bit, left justified; LRCLK, BICK = Input */
+#define AK4114_DIF_I24I2S	(AK4114_DIF2|AK4114_DIF1|AK4114_DIF0) /* STDO: I2S;  LRCLK, BICK = Input */
+#define AK4114_DEAU		(1<<3)	/* Deemphasis Autodetect Enable (1 = enable) */
+#define AK4114_DEM1		(1<<2)	/* 32kHz-48kHz Deemphasis Control */
+#define AK4114_DEM0		(1<<1)	/* 32kHz-48kHz Deemphasis Control */
+#define AK4114_DEM_44KHZ	(0)
+#define AK4114_DEM_48KHZ	(AK4114_DEM1)
+#define AK4114_DEM_32KHZ	(AK4114_DEM0|AK4114_DEM1)
+#define AK4114_DEM_96KHZ	(AK4114_DEM1)	/* DFS must be set */
+#define AK4114_DFS		(1<<0)	/* 96kHz Deemphasis Control */
+
+/* AK4114_REG_IO0 */
+#define AK4114_TX1E		(1<<7)	/* TX1 Output Enable (1 = enable) */
+#define AK4114_OPS12		(1<<2)	/* Output Though Data Selector for TX1 pin */
+#define AK4114_OPS11		(1<<1)	/* Output Though Data Selector for TX1 pin */
+#define AK4114_OPS10		(1<<0)	/* Output Though Data Selector for TX1 pin */
+#define AK4114_TX0E		(1<<3)	/* TX0 Output Enable (1 = enable) */
+#define AK4114_OPS02		(1<<2)	/* Output Though Data Selector for TX0 pin */
+#define AK4114_OPS01		(1<<1)	/* Output Though Data Selector for TX0 pin */
+#define AK4114_OPS00		(1<<0)	/* Output Though Data Selector for TX0 pin */
+
+/* AK4114_REG_IO1 */
+#define AK4114_EFH1		(1<<7)	/* Interrupt 0 pin Hold */
+#define AK4114_EFH0		(1<<6)	/* Interrupt 0 pin Hold */
+#define AK4114_EFH_512		(0)
+#define AK4114_EFH_1024		(AK4114_EFH0)
+#define AK4114_EFH_2048		(AK4114_EFH1)
+#define AK4114_EFH_4096		(AK4114_EFH1|AK4114_EFH0)
+#define AK4114_UDIT		(1<<5)	/* U-bit Control for DIT (0 = fixed '0', 1 = recovered) */
+#define AK4114_TLR		(1<<4)	/* Double Sampling Frequency Select for DIT (0 = L channel, 1 = R channel) */
+#define AK4114_DIT		(1<<3)	/* TX1 out: 0 = Through Data (RX data), 1 = Transmit Data (DAUX data) */
+#define AK4114_IPS2		(1<<2)	/* Input Recovery Data Select */
+#define AK4114_IPS1		(1<<1)	/* Input Recovery Data Select */
+#define AK4114_IPS0		(1<<0)	/* Input Recovery Data Select */
+#define AK4114_IPS(x)		((x)&7)
+
+/* AK4114_REG_INT0_MASK && AK4114_REG_INT1_MASK*/
+#define AK4117_MQI              (1<<7)  /* mask enable for QINT bit */
+#define AK4117_MAT              (1<<6)  /* mask enable for AUTO bit */
+#define AK4117_MCI              (1<<5)  /* mask enable for CINT bit */
+#define AK4117_MUL              (1<<4)  /* mask enable for UNLOCK bit */
+#define AK4117_MDTS             (1<<3)  /* mask enable for DTSCD bit */
+#define AK4117_MPE              (1<<2)  /* mask enable for PEM bit */
+#define AK4117_MAN              (1<<1)  /* mask enable for AUDN bit */
+#define AK4117_MPR              (1<<0)  /* mask enable for PAR bit */
+
+/* AK4114_REG_RCS0 */
+#define AK4114_QINT		(1<<7)	/* Q-subcode buffer interrupt, 0 = no change, 1 = changed */
+#define AK4114_AUTO		(1<<6)	/* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */
+#define AK4114_CINT		(1<<5)	/* channel status buffer interrupt, 0 = no change, 1 = change */
+#define AK4114_UNLCK		(1<<4)	/* PLL lock status, 0 = lock, 1 = unlock */
+#define AK4114_DTSCD		(1<<3)	/* DTS-CD Detect, 0 = No detect, 1 = Detect */
+#define AK4114_PEM		(1<<2)	/* Pre-emphasis Detect, 0 = OFF, 1 = ON */
+#define AK4114_AUDION		(1<<1)	/* audio bit output, 0 = audio, 1 = non-audio */
+#define AK4114_PAR		(1<<0)	/* parity error or biphase error status, 0 = no error, 1 = error */
+
+/* AK4114_REG_RCS1 */
+#define AK4114_FS3		(1<<7)	/* sampling frequency detection */
+#define AK4114_FS2		(1<<6)
+#define AK4114_FS1		(1<<5)
+#define AK4114_FS0		(1<<4)
+#define AK4114_FS_44100HZ	(0)
+#define AK4114_FS_48000HZ	(AK4114_FS1)
+#define AK4114_FS_32000HZ	(AK4114_FS1|AK4114_FS0)
+#define AK4114_FS_88200HZ	(AK4114_FS3)
+#define AK4114_FS_96000HZ	(AK4114_FS3|AK4114_FS1)
+#define AK4114_FS_176400HZ	(AK4114_FS3|AK4114_FS2)
+#define AK4114_FS_192000HZ	(AK4114_FS3|AK4114_FS2|AK4114_FS1)
+#define AK4114_V		(1<<3)	/* Validity of Channel Status, 0 = Valid, 1 = Invalid */
+#define AK4114_QCRC		(1<<1)	/* CRC for Q-subcode, 0 = no error, 1 = error */
+#define AK4114_CCRC		(1<<0)	/* CRC for channel status, 0 = no error, 1 = error */
+
+/* flags for snd_ak4114_check_rate_and_errors() */
+#define AK4114_CHECK_NO_STAT	(1<<0)	/* no statistics */
+#define AK4114_CHECK_NO_RATE	(1<<1)	/* no rate check */
+
+#define AK4114_CONTROLS		15
+
+typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data);
+typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr);
+
+struct ak4114 {
+	struct snd_card *card;
+	ak4114_write_t * write;
+	ak4114_read_t * read;
+	void * private_data;
+	unsigned int init: 1;
+	spinlock_t lock;
+	unsigned char regmap[7];
+	unsigned char txcsb[5];
+	struct snd_kcontrol *kctls[AK4114_CONTROLS];
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	unsigned long parity_errors;
+	unsigned long v_bit_errors;
+	unsigned long qcrc_errors;
+	unsigned long ccrc_errors;
+	unsigned char rcs0;
+	unsigned char rcs1;
+	struct delayed_work work;
+	unsigned int check_flags;
+	void *change_callback_private;
+	void (*change_callback)(struct ak4114 *ak4114, unsigned char c0, unsigned char c1);
+};
+
+int snd_ak4114_create(struct snd_card *card,
+		      ak4114_read_t *read, ak4114_write_t *write,
+		      const unsigned char pgm[7], const unsigned char txcsb[5],
+		      void *private_data, struct ak4114 **r_ak4114);
+void snd_ak4114_reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char mask, unsigned char val);
+void snd_ak4114_reinit(struct ak4114 *ak4114);
+int snd_ak4114_build(struct ak4114 *ak4114,
+		     struct snd_pcm_substream *playback_substream,
+                     struct snd_pcm_substream *capture_substream);
+int snd_ak4114_external_rate(struct ak4114 *ak4114);
+int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags);
+
+#endif /* __SOUND_AK4114_H */
+
diff --git a/include/sound/ak4117.h b/include/sound/ak4117.h
new file mode 100644
index 0000000..1e81781
--- /dev/null
+++ b/include/sound/ak4117.h
@@ -0,0 +1,189 @@
+#ifndef __SOUND_AK4117_H
+#define __SOUND_AK4117_H
+
+/*
+ *  Routines for Asahi Kasei AK4117
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define AK4117_REG_PWRDN	0x00	/* power down */
+#define AK4117_REG_CLOCK	0x01	/* clock control */
+#define AK4117_REG_IO		0x02	/* input/output control */
+#define AK4117_REG_INT0_MASK	0x03	/* interrupt0 mask */
+#define AK4117_REG_INT1_MASK	0x04	/* interrupt1 mask */
+#define AK4117_REG_RCS0		0x05	/* receiver status 0 */
+#define AK4117_REG_RCS1		0x06	/* receiver status 1 */
+#define AK4117_REG_RCS2		0x07	/* receiver status 2 */
+#define AK4117_REG_RXCSB0	0x08	/* RX channel status byte 0 */
+#define AK4117_REG_RXCSB1	0x09	/* RX channel status byte 1 */
+#define AK4117_REG_RXCSB2	0x0a	/* RX channel status byte 2 */
+#define AK4117_REG_RXCSB3	0x0b	/* RX channel status byte 3 */
+#define AK4117_REG_RXCSB4	0x0c	/* RX channel status byte 4 */
+#define AK4117_REG_Pc0		0x0d	/* burst preamble Pc byte 0 */
+#define AK4117_REG_Pc1		0x0e	/* burst preamble Pc byte 1 */
+#define AK4117_REG_Pd0		0x0f	/* burst preamble Pd byte 0 */
+#define AK4117_REG_Pd1		0x10	/* burst preamble Pd byte 1 */
+#define AK4117_REG_QSUB_ADDR	0x11	/* Q-subcode address + control */
+#define AK4117_REG_QSUB_TRACK	0x12	/* Q-subcode track */
+#define AK4117_REG_QSUB_INDEX	0x13	/* Q-subcode index */
+#define AK4117_REG_QSUB_MINUTE	0x14	/* Q-subcode minute */
+#define AK4117_REG_QSUB_SECOND	0x15	/* Q-subcode second */
+#define AK4117_REG_QSUB_FRAME	0x16	/* Q-subcode frame */
+#define AK4117_REG_QSUB_ZERO	0x17	/* Q-subcode zero */
+#define AK4117_REG_QSUB_ABSMIN	0x18	/* Q-subcode absolute minute */
+#define AK4117_REG_QSUB_ABSSEC	0x19	/* Q-subcode absolute second */
+#define AK4117_REG_QSUB_ABSFRM	0x1a	/* Q-subcode absolute frame */
+
+/* sizes */
+#define AK4117_REG_RXCSB_SIZE	((AK4117_REG_RXCSB4-AK4117_REG_RXCSB0)+1)
+#define AK4117_REG_QSUB_SIZE	((AK4117_REG_QSUB_ABSFRM-AK4117_REG_QSUB_ADDR)+1)
+
+/* AK4117_REG_PWRDN bits */
+#define AK4117_EXCT		(1<<4)	/* 0 = X'tal mode, 1 = external clock mode */
+#define AK4117_XTL1		(1<<3)	/* XTL1=0,XTL0=0 -> 11.2896Mhz; XTL1=0,XTL0=1 -> 12.288Mhz */
+#define AK4117_XTL0		(1<<2)	/* XTL1=1,XTL0=0 -> 24.576Mhz; XTL1=1,XTL0=1 -> use channel status */
+#define AK4117_XTL_11_2896M	(0)
+#define AK4117_XTL_12_288M	AK4117_XTL0
+#define AK4117_XTL_24_576M	AK4117_XTL1
+#define AK4117_XTL_EXT		(AK4117_XTL1|AK4117_XTL0)
+#define AK4117_PWN		(1<<1)	/* 0 = power down, 1 = normal operation */
+#define AK4117_RST		(1<<0)	/* 0 = reset & initialize (except this register), 1 = normal operation */
+
+/* AK4117_REQ_CLOCK bits */
+#define AK4117_LP		(1<<7)	/* 0 = normal mode, 1 = low power mode (Fs up to 48kHz only) */
+#define AK4117_PKCS1		(1<<6)	/* master clock frequency at PLL mode (when LP == 0) */
+#define AK4117_PKCS0		(1<<5)
+#define AK4117_PKCS_512fs	(0)
+#define AK4117_PKCS_256fs	AK4117_PKCS0
+#define AK4117_PKCS_128fs	AK4117_PKCS1
+#define AK4117_DIV		(1<<4)	/* 0 = MCKO == Fs, 1 = MCKO == Fs / 2; X'tal mode only */
+#define AK4117_XCKS1		(1<<3)	/* master clock frequency at X'tal mode */
+#define AK4117_XCKS0		(1<<2)
+#define AK4117_XCKS_128fs	(0)
+#define AK4117_XCKS_256fs	AK4117_XCKS0
+#define AK4117_XCKS_512fs	AK4117_XCKS1
+#define AK4117_XCKS_1024fs	(AK4117_XCKS1|AK4117_XCKS0)
+#define AK4117_CM1		(1<<1)	/* MCKO operation mode select */
+#define AK4117_CM0		(1<<0)
+#define AK4117_CM_PLL		(0)		/* use RX input as master clock */
+#define AK4117_CM_XTAL		(AK4117_CM0)	/* use X'tal as master clock */
+#define AK4117_CM_PLL_XTAL	(AK4117_CM1)	/* use Rx input but X'tal when PLL loses lock */
+#define AK4117_CM_MONITOR	(AK4117_CM0|AK4117_CM1) /* use X'tal as master clock, but use PLL for monitoring */
+
+/* AK4117_REG_IO */
+#define AK4117_IPS		(1<<7)	/* Input Recovery Data Select, 0 = RX0, 1 = RX1 */
+#define AK4117_UOUTE		(1<<6)	/* U-bit output enable to UOUT, 0 = disable, 1 = enable */
+#define AK4117_CS12		(1<<5)	/* channel status select, 0 = channel1, 1 = channel2 */
+#define AK4117_EFH2		(1<<4)	/* INT0 pin hold count select */
+#define AK4117_EFH1		(1<<3)
+#define AK4117_EFH_512LRCLK	(0)
+#define AK4117_EFH_1024LRCLK	(AK4117_EFH1)
+#define AK4117_EFH_2048LRCLK	(AK4117_EFH2)
+#define AK4117_EFH_4096LRCLK	(AK4117_EFH1|AK4117_EFH2)
+#define AK4117_DIF2		(1<<2)	/* audio data format control */
+#define AK4117_DIF1		(1<<1)
+#define AK4117_DIF0		(1<<0)
+#define AK4117_DIF_16R		(0)				/* STDO: 16-bit, right justified */
+#define AK4117_DIF_18R		(AK4117_DIF0)			/* STDO: 18-bit, right justified */
+#define AK4117_DIF_20R		(AK4117_DIF1)			/* STDO: 20-bit, right justified */
+#define AK4117_DIF_24R		(AK4117_DIF1|AK4117_DIF0)	/* STDO: 24-bit, right justified */
+#define AK4117_DIF_24L		(AK4117_DIF2)			/* STDO: 24-bit, left justified */
+#define AK4117_DIF_24I2S	(AK4117_DIF2|AK4117_DIF0)	/* STDO: I2S */
+
+/* AK4117_REG_INT0_MASK & AK4117_REG_INT1_MASK */
+#define AK4117_MULK		(1<<7)	/* mask enable for UNLOCK bit */
+#define AK4117_MPAR		(1<<6)	/* mask enable for PAR bit */
+#define AK4117_MAUTO		(1<<5)	/* mask enable for AUTO bit */
+#define AK4117_MV		(1<<4)	/* mask enable for V bit */
+#define AK4117_MAUD		(1<<3)	/* mask enable for AUDION bit */
+#define AK4117_MSTC		(1<<2)	/* mask enable for STC bit */
+#define AK4117_MCIT		(1<<1)	/* mask enable for CINT bit */
+#define AK4117_MQIT		(1<<0)	/* mask enable for QINT bit */
+
+/* AK4117_REG_RCS0 */
+#define AK4117_UNLCK		(1<<7)	/* PLL lock status, 0 = lock, 1 = unlock */
+#define AK4117_PAR		(1<<6)	/* parity error or biphase error status, 0 = no error, 1 = error */
+#define AK4117_AUTO		(1<<5)	/* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */
+#define AK4117_V		(1<<4)	/* Validity bit, 0 = valid, 1 = invalid */
+#define AK4117_AUDION		(1<<3)	/* audio bit output, 0 = audio, 1 = non-audio */
+#define AK4117_STC		(1<<2)	/* sampling frequency or Pre-emphasis change, 0 = no detect, 1 = detect */
+#define AK4117_CINT		(1<<1)	/* channel status buffer interrupt, 0 = no change, 1 = change */
+#define AK4117_QINT		(1<<0)	/* Q-subcode buffer interrupt, 0 = no change, 1 = changed */
+
+/* AK4117_REG_RCS1 */
+#define AK4117_DTSCD		(1<<6)	/* DTS-CD bit audio stream detect, 0 = no detect, 1 = detect */
+#define AK4117_NPCM		(1<<5)	/* Non-PCM bit stream detection, 0 = no detect, 1 = detect */
+#define AK4117_PEM		(1<<4)	/* Pre-emphasis detect, 0 = OFF, 1 = ON */
+#define AK4117_FS3		(1<<3)	/* sampling frequency detection */
+#define AK4117_FS2		(1<<2)
+#define AK4117_FS1		(1<<1)
+#define AK4117_FS0		(1<<0)
+#define AK4117_FS_44100HZ	(0)
+#define AK4117_FS_48000HZ	(AK4117_FS1)
+#define AK4117_FS_32000HZ	(AK4117_FS1|AK4117_FS0)
+#define AK4117_FS_88200HZ	(AK4117_FS3)
+#define AK4117_FS_96000HZ	(AK4117_FS3|AK4117_FS1)
+#define AK4117_FS_176400HZ	(AK4117_FS3|AK4117_FS2)
+#define AK4117_FS_192000HZ	(AK4117_FS3|AK4117_FS2|AK4117_FS1)
+
+/* AK4117_REG_RCS2 */
+#define AK4117_CCRC		(1<<1)	/* CRC for channel status, 0 = no error, 1 = error */
+#define AK4117_QCRC		(1<<0)	/* CRC for Q-subcode, 0 = no error, 1 = error */
+
+/* flags for snd_ak4117_check_rate_and_errors() */
+#define AK4117_CHECK_NO_STAT	(1<<0)	/* no statistics */
+#define AK4117_CHECK_NO_RATE	(1<<1)	/* no rate check */
+
+#define AK4117_CONTROLS		13
+
+typedef void (ak4117_write_t)(void *private_data, unsigned char addr, unsigned char data);
+typedef unsigned char (ak4117_read_t)(void *private_data, unsigned char addr);
+
+struct ak4117 {
+	struct snd_card *card;
+	ak4117_write_t * write;
+	ak4117_read_t * read;
+	void * private_data;
+	unsigned int init: 1;
+	spinlock_t lock;
+	unsigned char regmap[5];