File-copy from v4.4.100

This is the result of 'cp' from a linux-stable tree with the 'v4.4.100'
tag checked out (commit 26d6298789e695c9f627ce49a7bbd2286405798a) on
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Please refer to that tree for all history prior to this point.

Change-Id: I8a9ee2aea93cd29c52c847d0ce33091a73ae6afe
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
new file mode 100644
index 0000000..74bc854
--- /dev/null
+++ b/include/sound/ac97_codec.h
@@ -0,0 +1,666 @@
+#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 <sound/pcm.h>
+#include <sound/control.h>
+#include <sound/info.h>
+
+/* maximum number of devices on the AC97 bus */
+#define	AC97_BUS_MAX_DEVICES	4
+
+/*
+ *  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 */
+
+/* volume controls */
+#define AC97_MUTE_MASK_MONO	0x8000
+#define AC97_MUTE_MASK_STEREO	0x8080
+
+/* 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
+#define AC97_BC_3D_TECH_ID_MASK	0x7c00	/* Per-vendor ID of 3D enhancement */
+
+/* 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 aggressive 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_pcm_chmap;
+
+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 -- */
+	const 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;
+
+	struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */
+};
+
+#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
+int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
+	unsigned int id_mask);
+
+/* 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 subsystem 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,
+			   const 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;
+
+/* AC97 platform_data adding function */
+static inline void snd_ac97_dev_add_pdata(struct snd_ac97 *ac97, void *data)
+{
+	ac97->dev.platform_data = data;
+}
+
+#endif /* __SOUND_AC97_CODEC_H */
diff --git a/include/sound/aci.h b/include/sound/aci.h
new file mode 100644
index 0000000..ee639d3
--- /dev/null
+++ b/include/sound/aci.h
@@ -0,0 +1,90 @@
+#ifndef _ACI_H_
+#define _ACI_H_
+
+#define ACI_REG_COMMAND		0	/* write register offset */
+#define ACI_REG_STATUS		1	/* read register offset */
+#define ACI_REG_BUSY		2	/* busy register offset */
+#define ACI_REG_RDS		2	/* PCM20: RDS register offset */
+#define ACI_MINTIME		500	/* ACI time out limit */
+
+#define ACI_SET_MUTE		0x0d
+#define ACI_SET_POWERAMP	0x0f
+#define ACI_SET_TUNERMUTE	0xa3
+#define ACI_SET_TUNERMONO	0xa4
+#define ACI_SET_IDE		0xd0
+#define ACI_SET_WSS		0xd1
+#define ACI_SET_SOLOMODE	0xd2
+#define ACI_SET_PREAMP		0x03
+#define ACI_GET_PREAMP		0x21
+#define ACI_WRITE_TUNE		0xa7
+#define ACI_READ_TUNERSTEREO	0xa8
+#define ACI_READ_TUNERSTATION	0xa9
+#define ACI_READ_VERSION	0xf1
+#define ACI_READ_IDCODE		0xf2
+#define ACI_INIT		0xff
+#define ACI_STATUS		0xf0
+#define ACI_S_GENERAL		0x00
+#define ACI_ERROR_OP		0xdf
+
+/* ACI Mixer */
+
+/* These are the values for the right channel GET registers.
+   Add an offset of 0x01 for the left channel register.
+   (left=right+0x01) */
+
+#define ACI_GET_MASTER		0x03
+#define ACI_GET_MIC		0x05
+#define ACI_GET_LINE		0x07
+#define ACI_GET_CD		0x09
+#define ACI_GET_SYNTH		0x0b
+#define ACI_GET_PCM		0x0d
+#define ACI_GET_LINE1		0x10	/* Radio on PCM20 */
+#define ACI_GET_LINE2		0x12
+
+#define ACI_GET_EQ1		0x22	/* from Bass ... */
+#define ACI_GET_EQ2		0x24
+#define ACI_GET_EQ3		0x26
+#define ACI_GET_EQ4		0x28
+#define ACI_GET_EQ5		0x2a
+#define ACI_GET_EQ6		0x2c
+#define ACI_GET_EQ7		0x2e	/* ... to Treble */
+
+/* And these are the values for the right channel SET registers.
+   For left channel access you have to add an offset of 0x08.
+   MASTER is an exception, which needs an offset of 0x01 */
+
+#define ACI_SET_MASTER		0x00
+#define ACI_SET_MIC		0x30
+#define ACI_SET_LINE		0x31
+#define ACI_SET_CD		0x34
+#define ACI_SET_SYNTH		0x33
+#define ACI_SET_PCM		0x32
+#define ACI_SET_LINE1		0x35	/* Radio on PCM20 */
+#define ACI_SET_LINE2		0x36
+
+#define ACI_SET_EQ1		0x40	/* from Bass ... */
+#define ACI_SET_EQ2		0x41
+#define ACI_SET_EQ3		0x42
+#define ACI_SET_EQ4		0x43
+#define ACI_SET_EQ5		0x44
+#define ACI_SET_EQ6		0x45
+#define ACI_SET_EQ7		0x46	/* ... to Treble */
+
+struct snd_miro_aci {
+	unsigned long aci_port;
+	int aci_vendor;
+	int aci_product;
+	int aci_version;
+	int aci_amp;
+	int aci_preamp;
+	int aci_solomode;
+
+	struct mutex aci_mutex;
+};
+
+int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3);
+
+struct snd_miro_aci *snd_aci_get_aci(void);
+
+#endif  /* _ACI_H_ */
+
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
new file mode 100644
index 0000000..f2d3a6d
--- /dev/null
+++ b/include/sound/ad1816a.h
@@ -0,0 +1,181 @@
+#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 <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/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;
+#ifdef CONFIG_PM
+	unsigned short image[48];
+#endif
+};
+
+
+#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);
+extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
+extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device);
+#ifdef CONFIG_PM
+extern void snd_ad1816a_suspend(struct snd_ad1816a *chip);
+extern void snd_ad1816a_resume(struct snd_ad1816a *chip);
+#endif
+
+#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/adau1373.h b/include/sound/adau1373.h
new file mode 100644
index 0000000..1b19c76
--- /dev/null
+++ b/include/sound/adau1373.h
@@ -0,0 +1,34 @@
+/*
+ * Analog Devices ADAU1373 Audio Codec drive
+ *
+ * Copyright 2011 Analog Devices Inc.
+ * Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __SOUND_ADAU1373_H__
+#define __SOUND_ADAU1373_H__
+
+enum adau1373_micbias_voltage {
+	ADAU1373_MICBIAS_2_9V = 0,
+	ADAU1373_MICBIAS_2_2V = 1,
+	ADAU1373_MICBIAS_2_6V = 2,
+	ADAU1373_MICBIAS_1_8V = 3,
+};
+
+#define ADAU1373_DRC_SIZE 13
+
+struct adau1373_platform_data {
+	bool input_differential[4];
+	bool lineout_differential;
+	bool lineout_ground_sense;
+
+	unsigned int num_drc;
+	uint8_t drc_setting[3][ADAU1373_DRC_SIZE];
+
+	enum adau1373_micbias_voltage micbias1;
+	enum adau1373_micbias_voltage micbias2;
+};
+
+#endif
diff --git a/include/sound/aess.h b/include/sound/aess.h
new file mode 100644
index 0000000..cee0d09
--- /dev/null
+++ b/include/sound/aess.h
@@ -0,0 +1,53 @@
+/*
+ * AESS IP block reset
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef __SOUND_AESS_H__
+#define __SOUND_AESS_H__
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+/*
+ * AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
+ *     block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's
+ *     base address
+ */
+#define AESS_AUTO_GATING_ENABLE_OFFSET			0x07c
+
+/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */
+#define AESS_AUTO_GATING_ENABLE_SHIFT			0
+
+/**
+ * aess_enable_autogating - enable AESS internal autogating
+ * @oh: struct omap_hwmod *
+ *
+ * Enable internal autogating on the AESS.  This allows the AESS to
+ * indicate that it is idle to the OMAP PRCM.  Returns 0.
+ */
+static inline void aess_enable_autogating(void __iomem *base)
+{
+	u32 v;
+
+	/* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */
+	v = 1 << AESS_AUTO_GATING_ENABLE_SHIFT;
+	writel(v, base + AESS_AUTO_GATING_ENABLE_OFFSET);
+}
+
+#endif /* __SOUND_AESS_H__ */
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h
new file mode 100644
index 0000000..58c1456
--- /dev/null
+++ b/include/sound/ak4113.h
@@ -0,0 +1,330 @@
+#ifndef __SOUND_AK4113_H
+#define __SOUND_AK4113_H
+
+/*
+ *  Routines for Asahi Kasei AK4113
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *  Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.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
+ *
+ */
+
+/* AK4113 registers */
+/* power down */
+#define AK4113_REG_PWRDN	0x00
+/* format control */
+#define AK4113_REG_FORMAT	0x01
+/* input/output control */
+#define AK4113_REG_IO0		0x02
+/* input/output control */
+#define AK4113_REG_IO1		0x03
+/* interrupt0 mask */
+#define AK4113_REG_INT0_MASK	0x04
+/* interrupt1 mask */
+#define AK4113_REG_INT1_MASK	0x05
+/* DAT mask & DTS select */
+#define AK4113_REG_DATDTS	0x06
+/* receiver status 0 */
+#define AK4113_REG_RCS0		0x07
+/* receiver status 1 */
+#define AK4113_REG_RCS1		0x08
+/* receiver status 2 */
+#define AK4113_REG_RCS2		0x09
+/* RX channel status byte 0 */
+#define AK4113_REG_RXCSB0	0x0a
+/* RX channel status byte 1 */
+#define AK4113_REG_RXCSB1	0x0b
+/* RX channel status byte 2 */
+#define AK4113_REG_RXCSB2	0x0c
+/* RX channel status byte 3 */
+#define AK4113_REG_RXCSB3	0x0d
+/* RX channel status byte 4 */
+#define AK4113_REG_RXCSB4	0x0e
+/* burst preamble Pc byte 0 */
+#define AK4113_REG_Pc0		0x0f
+/* burst preamble Pc byte 1 */
+#define AK4113_REG_Pc1		0x10
+/* burst preamble Pd byte 0 */
+#define AK4113_REG_Pd0		0x11
+/* burst preamble Pd byte 1 */
+#define AK4113_REG_Pd1		0x12
+/* Q-subcode address + control */
+#define AK4113_REG_QSUB_ADDR	0x13
+/* Q-subcode track */
+#define AK4113_REG_QSUB_TRACK	0x14
+/* Q-subcode index */
+#define AK4113_REG_QSUB_INDEX	0x15
+/* Q-subcode minute */
+#define AK4113_REG_QSUB_MINUTE	0x16
+/* Q-subcode second */
+#define AK4113_REG_QSUB_SECOND	0x17
+/* Q-subcode frame */
+#define AK4113_REG_QSUB_FRAME	0x18
+/* Q-subcode zero */
+#define AK4113_REG_QSUB_ZERO	0x19
+/* Q-subcode absolute minute */
+#define AK4113_REG_QSUB_ABSMIN	0x1a
+/* Q-subcode absolute second */
+#define AK4113_REG_QSUB_ABSSEC	0x1b
+/* Q-subcode absolute frame */
+#define AK4113_REG_QSUB_ABSFRM	0x1c
+
+/* sizes */
+#define AK4113_REG_RXCSB_SIZE	((AK4113_REG_RXCSB4-AK4113_REG_RXCSB0)+1)
+#define AK4113_REG_QSUB_SIZE	((AK4113_REG_QSUB_ABSFRM-AK4113_REG_QSUB_ADDR)\
+		+1)
+
+#define AK4113_WRITABLE_REGS	(AK4113_REG_DATDTS + 1)
+
+/* AK4113_REG_PWRDN bits */
+/* Channel Status Select */
+#define AK4113_CS12		(1<<7)
+/* Block Start & C/U Output Mode */
+#define AK4113_BCU		(1<<6)
+/* Master Clock Operation Select */
+#define AK4113_CM1		(1<<5)
+/* Master Clock Operation Select */
+#define AK4113_CM0		(1<<4)
+/* Master Clock Frequency Select */
+#define AK4113_OCKS1		(1<<3)
+/* Master Clock Frequency Select */
+#define AK4113_OCKS0		(1<<2)
+/* 0 = power down, 1 = normal operation */
+#define AK4113_PWN		(1<<1)
+/* 0 = reset & initialize (except thisregister), 1 = normal operation */
+#define AK4113_RST		(1<<0)
+
+/* AK4113_REQ_FORMAT bits */
+/* V/TX Output select: 0 = Validity Flag Output, 1 = TX */
+#define AK4113_VTX		(1<<7)
+/* Audio Data Control */
+#define AK4113_DIF2		(1<<6)
+/* Audio Data Control */
+#define AK4113_DIF1		(1<<5)
+/* Audio Data Control */
+#define AK4113_DIF0		(1<<4)
+/* Deemphasis Autodetect Enable (1 = enable) */
+#define AK4113_DEAU		(1<<3)
+/* 32kHz-48kHz Deemphasis Control */
+#define AK4113_DEM1		(1<<2)
+/* 32kHz-48kHz Deemphasis Control */
+#define AK4113_DEM0		(1<<1)
+#define AK4113_DEM_OFF		(AK4113_DEM0)
+#define AK4113_DEM_44KHZ	(0)
+#define AK4113_DEM_48KHZ	(AK4113_DEM1)
+#define AK4113_DEM_32KHZ	(AK4113_DEM0|AK4113_DEM1)
+/* STDO: 16-bit, right justified */
+#define AK4113_DIF_16R		(0)
+/* STDO: 18-bit, right justified */
+#define AK4113_DIF_18R		(AK4113_DIF0)
+/* STDO: 20-bit, right justified */
+#define AK4113_DIF_20R		(AK4113_DIF1)
+/* STDO: 24-bit, right justified */
+#define AK4113_DIF_24R		(AK4113_DIF1|AK4113_DIF0)
+/* STDO: 24-bit, left justified */
+#define AK4113_DIF_24L		(AK4113_DIF2)
+/* STDO: I2S */
+#define AK4113_DIF_24I2S	(AK4113_DIF2|AK4113_DIF0)
+/* STDO: 24-bit, left justified; LRCLK, BICK = Input */
+#define AK4113_DIF_I24L		(AK4113_DIF2|AK4113_DIF1)
+/* STDO: I2S;  LRCLK, BICK = Input */
+#define AK4113_DIF_I24I2S	(AK4113_DIF2|AK4113_DIF1|AK4113_DIF0)
+
+/* AK4113_REG_IO0 */
+/* XTL1=0,XTL0=0 -> 11.2896Mhz; XTL1=0,XTL0=1 -> 12.288Mhz */
+#define AK4113_XTL1		(1<<6)
+/* XTL1=1,XTL0=0 -> 24.576Mhz; XTL1=1,XTL0=1 -> use channel status */
+#define AK4113_XTL0		(1<<5)
+/* Block Start Signal Output: 0 = U-bit, 1 = C-bit (req. BCU = 1) */
+#define AK4113_UCE		(1<<4)
+/* TX Output Enable (1 = enable) */
+#define AK4113_TXE		(1<<3)
+/* Output Through Data Selector for TX pin */
+#define AK4113_OPS2		(1<<2)
+/* Output Through Data Selector for TX pin */
+#define AK4113_OPS1		(1<<1)
+/* Output Through Data Selector for TX pin */
+#define AK4113_OPS0		(1<<0)
+/* 11.2896 MHz ref. Xtal freq. */
+#define AK4113_XTL_11_2896M	(0)
+/* 12.288 MHz ref. Xtal freq. */
+#define AK4113_XTL_12_288M	(AK4113_XTL0)
+/* 24.576 MHz ref. Xtal freq. */
+#define AK4113_XTL_24_576M	(AK4113_XTL1)
+
+/* AK4113_REG_IO1 */
+/* Interrupt 0 pin Hold */
+#define AK4113_EFH1		(1<<7)
+/* Interrupt 0 pin Hold */
+#define AK4113_EFH0		(1<<6)
+#define AK4113_EFH_512LRCLK	(0)
+#define AK4113_EFH_1024LRCLK	(AK4113_EFH0)
+#define AK4113_EFH_2048LRCLK	(AK4113_EFH1)
+#define AK4113_EFH_4096LRCLK	(AK4113_EFH1|AK4113_EFH0)
+/* PLL Lock Time: 0 = 384/fs, 1 = 1/fs */
+#define AK4113_FAST		(1<<5)
+/* MCKO2 Output Select: 0 = CMx/OCKSx, 1 = Xtal */
+#define AK4113_XMCK		(1<<4)
+/* MCKO2 Output Freq. Select: 0 = x1, 1 = x0.5  (req. XMCK = 1) */
+#define AK4113_DIV		(1<<3)
+/* Input Recovery Data Select */
+#define AK4113_IPS2		(1<<2)
+/* Input Recovery Data Select */
+#define AK4113_IPS1		(1<<1)
+/* Input Recovery Data Select */
+#define AK4113_IPS0		(1<<0)
+#define AK4113_IPS(x)		((x)&7)
+
+/* AK4113_REG_INT0_MASK && AK4113_REG_INT1_MASK*/
+/* mask enable for QINT bit */
+#define AK4113_MQI		(1<<7)
+/* mask enable for AUTO bit */
+#define AK4113_MAUT		(1<<6)
+/* mask enable for CINT bit */
+#define AK4113_MCIT		(1<<5)
+/* mask enable for UNLOCK bit */
+#define AK4113_MULK		(1<<4)
+/* mask enable for V bit */
+#define AK4113_V		(1<<3)
+/* mask enable for STC bit */
+#define AK4113_STC		(1<<2)
+/* mask enable for AUDN bit */
+#define AK4113_MAN		(1<<1)
+/* mask enable for PAR bit */
+#define AK4113_MPR		(1<<0)
+
+/* AK4113_REG_DATDTS */
+/* DAT Start ID Counter */
+#define AK4113_DCNT		(1<<4)
+/* DTS-CD 16-bit Sync Word Detect */
+#define AK4113_DTS16		(1<<3)
+/* DTS-CD 14-bit Sync Word Detect */
+#define AK4113_DTS14		(1<<2)
+/* mask enable for DAT bit (if 1, no INT1 effect */
+#define AK4113_MDAT1		(1<<1)
+/* mask enable for DAT bit (if 1, no INT0 effect */
+#define AK4113_MDAT0		(1<<0)
+
+/* AK4113_REG_RCS0 */
+/* Q-subcode buffer interrupt, 0 = no change, 1 = changed */
+#define AK4113_QINT		(1<<7)
+/* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */
+#define AK4113_AUTO		(1<<6)
+/* channel status buffer interrupt, 0 = no change, 1 = change */
+#define AK4113_CINT		(1<<5)
+/* PLL lock status, 0 = lock, 1 = unlock */
+#define AK4113_UNLCK		(1<<4)
+/* Validity bit, 0 = valid, 1 = invalid */
+#define AK4113_V		(1<<3)
+/* sampling frequency or Pre-emphasis change, 0 = no detect, 1 = detect */
+#define AK4113_STC		(1<<2)
+/* audio bit output, 0 = audio, 1 = non-audio */
+#define AK4113_AUDION		(1<<1)
+/* parity error or biphase error status, 0 = no error, 1 = error */
+#define AK4113_PAR		(1<<0)
+
+/* AK4113_REG_RCS1 */
+/* sampling frequency detection */
+#define AK4113_FS3		(1<<7)
+#define AK4113_FS2		(1<<6)
+#define AK4113_FS1		(1<<5)
+#define AK4113_FS0		(1<<4)
+/* Pre-emphasis detect, 0 = OFF, 1 = ON */
+#define AK4113_PEM		(1<<3)
+/* DAT Start ID Detect, 0 = no detect, 1 = detect */
+#define AK4113_DAT		(1<<2)
+/* DTS-CD bit audio stream detect, 0 = no detect, 1 = detect */
+#define AK4113_DTSCD		(1<<1)
+/* Non-PCM bit stream detection, 0 = no detect, 1 = detect */
+#define AK4113_NPCM		(1<<0)
+#define AK4113_FS_8000HZ	(AK4113_FS3|AK4113_FS0)
+#define AK4113_FS_11025HZ	(AK4113_FS2|AK4113_FS0)
+#define AK4113_FS_16000HZ	(AK4113_FS2|AK4113_FS1|AK4113_FS0)
+#define AK4113_FS_22050HZ	(AK4113_FS2)
+#define AK4113_FS_24000HZ	(AK4113_FS2|AK4113_FS1)
+#define AK4113_FS_32000HZ	(AK4113_FS1|AK4113_FS0)
+#define AK4113_FS_44100HZ	(0)
+#define AK4113_FS_48000HZ	(AK4113_FS1)
+#define AK4113_FS_64000HZ	(AK4113_FS3|AK4113_FS1|AK4113_FS0)
+#define AK4113_FS_88200HZ	(AK4113_FS3)
+#define AK4113_FS_96000HZ	(AK4113_FS3|AK4113_FS1)
+#define AK4113_FS_176400HZ	(AK4113_FS3|AK4113_FS2)
+#define AK4113_FS_192000HZ	(AK4113_FS3|AK4113_FS2|AK4113_FS1)
+
+/* AK4113_REG_RCS2 */
+/* CRC for Q-subcode, 0 = no error, 1 = error */
+#define AK4113_QCRC		(1<<1)
+/* CRC for channel status, 0 = no error, 1 = error */
+#define AK4113_CCRC		(1<<0)
+
+/* flags for snd_ak4113_check_rate_and_errors() */
+#define AK4113_CHECK_NO_STAT	(1<<0)	/* no statistics */
+#define AK4113_CHECK_NO_RATE	(1<<1)	/* no rate check */
+
+#define AK4113_CONTROLS		13
+
+typedef void (ak4113_write_t)(void *private_data, unsigned char addr,
+		unsigned char data);
+typedef unsigned char (ak4113_read_t)(void *private_data, unsigned char addr);
+
+struct ak4113 {
+	struct snd_card *card;
+	ak4113_write_t *write;
+	ak4113_read_t *read;
+	void *private_data;
+	atomic_t wq_processing;
+	struct mutex reinit_mutex;
+	spinlock_t lock;
+	unsigned char regmap[AK4113_WRITABLE_REGS];
+	struct snd_kcontrol *kctls[AK4113_CONTROLS];
+	struct snd_pcm_substream *substream;
+	unsigned long parity_errors;
+	unsigned long v_bit_errors;
+	unsigned long qcrc_errors;
+	unsigned long ccrc_errors;
+	unsigned char rcs0;
+	unsigned char rcs1;
+	unsigned char rcs2;
+	struct delayed_work work;
+	unsigned int check_flags;
+	void *change_callback_private;
+	void (*change_callback)(struct ak4113 *ak4113, unsigned char c0,
+			unsigned char c1);
+};
+
+int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
+		ak4113_write_t *write,
+		const unsigned char *pgm,
+		void *private_data, struct ak4113 **r_ak4113);
+void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
+		unsigned char mask, unsigned char val);
+void snd_ak4113_reinit(struct ak4113 *ak4113);
+int snd_ak4113_build(struct ak4113 *ak4113,
+		struct snd_pcm_substream *capture_substream);
+int snd_ak4113_external_rate(struct ak4113 *ak4113);
+int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags);
+
+#ifdef CONFIG_PM
+void snd_ak4113_suspend(struct ak4113 *chip);
+void snd_ak4113_resume(struct ak4113 *chip);
+#else
+static inline void snd_ak4113_suspend(struct ak4113 *chip) {}
+static inline void snd_ak4113_resume(struct ak4113 *chip) {}
+#endif
+
+#endif /* __SOUND_AK4113_H */
+
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
new file mode 100644
index 0000000..b6feb7e
--- /dev/null
+++ b/include/sound/ak4114.h
@@ -0,0 +1,212 @@
+#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<<6)	/* Output Data Selector for TX1 pin */
+#define AK4114_OPS11		(1<<5)	/* Output Data Selector for TX1 pin */
+#define AK4114_OPS10		(1<<4)	/* Output Data Selector for TX1 pin */
+#define AK4114_TX0E		(1<<3)	/* TX0 Output Enable (1 = enable) */
+#define AK4114_OPS02		(1<<2)	/* Output Data Selector for TX0 pin */
+#define AK4114_OPS01		(1<<1)	/* Output Data Selector for TX0 pin */
+#define AK4114_OPS00		(1<<0)	/* Output 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;
+	atomic_t wq_processing;
+	struct mutex reinit_mutex;
+	spinlock_t lock;
+	unsigned char regmap[6];
+	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[6], 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);
+
+#ifdef CONFIG_PM
+void snd_ak4114_suspend(struct ak4114 *chip);
+void snd_ak4114_resume(struct ak4114 *chip);
+#else
+static inline void snd_ak4114_suspend(struct ak4114 *chip) {}
+static inline void snd_ak4114_resume(struct ak4114 *chip) {}
+#endif
+
+#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];
+	struct snd_kcontrol *kctls[AK4117_CONTROLS];
+	struct snd_pcm_substream *substream;
+	unsigned long parity_errors;
+	unsigned long v_bit_errors;
+	unsigned long qcrc_errors;
+	unsigned long ccrc_errors;
+	unsigned char rcs0;
+	unsigned char rcs1;
+	unsigned char rcs2;
+	struct timer_list timer;	/* statistic timer */
+	void *change_callback_private;
+	void (*change_callback)(struct ak4117 *ak4117, unsigned char c0, unsigned char c1);
+};
+
+int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write,
+		      const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117);
+void snd_ak4117_reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char mask, unsigned char val);
+void snd_ak4117_reinit(struct ak4117 *ak4117);
+int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *capture_substream);
+int snd_ak4117_external_rate(struct ak4117 *ak4117);
+int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags);
+
+#endif /* __SOUND_AK4117_H */
+
diff --git a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h
new file mode 100644
index 0000000..85ea86e
--- /dev/null
+++ b/include/sound/ak4531_codec.h
@@ -0,0 +1,85 @@
+#ifndef __SOUND_AK4531_CODEC_H
+#define __SOUND_AK4531_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 <sound/info.h>
+#include <sound/control.h>
+
+/*
+ *  ASAHI KASEI - AK4531 codec
+ *  - not really AC'97 codec, but it uses very similar interface as AC'97
+ */
+
+/*
+ *  AK4531 codec registers
+ */
+
+#define AK4531_LMASTER  0x00	/* master volume left */
+#define AK4531_RMASTER  0x01	/* master volume right */
+#define AK4531_LVOICE   0x02	/* channel volume left */
+#define AK4531_RVOICE   0x03	/* channel volume right */
+#define AK4531_LFM      0x04	/* FM volume left */
+#define AK4531_RFM      0x05	/* FM volume right */
+#define AK4531_LCD      0x06	/* CD volume left */
+#define AK4531_RCD      0x07	/* CD volume right */
+#define AK4531_LLINE    0x08	/* LINE volume left */
+#define AK4531_RLINE    0x09	/* LINE volume right */
+#define AK4531_LAUXA    0x0a	/* AUXA volume left */
+#define AK4531_RAUXA    0x0b	/* AUXA volume right */
+#define AK4531_MONO1    0x0c	/* MONO1 volume left */
+#define AK4531_MONO2    0x0d	/* MONO1 volume right */
+#define AK4531_MIC      0x0e	/* MIC volume */
+#define AK4531_MONO_OUT 0x0f	/* Mono-out volume */
+#define AK4531_OUT_SW1  0x10	/* Output mixer switch 1 */
+#define AK4531_OUT_SW2  0x11	/* Output mixer switch 2 */
+#define AK4531_LIN_SW1  0x12	/* Input left mixer switch 1 */
+#define AK4531_RIN_SW1  0x13	/* Input right mixer switch 1 */
+#define AK4531_LIN_SW2  0x14	/* Input left mixer switch 2 */
+#define AK4531_RIN_SW2  0x15	/* Input right mixer switch 2 */
+#define AK4531_RESET    0x16	/* Reset & power down */
+#define AK4531_CLOCK    0x17	/* Clock select */
+#define AK4531_AD_IN    0x18	/* AD input select */
+#define AK4531_MIC_GAIN 0x19	/* MIC amplified gain */
+
+struct snd_ak4531 {
+	void (*write) (struct snd_ak4531 *ak4531, unsigned short reg,
+		       unsigned short val);
+	void *private_data;
+	void (*private_free) (struct snd_ak4531 *ak4531);
+	/* --- */
+	unsigned char regs[0x20];
+	struct mutex reg_mutex;
+};
+
+int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
+		     struct snd_ak4531 **rak4531);
+
+#ifdef CONFIG_PM
+void snd_ak4531_suspend(struct snd_ak4531 *ak4531);
+void snd_ak4531_resume(struct snd_ak4531 *ak4531);
+#endif
+
+#endif /* __SOUND_AK4531_CODEC_H */
diff --git a/include/sound/ak4641.h b/include/sound/ak4641.h
new file mode 100644
index 0000000..96d1991
--- /dev/null
+++ b/include/sound/ak4641.h
@@ -0,0 +1,26 @@
+/*
+ * AK4641 ALSA SoC Codec driver
+ *
+ * Copyright 2009 Philipp Zabel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __AK4641_H
+#define __AK4641_H
+
+/**
+ * struct ak4641_platform_data - platform specific AK4641 configuration
+ * @gpio_power:	GPIO to control external power to AK4641
+ * @gpio_npdn:	GPIO connected to AK4641 nPDN pin
+ *
+ * Both GPIO parameters are optional.
+ */
+struct ak4641_platform_data {
+	int gpio_power;
+	int gpio_npdn;
+};
+
+#endif /* __AK4641_H */
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h
new file mode 100644
index 0000000..030b87c
--- /dev/null
+++ b/include/sound/ak4xxx-adda.h
@@ -0,0 +1,99 @@
+#ifndef __SOUND_AK4XXX_ADDA_H
+#define __SOUND_AK4XXX_ADDA_H
+
+/*
+ *   ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4381
+ *   AD and DA converters
+ *
+ *	Copyright (c) 2000 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
+ *
+ */      
+
+#ifndef AK4XXX_MAX_CHIPS
+#define AK4XXX_MAX_CHIPS	4
+#endif
+
+struct snd_akm4xxx;
+
+struct snd_ak4xxx_ops {
+	void (*lock)(struct snd_akm4xxx *ak, int chip);
+	void (*unlock)(struct snd_akm4xxx *ak, int chip);
+	void (*write)(struct snd_akm4xxx *ak, int chip, unsigned char reg,
+		      unsigned char val);
+	void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate);
+};
+
+#define AK4XXX_IMAGE_SIZE	(AK4XXX_MAX_CHIPS * 16)	/* 64 bytes */
+
+/* DAC label and channels */
+struct snd_akm4xxx_dac_channel {
+	char *name;		/* mixer volume name */
+	unsigned int num_channels;
+	char *switch_name;		/* mixer switch*/
+};
+
+/* ADC labels and channels */
+struct snd_akm4xxx_adc_channel {
+	char *name;		/* capture gain volume label */
+	char *switch_name;	/* capture switch */
+	unsigned int num_channels;
+	char *selector_name;	/* capture source select label */
+	const char **input_names; /* capture source names (NULL terminated) */
+};
+
+struct snd_akm4xxx {
+	struct snd_card *card;
+	unsigned int num_adcs;			/* AK4524 or AK4528 ADCs */
+	unsigned int num_dacs;			/* AK4524 or AK4528 DACs */
+	unsigned char images[AK4XXX_IMAGE_SIZE]; /* saved register image */
+	unsigned char volumes[AK4XXX_IMAGE_SIZE]; /* saved volume values */
+	unsigned long private_value[AK4XXX_MAX_CHIPS];	/* helper for driver */
+	void *private_data[AK4XXX_MAX_CHIPS];		/* helper for driver */
+	/* template should fill the following fields */
+	unsigned int idx_offset;		/* control index offset */
+	enum {
+		SND_AK4524, SND_AK4528, SND_AK4529,
+		SND_AK4355, SND_AK4358, SND_AK4381,
+		SND_AK5365, SND_AK4620,
+	} type;
+
+	/* (array) information of combined codecs */
+	const struct snd_akm4xxx_dac_channel *dac_info;
+	const struct snd_akm4xxx_adc_channel *adc_info;
+
+	struct snd_ak4xxx_ops ops;
+	unsigned int num_chips;
+	unsigned int total_regs;
+	const char *name;
+};
+
+void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg,
+		       unsigned char val);
+void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state);
+void snd_akm4xxx_init(struct snd_akm4xxx *ak);
+int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak);
+
+#define snd_akm4xxx_get(ak,chip,reg) \
+	(ak)->images[(chip) * 16 + (reg)]
+#define snd_akm4xxx_set(ak,chip,reg,val) \
+	((ak)->images[(chip) * 16 + (reg)] = (val))
+#define snd_akm4xxx_get_vol(ak,chip,reg) \
+	(ak)->volumes[(chip) * 16 + (reg)]
+#define snd_akm4xxx_set_vol(ak,chip,reg,val) \
+	((ak)->volumes[(chip) * 16 + (reg)] = (val))
+
+#endif /* __SOUND_AK4XXX_ADDA_H */
diff --git a/include/sound/alc5623.h b/include/sound/alc5623.h
new file mode 100644
index 0000000..422c97d
--- /dev/null
+++ b/include/sound/alc5623.h
@@ -0,0 +1,15 @@
+#ifndef _INCLUDE_SOUND_ALC5623_H
+#define _INCLUDE_SOUND_ALC5623_H
+struct alc5623_platform_data {
+	/* configure :                              */
+	/* Lineout/Speaker Amps Vmid ratio control  */
+	/* enable/disable adc/dac high pass filters */
+	unsigned int add_ctrl;
+	/* configure :                              */
+	/* output to enable when jack is low        */
+	/* output to enable when jack is high       */
+	/* jack detect (gpio/nc/jack detect [12]    */
+	unsigned int jack_det_ctrl;
+};
+#endif
+
diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h
new file mode 100644
index 0000000..75935ce
--- /dev/null
+++ b/include/sound/asequencer.h
@@ -0,0 +1,86 @@
+/*
+ *  Main header file for the ALSA sequencer
+ *  Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
+ *            (c) 1998-1999 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
+ *
+ */
+#ifndef __SOUND_ASEQUENCER_H
+#define __SOUND_ASEQUENCER_H
+
+#include <linux/ioctl.h>
+#include <sound/asound.h>
+#include <uapi/sound/asequencer.h>
+
+/* helper macro */
+#define snd_seq_event_bounce_ext_data(ev) ((void*)((char *)(ev)->data.ext.ptr + sizeof(struct snd_seq_event_bounce)))
+
+/*
+ * type check macros
+ */
+/* result events: 0-4 */
+#define snd_seq_ev_is_result_type(ev)	((ev)->type < 5)
+/* channel specific events: 5-19 */
+#define snd_seq_ev_is_channel_type(ev)	((ev)->type >= 5 && (ev)->type < 20)
+/* note events: 5-9 */
+#define snd_seq_ev_is_note_type(ev)	((ev)->type >= 5 && (ev)->type < 10)
+/* control events: 10-19 */
+#define snd_seq_ev_is_control_type(ev)	((ev)->type >= 10 && (ev)->type < 20)
+/* queue control events: 30-39 */
+#define snd_seq_ev_is_queue_type(ev)	((ev)->type >= 30 && (ev)->type < 40)
+/* system status messages */
+#define snd_seq_ev_is_message_type(ev)	((ev)->type >= 60 && (ev)->type < 69)
+/* sample messages */
+#define snd_seq_ev_is_sample_type(ev)	((ev)->type >= 70 && (ev)->type < 79)
+/* user-defined messages */
+#define snd_seq_ev_is_user_type(ev)	((ev)->type >= 90 && (ev)->type < 99)
+/* fixed length events: 0-99 */
+#define snd_seq_ev_is_fixed_type(ev)	((ev)->type < 100)
+/* variable length events: 130-139 */
+#define snd_seq_ev_is_variable_type(ev)	((ev)->type >= 130 && (ev)->type < 140)
+/* reserved for kernel */
+#define snd_seq_ev_is_reserved(ev)	((ev)->type >= 150)
+
+/* direct dispatched events */
+#define snd_seq_ev_is_direct(ev)	((ev)->queue == SNDRV_SEQ_QUEUE_DIRECT)
+
+/*
+ * macros to check event flags
+ */
+/* prior events */
+#define snd_seq_ev_is_prior(ev)		(((ev)->flags & SNDRV_SEQ_PRIORITY_MASK) == SNDRV_SEQ_PRIORITY_HIGH)
+
+/* event length type */
+#define snd_seq_ev_length_type(ev)	((ev)->flags & SNDRV_SEQ_EVENT_LENGTH_MASK)
+#define snd_seq_ev_is_fixed(ev)		(snd_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_FIXED)
+#define snd_seq_ev_is_variable(ev)	(snd_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
+#define snd_seq_ev_is_varusr(ev)	(snd_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARUSR)
+
+/* time-stamp type */
+#define snd_seq_ev_timestamp_type(ev)	((ev)->flags & SNDRV_SEQ_TIME_STAMP_MASK)
+#define snd_seq_ev_is_tick(ev)		(snd_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_TICK)
+#define snd_seq_ev_is_real(ev)		(snd_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_REAL)
+
+/* time-mode type */
+#define snd_seq_ev_timemode_type(ev)	((ev)->flags & SNDRV_SEQ_TIME_MODE_MASK)
+#define snd_seq_ev_is_abstime(ev)	(snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_ABS)
+#define snd_seq_ev_is_reltime(ev)	(snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_REL)
+
+/* queue sync port */
+#define snd_seq_queue_sync_port(q)	((q) + 16)
+
+#endif /* __SOUND_ASEQUENCER_H */
diff --git a/include/sound/asound.h b/include/sound/asound.h
new file mode 100644
index 0000000..c2dff53
--- /dev/null
+++ b/include/sound/asound.h
@@ -0,0 +1,40 @@
+/*
+ *  Advanced Linux Sound Architecture - ALSA - Driver
+ *  Copyright (c) 1994-2003 by Jaroslav Kysela <perex@perex.cz>,
+ *                             Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ *   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
+ *
+ */
+#ifndef __SOUND_ASOUND_H
+#define __SOUND_ASOUND_H
+
+#include <linux/ioctl.h>
+#include <linux/time.h>
+#include <asm/byteorder.h>
+
+#ifdef  __LITTLE_ENDIAN
+#define SNDRV_LITTLE_ENDIAN
+#else
+#ifdef __BIG_ENDIAN
+#define SNDRV_BIG_ENDIAN
+#else
+#error "Unsupported endian..."
+#endif
+#endif
+
+#include <uapi/sound/asound.h>
+#endif /* __SOUND_ASOUND_H */
diff --git a/include/sound/asoundef.h b/include/sound/asoundef.h
new file mode 100644
index 0000000..bb05c02
--- /dev/null
+++ b/include/sound/asoundef.h
@@ -0,0 +1,325 @@
+#ifndef __SOUND_ASOUNDEF_H
+#define __SOUND_ASOUNDEF_H
+
+/*
+ *  Advanced Linux Sound Architecture - ALSA - Driver
+ *  Copyright (c) 1994-2000 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
+ *
+ */
+
+/****************************************************************************
+ *                                                                          *
+ *        Digital audio interface					    *
+ *                                                                          *
+ ****************************************************************************/
+
+/* AES/IEC958 channel status bits */
+#define IEC958_AES0_PROFESSIONAL	(1<<0)	/* 0 = consumer, 1 = professional */
+#define IEC958_AES0_NONAUDIO		(1<<1)	/* 0 = audio, 1 = non-audio */
+#define IEC958_AES0_PRO_EMPHASIS	(7<<2)	/* mask - emphasis */
+#define IEC958_AES0_PRO_EMPHASIS_NOTID	(0<<2)	/* emphasis not indicated */
+#define IEC958_AES0_PRO_EMPHASIS_NONE	(1<<2)	/* none emphasis */
+#define IEC958_AES0_PRO_EMPHASIS_5015	(3<<2)	/* 50/15us emphasis */
+#define IEC958_AES0_PRO_EMPHASIS_CCITT	(7<<2)	/* CCITT J.17 emphasis */
+#define IEC958_AES0_PRO_FREQ_UNLOCKED	(1<<5)	/* source sample frequency: 0 = locked, 1 = unlocked */
+#define IEC958_AES0_PRO_FS		(3<<6)	/* mask - sample frequency */
+#define IEC958_AES0_PRO_FS_NOTID	(0<<6)	/* fs not indicated */
+#define IEC958_AES0_PRO_FS_44100	(1<<6)	/* 44.1kHz */
+#define IEC958_AES0_PRO_FS_48000	(2<<6)	/* 48kHz */
+#define IEC958_AES0_PRO_FS_32000	(3<<6)	/* 32kHz */
+#define IEC958_AES0_CON_NOT_COPYRIGHT	(1<<2)	/* 0 = copyright, 1 = not copyright */
+#define IEC958_AES0_CON_EMPHASIS	(7<<3)	/* mask - emphasis */
+#define IEC958_AES0_CON_EMPHASIS_NONE	(0<<3)	/* none emphasis */
+#define IEC958_AES0_CON_EMPHASIS_5015	(1<<3)	/* 50/15us emphasis */
+#define IEC958_AES0_CON_MODE		(3<<6)	/* mask - mode */
+#define IEC958_AES1_PRO_MODE		(15<<0)	/* mask - channel mode */
+#define IEC958_AES1_PRO_MODE_NOTID	(0<<0)	/* not indicated */
+#define IEC958_AES1_PRO_MODE_STEREOPHONIC (2<<0) /* stereophonic - ch A is left */
+#define IEC958_AES1_PRO_MODE_SINGLE	(4<<0)	/* single channel */
+#define IEC958_AES1_PRO_MODE_TWO	(8<<0)	/* two channels */
+#define IEC958_AES1_PRO_MODE_PRIMARY	(12<<0)	/* primary/secondary */
+#define IEC958_AES1_PRO_MODE_BYTE3	(15<<0)	/* vector to byte 3 */
+#define IEC958_AES1_PRO_USERBITS	(15<<4)	/* mask - user bits */
+#define IEC958_AES1_PRO_USERBITS_NOTID	(0<<4)	/* not indicated */
+#define IEC958_AES1_PRO_USERBITS_192	(8<<4)	/* 192-bit structure */
+#define IEC958_AES1_PRO_USERBITS_UDEF	(12<<4)	/* user defined application */
+#define IEC958_AES1_CON_CATEGORY	0x7f
+#define IEC958_AES1_CON_GENERAL		0x00
+#define IEC958_AES1_CON_LASEROPT_MASK	0x07
+#define IEC958_AES1_CON_LASEROPT_ID	0x01
+#define IEC958_AES1_CON_IEC908_CD	(IEC958_AES1_CON_LASEROPT_ID|0x00)
+#define IEC958_AES1_CON_NON_IEC908_CD	(IEC958_AES1_CON_LASEROPT_ID|0x08)
+#define IEC958_AES1_CON_MINI_DISC	(IEC958_AES1_CON_LASEROPT_ID|0x48)
+#define IEC958_AES1_CON_DVD		(IEC958_AES1_CON_LASEROPT_ID|0x18)
+#define IEC958_AES1_CON_LASTEROPT_OTHER	(IEC958_AES1_CON_LASEROPT_ID|0x78)
+#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07
+#define IEC958_AES1_CON_DIGDIGCONV_ID	0x02
+#define IEC958_AES1_CON_PCM_CODER	(IEC958_AES1_CON_DIGDIGCONV_ID|0x00)
+#define IEC958_AES1_CON_MIXER		(IEC958_AES1_CON_DIGDIGCONV_ID|0x10)
+#define IEC958_AES1_CON_RATE_CONVERTER	(IEC958_AES1_CON_DIGDIGCONV_ID|0x18)
+#define IEC958_AES1_CON_SAMPLER		(IEC958_AES1_CON_DIGDIGCONV_ID|0x20)
+#define IEC958_AES1_CON_DSP		(IEC958_AES1_CON_DIGDIGCONV_ID|0x28)
+#define IEC958_AES1_CON_DIGDIGCONV_OTHER (IEC958_AES1_CON_DIGDIGCONV_ID|0x78)
+#define IEC958_AES1_CON_MAGNETIC_MASK	0x07
+#define IEC958_AES1_CON_MAGNETIC_ID	0x03
+#define IEC958_AES1_CON_DAT		(IEC958_AES1_CON_MAGNETIC_ID|0x00)
+#define IEC958_AES1_CON_VCR		(IEC958_AES1_CON_MAGNETIC_ID|0x08)
+#define IEC958_AES1_CON_DCC		(IEC958_AES1_CON_MAGNETIC_ID|0x40)
+#define IEC958_AES1_CON_MAGNETIC_DISC	(IEC958_AES1_CON_MAGNETIC_ID|0x18)
+#define IEC958_AES1_CON_MAGNETIC_OTHER	(IEC958_AES1_CON_MAGNETIC_ID|0x78)
+#define IEC958_AES1_CON_BROADCAST1_MASK 0x07
+#define IEC958_AES1_CON_BROADCAST1_ID	0x04
+#define IEC958_AES1_CON_DAB_JAPAN	(IEC958_AES1_CON_BROADCAST1_ID|0x00)
+#define IEC958_AES1_CON_DAB_EUROPE	(IEC958_AES1_CON_BROADCAST1_ID|0x08)
+#define IEC958_AES1_CON_DAB_USA		(IEC958_AES1_CON_BROADCAST1_ID|0x60)
+#define IEC958_AES1_CON_SOFTWARE	(IEC958_AES1_CON_BROADCAST1_ID|0x40)
+#define IEC958_AES1_CON_IEC62105	(IEC958_AES1_CON_BROADCAST1_ID|0x20)
+#define IEC958_AES1_CON_BROADCAST1_OTHER (IEC958_AES1_CON_BROADCAST1_ID|0x78)
+#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f
+#define IEC958_AES1_CON_BROADCAST2_ID	0x0e
+#define IEC958_AES1_CON_MUSICAL_MASK	0x07
+#define IEC958_AES1_CON_MUSICAL_ID	0x05
+#define IEC958_AES1_CON_SYNTHESIZER	(IEC958_AES1_CON_MUSICAL_ID|0x00)
+#define IEC958_AES1_CON_MICROPHONE	(IEC958_AES1_CON_MUSICAL_ID|0x08)
+#define IEC958_AES1_CON_MUSICAL_OTHER	(IEC958_AES1_CON_MUSICAL_ID|0x78)
+#define IEC958_AES1_CON_ADC_MASK	0x1f
+#define IEC958_AES1_CON_ADC_ID		0x06
+#define IEC958_AES1_CON_ADC		(IEC958_AES1_CON_ADC_ID|0x00)
+#define IEC958_AES1_CON_ADC_OTHER	(IEC958_AES1_CON_ADC_ID|0x60)
+#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
+#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x16
+#define IEC958_AES1_CON_ADC_COPYRIGHT	(IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x00)
+#define IEC958_AES1_CON_ADC_COPYRIGHT_OTHER (IEC958_AES1_CON_ADC_COPYRIGHT_ID|0x60)
+#define IEC958_AES1_CON_SOLIDMEM_MASK	0x0f
+#define IEC958_AES1_CON_SOLIDMEM_ID	0x08
+#define IEC958_AES1_CON_SOLIDMEM_DIGITAL_RECORDER_PLAYER (IEC958_AES1_CON_SOLIDMEM_ID|0x00)
+#define IEC958_AES1_CON_SOLIDMEM_OTHER	(IEC958_AES1_CON_SOLIDMEM_ID|0x70)
+#define IEC958_AES1_CON_EXPERIMENTAL	0x40
+#define IEC958_AES1_CON_ORIGINAL	(1<<7)	/* this bits depends on the category code */
+#define IEC958_AES2_PRO_SBITS		(7<<0)	/* mask - sample bits */
+#define IEC958_AES2_PRO_SBITS_20	(2<<0)	/* 20-bit - coordination */
+#define IEC958_AES2_PRO_SBITS_24	(4<<0)	/* 24-bit - main audio */
+#define IEC958_AES2_PRO_SBITS_UDEF	(6<<0)	/* user defined application */
+#define IEC958_AES2_PRO_WORDLEN		(7<<3)	/* mask - source word length */
+#define IEC958_AES2_PRO_WORDLEN_NOTID	(0<<3)	/* not indicated */
+#define IEC958_AES2_PRO_WORDLEN_22_18	(2<<3)	/* 22-bit or 18-bit */
+#define IEC958_AES2_PRO_WORDLEN_23_19	(4<<3)	/* 23-bit or 19-bit */
+#define IEC958_AES2_PRO_WORDLEN_24_20	(5<<3)	/* 24-bit or 20-bit */
+#define IEC958_AES2_PRO_WORDLEN_20_16	(6<<3)	/* 20-bit or 16-bit */
+#define IEC958_AES2_CON_SOURCE		(15<<0)	/* mask - source number */
+#define IEC958_AES2_CON_SOURCE_UNSPEC	(0<<0)	/* unspecified */
+#define IEC958_AES2_CON_CHANNEL		(15<<4)	/* mask - channel number */
+#define IEC958_AES2_CON_CHANNEL_UNSPEC	(0<<4)	/* unspecified */
+#define IEC958_AES3_CON_FS		(15<<0)	/* mask - sample frequency */
+#define IEC958_AES3_CON_FS_44100	(0<<0)	/* 44.1kHz */
+#define IEC958_AES3_CON_FS_NOTID	(1<<0)	/* non indicated */
+#define IEC958_AES3_CON_FS_48000	(2<<0)	/* 48kHz */
+#define IEC958_AES3_CON_FS_32000	(3<<0)	/* 32kHz */
+#define IEC958_AES3_CON_FS_22050	(4<<0)	/* 22.05kHz */
+#define IEC958_AES3_CON_FS_24000	(6<<0)	/* 24kHz */
+#define IEC958_AES3_CON_FS_88200	(8<<0)	/* 88.2kHz */
+#define IEC958_AES3_CON_FS_768000	(9<<0)	/* 768kHz */
+#define IEC958_AES3_CON_FS_96000	(10<<0)	/* 96kHz */
+#define IEC958_AES3_CON_FS_176400	(12<<0)	/* 176.4kHz */
+#define IEC958_AES3_CON_FS_192000	(14<<0)	/* 192kHz */
+#define IEC958_AES3_CON_CLOCK		(3<<4)	/* mask - clock accuracy */
+#define IEC958_AES3_CON_CLOCK_1000PPM	(0<<4)	/* 1000 ppm */
+#define IEC958_AES3_CON_CLOCK_50PPM	(1<<4)	/* 50 ppm */
+#define IEC958_AES3_CON_CLOCK_VARIABLE	(2<<4)	/* variable pitch */
+#define IEC958_AES4_CON_MAX_WORDLEN_24	(1<<0)	/* 0 = 20-bit, 1 = 24-bit */
+#define IEC958_AES4_CON_WORDLEN		(7<<1)	/* mask - sample word length */
+#define IEC958_AES4_CON_WORDLEN_NOTID	(0<<1)	/* not indicated */
+#define IEC958_AES4_CON_WORDLEN_20_16	(1<<1)	/* 20-bit or 16-bit */
+#define IEC958_AES4_CON_WORDLEN_22_18	(2<<1)	/* 22-bit or 18-bit */
+#define IEC958_AES4_CON_WORDLEN_23_19	(4<<1)	/* 23-bit or 19-bit */
+#define IEC958_AES4_CON_WORDLEN_24_20	(5<<1)	/* 24-bit or 20-bit */
+#define IEC958_AES4_CON_WORDLEN_21_17	(6<<1)	/* 21-bit or 17-bit */
+#define IEC958_AES4_CON_ORIGFS		(15<<4)	/* mask - original sample frequency */
+#define IEC958_AES4_CON_ORIGFS_NOTID	(0<<4)	/* not indicated */
+#define IEC958_AES4_CON_ORIGFS_192000	(1<<4)	/* 192kHz */
+#define IEC958_AES4_CON_ORIGFS_12000	(2<<4)	/* 12kHz */
+#define IEC958_AES4_CON_ORIGFS_176400	(3<<4)	/* 176.4kHz */
+#define IEC958_AES4_CON_ORIGFS_96000	(5<<4)	/* 96kHz */
+#define IEC958_AES4_CON_ORIGFS_8000	(6<<4)	/* 8kHz */
+#define IEC958_AES4_CON_ORIGFS_88200	(7<<4)	/* 88.2kHz */
+#define IEC958_AES4_CON_ORIGFS_16000	(8<<4)	/* 16kHz */
+#define IEC958_AES4_CON_ORIGFS_24000	(9<<4)	/* 24kHz */
+#define IEC958_AES4_CON_ORIGFS_11025	(10<<4)	/* 11.025kHz */
+#define IEC958_AES4_CON_ORIGFS_22050	(11<<4)	/* 22.05kHz */
+#define IEC958_AES4_CON_ORIGFS_32000	(12<<4)	/* 32kHz */
+#define IEC958_AES4_CON_ORIGFS_48000	(13<<4)	/* 48kHz */
+#define IEC958_AES4_CON_ORIGFS_44100	(15<<4)	/* 44.1kHz */
+#define IEC958_AES5_CON_CGMSA		(3<<0)	/* mask - CGMS-A */
+#define IEC958_AES5_CON_CGMSA_COPYFREELY (0<<0)	/* copying is permitted without restriction */
+#define IEC958_AES5_CON_CGMSA_COPYONCE	(1<<0)	/* one generation of copies may be made */
+#define IEC958_AES5_CON_CGMSA_COPYNOMORE (2<<0)	/* condition not be used */
+#define IEC958_AES5_CON_CGMSA_COPYNEVER	(3<<0)	/* no copying is permitted */
+
+/****************************************************************************
+ *                                                                          *
+ *        CEA-861 Audio InfoFrame. Used in HDMI and DisplayPort		    *
+ *                                                                          *
+ ****************************************************************************/
+#define CEA861_AUDIO_INFOFRAME_DB1CC		(7<<0) /* mask - channel count */
+#define CEA861_AUDIO_INFOFRAME_DB1CT		(0xf<<4) /* mask - coding type */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_FROM_STREAM (0<<4) /* refer to stream */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_IEC60958	(1<<4) /* IEC-60958 L-PCM */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_AC3	(2<<4) /* AC-3 */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_MPEG1	(3<<4) /* MPEG1 Layers 1 & 2 */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_MP3	(4<<4) /* MPEG1 Layer 3 */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_MPEG2_MULTICH (5<<4) /* MPEG2 Multichannel */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_AAC	(6<<4) /* AAC */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_DTS	(7<<4) /* DTS */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_ATRAC	(8<<4) /* ATRAC */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_ONEBIT	(9<<4) /* One Bit Audio */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_DOLBY_DIG_PLUS (10<<4) /* Dolby Digital + */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_DTS_HD	(11<<4) /* DTS-HD */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_MAT	(12<<4) /* MAT (MLP) */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_DST	(13<<4) /* DST */
+#define CEA861_AUDIO_INFOFRAME_DB1CT_WMA_PRO	(14<<4) /* WMA Pro */
+#define CEA861_AUDIO_INFOFRAME_DB2SF		(7<<2) /* mask - sample frequency */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_FROM_STREAM (0<<2) /* refer to stream */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_32000	(1<<2) /* 32kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_44100	(2<<2) /* 44.1kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_48000	(3<<2) /* 48kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_88200	(4<<2) /* 88.2kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_96000	(5<<2) /* 96kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_176400	(6<<2) /* 176.4kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SF_192000	(7<<2) /* 192kHz */
+#define CEA861_AUDIO_INFOFRAME_DB2SS		(3<<0) /* mask - sample size */
+#define CEA861_AUDIO_INFOFRAME_DB2SS_FROM_STREAM (0<<0) /* refer to stream */
+#define CEA861_AUDIO_INFOFRAME_DB2SS_16BIT	(1<<0) /* 16 bits */
+#define CEA861_AUDIO_INFOFRAME_DB2SS_20BIT	(2<<0) /* 20 bits */
+#define CEA861_AUDIO_INFOFRAME_DB2SS_24BIT	(3<<0) /* 24 bits */
+#define CEA861_AUDIO_INFOFRAME_DB5_DM_INH	(1<<7) /* mask - inhibit downmixing */
+#define CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PERMITTED (0<<7) /* stereo downmix permitted */
+#define CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED (1<<7) /* stereo downmis prohibited */
+#define CEA861_AUDIO_INFOFRAME_DB5_LSV		(0xf<<3) /* mask - level-shift values */
+
+/*****************************************************************************
+ *                                                                           *
+ *                            MIDI v1.0 interface                            *
+ *                                                                           *
+ *****************************************************************************/
+
+#define MIDI_CHANNELS			16
+#define MIDI_GM_DRUM_CHANNEL		(10-1)
+
+/*
+ *  MIDI commands
+ */
+
+#define MIDI_CMD_NOTE_OFF		0x80
+#define MIDI_CMD_NOTE_ON		0x90
+#define MIDI_CMD_NOTE_PRESSURE		0xa0
+#define MIDI_CMD_CONTROL		0xb0
+#define MIDI_CMD_PGM_CHANGE		0xc0
+#define MIDI_CMD_CHANNEL_PRESSURE	0xd0
+#define MIDI_CMD_BENDER			0xe0
+
+#define MIDI_CMD_COMMON_SYSEX		0xf0
+#define MIDI_CMD_COMMON_MTC_QUARTER	0xf1
+#define MIDI_CMD_COMMON_SONG_POS	0xf2
+#define MIDI_CMD_COMMON_SONG_SELECT	0xf3
+#define MIDI_CMD_COMMON_TUNE_REQUEST	0xf6
+#define MIDI_CMD_COMMON_SYSEX_END	0xf7
+#define MIDI_CMD_COMMON_CLOCK		0xf8
+#define MIDI_CMD_COMMON_START		0xfa
+#define MIDI_CMD_COMMON_CONTINUE	0xfb
+#define MIDI_CMD_COMMON_STOP		0xfc
+#define MIDI_CMD_COMMON_SENSING		0xfe
+#define MIDI_CMD_COMMON_RESET		0xff
+
+/*
+ *  MIDI controllers
+ */
+
+#define MIDI_CTL_MSB_BANK		0x00
+#define MIDI_CTL_MSB_MODWHEEL         	0x01
+#define MIDI_CTL_MSB_BREATH           	0x02
+#define MIDI_CTL_MSB_FOOT             	0x04
+#define MIDI_CTL_MSB_PORTAMENTO_TIME 	0x05
+#define MIDI_CTL_MSB_DATA_ENTRY		0x06
+#define MIDI_CTL_MSB_MAIN_VOLUME      	0x07
+#define MIDI_CTL_MSB_BALANCE          	0x08
+#define MIDI_CTL_MSB_PAN              	0x0a
+#define MIDI_CTL_MSB_EXPRESSION       	0x0b
+#define MIDI_CTL_MSB_EFFECT1		0x0c
+#define MIDI_CTL_MSB_EFFECT2		0x0d
+#define MIDI_CTL_MSB_GENERAL_PURPOSE1 	0x10
+#define MIDI_CTL_MSB_GENERAL_PURPOSE2 	0x11
+#define MIDI_CTL_MSB_GENERAL_PURPOSE3 	0x12
+#define MIDI_CTL_MSB_GENERAL_PURPOSE4 	0x13
+#define MIDI_CTL_LSB_BANK		0x20
+#define MIDI_CTL_LSB_MODWHEEL        	0x21
+#define MIDI_CTL_LSB_BREATH           	0x22
+#define MIDI_CTL_LSB_FOOT             	0x24
+#define MIDI_CTL_LSB_PORTAMENTO_TIME 	0x25
+#define MIDI_CTL_LSB_DATA_ENTRY		0x26
+#define MIDI_CTL_LSB_MAIN_VOLUME      	0x27
+#define MIDI_CTL_LSB_BALANCE          	0x28
+#define MIDI_CTL_LSB_PAN              	0x2a
+#define MIDI_CTL_LSB_EXPRESSION       	0x2b
+#define MIDI_CTL_LSB_EFFECT1		0x2c
+#define MIDI_CTL_LSB_EFFECT2		0x2d
+#define MIDI_CTL_LSB_GENERAL_PURPOSE1 	0x30
+#define MIDI_CTL_LSB_GENERAL_PURPOSE2 	0x31
+#define MIDI_CTL_LSB_GENERAL_PURPOSE3 	0x32
+#define MIDI_CTL_LSB_GENERAL_PURPOSE4 	0x33
+#define MIDI_CTL_SUSTAIN              	0x40
+#define MIDI_CTL_PORTAMENTO           	0x41
+#define MIDI_CTL_SOSTENUTO            	0x42
+#define MIDI_CTL_SOFT_PEDAL           	0x43
+#define MIDI_CTL_LEGATO_FOOTSWITCH	0x44
+#define MIDI_CTL_HOLD2                	0x45
+#define MIDI_CTL_SC1_SOUND_VARIATION	0x46
+#define MIDI_CTL_SC2_TIMBRE		0x47
+#define MIDI_CTL_SC3_RELEASE_TIME	0x48
+#define MIDI_CTL_SC4_ATTACK_TIME	0x49
+#define MIDI_CTL_SC5_BRIGHTNESS		0x4a
+#define MIDI_CTL_SC6			0x4b
+#define MIDI_CTL_SC7			0x4c
+#define MIDI_CTL_SC8			0x4d
+#define MIDI_CTL_SC9			0x4e
+#define MIDI_CTL_SC10			0x4f
+#define MIDI_CTL_GENERAL_PURPOSE5     	0x50
+#define MIDI_CTL_GENERAL_PURPOSE6     	0x51
+#define MIDI_CTL_GENERAL_PURPOSE7     	0x52
+#define MIDI_CTL_GENERAL_PURPOSE8     	0x53
+#define MIDI_CTL_PORTAMENTO_CONTROL	0x54
+#define MIDI_CTL_E1_REVERB_DEPTH	0x5b
+#define MIDI_CTL_E2_TREMOLO_DEPTH	0x5c
+#define MIDI_CTL_E3_CHORUS_DEPTH	0x5d
+#define MIDI_CTL_E4_DETUNE_DEPTH	0x5e
+#define MIDI_CTL_E5_PHASER_DEPTH	0x5f
+#define MIDI_CTL_DATA_INCREMENT       	0x60
+#define MIDI_CTL_DATA_DECREMENT       	0x61
+#define MIDI_CTL_NONREG_PARM_NUM_LSB  	0x62
+#define MIDI_CTL_NONREG_PARM_NUM_MSB  	0x63
+#define MIDI_CTL_REGIST_PARM_NUM_LSB  	0x64
+#define MIDI_CTL_REGIST_PARM_NUM_MSB	0x65
+#define MIDI_CTL_ALL_SOUNDS_OFF		0x78
+#define MIDI_CTL_RESET_CONTROLLERS	0x79
+#define MIDI_CTL_LOCAL_CONTROL_SWITCH	0x7a
+#define MIDI_CTL_ALL_NOTES_OFF		0x7b
+#define MIDI_CTL_OMNI_OFF		0x7c
+#define MIDI_CTL_OMNI_ON		0x7d
+#define MIDI_CTL_MONO1			0x7e
+#define MIDI_CTL_MONO2			0x7f
+
+#endif /* __SOUND_ASOUNDEF_H */
diff --git a/include/sound/atmel-abdac.h b/include/sound/atmel-abdac.h
new file mode 100644
index 0000000..a8f735d
--- /dev/null
+++ b/include/sound/atmel-abdac.h
@@ -0,0 +1,23 @@
+/*
+ * Driver for the Atmel Audio Bitstream DAC (ABDAC)
+ *
+ * Copyright (C) 2009 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#ifndef __INCLUDE_SOUND_ATMEL_ABDAC_H
+#define __INCLUDE_SOUND_ATMEL_ABDAC_H
+
+#include <linux/platform_data/dma-dw.h>
+
+/**
+ * struct atmel_abdac_pdata - board specific ABDAC configuration
+ * @dws: DMA slave interface to use for sound playback.
+ */
+struct atmel_abdac_pdata {
+	struct dw_dma_slave	dws;
+};
+
+#endif /* __INCLUDE_SOUND_ATMEL_ABDAC_H */
diff --git a/include/sound/atmel-ac97c.h b/include/sound/atmel-ac97c.h
new file mode 100644
index 0000000..f2a1cdc
--- /dev/null
+++ b/include/sound/atmel-ac97c.h
@@ -0,0 +1,38 @@
+/*
+ * Driver for the Atmel AC97C controller
+ *
+ * Copyright (C) 2005-2009 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#ifndef __INCLUDE_SOUND_ATMEL_AC97C_H
+#define __INCLUDE_SOUND_ATMEL_AC97C_H
+
+#include <linux/platform_data/dma-dw.h>
+
+#define AC97C_CAPTURE	0x01
+#define AC97C_PLAYBACK	0x02
+#define AC97C_BOTH	(AC97C_CAPTURE | AC97C_PLAYBACK)
+
+/**
+ * struct atmel_ac97c_pdata - board specific AC97C configuration
+ * @rx_dws: DMA slave interface to use for sound capture.
+ * @tx_dws: DMA slave interface to use for sound playback.
+ * @reset_pin: GPIO pin wired to the reset input on the external AC97 codec,
+ *             optional to use, set to -ENODEV if not in use. AC97 layer will
+ *             try to do a software reset of the external codec anyway.
+ *
+ * If the user do not want to use a DMA channel for playback or capture, i.e.
+ * only one feature is required on the board. The slave for playback or capture
+ * can be set to NULL. The AC97C driver will take use of this when setting up
+ * the sound streams.
+ */
+struct ac97c_platform_data {
+	struct dw_dma_slave	rx_dws;
+	struct dw_dma_slave	tx_dws;
+	int			reset_pin;
+};
+
+#endif /* __INCLUDE_SOUND_ATMEL_AC97C_H */
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
new file mode 100644
index 0000000..fa1d055
--- /dev/null
+++ b/include/sound/compress_driver.h
@@ -0,0 +1,185 @@
+/*
+ *  compress_driver.h - compress offload driver definations
+ *
+ *  Copyright (C) 2011 Intel Corporation
+ *  Authors:	Vinod Koul <vinod.koul@linux.intel.com>
+ *		Pierre-Louis Bossart <pierre-louis.bossart@linux.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; version 2 of the License.
+ *
+ *  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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+#ifndef __COMPRESS_DRIVER_H
+#define __COMPRESS_DRIVER_H
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <sound/core.h>
+#include <sound/compress_offload.h>
+#include <sound/asound.h>
+#include <sound/pcm.h>
+
+struct snd_compr_ops;
+
+/**
+ * struct snd_compr_runtime: runtime stream description
+ * @state: stream state
+ * @ops: pointer to DSP callbacks
+ * @buffer: pointer to kernel buffer, valid only when not in mmap mode or
+ *	DSP doesn't implement copy
+ * @buffer_size: size of the above buffer
+ * @fragment_size: size of buffer fragment in bytes
+ * @fragments: number of such fragments
+ * @total_bytes_available: cumulative number of bytes made available in
+ *	the ring buffer
+ * @total_bytes_transferred: cumulative bytes transferred by offload DSP
+ * @sleep: poll sleep
+ * @private_data: driver private data pointer
+ */
+struct snd_compr_runtime {
+	snd_pcm_state_t state;
+	struct snd_compr_ops *ops;
+	void *buffer;
+	u64 buffer_size;
+	u32 fragment_size;
+	u32 fragments;
+	u64 total_bytes_available;
+	u64 total_bytes_transferred;
+	wait_queue_head_t sleep;
+	void *private_data;
+};
+
+/**
+ * struct snd_compr_stream: compressed stream
+ * @name: device name
+ * @ops: pointer to DSP callbacks
+ * @runtime: pointer to runtime structure
+ * @device: device pointer
+ * @direction: stream direction, playback/recording
+ * @metadata_set: metadata set flag, true when set
+ * @next_track: has userspace signal next track transition, true when set
+ * @private_data: pointer to DSP private data
+ */
+struct snd_compr_stream {
+	const char *name;
+	struct snd_compr_ops *ops;
+	struct snd_compr_runtime *runtime;
+	struct snd_compr *device;
+	enum snd_compr_direction direction;
+	bool metadata_set;
+	bool next_track;
+	void *private_data;
+};
+
+/**
+ * struct snd_compr_ops: compressed path DSP operations
+ * @open: Open the compressed stream
+ * This callback is mandatory and shall keep dsp ready to receive the stream
+ * parameter
+ * @free: Close the compressed stream, mandatory
+ * @set_params: Sets the compressed stream parameters, mandatory
+ * This can be called in during stream creation only to set codec params
+ * and the stream properties
+ * @get_params: retrieve the codec parameters, mandatory
+ * @set_metadata: Set the metadata values for a stream
+ * @get_metadata: retrieves the requested metadata values from stream
+ * @trigger: Trigger operations like start, pause, resume, drain, stop.
+ * This callback is mandatory
+ * @pointer: Retrieve current h/w pointer information. Mandatory
+ * @copy: Copy the compressed data to/from userspace, Optional
+ * Can't be implemented if DSP supports mmap
+ * @mmap: DSP mmap method to mmap DSP memory
+ * @ack: Ack for DSP when data is written to audio buffer, Optional
+ * Not valid if copy is implemented
+ * @get_caps: Retrieve DSP capabilities, mandatory
+ * @get_codec_caps: Retrieve capabilities for a specific codec, mandatory
+ */
+struct snd_compr_ops {
+	int (*open)(struct snd_compr_stream *stream);
+	int (*free)(struct snd_compr_stream *stream);
+	int (*set_params)(struct snd_compr_stream *stream,
+			struct snd_compr_params *params);
+	int (*get_params)(struct snd_compr_stream *stream,
+			struct snd_codec *params);
+	int (*set_metadata)(struct snd_compr_stream *stream,
+			struct snd_compr_metadata *metadata);
+	int (*get_metadata)(struct snd_compr_stream *stream,
+			struct snd_compr_metadata *metadata);
+	int (*trigger)(struct snd_compr_stream *stream, int cmd);
+	int (*pointer)(struct snd_compr_stream *stream,
+			struct snd_compr_tstamp *tstamp);
+	int (*copy)(struct snd_compr_stream *stream, char __user *buf,
+		       size_t count);
+	int (*mmap)(struct snd_compr_stream *stream,
+			struct vm_area_struct *vma);
+	int (*ack)(struct snd_compr_stream *stream, size_t bytes);
+	int (*get_caps) (struct snd_compr_stream *stream,
+			struct snd_compr_caps *caps);
+	int (*get_codec_caps) (struct snd_compr_stream *stream,
+			struct snd_compr_codec_caps *codec);
+};
+
+/**
+ * struct snd_compr: Compressed device
+ * @name: DSP device name
+ * @dev: associated device instance
+ * @ops: pointer to DSP callbacks
+ * @private_data: pointer to DSP pvt data
+ * @card: sound card pointer
+ * @direction: Playback or capture direction
+ * @lock: device lock
+ * @device: device id
+ */
+struct snd_compr {
+	const char *name;
+	struct device dev;
+	struct snd_compr_ops *ops;
+	void *private_data;
+	struct snd_card *card;
+	unsigned int direction;
+	struct mutex lock;
+	int device;
+};
+
+/* compress device register APIs */
+int snd_compress_register(struct snd_compr *device);
+int snd_compress_deregister(struct snd_compr *device);
+int snd_compress_new(struct snd_card *card, int device,
+			int type, struct snd_compr *compr);
+
+/* dsp driver callback apis
+ * For playback: driver should call snd_compress_fragment_elapsed() to let the
+ * framework know that a fragment has been consumed from the ring buffer
+ *
+ * For recording: we want to know when a frame is available or when
+ * at least one frame is available so snd_compress_frame_elapsed()
+ * callback should be called when a encodeded frame is available
+ */
+static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream)
+{
+	wake_up(&stream->runtime->sleep);
+}
+
+static inline void snd_compr_drain_notify(struct snd_compr_stream *stream)
+{
+	if (snd_BUG_ON(!stream))
+		return;
+
+	stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+	wake_up(&stream->runtime->sleep);
+}
+
+#endif
diff --git a/include/sound/control.h b/include/sound/control.h
new file mode 100644
index 0000000..21d047f
--- /dev/null
+++ b/include/sound/control.h
@@ -0,0 +1,259 @@
+#ifndef __SOUND_CONTROL_H
+#define __SOUND_CONTROL_H
+
+/*
+ *  Header file for control interface
+ *  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
+ *
+ */
+
+#include <sound/asound.h>
+
+#define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
+
+struct snd_kcontrol;
+typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo);
+typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
+typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
+typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
+				    int op_flag, /* SNDRV_CTL_TLV_OP_XXX */
+				    unsigned int size,
+				    unsigned int __user *tlv);
+
+enum {
+	SNDRV_CTL_TLV_OP_READ = 0,
+	SNDRV_CTL_TLV_OP_WRITE = 1,
+	SNDRV_CTL_TLV_OP_CMD = -1,
+};
+
+struct snd_kcontrol_new {
+	snd_ctl_elem_iface_t iface;	/* interface identifier */
+	unsigned int device;		/* device/client number */
+	unsigned int subdevice;		/* subdevice (substream) number */
+	const unsigned char *name;	/* ASCII name of item */
+	unsigned int index;		/* index of item */
+	unsigned int access;		/* access rights */
+	unsigned int count;		/* count of same elements */
+	snd_kcontrol_info_t *info;
+	snd_kcontrol_get_t *get;
+	snd_kcontrol_put_t *put;
+	union {
+		snd_kcontrol_tlv_rw_t *c;
+		const unsigned int *p;
+	} tlv;
+	unsigned long private_value;
+};
+
+struct snd_kcontrol_volatile {
+	struct snd_ctl_file *owner;	/* locked */
+	unsigned int access;	/* access rights */
+};
+
+struct snd_kcontrol {
+	struct list_head list;		/* list of controls */
+	struct snd_ctl_elem_id id;
+	unsigned int count;		/* count of same elements */
+	snd_kcontrol_info_t *info;
+	snd_kcontrol_get_t *get;
+	snd_kcontrol_put_t *put;
+	union {
+		snd_kcontrol_tlv_rw_t *c;
+		const unsigned int *p;
+	} tlv;
+	unsigned long private_value;
+	void *private_data;
+	void (*private_free)(struct snd_kcontrol *kcontrol);
+	struct snd_kcontrol_volatile vd[0];	/* volatile data */
+};
+
+#define snd_kcontrol(n) list_entry(n, struct snd_kcontrol, list)
+
+struct snd_kctl_event {
+	struct list_head list;	/* list of events */
+	struct snd_ctl_elem_id id;
+	unsigned int mask;
+};
+
+#define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
+
+struct pid;
+
+enum {
+	SND_CTL_SUBDEV_PCM,
+	SND_CTL_SUBDEV_RAWMIDI,
+	SND_CTL_SUBDEV_ITEMS,
+};
+
+struct snd_ctl_file {
+	struct list_head list;		/* list of all control files */
+	struct snd_card *card;
+	struct pid *pid;
+	int preferred_subdevice[SND_CTL_SUBDEV_ITEMS];
+	wait_queue_head_t change_sleep;
+	spinlock_t read_lock;
+	struct fasync_struct *fasync;
+	int subscribed;			/* read interface is activated */
+	struct list_head events;	/* waiting events for read */
+};
+
+#define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
+
+typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
+				      struct snd_ctl_file * control,
+				      unsigned int cmd, unsigned long arg);
+
+void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
+
+struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
+void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
+int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
+int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
+int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
+int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
+int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
+			int active);
+struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
+struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+
+int snd_ctl_create(struct snd_card *card);
+
+int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
+int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
+#ifdef CONFIG_COMPAT
+int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn);
+int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
+#else
+#define snd_ctl_register_ioctl_compat(fcn)
+#define snd_ctl_unregister_ioctl_compat(fcn)
+#endif
+
+int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
+
+static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
+{
+	return id->numid - kctl->id.numid;
+}
+
+static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
+{
+	return id->index - kctl->id.index;
+}
+
+static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
+{
+	if (id->numid) {
+		return snd_ctl_get_ioffnum(kctl, id);
+	} else {
+		return snd_ctl_get_ioffidx(kctl, id);
+	}
+}
+
+static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id *dst_id,
+						    struct snd_kcontrol *src_kctl,
+						    unsigned int offset)
+{
+	*dst_id = src_kctl->id;
+	dst_id->index += offset;
+	dst_id->numid += offset;
+	return dst_id;
+}
+
+/*
+ * Frequently used control callbacks/helpers
+ */
+int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo);
+int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo);
+int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
+		      unsigned int items, const char *const names[]);
+
+/*
+ * virtual master control
+ */
+struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
+						 const unsigned int *tlv);
+int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave,
+		       unsigned int flags);
+/* optional flags for slave */
+#define SND_CTL_SLAVE_NEED_UPDATE	(1 << 0)
+
+/**
+ * snd_ctl_add_slave - Add a virtual slave control
+ * @master: vmaster element
+ * @slave: slave element to add
+ *
+ * Add a virtual slave control to the given master element created via
+ * snd_ctl_create_virtual_master() beforehand.
+ *
+ * All slaves must be the same type (returning the same information
+ * via info callback).  The function doesn't check it, so it's your
+ * responsibility.
+ *
+ * Also, some additional limitations:
+ * at most two channels,
+ * logarithmic volume control (dB level) thus no linear volume,
+ * master can only attenuate the volume without gain
+ *
+ * Return: Zero if successful or a negative error code.
+ */
+static inline int
+snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave)
+{
+	return _snd_ctl_add_slave(master, slave, 0);
+}
+
+/**
+ * snd_ctl_add_slave_uncached - Add a virtual slave control
+ * @master: vmaster element
+ * @slave: slave element to add
+ *
+ * Add a virtual slave control to the given master.
+ * Unlike snd_ctl_add_slave(), the element added via this function
+ * is supposed to have volatile values, and get callback is called
+ * at each time queried from the master.
+ *
+ * When the control peeks the hardware values directly and the value
+ * can be changed by other means than the put callback of the element,
+ * this function should be used to keep the value always up-to-date.
+ *
+ * Return: Zero if successful or a negative error code.
+ */
+static inline int
+snd_ctl_add_slave_uncached(struct snd_kcontrol *master,
+			   struct snd_kcontrol *slave)
+{
+	return _snd_ctl_add_slave(master, slave, SND_CTL_SLAVE_NEED_UPDATE);
+}
+
+int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
+			     void (*hook)(void *private_data, int),
+			     void *private_data);
+void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
+#define snd_ctl_sync_vmaster_hook(kctl)	snd_ctl_sync_vmaster(kctl, true)
+
+/*
+ * Helper functions for jack-detection controls
+ */
+struct snd_kcontrol *
+snd_kctl_jack_new(const char *name, struct snd_card *card);
+void snd_kctl_jack_report(struct snd_card *card,
+			  struct snd_kcontrol *kctl, bool status);
+
+#endif	/* __SOUND_CONTROL_H */
diff --git a/include/sound/core.h b/include/sound/core.h
new file mode 100644
index 0000000..cdfecaf
--- /dev/null
+++ b/include/sound/core.h
@@ -0,0 +1,459 @@
+#ifndef __SOUND_CORE_H
+#define __SOUND_CORE_H
+
+/*
+ *  Main header file for the ALSA driver
+ *  Copyright (c) 1994-2001 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
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/sched.h>		/* wake_up() */
+#include <linux/mutex.h>		/* struct mutex */
+#include <linux/rwsem.h>		/* struct rw_semaphore */
+#include <linux/pm.h>			/* pm_message_t */
+#include <linux/stringify.h>
+#include <linux/printk.h>
+
+/* number of supported soundcards */
+#ifdef CONFIG_SND_DYNAMIC_MINORS
+#define SNDRV_CARDS CONFIG_SND_MAX_CARDS
+#else
+#define SNDRV_CARDS 8		/* don't change - minor numbers */
+#endif
+
+#define CONFIG_SND_MAJOR	116	/* standard configuration */
+
+/* forward declarations */
+struct pci_dev;
+struct module;
+struct completion;
+
+/* device allocation stuff */
+
+/* type of the object used in snd_device_*()
+ * this also defines the calling order
+ */
+enum snd_device_type {
+	SNDRV_DEV_LOWLEVEL,
+	SNDRV_DEV_CONTROL,
+	SNDRV_DEV_INFO,
+	SNDRV_DEV_BUS,
+	SNDRV_DEV_CODEC,
+	SNDRV_DEV_PCM,
+	SNDRV_DEV_COMPRESS,
+	SNDRV_DEV_RAWMIDI,
+	SNDRV_DEV_TIMER,
+	SNDRV_DEV_SEQUENCER,
+	SNDRV_DEV_HWDEP,
+	SNDRV_DEV_JACK,
+};
+
+enum snd_device_state {
+	SNDRV_DEV_BUILD,
+	SNDRV_DEV_REGISTERED,
+	SNDRV_DEV_DISCONNECTED,
+};
+
+struct snd_device;
+
+struct snd_device_ops {
+	int (*dev_free)(struct snd_device *dev);
+	int (*dev_register)(struct snd_device *dev);
+	int (*dev_disconnect)(struct snd_device *dev);
+};
+
+struct snd_device {
+	struct list_head list;		/* list of registered devices */
+	struct snd_card *card;		/* card which holds this device */
+	enum snd_device_state state;	/* state of the device */
+	enum snd_device_type type;	/* device type */
+	void *device_data;		/* device structure */
+	struct snd_device_ops *ops;	/* operations */
+};
+
+#define snd_device(n) list_entry(n, struct snd_device, list)
+
+/* main structure for soundcard */
+
+struct snd_card {
+	int number;			/* number of soundcard (index to
+								snd_cards) */
+
+	char id[16];			/* id string of this card */
+	char driver[16];		/* driver name */
+	char shortname[32];		/* short name of this soundcard */
+	char longname[80];		/* name of this soundcard */
+	char mixername[80];		/* mixer name */
+	char components[128];		/* card components delimited with
+								space */
+	struct module *module;		/* top-level module */
+
+	void *private_data;		/* private data for soundcard */
+	void (*private_free) (struct snd_card *card); /* callback for freeing of
+								private data */
+	struct list_head devices;	/* devices */
+
+	struct device ctl_dev;		/* control device */
+	unsigned int last_numid;	/* last used numeric ID */
+	struct rw_semaphore controls_rwsem;	/* controls list lock */
+	rwlock_t ctl_files_rwlock;	/* ctl_files list lock */
+	int controls_count;		/* count of all controls */
+	int user_ctl_count;		/* count of all user controls */
+	struct list_head controls;	/* all controls for this card */
+	struct list_head ctl_files;	/* active control files */
+	struct mutex user_ctl_lock;	/* protects user controls against
+					   concurrent access */
+
+	struct snd_info_entry *proc_root;	/* root for soundcard specific files */
+	struct snd_info_entry *proc_id;	/* the card id */
+	struct proc_dir_entry *proc_root_link;	/* number link to real id */
+
+	struct list_head files_list;	/* all files associated to this card */
+	struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown
+								state */
+	spinlock_t files_lock;		/* lock the files for this card */
+	int shutdown;			/* this card is going down */
+	struct completion *release_completion;
+	struct device *dev;		/* device assigned to this card */
+	struct device card_dev;		/* cardX object for sysfs */
+	const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
+	bool registered;		/* card_dev is registered? */
+
+#ifdef CONFIG_PM
+	unsigned int power_state;	/* power state */
+	struct mutex power_lock;	/* power lock */
+	wait_queue_head_t power_sleep;
+#endif
+
+#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+	struct snd_mixer_oss *mixer_oss;
+	int mixer_oss_change_count;
+#endif
+};
+
+#define dev_to_snd_card(p)	container_of(p, struct snd_card, card_dev)
+
+#ifdef CONFIG_PM
+static inline void snd_power_lock(struct snd_card *card)
+{
+	mutex_lock(&card->power_lock);
+}
+
+static inline void snd_power_unlock(struct snd_card *card)
+{
+	mutex_unlock(&card->power_lock);
+}
+
+static inline unsigned int snd_power_get_state(struct snd_card *card)
+{
+	return card->power_state;
+}
+
+static inline void snd_power_change_state(struct snd_card *card, unsigned int state)
+{
+	card->power_state = state;
+	wake_up(&card->power_sleep);
+}
+
+/* init.c */
+int snd_power_wait(struct snd_card *card, unsigned int power_state);
+
+#else /* ! CONFIG_PM */
+
+#define snd_power_lock(card)		do { (void)(card); } while (0)
+#define snd_power_unlock(card)		do { (void)(card); } while (0)
+static inline int snd_power_wait(struct snd_card *card, unsigned int state) { return 0; }
+#define snd_power_get_state(card)	({ (void)(card); SNDRV_CTL_POWER_D0; })
+#define snd_power_change_state(card, state)	do { (void)(card); } while (0)
+
+#endif /* CONFIG_PM */
+
+struct snd_minor {
+	int type;			/* SNDRV_DEVICE_TYPE_XXX */
+	int card;			/* card number */
+	int device;			/* device number */
+	const struct file_operations *f_ops;	/* file operations */
+	void *private_data;		/* private data for f_ops->open */
+	struct device *dev;		/* device for sysfs */
+	struct snd_card *card_ptr;	/* assigned card instance */
+};
+
+/* return a device pointer linked to each sound device as a parent */
+static inline struct device *snd_card_get_device_link(struct snd_card *card)
+{
+	return card ? &card->card_dev : NULL;
+}
+
+/* sound.c */
+
+extern int snd_major;
+extern int snd_ecards_limit;
+extern struct class *sound_class;
+
+void snd_request_card(int card);
+
+void snd_device_initialize(struct device *dev, struct snd_card *card);
+
+int snd_register_device(int type, struct snd_card *card, int dev,
+			const struct file_operations *f_ops,
+			void *private_data, struct device *device);
+int snd_unregister_device(struct device *dev);
+void *snd_lookup_minor_data(unsigned int minor, int type);
+
+#ifdef CONFIG_SND_OSSEMUL
+int snd_register_oss_device(int type, struct snd_card *card, int dev,
+			    const struct file_operations *f_ops, void *private_data);
+int snd_unregister_oss_device(int type, struct snd_card *card, int dev);
+void *snd_lookup_oss_minor_data(unsigned int minor, int type);
+#endif
+
+int snd_minor_info_init(void);
+
+/* sound_oss.c */
+
+#ifdef CONFIG_SND_OSSEMUL
+int snd_minor_info_oss_init(void);
+#else
+static inline int snd_minor_info_oss_init(void) { return 0; }
+#endif
+
+/* memory.c */
+
+int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
+int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
+
+/* init.c */
+
+extern struct snd_card *snd_cards[SNDRV_CARDS];
+int snd_card_locked(int card);
+#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+#define SND_MIXER_OSS_NOTIFY_REGISTER	0
+#define SND_MIXER_OSS_NOTIFY_DISCONNECT	1
+#define SND_MIXER_OSS_NOTIFY_FREE	2
+extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
+#endif
+
+int snd_card_new(struct device *parent, int idx, const char *xid,
+		 struct module *module, int extra_size,
+		 struct snd_card **card_ret);
+
+int snd_card_disconnect(struct snd_card *card);
+int snd_card_free(struct snd_card *card);
+int snd_card_free_when_closed(struct snd_card *card);
+void snd_card_set_id(struct snd_card *card, const char *id);
+int snd_card_register(struct snd_card *card);
+int snd_card_info_init(void);
+int snd_card_add_dev_attr(struct snd_card *card,
+			  const struct attribute_group *group);
+int snd_component_add(struct snd_card *card, const char *component);
+int snd_card_file_add(struct snd_card *card, struct file *file);
+int snd_card_file_remove(struct snd_card *card, struct file *file);
+#define snd_card_unref(card)	put_device(&(card)->card_dev)
+
+#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
+
+/* device.c */
+
+int snd_device_new(struct snd_card *card, enum snd_device_type type,
+		   void *device_data, struct snd_device_ops *ops);
+int snd_device_register(struct snd_card *card, void *device_data);
+int snd_device_register_all(struct snd_card *card);
+void snd_device_disconnect(struct snd_card *card, void *device_data);
+void snd_device_disconnect_all(struct snd_card *card);
+void snd_device_free(struct snd_card *card, void *device_data);
+void snd_device_free_all(struct snd_card *card);
+
+/* isadma.c */
+
+#ifdef CONFIG_ISA_DMA_API
+#define DMA_MODE_NO_ENABLE	0x0100
+
+void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
+void snd_dma_disable(unsigned long dma);
+unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
+#endif
+
+/* misc.c */
+struct resource;
+void release_and_free_resource(struct resource *res);
+
+/* --- */
+
+/* sound printk debug levels */
+enum {
+	SND_PR_ALWAYS,
+	SND_PR_DEBUG,
+	SND_PR_VERBOSE,
+};
+
+#if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
+__printf(4, 5)
+void __snd_printk(unsigned int level, const char *file, int line,
+		  const char *format, ...);
+#else
+#define __snd_printk(level, file, line, format, args...) \
+	printk(format, ##args)
+#endif
+
+/**
+ * snd_printk - printk wrapper
+ * @fmt: format string
+ *
+ * Works like printk() but prints the file and the line of the caller
+ * when configured with CONFIG_SND_VERBOSE_PRINTK.
+ */
+#define snd_printk(fmt, args...) \
+	__snd_printk(0, __FILE__, __LINE__, fmt, ##args)
+
+#ifdef CONFIG_SND_DEBUG
+/**
+ * snd_printd - debug printk
+ * @fmt: format string
+ *
+ * Works like snd_printk() for debugging purposes.
+ * Ignored when CONFIG_SND_DEBUG is not set.
+ */
+#define snd_printd(fmt, args...) \
+	__snd_printk(1, __FILE__, __LINE__, fmt, ##args)
+#define _snd_printd(level, fmt, args...) \
+	__snd_printk(level, __FILE__, __LINE__, fmt, ##args)
+
+/**
+ * snd_BUG - give a BUG warning message and stack trace
+ *
+ * Calls WARN() if CONFIG_SND_DEBUG is set.
+ * Ignored when CONFIG_SND_DEBUG is not set.
+ */
+#define snd_BUG()		WARN(1, "BUG?\n")
+
+/**
+ * Suppress high rates of output when CONFIG_SND_DEBUG is enabled.
+ */
+#define snd_printd_ratelimit() printk_ratelimit()
+
+/**
+ * snd_BUG_ON - debugging check macro
+ * @cond: condition to evaluate
+ *
+ * Has the same behavior as WARN_ON when CONFIG_SND_DEBUG is set,
+ * otherwise just evaluates the conditional and returns the value.
+ */
+#define snd_BUG_ON(cond)	WARN_ON((cond))
+
+#else /* !CONFIG_SND_DEBUG */
+
+__printf(1, 2)
+static inline void snd_printd(const char *format, ...) {}
+__printf(2, 3)
+static inline void _snd_printd(int level, const char *format, ...) {}
+
+#define snd_BUG()			do { } while (0)
+
+#define snd_BUG_ON(condition) ({ \
+	int __ret_warn_on = !!(condition); \
+	unlikely(__ret_warn_on); \
+})
+
+static inline bool snd_printd_ratelimit(void) { return false; }
+
+#endif /* CONFIG_SND_DEBUG */
+
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+/**
+ * snd_printdd - debug printk
+ * @format: format string
+ *
+ * Works like snd_printk() for debugging purposes.
+ * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
+ */
+#define snd_printdd(format, args...) \
+	__snd_printk(2, __FILE__, __LINE__, format, ##args)
+#else
+__printf(1, 2)
+static inline void snd_printdd(const char *format, ...) {}
+#endif
+
+
+#define SNDRV_OSS_VERSION         ((3<<16)|(8<<8)|(1<<4)|(0))	/* 3.8.1a */
+
+/* for easier backward-porting */
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
+#define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev))
+#define gameport_set_port_data(gp,r) ((gp)->port_data = (r))
+#define gameport_get_port_data(gp) (gp)->port_data
+#endif
+
+/* PCI quirk list helper */
+struct snd_pci_quirk {
+	unsigned short subvendor;	/* PCI subvendor ID */
+	unsigned short subdevice;	/* PCI subdevice ID */
+	unsigned short subdevice_mask;	/* bitmask to match */
+	int value;			/* value */
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+	const char *name;		/* name of the device (optional) */
+#endif
+};
+
+#define _SND_PCI_QUIRK_ID_MASK(vend, mask, dev)	\
+	.subvendor = (vend), .subdevice = (dev), .subdevice_mask = (mask)
+#define _SND_PCI_QUIRK_ID(vend, dev) \
+	_SND_PCI_QUIRK_ID_MASK(vend, 0xffff, dev)
+#define SND_PCI_QUIRK_ID(vend,dev) {_SND_PCI_QUIRK_ID(vend, dev)}
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+#define SND_PCI_QUIRK(vend,dev,xname,val) \
+	{_SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname)}
+#define SND_PCI_QUIRK_VENDOR(vend, xname, val)			\
+	{_SND_PCI_QUIRK_ID_MASK(vend, 0, 0), .value = (val), .name = (xname)}
+#define SND_PCI_QUIRK_MASK(vend, mask, dev, xname, val)			\
+	{_SND_PCI_QUIRK_ID_MASK(vend, mask, dev),			\
+			.value = (val), .name = (xname)}
+#define snd_pci_quirk_name(q)	((q)->name)
+#else
+#define SND_PCI_QUIRK(vend,dev,xname,val) \
+	{_SND_PCI_QUIRK_ID(vend, dev), .value = (val)}
+#define SND_PCI_QUIRK_MASK(vend, mask, dev, xname, val)			\
+	{_SND_PCI_QUIRK_ID_MASK(vend, mask, dev), .value = (val)}
+#define SND_PCI_QUIRK_VENDOR(vend, xname, val)			\
+	{_SND_PCI_QUIRK_ID_MASK(vend, 0, 0), .value = (val)}
+#define snd_pci_quirk_name(q)	""
+#endif
+
+#ifdef CONFIG_PCI
+const struct snd_pci_quirk *
+snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list);
+
+const struct snd_pci_quirk *
+snd_pci_quirk_lookup_id(u16 vendor, u16 device,
+			const struct snd_pci_quirk *list);
+#else
+static inline const struct snd_pci_quirk *
+snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
+{
+	return NULL;
+}
+
+static inline const struct snd_pci_quirk *
+snd_pci_quirk_lookup_id(u16 vendor, u16 device,
+			const struct snd_pci_quirk *list)
+{
+	return NULL;
+}
+#endif
+
+#endif /* __SOUND_CORE_H */
diff --git a/include/sound/cs4231-regs.h b/include/sound/cs4231-regs.h
new file mode 100644
index 0000000..66d28c2
--- /dev/null
+++ b/include/sound/cs4231-regs.h
@@ -0,0 +1,187 @@
+#ifndef __SOUND_CS4231_REGS_H
+#define __SOUND_CS4231_REGS_H
+
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Definitions for CS4231 & InterWave chips & compatible chips registers
+ *
+ *
+ *   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
+ *
+ */
+
+/* IO ports */
+
+#define CS4231P(x)		(c_d_c_CS4231##x)
+
+#define c_d_c_CS4231REGSEL	0
+#define c_d_c_CS4231REG		1
+#define c_d_c_CS4231STATUS	2
+#define c_d_c_CS4231PIO		3
+
+/* codec registers */
+
+#define CS4231_LEFT_INPUT	0x00	/* left input control */
+#define CS4231_RIGHT_INPUT	0x01	/* right input control */
+#define CS4231_AUX1_LEFT_INPUT	0x02	/* left AUX1 input control */
+#define CS4231_AUX1_RIGHT_INPUT	0x03	/* right AUX1 input control */
+#define CS4231_AUX2_LEFT_INPUT	0x04	/* left AUX2 input control */
+#define CS4231_AUX2_RIGHT_INPUT	0x05	/* right AUX2 input control */
+#define CS4231_LEFT_OUTPUT	0x06	/* left output control register */
+#define CS4231_RIGHT_OUTPUT	0x07	/* right output control register */
+#define CS4231_PLAYBK_FORMAT	0x08	/* clock and data format - playback - bits 7-0 MCE */
+#define CS4231_IFACE_CTRL	0x09	/* interface control - bits 7-2 MCE */
+#define CS4231_PIN_CTRL		0x0a	/* pin control */
+#define CS4231_TEST_INIT	0x0b	/* test and initialization */
+#define CS4231_MISC_INFO	0x0c	/* miscellaneous information */
+#define CS4231_LOOPBACK		0x0d	/* loopback control */
+#define CS4231_PLY_UPR_CNT	0x0e	/* playback upper base count */
+#define CS4231_PLY_LWR_CNT	0x0f	/* playback lower base count */
+#define CS4231_ALT_FEATURE_1	0x10	/* alternate #1 feature enable */
+#define AD1845_AF1_MIC_LEFT	0x10	/* alternate #1 feature + MIC left */
+#define CS4231_ALT_FEATURE_2	0x11	/* alternate #2 feature enable */
+#define AD1845_AF2_MIC_RIGHT	0x11	/* alternate #2 feature + MIC right */
+#define CS4231_LEFT_LINE_IN	0x12	/* left line input control */
+#define CS4231_RIGHT_LINE_IN	0x13	/* right line input control */
+#define CS4231_TIMER_LOW	0x14	/* timer low byte */
+#define CS4231_TIMER_HIGH	0x15	/* timer high byte */
+#define CS4231_LEFT_MIC_INPUT	0x16	/* left MIC input control register (InterWave only) */
+#define AD1845_UPR_FREQ_SEL	0x16	/* upper byte of frequency select */
+#define CS4231_RIGHT_MIC_INPUT	0x17	/* right MIC input control register (InterWave only) */
+#define AD1845_LWR_FREQ_SEL	0x17	/* lower byte of frequency select */
+#define CS4236_EXT_REG		0x17	/* extended register access */
+#define CS4231_IRQ_STATUS	0x18	/* irq status register */
+#define CS4231_LINE_LEFT_OUTPUT	0x19	/* left line output control register (InterWave only) */
+#define CS4231_VERSION		0x19	/* CS4231(A) - version values */
+#define CS4231_MONO_CTRL	0x1a	/* mono input/output control */
+#define CS4231_LINE_RIGHT_OUTPUT 0x1b	/* right line output control register (InterWave only) */
+#define AD1845_PWR_DOWN		0x1b	/* power down control */
+#define CS4235_LEFT_MASTER	0x1b	/* left master output control */
+#define CS4231_REC_FORMAT	0x1c	/* clock and data format - record - bits 7-0 MCE */
+#define AD1845_CLOCK		0x1d	/* crystal clock select and total power down */
+#define CS4235_RIGHT_MASTER	0x1d	/* right master output control */
+#define CS4231_REC_UPR_CNT	0x1e	/* record upper count */
+#define CS4231_REC_LWR_CNT	0x1f	/* record lower count */
+
+/* definitions for codec register select port - CODECP( REGSEL ) */
+
+#define CS4231_INIT		0x80	/* CODEC is initializing */
+#define CS4231_MCE		0x40	/* mode change enable */
+#define CS4231_TRD		0x20	/* transfer request disable */
+
+/* definitions for codec status register - CODECP( STATUS ) */
+
+#define CS4231_GLOBALIRQ	0x01	/* IRQ is active */
+
+/* definitions for codec irq status */
+
+#define CS4231_PLAYBACK_IRQ	0x10
+#define CS4231_RECORD_IRQ	0x20
+#define CS4231_TIMER_IRQ	0x40
+#define CS4231_ALL_IRQS		0x70
+#define CS4231_REC_UNDERRUN	0x08
+#define CS4231_REC_OVERRUN	0x04
+#define CS4231_PLY_OVERRUN	0x02
+#define CS4231_PLY_UNDERRUN	0x01
+
+/* definitions for CS4231_LEFT_INPUT and CS4231_RIGHT_INPUT registers */
+
+#define CS4231_ENABLE_MIC_GAIN	0x20
+
+#define CS4231_MIXS_LINE	0x00
+#define CS4231_MIXS_AUX1	0x40
+#define CS4231_MIXS_MIC		0x80
+#define CS4231_MIXS_ALL		0xc0
+
+/* definitions for clock and data format register - CS4231_PLAYBK_FORMAT */
+
+#define CS4231_LINEAR_8		0x00	/* 8-bit unsigned data */
+#define CS4231_ALAW_8		0x60	/* 8-bit A-law companded */
+#define CS4231_ULAW_8		0x20	/* 8-bit U-law companded */
+#define CS4231_LINEAR_16	0x40	/* 16-bit twos complement data - little endian */
+#define CS4231_LINEAR_16_BIG	0xc0	/* 16-bit twos complement data - big endian */
+#define CS4231_ADPCM_16		0xa0	/* 16-bit ADPCM */
+#define CS4231_STEREO		0x10	/* stereo mode */
+/* bits 3-1 define frequency divisor */
+#define CS4231_XTAL1		0x00	/* 24.576 crystal */
+#define CS4231_XTAL2		0x01	/* 16.9344 crystal */
+
+/* definitions for interface control register - CS4231_IFACE_CTRL */
+
+#define CS4231_RECORD_PIO	0x80	/* record PIO enable */
+#define CS4231_PLAYBACK_PIO	0x40	/* playback PIO enable */
+#define CS4231_CALIB_MODE	0x18	/* calibration mode bits */
+#define CS4231_AUTOCALIB	0x08	/* auto calibrate */
+#define CS4231_SINGLE_DMA	0x04	/* use single DMA channel */
+#define CS4231_RECORD_ENABLE	0x02	/* record enable */
+#define CS4231_PLAYBACK_ENABLE	0x01	/* playback enable */
+
+/* definitions for pin control register - CS4231_PIN_CTRL */
+
+#define CS4231_IRQ_ENABLE	0x02	/* enable IRQ */
+#define CS4231_XCTL1		0x40	/* external control #1 */
+#define CS4231_XCTL0		0x80	/* external control #0 */
+
+/* definitions for test and init register - CS4231_TEST_INIT */
+
+#define CS4231_CALIB_IN_PROGRESS 0x20	/* auto calibrate in progress */
+#define CS4231_DMA_REQUEST	0x10	/* DMA request in progress */
+
+/* definitions for misc control register - CS4231_MISC_INFO */
+
+#define CS4231_MODE2		0x40	/* MODE 2 */
+#define CS4231_IW_MODE3		0x6c	/* MODE 3 - InterWave enhanced mode */
+#define CS4231_4236_MODE3	0xe0	/* MODE 3 - CS4236+ enhanced mode */
+
+/* definitions for alternate feature 1 register - CS4231_ALT_FEATURE_1 */
+
+#define	CS4231_DACZ		0x01	/* zero DAC when underrun */
+#define CS4231_TIMER_ENABLE	0x40	/* codec timer enable */
+#define CS4231_OLB		0x80	/* output level bit */
+
+/* definitions for Extended Registers - CS4236+ */
+
+#define CS4236_REG(i23val)	(((i23val << 2) & 0x10) | ((i23val >> 4) & 0x0f))
+#define CS4236_I23VAL(reg)	((((reg)&0xf) << 4) | (((reg)&0x10) >> 2) | 0x8)
+
+#define CS4236_LEFT_LINE	0x08	/* left LINE alternate volume */
+#define CS4236_RIGHT_LINE	0x18	/* right LINE alternate volume */
+#define CS4236_LEFT_MIC		0x28	/* left MIC volume */
+#define CS4236_RIGHT_MIC	0x38	/* right MIC volume */
+#define CS4236_LEFT_MIX_CTRL	0x48	/* synthesis and left input mixer control */
+#define CS4236_RIGHT_MIX_CTRL	0x58	/* right input mixer control */
+#define CS4236_LEFT_FM		0x68	/* left FM volume */
+#define CS4236_RIGHT_FM		0x78	/* right FM volume */
+#define CS4236_LEFT_DSP		0x88	/* left DSP serial port volume */
+#define CS4236_RIGHT_DSP	0x98	/* right DSP serial port volume */
+#define CS4236_RIGHT_LOOPBACK	0xa8	/* right loopback monitor volume */
+#define CS4236_DAC_MUTE		0xb8	/* DAC mute and IFSE enable */
+#define CS4236_ADC_RATE		0xc8	/* indenpendent ADC sample frequency */
+#define CS4236_DAC_RATE		0xd8	/* indenpendent DAC sample frequency */
+#define CS4236_LEFT_MASTER	0xe8	/* left master digital audio volume */
+#define CS4236_RIGHT_MASTER	0xf8	/* right master digital audio volume */
+#define CS4236_LEFT_WAVE	0x0c	/* left wavetable serial port volume */
+#define CS4236_RIGHT_WAVE	0x1c	/* right wavetable serial port volume */
+#define CS4236_VERSION		0x9c	/* chip version and ID */
+
+/* definitions for extended registers - OPTI93X */
+#define OPTi931_AUX_LEFT_INPUT	0x10
+#define OPTi931_AUX_RIGHT_INPUT	0x11
+#define OPTi93X_MIC_LEFT_INPUT	0x14
+#define OPTi93X_MIC_RIGHT_INPUT	0x15
+#define OPTi93X_OUT_LEFT	0x16
+#define OPTi93X_OUT_RIGHT	0x17
+
+#endif /* __SOUND_CS4231_REGS_H */
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h
new file mode 100644
index 0000000..70f4535
--- /dev/null
+++ b/include/sound/cs4271.h
@@ -0,0 +1,40 @@
+/*
+ * Definitions for CS4271 ASoC codec driver
+ *
+ * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
+ *
+ * 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.
+ */
+
+#ifndef __CS4271_H
+#define __CS4271_H
+
+struct cs4271_platform_data {
+	int gpio_nreset;	/* GPIO driving Reset pin, if any */
+	bool amutec_eq_bmutec;	/* flag to enable AMUTEC=BMUTEC */
+
+	/*
+	 * The CS4271 requires its LRCLK and MCLK to be stable before its RESET
+	 * line is de-asserted. That also means that clocks cannot be changed
+	 * without putting the chip back into hardware reset, which also requires
+	 * a complete re-initialization of all registers.
+	 *
+	 * One (undocumented) workaround is to assert and de-assert the PDN bit
+	 * in the MODE2 register. This workaround can be enabled with the
+	 * following flag.
+	 *
+	 * Note that this is not needed in case the clocks are stable
+	 * throughout the entire runtime of the codec.
+	 */
+	bool enable_soft_reset;
+};
+
+#endif /* __CS4271_H */
diff --git a/include/sound/cs42l52.h b/include/sound/cs42l52.h
new file mode 100644
index 0000000..bbabf84
--- /dev/null
+++ b/include/sound/cs42l52.h
@@ -0,0 +1,32 @@
+/*
+ * linux/sound/cs42l52.h -- Platform data for CS42L52
+ *
+ * Copyright (c) 2012 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CS42L52_H
+#define __CS42L52_H
+
+struct cs42l52_platform_data {
+
+	/* MICBIAS Level. Check datasheet Pg48 */
+	unsigned int micbias_lvl;
+
+	/* MICA mode selection Differential or Single-ended */
+	bool mica_diff_cfg;
+
+	/* MICB mode selection Differential or Single-ended */
+	bool micb_diff_cfg;
+
+	/* Charge Pump Freq. Check datasheet Pg73 */
+	unsigned int chgfreq;
+
+	/* Reset GPIO */
+	unsigned int reset_gpio;
+};
+
+#endif /* __CS42L52_H */
diff --git a/include/sound/cs42l56.h b/include/sound/cs42l56.h
new file mode 100644
index 0000000..2467c8f
--- /dev/null
+++ b/include/sound/cs42l56.h
@@ -0,0 +1,48 @@
+/*
+ * linux/sound/cs42l56.h -- Platform data for CS42L56
+ *
+ * Copyright (c) 2014 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CS42L56_H
+#define __CS42L56_H
+
+struct cs42l56_platform_data {
+
+	/* GPIO for Reset */
+	unsigned int gpio_nreset;
+
+	/* MICBIAS Level. Check datasheet Pg48 */
+	unsigned int micbias_lvl;
+
+	/* Analog Input 1A Reference 0=Single 1=Pseudo-Differential */
+	unsigned int ain1a_ref_cfg;
+
+	/* Analog Input 2A Reference 0=Single 1=Pseudo-Differential */
+	unsigned int ain2a_ref_cfg;
+
+	/* Analog Input 1B Reference 0=Single 1=Pseudo-Differential */
+	unsigned int ain1b_ref_cfg;
+
+	/* Analog Input 2B Reference 0=Single 1=Pseudo-Differential */
+	unsigned int ain2b_ref_cfg;
+
+	/* Charge Pump Freq. Check datasheet Pg62 */
+	unsigned int chgfreq;
+
+	/* HighPass Filter Right Channel Corner Frequency */
+	unsigned int hpfb_freq;
+
+	/* HighPass Filter Left Channel Corner Frequency */
+	unsigned int hpfa_freq;
+
+	/* Adaptive Power Control for LO/HP */
+	unsigned int adaptive_pwr;
+
+};
+
+#endif /* __CS42L56_H */
diff --git a/include/sound/cs42l73.h b/include/sound/cs42l73.h
new file mode 100644
index 0000000..f354be4
--- /dev/null
+++ b/include/sound/cs42l73.h
@@ -0,0 +1,22 @@
+/*
+ * linux/sound/cs42l73.h -- Platform data for CS42L73
+ *
+ * Copyright (c) 2012 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CS42L73_H
+#define __CS42L73_H
+
+struct cs42l73_platform_data {
+	/* RST GPIO */
+	unsigned int reset_gpio;
+	unsigned int chgfreq;
+	int jack_detection;
+	unsigned int mclk_freq;
+};
+
+#endif /* __CS42L73_H */
diff --git a/include/sound/cs8403.h b/include/sound/cs8403.h
new file mode 100644
index 0000000..3a8c174
--- /dev/null
+++ b/include/sound/cs8403.h
@@ -0,0 +1,257 @@
+#ifndef __SOUND_CS8403_H
+#define __SOUND_CS8403_H
+
+/*
+ *  Routines for Cirrus Logic CS8403/CS8404A IEC958 (S/PDIF) Transmitter
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *		     Takashi Iwai <tiwai@suse.de>
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#ifdef SND_CS8403
+
+#ifndef SND_CS8403_DECL
+#define SND_CS8403_DECL static
+#endif
+#ifndef SND_CS8403_DECODE
+#define SND_CS8403_DECODE snd_cs8403_decode_spdif_bits
+#endif
+#ifndef SND_CS8403_ENCODE
+#define SND_CS8403_ENCODE snd_cs8403_encode_spdif_bits
+#endif
+
+
+SND_CS8403_DECL void SND_CS8403_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
+{
+	if (bits & 0x01) {	/* consumer */
+		if (!(bits & 0x02))
+			diga->status[0] |= IEC958_AES0_NONAUDIO;
+		if (!(bits & 0x08))
+			diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
+		switch (bits & 0x10) {
+		case 0x10: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; break;
+		case 0x00: diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015; break;
+		}
+		if (!(bits & 0x80))
+			diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
+		switch (bits & 0x60) {
+		case 0x00: diga->status[1] |= IEC958_AES1_CON_MAGNETIC_ID; break;
+		case 0x20: diga->status[1] |= IEC958_AES1_CON_DIGDIGCONV_ID; break;
+		case 0x40: diga->status[1] |= IEC958_AES1_CON_LASEROPT_ID; break;
+		case 0x60: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
+		}
+		switch (bits & 0x06) {
+		case 0x00: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
+		case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
+		case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
+		}
+	} else {
+		diga->status[0] = IEC958_AES0_PROFESSIONAL;
+		switch (bits & 0x18) {
+		case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
+		case 0x10: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
+		case 0x08: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
+		case 0x18: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
+		}
+		switch (bits & 0x60) {
+		case 0x20: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
+		case 0x40: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
+		case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
+		case 0x60: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
+		}
+		if (bits & 0x80)
+			diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
+	}
+}
+
+SND_CS8403_DECL unsigned char SND_CS8403_ENCODE(struct snd_aes_iec958 *diga)
+{
+	unsigned char bits;
+
+	if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
+		bits = 0x01;	/* consumer mode */
+		if (diga->status[0] & IEC958_AES0_NONAUDIO)
+			bits &= ~0x02;
+		else
+			bits |= 0x02;
+		if (diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT)
+			bits &= ~0x08;
+		else
+			bits |= 0x08;
+		switch (diga->status[0] & IEC958_AES0_CON_EMPHASIS) {
+		default:
+		case IEC958_AES0_CON_EMPHASIS_NONE: bits |= 0x10; break;
+		case IEC958_AES0_CON_EMPHASIS_5015: bits |= 0x00; break;
+		}
+		if (diga->status[1] & IEC958_AES1_CON_ORIGINAL)
+			bits &= ~0x80;
+		else
+			bits |= 0x80;
+		if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
+			bits |= 0x60;
+		else {
+			switch(diga->status[1] & IEC958_AES1_CON_MAGNETIC_MASK) {
+			case IEC958_AES1_CON_MAGNETIC_ID:
+				bits |= 0x00; break;
+			case IEC958_AES1_CON_DIGDIGCONV_ID:
+				bits |= 0x20; break;
+			default:
+			case IEC958_AES1_CON_LASEROPT_ID:
+				bits |= 0x40; break;
+			}
+		}
+		switch (diga->status[3] & IEC958_AES3_CON_FS) {
+		default:
+		case IEC958_AES3_CON_FS_44100: bits |= 0x00; break;
+		case IEC958_AES3_CON_FS_48000: bits |= 0x02; break;
+		case IEC958_AES3_CON_FS_32000: bits |= 0x04; break;
+		}
+	} else {
+		bits = 0x00;	/* professional mode */
+		if (diga->status[0] & IEC958_AES0_NONAUDIO)
+			bits &= ~0x02;
+		else
+			bits |= 0x02;
+		/* CHECKME: I'm not sure about the bit order in val here */
+		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+		case IEC958_AES0_PRO_FS_32000:	bits |= 0x00; break;
+		case IEC958_AES0_PRO_FS_44100:	bits |= 0x10; break;	/* 44.1kHz */
+		case IEC958_AES0_PRO_FS_48000:	bits |= 0x08; break;	/* 48kHz */
+		default:
+		case IEC958_AES0_PRO_FS_NOTID: bits |= 0x18; break;
+		}
+		switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
+		case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x20; break;
+		case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x40; break;
+		case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
+		default:
+		case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x60; break;
+		}
+		switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
+		case IEC958_AES1_PRO_MODE_TWO:
+		case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
+		default: bits |= 0x80; break;
+		}
+	}
+	return bits;
+}
+
+#endif /* SND_CS8403 */
+
+#ifdef SND_CS8404
+
+#ifndef SND_CS8404_DECL
+#define SND_CS8404_DECL static
+#endif
+#ifndef SND_CS8404_DECODE
+#define SND_CS8404_DECODE snd_cs8404_decode_spdif_bits
+#endif
+#ifndef SND_CS8404_ENCODE
+#define SND_CS8404_ENCODE snd_cs8404_encode_spdif_bits
+#endif
+
+
+SND_CS8404_DECL void SND_CS8404_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
+{
+	if (bits & 0x10) {	/* consumer */
+		if (!(bits & 0x20))
+			diga->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
+		if (!(bits & 0x40))
+			diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
+		if (!(bits & 0x80))
+			diga->status[1] |= IEC958_AES1_CON_ORIGINAL;
+		switch (bits & 0x03) {
+		case 0x00: diga->status[1] |= IEC958_AES1_CON_DAT; break;
+		case 0x03: diga->status[1] |= IEC958_AES1_CON_GENERAL; break;
+		}
+		switch (bits & 0x06) {
+		case 0x02: diga->status[3] |= IEC958_AES3_CON_FS_32000; break;
+		case 0x04: diga->status[3] |= IEC958_AES3_CON_FS_48000; break;
+		case 0x06: diga->status[3] |= IEC958_AES3_CON_FS_44100; break;
+		}
+	} else {
+		diga->status[0] = IEC958_AES0_PROFESSIONAL;
+		if (!(bits & 0x04))
+			diga->status[0] |= IEC958_AES0_NONAUDIO;
+		switch (bits & 0x60) {
+		case 0x00: diga->status[0] |= IEC958_AES0_PRO_FS_32000; break;
+		case 0x40: diga->status[0] |= IEC958_AES0_PRO_FS_44100; break;
+		case 0x20: diga->status[0] |= IEC958_AES0_PRO_FS_48000; break;
+		case 0x60: diga->status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
+		}
+		switch (bits & 0x03) {
+		case 0x02: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NONE; break;
+		case 0x01: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015; break;
+		case 0x00: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_CCITT; break;
+		case 0x03: diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_NOTID; break;
+		}
+		if (!(bits & 0x80))
+			diga->status[1] |= IEC958_AES1_PRO_MODE_STEREOPHONIC;
+	}
+}
+
+SND_CS8404_DECL unsigned char SND_CS8404_ENCODE(struct snd_aes_iec958 *diga)
+{
+	unsigned char bits;
+
+	if (!(diga->status[0] & IEC958_AES0_PROFESSIONAL)) {
+		bits = 0x10;	/* consumer mode */
+		if (!(diga->status[0] & IEC958_AES0_CON_NOT_COPYRIGHT))
+			bits |= 0x20;
+		if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_NONE)
+			bits |= 0x40;
+		if (!(diga->status[1] & IEC958_AES1_CON_ORIGINAL))
+			bits |= 0x80;
+		if ((diga->status[1] & IEC958_AES1_CON_CATEGORY) == IEC958_AES1_CON_GENERAL)
+			bits |= 0x03;
+		switch (diga->status[3] & IEC958_AES3_CON_FS) {
+		default:
+		case IEC958_AES3_CON_FS_44100: bits |= 0x06; break;
+		case IEC958_AES3_CON_FS_48000: bits |= 0x04; break;
+		case IEC958_AES3_CON_FS_32000: bits |= 0x02; break;
+		}
+	} else {
+		bits = 0x00;	/* professional mode */
+		if (!(diga->status[0] & IEC958_AES0_NONAUDIO))
+			bits |= 0x04;
+		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+		case IEC958_AES0_PRO_FS_32000:	bits |= 0x00; break;
+		case IEC958_AES0_PRO_FS_44100:	bits |= 0x40; break;	/* 44.1kHz */
+		case IEC958_AES0_PRO_FS_48000:	bits |= 0x20; break;	/* 48kHz */
+		default:
+		case IEC958_AES0_PRO_FS_NOTID:	bits |= 0x00; break;
+		}
+		switch (diga->status[0] & IEC958_AES0_PRO_EMPHASIS) {
+		case IEC958_AES0_PRO_EMPHASIS_NONE: bits |= 0x02; break;
+		case IEC958_AES0_PRO_EMPHASIS_5015: bits |= 0x01; break;
+		case IEC958_AES0_PRO_EMPHASIS_CCITT: bits |= 0x00; break;
+		default:
+		case IEC958_AES0_PRO_EMPHASIS_NOTID: bits |= 0x03; break;
+		}
+		switch (diga->status[1] & IEC958_AES1_PRO_MODE) {
+		case IEC958_AES1_PRO_MODE_TWO:
+		case IEC958_AES1_PRO_MODE_STEREOPHONIC: bits |= 0x00; break;
+		default: bits |= 0x80; break;
+		}
+	}
+	return bits;
+}
+
+#endif /* SND_CS8404 */
+
+#endif /* __SOUND_CS8403_H */
diff --git a/include/sound/cs8427.h b/include/sound/cs8427.h
new file mode 100644
index 0000000..0b6a187
--- /dev/null
+++ b/include/sound/cs8427.h
@@ -0,0 +1,202 @@
+#ifndef __SOUND_CS8427_H
+#define __SOUND_CS8427_H
+
+/*
+ *  Routines for Cirrus Logic CS8427
+ *  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
+ *
+ */
+
+#include <sound/i2c.h>
+
+#define CS8427_BASE_ADDR	0x10	/* base I2C address */
+
+#define CS8427_REG_AUTOINC	0x80	/* flag - autoincrement */
+#define CS8427_REG_CONTROL1	0x01
+#define CS8427_REG_CONTROL2	0x02
+#define CS8427_REG_DATAFLOW	0x03
+#define CS8427_REG_CLOCKSOURCE	0x04
+#define CS8427_REG_SERIALINPUT	0x05
+#define CS8427_REG_SERIALOUTPUT	0x06
+#define CS8427_REG_INT1STATUS	0x07
+#define CS8427_REG_INT2STATUS	0x08
+#define CS8427_REG_INT1MASK	0x09
+#define CS8427_REG_INT1MODEMSB	0x0a
+#define CS8427_REG_INT1MODELSB	0x0b
+#define CS8427_REG_INT2MASK	0x0c
+#define CS8427_REG_INT2MODEMSB	0x0d
+#define CS8427_REG_INT2MODELSB	0x0e
+#define CS8427_REG_RECVCSDATA	0x0f
+#define CS8427_REG_RECVERRORS	0x10
+#define CS8427_REG_RECVERRMASK	0x11
+#define CS8427_REG_CSDATABUF	0x12
+#define CS8427_REG_UDATABUF	0x13
+#define CS8427_REG_QSUBCODE	0x14	/* 0x14-0x1d (10 bytes) */
+#define CS8427_REG_OMCKRMCKRATIO 0x1e
+#define CS8427_REG_CORU_DATABUF	0x20	/* 24 byte buffer area */
+#define CS8427_REG_ID_AND_VER	0x7f
+
+/* CS8427_REG_CONTROL1 bits */
+#define CS8427_SWCLK		(1<<7)	/* 0 = RMCK default, 1 = OMCK output on RMCK pin */
+#define CS8427_VSET		(1<<6)	/* 0 = valid PCM data, 1 = invalid PCM data */
+#define CS8427_MUTESAO		(1<<5)	/* mute control for the serial audio output port, 0 = disabled, 1 = enabled */
+#define CS8427_MUTEAES		(1<<4)	/* mute control for the AES transmitter output, 0 = disabled, 1 = enabled */
+#define CS8427_INTMASK		(3<<1)	/* interrupt output pin setup mask */
+#define CS8427_INTACTHIGH	(0<<1)	/* active high */
+#define CS8427_INTACTLOW	(1<<1)	/* active low */
+#define CS8427_INTOPENDRAIN	(2<<1)	/* open drain, active low */
+#define CS8427_TCBLDIR		(1<<0)	/* 0 = TCBL is an input, 1 = TCBL is an output */
+
+/* CS8427_REQ_CONTROL2 bits */
+#define CS8427_HOLDMASK		(3<<5)	/* action when a receiver error occurs */
+#define CS8427_HOLDLASTSAMPLE	(0<<5)	/* hold the last valid sample */
+#define CS8427_HOLDZERO		(1<<5)	/* replace the current audio sample with zero (mute) */
+#define CS8427_HOLDNOCHANGE	(2<<5)	/* do not change the received audio sample */
+#define CS8427_RMCKF		(1<<4)	/* 0 = 256*Fsi, 1 = 128*Fsi */
+#define CS8427_MMR		(1<<3)	/* AES3 receiver operation, 0 = stereo, 1 = mono */
+#define CS8427_MMT		(1<<2)	/* AES3 transmitter operation, 0 = stereo, 1 = mono */
+#define CS8427_MMTCS		(1<<1)	/* 0 = use A + B CS data, 1 = use MMTLR CS data */
+#define CS8427_MMTLR		(1<<0)	/* 0 = use A CS data, 1 = use B CS data */
+
+/* CS8427_REG_DATAFLOW */
+#define CS8427_TXOFF		(1<<6)	/* AES3 transmitter Output, 0 = normal operation, 1 = off (0V) */
+#define CS8427_AESBP		(1<<5)	/* AES3 hardware bypass mode, 0 = normal, 1 = bypass (RX->TX) */
+#define CS8427_TXDMASK		(3<<3)	/* AES3 Transmitter Data Source Mask */
+#define CS8427_TXDSERIAL	(1<<3)	/* TXD - serial audio input port */
+#define CS8427_TXAES3DRECEIVER	(2<<3)	/* TXD - AES3 receiver */
+#define CS8427_SPDMASK		(3<<1)	/* Serial Audio Output Port Data Source Mask */
+#define CS8427_SPDSERIAL	(1<<1)	/* SPD - serial audio input port */
+#define CS8427_SPDAES3RECEIVER	(2<<1)	/* SPD - AES3 receiver */
+
+/* CS8427_REG_CLOCKSOURCE */
+#define CS8427_RUN		(1<<6)	/* 0 = clock off, 1 = clock on */
+#define CS8427_CLKMASK		(3<<4)	/* OMCK frequency mask */
+#define CS8427_CLK256		(0<<4)	/* 256*Fso */
+#define CS8427_CLK384		(1<<4)	/* 384*Fso */
+#define CS8427_CLK512		(2<<4)	/* 512*Fso */
+#define CS8427_OUTC		(1<<3)	/* Output Time Base, 0 = OMCK, 1 = recovered input clock */
+#define CS8427_INC		(1<<2)	/* Input Time Base Clock Source, 0 = recoverd input clock, 1 = OMCK input pin */
+#define CS8427_RXDMASK		(3<<0)	/* Recovered Input Clock Source Mask */
+#define CS8427_RXDILRCK		(0<<0)	/* 256*Fsi from ILRCK pin */
+#define CS8427_RXDAES3INPUT	(1<<0)	/* 256*Fsi from AES3 input */
+#define CS8427_EXTCLOCKRESET	(2<<0)	/* bypass PLL, 256*Fsi clock, synchronous reset */
+#define CS8427_EXTCLOCK		(3<<0)	/* bypass PLL, 256*Fsi clock */
+
+/* CS8427_REG_SERIALINPUT */
+#define CS8427_SIMS		(1<<7)	/* 0 = slave, 1 = master mode */
+#define CS8427_SISF		(1<<6)	/* ISCLK freq, 0 = 64*Fsi, 1 = 128*Fsi */
+#define CS8427_SIRESMASK	(3<<4)	/* Resolution of the input data for right justified formats */
+#define CS8427_SIRES24		(0<<4)	/* SIRES 24-bit */
+#define CS8427_SIRES20		(1<<4)	/* SIRES 20-bit */
+#define CS8427_SIRES16		(2<<4)	/* SIRES 16-bit */
+#define CS8427_SIJUST		(1<<3)	/* Justification of SDIN data relative to ILRCK, 0 = left-justified, 1 = right-justified */
+#define CS8427_SIDEL		(1<<2)	/* Delay of SDIN data relative to ILRCK for left-justified data formats, 0 = first ISCLK period, 1 = second ISCLK period */
+#define CS8427_SISPOL		(1<<1)	/* ICLK clock polarity, 0 = rising edge of ISCLK, 1 = falling edge of ISCLK */
+#define CS8427_SILRPOL		(1<<0)	/* ILRCK clock polarity, 0 = SDIN data left channel when ILRCK is high, 1 = SDIN right when ILRCK is high */
+
+/* CS8427_REG_SERIALOUTPUT */
+#define CS8427_SOMS		(1<<7)	/* 0 = slave, 1 = master mode */
+#define CS8427_SOSF		(1<<6)	/* OSCLK freq, 0 = 64*Fso, 1 = 128*Fso */
+#define CS8427_SORESMASK	(3<<4)	/* Resolution of the output data on SDOUT and AES3 output */
+#define CS8427_SORES24		(0<<4)	/* SIRES 24-bit */
+#define CS8427_SORES20		(1<<4)	/* SIRES 20-bit */
+#define CS8427_SORES16		(2<<4)	/* SIRES 16-bit */
+#define CS8427_SORESDIRECT	(2<<4)	/* SIRES direct copy from AES3 receiver */
+#define CS8427_SOJUST		(1<<3)	/* Justification of SDOUT data relative to OLRCK, 0 = left-justified, 1 = right-justified */
+#define CS8427_SODEL		(1<<2)	/* Delay of SDOUT data relative to OLRCK for left-justified data formats, 0 = first OSCLK period, 1 = second OSCLK period */
+#define CS8427_SOSPOL		(1<<1)	/* OSCLK clock polarity, 0 = rising edge of ISCLK, 1 = falling edge of ISCLK */
+#define CS8427_SOLRPOL		(1<<0)	/* OLRCK clock polarity, 0 = SDOUT data left channel when OLRCK is high, 1 = SDOUT right when OLRCK is high */
+
+/* CS8427_REG_INT1STATUS */
+#define CS8427_TSLIP		(1<<7)	/* AES3 transmitter source data slip interrupt */
+#define CS8427_OSLIP		(1<<6)	/* Serial audio output port data slip interrupt */
+#define CS8427_DETC		(1<<2)	/* D to E C-buffer transfer interrupt */
+#define CS8427_EFTC		(1<<1)	/* E to F C-buffer transfer interrupt */
+#define CS8427_RERR		(1<<0)	/* A receiver error has occurred */
+
+/* CS8427_REG_INT2STATUS */
+#define CS8427_DETU		(1<<3)	/* D to E U-buffer transfer interrupt */
+#define CS8427_EFTU		(1<<2)	/* E to F U-buffer transfer interrupt */
+#define CS8427_QCH		(1<<1)	/* A new block of Q-subcode data is available for reading */
+
+/* CS8427_REG_INT1MODEMSB && CS8427_REG_INT1MODELSB */
+/* bits are defined in CS8427_REG_INT1STATUS */
+/* CS8427_REG_INT2MODEMSB && CS8427_REG_INT2MODELSB */
+/* bits are defined in CS8427_REG_INT2STATUS */
+#define CS8427_INTMODERISINGMSB	0
+#define CS8427_INTMODERESINGLSB	0
+#define CS8427_INTMODEFALLINGMSB 0
+#define CS8427_INTMODEFALLINGLSB 1
+#define CS8427_INTMODELEVELMSB	1
+#define CS8427_INTMODELEVELLSB	0
+
+/* CS8427_REG_RECVCSDATA */
+#define CS8427_AUXMASK		(15<<4)	/* auxiliary data field width */
+#define CS8427_AUXSHIFT		4
+#define CS8427_PRO		(1<<3)	/* Channel status block format indicator */
+#define CS8427_AUDIO		(1<<2)	/* Audio indicator (0 = audio, 1 = nonaudio */
+#define CS8427_COPY		(1<<1)	/* 0 = copyright asserted, 1 = copyright not asserted */
+#define CS8427_ORIG		(1<<0)	/* SCMS generation indicator, 0 = 1st generation or highter, 1 = original */
+
+/* CS8427_REG_RECVERRORS */
+/* CS8427_REG_RECVERRMASK for CS8427_RERR */
+#define CS8427_QCRC		(1<<6)	/* Q-subcode data CRC error indicator */
+#define CS8427_CCRC		(1<<5)	/* Chancnel Status Block Cyclick Redundancy Check Bit */
+#define CS8427_UNLOCK		(1<<4)	/* PLL lock status bit */
+#define CS8427_V		(1<<3)	/* 0 = valid data */
+#define CS8427_CONF		(1<<2)	/* Confidence bit */
+#define CS8427_BIP		(1<<1)	/* Bi-phase error bit */
+#define CS8427_PAR		(1<<0)	/* Parity error */
+
+/* CS8427_REG_CSDATABUF	*/
+#define CS8427_BSEL		(1<<5)	/* 0 = CS data, 1 = U data */
+#define CS8427_CBMR		(1<<4)	/* 0 = overwrite first 5 bytes for CS D to E buffer, 1 = prevent */
+#define CS8427_DETCI		(1<<3)	/* D to E CS data buffer transfer inhibit bit, 0 = allow, 1 = inhibit */
+#define CS8427_EFTCI		(1<<2)	/* E to F CS data buffer transfer inhibit bit, 0 = allow, 1 = inhibit */
+#define CS8427_CAM		(1<<1)	/* CS data buffer control port access mode bit, 0 = one byte, 1 = two byte */
+#define CS8427_CHS		(1<<0)	/* Channel select bit, 0 = Channel A, 1 = Channel B */
+
+/* CS8427_REG_UDATABUF */
+#define CS8427_UD		(1<<4)	/* User data pin (U) direction, 0 = input, 1 = output */
+#define CS8427_UBMMASK		(3<<2)	/* Operating mode of the AES3 U bit manager */
+#define CS8427_UBMZEROS		(0<<2)	/* transmit all zeros mode */
+#define CS8427_UBMBLOCK		(1<<2)	/* block mode */
+#define CS8427_DETUI		(1<<1)	/* D to E U-data buffer transfer inhibit bit, 0 = allow, 1 = inhibit */
+#define CS8427_EFTUI		(1<<1)	/* E to F U-data buffer transfer inhibit bit, 0 = allow, 1 = inhibit */
+
+/* CS8427_REG_ID_AND_VER */
+#define CS8427_IDMASK		(15<<4)
+#define CS8427_IDSHIFT		4
+#define CS8427_VERMASK		(15<<0)
+#define CS8427_VERSHIFT		0
+#define CS8427_VER8427A		0x71
+
+struct snd_pcm_substream;
+
+int snd_cs8427_init(struct snd_i2c_bus *bus, struct snd_i2c_device *device);
+int snd_cs8427_create(struct snd_i2c_bus *bus, unsigned char addr,
+		      unsigned int reset_timeout, struct snd_i2c_device **r_cs8427);
+int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
+			 unsigned char val);
+int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
+			    struct snd_pcm_substream *playback_substream,
+			    struct snd_pcm_substream *capture_substream);
+int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active);
+int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate);
+
+#endif /* __SOUND_CS8427_H */
diff --git a/include/sound/da7213.h b/include/sound/da7213.h
new file mode 100644
index 0000000..e7eac89
--- /dev/null
+++ b/include/sound/da7213.h
@@ -0,0 +1,49 @@
+/*
+ * da7213.h - DA7213 ASoC Codec Driver Platform Data
+ *
+ * Copyright (c) 2013 Dialog Semiconductor
+ *
+ * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DA7213_PDATA_H
+#define _DA7213_PDATA_H
+
+enum da7213_micbias_voltage {
+	DA7213_MICBIAS_1_6V = 0,
+	DA7213_MICBIAS_2_2V = 1,
+	DA7213_MICBIAS_2_5V = 2,
+	DA7213_MICBIAS_3_0V = 3,
+};
+
+enum da7213_dmic_data_sel {
+	DA7213_DMIC_DATA_LRISE_RFALL = 0,
+	DA7213_DMIC_DATA_LFALL_RRISE = 1,
+};
+
+enum da7213_dmic_samplephase {
+	DA7213_DMIC_SAMPLE_ON_CLKEDGE = 0,
+	DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE = 1,
+};
+
+enum da7213_dmic_clk_rate {
+	DA7213_DMIC_CLK_3_0MHZ = 0,
+	DA7213_DMIC_CLK_1_5MHZ = 1,
+};
+
+struct da7213_platform_data {
+	/* Mic Bias voltage */
+	enum da7213_micbias_voltage micbias1_lvl;
+	enum da7213_micbias_voltage micbias2_lvl;
+
+	/* DMIC config */
+	enum da7213_dmic_data_sel dmic_data_sel;
+	enum da7213_dmic_samplephase dmic_samplephase;
+	enum da7213_dmic_clk_rate dmic_clk_rate;
+};
+
+#endif /* _DA7213_PDATA_H */
diff --git a/include/sound/da7219-aad.h b/include/sound/da7219-aad.h
new file mode 100644
index 0000000..17802fb
--- /dev/null
+++ b/include/sound/da7219-aad.h
@@ -0,0 +1,99 @@
+/*
+ * da7219-aad.h - DA7322 ASoC Codec AAD Driver Platform Data
+ *
+ * Copyright (c) 2015 Dialog Semiconductor Ltd.
+ *
+ * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.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.
+ */
+
+#ifndef __DA7219_AAD_PDATA_H
+#define __DA7219_AAD_PDATA_H
+
+enum da7219_aad_micbias_pulse_lvl {
+	DA7219_AAD_MICBIAS_PULSE_LVL_OFF = 0,
+	DA7219_AAD_MICBIAS_PULSE_LVL_2_8V = 6,
+	DA7219_AAD_MICBIAS_PULSE_LVL_2_9V,
+};
+
+enum da7219_aad_btn_cfg {
+	DA7219_AAD_BTN_CFG_2MS = 1,
+	DA7219_AAD_BTN_CFG_5MS,
+	DA7219_AAD_BTN_CFG_10MS,
+	DA7219_AAD_BTN_CFG_50MS,
+	DA7219_AAD_BTN_CFG_100MS,
+	DA7219_AAD_BTN_CFG_200MS,
+	DA7219_AAD_BTN_CFG_500MS,
+};
+
+enum da7219_aad_mic_det_thr {
+	DA7219_AAD_MIC_DET_THR_200_OHMS = 0,
+	DA7219_AAD_MIC_DET_THR_500_OHMS,
+	DA7219_AAD_MIC_DET_THR_750_OHMS,
+	DA7219_AAD_MIC_DET_THR_1000_OHMS,
+};
+
+enum da7219_aad_jack_ins_deb {
+	DA7219_AAD_JACK_INS_DEB_5MS = 0,
+	DA7219_AAD_JACK_INS_DEB_10MS,
+	DA7219_AAD_JACK_INS_DEB_20MS,
+	DA7219_AAD_JACK_INS_DEB_50MS,
+	DA7219_AAD_JACK_INS_DEB_100MS,
+	DA7219_AAD_JACK_INS_DEB_200MS,
+	DA7219_AAD_JACK_INS_DEB_500MS,
+	DA7219_AAD_JACK_INS_DEB_1S,
+};
+
+enum da7219_aad_jack_det_rate {
+	DA7219_AAD_JACK_DET_RATE_32_64MS = 0,
+	DA7219_AAD_JACK_DET_RATE_64_128MS,
+	DA7219_AAD_JACK_DET_RATE_128_256MS,
+	DA7219_AAD_JACK_DET_RATE_256_512MS,
+};
+
+enum da7219_aad_jack_rem_deb {
+	DA7219_AAD_JACK_REM_DEB_1MS = 0,
+	DA7219_AAD_JACK_REM_DEB_5MS,
+	DA7219_AAD_JACK_REM_DEB_10MS,
+	DA7219_AAD_JACK_REM_DEB_20MS,
+};
+
+enum da7219_aad_btn_avg {
+	DA7219_AAD_BTN_AVG_1 = 0,
+	DA7219_AAD_BTN_AVG_2,
+	DA7219_AAD_BTN_AVG_4,
+	DA7219_AAD_BTN_AVG_8,
+};
+
+enum da7219_aad_adc_1bit_rpt {
+	DA7219_AAD_ADC_1BIT_RPT_1 = 0,
+	DA7219_AAD_ADC_1BIT_RPT_2,
+	DA7219_AAD_ADC_1BIT_RPT_4,
+	DA7219_AAD_ADC_1BIT_RPT_8,
+};
+
+struct da7219_aad_pdata {
+	int irq;
+
+	enum da7219_aad_micbias_pulse_lvl micbias_pulse_lvl;
+	u32 micbias_pulse_time;
+	enum da7219_aad_btn_cfg btn_cfg;
+	enum da7219_aad_mic_det_thr mic_det_thr;
+	enum da7219_aad_jack_ins_deb jack_ins_deb;
+	enum da7219_aad_jack_det_rate jack_det_rate;
+	enum da7219_aad_jack_rem_deb jack_rem_deb;
+
+	u8 a_d_btn_thr;
+	u8 d_b_btn_thr;
+	u8 b_c_btn_thr;
+	u8 c_mic_btn_thr;
+
+	enum da7219_aad_btn_avg btn_avg;
+	enum da7219_aad_adc_1bit_rpt adc_1bit_rpt;
+};
+
+#endif /* __DA7219_AAD_PDATA_H */
diff --git a/include/sound/da7219.h b/include/sound/da7219.h
new file mode 100644
index 0000000..3f39e13
--- /dev/null
+++ b/include/sound/da7219.h
@@ -0,0 +1,55 @@
+/*
+ * da7219.h - DA7219 ASoC Codec Driver Platform Data
+ *
+ * Copyright (c) 2015 Dialog Semiconductor
+ *
+ * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.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.
+ */
+
+#ifndef __DA7219_PDATA_H
+#define __DA7219_PDATA_H
+
+/* LDO */
+enum da7219_ldo_lvl_sel {
+	DA7219_LDO_LVL_SEL_1_05V = 0,
+	DA7219_LDO_LVL_SEL_1_10V,
+	DA7219_LDO_LVL_SEL_1_20V,
+	DA7219_LDO_LVL_SEL_1_40V,
+};
+
+/* Mic Bias */
+enum da7219_micbias_voltage {
+	DA7219_MICBIAS_1_8V = 1,
+	DA7219_MICBIAS_2_0V,
+	DA7219_MICBIAS_2_2V,
+	DA7219_MICBIAS_2_4V,
+	DA7219_MICBIAS_2_6V,
+};
+
+/* Mic input type */
+enum da7219_mic_amp_in_sel {
+	DA7219_MIC_AMP_IN_SEL_DIFF = 0,
+	DA7219_MIC_AMP_IN_SEL_SE_P,
+	DA7219_MIC_AMP_IN_SEL_SE_N,
+};
+
+struct da7219_aad_pdata;
+
+struct da7219_pdata {
+	/* Internal LDO */
+	enum da7219_ldo_lvl_sel ldo_lvl_sel;
+
+	/* Mic */
+	enum da7219_micbias_voltage micbias_lvl;
+	enum da7219_mic_amp_in_sel mic_amp_in_sel;
+
+	/* AAD */
+	struct da7219_aad_pdata *aad_pdata;
+};
+
+#endif /* __DA7219_PDATA_H */
diff --git a/include/sound/da9055.h b/include/sound/da9055.h
new file mode 100644
index 0000000..cf1241b
--- /dev/null
+++ b/include/sound/da9055.h
@@ -0,0 +1,33 @@
+/*
+ * DA9055 ALSA Soc codec driver
+ *
+ * Copyright (c) 2012 Dialog Semiconductor
+ *
+ * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C
+ * Written by David Chen <david.chen@diasemi.com> and
+ * Ashish Chavan <ashish.chavan@kpitcummins.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.
+ */
+
+#ifndef __SOUND_DA9055_H__
+#define __SOUND_DA9055_H__
+
+enum da9055_micbias_voltage {
+	DA9055_MICBIAS_1_6V = 0,
+	DA9055_MICBIAS_1_8V = 1,
+	DA9055_MICBIAS_2_1V = 2,
+	DA9055_MICBIAS_2_2V = 3,
+};
+
+struct da9055_platform_data {
+	/* Selects which of the two MicBias pins acts as the bias source */
+	bool micbias_source;
+	/* Selects the micbias voltage */
+	enum da9055_micbias_voltage micbias;
+};
+
+#endif
diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h
new file mode 100644
index 0000000..8966ba7
--- /dev/null
+++ b/include/sound/designware_i2s.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (ST) 2012 Rajeev Kumar (rajeevkumar.linux@gmail.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
+ *
+ */
+
+#ifndef __SOUND_DESIGNWARE_I2S_H
+#define __SOUND_DESIGNWARE_I2S_H
+
+#include <linux/dmaengine.h>
+#include <linux/types.h>
+
+/*
+ * struct i2s_clk_config_data - represent i2s clk configuration data
+ * @chan_nr: number of channel
+ * @data_width: number of bits per sample (8/16/24/32 bit)
+ * @sample_rate: sampling frequency (8Khz, 16Khz, 32Khz, 44Khz, 48Khz)
+ */
+struct i2s_clk_config_data {
+	int chan_nr;
+	u32 data_width;
+	u32 sample_rate;
+};
+
+struct i2s_platform_data {
+	#define DWC_I2S_PLAY	(1 << 0)
+	#define DWC_I2S_RECORD	(1 << 1)
+	#define DW_I2S_SLAVE	(1 << 2)
+	#define DW_I2S_MASTER	(1 << 3)
+	unsigned int cap;
+	int channel;
+	u32 snd_fmts;
+	u32 snd_rates;
+
+	void *play_dma_data;
+	void *capture_dma_data;
+	bool (*filter)(struct dma_chan *chan, void *slave);
+	int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
+};
+
+struct i2s_dma_data {
+	void *data;
+	dma_addr_t addr;
+	u32 max_burst;
+	enum dma_slave_buswidth addr_width;
+	bool (*filter)(struct dma_chan *chan, void *slave);
+};
+
+/* I2S DMA registers */
+#define I2S_RXDMA		0x01C0
+#define I2S_TXDMA		0x01C8
+
+#define TWO_CHANNEL_SUPPORT	2	/* up to 2.0 */
+#define FOUR_CHANNEL_SUPPORT	4	/* up to 3.1 */
+#define SIX_CHANNEL_SUPPORT	6	/* up to 5.1 */
+#define EIGHT_CHANNEL_SUPPORT	8	/* up to 7.1 */
+
+#endif /*  __SOUND_DESIGNWARE_I2S_H */
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
new file mode 100644
index 0000000..f86ef5e
--- /dev/null
+++ b/include/sound/dmaengine_pcm.h
@@ -0,0 +1,152 @@
+/*
+ *  Copyright (C) 2012, Analog Devices Inc.
+ *	Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under  the terms of the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __SOUND_DMAENGINE_PCM_H__
+#define __SOUND_DMAENGINE_PCM_H__
+
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <linux/dmaengine.h>
+
+/**
+ * snd_pcm_substream_to_dma_direction - Get dma_transfer_direction for a PCM
+ *   substream
+ * @substream: PCM substream
+ */
+static inline enum dma_transfer_direction
+snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return DMA_MEM_TO_DEV;
+	else
+		return DMA_DEV_TO_MEM;
+}
+
+int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
+	const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
+int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
+snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream);
+snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream);
+
+int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
+	struct dma_chan *chan);
+int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
+
+int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream,
+	dma_filter_fn filter_fn, void *filter_data);
+int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream);
+
+struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn,
+	void *filter_data);
+struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
+
+/**
+ * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
+ * @addr: Address of the DAI data source or destination register.
+ * @addr_width: Width of the DAI data source or destination register.
+ * @maxburst: Maximum number of words(note: words, as in units of the
+ * src_addr_width member, not bytes) that can be send to or received from the
+ * DAI in one burst.
+ * @slave_id: Slave requester id for the DMA channel.
+ * @filter_data: Custom DMA channel filter data, this will usually be used when
+ * requesting the DMA channel.
+ * @chan_name: Custom channel name to use when requesting DMA channel.
+ * @fifo_size: FIFO size of the DAI controller in bytes
+ */
+struct snd_dmaengine_dai_dma_data {
+	dma_addr_t addr;
+	enum dma_slave_buswidth addr_width;
+	u32 maxburst;
+	unsigned int slave_id;
+	void *filter_data;
+	const char *chan_name;
+	unsigned int fifo_size;
+};
+
+void snd_dmaengine_pcm_set_config_from_dai_data(
+	const struct snd_pcm_substream *substream,
+	const struct snd_dmaengine_dai_dma_data *dma_data,
+	struct dma_slave_config *config);
+
+
+/*
+ * Try to request the DMA channel using compat_request_channel or
+ * compat_filter_fn if it couldn't be requested through devicetree.
+ */
+#define SND_DMAENGINE_PCM_FLAG_COMPAT BIT(0)
+/*
+ * Don't try to request the DMA channels through devicetree. This flag only
+ * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
+ */
+#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
+/*
+ * The PCM is half duplex and the DMA channel is shared between capture and
+ * playback.
+ */
+#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
+/*
+ * The PCM streams have custom channel names specified.
+ */
+#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
+
+/**
+ * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
+ * @prepare_slave_config: Callback used to fill in the DMA slave_config for a
+ *   PCM substream. Will be called from the PCM drivers hwparams callback.
+ * @compat_request_channel: Callback to request a DMA channel for platforms
+ *   which do not use devicetree.
+ * @compat_filter_fn: Will be used as the filter function when requesting a
+ *  channel for platforms which do not use devicetree. The filter parameter
+ *  will be the DAI's DMA data.
+ * @dma_dev: If set, request DMA channel on this device rather than the DAI
+ *  device.
+ * @chan_names: If set, these custom DMA channel names will be requested at
+ *  registration time.
+ * @pcm_hardware: snd_pcm_hardware struct to be used for the PCM.
+ * @prealloc_buffer_size: Size of the preallocated audio buffer.
+ *
+ * Note: If both compat_request_channel and compat_filter_fn are set
+ * compat_request_channel will be used to request the channel and
+ * compat_filter_fn will be ignored. Otherwise the channel will be requested
+ * using dma_request_channel with compat_filter_fn as the filter function.
+ */
+struct snd_dmaengine_pcm_config {
+	int (*prepare_slave_config)(struct snd_pcm_substream *substream,
+			struct snd_pcm_hw_params *params,
+			struct dma_slave_config *slave_config);
+	struct dma_chan *(*compat_request_channel)(
+			struct snd_soc_pcm_runtime *rtd,
+			struct snd_pcm_substream *substream);
+	dma_filter_fn compat_filter_fn;
+	struct device *dma_dev;
+	const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
+
+	const struct snd_pcm_hardware *pcm_hardware;
+	unsigned int prealloc_buffer_size;
+};
+
+int snd_dmaengine_pcm_register(struct device *dev,
+	const struct snd_dmaengine_pcm_config *config,
+	unsigned int flags);
+void snd_dmaengine_pcm_unregister(struct device *dev);
+
+int devm_snd_dmaengine_pcm_register(struct device *dev,
+	const struct snd_dmaengine_pcm_config *config,
+	unsigned int flags);
+
+int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params,
+	struct dma_slave_config *slave_config);
+
+#endif
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
new file mode 100644
index 0000000..5bd1346
--- /dev/null
+++ b/include/sound/emu10k1.h
@@ -0,0 +1,1906 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *		     Creative Labs, Inc.
+ *  Definitions for EMU10K1 (SB Live!) chips
+ *
+ *
+ *   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
+ *
+ */
+#ifndef __SOUND_EMU10K1_H
+#define __SOUND_EMU10K1_H
+
+
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/hwdep.h>
+#include <sound/ac97_codec.h>
+#include <sound/util_mem.h>
+#include <sound/pcm-indirect.h>
+#include <sound/timer.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+
+#include <uapi/sound/emu10k1.h>
+
+/* ------------------- DEFINES -------------------- */
+
+#define EMUPAGESIZE     4096
+#define MAXREQVOICES    8
+#define MAXPAGES0       4096	/* 32 bit mode */
+#define MAXPAGES1       8192	/* 31 bit mode */
+#define RESERVED        0
+#define NUM_MIDI        16
+#define NUM_G           64              /* use all channels */
+#define NUM_FXSENDS     4
+#define NUM_EFX_PLAYBACK    16
+
+/* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
+#define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
+#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit mode */
+
+#define TMEMSIZE        256*1024
+#define TMEMSIZEREG     4
+
+#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
+
+// Audigy specify registers are prefixed with 'A_'
+
+/************************************************************************************************/
+/* PCI function 0 registers, address = <val> + PCIBASE0						*/
+/************************************************************************************************/
+
+#define PTR			0x00		/* Indexed register set pointer register	*/
+						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
+						/* be modified independently of each other.	*/
+#define PTR_CHANNELNUM_MASK	0x0000003f	/* For each per-channel register, indicates the	*/
+						/* channel number of the register to be		*/
+						/* accessed.  For non per-channel registers the	*/
+						/* value should be set to zero.			*/
+#define PTR_ADDRESS_MASK	0x07ff0000	/* Register index				*/
+#define A_PTR_ADDRESS_MASK	0x0fff0000
+
+#define DATA			0x04		/* Indexed register set data register		*/
+
+#define IPR			0x08		/* Global interrupt pending register		*/
+						/* Clear pending interrupts by writing a 1 to	*/
+						/* the relevant bits and zero to the other bits	*/
+#define IPR_P16V		0x80000000	/* Bit set when the CA0151 P16V chip wishes
+						   to interrupt */
+#define IPR_GPIOMSG		0x20000000	/* GPIO message interrupt (RE'd, still not sure 
+						   which INTE bits enable it)			*/
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
+#define IPR_A_MIDITRANSBUFEMPTY2 0x10000000	/* MIDI UART transmit buffer empty		*/
+#define IPR_A_MIDIRECVBUFEMPTY2	0x08000000	/* MIDI UART receive buffer empty		*/
+
+#define IPR_SPDIFBUFFULL	0x04000000	/* SPDIF capture related, 10k2 only? (RE)	*/
+#define IPR_SPDIFBUFHALFFULL	0x02000000	/* SPDIF capture related? (RE)			*/
+
+#define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
+#define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
+#define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
+#define IPR_PCIERROR		0x00200000	/* PCI bus error				*/
+#define IPR_VOLINCR		0x00100000	/* Volume increment button pressed		*/
+#define IPR_VOLDECR		0x00080000	/* Volume decrement button pressed		*/
+#define IPR_MUTE		0x00040000	/* Mute button pressed				*/
+#define IPR_MICBUFFULL		0x00020000	/* Microphone buffer full			*/
+#define IPR_MICBUFHALFFULL	0x00010000	/* Microphone buffer half full			*/
+#define IPR_ADCBUFFULL		0x00008000	/* ADC buffer full				*/
+#define IPR_ADCBUFHALFFULL	0x00004000	/* ADC buffer half full				*/
+#define IPR_EFXBUFFULL		0x00002000	/* Effects buffer full				*/
+#define IPR_EFXBUFHALFFULL	0x00001000	/* Effects buffer half full			*/
+#define IPR_GPSPDIFSTATUSCHANGE	0x00000800	/* GPSPDIF channel status change		*/
+#define IPR_CDROMSTATUSCHANGE	0x00000400	/* CD-ROM channel status change			*/
+#define IPR_INTERVALTIMER	0x00000200	/* Interval timer terminal count		*/
+#define IPR_MIDITRANSBUFEMPTY	0x00000100	/* MIDI UART transmit buffer empty		*/
+#define IPR_MIDIRECVBUFEMPTY	0x00000080	/* MIDI UART receive buffer empty		*/
+#define IPR_CHANNELLOOP		0x00000040	/* Channel (half) loop interrupt(s) pending	*/
+#define IPR_CHANNELNUMBERMASK	0x0000003f	/* When IPR_CHANNELLOOP is set, indicates the	*/
+						/* highest set channel in CLIPL, CLIPH, HLIPL,  */
+						/* or HLIPH.  When IP is written with CL set,	*/
+						/* the bit in H/CLIPL or H/CLIPH corresponding	*/
+						/* to the CIN value written will be cleared.	*/
+
+#define INTE			0x0c		/* Interrupt enable register			*/
+#define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
+#define INTE_VIRTUALSB_220	0x00000000	/* Capture at I/O base address 0x220-0x22f	*/
+#define INTE_VIRTUALSB_240	0x40000000	/* Capture at I/O base address 0x240		*/
+#define INTE_VIRTUALSB_260	0x80000000	/* Capture at I/O base address 0x260		*/
+#define INTE_VIRTUALSB_280	0xc0000000	/* Capture at I/O base address 0x280		*/
+#define INTE_VIRTUALMPU_MASK	0x30000000	/* Virtual MPU I/O port capture			*/
+#define INTE_VIRTUALMPU_300	0x00000000	/* Capture at I/O base address 0x300-0x301	*/
+#define INTE_VIRTUALMPU_310	0x10000000	/* Capture at I/O base address 0x310		*/
+#define INTE_VIRTUALMPU_320	0x20000000	/* Capture at I/O base address 0x320		*/
+#define INTE_VIRTUALMPU_330	0x30000000	/* Capture at I/O base address 0x330		*/
+#define INTE_MASTERDMAENABLE	0x08000000	/* Master DMA emulation at 0x000-0x00f		*/
+#define INTE_SLAVEDMAENABLE	0x04000000	/* Slave DMA emulation at 0x0c0-0x0df		*/
+#define INTE_MASTERPICENABLE	0x02000000	/* Master PIC emulation at 0x020-0x021		*/
+#define INTE_SLAVEPICENABLE	0x01000000	/* Slave PIC emulation at 0x0a0-0x0a1		*/
+#define INTE_VSBENABLE		0x00800000	/* Enable virtual Soundblaster			*/
+#define INTE_ADLIBENABLE	0x00400000	/* Enable AdLib emulation at 0x388-0x38b	*/
+#define INTE_MPUENABLE		0x00200000	/* Enable virtual MPU				*/
+#define INTE_FORCEINT		0x00100000	/* Continuously assert INTAN			*/
+
+#define INTE_MRHANDENABLE	0x00080000	/* Enable the "Mr. Hand" logic			*/
+						/* NOTE: There is no reason to use this under	*/
+						/* Linux, and it will cause odd hardware 	*/
+						/* behavior and possibly random segfaults and	*/
+						/* lockups if enabled.				*/
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
+#define INTE_A_MIDITXENABLE2	0x00020000	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_A_MIDIRXENABLE2	0x00010000	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+
+#define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
+						/* NOTE: This bit must always be enabled       	*/
+#define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
+#define INTE_PCIERRORENABLE	0x00000800	/* Enable PCI bus error interrupts		*/
+#define INTE_VOLINCRENABLE	0x00000400	/* Enable volume increment button interrupts	*/
+#define INTE_VOLDECRENABLE	0x00000200	/* Enable volume decrement button interrupts	*/
+#define INTE_MUTEENABLE		0x00000100	/* Enable mute button interrupts		*/
+#define INTE_MICBUFENABLE	0x00000080	/* Enable microphone buffer interrupts		*/
+#define INTE_ADCBUFENABLE	0x00000040	/* Enable ADC buffer interrupts			*/
+#define INTE_EFXBUFENABLE	0x00000020	/* Enable Effects buffer interrupts		*/
+#define INTE_GPSPDIFENABLE	0x00000010	/* Enable GPSPDIF status interrupts		*/
+#define INTE_CDSPDIFENABLE	0x00000008	/* Enable CDSPDIF status interrupts		*/
+#define INTE_INTERVALTIMERENB	0x00000004	/* Enable interval timer interrupts		*/
+#define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+#define WC			0x10		/* Wall Clock register				*/
+#define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
+#define WC_SAMPLECOUNTER	0x14060010
+#define WC_CURRENTCHANNEL	0x0000003F	/* Channel [0..63] currently being serviced	*/
+						/* NOTE: Each channel takes 1/64th of a sample	*/
+						/* period to be serviced.			*/
+
+#define HCFG			0x14		/* Hardware config register			*/
+						/* NOTE: There is no reason to use the legacy	*/
+						/* SoundBlaster emulation stuff described below	*/
+						/* under Linux, and all kinds of weird hardware	*/
+						/* behavior can result if you try.  Don't.	*/
+#define HCFG_LEGACYFUNC_MASK	0xe0000000	/* Legacy function number 			*/
+#define HCFG_LEGACYFUNC_MPU	0x00000000	/* Legacy MPU	 				*/
+#define HCFG_LEGACYFUNC_SB	0x40000000	/* Legacy SB					*/
+#define HCFG_LEGACYFUNC_AD	0x60000000	/* Legacy AD					*/
+#define HCFG_LEGACYFUNC_MPIC	0x80000000	/* Legacy MPIC					*/
+#define HCFG_LEGACYFUNC_MDMA	0xa0000000	/* Legacy MDMA					*/
+#define HCFG_LEGACYFUNC_SPCI	0xc0000000	/* Legacy SPCI					*/
+#define HCFG_LEGACYFUNC_SDMA	0xe0000000	/* Legacy SDMA					*/
+#define HCFG_IOCAPTUREADDR	0x1f000000	/* The 4 LSBs of the captured I/O address.	*/
+#define HCFG_LEGACYWRITE	0x00800000	/* 1 = write, 0 = read 				*/
+#define HCFG_LEGACYWORD		0x00400000	/* 1 = word, 0 = byte 				*/
+#define HCFG_LEGACYINT		0x00200000	/* 1 = legacy event captured. Write 1 to clear.	*/
+						/* NOTE: The rest of the bits in this register	*/
+						/* _are_ relevant under Linux.			*/
+#define HCFG_PUSH_BUTTON_ENABLE 0x00100000	/* Enables Volume Inc/Dec and Mute functions    */
+#define HCFG_BAUD_RATE		0x00080000	/* 0 = 48kHz, 1 = 44.1kHz			*/
+#define HCFG_EXPANDED_MEM	0x00040000	/* 1 = any 16M of 4G addr, 0 = 32M of 2G addr	*/
+#define HCFG_CODECFORMAT_MASK	0x00030000	/* CODEC format					*/
+
+/* Specific to Alice2, CA0102 */
+#define HCFG_CODECFORMAT_AC97_1	0x00000000	/* AC97 CODEC format -- Ver 1.03		*/
+#define HCFG_CODECFORMAT_AC97_2	0x00010000	/* AC97 CODEC format -- Ver 2.1			*/
+#define HCFG_AUTOMUTE_ASYNC	0x00008000	/* When set, the async sample rate convertors	*/
+						/* will automatically mute their output when	*/
+						/* they are not rate-locked to the external	*/
+						/* async audio source  				*/
+#define HCFG_AUTOMUTE_SPDIF	0x00004000	/* When set, the async sample rate convertors	*/
+						/* will automatically mute their output when	*/
+						/* the SPDIF V-bit indicates invalid audio	*/
+#define HCFG_EMU32_SLAVE	0x00002000	/* 0 = Master, 1 = Slave. Slave for EMU1010	*/
+#define HCFG_SLOW_RAMP		0x00001000	/* Increases Send Smoothing time constant	*/
+/* 0x00000800 not used on Alice2 */
+#define HCFG_PHASE_TRACK_MASK	0x00000700	/* When set, forces corresponding input to	*/
+						/* phase track the previous input.		*/
+						/* I2S0 can phase track the last S/PDIF input	*/
+#define HCFG_I2S_ASRC_ENABLE	0x00000070	/* When set, enables asynchronous sample rate   */
+						/* conversion for the corresponding		*/
+ 						/* I2S format input				*/
+/* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc.  */
+
+
+
+/* Older chips */
+#define HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format -- Primary Output		*/
+#define HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format -- Secondary (Rear) Output	*/
+#define HCFG_GPINPUT0		0x00004000	/* External pin112				*/
+#define HCFG_GPINPUT1		0x00002000	/* External pin110				*/
+#define HCFG_GPOUTPUT_MASK	0x00001c00	/* External pins which may be controlled	*/
+#define HCFG_GPOUT0		0x00001000	/* External pin? (spdif enable on 5.1)		*/
+#define HCFG_GPOUT1		0x00000800	/* External pin? (IR)				*/
+#define HCFG_GPOUT2		0x00000400	/* External pin? (IR)				*/
+#define HCFG_JOYENABLE      	0x00000200	/* Internal joystick enable    			*/
+#define HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable			*/
+						/* 1 = Force all 3 async digital inputs to use	*/
+						/* the same async sample rate tracker (ZVIDEO)	*/
+#define HCFG_AC3ENABLE_MASK	0x000000e0	/* AC3 async input control - Not implemented	*/
+#define HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Channels 0 and 1 replace ZVIDEO		*/
+#define HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Channels 0 and 1 replace CDSPDIF		*/
+#define HCFG_AC3ENABLE_GPSPDIF  0x00000020      /* Channels 0 and 1 replace GPSPDIF             */
+#define HCFG_AUTOMUTE		0x00000010	/* When set, the async sample rate convertors	*/
+						/* will automatically mute their output when	*/
+						/* they are not rate-locked to the external	*/
+						/* async audio source  				*/
+#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE_MASK	0x00000004	/* 1 = Cancel bustmaster accesses to tankcache	*/
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE	0x01020014
+#define HCFG_MUTEBUTTONENABLE	0x00000002	/* 1 = Master mute button sets AUDIOENABLE = 0.	*/
+						/* NOTE: This is a 'cheap' way to implement a	*/
+						/* master mute function on the mute button, and	*/
+						/* in general should not be used unless a more	*/
+						/* sophisticated master mute function has not	*/
+						/* been written.       				*/
+#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
+						/* Should be set to 1 when the EMU10K1 is	*/
+						/* completely initialized.			*/
+
+//For Audigy, MPU port move to 0x70-0x74 ptr register
+
+#define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
+
+#define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
+#define MUCMD_RESET		0xff		/* RESET command				*/
+#define MUCMD_ENTERUARTMODE	0x3f		/* Enter_UART_mode command			*/
+						/* NOTE: All other commands are ignored		*/
+
+#define MUSTAT			MUCMD		/* MPU401 status register (8 bits)     		*/
+#define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
+#define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
+
+#define A_IOCFG			0x18		/* GPIO on Audigy card (16bits)			*/
+#define A_GPINPUT_MASK		0xff00
+#define A_GPOUTPUT_MASK		0x00ff
+
+// Audigy output/GPIO stuff taken from the kX drivers
+#define A_IOCFG_GPOUT0		0x0044		/* analog/digital				*/
+#define A_IOCFG_DISABLE_ANALOG	0x0040		/* = 'enable' for Audigy2 (chiprev=4)		*/
+#define A_IOCFG_ENABLE_DIGITAL	0x0004
+#define A_IOCFG_ENABLE_DIGITAL_AUDIGY4	0x0080
+#define A_IOCFG_UNKNOWN_20      0x0020
+#define A_IOCFG_DISABLE_AC97_FRONT      0x0080  /* turn off ac97 front -> front (10k2.1)	*/
+#define A_IOCFG_GPOUT1		0x0002		/* IR? drive's internal bypass (?)		*/
+#define A_IOCFG_GPOUT2		0x0001		/* IR */
+#define A_IOCFG_MULTIPURPOSE_JACK	0x2000  /* center+lfe+rear_center (a2/a2ex)		*/
+                                                /* + digital for generic 10k2			*/
+#define A_IOCFG_DIGITAL_JACK    0x1000          /* digital for a2 platinum			*/
+#define A_IOCFG_FRONT_JACK      0x4000
+#define A_IOCFG_REAR_JACK       0x8000
+#define A_IOCFG_PHONES_JACK     0x0100          /* LiveDrive					*/
+
+/* outputs:
+ *	for audigy2 platinum:	0xa00
+ *	for a2 platinum ex:	0x1c00
+ *	for a1 platinum:	0x0
+ */
+
+#define TIMER			0x1a		/* Timer terminal count register		*/
+						/* NOTE: After the rate is changed, a maximum	*/
+						/* of 1024 sample periods should be allowed	*/
+						/* before the new rate is guaranteed accurate.	*/
+#define TIMER_RATE_MASK		0x000003ff	/* Timer interrupt rate in sample periods	*/
+						/* 0 == 1024 periods, [1..4] are not useful	*/
+#define TIMER_RATE		0x0a00001a
+
+#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
+
+#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
+#define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
+#define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
+
+/* Available on the Audigy 2 and Audigy 4 only. This is the P16V chip. */
+#define PTR2			0x20		/* Indexed register set pointer register	*/
+#define DATA2			0x24		/* Indexed register set data register		*/
+#define IPR2			0x28		/* P16V interrupt pending register		*/
+#define IPR2_PLAYBACK_CH_0_LOOP      0x00001000 /* Playback Channel 0 loop                               */
+#define IPR2_PLAYBACK_CH_0_HALF_LOOP 0x00000100 /* Playback Channel 0 half loop                          */
+#define IPR2_CAPTURE_CH_0_LOOP       0x00100000 /* Capture Channel 0 loop                               */
+#define IPR2_CAPTURE_CH_0_HALF_LOOP  0x00010000 /* Capture Channel 0 half loop                          */
+						/* 0x00000100 Playback. Only in once per period.
+						 * 0x00110000 Capture. Int on half buffer.
+						 */
+#define INTE2			0x2c		/* P16V Interrupt enable register. 	*/
+#define INTE2_PLAYBACK_CH_0_LOOP      0x00001000 /* Playback Channel 0 loop                               */
+#define INTE2_PLAYBACK_CH_0_HALF_LOOP 0x00000100 /* Playback Channel 0 half loop                          */
+#define INTE2_PLAYBACK_CH_1_LOOP      0x00002000 /* Playback Channel 1 loop                               */
+#define INTE2_PLAYBACK_CH_1_HALF_LOOP 0x00000200 /* Playback Channel 1 half loop                          */
+#define INTE2_PLAYBACK_CH_2_LOOP      0x00004000 /* Playback Channel 2 loop                               */
+#define INTE2_PLAYBACK_CH_2_HALF_LOOP 0x00000400 /* Playback Channel 2 half loop                          */
+#define INTE2_PLAYBACK_CH_3_LOOP      0x00008000 /* Playback Channel 3 loop                               */
+#define INTE2_PLAYBACK_CH_3_HALF_LOOP 0x00000800 /* Playback Channel 3 half loop                          */
+#define INTE2_CAPTURE_CH_0_LOOP       0x00100000 /* Capture Channel 0 loop                               */
+#define INTE2_CAPTURE_CH_0_HALF_LOOP  0x00010000 /* Caputre Channel 0 half loop                          */
+#define HCFG2			0x34		/* Defaults: 0, win2000 sets it to 00004201 */
+						/* 0x00000000 2-channel output. */
+						/* 0x00000200 8-channel output. */
+						/* 0x00000004 pauses stream/irq fail. */
+						/* Rest of bits no nothing to sound output */
+						/* bit 0: Enable P16V audio.
+						 * bit 1: Lock P16V record memory cache.
+						 * bit 2: Lock P16V playback memory cache.
+						 * bit 3: Dummy record insert zero samples.
+						 * bit 8: Record 8-channel in phase.
+						 * bit 9: Playback 8-channel in phase.
+						 * bit 11-12: Playback mixer attenuation: 0=0dB, 1=-6dB, 2=-12dB, 3=Mute.
+						 * bit 13: Playback mixer enable.
+						 * bit 14: Route SRC48 mixer output to fx engine.
+						 * bit 15: Enable IEEE 1394 chip.
+						 */
+#define IPR3			0x38		/* Cdif interrupt pending register		*/
+#define INTE3			0x3c		/* Cdif interrupt enable register. 	*/
+/************************************************************************************************/
+/* PCI function 1 registers, address = <val> + PCIBASE1						*/
+/************************************************************************************************/
+
+#define JOYSTICK1		0x00		/* Analog joystick port register		*/
+#define JOYSTICK2		0x01		/* Analog joystick port register		*/
+#define JOYSTICK3		0x02		/* Analog joystick port register		*/
+#define JOYSTICK4		0x03		/* Analog joystick port register		*/
+#define JOYSTICK5		0x04		/* Analog joystick port register		*/
+#define JOYSTICK6		0x05		/* Analog joystick port register		*/
+#define JOYSTICK7		0x06		/* Analog joystick port register		*/
+#define JOYSTICK8		0x07		/* Analog joystick port register		*/
+
+/* When writing, any write causes JOYSTICK_COMPARATOR output enable to be pulsed on write.	*/
+/* When reading, use these bitfields: */
+#define JOYSTICK_BUTTONS	0x0f		/* Joystick button data				*/
+#define JOYSTICK_COMPARATOR	0xf0		/* Joystick comparator data			*/
+
+
+/********************************************************************************************************/
+/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
+/********************************************************************************************************/
+
+#define CPF			0x00		/* Current pitch and fraction register			*/
+#define CPF_CURRENTPITCH_MASK	0xffff0000	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
+#define CPF_CURRENTPITCH	0x10100000
+#define CPF_STEREO_MASK		0x00008000	/* 1 = Even channel interleave, odd channel locked	*/
+#define CPF_STOP_MASK		0x00004000	/* 1 = Current pitch forced to 0			*/
+#define CPF_FRACADDRESS_MASK	0x00003fff	/* Linear fractional address of the current channel	*/
+
+#define PTRX			0x01		/* Pitch target and send A/B amounts register		*/
+#define PTRX_PITCHTARGET_MASK	0xffff0000	/* Pitch target of specified channel			*/
+#define PTRX_PITCHTARGET	0x10100001
+#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00	/* Linear level of channel output sent to FX send bus A	*/
+#define PTRX_FXSENDAMOUNT_A	0x08080001
+#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff	/* Linear level of channel output sent to FX send bus B	*/
+#define PTRX_FXSENDAMOUNT_B	0x08000001
+
+#define CVCF			0x02		/* Current volume and filter cutoff register		*/
+#define CVCF_CURRENTVOL_MASK	0xffff0000	/* Current linear volume of specified channel		*/
+#define CVCF_CURRENTVOL		0x10100002
+#define CVCF_CURRENTFILTER_MASK	0x0000ffff	/* Current filter cutoff frequency of specified channel	*/
+#define CVCF_CURRENTFILTER	0x10000002
+
+#define VTFT			0x03		/* Volume target and filter cutoff target register	*/
+#define VTFT_VOLUMETARGET_MASK	0xffff0000	/* Volume target of specified channel			*/
+#define VTFT_VOLUMETARGET	0x10100003
+#define VTFT_FILTERTARGET_MASK	0x0000ffff	/* Filter cutoff target of specified channel		*/
+#define VTFT_FILTERTARGET	0x10000003
+
+#define Z1			0x05		/* Filter delay memory 1 register			*/
+
+#define Z2			0x04		/* Filter delay memory 2 register			*/
+
+#define PSST			0x06		/* Send C amount and loop start address register	*/
+#define PSST_FXSENDAMOUNT_C_MASK 0xff000000	/* Linear level of channel output sent to FX send bus C	*/
+
+#define PSST_FXSENDAMOUNT_C	0x08180006
+
+#define PSST_LOOPSTARTADDR_MASK	0x00ffffff	/* Loop start address of the specified channel		*/
+#define PSST_LOOPSTARTADDR	0x18000006
+
+#define DSL			0x07		/* Send D amount and loop start address register	*/
+#define DSL_FXSENDAMOUNT_D_MASK	0xff000000	/* Linear level of channel output sent to FX send bus D	*/
+
+#define DSL_FXSENDAMOUNT_D	0x08180007
+
+#define DSL_LOOPENDADDR_MASK	0x00ffffff	/* Loop end address of the specified channel		*/
+#define DSL_LOOPENDADDR		0x18000007
+
+#define CCCA			0x08		/* Filter Q, interp. ROM, byte size, cur. addr register */
+#define CCCA_RESONANCE		0xf0000000	/* Lowpass filter resonance (Q) height			*/
+#define CCCA_INTERPROMMASK	0x0e000000	/* Selects passband of interpolation ROM		*/
+						/* 1 == full band, 7 == lowpass				*/
+						/* ROM 0 is used when pitch shifting downward or less	*/
+						/* then 3 semitones upward.  Increasingly higher ROM	*/
+						/* numbers are used, typically in steps of 3 semitones,	*/
+						/* as upward pitch shifting is performed.		*/
+#define CCCA_INTERPROM_0	0x00000000	/* Select interpolation ROM 0				*/
+#define CCCA_INTERPROM_1	0x02000000	/* Select interpolation ROM 1				*/
+#define CCCA_INTERPROM_2	0x04000000	/* Select interpolation ROM 2				*/
+#define CCCA_INTERPROM_3	0x06000000	/* Select interpolation ROM 3				*/
+#define CCCA_INTERPROM_4	0x08000000	/* Select interpolation ROM 4				*/
+#define CCCA_INTERPROM_5	0x0a000000	/* Select interpolation ROM 5				*/
+#define CCCA_INTERPROM_6	0x0c000000	/* Select interpolation ROM 6				*/
+#define CCCA_INTERPROM_7	0x0e000000	/* Select interpolation ROM 7				*/
+#define CCCA_8BITSELECT		0x01000000	/* 1 = Sound memory for this channel uses 8-bit samples	*/
+#define CCCA_CURRADDR_MASK	0x00ffffff	/* Current address of the selected channel		*/
+#define CCCA_CURRADDR		0x18000008
+
+#define CCR			0x09		/* Cache control register				*/
+#define CCR_CACHEINVALIDSIZE	0x07190009
+#define CCR_CACHEINVALIDSIZE_MASK	0xfe000000	/* Number of invalid samples cache for this channel    	*/
+#define CCR_CACHELOOPFLAG	0x01000000	/* 1 = Cache has a loop service pending			*/
+#define CCR_INTERLEAVEDSAMPLES	0x00800000	/* 1 = A cache service will fetch interleaved samples	*/
+#define CCR_WORDSIZEDSAMPLES	0x00400000	/* 1 = A cache service will fetch word sized samples	*/
+#define CCR_READADDRESS		0x06100009
+#define CCR_READADDRESS_MASK	0x003f0000	/* Location of cache just beyond current cache service	*/
+#define CCR_LOOPINVALSIZE	0x0000fe00	/* Number of invalid samples in cache prior to loop	*/
+						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
+#define CCR_LOOPFLAG		0x00000100	/* Set for a single sample period when a loop occurs	*/
+#define CCR_CACHELOOPADDRHI	0x000000ff	/* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/
+
+#define CLP			0x0a		/* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
+						/* NOTE: This register is normally not used		*/
+#define CLP_CACHELOOPADDR	0x0000ffff	/* Cache loop address (DSL_LOOPSTARTADDR [0..15])	*/
+
+#define FXRT			0x0b		/* Effects send routing register			*/
+						/* NOTE: It is illegal to assign the same routing to	*/
+						/* two effects sends.					*/
+#define FXRT_CHANNELA		0x000f0000	/* Effects send bus number for channel's effects send A	*/
+#define FXRT_CHANNELB		0x00f00000	/* Effects send bus number for channel's effects send B	*/
+#define FXRT_CHANNELC		0x0f000000	/* Effects send bus number for channel's effects send C	*/
+#define FXRT_CHANNELD		0xf0000000	/* Effects send bus number for channel's effects send D	*/
+
+#define A_HR			0x0b	/* High Resolution. 24bit playback from host to DSP. */
+#define MAPA			0x0c		/* Cache map A						*/
+
+#define MAPB			0x0d		/* Cache map B						*/
+
+#define MAP_PTE_MASK0		0xfffff000	/* The 20 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK0		0x00000fff	/* The 12 bit index to one of the 4096 PTE dwords      	*/
+
+#define MAP_PTE_MASK1		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK1		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
+
+/* 0x0e, 0x0f: Not used */
+
+#define ENVVOL			0x10		/* Volume envelope register				*/
+#define ENVVOL_MASK		0x0000ffff	/* Current value of volume envelope state variable	*/  
+						/* 0x8000-n == 666*n usec delay	       			*/
+
+#define ATKHLDV 		0x11		/* Volume envelope hold and attack register		*/
+#define ATKHLDV_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDV_HOLDTIME_MASK	0x00007f00	/* Envelope hold time (127-n == n*88.2msec)		*/
+#define ATKHLDV_ATTACKTIME_MASK	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/
+
+#define DCYSUSV 		0x12		/* Volume envelope sustain and decay register		*/
+#define DCYSUSV_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSV_CHANNELENABLE_MASK 0x00000080	/* 1 = Inhibit envelope engine from writing values in	*/
+						/* this channel and from writing to pitch, filter and	*/
+						/* volume targets.					*/
+#define DCYSUSV_DECAYTIME_MASK	0x0000007f	/* Volume envelope decay time, log encoded     		*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL1 		0x13		/* Modulation LFO value					*/
+#define LFOVAL_MASK		0x0000ffff	/* Current value of modulation LFO state variable	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ENVVAL			0x14		/* Modulation envelope register				*/
+#define ENVVAL_MASK		0x0000ffff	/* Current value of modulation envelope state variable 	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ATKHLDM			0x15		/* Modulation envelope hold and attack register		*/
+#define ATKHLDM_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDM_HOLDTIME	0x00007f00	/* Envelope hold time (127-n == n*42msec)		*/
+#define ATKHLDM_ATTACKTIME	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/
+
+#define DCYSUSM			0x16		/* Modulation envelope decay and sustain register	*/
+#define DCYSUSM_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSM_DECAYTIME_MASK	0x0000007f	/* Envelope decay time, log encoded			*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL2 		0x17		/* Vibrato LFO register					*/
+#define LFOVAL2_MASK		0x0000ffff	/* Current value of vibrato LFO state variable 		*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define IP			0x18		/* Initial pitch register				*/
+#define IP_MASK			0x0000ffff	/* Exponential initial pitch shift			*/
+						/* 4 bits of octave, 12 bits of fractional octave	*/
+#define IP_UNITY		0x0000e000	/* Unity pitch shift					*/
+
+#define IFATN			0x19		/* Initial filter cutoff and attenuation register	*/
+#define IFATN_FILTERCUTOFF_MASK	0x0000ff00	/* Initial filter cutoff frequency in exponential units	*/
+						/* 6 most significant bits are semitones		*/
+						/* 2 least significant bits are fractions		*/
+#define IFATN_FILTERCUTOFF	0x08080019
+#define IFATN_ATTENUATION_MASK	0x000000ff	/* Initial attenuation in 0.375dB steps			*/
+#define IFATN_ATTENUATION	0x08000019
+
+
+#define PEFE			0x1a		/* Pitch envelope and filter envelope amount register	*/
+#define PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount					*/
+						/* Signed 2's complement, +/- one octave peak extremes	*/
+#define PEFE_PITCHAMOUNT	0x0808001a
+#define PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount				*/
+						/* Signed 2's complement, +/- six octaves peak extremes */
+#define PEFE_FILTERAMOUNT	0x0800001a
+#define FMMOD			0x1b		/* Vibrato/filter modulation from LFO register		*/
+#define FMMOD_MODVIBRATO	0x0000ff00	/* Vibrato LFO modulation depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FMMOD_MOFILTER		0x000000ff	/* Filter LFO modulation depth				*/
+						/* Signed 2's complement, +/- three octave extremes	*/
+
+
+#define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
+#define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
+						/* Signed 2's complement, with +/- 12dB extremes	*/
+
+#define TREMFRQ_FREQUENCY	0x000000ff	/* Tremolo LFO frequency				*/
+						/* ??Hz steps, maximum of ?? Hz.			*/
+#define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
+#define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FM2FRQ2_FREQUENCY	0x000000ff	/* Vibrato LFO frequency				*/
+						/* 0.039Hz steps, maximum of 9.85 Hz.			*/
+
+#define TEMPENV 		0x1e		/* Tempory envelope register				*/
+#define TEMPENV_MASK		0x0000ffff	/* 16-bit value						*/
+						/* NOTE: All channels contain internal variables; do	*/
+						/* not write to these locations.			*/
+
+/* 0x1f: not used */
+
+#define CD0			0x20		/* Cache data 0 register				*/
+#define CD1			0x21		/* Cache data 1 register				*/
+#define CD2			0x22		/* Cache data 2 register				*/
+#define CD3			0x23		/* Cache data 3 register				*/
+#define CD4			0x24		/* Cache data 4 register				*/
+#define CD5			0x25		/* Cache data 5 register				*/
+#define CD6			0x26		/* Cache data 6 register				*/
+#define CD7			0x27		/* Cache data 7 register				*/
+#define CD8			0x28		/* Cache data 8 register				*/
+#define CD9			0x29		/* Cache data 9 register				*/
+#define CDA			0x2a		/* Cache data A register				*/
+#define CDB			0x2b		/* Cache data B register				*/
+#define CDC			0x2c		/* Cache data C register				*/
+#define CDD			0x2d		/* Cache data D register				*/
+#define CDE			0x2e		/* Cache data E register				*/
+#define CDF			0x2f		/* Cache data F register				*/
+
+/* 0x30-3f seem to be the same as 0x20-2f */
+
+#define PTB			0x40		/* Page table base register				*/
+#define PTB_MASK		0xfffff000	/* Physical address of the page table in host memory	*/
+
+#define TCB			0x41		/* Tank cache base register    				*/
+#define TCB_MASK		0xfffff000	/* Physical address of the bottom of host based TRAM	*/
+
+#define ADCCR			0x42		/* ADC sample rate/stereo control register		*/
+#define ADCCR_RCHANENABLE	0x00000010	/* Enables right channel for writing to the host       	*/
+#define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
+						/* NOTE: To guarantee phase coherency, both channels	*/
+						/* must be disabled prior to enabling both channels.	*/
+#define A_ADCCR_RCHANENABLE	0x00000020
+#define A_ADCCR_LCHANENABLE	0x00000010
+
+#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor output rate		*/
+#define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
+#define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
+#define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
+#define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
+#define ADCCR_SAMPLERATE_24	0x00000003	/* 24kHz sample rate					*/
+#define ADCCR_SAMPLERATE_22	0x00000004	/* 22.05kHz sample rate					*/
+#define ADCCR_SAMPLERATE_16	0x00000005	/* 16kHz sample rate					*/
+#define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
+#define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
+#define A_ADCCR_SAMPLERATE_12	0x00000006	/* 12kHz sample rate					*/
+#define A_ADCCR_SAMPLERATE_11	0x00000007	/* 11.025kHz sample rate				*/
+#define A_ADCCR_SAMPLERATE_8	0x00000008	/* 8kHz sample rate					*/
+
+#define FXWC			0x43		/* FX output write channels register			*/
+						/* When set, each bit enables the writing of the	*/
+						/* corresponding FX output channel (internal registers  */
+						/* 0x20-0x3f) to host memory.  This mode of recording   */
+						/* is 16bit, 48KHz only. All 32 channels can be enabled */
+						/* simultaneously.					*/
+
+#define FXWC_DEFAULTROUTE_C     (1<<0)		/* left emu out? */
+#define FXWC_DEFAULTROUTE_B     (1<<1)		/* right emu out? */
+#define FXWC_DEFAULTROUTE_A     (1<<12)
+#define FXWC_DEFAULTROUTE_D     (1<<13)
+#define FXWC_ADCLEFT            (1<<18)
+#define FXWC_CDROMSPDIFLEFT     (1<<18)
+#define FXWC_ADCRIGHT           (1<<19)
+#define FXWC_CDROMSPDIFRIGHT    (1<<19)
+#define FXWC_MIC                (1<<20)
+#define FXWC_ZOOMLEFT           (1<<20)
+#define FXWC_ZOOMRIGHT          (1<<21)
+#define FXWC_SPDIFLEFT          (1<<22)		/* 0x00400000 */
+#define FXWC_SPDIFRIGHT         (1<<23)		/* 0x00800000 */
+
+#define A_TBLSZ			0x43	/* Effects Tank Internal Table Size. Only low byte or register used */
+
+#define TCBS			0x44		/* Tank cache buffer size register			*/
+#define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
+#define TCBS_BUFFSIZE_16K	0x00000000
+#define TCBS_BUFFSIZE_32K	0x00000001
+#define TCBS_BUFFSIZE_64K	0x00000002
+#define TCBS_BUFFSIZE_128K	0x00000003
+#define TCBS_BUFFSIZE_256K	0x00000004
+#define TCBS_BUFFSIZE_512K	0x00000005
+#define TCBS_BUFFSIZE_1024K	0x00000006
+#define TCBS_BUFFSIZE_2048K	0x00000007
+
+#define MICBA			0x45		/* AC97 microphone buffer address register		*/
+#define MICBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define ADCBA			0x46		/* ADC buffer address register				*/
+#define ADCBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define FXBA			0x47		/* FX Buffer Address */
+#define FXBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define A_HWM			0x48	/* High PCI Water Mark - word access, defaults to 3f */
+
+#define MICBS			0x49		/* Microphone buffer size register			*/
+
+#define ADCBS			0x4a		/* ADC buffer size register				*/
+
+#define FXBS			0x4b		/* FX buffer size register				*/
+
+/* register: 0x4c..4f: ffff-ffff current amounts, per-channel */
+
+/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
+#define ADCBS_BUFSIZE_NONE	0x00000000
+#define ADCBS_BUFSIZE_384	0x00000001
+#define ADCBS_BUFSIZE_448	0x00000002
+#define ADCBS_BUFSIZE_512	0x00000003
+#define ADCBS_BUFSIZE_640	0x00000004
+#define ADCBS_BUFSIZE_768	0x00000005
+#define ADCBS_BUFSIZE_896	0x00000006
+#define ADCBS_BUFSIZE_1024	0x00000007
+#define ADCBS_BUFSIZE_1280	0x00000008
+#define ADCBS_BUFSIZE_1536	0x00000009
+#define ADCBS_BUFSIZE_1792	0x0000000a
+#define ADCBS_BUFSIZE_2048	0x0000000b
+#define ADCBS_BUFSIZE_2560	0x0000000c
+#define ADCBS_BUFSIZE_3072	0x0000000d
+#define ADCBS_BUFSIZE_3584	0x0000000e
+#define ADCBS_BUFSIZE_4096	0x0000000f
+#define ADCBS_BUFSIZE_5120	0x00000010
+#define ADCBS_BUFSIZE_6144	0x00000011
+#define ADCBS_BUFSIZE_7168	0x00000012
+#define ADCBS_BUFSIZE_8192	0x00000013
+#define ADCBS_BUFSIZE_10240	0x00000014
+#define ADCBS_BUFSIZE_12288	0x00000015
+#define ADCBS_BUFSIZE_14366	0x00000016
+#define ADCBS_BUFSIZE_16384	0x00000017
+#define ADCBS_BUFSIZE_20480	0x00000018
+#define ADCBS_BUFSIZE_24576	0x00000019
+#define ADCBS_BUFSIZE_28672	0x0000001a
+#define ADCBS_BUFSIZE_32768	0x0000001b
+#define ADCBS_BUFSIZE_40960	0x0000001c
+#define ADCBS_BUFSIZE_49152	0x0000001d
+#define ADCBS_BUFSIZE_57344	0x0000001e
+#define ADCBS_BUFSIZE_65536	0x0000001f
+
+/* Current Send B, A Amounts */
+#define A_CSBA			0x4c
+
+/* Current Send D, C Amounts */
+#define A_CSDC			0x4d
+
+/* Current Send F, E Amounts */
+#define A_CSFE			0x4e
+
+/* Current Send H, G Amounts */
+#define A_CSHG			0x4f
+
+
+#define CDCS			0x50		/* CD-ROM digital channel status register	*/
+
+#define GPSCS			0x51		/* General Purpose SPDIF channel status register*/
+
+#define DBG			0x52		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+/* S/PDIF Input C Channel Status */
+#define A_SPSC			0x52
+
+#define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+#define A_DBG			 0x53
+#define A_DBG_SINGLE_STEP	 0x00020000	/* Set to zero to start dsp */
+#define A_DBG_ZC		 0x40000000	/* zero tram counter */
+#define A_DBG_STEP_ADDR		 0x000003ff
+#define A_DBG_SATURATION_OCCURED 0x20000000
+#define A_DBG_SATURATION_ADDR	 0x0ffc0000
+
+// NOTE: 0x54,55,56: 64-bit
+#define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
+
+#define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
+
+#define SPCS2			0x56		/* SPDIF output Channel Status 2 register	*/
+
+#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
+#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
+#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
+#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
+#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
+#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
+#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
+#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
+#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
+#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
+#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
+#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
+#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
+#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
+#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
+#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
+#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
+#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
+#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
+#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
+#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
+#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
+#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
+
+/* 0x57: Not used */
+
+/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status      		*/
+#define CLIEL			0x58		/* Channel loop interrupt enable low register	*/
+
+#define CLIEH			0x59		/* Channel loop interrupt enable high register	*/
+
+#define CLIPL			0x5a		/* Channel loop interrupt pending low register	*/
+
+#define CLIPH			0x5b		/* Channel loop interrupt pending high register	*/
+
+#define SOLEL			0x5c		/* Stop on loop enable low register		*/
+
+#define SOLEH			0x5d		/* Stop on loop enable high register		*/
+
+#define SPBYPASS		0x5e		/* SPDIF BYPASS mode register			*/
+#define SPBYPASS_SPDIF0_MASK	0x00000003	/* SPDIF 0 bypass mode				*/
+#define SPBYPASS_SPDIF1_MASK	0x0000000c	/* SPDIF 1 bypass mode				*/
+/* bypass mode: 0 - DSP; 1 - SPDIF A, 2 - SPDIF B, 3 - SPDIF C					*/
+#define SPBYPASS_FORMAT		0x00000f00      /* If 1, SPDIF XX uses 24 bit, if 0 - 20 bit	*/
+
+#define AC97SLOT		0x5f            /* additional AC97 slots enable bits		*/
+#define AC97SLOT_REAR_RIGHT	0x01		/* Rear left */
+#define AC97SLOT_REAR_LEFT	0x02		/* Rear right */
+#define AC97SLOT_CNTR		0x10            /* Center enable */
+#define AC97SLOT_LFE		0x20            /* LFE enable */
+
+/* PCB Revision */
+#define A_PCB			0x5f
+
+// NOTE: 0x60,61,62: 64-bit
+#define CDSRCS			0x60		/* CD-ROM Sample Rate Converter status register	*/
+
+#define GPSRCS			0x61		/* General Purpose SPDIF sample rate cvt status */
+
+#define ZVSRCS			0x62		/* ZVideo sample rate converter status		*/
+						/* NOTE: This one has no SPDIFLOCKED field	*/
+						/* Assumes sample lock				*/
+
+/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
+#define SRCS_SPDIFVALID		0x04000000	/* SPDIF stream valid				*/
+#define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
+#define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
+#define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
+
+/* Note that these values can vary +/- by a small amount                                        */
+#define SRCS_SPDIFRATE_44	0x0003acd9
+#define SRCS_SPDIFRATE_48	0x00040000
+#define SRCS_SPDIFRATE_96	0x00080000
+
+#define MICIDX                  0x63            /* Microphone recording buffer index register   */
+#define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
+#define MICIDX_IDX		0x10000063
+
+#define ADCIDX			0x64		/* ADC recording buffer index register		*/
+#define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
+#define ADCIDX_IDX		0x10000064
+
+#define A_ADCIDX		0x63
+#define A_ADCIDX_IDX		0x10000063
+
+#define A_MICIDX		0x64
+#define A_MICIDX_IDX		0x10000064
+
+#define FXIDX			0x65		/* FX recording buffer index register		*/
+#define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
+#define FXIDX_IDX		0x10000065
+
+/* The 32-bit HLIx and HLIPx registers all have one bit per channel control/status      		*/
+#define HLIEL			0x66		/* Channel half loop interrupt enable low register	*/
+
+#define HLIEH			0x67		/* Channel half loop interrupt enable high register	*/
+
+#define HLIPL			0x68		/* Channel half loop interrupt pending low register	*/
+
+#define HLIPH			0x69		/* Channel half loop interrupt pending high register	*/
+
+/* S/PDIF Host Record Index (bypasses SRC) */
+#define A_SPRI			0x6a
+/* S/PDIF Host Record Address */
+#define A_SPRA			0x6b
+/* S/PDIF Host Record Control */
+#define A_SPRC			0x6c
+/* Delayed Interrupt Counter & Enable */
+#define A_DICE			0x6d
+/* Tank Table Base */
+#define A_TTB			0x6e
+/* Tank Delay Offset */
+#define A_TDOF			0x6f
+
+/* This is the MPU port on the card (via the game port)						*/
+#define A_MUDATA1		0x70
+#define A_MUCMD1		0x71
+#define A_MUSTAT1		A_MUCMD1
+
+/* This is the MPU port on the Audigy Drive 							*/
+#define A_MUDATA2		0x72
+#define A_MUCMD2		0x73
+#define A_MUSTAT2		A_MUCMD2	
+
+/* The next two are the Audigy equivalent of FXWC						*/
+/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) 		*/
+/* Each bit selects a channel for recording */
+#define A_FXWC1			0x74            /* Selects 0x7f-0x60 for FX recording           */
+#define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
+
+/* Extended Hardware Control */
+#define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
+#define A_SAMPLE_RATE		0x76		/* Various sample rate settings. */
+#define A_SAMPLE_RATE_NOT_USED  0x0ffc111e	/* Bits that are not used and cannot be set. 	*/
+#define A_SAMPLE_RATE_UNKNOWN	0xf0030001	/* Bits that can be set, but have unknown use. 	*/
+#define A_SPDIF_RATE_MASK	0x000000e0	/* Any other values for rates, just use 48000	*/
+#define A_SPDIF_48000		0x00000000
+#define A_SPDIF_192000		0x00000020
+#define A_SPDIF_96000		0x00000040
+#define A_SPDIF_44100		0x00000080
+
+#define A_I2S_CAPTURE_RATE_MASK	0x00000e00	/* This sets the capture PCM rate, but it is    */
+#define A_I2S_CAPTURE_48000	0x00000000	/* unclear if this sets the ADC rate as well.	*/
+#define A_I2S_CAPTURE_192000	0x00000200
+#define A_I2S_CAPTURE_96000	0x00000400
+#define A_I2S_CAPTURE_44100	0x00000800
+
+#define A_PCM_RATE_MASK		0x0000e000	/* This sets the playback PCM rate on the P16V	*/
+#define A_PCM_48000		0x00000000
+#define A_PCM_192000		0x00002000
+#define A_PCM_96000		0x00004000
+#define A_PCM_44100		0x00008000
+
+/* I2S0 Sample Rate Tracker Status */
+#define A_SRT3			0x77
+
+/* I2S1 Sample Rate Tracker Status */
+#define A_SRT4			0x78
+
+/* I2S2 Sample Rate Tracker Status */
+#define A_SRT5			0x79
+/* - default to 0x01080000 on my audigy 2 ZS --rlrevell	*/
+
+/* Tank Table DMA Address */
+#define A_TTDA			0x7a
+/* Tank Table DMA Data */
+#define A_TTDD			0x7b
+
+#define A_FXRT2			0x7c
+#define A_FXRT_CHANNELE		0x0000003f	/* Effects send bus number for channel's effects send E	*/
+#define A_FXRT_CHANNELF		0x00003f00	/* Effects send bus number for channel's effects send F	*/
+#define A_FXRT_CHANNELG		0x003f0000	/* Effects send bus number for channel's effects send G	*/
+#define A_FXRT_CHANNELH		0x3f000000	/* Effects send bus number for channel's effects send H	*/
+
+#define A_SENDAMOUNTS		0x7d
+#define A_FXSENDAMOUNT_E_MASK	0xFF000000
+#define A_FXSENDAMOUNT_F_MASK	0x00FF0000
+#define A_FXSENDAMOUNT_G_MASK	0x0000FF00
+#define A_FXSENDAMOUNT_H_MASK	0x000000FF
+/* 0x7c, 0x7e "high bit is used for filtering" */
+ 
+/* The send amounts for this one are the same as used with the emu10k1 */
+#define A_FXRT1			0x7e
+#define A_FXRT_CHANNELA		0x0000003f
+#define A_FXRT_CHANNELB		0x00003f00
+#define A_FXRT_CHANNELC		0x003f0000
+#define A_FXRT_CHANNELD		0x3f000000
+
+/* 0x7f: Not used */
+/* Each FX general purpose register is 32 bits in length, all bits are used			*/
+#define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
+#define A_FXGPREGBASE		0x400		/* Audigy GPRs, 0x400 to 0x5ff			*/
+
+#define A_TANKMEMCTLREGBASE	0x100		/* Tank memory control registers base - only for Audigy */
+#define A_TANKMEMCTLREG_MASK	0x1f		/* only 5 bits used - only for Audigy */
+
+/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
+/* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
+/* locations are for external TRAM. 								*/
+#define TANKMEMDATAREGBASE	0x200		/* Tank memory data registers base     		*/
+#define TANKMEMDATAREG_MASK	0x000fffff	/* 20 bit tank audio data field			*/
+
+/* Combined address field and memory opcode or flag field.  160 locations, last 32 are external	*/
+#define TANKMEMADDRREGBASE	0x300		/* Tank memory address registers base		*/
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
+#define TANKMEMADDRREG_CLEAR	0x00800000	/* Clear tank memory				*/
+#define TANKMEMADDRREG_ALIGN	0x00400000	/* Align read or write relative to tank access	*/
+#define TANKMEMADDRREG_WRITE	0x00200000	/* Write to tank memory				*/
+#define TANKMEMADDRREG_READ	0x00100000	/* Read from tank memory			*/
+
+#define MICROCODEBASE		0x400		/* Microcode data base address			*/
+
+/* Each DSP microcode instruction is mapped into 2 doublewords 					*/
+/* NOTE: When writing, always write the LO doubleword first.  Reads can be in either order.	*/
+#define LOWORD_OPX_MASK		0x000ffc00	/* Instruction operand X			*/
+#define LOWORD_OPY_MASK		0x000003ff	/* Instruction operand Y			*/
+#define HIWORD_OPCODE_MASK	0x00f00000	/* Instruction opcode				*/
+#define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
+#define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
+
+
+/* Audigy Soundcard have a different instruction format */
+#define A_MICROCODEBASE		0x600
+#define A_LOWORD_OPY_MASK	0x000007ff
+#define A_LOWORD_OPX_MASK	0x007ff000
+#define A_HIWORD_OPCODE_MASK	0x0f000000
+#define A_HIWORD_RESULT_MASK	0x007ff000
+#define A_HIWORD_OPA_MASK	0x000007ff
+
+/************************************************************************************************/
+/* EMU1010m HANA FPGA registers									*/
+/************************************************************************************************/
+#define EMU_HANA_DESTHI		0x00	/* 0000xxx  3 bits Link Destination */
+#define EMU_HANA_DESTLO		0x01	/* 00xxxxx  5 bits */
+#define EMU_HANA_SRCHI		0x02	/* 0000xxx  3 bits Link Source */
+#define EMU_HANA_SRCLO		0x03	/* 00xxxxx  5 bits */
+#define EMU_HANA_DOCK_PWR	0x04	/* 000000x  1 bits Audio Dock power */
+#define EMU_HANA_DOCK_PWR_ON		0x01 /* Audio Dock power on */
+#define EMU_HANA_WCLOCK		0x05	/* 0000xxx  3 bits Word Clock source select  */
+					/* Must be written after power on to reset DLL */
+					/* One is unable to detect the Audio dock without this */
+#define EMU_HANA_WCLOCK_SRC_MASK	0x07
+#define EMU_HANA_WCLOCK_INT_48K		0x00
+#define EMU_HANA_WCLOCK_INT_44_1K	0x01
+#define EMU_HANA_WCLOCK_HANA_SPDIF_IN	0x02
+#define EMU_HANA_WCLOCK_HANA_ADAT_IN	0x03
+#define EMU_HANA_WCLOCK_SYNC_BNCN	0x04
+#define EMU_HANA_WCLOCK_2ND_HANA	0x05
+#define EMU_HANA_WCLOCK_SRC_RESERVED	0x06
+#define EMU_HANA_WCLOCK_OFF		0x07 /* For testing, forces fallback to DEFCLOCK */
+#define EMU_HANA_WCLOCK_MULT_MASK	0x18
+#define EMU_HANA_WCLOCK_1X		0x00
+#define EMU_HANA_WCLOCK_2X		0x08
+#define EMU_HANA_WCLOCK_4X		0x10
+#define EMU_HANA_WCLOCK_MULT_RESERVED	0x18
+
+#define EMU_HANA_DEFCLOCK	0x06	/* 000000x  1 bits Default Word Clock  */
+#define EMU_HANA_DEFCLOCK_48K		0x00
+#define EMU_HANA_DEFCLOCK_44_1K		0x01
+
+#define EMU_HANA_UNMUTE		0x07	/* 000000x  1 bits Mute all audio outputs  */
+#define EMU_MUTE			0x00
+#define EMU_UNMUTE			0x01
+
+#define EMU_HANA_FPGA_CONFIG	0x08	/* 00000xx  2 bits Config control of FPGAs  */
+#define EMU_HANA_FPGA_CONFIG_AUDIODOCK	0x01 /* Set in order to program FPGA on Audio Dock */
+#define EMU_HANA_FPGA_CONFIG_HANA	0x02 /* Set in order to program FPGA on Hana */
+
+#define EMU_HANA_IRQ_ENABLE	0x09	/* 000xxxx  4 bits IRQ Enable  */
+#define EMU_HANA_IRQ_WCLK_CHANGED	0x01
+#define EMU_HANA_IRQ_ADAT		0x02
+#define EMU_HANA_IRQ_DOCK		0x04
+#define EMU_HANA_IRQ_DOCK_LOST		0x08
+
+#define EMU_HANA_SPDIF_MODE	0x0a	/* 00xxxxx  5 bits SPDIF MODE  */
+#define EMU_HANA_SPDIF_MODE_TX_COMSUMER	0x00
+#define EMU_HANA_SPDIF_MODE_TX_PRO	0x01
+#define EMU_HANA_SPDIF_MODE_TX_NOCOPY	0x02
+#define EMU_HANA_SPDIF_MODE_RX_COMSUMER	0x00
+#define EMU_HANA_SPDIF_MODE_RX_PRO	0x04
+#define EMU_HANA_SPDIF_MODE_RX_NOCOPY	0x08
+#define EMU_HANA_SPDIF_MODE_RX_INVALID	0x10
+
+#define EMU_HANA_OPTICAL_TYPE	0x0b	/* 00000xx  2 bits ADAT or SPDIF in/out  */
+#define EMU_HANA_OPTICAL_IN_SPDIF	0x00
+#define EMU_HANA_OPTICAL_IN_ADAT	0x01
+#define EMU_HANA_OPTICAL_OUT_SPDIF	0x00
+#define EMU_HANA_OPTICAL_OUT_ADAT	0x02
+
+#define EMU_HANA_MIDI_IN		0x0c	/* 000000x  1 bit  Control MIDI  */
+#define EMU_HANA_MIDI_IN_FROM_HAMOA	0x00 /* HAMOA MIDI in to Alice 2 MIDI B */
+#define EMU_HANA_MIDI_IN_FROM_DOCK	0x01 /* Audio Dock MIDI in to Alice 2 MIDI B */
+
+#define EMU_HANA_DOCK_LEDS_1	0x0d	/* 000xxxx  4 bit  Audio Dock LEDs  */
+#define EMU_HANA_DOCK_LEDS_1_MIDI1	0x01	/* MIDI 1 LED on */
+#define EMU_HANA_DOCK_LEDS_1_MIDI2	0x02	/* MIDI 2 LED on */
+#define EMU_HANA_DOCK_LEDS_1_SMPTE_IN	0x04	/* SMPTE IN LED on */
+#define EMU_HANA_DOCK_LEDS_1_SMPTE_OUT	0x08	/* SMPTE OUT LED on */
+
+#define EMU_HANA_DOCK_LEDS_2	0x0e	/* 0xxxxxx  6 bit  Audio Dock LEDs  */
+#define EMU_HANA_DOCK_LEDS_2_44K	0x01	/* 44.1 kHz LED on */
+#define EMU_HANA_DOCK_LEDS_2_48K	0x02	/* 48 kHz LED on */
+#define EMU_HANA_DOCK_LEDS_2_96K	0x04	/* 96 kHz LED on */
+#define EMU_HANA_DOCK_LEDS_2_192K	0x08	/* 192 kHz LED on */
+#define EMU_HANA_DOCK_LEDS_2_LOCK	0x10	/* LOCK LED on */
+#define EMU_HANA_DOCK_LEDS_2_EXT	0x20	/* EXT LED on */
+
+#define EMU_HANA_DOCK_LEDS_3	0x0f	/* 0xxxxxx  6 bit  Audio Dock LEDs  */
+#define EMU_HANA_DOCK_LEDS_3_CLIP_A	0x01	/* Mic A Clip LED on */
+#define EMU_HANA_DOCK_LEDS_3_CLIP_B	0x02	/* Mic B Clip LED on */
+#define EMU_HANA_DOCK_LEDS_3_SIGNAL_A	0x04	/* Signal A Clip LED on */
+#define EMU_HANA_DOCK_LEDS_3_SIGNAL_B	0x08	/* Signal B Clip LED on */
+#define EMU_HANA_DOCK_LEDS_3_MANUAL_CLIP	0x10	/* Manual Clip detection */
+#define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL	0x20	/* Manual Signal detection */
+
+#define EMU_HANA_ADC_PADS	0x10	/* 0000xxx  3 bit  Audio Dock ADC 14dB pads */
+#define EMU_HANA_DOCK_ADC_PAD1	0x01	/* 14dB Attenuation on Audio Dock ADC 1 */
+#define EMU_HANA_DOCK_ADC_PAD2	0x02	/* 14dB Attenuation on Audio Dock ADC 2 */
+#define EMU_HANA_DOCK_ADC_PAD3	0x04	/* 14dB Attenuation on Audio Dock ADC 3 */
+#define EMU_HANA_0202_ADC_PAD1	0x08	/* 14dB Attenuation on 0202 ADC 1 */
+
+#define EMU_HANA_DOCK_MISC	0x11	/* 0xxxxxx  6 bit  Audio Dock misc bits */
+#define EMU_HANA_DOCK_DAC1_MUTE	0x01	/* DAC 1 Mute */
+#define EMU_HANA_DOCK_DAC2_MUTE	0x02	/* DAC 2 Mute */
+#define EMU_HANA_DOCK_DAC3_MUTE	0x04	/* DAC 3 Mute */
+#define EMU_HANA_DOCK_DAC4_MUTE	0x08	/* DAC 4 Mute */
+#define EMU_HANA_DOCK_PHONES_192_DAC1	0x00	/* DAC 1 Headphones source at 192kHz */
+#define EMU_HANA_DOCK_PHONES_192_DAC2	0x10	/* DAC 2 Headphones source at 192kHz */
+#define EMU_HANA_DOCK_PHONES_192_DAC3	0x20	/* DAC 3 Headphones source at 192kHz */
+#define EMU_HANA_DOCK_PHONES_192_DAC4	0x30	/* DAC 4 Headphones source at 192kHz */
+
+#define EMU_HANA_MIDI_OUT	0x12	/* 00xxxxx  5 bit  Source for each MIDI out port */
+#define EMU_HANA_MIDI_OUT_0202	0x01 /* 0202 MIDI from Alice 2. 0 = A, 1 = B */
+#define EMU_HANA_MIDI_OUT_DOCK1	0x02 /* Audio Dock MIDI1 front, from Alice 2. 0 = A, 1 = B */
+#define EMU_HANA_MIDI_OUT_DOCK2	0x04 /* Audio Dock MIDI2 rear, from Alice 2. 0 = A, 1 = B */
+#define EMU_HANA_MIDI_OUT_SYNC2	0x08 /* Sync card. Not the actual MIDI out jack. 0 = A, 1 = B */
+#define EMU_HANA_MIDI_OUT_LOOP	0x10 /* 0 = bits (3:0) normal. 1 = MIDI loopback enabled. */
+
+#define EMU_HANA_DAC_PADS	0x13	/* 00xxxxx  5 bit  DAC 14dB attenuation pads */
+#define EMU_HANA_DOCK_DAC_PAD1	0x01	/* 14dB Attenuation on AudioDock DAC 1. Left and Right */
+#define EMU_HANA_DOCK_DAC_PAD2	0x02	/* 14dB Attenuation on AudioDock DAC 2. Left and Right */
+#define EMU_HANA_DOCK_DAC_PAD3	0x04	/* 14dB Attenuation on AudioDock DAC 3. Left and Right */
+#define EMU_HANA_DOCK_DAC_PAD4	0x08	/* 14dB Attenuation on AudioDock DAC 4. Left and Right */
+#define EMU_HANA_0202_DAC_PAD1	0x10	/* 14dB Attenuation on 0202 DAC 1. Left and Right */
+
+/* 0x14 - 0x1f Unused R/W registers */
+#define EMU_HANA_IRQ_STATUS	0x20	/* 000xxxx  4 bits IRQ Status  */
+#if 0  /* Already defined for reg 0x09 IRQ_ENABLE */
+#define EMU_HANA_IRQ_WCLK_CHANGED	0x01
+#define EMU_HANA_IRQ_ADAT		0x02
+#define EMU_HANA_IRQ_DOCK		0x04
+#define EMU_HANA_IRQ_DOCK_LOST		0x08
+#endif
+
+#define EMU_HANA_OPTION_CARDS	0x21	/* 000xxxx  4 bits Presence of option cards */
+#define EMU_HANA_OPTION_HAMOA	0x01	/* HAMOA card present */
+#define EMU_HANA_OPTION_SYNC	0x02	/* Sync card present */
+#define EMU_HANA_OPTION_DOCK_ONLINE	0x04	/* Audio Dock online and FPGA configured */
+#define EMU_HANA_OPTION_DOCK_OFFLINE	0x08	/* Audio Dock online and FPGA not configured */
+
+#define EMU_HANA_ID		0x22	/* 1010101  7 bits ID byte & 0x7f = 0x55 */
+
+#define EMU_HANA_MAJOR_REV	0x23	/* 0000xxx  3 bit  Hana FPGA Major rev */
+#define EMU_HANA_MINOR_REV	0x24	/* 0000xxx  3 bit  Hana FPGA Minor rev */
+
+#define EMU_DOCK_MAJOR_REV	0x25	/* 0000xxx  3 bit  Audio Dock FPGA Major rev */
+#define EMU_DOCK_MINOR_REV	0x26	/* 0000xxx  3 bit  Audio Dock FPGA Minor rev */
+
+#define EMU_DOCK_BOARD_ID	0x27	/* 00000xx  2 bits Audio Dock ID pins */
+#define EMU_DOCK_BOARD_ID0	0x00	/* ID bit 0 */
+#define EMU_DOCK_BOARD_ID1	0x03	/* ID bit 1 */
+
+#define EMU_HANA_WC_SPDIF_HI	0x28	/* 0xxxxxx  6 bit  SPDIF IN Word clock, upper 6 bits */
+#define EMU_HANA_WC_SPDIF_LO	0x29	/* 0xxxxxx  6 bit  SPDIF IN Word clock, lower 6 bits */
+
+#define EMU_HANA_WC_ADAT_HI	0x2a	/* 0xxxxxx  6 bit  ADAT IN Word clock, upper 6 bits */
+#define EMU_HANA_WC_ADAT_LO	0x2b	/* 0xxxxxx  6 bit  ADAT IN Word clock, lower 6 bits */
+
+#define EMU_HANA_WC_BNC_LO	0x2c	/* 0xxxxxx  6 bit  BNC IN Word clock, lower 6 bits */
+#define EMU_HANA_WC_BNC_HI	0x2d	/* 0xxxxxx  6 bit  BNC IN Word clock, upper 6 bits */
+
+#define EMU_HANA2_WC_SPDIF_HI	0x2e	/* 0xxxxxx  6 bit  HANA2 SPDIF IN Word clock, upper 6 bits */
+#define EMU_HANA2_WC_SPDIF_LO	0x2f	/* 0xxxxxx  6 bit  HANA2 SPDIF IN Word clock, lower 6 bits */
+/* 0x30 - 0x3f Unused Read only registers */
+
+/************************************************************************************************/
+/* EMU1010m HANA Destinations									*/
+/************************************************************************************************/
+/* Hana, original 1010,1212,1820 using Alice2
+ * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
+ * 0x01, 0x10-0x1f: 32 Elink channels to Audio Dock
+ * 0x01, 0x00: Dock DAC 1 Left
+ * 0x01, 0x04: Dock DAC 1 Right
+ * 0x01, 0x08: Dock DAC 2 Left
+ * 0x01, 0x0c: Dock DAC 2 Right
+ * 0x01, 0x10: Dock DAC 3 Left
+ * 0x01, 0x12: PHONES Left
+ * 0x01, 0x14: Dock DAC 3 Right
+ * 0x01, 0x16: PHONES Right
+ * 0x01, 0x18: Dock DAC 4 Left
+ * 0x01, 0x1a: S/PDIF Left
+ * 0x01, 0x1c: Dock DAC 4 Right
+ * 0x01, 0x1e: S/PDIF Right
+ * 0x02, 0x00: Hana S/PDIF Left
+ * 0x02, 0x01: Hana S/PDIF Right
+ * 0x03, 0x00: Hanoa DAC Left
+ * 0x03, 0x01: Hanoa DAC Right
+ * 0x04, 0x00-0x07: Hana ADAT
+ * 0x05, 0x00: I2S0 Left to Alice2
+ * 0x05, 0x01: I2S0 Right to Alice2
+ * 0x06, 0x00: I2S0 Left to Alice2
+ * 0x06, 0x01: I2S0 Right to Alice2
+ * 0x07, 0x00: I2S0 Left to Alice2
+ * 0x07, 0x01: I2S0 Right to Alice2
+ *
+ * Hana2 never released, but used Tina
+ * Not needed.
+ *
+ * Hana3, rev2 1010,1212,1616 using Tina
+ * Destinations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina
+ * 0x01, 0x10-0x1f: 32 EDI channels to Micro Dock
+ * 0x01, 0x00: Dock DAC 1 Left
+ * 0x01, 0x04: Dock DAC 1 Right
+ * 0x01, 0x08: Dock DAC 2 Left
+ * 0x01, 0x0c: Dock DAC 2 Right
+ * 0x01, 0x10: Dock DAC 3 Left
+ * 0x01, 0x12: Dock S/PDIF Left
+ * 0x01, 0x14: Dock DAC 3 Right
+ * 0x01, 0x16: Dock S/PDIF Right
+ * 0x01, 0x18-0x1f: Dock ADAT 0-7
+ * 0x02, 0x00: Hana3 S/PDIF Left
+ * 0x02, 0x01: Hana3 S/PDIF Right
+ * 0x03, 0x00: Hanoa DAC Left
+ * 0x03, 0x01: Hanoa DAC Right
+ * 0x04, 0x00-0x07: Hana3 ADAT 0-7
+ * 0x05, 0x00-0x0f: 16 EMU32B channels to Tina
+ * 0x06-0x07: Not used
+ *
+ * HanaLite, rev1 0404 using Alice2
+ * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
+ * 0x01: Not used
+ * 0x02, 0x00: S/PDIF Left
+ * 0x02, 0x01: S/PDIF Right
+ * 0x03, 0x00: DAC Left
+ * 0x03, 0x01: DAC Right
+ * 0x04-0x07: Not used
+ *
+ * HanaLiteLite, rev2 0404 using Alice2
+ * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
+ * 0x01: Not used
+ * 0x02, 0x00: S/PDIF Left
+ * 0x02, 0x01: S/PDIF Right
+ * 0x03, 0x00: DAC Left
+ * 0x03, 0x01: DAC Right
+ * 0x04-0x07: Not used
+ *
+ * Mana, Cardbus 1616 using Tina2
+ * Destinations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina2
+ * 0x01, 0x10-0x1f: 32 EDI channels to Micro Dock
+ * 0x01, 0x00: Dock DAC 1 Left
+ * 0x01, 0x04: Dock DAC 1 Right
+ * 0x01, 0x08: Dock DAC 2 Left
+ * 0x01, 0x0c: Dock DAC 2 Right
+ * 0x01, 0x10: Dock DAC 3 Left
+ * 0x01, 0x12: Dock S/PDIF Left
+ * 0x01, 0x14: Dock DAC 3 Right
+ * 0x01, 0x16: Dock S/PDIF Right
+ * 0x01, 0x18-0x1f: Dock ADAT 0-7
+ * 0x02: Not used
+ * 0x03, 0x00: Mana DAC Left
+ * 0x03, 0x01: Mana DAC Right
+ * 0x04, 0x00-0x0f: 16 EMU32B channels to Tina2
+ * 0x05-0x07: Not used
+ *
+ *
+ */
+/* 32-bit destinations of signal in the Hana FPGA. Destinations are either
+ * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture
+ * - 16 x EMU_DST_ALICE2_EMU32_X.
+ */
+/* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */
+/* EMU_DST_ALICE2_EMU32_X - data channels from Hana to Alice2 used for capture.
+ * Which data is fed into a EMU_DST_ALICE2_EMU32_X channel in Hana depends on
+ * setup of mixer control for each destination - see emumixer.c -
+ * snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[]
+ */
+#define EMU_DST_ALICE2_EMU32_0	0x000f	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_1	0x0000	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_2	0x0001	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_3	0x0002	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_4	0x0003	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_5	0x0004	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_6	0x0005	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_7	0x0006	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_8	0x0007	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_9	0x0008	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_A	0x0009	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_B	0x000a	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_C	0x000b	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_D	0x000c	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_E	0x000d	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_ALICE2_EMU32_F	0x000e	/* 16 EMU32 channels to Alice2 +0 to +0xf */
+#define EMU_DST_DOCK_DAC1_LEFT1	0x0100	/* Audio Dock DAC1 Left, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC1_LEFT2	0x0101	/* Audio Dock DAC1 Left, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC1_LEFT3	0x0102	/* Audio Dock DAC1 Left, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC1_LEFT4	0x0103	/* Audio Dock DAC1 Left, 4th or 192kHz */
+#define EMU_DST_DOCK_DAC1_RIGHT1	0x0104	/* Audio Dock DAC1 Right, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC1_RIGHT2	0x0105	/* Audio Dock DAC1 Right, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC1_RIGHT3	0x0106	/* Audio Dock DAC1 Right, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC1_RIGHT4	0x0107	/* Audio Dock DAC1 Right, 4th or 192kHz */
+#define EMU_DST_DOCK_DAC2_LEFT1	0x0108	/* Audio Dock DAC2 Left, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC2_LEFT2	0x0109	/* Audio Dock DAC2 Left, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC2_LEFT3	0x010a	/* Audio Dock DAC2 Left, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC2_LEFT4	0x010b	/* Audio Dock DAC2 Left, 4th or 192kHz */
+#define EMU_DST_DOCK_DAC2_RIGHT1	0x010c	/* Audio Dock DAC2 Right, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC2_RIGHT2	0x010d	/* Audio Dock DAC2 Right, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC2_RIGHT3	0x010e	/* Audio Dock DAC2 Right, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC2_RIGHT4	0x010f	/* Audio Dock DAC2 Right, 4th or 192kHz */
+#define EMU_DST_DOCK_DAC3_LEFT1	0x0110	/* Audio Dock DAC1 Left, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC3_LEFT2	0x0111	/* Audio Dock DAC1 Left, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC3_LEFT3	0x0112	/* Audio Dock DAC1 Left, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC3_LEFT4	0x0113	/* Audio Dock DAC1 Left, 4th or 192kHz */
+#define EMU_DST_DOCK_PHONES_LEFT1	0x0112	/* Audio Dock PHONES Left, 1st or 48kHz only */
+#define EMU_DST_DOCK_PHONES_LEFT2	0x0113	/* Audio Dock PHONES Left, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC3_RIGHT1	0x0114	/* Audio Dock DAC1 Right, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC3_RIGHT2	0x0115	/* Audio Dock DAC1 Right, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC3_RIGHT3	0x0116	/* Audio Dock DAC1 Right, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC3_RIGHT4	0x0117	/* Audio Dock DAC1 Right, 4th or 192kHz */
+#define EMU_DST_DOCK_PHONES_RIGHT1	0x0116	/* Audio Dock PHONES Right, 1st or 48kHz only */
+#define EMU_DST_DOCK_PHONES_RIGHT2	0x0117	/* Audio Dock PHONES Right, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC4_LEFT1	0x0118	/* Audio Dock DAC2 Left, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC4_LEFT2	0x0119	/* Audio Dock DAC2 Left, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC4_LEFT3	0x011a	/* Audio Dock DAC2 Left, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC4_LEFT4	0x011b	/* Audio Dock DAC2 Left, 4th or 192kHz */
+#define EMU_DST_DOCK_SPDIF_LEFT1	0x011a	/* Audio Dock SPDIF Left, 1st or 48kHz only */
+#define EMU_DST_DOCK_SPDIF_LEFT2	0x011b	/* Audio Dock SPDIF Left, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC4_RIGHT1	0x011c	/* Audio Dock DAC2 Right, 1st or 48kHz only */
+#define EMU_DST_DOCK_DAC4_RIGHT2	0x011d	/* Audio Dock DAC2 Right, 2nd or 96kHz */
+#define EMU_DST_DOCK_DAC4_RIGHT3	0x011e	/* Audio Dock DAC2 Right, 3rd or 192kHz */
+#define EMU_DST_DOCK_DAC4_RIGHT4	0x011f	/* Audio Dock DAC2 Right, 4th or 192kHz */
+#define EMU_DST_DOCK_SPDIF_RIGHT1	0x011e	/* Audio Dock SPDIF Right, 1st or 48kHz only */
+#define EMU_DST_DOCK_SPDIF_RIGHT2	0x011f	/* Audio Dock SPDIF Right, 2nd or 96kHz */
+#define EMU_DST_HANA_SPDIF_LEFT1	0x0200	/* Hana SPDIF Left, 1st or 48kHz only */
+#define EMU_DST_HANA_SPDIF_LEFT2	0x0202	/* Hana SPDIF Left, 2nd or 96kHz */
+#define EMU_DST_HANA_SPDIF_RIGHT1	0x0201	/* Hana SPDIF Right, 1st or 48kHz only */
+#define EMU_DST_HANA_SPDIF_RIGHT2	0x0203	/* Hana SPDIF Right, 2nd or 96kHz */
+#define EMU_DST_HAMOA_DAC_LEFT1	0x0300	/* Hamoa DAC Left, 1st or 48kHz only */
+#define EMU_DST_HAMOA_DAC_LEFT2	0x0302	/* Hamoa DAC Left, 2nd or 96kHz */
+#define EMU_DST_HAMOA_DAC_LEFT3	0x0304	/* Hamoa DAC Left, 3rd or 192kHz */
+#define EMU_DST_HAMOA_DAC_LEFT4	0x0306	/* Hamoa DAC Left, 4th or 192kHz */
+#define EMU_DST_HAMOA_DAC_RIGHT1	0x0301	/* Hamoa DAC Right, 1st or 48kHz only */
+#define EMU_DST_HAMOA_DAC_RIGHT2	0x0303	/* Hamoa DAC Right, 2nd or 96kHz */
+#define EMU_DST_HAMOA_DAC_RIGHT3	0x0305	/* Hamoa DAC Right, 3rd or 192kHz */
+#define EMU_DST_HAMOA_DAC_RIGHT4	0x0307	/* Hamoa DAC Right, 4th or 192kHz */
+#define EMU_DST_HANA_ADAT	0x0400	/* Hana ADAT 8 channel out +0 to +7 */
+#define EMU_DST_ALICE_I2S0_LEFT		0x0500	/* Alice2 I2S0 Left */
+#define EMU_DST_ALICE_I2S0_RIGHT	0x0501	/* Alice2 I2S0 Right */
+#define EMU_DST_ALICE_I2S1_LEFT		0x0600	/* Alice2 I2S1 Left */
+#define EMU_DST_ALICE_I2S1_RIGHT	0x0601	/* Alice2 I2S1 Right */
+#define EMU_DST_ALICE_I2S2_LEFT		0x0700	/* Alice2 I2S2 Left */
+#define EMU_DST_ALICE_I2S2_RIGHT	0x0701	/* Alice2 I2S2 Right */
+
+/* Additional destinations for 1616(M)/Microdock */
+/* Microdock S/PDIF OUT Left, 1st or 48kHz only */
+#define EMU_DST_MDOCK_SPDIF_LEFT1	0x0112
+/* Microdock S/PDIF OUT Left, 2nd or 96kHz */
+#define EMU_DST_MDOCK_SPDIF_LEFT2	0x0113
+/* Microdock S/PDIF OUT Right, 1st or 48kHz only */
+#define EMU_DST_MDOCK_SPDIF_RIGHT1	0x0116
+/* Microdock S/PDIF OUT Right, 2nd or 96kHz  */
+#define EMU_DST_MDOCK_SPDIF_RIGHT2	0x0117
+/* Microdock S/PDIF ADAT 8 channel out +8 to +f */
+#define EMU_DST_MDOCK_ADAT		0x0118
+
+/* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
+#define EMU_DST_MANA_DAC_LEFT		0x0300
+/* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
+#define EMU_DST_MANA_DAC_RIGHT		0x0301
+
+/************************************************************************************************/
+/* EMU1010m HANA Sources									*/
+/************************************************************************************************/
+/* Hana, original 1010,1212,1820 using Alice2
+ * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00,0x00-0x1f: Silence
+ * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock
+ * 0x01, 0x00: Dock Mic A
+ * 0x01, 0x04: Dock Mic B
+ * 0x01, 0x08: Dock ADC 1 Left
+ * 0x01, 0x0c: Dock ADC 1 Right
+ * 0x01, 0x10: Dock ADC 2 Left
+ * 0x01, 0x14: Dock ADC 2 Right
+ * 0x01, 0x18: Dock ADC 3 Left
+ * 0x01, 0x1c: Dock ADC 3 Right
+ * 0x02, 0x00: Hana ADC Left
+ * 0x02, 0x01: Hana ADC Right
+ * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
+ * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
+ * 0x04, 0x00-0x07: Hana ADAT
+ * 0x05, 0x00: Hana S/PDIF Left
+ * 0x05, 0x01: Hana S/PDIF Right
+ * 0x06-0x07: Not used
+ *
+ * Hana2 never released, but used Tina
+ * Not needed.
+ *
+ * Hana3, rev2 1010,1212,1616 using Tina
+ * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00,0x00-0x1f: Silence
+ * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock
+ * 0x01, 0x00: Dock Mic A
+ * 0x01, 0x04: Dock Mic B
+ * 0x01, 0x08: Dock ADC 1 Left
+ * 0x01, 0x0c: Dock ADC 1 Right
+ * 0x01, 0x10: Dock ADC 2 Left
+ * 0x01, 0x12: Dock S/PDIF Left
+ * 0x01, 0x14: Dock ADC 2 Right
+ * 0x01, 0x16: Dock S/PDIF Right
+ * 0x01, 0x18-0x1f: Dock ADAT 0-7
+ * 0x01, 0x18: Dock ADC 3 Left
+ * 0x01, 0x1c: Dock ADC 3 Right
+ * 0x02, 0x00: Hanoa ADC Left
+ * 0x02, 0x01: Hanoa ADC Right
+ * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output
+ * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output
+ * 0x04, 0x00-0x07: Hana3 ADAT
+ * 0x05, 0x00: Hana3 S/PDIF Left
+ * 0x05, 0x01: Hana3 S/PDIF Right
+ * 0x06-0x07: Not used
+ *
+ * HanaLite, rev1 0404 using Alice2
+ * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00,0x00-0x1f: Silence
+ * 0x01: Not used
+ * 0x02, 0x00: ADC Left
+ * 0x02, 0x01: ADC Right
+ * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
+ * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
+ * 0x04: Not used
+ * 0x05, 0x00: S/PDIF Left
+ * 0x05, 0x01: S/PDIF Right
+ * 0x06-0x07: Not used
+ *
+ * HanaLiteLite, rev2 0404 using Alice2
+ * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00,0x00-0x1f: Silence
+ * 0x01: Not used
+ * 0x02, 0x00: ADC Left
+ * 0x02, 0x01: ADC Right
+ * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
+ * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
+ * 0x04: Not used
+ * 0x05, 0x00: S/PDIF Left
+ * 0x05, 0x01: S/PDIF Right
+ * 0x06-0x07: Not used
+ *
+ * Mana, Cardbus 1616 using Tina2
+ * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
+ * 0x00,0x00-0x1f: Silence
+ * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock
+ * 0x01, 0x00: Dock Mic A
+ * 0x01, 0x04: Dock Mic B
+ * 0x01, 0x08: Dock ADC 1 Left
+ * 0x01, 0x0c: Dock ADC 1 Right
+ * 0x01, 0x10: Dock ADC 2 Left
+ * 0x01, 0x12: Dock S/PDIF Left
+ * 0x01, 0x14: Dock ADC 2 Right
+ * 0x01, 0x16: Dock S/PDIF Right
+ * 0x01, 0x18-0x1f: Dock ADAT 0-7
+ * 0x01, 0x18: Dock ADC 3 Left
+ * 0x01, 0x1c: Dock ADC 3 Right
+ * 0x02: Not used
+ * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output
+ * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output
+ * 0x04-0x07: Not used
+ *
+ */
+
+/* 32-bit sources of signal in the Hana FPGA. The sources are routed to
+ * destinations using mixer control for each destination - see emumixer.c
+ * Sources are either physical inputs of FPGA,
+ * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A +
+ * 16 x EMU_SRC_ALICE_EMU32B
+ */
+#define EMU_SRC_SILENCE		0x0000	/* Silence */
+#define EMU_SRC_DOCK_MIC_A1	0x0100	/* Audio Dock Mic A, 1st or 48kHz only */
+#define EMU_SRC_DOCK_MIC_A2	0x0101	/* Audio Dock Mic A, 2nd or 96kHz */
+#define EMU_SRC_DOCK_MIC_A3	0x0102	/* Audio Dock Mic A, 3rd or 192kHz */
+#define EMU_SRC_DOCK_MIC_A4	0x0103	/* Audio Dock Mic A, 4th or 192kHz */
+#define EMU_SRC_DOCK_MIC_B1	0x0104	/* Audio Dock Mic B, 1st or 48kHz only */
+#define EMU_SRC_DOCK_MIC_B2	0x0105	/* Audio Dock Mic B, 2nd or 96kHz */
+#define EMU_SRC_DOCK_MIC_B3	0x0106	/* Audio Dock Mic B, 3rd or 192kHz */
+#define EMU_SRC_DOCK_MIC_B4	0x0107	/* Audio Dock Mic B, 4th or 192kHz */
+#define EMU_SRC_DOCK_ADC1_LEFT1	0x0108	/* Audio Dock ADC1 Left, 1st or 48kHz only */
+#define EMU_SRC_DOCK_ADC1_LEFT2	0x0109	/* Audio Dock ADC1 Left, 2nd or 96kHz */
+#define EMU_SRC_DOCK_ADC1_LEFT3	0x010a	/* Audio Dock ADC1 Left, 3rd or 192kHz */
+#define EMU_SRC_DOCK_ADC1_LEFT4	0x010b	/* Audio Dock ADC1 Left, 4th or 192kHz */
+#define EMU_SRC_DOCK_ADC1_RIGHT1	0x010c	/* Audio Dock ADC1 Right, 1st or 48kHz only */
+#define EMU_SRC_DOCK_ADC1_RIGHT2	0x010d	/* Audio Dock ADC1 Right, 2nd or 96kHz */
+#define EMU_SRC_DOCK_ADC1_RIGHT3	0x010e	/* Audio Dock ADC1 Right, 3rd or 192kHz */
+#define EMU_SRC_DOCK_ADC1_RIGHT4	0x010f	/* Audio Dock ADC1 Right, 4th or 192kHz */
+#define EMU_SRC_DOCK_ADC2_LEFT1	0x0110	/* Audio Dock ADC2 Left, 1st or 48kHz only */
+#define EMU_SRC_DOCK_ADC2_LEFT2	0x0111	/* Audio Dock ADC2 Left, 2nd or 96kHz */
+#define EMU_SRC_DOCK_ADC2_LEFT3	0x0112	/* Audio Dock ADC2 Left, 3rd or 192kHz */
+#define EMU_SRC_DOCK_ADC2_LEFT4	0x0113	/* Audio Dock ADC2 Left, 4th or 192kHz */
+#define EMU_SRC_DOCK_ADC2_RIGHT1	0x0114	/* Audio Dock ADC2 Right, 1st or 48kHz only */
+#define EMU_SRC_DOCK_ADC2_RIGHT2	0x0115	/* Audio Dock ADC2 Right, 2nd or 96kHz */
+#define EMU_SRC_DOCK_ADC2_RIGHT3	0x0116	/* Audio Dock ADC2 Right, 3rd or 192kHz */
+#define EMU_SRC_DOCK_ADC2_RIGHT4	0x0117	/* Audio Dock ADC2 Right, 4th or 192kHz */
+#define EMU_SRC_DOCK_ADC3_LEFT1	0x0118	/* Audio Dock ADC3 Left, 1st or 48kHz only */
+#define EMU_SRC_DOCK_ADC3_LEFT2	0x0119	/* Audio Dock ADC3 Left, 2nd or 96kHz */
+#define EMU_SRC_DOCK_ADC3_LEFT3	0x011a	/* Audio Dock ADC3 Left, 3rd or 192kHz */
+#define EMU_SRC_DOCK_ADC3_LEFT4	0x011b	/* Audio Dock ADC3 Left, 4th or 192kHz */
+#define EMU_SRC_DOCK_ADC3_RIGHT1	0x011c	/* Audio Dock ADC3 Right, 1st or 48kHz only */
+#define EMU_SRC_DOCK_ADC3_RIGHT2	0x011d	/* Audio Dock ADC3 Right, 2nd or 96kHz */
+#define EMU_SRC_DOCK_ADC3_RIGHT3	0x011e	/* Audio Dock ADC3 Right, 3rd or 192kHz */
+#define EMU_SRC_DOCK_ADC3_RIGHT4	0x011f	/* Audio Dock ADC3 Right, 4th or 192kHz */
+#define EMU_SRC_HAMOA_ADC_LEFT1	0x0200	/* Hamoa ADC Left, 1st or 48kHz only */
+#define EMU_SRC_HAMOA_ADC_LEFT2	0x0202	/* Hamoa ADC Left, 2nd or 96kHz */
+#define EMU_SRC_HAMOA_ADC_LEFT3	0x0204	/* Hamoa ADC Left, 3rd or 192kHz */
+#define EMU_SRC_HAMOA_ADC_LEFT4	0x0206	/* Hamoa ADC Left, 4th or 192kHz */
+#define EMU_SRC_HAMOA_ADC_RIGHT1	0x0201	/* Hamoa ADC Right, 1st or 48kHz only */
+#define EMU_SRC_HAMOA_ADC_RIGHT2	0x0203	/* Hamoa ADC Right, 2nd or 96kHz */
+#define EMU_SRC_HAMOA_ADC_RIGHT3	0x0205	/* Hamoa ADC Right, 3rd or 192kHz */
+#define EMU_SRC_HAMOA_ADC_RIGHT4	0x0207	/* Hamoa ADC Right, 4th or 192kHz */
+#define EMU_SRC_ALICE_EMU32A		0x0300	/* Alice2 EMU32a 16 outputs. +0 to +0xf */
+#define EMU_SRC_ALICE_EMU32B		0x0310	/* Alice2 EMU32b 16 outputs. +0 to +0xf */
+#define EMU_SRC_HANA_ADAT	0x0400	/* Hana ADAT 8 channel in +0 to +7 */
+#define EMU_SRC_HANA_SPDIF_LEFT1	0x0500	/* Hana SPDIF Left, 1st or 48kHz only */
+#define EMU_SRC_HANA_SPDIF_LEFT2	0x0502	/* Hana SPDIF Left, 2nd or 96kHz */
+#define EMU_SRC_HANA_SPDIF_RIGHT1	0x0501	/* Hana SPDIF Right, 1st or 48kHz only */
+#define EMU_SRC_HANA_SPDIF_RIGHT2	0x0503	/* Hana SPDIF Right, 2nd or 96kHz */
+
+/* Additional inputs for 1616(M)/Microdock */
+/* Microdock S/PDIF Left, 1st or 48kHz only */
+#define EMU_SRC_MDOCK_SPDIF_LEFT1	0x0112
+/* Microdock S/PDIF Left, 2nd or 96kHz */
+#define EMU_SRC_MDOCK_SPDIF_LEFT2	0x0113
+/* Microdock S/PDIF Right, 1st or 48kHz only */
+#define EMU_SRC_MDOCK_SPDIF_RIGHT1	0x0116
+/* Microdock S/PDIF Right, 2nd or 96kHz */
+#define EMU_SRC_MDOCK_SPDIF_RIGHT2	0x0117
+/* Microdock ADAT 8 channel in +8 to +f */
+#define EMU_SRC_MDOCK_ADAT		0x0118
+
+/* 0x600 and 0x700 no used */
+
+/* ------------------- STRUCTURES -------------------- */
+
+enum {
+	EMU10K1_EFX,
+	EMU10K1_PCM,
+	EMU10K1_SYNTH,
+	EMU10K1_MIDI
+};
+
+struct snd_emu10k1;
+
+struct snd_emu10k1_voice {
+	struct snd_emu10k1 *emu;
+	int number;
+	unsigned int use: 1,
+	    pcm: 1,
+	    efx: 1,
+	    synth: 1,
+	    midi: 1;
+	void (*interrupt)(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice);
+
+	struct snd_emu10k1_pcm *epcm;
+};
+
+enum {
+	PLAYBACK_EMUVOICE,
+	PLAYBACK_EFX,
+	CAPTURE_AC97ADC,
+	CAPTURE_AC97MIC,
+	CAPTURE_EFX
+};
+
+struct snd_emu10k1_pcm {
+	struct snd_emu10k1 *emu;
+	int type;
+	struct snd_pcm_substream *substream;
+	struct snd_emu10k1_voice *voices[NUM_EFX_PLAYBACK];
+	struct snd_emu10k1_voice *extra;
+	unsigned short running;
+	unsigned short first_ptr;
+	struct snd_util_memblk *memblk;
+	unsigned int start_addr;
+	unsigned int ccca_start_addr;
+	unsigned int capture_ipr;	/* interrupt acknowledge mask */
+	unsigned int capture_inte;	/* interrupt enable mask */
+	unsigned int capture_ba_reg;	/* buffer address register */
+	unsigned int capture_bs_reg;	/* buffer size register */
+	unsigned int capture_idx_reg;	/* buffer index register */
+	unsigned int capture_cr_val;	/* control value */
+	unsigned int capture_cr_val2;	/* control value2 (for audigy) */
+	unsigned int capture_bs_val;	/* buffer size value */
+	unsigned int capture_bufsize;	/* buffer size in bytes */
+};
+
+struct snd_emu10k1_pcm_mixer {
+	/* mono, left, right x 8 sends (4 on emu10k1) */
+	unsigned char send_routing[3][8];
+	unsigned char send_volume[3][8];
+	unsigned short attn[3];
+	struct snd_emu10k1_pcm *epcm;
+};
+
+#define snd_emu10k1_compose_send_routing(route) \
+((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)
+
+#define snd_emu10k1_compose_audigy_fxrt1(route) \
+((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 24))
+
+#define snd_emu10k1_compose_audigy_fxrt2(route) \
+((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24))
+
+struct snd_emu10k1_memblk {
+	struct snd_util_memblk mem;
+	/* private part */
+	int first_page, last_page, pages, mapped_page;
+	unsigned int map_locked;
+	struct list_head mapped_link;
+	struct list_head mapped_order_link;
+};
+
+#define snd_emu10k1_memblk_offset(blk)	(((blk)->mapped_page << PAGE_SHIFT) | ((blk)->mem.offset & (PAGE_SIZE - 1)))
+
+#define EMU10K1_MAX_TRAM_BLOCKS_PER_CODE	16
+
+struct snd_emu10k1_fx8010_ctl {
+	struct list_head list;		/* list link container */
+	unsigned int vcount;
+	unsigned int count;		/* count of GPR (1..16) */
+	unsigned short gpr[32];		/* GPR number(s) */
+	unsigned int value[32];
+	unsigned int min;		/* minimum range */
+	unsigned int max;		/* maximum range */
+	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
+	struct snd_kcontrol *kcontrol;
+};
+
+typedef void (snd_fx8010_irq_handler_t)(struct snd_emu10k1 *emu, void *private_data);
+
+struct snd_emu10k1_fx8010_irq {
+	struct snd_emu10k1_fx8010_irq *next;
+	snd_fx8010_irq_handler_t *handler;
+	unsigned short gpr_running;
+	void *private_data;
+};
+
+struct snd_emu10k1_fx8010_pcm {
+	unsigned int valid: 1,
+		     opened: 1,
+		     active: 1;
+	unsigned int channels;		/* 16-bit channels count */
+	unsigned int tram_start;	/* initial ring buffer position in TRAM (in samples) */
+	unsigned int buffer_size;	/* count of buffered samples */
+	unsigned short gpr_size;		/* GPR containing size of ring buffer in samples (host) */
+	unsigned short gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+	unsigned short gpr_count;	/* GPR containing count of samples between two interrupts (host) */
+	unsigned short gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
+	unsigned short gpr_trigger;	/* GPR containing trigger (activate) information (host) */
+	unsigned short gpr_running;	/* GPR containing info if PCM is running (FX8010) */
+	unsigned char etram[32];	/* external TRAM address & data */
+	struct snd_pcm_indirect pcm_rec;
+	unsigned int tram_pos;
+	unsigned int tram_shift;
+	struct snd_emu10k1_fx8010_irq *irq;
+};
+
+struct snd_emu10k1_fx8010 {
+	unsigned short fxbus_mask;	/* used FX buses (bitmask) */
+	unsigned short extin_mask;	/* used external inputs (bitmask) */
+	unsigned short extout_mask;	/* used external outputs (bitmask) */
+	unsigned short pad1;
+	unsigned int itram_size;	/* internal TRAM size in samples */
+	struct snd_dma_buffer etram_pages; /* external TRAM pages and size */
+	unsigned int dbg;		/* FX debugger register */
+	unsigned char name[128];
+	int gpr_size;			/* size of allocated GPR controls */
+	int gpr_count;			/* count of used kcontrols */
+	struct list_head gpr_ctl;	/* GPR controls */
+	struct mutex lock;
+	struct snd_emu10k1_fx8010_pcm pcm[8];
+	spinlock_t irq_lock;
+	struct snd_emu10k1_fx8010_irq *irq_handlers;
+};
+
+struct snd_emu10k1_midi {
+	struct snd_emu10k1 *emu;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *substream_input;
+	struct snd_rawmidi_substream *substream_output;
+	unsigned int midi_mode;
+	spinlock_t input_lock;
+	spinlock_t output_lock;
+	spinlock_t open_lock;
+	int tx_enable, rx_enable;
+	int port;
+	int ipr_tx, ipr_rx;
+	void (*interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+};
+
+enum {
+	EMU_MODEL_SB,
+	EMU_MODEL_EMU1010,
+	EMU_MODEL_EMU1010B,
+	EMU_MODEL_EMU1616,
+	EMU_MODEL_EMU0404,
+};
+
+struct snd_emu_chip_details {
+	u32 vendor;
+	u32 device;
+	u32 subsystem;
+	unsigned char revision;
+	unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */
+	unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
+	unsigned char ca0102_chip;  /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
+	unsigned char ca0108_chip;  /* Audigy 2 Value */
+	unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
+	unsigned char ca0151_chip;  /* P16V */
+	unsigned char spk71;        /* Has 7.1 speakers */
+	unsigned char sblive51;	    /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
+	unsigned char spdif_bug;    /* Has Spdif phasing bug */
+	unsigned char ac97_chip;    /* Has an AC97 chip: 1 = mandatory, 2 = optional */
+	unsigned char ecard;        /* APS EEPROM */
+	unsigned char emu_model;     /* EMU model type */
+	unsigned char spi_dac;      /* SPI interface for DAC */
+	unsigned char i2c_adc;      /* I2C interface for ADC */
+	unsigned char adc_1361t;    /* Use Philips 1361T ADC */
+	unsigned char invert_shared_spdif; /* analog/digital switch inverted */
+	const char *driver;
+	const char *name;
+	const char *id;		/* for backward compatibility - can be NULL if not needed */
+};
+
+struct snd_emu1010 {
+	unsigned int output_source[64];
+	unsigned int input_source[64];
+	unsigned int adc_pads; /* bit mask */
+	unsigned int dac_pads; /* bit mask */
+	unsigned int internal_clock; /* 44100 or 48000 */
+	unsigned int optical_in; /* 0:SPDIF, 1:ADAT */
+	unsigned int optical_out; /* 0:SPDIF, 1:ADAT */
+	struct task_struct *firmware_thread;
+};
+
+struct snd_emu10k1 {
+	int irq;
+
+	unsigned long port;			/* I/O port number */
+	unsigned int tos_link: 1,		/* tos link detected */
+		rear_ac97: 1,			/* rear channels are on AC'97 */
+		enable_ir: 1;
+	unsigned int support_tlv :1;
+	/* Contains profile of card capabilities */
+	const struct snd_emu_chip_details *card_capabilities;
+	unsigned int audigy;			/* is Audigy? */
+	unsigned int revision;			/* chip revision */
+	unsigned int serial;			/* serial number */
+	unsigned short model;			/* subsystem id */
+	unsigned int card_type;			/* EMU10K1_CARD_* */
+	unsigned int ecard_ctrl;		/* ecard control bits */
+	unsigned int address_mode;		/* address mode */
+	unsigned long dma_mask;			/* PCI DMA mask */
+	unsigned int delay_pcm_irq;		/* in samples */
+	int max_cache_pages;			/* max memory size / PAGE_SIZE */
+	struct snd_dma_buffer silent_page;	/* silent page */
+	struct snd_dma_buffer ptb_pages;	/* page table pages */
+	struct snd_dma_device p16v_dma_dev;
+	struct snd_dma_buffer p16v_buffer;
+
+	struct snd_util_memhdr *memhdr;		/* page allocation list */
+	struct snd_emu10k1_memblk *reserved_page;	/* reserved page */
+
+	struct list_head mapped_link_head;
+	struct list_head mapped_order_link_head;
+	void **page_ptr_table;
+	unsigned long *page_addr_table;
+	spinlock_t memblk_lock;
+
+	unsigned int spdif_bits[3];		/* s/pdif out setup */
+	unsigned int i2c_capture_source;
+	u8 i2c_capture_volume[4][2];
+
+	struct snd_emu10k1_fx8010 fx8010;		/* FX8010 info */
+	int gpr_base;
+	
+	struct snd_ac97 *ac97;
+
+	struct pci_dev *pci;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm *pcm_mic;
+	struct snd_pcm *pcm_efx;
+	struct snd_pcm *pcm_multi;
+	struct snd_pcm *pcm_p16v;
+
+	spinlock_t synth_lock;
+	void *synth;
+	int (*get_synth_voice)(struct snd_emu10k1 *emu);
+
+	spinlock_t reg_lock;
+	spinlock_t emu_lock;
+	spinlock_t voice_lock;
+	spinlock_t spi_lock; /* serialises access to spi port */
+	spinlock_t i2c_lock; /* serialises access to i2c port */
+
+	struct snd_emu10k1_voice voices[NUM_G];
+	struct snd_emu10k1_voice p16v_voices[4];
+	struct snd_emu10k1_voice p16v_capture_voice;
+	int p16v_device_offset;
+	u32 p16v_capture_source;
+	u32 p16v_capture_channel;
+        struct snd_emu1010 emu1010;
+	struct snd_emu10k1_pcm_mixer pcm_mixer[32];
+	struct snd_emu10k1_pcm_mixer efx_pcm_mixer[NUM_EFX_PLAYBACK];
+	struct snd_kcontrol *ctl_send_routing;
+	struct snd_kcontrol *ctl_send_volume;
+	struct snd_kcontrol *ctl_attn;
+	struct snd_kcontrol *ctl_efx_send_routing;
+	struct snd_kcontrol *ctl_efx_send_volume;
+	struct snd_kcontrol *ctl_efx_attn;
+
+	void (*hwvol_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*capture_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*capture_mic_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*dsp_interrupt)(struct snd_emu10k1 *emu);
+
+	struct snd_pcm_substream *pcm_capture_substream;
+	struct snd_pcm_substream *pcm_capture_mic_substream;
+	struct snd_pcm_substream *pcm_capture_efx_substream;
+	struct snd_pcm_substream *pcm_playback_efx_substream;
+
+	struct snd_timer *timer;
+
+	struct snd_emu10k1_midi midi;
+	struct snd_emu10k1_midi midi2; /* for audigy */
+
+	unsigned int efx_voices_mask[2];
+	unsigned int next_free_voice;
+
+	const struct firmware *firmware;
+	const struct firmware *dock_fw;
+
+#ifdef CONFIG_PM_SLEEP
+	unsigned int *saved_ptr;
+	unsigned int *saved_gpr;
+	unsigned int *tram_val_saved;
+	unsigned int *tram_addr_saved;
+	unsigned int *saved_icode;
+	unsigned int *p16v_saved;
+	unsigned int saved_a_iocfg, saved_hcfg;
+	bool suspend;
+#endif
+
+};
+
+int snd_emu10k1_create(struct snd_card *card,
+		       struct pci_dev *pci,
+		       unsigned short extin_mask,
+		       unsigned short extout_mask,
+		       long max_cache_bytes,
+		       int enable_ir,
+		       uint subsystem,
+		       struct snd_emu10k1 ** remu);
+
+int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device);
+int snd_p16v_pcm(struct snd_emu10k1 *emu, int device);
+int snd_p16v_free(struct snd_emu10k1 * emu);
+int snd_p16v_mixer(struct snd_emu10k1 * emu);
+int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 *emu, int device);
+int snd_emu10k1_mixer(struct snd_emu10k1 * emu, int pcm_device, int multi_device);
+int snd_emu10k1_timer(struct snd_emu10k1 * emu, int device);
+int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device);
+
+irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id);
+
+void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int voice);
+int snd_emu10k1_init_efx(struct snd_emu10k1 *emu);
+void snd_emu10k1_free_efx(struct snd_emu10k1 *emu);
+int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size);
+int snd_emu10k1_done(struct snd_emu10k1 * emu);
+
+/* I/O functions */
+unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
+unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
+int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
+int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
+int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value);
+int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value);
+int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src);
+unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
+void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
+void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
+void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait);
+static inline unsigned int snd_emu10k1_wc(struct snd_emu10k1 *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
+unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
+void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data);
+unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
+
+#ifdef CONFIG_PM_SLEEP
+void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu);
+void snd_emu10k1_resume_init(struct snd_emu10k1 *emu);
+void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu);
+int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu);
+void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu);
+void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu);
+void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu);
+int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu);
+void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu);
+void snd_p16v_suspend(struct snd_emu10k1 *emu);
+void snd_p16v_resume(struct snd_emu10k1 *emu);
+#endif
+
+/* memory allocation */
+struct snd_util_memblk *snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream);
+int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
+struct snd_util_memblk *snd_emu10k1_synth_alloc(struct snd_emu10k1 *emu, unsigned int size);
+int snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
+int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, int size);
+int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, const char __user *data, int size);
+int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk);
+
+/* voice allocation */
+int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int pair, struct snd_emu10k1_voice **rvoice);
+int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice);
+
+/* MIDI uart */
+int snd_emu10k1_midi(struct snd_emu10k1 * emu);
+int snd_emu10k1_audigy_midi(struct snd_emu10k1 * emu);
+
+/* proc interface */
+int snd_emu10k1_proc_init(struct snd_emu10k1 * emu);
+
+/* fx8010 irq handler */
+int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
+					    snd_fx8010_irq_handler_t *handler,
+					    unsigned char gpr_running,
+					    void *private_data,
+					    struct snd_emu10k1_fx8010_irq **r_irq);
+int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
+					      struct snd_emu10k1_fx8010_irq *irq);
+
+#endif	/* __SOUND_EMU10K1_H */
diff --git a/include/sound/emu10k1_synth.h b/include/sound/emu10k1_synth.h
new file mode 100644
index 0000000..9f211e9
--- /dev/null
+++ b/include/sound/emu10k1_synth.h
@@ -0,0 +1,39 @@
+#ifndef __EMU10K1_SYNTH_H
+#define __EMU10K1_SYNTH_H
+/*
+ *  Defines for the Emu10k1 WaveTable synth
+ *
+ *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/emu10k1.h>
+#include <sound/emux_synth.h>
+
+/* sequencer device id */
+#define SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH	"emu10k1-synth"
+
+/* argument for snd_seq_device_new */
+struct snd_emu10k1_synth_arg {
+	struct snd_emu10k1 *hwptr;	/* chip */
+	int index;		/* sequencer client index */
+	int seq_ports;		/* number of sequencer ports to be created */
+	int max_voices;		/* maximum number of voices for wavetable */
+};
+
+#define EMU10K1_MAX_MEMSIZE	(32 * 1024 * 1024) /* 32MB */
+
+#endif
diff --git a/include/sound/emu8000.h b/include/sound/emu8000.h
new file mode 100644
index 0000000..c321302
--- /dev/null
+++ b/include/sound/emu8000.h
@@ -0,0 +1,121 @@
+#ifndef __SOUND_EMU8000_H
+#define __SOUND_EMU8000_H
+/*
+ *  Defines for the emu8000 (AWE32/64)
+ *
+ *  Copyright (C) 1999 Steve Ratcliffe
+ *  Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/emux_synth.h>
+#include <sound/seq_kernel.h>
+
+/*
+ * Hardware parameters.
+ */
+#define EMU8000_MAX_DRAM (28 * 1024 * 1024) /* Max on-board mem is 28Mb ???*/
+#define EMU8000_DRAM_OFFSET 0x200000	/* Beginning of on board ram */
+#define EMU8000_CHANNELS   32	/* Number of hardware channels */
+#define EMU8000_DRAM_VOICES	30	/* number of normal voices */
+
+/* Flags to set a dma channel to read or write */
+#define EMU8000_RAM_READ   0
+#define EMU8000_RAM_WRITE  1
+#define EMU8000_RAM_CLOSE  2
+#define EMU8000_RAM_MODE_MASK	0x03
+#define EMU8000_RAM_RIGHT	0x10	/* use 'right' DMA channel */
+
+enum {
+	EMU8000_CONTROL_BASS = 0,
+	EMU8000_CONTROL_TREBLE,
+	EMU8000_CONTROL_CHORUS_MODE,
+	EMU8000_CONTROL_REVERB_MODE,
+	EMU8000_CONTROL_FM_CHORUS_DEPTH,
+	EMU8000_CONTROL_FM_REVERB_DEPTH,
+	EMU8000_NUM_CONTROLS,
+};
+
+/*
+ * Structure to hold all state information for the emu8000 driver.
+ *
+ * Note 1: The chip supports 32 channels in hardware this is max_channels
+ * some of the channels may be used for other things so max_channels is
+ * the number in use for wave voices.
+ */
+struct snd_emu8000 {
+
+	struct snd_emux *emu;
+
+	int index;		/* sequencer client index */
+	int seq_ports;		/* number of sequencer ports */
+	int fm_chorus_depth;	/* FM OPL3 chorus depth */
+	int fm_reverb_depth;	/* FM OPL3 reverb depth */
+
+	int mem_size;		/* memory size */
+	unsigned long port1;	/* Port usually base+0 */
+	unsigned long port2;	/* Port usually at base+0x400 */
+	unsigned long port3;	/* Port usually at base+0x800 */
+	struct resource *res_port1;
+	struct resource *res_port2;
+	struct resource *res_port3;
+	unsigned short last_reg;/* Last register command */
+	spinlock_t reg_lock;
+
+	int dram_checked;
+
+	struct snd_card *card;		/* The card that this belongs to */
+
+	int chorus_mode;
+	int reverb_mode;
+	int bass_level;
+	int treble_level;
+
+	struct snd_util_memhdr *memhdr;
+
+	spinlock_t control_lock;
+	struct snd_kcontrol *controls[EMU8000_NUM_CONTROLS];
+
+	struct snd_pcm *pcm; /* pcm on emu8000 wavetable */
+
+};
+
+/* sequencer device id */
+#define SNDRV_SEQ_DEV_ID_EMU8000	"emu8000-synth"
+
+
+/* exported functions */
+int snd_emu8000_new(struct snd_card *card, int device, long port, int seq_ports,
+		    struct snd_seq_device **ret);
+void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg,
+		      unsigned int val);
+unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port,
+				unsigned int reg);
+void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg,
+			 unsigned int val);
+unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port,
+				 unsigned int reg);
+void snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode);
+
+void snd_emu8000_init_fm(struct snd_emu8000 *emu);
+
+void snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu);
+void snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu);
+void snd_emu8000_update_equalizer(struct snd_emu8000 *emu);
+int snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len);
+int snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len);
+
+#endif /* __SOUND_EMU8000_H */
diff --git a/include/sound/emu8000_reg.h b/include/sound/emu8000_reg.h
new file mode 100644
index 0000000..4b9827a
--- /dev/null
+++ b/include/sound/emu8000_reg.h
@@ -0,0 +1,207 @@
+#ifndef __SOUND_EMU8000_REG_H
+#define __SOUND_EMU8000_REG_H
+/*
+ *  Register operations for the EMU8000
+ *
+ *  Copyright (C) 1999 Steve Ratcliffe
+ *
+ *  Based on awe_wave.c by Takashi Iwai
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/*
+ * Data port addresses relative to the EMU base.
+ */
+#define EMU8000_DATA0(e)    ((e)->port1)
+#define EMU8000_DATA1(e)    ((e)->port2)
+#define EMU8000_DATA2(e)    ((e)->port2+2)
+#define EMU8000_DATA3(e)    ((e)->port3)
+#define EMU8000_PTR(e)      ((e)->port3+2)
+
+/*
+ * Make a command from a register and channel.
+ */
+#define EMU8000_CMD(reg, chan) ((reg)<<5 | (chan))
+
+/*
+ * Commands to read and write the EMU8000 registers.
+ * These macros should be used for all register accesses.
+ */
+#define EMU8000_CPF_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(0, (chan)))
+#define EMU8000_PTRX_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (chan)))
+#define EMU8000_CVCF_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(2, (chan)))
+#define EMU8000_VTFT_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(3, (chan)))
+#define EMU8000_PSST_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(6, (chan)))
+#define EMU8000_CSL_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(7, (chan)))
+#define EMU8000_CCCA_READ(emu, chan) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(0, (chan)))
+#define EMU8000_HWCF4_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 9))
+#define EMU8000_HWCF5_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 10))
+#define EMU8000_HWCF6_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 13))
+#define EMU8000_SMALR_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 20))
+#define EMU8000_SMARR_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 21))
+#define EMU8000_SMALW_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 22))
+#define EMU8000_SMARW_READ(emu) \
+	snd_emu8000_peek_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 23))
+#define EMU8000_SMLD_READ(emu) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 26))
+#define EMU8000_SMRD_READ(emu) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(1, 26))
+#define EMU8000_WC_READ(emu) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(1, 27))
+#define EMU8000_HWCF1_READ(emu) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 29))
+#define EMU8000_HWCF2_READ(emu) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 30))
+#define EMU8000_HWCF3_READ(emu) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 31))
+#define EMU8000_INIT1_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(2, (chan)))
+#define EMU8000_INIT2_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(2, (chan)))
+#define EMU8000_INIT3_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(3, (chan)))
+#define EMU8000_INIT4_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(3, (chan)))
+#define EMU8000_ENVVOL_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(4, (chan)))
+#define EMU8000_DCYSUSV_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(5, (chan)))
+#define EMU8000_ENVVAL_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(6, (chan)))
+#define EMU8000_DCYSUS_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA1(emu), EMU8000_CMD(7, (chan)))
+#define EMU8000_ATKHLDV_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(4, (chan)))
+#define EMU8000_LFO1VAL_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(5, (chan)))
+#define EMU8000_ATKHLD_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(6, (chan)))
+#define EMU8000_LFO2VAL_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA2(emu), EMU8000_CMD(7, (chan)))
+#define EMU8000_IP_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA3(emu), EMU8000_CMD(0, (chan)))
+#define EMU8000_IFATN_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA3(emu), EMU8000_CMD(1, (chan)))
+#define EMU8000_PEFE_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA3(emu), EMU8000_CMD(2, (chan)))
+#define EMU8000_FMMOD_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA3(emu), EMU8000_CMD(3, (chan)))
+#define EMU8000_TREMFRQ_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA3(emu), EMU8000_CMD(4, (chan)))
+#define EMU8000_FM2FRQ2_READ(emu, chan) \
+	snd_emu8000_peek((emu), EMU8000_DATA3(emu), EMU8000_CMD(5, (chan)))
+
+
+#define EMU8000_CPF_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(0, (chan)), (val))
+#define EMU8000_PTRX_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (chan)), (val))
+#define EMU8000_CVCF_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(2, (chan)), (val))
+#define EMU8000_VTFT_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(3, (chan)), (val))
+#define EMU8000_PSST_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(6, (chan)), (val))
+#define EMU8000_CSL_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(7, (chan)), (val))
+#define EMU8000_CCCA_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(0, (chan)), (val))
+#define EMU8000_HWCF4_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 9), (val))
+#define EMU8000_HWCF5_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 10), (val))
+#define EMU8000_HWCF6_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 13), (val))
+/* this register is not documented */
+#define EMU8000_HWCF7_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 14), (val))
+#define EMU8000_SMALR_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 20), (val))
+#define EMU8000_SMARR_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 21), (val))
+#define EMU8000_SMALW_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 22), (val))
+#define EMU8000_SMARW_WRITE(emu, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 23), (val))
+#define EMU8000_SMLD_WRITE(emu, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 26), (val))
+#define EMU8000_SMRD_WRITE(emu, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(1, 26), (val))
+#define EMU8000_WC_WRITE(emu, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(1, 27), (val))
+#define EMU8000_HWCF1_WRITE(emu, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 29), (val))
+#define EMU8000_HWCF2_WRITE(emu, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 30), (val))
+#define EMU8000_HWCF3_WRITE(emu, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(1, 31), (val))
+#define EMU8000_INIT1_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(2, (chan)), (val))
+#define EMU8000_INIT2_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(2, (chan)), (val))
+#define EMU8000_INIT3_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(3, (chan)), (val))
+#define EMU8000_INIT4_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(3, (chan)), (val))
+#define EMU8000_ENVVOL_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(4, (chan)), (val))
+#define EMU8000_DCYSUSV_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(5, (chan)), (val))
+#define EMU8000_ENVVAL_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(6, (chan)), (val))
+#define EMU8000_DCYSUS_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA1(emu), EMU8000_CMD(7, (chan)), (val))
+#define EMU8000_ATKHLDV_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(4, (chan)), (val))
+#define EMU8000_LFO1VAL_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(5, (chan)), (val))
+#define EMU8000_ATKHLD_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(6, (chan)), (val))
+#define EMU8000_LFO2VAL_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA2(emu), EMU8000_CMD(7, (chan)), (val))
+#define EMU8000_IP_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA3(emu), EMU8000_CMD(0, (chan)), (val))
+#define EMU8000_IFATN_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA3(emu), EMU8000_CMD(1, (chan)), (val))
+#define EMU8000_PEFE_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA3(emu), EMU8000_CMD(2, (chan)), (val))
+#define EMU8000_FMMOD_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA3(emu), EMU8000_CMD(3, (chan)), (val))
+#define EMU8000_TREMFRQ_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA3(emu), EMU8000_CMD(4, (chan)), (val))
+#define EMU8000_FM2FRQ2_WRITE(emu, chan, val) \
+	snd_emu8000_poke((emu), EMU8000_DATA3(emu), EMU8000_CMD(5, (chan)), (val))
+
+#define EMU8000_0080_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(4, (chan)), (val))
+#define EMU8000_00A0_WRITE(emu, chan, val) \
+	snd_emu8000_poke_dw((emu), EMU8000_DATA0(emu), EMU8000_CMD(5, (chan)), (val))
+
+#endif /* __SOUND_EMU8000_REG_H */
diff --git a/include/sound/emux_legacy.h b/include/sound/emux_legacy.h
new file mode 100644
index 0000000..baf43fc
--- /dev/null
+++ b/include/sound/emux_legacy.h
@@ -0,0 +1,146 @@
+#ifndef __SOUND_EMUX_LEGACY_H
+#define __SOUND_EMUX_LEGACY_H
+
+/*
+ *  Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
+ *
+ *  Definitions of OSS compatible headers for Emu8000 device informations
+ *
+ *   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 <sound/seq_oss_legacy.h>
+
+/*
+ * awe hardware controls
+ */
+
+#define _EMUX_OSS_DEBUG_MODE		0x00
+#define _EMUX_OSS_REVERB_MODE		0x01
+#define _EMUX_OSS_CHORUS_MODE		0x02
+#define _EMUX_OSS_REMOVE_LAST_SAMPLES	0x03
+#define _EMUX_OSS_INITIALIZE_CHIP	0x04
+#define _EMUX_OSS_SEND_EFFECT		0x05
+#define _EMUX_OSS_TERMINATE_CHANNEL	0x06
+#define _EMUX_OSS_TERMINATE_ALL		0x07
+#define _EMUX_OSS_INITIAL_VOLUME	0x08
+#define _EMUX_OSS_INITIAL_ATTEN	_EMUX_OSS_INITIAL_VOLUME
+#define _EMUX_OSS_RESET_CHANNEL		0x09
+#define _EMUX_OSS_CHANNEL_MODE		0x0a
+#define _EMUX_OSS_DRUM_CHANNELS		0x0b
+#define _EMUX_OSS_MISC_MODE		0x0c
+#define _EMUX_OSS_RELEASE_ALL		0x0d
+#define _EMUX_OSS_NOTEOFF_ALL		0x0e
+#define _EMUX_OSS_CHN_PRESSURE		0x0f
+#define _EMUX_OSS_EQUALIZER		0x11
+
+#define _EMUX_OSS_MODE_FLAG		0x80
+#define _EMUX_OSS_COOKED_FLAG		0x40	/* not supported */
+#define _EMUX_OSS_MODE_VALUE_MASK	0x3F
+
+
+/*
+ * mode type definitions
+ */
+enum {
+/* 0*/	EMUX_MD_EXCLUSIVE_OFF,	/* obsolete */
+/* 1*/	EMUX_MD_EXCLUSIVE_ON,	/* obsolete */
+/* 2*/	EMUX_MD_VERSION,		/* read only */
+/* 3*/	EMUX_MD_EXCLUSIVE_SOUND,	/* 0/1: exclusive note on (default=1) */
+/* 4*/	EMUX_MD_REALTIME_PAN,	/* 0/1: do realtime pan change (default=1) */
+/* 5*/	EMUX_MD_GUS_BANK,	/* bank number for GUS patches (default=0) */
+/* 6*/	EMUX_MD_KEEP_EFFECT,	/* 0/1: keep effect values, (default=0) */
+/* 7*/	EMUX_MD_ZERO_ATTEN,	/* attenuation of max volume (default=32) */
+/* 8*/	EMUX_MD_CHN_PRIOR,	/* 0/1: set MIDI channel priority mode (default=1) */
+/* 9*/	EMUX_MD_MOD_SENSE,	/* integer: modwheel sensitivity (def=18) */
+/*10*/	EMUX_MD_DEF_PRESET,	/* integer: default preset number (def=0) */
+/*11*/	EMUX_MD_DEF_BANK,	/* integer: default bank number (def=0) */
+/*12*/	EMUX_MD_DEF_DRUM,	/* integer: default drumset number (def=0) */
+/*13*/	EMUX_MD_TOGGLE_DRUM_BANK, /* 0/1: toggle drum flag with bank# (def=0) */
+/*14*/	EMUX_MD_NEW_VOLUME_CALC,	/* 0/1: volume calculation mode (def=1) */
+/*15*/	EMUX_MD_CHORUS_MODE,	/* integer: chorus mode (def=2) */
+/*16*/	EMUX_MD_REVERB_MODE,	/* integer: chorus mode (def=4) */
+/*17*/	EMUX_MD_BASS_LEVEL,	/* integer: bass level (def=5) */
+/*18*/	EMUX_MD_TREBLE_LEVEL,	/* integer: treble level (def=9) */
+/*19*/	EMUX_MD_DEBUG_MODE,	/* integer: debug level (def=0) */
+/*20*/	EMUX_MD_PAN_EXCHANGE,	/* 0/1: exchange panning direction (def=0) */
+	EMUX_MD_END,
+};
+
+
+/*
+ * effect parameters
+ */
+enum {
+
+/* modulation envelope parameters */
+/* 0*/	EMUX_FX_ENV1_DELAY,	/* WORD: ENVVAL */
+/* 1*/	EMUX_FX_ENV1_ATTACK,	/* BYTE: up ATKHLD */
+/* 2*/	EMUX_FX_ENV1_HOLD,	/* BYTE: lw ATKHLD */
+/* 3*/	EMUX_FX_ENV1_DECAY,	/* BYTE: lw DCYSUS */
+/* 4*/	EMUX_FX_ENV1_RELEASE,	/* BYTE: lw DCYSUS */
+/* 5*/	EMUX_FX_ENV1_SUSTAIN,	/* BYTE: up DCYSUS */
+/* 6*/	EMUX_FX_ENV1_PITCH,	/* BYTE: up PEFE */
+/* 7*/	EMUX_FX_ENV1_CUTOFF,	/* BYTE: lw PEFE */
+
+/* volume envelope parameters */
+/* 8*/	EMUX_FX_ENV2_DELAY,	/* WORD: ENVVOL */
+/* 9*/	EMUX_FX_ENV2_ATTACK,	/* BYTE: up ATKHLDV */
+/*10*/	EMUX_FX_ENV2_HOLD,	/* BYTE: lw ATKHLDV */
+/*11*/	EMUX_FX_ENV2_DECAY,	/* BYTE: lw DCYSUSV */
+/*12*/	EMUX_FX_ENV2_RELEASE,	/* BYTE: lw DCYSUSV */
+/*13*/	EMUX_FX_ENV2_SUSTAIN,	/* BYTE: up DCYSUSV */
+	
+/* LFO1 (tremolo & vibrato) parameters */
+/*14*/	EMUX_FX_LFO1_DELAY,	/* WORD: LFO1VAL */
+/*15*/	EMUX_FX_LFO1_FREQ,	/* BYTE: lo TREMFRQ */
+/*16*/	EMUX_FX_LFO1_VOLUME,	/* BYTE: up TREMFRQ */
+/*17*/	EMUX_FX_LFO1_PITCH,	/* BYTE: up FMMOD */
+/*18*/	EMUX_FX_LFO1_CUTOFF,	/* BYTE: lo FMMOD */
+
+/* LFO2 (vibrato) parameters */
+/*19*/	EMUX_FX_LFO2_DELAY,	/* WORD: LFO2VAL */
+/*20*/	EMUX_FX_LFO2_FREQ,	/* BYTE: lo FM2FRQ2 */
+/*21*/	EMUX_FX_LFO2_PITCH,	/* BYTE: up FM2FRQ2 */
+
+/* Other overall effect parameters */
+/*22*/	EMUX_FX_INIT_PITCH,	/* SHORT: pitch offset */
+/*23*/	EMUX_FX_CHORUS,		/* BYTE: chorus effects send (0-255) */
+/*24*/	EMUX_FX_REVERB,		/* BYTE: reverb effects send (0-255) */
+/*25*/	EMUX_FX_CUTOFF,		/* BYTE: up IFATN */
+/*26*/	EMUX_FX_FILTERQ,		/* BYTE: up CCCA */
+
+/* Sample / loop offset changes */
+/*27*/	EMUX_FX_SAMPLE_START,	/* SHORT: offset */
+/*28*/	EMUX_FX_LOOP_START,	/* SHORT: offset */
+/*29*/	EMUX_FX_LOOP_END,	/* SHORT: offset */
+/*30*/	EMUX_FX_COARSE_SAMPLE_START,	/* SHORT: upper word offset */
+/*31*/	EMUX_FX_COARSE_LOOP_START,	/* SHORT: upper word offset */
+/*32*/	EMUX_FX_COARSE_LOOP_END,		/* SHORT: upper word offset */
+/*33*/	EMUX_FX_ATTEN,		/* BYTE: lo IFATN */
+
+	EMUX_FX_END,
+};
+/* number of effects */
+#define EMUX_NUM_EFFECTS  EMUX_FX_END
+
+/* effect flag values */
+#define EMUX_FX_FLAG_OFF	0
+#define EMUX_FX_FLAG_SET	1
+#define EMUX_FX_FLAG_ADD	2
+
+
+#endif /* __SOUND_EMUX_LEGACY_H */
diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h
new file mode 100644
index 0000000..a0a40b7
--- /dev/null
+++ b/include/sound/emux_synth.h
@@ -0,0 +1,244 @@
+#ifndef __SOUND_EMUX_SYNTH_H
+#define __SOUND_EMUX_SYNTH_H
+
+/*
+ *  Defines for the Emu-series WaveTable chip
+ *
+ *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/seq_kernel.h>
+#include <sound/seq_device.h>
+#include <sound/soundfont.h>
+#include <sound/seq_midi_emul.h>
+#ifdef CONFIG_SND_SEQUENCER_OSS
+#include <sound/seq_oss.h>
+#endif
+#include <sound/emux_legacy.h>
+#include <sound/seq_virmidi.h>
+
+/*
+ * compile flags
+ */
+#define SNDRV_EMUX_USE_RAW_EFFECT
+
+struct snd_emux;
+struct snd_emux_port;
+struct snd_emux_voice;
+struct snd_emux_effect_table;
+
+/*
+ * operators
+ */
+struct snd_emux_operators {
+	struct module *owner;
+	struct snd_emux_voice *(*get_voice)(struct snd_emux *emu,
+					    struct snd_emux_port *port);
+	int (*prepare)(struct snd_emux_voice *vp);
+	void (*trigger)(struct snd_emux_voice *vp);
+	void (*release)(struct snd_emux_voice *vp);
+	void (*update)(struct snd_emux_voice *vp, int update);
+	void (*terminate)(struct snd_emux_voice *vp);
+	void (*free_voice)(struct snd_emux_voice *vp);
+	void (*reset)(struct snd_emux *emu, int ch);
+	/* the first parameters are struct snd_emux */
+	int (*sample_new)(struct snd_emux *emu, struct snd_sf_sample *sp,
+			  struct snd_util_memhdr *hdr,
+			  const void __user *data, long count);
+	int (*sample_free)(struct snd_emux *emu, struct snd_sf_sample *sp,
+			   struct snd_util_memhdr *hdr);
+	void (*sample_reset)(struct snd_emux *emu);
+	int (*load_fx)(struct snd_emux *emu, int type, int arg,
+		       const void __user *data, long count);
+	void (*sysex)(struct snd_emux *emu, char *buf, int len, int parsed,
+		      struct snd_midi_channel_set *chset);
+#ifdef CONFIG_SND_SEQUENCER_OSS
+	int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2);
+#endif
+};
+
+
+/*
+ * constant values
+ */
+#define SNDRV_EMUX_MAX_PORTS		32	/* max # of sequencer ports */
+#define SNDRV_EMUX_MAX_VOICES		64	/* max # of voices */
+#define SNDRV_EMUX_MAX_MULTI_VOICES	16	/* max # of playable voices
+						 * simultineously
+						 */
+
+/*
+ * flags
+ */
+#define SNDRV_EMUX_ACCEPT_ROM		(1<<0)
+
+/*
+ * emuX wavetable
+ */
+struct snd_emux {
+
+	struct snd_card *card;	/* assigned card */
+
+	/* following should be initialized before registration */
+	int max_voices;		/* Number of voices */
+	int mem_size;		/* memory size (in byte) */
+	int num_ports;		/* number of ports to be created */
+	int pitch_shift;	/* pitch shift value (for Emu10k1) */
+	struct snd_emux_operators ops;	/* operators */
+	void *hw;		/* hardware */
+	unsigned long flags;	/* other conditions */
+	int midi_ports;		/* number of virtual midi devices */
+	int midi_devidx;	/* device offset of virtual midi */
+	unsigned int linear_panning: 1; /* panning is linear (sbawe = 1, emu10k1 = 0) */
+	int hwdep_idx;		/* hwdep device index */
+	struct snd_hwdep *hwdep;	/* hwdep device */
+
+	/* private */
+	int num_voices;		/* current number of voices */
+	struct snd_sf_list *sflist;	/* root of SoundFont list */
+	struct snd_emux_voice *voices;	/* Voices (EMU 'channel') */
+	int use_time;	/* allocation counter */
+	spinlock_t voice_lock;	/* Lock for voice access */
+	struct mutex register_mutex;
+	int client;		/* For the sequencer client */
+	int ports[SNDRV_EMUX_MAX_PORTS];	/* The ports for this device */
+	struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS];
+	int used;	/* use counter */
+	char *name;	/* name of the device (internal) */
+	struct snd_rawmidi **vmidi;
+	struct timer_list tlist;	/* for pending note-offs */
+	int timer_active;
+
+	struct snd_util_memhdr *memhdr;	/* memory chunk information */
+
+#ifdef CONFIG_SND_PROC_FS
+	struct snd_info_entry *proc;
+#endif
+
+#ifdef CONFIG_SND_SEQUENCER_OSS
+	struct snd_seq_device *oss_synth;
+#endif
+};
+
+
+/*
+ * sequencer port information
+ */
+struct snd_emux_port {
+
+	struct snd_midi_channel_set chset;
+	struct snd_emux *emu;
+
+	char port_mode;			/* operation mode */
+	int volume_atten;		/* emuX raw attenuation */
+	unsigned long drum_flags;	/* drum bitmaps */
+	int ctrls[EMUX_MD_END];		/* control parameters */
+#ifdef SNDRV_EMUX_USE_RAW_EFFECT
+	struct snd_emux_effect_table *effect;
+#endif
+#ifdef CONFIG_SND_SEQUENCER_OSS
+	struct snd_seq_oss_arg *oss_arg;
+#endif
+};
+
+/* port_mode */
+#define SNDRV_EMUX_PORT_MODE_MIDI		0	/* normal MIDI port */
+#define SNDRV_EMUX_PORT_MODE_OSS_SYNTH	1	/* OSS synth port */
+#define SNDRV_EMUX_PORT_MODE_OSS_MIDI	2	/* OSS multi channel synth port */
+
+/*
+ * A structure to keep track of each hardware voice
+ */
+struct snd_emux_voice {
+	int  ch;		/* Hardware channel number */
+
+	int  state;		/* status */
+#define SNDRV_EMUX_ST_OFF		0x00	/* Not playing, and inactive */
+#define SNDRV_EMUX_ST_ON		0x01	/* Note on */
+#define SNDRV_EMUX_ST_RELEASED 	(0x02|SNDRV_EMUX_ST_ON)	/* Note released */
+#define SNDRV_EMUX_ST_SUSTAINED	(0x04|SNDRV_EMUX_ST_ON)	/* Note sustained */
+#define SNDRV_EMUX_ST_STANDBY	(0x08|SNDRV_EMUX_ST_ON)	/* Waiting to be triggered */
+#define SNDRV_EMUX_ST_PENDING 	(0x10|SNDRV_EMUX_ST_ON)	/* Note will be released */
+#define SNDRV_EMUX_ST_LOCKED		0x100	/* Not accessible */
+
+	unsigned int  time;	/* An allocation time */
+	unsigned char note;	/* Note currently assigned to this voice */
+	unsigned char key;
+	unsigned char velocity;	/* Velocity of current note */
+
+	struct snd_sf_zone *zone;	/* Zone assigned to this note */
+	void *block;		/* sample block pointer (optional) */
+	struct snd_midi_channel *chan;	/* Midi channel for this note */
+	struct snd_emux_port *port;	/* associated port */
+	struct snd_emux *emu;	/* assigned root info */
+	void *hw;		/* hardware pointer (emu8000 or emu10k1) */
+	unsigned long ontime;	/* jiffies at note triggered */
+	
+	/* Emu8k/Emu10k1 registers */
+	struct soundfont_voice_info reg;
+
+	/* additional registers */
+	int avol;		/* volume attenuation */
+	int acutoff;		/* cutoff target */
+	int apitch;		/* pitch offset */
+	int apan;		/* pan/aux pair */
+	int aaux;
+	int ptarget;		/* pitch target */
+	int vtarget;		/* volume target */
+	int ftarget;		/* filter target */
+
+};
+
+/*
+ * update flags (can be combined)
+ */
+#define SNDRV_EMUX_UPDATE_VOLUME		(1<<0)
+#define SNDRV_EMUX_UPDATE_PITCH		(1<<1)
+#define SNDRV_EMUX_UPDATE_PAN		(1<<2)
+#define SNDRV_EMUX_UPDATE_FMMOD		(1<<3)
+#define SNDRV_EMUX_UPDATE_TREMFREQ	(1<<4)
+#define SNDRV_EMUX_UPDATE_FM2FRQ2		(1<<5)
+#define SNDRV_EMUX_UPDATE_Q		(1<<6)
+
+
+#ifdef SNDRV_EMUX_USE_RAW_EFFECT
+/*
+ * effect table
+ */
+struct snd_emux_effect_table {
+	/* Emu8000 specific effects */
+	short val[EMUX_NUM_EFFECTS];
+	unsigned char flag[EMUX_NUM_EFFECTS];
+};
+#endif /* SNDRV_EMUX_USE_RAW_EFFECT */
+
+
+/*
+ * prototypes - interface to Emu10k1 and Emu8k routines
+ */
+int snd_emux_new(struct snd_emux **remu);
+int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name);
+int snd_emux_free(struct snd_emux *emu);
+
+/*
+ * exported functions
+ */
+void snd_emux_terminate_all(struct snd_emux *emu);
+void snd_emux_lock_voice(struct snd_emux *emu, int voice);
+void snd_emux_unlock_voice(struct snd_emux *emu, int voice);
+
+#endif /* __SOUND_EMUX_SYNTH_H */
diff --git a/include/sound/es1688.h b/include/sound/es1688.h
new file mode 100644
index 0000000..b34f23a
--- /dev/null
+++ b/include/sound/es1688.h
@@ -0,0 +1,122 @@
+#ifndef __SOUND_ES1688_H
+#define __SOUND_ES1688_H
+
+/*
+ *  Header file for ES488/ES1688
+ *  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
+ *
+ */
+
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <linux/interrupt.h>
+
+#define ES1688_HW_AUTO		0x0000
+#define ES1688_HW_688		0x0001
+#define ES1688_HW_1688		0x0002
+#define ES1688_HW_UNDEF	0x0003
+
+struct snd_es1688 {
+	unsigned long port;		/* port of ESS chip */
+	struct resource *res_port;
+	unsigned long mpu_port;		/* MPU-401 port of ESS chip */
+	int irq;			/* IRQ number of ESS chip */
+	int mpu_irq;			/* MPU IRQ */
+	int dma8;			/* 8-bit DMA */
+	unsigned short version;		/* version of ESS chip */
+	unsigned short hardware;	/* see to ES1688_HW_XXXX */
+
+	unsigned short trigger_value;
+	unsigned char pad;
+	unsigned int dma_size;
+
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+
+	spinlock_t reg_lock;
+	spinlock_t mixer_lock;
+};
+
+/* I/O ports */
+
+#define ES1688P(codec, x) ((codec)->port + e_s_s_ESS1688##x)
+
+#define e_s_s_ESS1688RESET	0x6
+#define e_s_s_ESS1688READ	0xa
+#define e_s_s_ESS1688WRITE	0xc
+#define e_s_s_ESS1688COMMAND	0xc
+#define e_s_s_ESS1688STATUS	0xc
+#define e_s_s_ESS1688DATA_AVAIL	0xe
+#define e_s_s_ESS1688DATA_AVAIL_16 0xf
+#define e_s_s_ESS1688MIXER_ADDR	0x4
+#define e_s_s_ESS1688MIXER_DATA	0x5
+#define e_s_s_ESS1688OPL3_LEFT	0x0
+#define e_s_s_ESS1688OPL3_RIGHT	0x2
+#define e_s_s_ESS1688OPL3_BOTH	0x8
+#define e_s_s_ESS1688ENABLE0	0x0
+#define e_s_s_ESS1688ENABLE1	0x9
+#define e_s_s_ESS1688ENABLE2	0xb
+#define e_s_s_ESS1688INIT1	0x7
+
+#define ES1688_DSP_CMD_DMAOFF	0xd0
+#define ES1688_DSP_CMD_SPKON	0xd1
+#define ES1688_DSP_CMD_SPKOFF	0xd3
+#define ES1688_DSP_CMD_DMAON	0xd4
+
+#define ES1688_PCM_DEV		0x14
+#define ES1688_MIC_DEV		0x1a
+#define ES1688_REC_DEV		0x1c
+#define ES1688_MASTER_DEV	0x32
+#define ES1688_FM_DEV		0x36
+#define ES1688_CD_DEV		0x38
+#define ES1688_AUX_DEV		0x3a
+#define ES1688_SPEAKER_DEV	0x3c
+#define ES1688_LINE_DEV		0x3e
+#define ES1688_RECLEV_DEV	0xb4
+
+#define ES1688_MIXS_MASK	0x17
+#define ES1688_MIXS_MIC		0x00
+#define ES1688_MIXS_MIC_MASTER	0x01
+#define ES1688_MIXS_CD		0x02
+#define ES1688_MIXS_AOUT	0x03
+#define ES1688_MIXS_MIC1	0x04
+#define ES1688_MIXS_REC_MIX	0x05
+#define ES1688_MIXS_LINE	0x06
+#define ES1688_MIXS_MASTER	0x07
+#define ES1688_MIXS_MUTE	0x10
+
+/*
+
+ */
+
+void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data);
+
+int snd_es1688_create(struct snd_card *card,
+		      struct snd_es1688 *chip,
+		      unsigned long port,
+		      unsigned long mpu_port,
+		      int irq,
+		      int mpu_irq,
+		      int dma8,
+		      unsigned short hardware);
+int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device);
+int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip);
+int snd_es1688_reset(struct snd_es1688 *chip);
+
+#endif /* __SOUND_ES1688_H */
diff --git a/include/sound/gus.h b/include/sound/gus.h
new file mode 100644
index 0000000..07c116f
--- /dev/null
+++ b/include/sound/gus.h
@@ -0,0 +1,631 @@
+#ifndef __SOUND_GUS_H
+#define __SOUND_GUS_H
+
+/*
+ *  Global structures used for GUS part of ALSA driver
+ *  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
+ *
+ */
+
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/timer.h>
+#include <sound/seq_midi_emul.h>
+#include <sound/seq_device.h>
+#include <linux/io.h>
+
+/* IO ports */
+
+#define GUSP(gus, x)			((gus)->gf1.port + SNDRV_g_u_s_##x)
+
+#define SNDRV_g_u_s_MIDICTRL		(0x320-0x220)
+#define SNDRV_g_u_s_MIDISTAT		(0x320-0x220)
+#define SNDRV_g_u_s_MIDIDATA		(0x321-0x220)
+
+#define SNDRV_g_u_s_GF1PAGE		(0x322-0x220)
+#define SNDRV_g_u_s_GF1REGSEL		(0x323-0x220)
+#define SNDRV_g_u_s_GF1DATALOW		(0x324-0x220)
+#define SNDRV_g_u_s_GF1DATAHIGH		(0x325-0x220)
+#define SNDRV_g_u_s_IRQSTAT		(0x226-0x220)
+#define SNDRV_g_u_s_TIMERCNTRL		(0x228-0x220)
+#define SNDRV_g_u_s_TIMERDATA		(0x229-0x220)
+#define SNDRV_g_u_s_DRAM		(0x327-0x220)
+#define SNDRV_g_u_s_MIXCNTRLREG		(0x220-0x220)
+#define SNDRV_g_u_s_IRQDMACNTRLREG	(0x22b-0x220)
+#define SNDRV_g_u_s_REGCNTRLS		(0x22f-0x220)
+#define SNDRV_g_u_s_BOARDVERSION	(0x726-0x220)
+#define SNDRV_g_u_s_MIXCNTRLPORT	(0x726-0x220)
+#define SNDRV_g_u_s_IVER		(0x325-0x220)
+#define SNDRV_g_u_s_MIXDATAPORT		(0x326-0x220)
+#define SNDRV_g_u_s_MAXCNTRLPORT	(0x326-0x220)
+
+/* GF1 registers */
+
+/* global registers */
+#define SNDRV_GF1_GB_ACTIVE_VOICES		0x0e
+#define SNDRV_GF1_GB_VOICES_IRQ			0x0f
+#define SNDRV_GF1_GB_GLOBAL_MODE		0x19
+#define SNDRV_GF1_GW_LFO_BASE			0x1a
+#define SNDRV_GF1_GB_VOICES_IRQ_READ		0x1f
+#define SNDRV_GF1_GB_DRAM_DMA_CONTROL		0x41
+#define SNDRV_GF1_GW_DRAM_DMA_LOW		0x42
+#define SNDRV_GF1_GW_DRAM_IO_LOW		0x43
+#define SNDRV_GF1_GB_DRAM_IO_HIGH		0x44
+#define SNDRV_GF1_GB_SOUND_BLASTER_CONTROL	0x45
+#define SNDRV_GF1_GB_ADLIB_TIMER_1		0x46
+#define SNDRV_GF1_GB_ADLIB_TIMER_2		0x47
+#define SNDRV_GF1_GB_RECORD_RATE		0x48
+#define SNDRV_GF1_GB_REC_DMA_CONTROL		0x49
+#define SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL		0x4b
+#define SNDRV_GF1_GB_RESET			0x4c
+#define SNDRV_GF1_GB_DRAM_DMA_HIGH		0x50
+#define SNDRV_GF1_GW_DRAM_IO16			0x51
+#define SNDRV_GF1_GW_MEMORY_CONFIG		0x52
+#define SNDRV_GF1_GB_MEMORY_CONTROL		0x53
+#define SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR	0x54
+#define SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR	0x55
+#define SNDRV_GF1_GW_FIFO_SIZE			0x56
+#define SNDRV_GF1_GW_INTERLEAVE			0x57
+#define SNDRV_GF1_GB_COMPATIBILITY		0x59
+#define SNDRV_GF1_GB_DECODE_CONTROL		0x5a
+#define SNDRV_GF1_GB_VERSION_NUMBER		0x5b
+#define SNDRV_GF1_GB_MPU401_CONTROL_A		0x5c
+#define SNDRV_GF1_GB_MPU401_CONTROL_B		0x5d
+#define SNDRV_GF1_GB_EMULATION_IRQ		0x60
+/* voice specific registers */
+#define SNDRV_GF1_VB_ADDRESS_CONTROL		0x00
+#define SNDRV_GF1_VW_FREQUENCY			0x01
+#define SNDRV_GF1_VW_START_HIGH			0x02
+#define SNDRV_GF1_VW_START_LOW			0x03
+#define SNDRV_GF1_VA_START			SNDRV_GF1_VW_START_HIGH
+#define SNDRV_GF1_VW_END_HIGH			0x04
+#define SNDRV_GF1_VW_END_LOW			0x05
+#define SNDRV_GF1_VA_END			SNDRV_GF1_VW_END_HIGH
+#define SNDRV_GF1_VB_VOLUME_RATE		0x06
+#define SNDRV_GF1_VB_VOLUME_START		0x07
+#define SNDRV_GF1_VB_VOLUME_END			0x08
+#define SNDRV_GF1_VW_VOLUME			0x09
+#define SNDRV_GF1_VW_CURRENT_HIGH		0x0a
+#define SNDRV_GF1_VW_CURRENT_LOW		0x0b
+#define SNDRV_GF1_VA_CURRENT			SNDRV_GF1_VW_CURRENT_HIGH
+#define SNDRV_GF1_VB_PAN			0x0c
+#define SNDRV_GF1_VW_OFFSET_RIGHT		0x0c
+#define SNDRV_GF1_VB_VOLUME_CONTROL		0x0d
+#define SNDRV_GF1_VB_UPPER_ADDRESS		0x10
+#define SNDRV_GF1_VW_EFFECT_HIGH		0x11
+#define SNDRV_GF1_VW_EFFECT_LOW			0x12
+#define SNDRV_GF1_VA_EFFECT			SNDRV_GF1_VW_EFFECT_HIGH
+#define SNDRV_GF1_VW_OFFSET_LEFT		0x13
+#define SNDRV_GF1_VB_ACCUMULATOR		0x14
+#define SNDRV_GF1_VB_MODE			0x15
+#define SNDRV_GF1_VW_EFFECT_VOLUME		0x16
+#define SNDRV_GF1_VB_FREQUENCY_LFO		0x17
+#define SNDRV_GF1_VB_VOLUME_LFO			0x18
+#define SNDRV_GF1_VW_OFFSET_RIGHT_FINAL		0x1b
+#define SNDRV_GF1_VW_OFFSET_LEFT_FINAL		0x1c
+#define SNDRV_GF1_VW_EFFECT_VOLUME_FINAL	0x1d
+
+/* ICS registers */
+
+#define SNDRV_ICS_MIC_DEV		0
+#define SNDRV_ICS_LINE_DEV		1
+#define SNDRV_ICS_CD_DEV		2
+#define SNDRV_ICS_GF1_DEV		3
+#define SNDRV_ICS_NONE_DEV		4
+#define SNDRV_ICS_MASTER_DEV		5
+
+/* LFO */
+
+#define SNDRV_LFO_TREMOLO		0
+#define SNDRV_LFO_VIBRATO		1
+
+/* misc */
+
+#define SNDRV_GF1_DMA_UNSIGNED	0x80
+#define SNDRV_GF1_DMA_16BIT	0x40
+#define SNDRV_GF1_DMA_IRQ	0x20
+#define SNDRV_GF1_DMA_WIDTH16	0x04
+#define SNDRV_GF1_DMA_READ	0x02	/* read from GUS's DRAM */
+#define SNDRV_GF1_DMA_ENABLE	0x01
+
+/* ramp ranges */
+
+#define SNDRV_GF1_ATTEN(x)	(snd_gf1_atten_table[x])
+#define SNDRV_GF1_MIN_VOLUME	1800
+#define SNDRV_GF1_MAX_VOLUME	4095
+#define SNDRV_GF1_MIN_OFFSET	(SNDRV_GF1_MIN_VOLUME>>4)
+#define SNDRV_GF1_MAX_OFFSET	255
+#define SNDRV_GF1_MAX_TDEPTH	90
+
+/* defines for memory manager */
+
+#define SNDRV_GF1_MEM_BLOCK_16BIT	0x0001
+
+#define SNDRV_GF1_MEM_OWNER_DRIVER	0x0001
+#define SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE	0x0002
+#define SNDRV_GF1_MEM_OWNER_WAVE_GF1	0x0003
+#define SNDRV_GF1_MEM_OWNER_WAVE_IWFFFF	0x0004
+
+/* constants for interrupt handlers */
+
+#define SNDRV_GF1_HANDLER_MIDI_OUT	0x00010000
+#define SNDRV_GF1_HANDLER_MIDI_IN	0x00020000
+#define SNDRV_GF1_HANDLER_TIMER1	0x00040000
+#define SNDRV_GF1_HANDLER_TIMER2	0x00080000
+#define SNDRV_GF1_HANDLER_VOICE		0x00100000
+#define SNDRV_GF1_HANDLER_DMA_WRITE	0x00200000
+#define SNDRV_GF1_HANDLER_DMA_READ	0x00400000
+#define SNDRV_GF1_HANDLER_ALL		(0xffff0000&~SNDRV_GF1_HANDLER_VOICE)
+
+/* constants for DMA flags */
+
+#define SNDRV_GF1_DMA_TRIGGER		1
+
+/* --- */
+
+struct snd_gus_card;
+
+/* GF1 specific structure */
+
+struct snd_gf1_bank_info {
+	unsigned int address;
+	unsigned int size;
+};
+
+struct snd_gf1_mem_block {
+	unsigned short flags;	/* flags - SNDRV_GF1_MEM_BLOCK_XXXX */
+	unsigned short owner;	/* owner - SNDRV_GF1_MEM_OWNER_XXXX */
+	unsigned int share;	/* share count */
+	unsigned int share_id[4]; /* share ID */
+	unsigned int ptr;
+	unsigned int size;
+	char *name;
+	struct snd_gf1_mem_block *next;
+	struct snd_gf1_mem_block *prev;
+};
+
+struct snd_gf1_mem {
+	struct snd_gf1_bank_info banks_8[4];
+	struct snd_gf1_bank_info banks_16[4];
+	struct snd_gf1_mem_block *first;
+	struct snd_gf1_mem_block *last;
+	struct mutex memory_mutex;
+};
+
+struct snd_gf1_dma_block {
+	void *buffer;		/* buffer in computer's RAM */
+	unsigned long buf_addr;	/* buffer address */
+	unsigned int addr;	/* address in onboard memory */
+	unsigned int count;	/* count in bytes */
+	unsigned int cmd;	/* DMA command (format) */
+	void (*ack)(struct snd_gus_card * gus, void *private_data);
+	void *private_data;
+	struct snd_gf1_dma_block *next;
+};
+
+struct snd_gus_port {
+	struct snd_midi_channel_set * chset;
+	struct snd_gus_card * gus;
+	int mode;		/* operation mode */
+	int client;		/* sequencer client number */
+	int port;		/* sequencer port number */
+	unsigned int midi_has_voices: 1;
+};
+
+struct snd_gus_voice;
+
+#define SNDRV_GF1_VOICE_TYPE_PCM	0
+#define SNDRV_GF1_VOICE_TYPE_SYNTH 	1
+#define SNDRV_GF1_VOICE_TYPE_MIDI	2
+
+#define SNDRV_GF1_VFLG_RUNNING		(1<<0)
+#define SNDRV_GF1_VFLG_EFFECT_TIMER1	(1<<1)
+#define SNDRV_GF1_VFLG_PAN		(1<<2)
+
+enum snd_gus_volume_state {
+	VENV_BEFORE,
+	VENV_ATTACK,
+	VENV_SUSTAIN,
+	VENV_RELEASE,
+	VENV_DONE,
+	VENV_VOLUME
+};
+
+struct snd_gus_voice {
+	int number;
+	unsigned int use: 1,
+	    pcm: 1,
+	    synth:1,
+	    midi: 1;
+	unsigned int flags;
+	unsigned char client;
+	unsigned char port;
+	unsigned char index;
+	unsigned char pad;
+	
+#ifdef CONFIG_SND_DEBUG
+	unsigned int interrupt_stat_wave;
+	unsigned int interrupt_stat_volume;
+#endif
+	void (*handler_wave) (struct snd_gus_card * gus, struct snd_gus_voice * voice);
+	void (*handler_volume) (struct snd_gus_card * gus, struct snd_gus_voice * voice);
+	void (*handler_effect) (struct snd_gus_card * gus, struct snd_gus_voice * voice);
+	void (*volume_change) (struct snd_gus_card * gus);
+
+	struct snd_gus_sample_ops *sample_ops;
+
+	/* running status / registers */
+
+	unsigned short fc_register;
+	unsigned short fc_lfo;
+	unsigned short gf1_volume;
+	unsigned char control;
+	unsigned char mode;
+	unsigned char gf1_pan;
+	unsigned char effect_accumulator;
+	unsigned char volume_control;
+	unsigned char venv_value_next;
+	enum snd_gus_volume_state venv_state;
+	enum snd_gus_volume_state venv_state_prev;
+	unsigned short vlo;
+	unsigned short vro;
+	unsigned short gf1_effect_volume;
+	
+	/* --- */
+
+	void *private_data;
+	void (*private_free)(struct snd_gus_voice *voice);
+};
+
+struct snd_gf1 {
+
+	unsigned int enh_mode:1,	/* enhanced mode (GFA1) */
+		     hw_lfo:1,		/* use hardware LFO */
+		     sw_lfo:1,		/* use software LFO */
+		     effect:1;		/* use effect voices */
+
+	unsigned long port;		/* port of GF1 chip */
+	struct resource *res_port1;
+	struct resource *res_port2;
+	int irq;			/* IRQ number */
+	int dma1;			/* DMA1 number */
+	int dma2;			/* DMA2 number */
+	unsigned int memory;		/* GUS's DRAM size in bytes */
+	unsigned int rom_memory;	/* GUS's ROM size in bytes */
+	unsigned int rom_present;	/* bitmask */
+	unsigned int rom_banks;		/* GUS's ROM banks */
+
+	struct snd_gf1_mem mem_alloc;
+
+	/* registers */
+	unsigned short reg_page;
+	unsigned short reg_regsel;
+	unsigned short reg_data8;
+	unsigned short reg_data16;
+	unsigned short reg_irqstat;
+	unsigned short reg_dram;
+	unsigned short reg_timerctrl;
+	unsigned short reg_timerdata;
+	unsigned char ics_regs[6][2];
+	/* --------- */
+
+	unsigned char active_voices;	/* active voices */
+	unsigned char active_voice;	/* selected voice (GF1PAGE register) */
+
+	struct snd_gus_voice voices[32];	/* GF1 voices */
+
+	unsigned int default_voice_address;
+
+	unsigned short playback_freq;	/* GF1 playback (mixing) frequency */
+	unsigned short mode;		/* see to SNDRV_GF1_MODE_XXXX */
+	unsigned char volume_ramp;
+	unsigned char smooth_pan;
+	unsigned char full_range_pan;
+	unsigned char pad0;
+
+	unsigned char *lfos;
+
+	/* interrupt handlers */
+
+	void (*interrupt_handler_midi_out) (struct snd_gus_card * gus);
+	void (*interrupt_handler_midi_in) (struct snd_gus_card * gus);
+	void (*interrupt_handler_timer1) (struct snd_gus_card * gus);
+	void (*interrupt_handler_timer2) (struct snd_gus_card * gus);
+	void (*interrupt_handler_dma_write) (struct snd_gus_card * gus);
+	void (*interrupt_handler_dma_read) (struct snd_gus_card * gus);
+
+#ifdef CONFIG_SND_DEBUG
+	unsigned int interrupt_stat_midi_out;
+	unsigned int interrupt_stat_midi_in;
+	unsigned int interrupt_stat_timer1;
+	unsigned int interrupt_stat_timer2;
+	unsigned int interrupt_stat_dma_write;
+	unsigned int interrupt_stat_dma_read;
+	unsigned int interrupt_stat_voice_lost;
+#endif
+
+	/* synthesizer */
+
+	int seq_client;
+	struct snd_gus_port seq_ports[4];
+
+	/* timer */
+
+	unsigned short timer_enabled;
+	struct snd_timer *timer1;
+	struct snd_timer *timer2;
+
+	/* midi */
+
+	unsigned short uart_cmd;
+	unsigned int uart_framing;
+	unsigned int uart_overrun;
+
+	/* dma operations */
+
+	unsigned int dma_flags;
+	unsigned int dma_shared;
+	struct snd_gf1_dma_block *dma_data_pcm;
+	struct snd_gf1_dma_block *dma_data_pcm_last;
+	struct snd_gf1_dma_block *dma_data_synth;
+	struct snd_gf1_dma_block *dma_data_synth_last;
+	void (*dma_ack)(struct snd_gus_card * gus, void *private_data);
+	void *dma_private_data;
+
+	/* pcm */
+	int pcm_channels;
+	int pcm_alloc_voices;
+        unsigned short pcm_volume_level_left;
+	unsigned short pcm_volume_level_right;
+	unsigned short pcm_volume_level_left1;
+	unsigned short pcm_volume_level_right1;
+                                
+	unsigned char pcm_rcntrl_reg;
+	unsigned char pad_end;
+};
+
+/* main structure for GUS card */
+
+struct snd_gus_card {
+	struct snd_card *card;
+
+	unsigned int
+	 initialized: 1,		/* resources were initialized */
+	 equal_irq:1,			/* GF1 and CODEC shares IRQ (GUS MAX only) */
+	 equal_dma:1,			/* if dma channels are equal (not valid for daughter board) */
+	 ics_flag:1,			/* have we ICS mixer chip */
+	 ics_flipped:1,			/* ICS mixer have flipped some channels? */
+	 codec_flag:1,			/* have we CODEC chip? */
+	 max_flag:1,			/* have we GUS MAX card? */
+	 max_ctrl_flag:1,		/* have we original GUS MAX card? */
+	 daughter_flag:1,		/* have we daughter board? */
+	 interwave:1,			/* hey - we have InterWave card */
+	 ess_flag:1,			/* ESS chip found... GUS Extreme */
+	 ace_flag:1,			/* GUS ACE detected */
+	 uart_enable:1;			/* enable MIDI UART */
+	unsigned short revision;	/* revision of chip */
+	unsigned short max_cntrl_val;	/* GUS MAX control value */
+	unsigned short mix_cntrl_reg;	/* mixer control register */
+	unsigned short joystick_dac;	/* joystick DAC level */
+	int timer_dev;			/* timer device */
+
+	struct snd_gf1 gf1;	/* gf1 specific variables */
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *pcm_cap_substream;
+	unsigned int c_dma_size;
+	unsigned int c_period_size;
+	unsigned int c_pos;
+
+	struct snd_rawmidi *midi_uart;
+	struct snd_rawmidi_substream *midi_substream_output;
+	struct snd_rawmidi_substream *midi_substream_input;
+
+	spinlock_t reg_lock;
+	spinlock_t voice_alloc;
+	spinlock_t active_voice_lock;
+	spinlock_t event_lock;
+	spinlock_t dma_lock;
+	spinlock_t pcm_volume_level_lock;
+	spinlock_t uart_cmd_lock;
+	struct mutex dma_mutex;
+	struct mutex register_mutex;
+};
+
+/* I/O functions for GF1/InterWave chip - gus_io.c */
+
+static inline void snd_gf1_select_voice(struct snd_gus_card * gus, int voice)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&gus->active_voice_lock, flags);
+	if (voice != gus->gf1.active_voice) {
+		gus->gf1.active_voice = voice;
+		outb(voice, GUSP(gus, GF1PAGE));
+	}
+	spin_unlock_irqrestore(&gus->active_voice_lock, flags);
+}
+
+static inline void snd_gf1_uart_cmd(struct snd_gus_card * gus, unsigned char b)
+{
+	outb(gus->gf1.uart_cmd = b, GUSP(gus, MIDICTRL));
+}
+
+static inline unsigned char snd_gf1_uart_stat(struct snd_gus_card * gus)
+{
+	return inb(GUSP(gus, MIDISTAT));
+}
+
+static inline void snd_gf1_uart_put(struct snd_gus_card * gus, unsigned char b)
+{
+	outb(b, GUSP(gus, MIDIDATA));
+}
+
+static inline unsigned char snd_gf1_uart_get(struct snd_gus_card * gus)
+{
+	return inb(GUSP(gus, MIDIDATA));
+}
+
+extern void snd_gf1_delay(struct snd_gus_card * gus);
+
+extern void snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg);
+
+extern void snd_gf1_write8(struct snd_gus_card * gus, unsigned char reg, unsigned char data);
+extern unsigned char snd_gf1_look8(struct snd_gus_card * gus, unsigned char reg);
+static inline unsigned char snd_gf1_read8(struct snd_gus_card * gus, unsigned char reg)
+{
+	return snd_gf1_look8(gus, reg | 0x80);
+}
+extern void snd_gf1_write16(struct snd_gus_card * gus, unsigned char reg, unsigned int data);
+extern unsigned short snd_gf1_look16(struct snd_gus_card * gus, unsigned char reg);
+static inline unsigned short snd_gf1_read16(struct snd_gus_card * gus, unsigned char reg)
+{
+	return snd_gf1_look16(gus, reg | 0x80);
+}
+extern void snd_gf1_adlib_write(struct snd_gus_card * gus, unsigned char reg, unsigned char data);
+extern void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr);
+extern void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data);
+extern unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr);
+extern void snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg, unsigned int addr, short w_16bit);
+extern unsigned int snd_gf1_read_addr(struct snd_gus_card * gus, unsigned char reg, short w_16bit);
+extern void snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg);
+extern void snd_gf1_i_write8(struct snd_gus_card * gus, unsigned char reg, unsigned char data);
+extern unsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg);
+extern void snd_gf1_i_write16(struct snd_gus_card * gus, unsigned char reg, unsigned int data);
+static inline unsigned char snd_gf1_i_read8(struct snd_gus_card * gus, unsigned char reg)
+{
+	return snd_gf1_i_look8(gus, reg | 0x80);
+}
+extern unsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg);
+static inline unsigned short snd_gf1_i_read16(struct snd_gus_card * gus, unsigned char reg)
+{
+	return snd_gf1_i_look16(gus, reg | 0x80);
+}
+
+extern void snd_gf1_select_active_voices(struct snd_gus_card * gus);
+
+/* gus_lfo.c */
+
+struct _SND_IW_LFO_PROGRAM {
+	unsigned short freq_and_control;
+	unsigned char depth_final;
+	unsigned char depth_inc;
+	unsigned short twave;
+	unsigned short depth;
+};
+
+#if 0
+extern irqreturn_t snd_gf1_lfo_effect_interrupt(struct snd_gus_card * gus, snd_gf1_voice_t * voice);
+#endif
+extern void snd_gf1_lfo_init(struct snd_gus_card * gus);
+extern void snd_gf1_lfo_done(struct snd_gus_card * gus);
+extern void snd_gf1_lfo_program(struct snd_gus_card * gus, int voice, int lfo_type, struct _SND_IW_LFO_PROGRAM *program);
+extern void snd_gf1_lfo_enable(struct snd_gus_card * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_disable(struct snd_gus_card * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_change_freq(struct snd_gus_card * gus, int voice, int lfo_type, int freq);
+extern void snd_gf1_lfo_change_depth(struct snd_gus_card * gus, int voice, int lfo_type, int depth);
+extern void snd_gf1_lfo_setup(struct snd_gus_card * gus, int voice, int lfo_type, int freq, int current_depth, int depth, int sweep, int shape);
+extern void snd_gf1_lfo_shutdown(struct snd_gus_card * gus, int voice, int lfo_type);
+#if 0
+extern void snd_gf1_lfo_command(struct snd_gus_card * gus, int voice, unsigned char *command);
+#endif
+
+/* gus_mem.c */
+
+void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup);
+int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * block);
+struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owner,
+				       char *name, int size, int w_16,
+				       int align, unsigned int *share_id);
+int snd_gf1_mem_free(struct snd_gf1_mem * alloc, unsigned int address);
+int snd_gf1_mem_free_owner(struct snd_gf1_mem * alloc, int owner);
+int snd_gf1_mem_init(struct snd_gus_card * gus);
+int snd_gf1_mem_done(struct snd_gus_card * gus);
+
+/* gus_mem_proc.c */
+
+int snd_gf1_mem_proc_init(struct snd_gus_card * gus);
+
+/* gus_dma.c */
+
+int snd_gf1_dma_init(struct snd_gus_card * gus);
+int snd_gf1_dma_done(struct snd_gus_card * gus);
+int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
+			       struct snd_gf1_dma_block * block,
+			       int atomic,
+			       int synth);
+
+/* gus_volume.c */
+
+unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol);
+unsigned short snd_gf1_translate_freq(struct snd_gus_card * gus, unsigned int freq2);
+
+/* gus_reset.c */
+
+void snd_gf1_set_default_handlers(struct snd_gus_card * gus, unsigned int what);
+void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice);
+void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice);
+void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsigned short v_max);
+struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, int client, int port);
+void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice);
+int snd_gf1_start(struct snd_gus_card * gus);
+int snd_gf1_stop(struct snd_gus_card * gus);
+
+/* gus_mixer.c */
+
+int snd_gf1_new_mixer(struct snd_gus_card * gus);
+
+/* gus_pcm.c */
+
+int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index);
+
+#ifdef CONFIG_SND_DEBUG
+extern void snd_gf1_print_voice_registers(struct snd_gus_card * gus);
+#endif
+
+/* gus.c */
+
+int snd_gus_use_inc(struct snd_gus_card * gus);
+void snd_gus_use_dec(struct snd_gus_card * gus);
+int snd_gus_create(struct snd_card *card,
+		   unsigned long port,
+		   int irq, int dma1, int dma2,
+		   int timer_dev,
+		   int voices,
+		   int pcm_channels,
+		   int effect,
+		   struct snd_gus_card ** rgus);
+int snd_gus_initialize(struct snd_gus_card * gus);
+
+/* gus_irq.c */
+
+irqreturn_t snd_gus_interrupt(int irq, void *dev_id);
+#ifdef CONFIG_SND_DEBUG
+void snd_gus_irq_profile_init(struct snd_gus_card *gus);
+#endif
+
+/* gus_uart.c */
+
+int snd_gf1_rawmidi_new(struct snd_gus_card *gus, int device);
+
+/* gus_dram.c */
+int snd_gus_dram_write(struct snd_gus_card *gus, char __user *ptr,
+		       unsigned int addr, unsigned int size);
+int snd_gus_dram_read(struct snd_gus_card *gus, char __user *ptr,
+		      unsigned int addr, unsigned int size, int rom);
+
+#endif /* __SOUND_GUS_H */
diff --git a/include/sound/hda_hwdep.h b/include/sound/hda_hwdep.h
new file mode 100644
index 0000000..1c0034e
--- /dev/null
+++ b/include/sound/hda_hwdep.h
@@ -0,0 +1,44 @@
+/*
+ * HWDEP Interface for HD-audio codec
+ *
+ * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
+ *
+ *  This driver 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 driver 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
+ */
+
+#ifndef __SOUND_HDA_HWDEP_H
+#define __SOUND_HDA_HWDEP_H
+
+#define HDA_HWDEP_VERSION	((1 << 16) | (0 << 8) | (0 << 0)) /* 1.0.0 */
+
+/* verb */
+#define HDA_REG_NID_SHIFT	24
+#define HDA_REG_VERB_SHIFT	8
+#define HDA_REG_VAL_SHIFT	0
+#define HDA_VERB(nid,verb,param)	((nid)<<24 | (verb)<<8 | (param))
+
+struct hda_verb_ioctl {
+	u32 verb;	/* HDA_VERB() */
+	u32 res;	/* response */
+};
+
+/*
+ * ioctls
+ */
+#define HDA_IOCTL_PVERSION		_IOR('H', 0x10, int)
+#define HDA_IOCTL_VERB_WRITE		_IOWR('H', 0x11, struct hda_verb_ioctl)
+#define HDA_IOCTL_GET_WCAP		_IOWR('H', 0x12, struct hda_verb_ioctl)
+
+#endif
diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
new file mode 100644
index 0000000..930b41e
--- /dev/null
+++ b/include/sound/hda_i915.h
@@ -0,0 +1,43 @@
+/*
+ * HD-Audio helpers to sync with i915 driver
+ */
+#ifndef __SOUND_HDA_I915_H
+#define __SOUND_HDA_I915_H
+
+#include <drm/i915_component.h>
+
+#ifdef CONFIG_SND_HDA_I915
+int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
+int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
+int snd_hdac_get_display_clk(struct hdac_bus *bus);
+int snd_hdac_i915_init(struct hdac_bus *bus);
+int snd_hdac_i915_exit(struct hdac_bus *bus);
+int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *);
+#else
+static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
+{
+	return 0;
+}
+static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
+{
+	return 0;
+}
+static inline int snd_hdac_get_display_clk(struct hdac_bus *bus)
+{
+	return 0;
+}
+static inline int snd_hdac_i915_init(struct hdac_bus *bus)
+{
+	return -ENODEV;
+}
+static inline int snd_hdac_i915_exit(struct hdac_bus *bus)
+{
+	return 0;
+}
+static inline int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *ops)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif /* __SOUND_HDA_I915_H */
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
new file mode 100644
index 0000000..94dc6a9
--- /dev/null
+++ b/include/sound/hda_register.h
@@ -0,0 +1,251 @@
+/*
+ * HD-audio controller (Azalia) registers and helpers
+ *
+ * For traditional reasons, we still use azx_ prefix here
+ */
+
+#ifndef __SOUND_HDA_REGISTER_H
+#define __SOUND_HDA_REGISTER_H
+
+#include <linux/io.h>
+#include <sound/hdaudio.h>
+
+#define AZX_REG_GCAP			0x00
+#define   AZX_GCAP_64OK		(1 << 0)   /* 64bit address support */
+#define   AZX_GCAP_NSDO		(3 << 1)   /* # of serial data out signals */
+#define   AZX_GCAP_BSS		(31 << 3)  /* # of bidirectional streams */
+#define   AZX_GCAP_ISS		(15 << 8)  /* # of input streams */
+#define   AZX_GCAP_OSS		(15 << 12) /* # of output streams */
+#define AZX_REG_VMIN			0x02
+#define AZX_REG_VMAJ			0x03
+#define AZX_REG_OUTPAY			0x04
+#define AZX_REG_INPAY			0x06
+#define AZX_REG_GCTL			0x08
+#define   AZX_GCTL_RESET	(1 << 0)   /* controller reset */
+#define   AZX_GCTL_FCNTRL	(1 << 1)   /* flush control */
+#define   AZX_GCTL_UNSOL	(1 << 8)   /* accept unsol. response enable */
+#define AZX_REG_WAKEEN			0x0c
+#define AZX_REG_STATESTS		0x0e
+#define AZX_REG_GSTS			0x10
+#define   AZX_GSTS_FSTS		(1 << 1)   /* flush status */
+#define AZX_REG_GCAP2			0x12
+#define AZX_REG_LLCH			0x14
+#define AZX_REG_OUTSTRMPAY		0x18
+#define AZX_REG_INSTRMPAY		0x1A
+#define AZX_REG_INTCTL			0x20
+#define AZX_REG_INTSTS			0x24
+#define AZX_REG_WALLCLK			0x30	/* 24Mhz source */
+#define AZX_REG_OLD_SSYNC		0x34	/* SSYNC for old ICH */
+#define AZX_REG_SSYNC			0x38
+#define AZX_REG_CORBLBASE		0x40
+#define AZX_REG_CORBUBASE		0x44
+#define AZX_REG_CORBWP			0x48
+#define AZX_REG_CORBRP			0x4a
+#define   AZX_CORBRP_RST	(1 << 15)  /* read pointer reset */
+#define AZX_REG_CORBCTL			0x4c
+#define   AZX_CORBCTL_RUN	(1 << 1)   /* enable DMA */
+#define   AZX_CORBCTL_CMEIE	(1 << 0)   /* enable memory error irq */
+#define AZX_REG_CORBSTS			0x4d
+#define   AZX_CORBSTS_CMEI	(1 << 0)   /* memory error indication */
+#define AZX_REG_CORBSIZE		0x4e
+
+#define AZX_REG_RIRBLBASE		0x50
+#define AZX_REG_RIRBUBASE		0x54
+#define AZX_REG_RIRBWP			0x58
+#define   AZX_RIRBWP_RST	(1 << 15)  /* write pointer reset */
+#define AZX_REG_RINTCNT			0x5a
+#define AZX_REG_RIRBCTL			0x5c
+#define   AZX_RBCTL_IRQ_EN	(1 << 0)   /* enable IRQ */
+#define   AZX_RBCTL_DMA_EN	(1 << 1)   /* enable DMA */
+#define   AZX_RBCTL_OVERRUN_EN	(1 << 2)   /* enable overrun irq */
+#define AZX_REG_RIRBSTS			0x5d
+#define   AZX_RBSTS_IRQ		(1 << 0)   /* response irq */
+#define   AZX_RBSTS_OVERRUN	(1 << 2)   /* overrun irq */
+#define AZX_REG_RIRBSIZE		0x5e
+
+#define AZX_REG_IC			0x60
+#define AZX_REG_IR			0x64
+#define AZX_REG_IRS			0x68
+#define   AZX_IRS_VALID		(1<<1)
+#define   AZX_IRS_BUSY		(1<<0)
+
+#define AZX_REG_DPLBASE			0x70
+#define AZX_REG_DPUBASE			0x74
+#define   AZX_DPLBASE_ENABLE	0x1	/* Enable position buffer */
+
+/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
+enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
+
+/* stream register offsets from stream base */
+#define AZX_REG_SD_CTL			0x00
+#define AZX_REG_SD_STS			0x03
+#define AZX_REG_SD_LPIB			0x04
+#define AZX_REG_SD_CBL			0x08
+#define AZX_REG_SD_LVI			0x0c
+#define AZX_REG_SD_FIFOW		0x0e
+#define AZX_REG_SD_FIFOSIZE		0x10
+#define AZX_REG_SD_FORMAT		0x12
+#define AZX_REG_SD_FIFOL		0x14
+#define AZX_REG_SD_BDLPL		0x18
+#define AZX_REG_SD_BDLPU		0x1c
+
+/* Haswell/Broadwell display HD-A controller Extended Mode registers */
+#define AZX_REG_HSW_EM4			0x100c
+#define AZX_REG_HSW_EM5			0x1010
+
+/* Skylake/Broxton display HD-A controller Extended Mode registers */
+#define AZX_REG_SKL_EM4L		0x1040
+
+/* PCI space */
+#define AZX_PCIREG_TCSEL		0x44
+
+/*
+ * other constants
+ */
+
+/* max number of fragments - we may use more if allocating more pages for BDL */
+#define BDL_SIZE		4096
+#define AZX_MAX_BDL_ENTRIES	(BDL_SIZE / 16)
+#define AZX_MAX_FRAG		32
+/* max buffer size - no h/w limit, you can increase as you like */
+#define AZX_MAX_BUF_SIZE	(1024*1024*1024)
+
+/* RIRB int mask: overrun[2], response[0] */
+#define RIRB_INT_RESPONSE	0x01
+#define RIRB_INT_OVERRUN	0x04
+#define RIRB_INT_MASK		0x05
+
+/* STATESTS int mask: S3,SD2,SD1,SD0 */
+#define STATESTS_INT_MASK	((1 << HDA_MAX_CODECS) - 1)
+
+/* SD_CTL bits */
+#define SD_CTL_STREAM_RESET	0x01	/* stream reset bit */
+#define SD_CTL_DMA_START	0x02	/* stream DMA start bit */
+#define SD_CTL_STRIPE		(3 << 16)	/* stripe control */
+#define SD_CTL_TRAFFIC_PRIO	(1 << 18)	/* traffic priority */
+#define SD_CTL_DIR		(1 << 19)	/* bi-directional stream */
+#define SD_CTL_STREAM_TAG_MASK	(0xf << 20)
+#define SD_CTL_STREAM_TAG_SHIFT	20
+
+/* SD_CTL and SD_STS */
+#define SD_INT_DESC_ERR		0x10	/* descriptor error interrupt */
+#define SD_INT_FIFO_ERR		0x08	/* FIFO error interrupt */
+#define SD_INT_COMPLETE		0x04	/* completion interrupt */
+#define SD_INT_MASK		(SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\
+				 SD_INT_COMPLETE)
+
+/* SD_STS */
+#define SD_STS_FIFO_READY	0x20	/* FIFO ready */
+
+/* INTCTL and INTSTS */
+#define AZX_INT_ALL_STREAM	0xff	   /* all stream interrupts */
+#define AZX_INT_CTRL_EN	0x40000000 /* controller interrupt enable bit */
+#define AZX_INT_GLOBAL_EN	0x80000000 /* global interrupt enable bit */
+
+/* below are so far hardcoded - should read registers in future */
+#define AZX_MAX_CORB_ENTRIES	256
+#define AZX_MAX_RIRB_ENTRIES	256
+
+/* Capability header  Structure */
+#define AZX_REG_CAP_HDR			0x0
+#define AZX_CAP_HDR_VER_OFF		28
+#define AZX_CAP_HDR_VER_MASK		(0xF << AZX_CAP_HDR_VER_OFF)
+#define AZX_CAP_HDR_ID_OFF		16
+#define AZX_CAP_HDR_ID_MASK		(0xFFF << AZX_CAP_HDR_ID_OFF)
+#define AZX_CAP_HDR_NXT_PTR_MASK	0xFFFF
+
+/* registers of Software Position Based FIFO Capability Structure */
+#define AZX_SPB_CAP_ID			0x4
+#define AZX_REG_SPB_BASE_ADDR		0x700
+#define AZX_REG_SPB_SPBFCH		0x00
+#define AZX_REG_SPB_SPBFCCTL		0x04
+/* Base used to calculate the iterating register offset */
+#define AZX_SPB_BASE			0x08
+/* Interval used to calculate the iterating register offset */
+#define AZX_SPB_INTERVAL		0x08
+/* SPIB base */
+#define AZX_SPB_SPIB			0x00
+/* SPIB MAXFIFO base*/
+#define AZX_SPB_MAXFIFO			0x04
+
+/* registers of Global Time Synchronization Capability Structure */
+#define AZX_GTS_CAP_ID			0x1
+#define AZX_REG_GTS_GTSCH		0x00
+#define AZX_REG_GTS_GTSCD		0x04
+#define AZX_REG_GTS_GTSCTLAC		0x0C
+#define AZX_GTS_BASE			0x20
+#define AZX_GTS_INTERVAL		0x20
+
+/* registers for Processing Pipe Capability Structure */
+#define AZX_PP_CAP_ID			0x3
+#define AZX_REG_PP_PPCH			0x10
+#define AZX_REG_PP_PPCTL		0x04
+#define AZX_PPCTL_PIE			(1<<31)
+#define AZX_PPCTL_GPROCEN		(1<<30)
+/* _X_ = dma engine # and cannot * exceed 29 (per spec max 30 dma engines) */
+#define AZX_PPCTL_PROCEN(_X_)		(1<<(_X_))
+
+#define AZX_REG_PP_PPSTS		0x08
+
+#define AZX_PPHC_BASE			0x10
+#define AZX_PPHC_INTERVAL		0x10
+
+#define AZX_REG_PPHCLLPL		0x0
+#define AZX_REG_PPHCLLPU		0x4
+#define AZX_REG_PPHCLDPL		0x8
+#define AZX_REG_PPHCLDPU		0xC
+
+#define AZX_PPLC_BASE			0x10
+#define AZX_PPLC_MULTI			0x10
+#define AZX_PPLC_INTERVAL		0x10
+
+#define AZX_REG_PPLCCTL			0x0
+#define AZX_PPLCCTL_STRM_BITS		4
+#define AZX_PPLCCTL_STRM_SHIFT		20
+#define AZX_REG_MASK(bit_num, offset) \
+	(((1 << (bit_num)) - 1) << (offset))
+#define AZX_PPLCCTL_STRM_MASK \
+	AZX_REG_MASK(AZX_PPLCCTL_STRM_BITS, AZX_PPLCCTL_STRM_SHIFT)
+#define AZX_PPLCCTL_RUN			(1<<1)
+#define AZX_PPLCCTL_STRST		(1<<0)
+
+#define AZX_REG_PPLCFMT			0x4
+#define AZX_REG_PPLCLLPL		0x8
+#define AZX_REG_PPLCLLPU		0xC
+
+/* registers for Multiple Links Capability Structure */
+#define AZX_ML_CAP_ID			0x2
+#define AZX_REG_ML_MLCH			0x00
+#define AZX_REG_ML_MLCD			0x04
+#define AZX_ML_BASE			0x40
+#define AZX_ML_INTERVAL			0x40
+
+#define AZX_REG_ML_LCAP			0x00
+#define AZX_REG_ML_LCTL			0x04
+#define AZX_REG_ML_LOSIDV		0x08
+#define AZX_REG_ML_LSDIID		0x0C
+#define AZX_REG_ML_LPSOO		0x10
+#define AZX_REG_ML_LPSIO		0x12
+#define AZX_REG_ML_LWALFC		0x18
+#define AZX_REG_ML_LOUTPAY		0x20
+#define AZX_REG_ML_LINPAY		0x30
+
+#define AZX_MLCTL_SPA			(1<<16)
+#define AZX_MLCTL_CPA			23
+
+/*
+ * helpers to read the stream position
+ */
+static inline unsigned int
+snd_hdac_stream_get_pos_lpib(struct hdac_stream *stream)
+{
+	return snd_hdac_stream_readl(stream, SD_LPIB);
+}
+
+static inline unsigned int
+snd_hdac_stream_get_pos_posbuf(struct hdac_stream *stream)
+{
+	return le32_to_cpu(*stream->posbuf);
+}
+
+#endif /* __SOUND_HDA_REGISTER_H */
diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h
new file mode 100644
index 0000000..2767c55
--- /dev/null
+++ b/include/sound/hda_regmap.h
@@ -0,0 +1,219 @@
+/*
+ * HD-audio regmap helpers
+ */
+
+#ifndef __SOUND_HDA_REGMAP_H
+#define __SOUND_HDA_REGMAP_H
+
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/hdaudio.h>
+
+#define AC_AMP_FAKE_MUTE	0x10	/* fake mute bit set to amp verbs */
+
+int snd_hdac_regmap_init(struct hdac_device *codec);
+void snd_hdac_regmap_exit(struct hdac_device *codec);
+int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
+				    unsigned int verb);
+int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
+			     unsigned int *val);
+int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
+			      unsigned int val);
+int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
+			       unsigned int mask, unsigned int val);
+
+/**
+ * snd_hdac_regmap_encode_verb - encode the verb to a pseudo register
+ * @nid: widget NID
+ * @verb: codec verb
+ *
+ * Returns an encoded pseudo register.
+ */
+#define snd_hdac_regmap_encode_verb(nid, verb)		\
+	(((verb) << 8) | 0x80000 | ((unsigned int)(nid) << 20))
+
+/**
+ * snd_hdac_regmap_encode_amp - encode the AMP verb to a pseudo register
+ * @nid: widget NID
+ * @ch: channel (left = 0, right = 1)
+ * @dir: direction (#HDA_INPUT, #HDA_OUTPUT)
+ * @idx: input index value
+ *
+ * Returns an encoded pseudo register.
+ */
+#define snd_hdac_regmap_encode_amp(nid, ch, dir, idx)			\
+	(snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) |	\
+	 ((ch) ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT) |			\
+	 ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
+	 (idx))
+
+/**
+ * snd_hdac_regmap_encode_amp_stereo - encode a pseudo register for stereo AMPs
+ * @nid: widget NID
+ * @dir: direction (#HDA_INPUT, #HDA_OUTPUT)
+ * @idx: input index value
+ *
+ * Returns an encoded pseudo register.
+ */
+#define snd_hdac_regmap_encode_amp_stereo(nid, dir, idx)		\
+	(snd_hdac_regmap_encode_verb(nid, AC_VERB_GET_AMP_GAIN_MUTE) |	\
+	 AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT | /* both bits set! */	\
+	 ((dir) == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT) | \
+	 (idx))
+
+/**
+ * snd_hdac_regmap_write - Write a verb with caching
+ * @nid: codec NID
+ * @reg: verb to write
+ * @val: value to write
+ *
+ * For writing an amp value, use snd_hdac_regmap_update_amp().
+ */
+static inline int
+snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
+		      unsigned int verb, unsigned int val)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
+
+	return snd_hdac_regmap_write_raw(codec, cmd, val);
+}
+
+/**
+ * snd_hda_regmap_update - Update a verb value with caching
+ * @nid: codec NID
+ * @verb: verb to update
+ * @mask: bit mask to update
+ * @val: value to update
+ *
+ * For updating an amp value, use snd_hdac_regmap_update_amp().
+ */
+static inline int
+snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
+		       unsigned int verb, unsigned int mask,
+		       unsigned int val)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
+
+	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
+}
+
+/**
+ * snd_hda_regmap_read - Read a verb with caching
+ * @nid: codec NID
+ * @verb: verb to read
+ * @val: pointer to store the value
+ *
+ * For reading an amp value, use snd_hda_regmap_get_amp().
+ */
+static inline int
+snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
+		     unsigned int verb, unsigned int *val)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_verb(nid, verb);
+
+	return snd_hdac_regmap_read_raw(codec, cmd, val);
+}
+
+/**
+ * snd_hdac_regmap_get_amp - Read AMP value
+ * @codec: HD-audio codec
+ * @nid: NID to read the AMP value
+ * @ch: channel (left=0 or right=1)
+ * @direction: #HDA_INPUT or #HDA_OUTPUT
+ * @index: the index value (only for input direction)
+ * @val: the pointer to store the value
+ *
+ * Read AMP value.  The volume is between 0 to 0x7f, 0x80 = mute bit.
+ * Returns the value or a negative error.
+ */
+static inline int
+snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
+			int ch, int dir, int idx)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
+	int err, val;
+
+	err = snd_hdac_regmap_read_raw(codec, cmd, &val);
+	return err < 0 ? err : val;
+}
+
+/**
+ * snd_hdac_regmap_update_amp - update the AMP value
+ * @codec: HD-audio codec
+ * @nid: NID to read the AMP value
+ * @ch: channel (left=0 or right=1)
+ * @direction: #HDA_INPUT or #HDA_OUTPUT
+ * @idx: the index value (only for input direction)
+ * @mask: bit mask to set
+ * @val: the bits value to set
+ *
+ * Update the AMP value with a bit mask.
+ * Returns 0 if the value is unchanged, 1 if changed, or a negative error.
+ */
+static inline int
+snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
+			   int ch, int dir, int idx, int mask, int val)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
+
+	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
+}
+
+/**
+ * snd_hdac_regmap_get_amp_stereo - Read stereo AMP values
+ * @codec: HD-audio codec
+ * @nid: NID to read the AMP value
+ * @ch: channel (left=0 or right=1)
+ * @direction: #HDA_INPUT or #HDA_OUTPUT
+ * @index: the index value (only for input direction)
+ * @val: the pointer to store the value
+ *
+ * Read stereo AMP values.  The lower byte is left, the upper byte is right.
+ * Returns the value or a negative error.
+ */
+static inline int
+snd_hdac_regmap_get_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
+			       int dir, int idx)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_amp_stereo(nid, dir, idx);
+	int err, val;
+
+	err = snd_hdac_regmap_read_raw(codec, cmd, &val);
+	return err < 0 ? err : val;
+}
+
+/**
+ * snd_hdac_regmap_update_amp_stereo - update the stereo AMP value
+ * @codec: HD-audio codec
+ * @nid: NID to read the AMP value
+ * @direction: #HDA_INPUT or #HDA_OUTPUT
+ * @idx: the index value (only for input direction)
+ * @mask: bit mask to set
+ * @val: the bits value to set
+ *
+ * Update the stereo AMP value with a bit mask.
+ * The lower byte is left, the upper byte is right.
+ * Returns 0 if the value is unchanged, 1 if changed, or a negative error.
+ */
+static inline int
+snd_hdac_regmap_update_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
+				  int dir, int idx, int mask, int val)
+{
+	unsigned int cmd = snd_hdac_regmap_encode_amp_stereo(nid, dir, idx);
+
+	return snd_hdac_regmap_update_raw(codec, cmd, mask, val);
+}
+
+/**
+ * snd_hdac_regmap_sync_node - sync the widget node attributes
+ * @codec: HD-audio codec
+ * @nid: NID to sync
+ */
+static inline void
+snd_hdac_regmap_sync_node(struct hdac_device *codec, hda_nid_t nid)
+{
+	regcache_mark_dirty(codec->regmap);
+	regcache_sync_region(codec->regmap, nid << 20, ((nid + 1) << 20) - 1);
+}
+
+#endif /* __SOUND_HDA_REGMAP_H */
diff --git a/include/sound/hda_verbs.h b/include/sound/hda_verbs.h
new file mode 100644
index 0000000..d0509db
--- /dev/null
+++ b/include/sound/hda_verbs.h
@@ -0,0 +1,554 @@
+/*
+ * HD-audio codec verbs
+ */
+
+#ifndef __SOUND_HDA_VERBS_H
+#define __SOUND_HDA_VERBS_H
+
+/*
+ * nodes
+ */
+#define	AC_NODE_ROOT		0x00
+
+/*
+ * function group types
+ */
+enum {
+	AC_GRP_AUDIO_FUNCTION = 0x01,
+	AC_GRP_MODEM_FUNCTION = 0x02,
+};
+
+/*
+ * widget types
+ */
+enum {
+	AC_WID_AUD_OUT,		/* Audio Out */
+	AC_WID_AUD_IN,		/* Audio In */
+	AC_WID_AUD_MIX,		/* Audio Mixer */
+	AC_WID_AUD_SEL,		/* Audio Selector */
+	AC_WID_PIN,		/* Pin Complex */
+	AC_WID_POWER,		/* Power */
+	AC_WID_VOL_KNB,		/* Volume Knob */
+	AC_WID_BEEP,		/* Beep Generator */
+	AC_WID_VENDOR = 0x0f	/* Vendor specific */
+};
+
+/*
+ * GET verbs
+ */
+#define AC_VERB_GET_STREAM_FORMAT		0x0a00
+#define AC_VERB_GET_AMP_GAIN_MUTE		0x0b00
+#define AC_VERB_GET_PROC_COEF			0x0c00
+#define AC_VERB_GET_COEF_INDEX			0x0d00
+#define AC_VERB_PARAMETERS			0x0f00
+#define AC_VERB_GET_CONNECT_SEL			0x0f01
+#define AC_VERB_GET_CONNECT_LIST		0x0f02
+#define AC_VERB_GET_PROC_STATE			0x0f03
+#define AC_VERB_GET_SDI_SELECT			0x0f04
+#define AC_VERB_GET_POWER_STATE			0x0f05
+#define AC_VERB_GET_CONV			0x0f06
+#define AC_VERB_GET_PIN_WIDGET_CONTROL		0x0f07
+#define AC_VERB_GET_UNSOLICITED_RESPONSE	0x0f08
+#define AC_VERB_GET_PIN_SENSE			0x0f09
+#define AC_VERB_GET_BEEP_CONTROL		0x0f0a
+#define AC_VERB_GET_EAPD_BTLENABLE		0x0f0c
+#define AC_VERB_GET_DIGI_CONVERT_1		0x0f0d
+#define AC_VERB_GET_DIGI_CONVERT_2		0x0f0e /* unused */
+#define AC_VERB_GET_VOLUME_KNOB_CONTROL		0x0f0f
+/* f10-f1a: GPIO */
+#define AC_VERB_GET_GPIO_DATA			0x0f15
+#define AC_VERB_GET_GPIO_MASK			0x0f16
+#define AC_VERB_GET_GPIO_DIRECTION		0x0f17
+#define AC_VERB_GET_GPIO_WAKE_MASK		0x0f18
+#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK	0x0f19
+#define AC_VERB_GET_GPIO_STICKY_MASK		0x0f1a
+#define AC_VERB_GET_CONFIG_DEFAULT		0x0f1c
+/* f20: AFG/MFG */
+#define AC_VERB_GET_SUBSYSTEM_ID		0x0f20
+#define AC_VERB_GET_CVT_CHAN_COUNT		0x0f2d
+#define AC_VERB_GET_HDMI_DIP_SIZE		0x0f2e
+#define AC_VERB_GET_HDMI_ELDD			0x0f2f
+#define AC_VERB_GET_HDMI_DIP_INDEX		0x0f30
+#define AC_VERB_GET_HDMI_DIP_DATA		0x0f31
+#define AC_VERB_GET_HDMI_DIP_XMIT		0x0f32
+#define AC_VERB_GET_HDMI_CP_CTRL		0x0f33
+#define AC_VERB_GET_HDMI_CHAN_SLOT		0x0f34
+#define AC_VERB_GET_DEVICE_SEL			0xf35
+#define AC_VERB_GET_DEVICE_LIST			0xf36
+
+/*
+ * SET verbs
+ */
+#define AC_VERB_SET_STREAM_FORMAT		0x200
+#define AC_VERB_SET_AMP_GAIN_MUTE		0x300
+#define AC_VERB_SET_PROC_COEF			0x400
+#define AC_VERB_SET_COEF_INDEX			0x500
+#define AC_VERB_SET_CONNECT_SEL			0x701
+#define AC_VERB_SET_PROC_STATE			0x703
+#define AC_VERB_SET_SDI_SELECT			0x704
+#define AC_VERB_SET_POWER_STATE			0x705
+#define AC_VERB_SET_CHANNEL_STREAMID		0x706
+#define AC_VERB_SET_PIN_WIDGET_CONTROL		0x707
+#define AC_VERB_SET_UNSOLICITED_ENABLE		0x708
+#define AC_VERB_SET_PIN_SENSE			0x709
+#define AC_VERB_SET_BEEP_CONTROL		0x70a
+#define AC_VERB_SET_EAPD_BTLENABLE		0x70c
+#define AC_VERB_SET_DIGI_CONVERT_1		0x70d
+#define AC_VERB_SET_DIGI_CONVERT_2		0x70e
+#define AC_VERB_SET_VOLUME_KNOB_CONTROL		0x70f
+#define AC_VERB_SET_GPIO_DATA			0x715
+#define AC_VERB_SET_GPIO_MASK			0x716
+#define AC_VERB_SET_GPIO_DIRECTION		0x717
+#define AC_VERB_SET_GPIO_WAKE_MASK		0x718
+#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK	0x719
+#define AC_VERB_SET_GPIO_STICKY_MASK		0x71a
+#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0	0x71c
+#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1	0x71d
+#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2	0x71e
+#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3	0x71f
+#define AC_VERB_SET_EAPD				0x788
+#define AC_VERB_SET_CODEC_RESET			0x7ff
+#define AC_VERB_SET_CVT_CHAN_COUNT		0x72d
+#define AC_VERB_SET_HDMI_DIP_INDEX		0x730
+#define AC_VERB_SET_HDMI_DIP_DATA		0x731
+#define AC_VERB_SET_HDMI_DIP_XMIT		0x732
+#define AC_VERB_SET_HDMI_CP_CTRL		0x733
+#define AC_VERB_SET_HDMI_CHAN_SLOT		0x734
+#define AC_VERB_SET_DEVICE_SEL			0x735
+
+/*
+ * Parameter IDs
+ */
+#define AC_PAR_VENDOR_ID		0x00
+#define AC_PAR_SUBSYSTEM_ID		0x01
+#define AC_PAR_REV_ID			0x02
+#define AC_PAR_NODE_COUNT		0x04
+#define AC_PAR_FUNCTION_TYPE		0x05
+#define AC_PAR_AUDIO_FG_CAP		0x08
+#define AC_PAR_AUDIO_WIDGET_CAP		0x09
+#define AC_PAR_PCM			0x0a
+#define AC_PAR_STREAM			0x0b
+#define AC_PAR_PIN_CAP			0x0c
+#define AC_PAR_AMP_IN_CAP		0x0d
+#define AC_PAR_CONNLIST_LEN		0x0e
+#define AC_PAR_POWER_STATE		0x0f
+#define AC_PAR_PROC_CAP			0x10
+#define AC_PAR_GPIO_CAP			0x11
+#define AC_PAR_AMP_OUT_CAP		0x12
+#define AC_PAR_VOL_KNB_CAP		0x13
+#define AC_PAR_DEVLIST_LEN		0x15
+#define AC_PAR_HDMI_LPCM_CAP		0x20
+
+/*
+ * AC_VERB_PARAMETERS results (32bit)
+ */
+
+/* Function Group Type */
+#define AC_FGT_TYPE			(0xff<<0)
+#define AC_FGT_TYPE_SHIFT		0
+#define AC_FGT_UNSOL_CAP		(1<<8)
+
+/* Audio Function Group Capabilities */
+#define AC_AFG_OUT_DELAY		(0xf<<0)
+#define AC_AFG_IN_DELAY			(0xf<<8)
+#define AC_AFG_BEEP_GEN			(1<<16)
+
+/* Audio Widget Capabilities */
+#define AC_WCAP_STEREO			(1<<0)	/* stereo I/O */
+#define AC_WCAP_IN_AMP			(1<<1)	/* AMP-in present */
+#define AC_WCAP_OUT_AMP			(1<<2)	/* AMP-out present */
+#define AC_WCAP_AMP_OVRD		(1<<3)	/* AMP-parameter override */
+#define AC_WCAP_FORMAT_OVRD		(1<<4)	/* format override */
+#define AC_WCAP_STRIPE			(1<<5)	/* stripe */
+#define AC_WCAP_PROC_WID		(1<<6)	/* Proc Widget */
+#define AC_WCAP_UNSOL_CAP		(1<<7)	/* Unsol capable */
+#define AC_WCAP_CONN_LIST		(1<<8)	/* connection list */
+#define AC_WCAP_DIGITAL			(1<<9)	/* digital I/O */
+#define AC_WCAP_POWER			(1<<10)	/* power control */
+#define AC_WCAP_LR_SWAP			(1<<11)	/* L/R swap */
+#define AC_WCAP_CP_CAPS			(1<<12) /* content protection */
+#define AC_WCAP_CHAN_CNT_EXT		(7<<13)	/* channel count ext */
+#define AC_WCAP_DELAY			(0xf<<16)
+#define AC_WCAP_DELAY_SHIFT		16
+#define AC_WCAP_TYPE			(0xf<<20)
+#define AC_WCAP_TYPE_SHIFT		20
+
+/* supported PCM rates and bits */
+#define AC_SUPPCM_RATES			(0xfff << 0)
+#define AC_SUPPCM_BITS_8		(1<<16)
+#define AC_SUPPCM_BITS_16		(1<<17)
+#define AC_SUPPCM_BITS_20		(1<<18)
+#define AC_SUPPCM_BITS_24		(1<<19)
+#define AC_SUPPCM_BITS_32		(1<<20)
+
+/* supported PCM stream format */
+#define AC_SUPFMT_PCM			(1<<0)
+#define AC_SUPFMT_FLOAT32		(1<<1)
+#define AC_SUPFMT_AC3			(1<<2)
+
+/* GP I/O count */
+#define AC_GPIO_IO_COUNT		(0xff<<0)
+#define AC_GPIO_O_COUNT			(0xff<<8)
+#define AC_GPIO_O_COUNT_SHIFT		8
+#define AC_GPIO_I_COUNT			(0xff<<16)
+#define AC_GPIO_I_COUNT_SHIFT		16
+#define AC_GPIO_UNSOLICITED		(1<<30)
+#define AC_GPIO_WAKE			(1<<31)
+
+/* Converter stream, channel */
+#define AC_CONV_CHANNEL			(0xf<<0)
+#define AC_CONV_STREAM			(0xf<<4)
+#define AC_CONV_STREAM_SHIFT		4
+
+/* Input converter SDI select */
+#define AC_SDI_SELECT			(0xf<<0)
+
+/* stream format id */
+#define AC_FMT_CHAN_SHIFT		0
+#define AC_FMT_CHAN_MASK		(0x0f << 0)
+#define AC_FMT_BITS_SHIFT		4
+#define AC_FMT_BITS_MASK		(7 << 4)
+#define AC_FMT_BITS_8			(0 << 4)
+#define AC_FMT_BITS_16			(1 << 4)
+#define AC_FMT_BITS_20			(2 << 4)
+#define AC_FMT_BITS_24			(3 << 4)
+#define AC_FMT_BITS_32			(4 << 4)
+#define AC_FMT_DIV_SHIFT		8
+#define AC_FMT_DIV_MASK			(7 << 8)
+#define AC_FMT_MULT_SHIFT		11
+#define AC_FMT_MULT_MASK		(7 << 11)
+#define AC_FMT_BASE_SHIFT		14
+#define AC_FMT_BASE_48K			(0 << 14)
+#define AC_FMT_BASE_44K			(1 << 14)
+#define AC_FMT_TYPE_SHIFT		15
+#define AC_FMT_TYPE_PCM			(0 << 15)
+#define AC_FMT_TYPE_NON_PCM		(1 << 15)
+
+/* Unsolicited response control */
+#define AC_UNSOL_TAG			(0x3f<<0)
+#define AC_UNSOL_ENABLED		(1<<7)
+#define AC_USRSP_EN			AC_UNSOL_ENABLED
+
+/* Unsolicited responses */
+#define AC_UNSOL_RES_TAG		(0x3f<<26)
+#define AC_UNSOL_RES_TAG_SHIFT		26
+#define AC_UNSOL_RES_SUBTAG		(0x1f<<21)
+#define AC_UNSOL_RES_SUBTAG_SHIFT	21
+#define AC_UNSOL_RES_DE			(0x3f<<15)  /* Device Entry
+						     * (for DP1.2 MST)
+						     */
+#define AC_UNSOL_RES_DE_SHIFT		15
+#define AC_UNSOL_RES_IA			(1<<2)	/* Inactive (for DP1.2 MST) */
+#define AC_UNSOL_RES_ELDV		(1<<1)	/* ELD Data valid (for HDMI) */
+#define AC_UNSOL_RES_PD			(1<<0)	/* pinsense detect */
+#define AC_UNSOL_RES_CP_STATE		(1<<1)	/* content protection */
+#define AC_UNSOL_RES_CP_READY		(1<<0)	/* content protection */
+
+/* Pin widget capabilies */
+#define AC_PINCAP_IMP_SENSE		(1<<0)	/* impedance sense capable */
+#define AC_PINCAP_TRIG_REQ		(1<<1)	/* trigger required */
+#define AC_PINCAP_PRES_DETECT		(1<<2)	/* presence detect capable */
+#define AC_PINCAP_HP_DRV		(1<<3)	/* headphone drive capable */
+#define AC_PINCAP_OUT			(1<<4)	/* output capable */
+#define AC_PINCAP_IN			(1<<5)	/* input capable */
+#define AC_PINCAP_BALANCE		(1<<6)	/* balanced I/O capable */
+/* Note: This LR_SWAP pincap is defined in the Realtek ALC883 specification,
+ *       but is marked reserved in the Intel HDA specification.
+ */
+#define AC_PINCAP_LR_SWAP		(1<<7)	/* L/R swap */
+/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
+ *       in HD-audio specification
+ */
+#define AC_PINCAP_HDMI			(1<<7)	/* HDMI pin */
+#define AC_PINCAP_DP			(1<<24)	/* DisplayPort pin, can
+						 * coexist with AC_PINCAP_HDMI
+						 */
+#define AC_PINCAP_VREF			(0x37<<8)
+#define AC_PINCAP_VREF_SHIFT		8
+#define AC_PINCAP_EAPD			(1<<16)	/* EAPD capable */
+#define AC_PINCAP_HBR			(1<<27)	/* High Bit Rate */
+/* Vref status (used in pin cap) */
+#define AC_PINCAP_VREF_HIZ		(1<<0)	/* Hi-Z */
+#define AC_PINCAP_VREF_50		(1<<1)	/* 50% */
+#define AC_PINCAP_VREF_GRD		(1<<2)	/* ground */
+#define AC_PINCAP_VREF_80		(1<<4)	/* 80% */
+#define AC_PINCAP_VREF_100		(1<<5)	/* 100% */
+
+/* Amplifier capabilities */
+#define AC_AMPCAP_OFFSET		(0x7f<<0)  /* 0dB offset */
+#define AC_AMPCAP_OFFSET_SHIFT		0
+#define AC_AMPCAP_NUM_STEPS		(0x7f<<8)  /* number of steps */
+#define AC_AMPCAP_NUM_STEPS_SHIFT	8
+#define AC_AMPCAP_STEP_SIZE		(0x7f<<16) /* step size 0-32dB
+						    * in 0.25dB
+						    */
+#define AC_AMPCAP_STEP_SIZE_SHIFT	16
+#define AC_AMPCAP_MUTE			(1<<31)    /* mute capable */
+#define AC_AMPCAP_MUTE_SHIFT		31
+
+/* driver-specific amp-caps: using bits 24-30 */
+#define AC_AMPCAP_MIN_MUTE		(1 << 30) /* min-volume = mute */
+
+/* Connection list */
+#define AC_CLIST_LENGTH			(0x7f<<0)
+#define AC_CLIST_LONG			(1<<7)
+
+/* Supported power status */
+#define AC_PWRST_D0SUP			(1<<0)
+#define AC_PWRST_D1SUP			(1<<1)
+#define AC_PWRST_D2SUP			(1<<2)
+#define AC_PWRST_D3SUP			(1<<3)
+#define AC_PWRST_D3COLDSUP		(1<<4)
+#define AC_PWRST_S3D3COLDSUP		(1<<29)
+#define AC_PWRST_CLKSTOP		(1<<30)
+#define AC_PWRST_EPSS			(1U<<31)
+
+/* Power state values */
+#define AC_PWRST_SETTING		(0xf<<0)
+#define AC_PWRST_ACTUAL			(0xf<<4)
+#define AC_PWRST_ACTUAL_SHIFT		4
+#define AC_PWRST_D0			0x00
+#define AC_PWRST_D1			0x01
+#define AC_PWRST_D2			0x02
+#define AC_PWRST_D3			0x03
+#define AC_PWRST_ERROR                  (1<<8)
+#define AC_PWRST_CLK_STOP_OK            (1<<9)
+#define AC_PWRST_SETTING_RESET          (1<<10)
+
+/* Processing capabilies */
+#define AC_PCAP_BENIGN			(1<<0)
+#define AC_PCAP_NUM_COEF		(0xff<<8)
+#define AC_PCAP_NUM_COEF_SHIFT		8
+
+/* Volume knobs capabilities */
+#define AC_KNBCAP_NUM_STEPS		(0x7f<<0)
+#define AC_KNBCAP_DELTA			(1<<7)
+
+/* HDMI LPCM capabilities */
+#define AC_LPCMCAP_48K_CP_CHNS		(0x0f<<0) /* max channels w/ CP-on */
+#define AC_LPCMCAP_48K_NO_CHNS		(0x0f<<4) /* max channels w/o CP-on */
+#define AC_LPCMCAP_48K_20BIT		(1<<8)	/* 20b bitrate supported */
+#define AC_LPCMCAP_48K_24BIT		(1<<9)	/* 24b bitrate supported */
+#define AC_LPCMCAP_96K_CP_CHNS		(0x0f<<10) /* max channels w/ CP-on */
+#define AC_LPCMCAP_96K_NO_CHNS		(0x0f<<14) /* max channels w/o CP-on */
+#define AC_LPCMCAP_96K_20BIT		(1<<18)	/* 20b bitrate supported */
+#define AC_LPCMCAP_96K_24BIT		(1<<19)	/* 24b bitrate supported */
+#define AC_LPCMCAP_192K_CP_CHNS		(0x0f<<20) /* max channels w/ CP-on */
+#define AC_LPCMCAP_192K_NO_CHNS		(0x0f<<24) /* max channels w/o CP-on */
+#define AC_LPCMCAP_192K_20BIT		(1<<28)	/* 20b bitrate supported */
+#define AC_LPCMCAP_192K_24BIT		(1<<29)	/* 24b bitrate supported */
+#define AC_LPCMCAP_44K			(1<<30)	/* 44.1kHz support */
+#define AC_LPCMCAP_44K_MS		(1<<31)	/* 44.1kHz-multiplies support */
+
+/* Display pin's device list length */
+#define AC_DEV_LIST_LEN_MASK		0x3f
+#define AC_MAX_DEV_LIST_LEN		64
+
+/*
+ * Control Parameters
+ */
+
+/* Amp gain/mute */
+#define AC_AMP_MUTE			(1<<7)
+#define AC_AMP_GAIN			(0x7f)
+#define AC_AMP_GET_INDEX		(0xf<<0)
+
+#define AC_AMP_GET_LEFT			(1<<13)
+#define AC_AMP_GET_RIGHT		(0<<13)
+#define AC_AMP_GET_OUTPUT		(1<<15)
+#define AC_AMP_GET_INPUT		(0<<15)
+
+#define AC_AMP_SET_INDEX		(0xf<<8)
+#define AC_AMP_SET_INDEX_SHIFT		8
+#define AC_AMP_SET_RIGHT		(1<<12)
+#define AC_AMP_SET_LEFT			(1<<13)
+#define AC_AMP_SET_INPUT		(1<<14)
+#define AC_AMP_SET_OUTPUT		(1<<15)
+
+/* DIGITAL1 bits */
+#define AC_DIG1_ENABLE			(1<<0)
+#define AC_DIG1_V			(1<<1)
+#define AC_DIG1_VCFG			(1<<2)
+#define AC_DIG1_EMPHASIS		(1<<3)
+#define AC_DIG1_COPYRIGHT		(1<<4)
+#define AC_DIG1_NONAUDIO		(1<<5)
+#define AC_DIG1_PROFESSIONAL		(1<<6)
+#define AC_DIG1_LEVEL			(1<<7)
+
+/* DIGITAL2 bits */
+#define AC_DIG2_CC			(0x7f<<0)
+
+/* DIGITAL3 bits */
+#define AC_DIG3_ICT			(0xf<<0)
+#define AC_DIG3_KAE			(1<<7)
+
+/* Pin widget control - 8bit */
+#define AC_PINCTL_EPT			(0x3<<0)
+#define AC_PINCTL_EPT_NATIVE		0
+#define AC_PINCTL_EPT_HBR		3
+#define AC_PINCTL_VREFEN		(0x7<<0)
+#define AC_PINCTL_VREF_HIZ		0	/* Hi-Z */
+#define AC_PINCTL_VREF_50		1	/* 50% */
+#define AC_PINCTL_VREF_GRD		2	/* ground */
+#define AC_PINCTL_VREF_80		4	/* 80% */
+#define AC_PINCTL_VREF_100		5	/* 100% */
+#define AC_PINCTL_IN_EN			(1<<5)
+#define AC_PINCTL_OUT_EN		(1<<6)
+#define AC_PINCTL_HP_EN			(1<<7)
+
+/* Pin sense - 32bit */
+#define AC_PINSENSE_IMPEDANCE_MASK	(0x7fffffff)
+#define AC_PINSENSE_PRESENCE		(1<<31)
+#define AC_PINSENSE_ELDV		(1<<30)	/* ELD valid (HDMI) */
+
+/* EAPD/BTL enable - 32bit */
+#define AC_EAPDBTL_BALANCED		(1<<0)
+#define AC_EAPDBTL_EAPD			(1<<1)
+#define AC_EAPDBTL_LR_SWAP		(1<<2)
+
+/* HDMI ELD data */
+#define AC_ELDD_ELD_VALID		(1<<31)
+#define AC_ELDD_ELD_DATA		0xff
+
+/* HDMI DIP size */
+#define AC_DIPSIZE_ELD_BUF		(1<<3) /* ELD buf size of packet size */
+#define AC_DIPSIZE_PACK_IDX		(0x07<<0) /* packet index */
+
+/* HDMI DIP index */
+#define AC_DIPIDX_PACK_IDX		(0x07<<5) /* packet idnex */
+#define AC_DIPIDX_BYTE_IDX		(0x1f<<0) /* byte index */
+
+/* HDMI DIP xmit (transmit) control */
+#define AC_DIPXMIT_MASK			(0x3<<6)
+#define AC_DIPXMIT_DISABLE		(0x0<<6) /* disable xmit */
+#define AC_DIPXMIT_ONCE			(0x2<<6) /* xmit once then disable */
+#define AC_DIPXMIT_BEST			(0x3<<6) /* best effort */
+
+/* HDMI content protection (CP) control */
+#define AC_CPCTRL_CES			(1<<9) /* current encryption state */
+#define AC_CPCTRL_READY			(1<<8) /* ready bit */
+#define AC_CPCTRL_SUBTAG		(0x1f<<3) /* subtag for unsol-resp */
+#define AC_CPCTRL_STATE			(3<<0) /* current CP request state */
+
+/* Converter channel <-> HDMI slot mapping */
+#define AC_CVTMAP_HDMI_SLOT		(0xf<<0) /* HDMI slot number */
+#define AC_CVTMAP_CHAN			(0xf<<4) /* converter channel number */
+
+/* configuration default - 32bit */
+#define AC_DEFCFG_SEQUENCE		(0xf<<0)
+#define AC_DEFCFG_DEF_ASSOC		(0xf<<4)
+#define AC_DEFCFG_ASSOC_SHIFT		4
+#define AC_DEFCFG_MISC			(0xf<<8)
+#define AC_DEFCFG_MISC_SHIFT		8
+#define AC_DEFCFG_MISC_NO_PRESENCE	(1<<0)
+#define AC_DEFCFG_COLOR			(0xf<<12)
+#define AC_DEFCFG_COLOR_SHIFT		12
+#define AC_DEFCFG_CONN_TYPE		(0xf<<16)
+#define AC_DEFCFG_CONN_TYPE_SHIFT	16
+#define AC_DEFCFG_DEVICE		(0xf<<20)
+#define AC_DEFCFG_DEVICE_SHIFT		20
+#define AC_DEFCFG_LOCATION		(0x3f<<24)
+#define AC_DEFCFG_LOCATION_SHIFT	24
+#define AC_DEFCFG_PORT_CONN		(0x3<<30)
+#define AC_DEFCFG_PORT_CONN_SHIFT	30
+
+/* Display pin's device list entry */
+#define AC_DE_PD			(1<<0)
+#define AC_DE_ELDV			(1<<1)
+#define AC_DE_IA			(1<<2)
+
+/* device device types (0x0-0xf) */
+enum {
+	AC_JACK_LINE_OUT,
+	AC_JACK_SPEAKER,
+	AC_JACK_HP_OUT,
+	AC_JACK_CD,
+	AC_JACK_SPDIF_OUT,
+	AC_JACK_DIG_OTHER_OUT,
+	AC_JACK_MODEM_LINE_SIDE,
+	AC_JACK_MODEM_HAND_SIDE,
+	AC_JACK_LINE_IN,
+	AC_JACK_AUX,
+	AC_JACK_MIC_IN,
+	AC_JACK_TELEPHONY,
+	AC_JACK_SPDIF_IN,
+	AC_JACK_DIG_OTHER_IN,
+	AC_JACK_OTHER = 0xf,
+};
+
+/* jack connection types (0x0-0xf) */
+enum {
+	AC_JACK_CONN_UNKNOWN,
+	AC_JACK_CONN_1_8,
+	AC_JACK_CONN_1_4,
+	AC_JACK_CONN_ATAPI,
+	AC_JACK_CONN_RCA,
+	AC_JACK_CONN_OPTICAL,
+	AC_JACK_CONN_OTHER_DIGITAL,
+	AC_JACK_CONN_OTHER_ANALOG,
+	AC_JACK_CONN_DIN,
+	AC_JACK_CONN_XLR,
+	AC_JACK_CONN_RJ11,
+	AC_JACK_CONN_COMB,
+	AC_JACK_CONN_OTHER = 0xf,
+};
+
+/* jack colors (0x0-0xf) */
+enum {
+	AC_JACK_COLOR_UNKNOWN,
+	AC_JACK_COLOR_BLACK,
+	AC_JACK_COLOR_GREY,
+	AC_JACK_COLOR_BLUE,
+	AC_JACK_COLOR_GREEN,
+	AC_JACK_COLOR_RED,
+	AC_JACK_COLOR_ORANGE,
+	AC_JACK_COLOR_YELLOW,
+	AC_JACK_COLOR_PURPLE,
+	AC_JACK_COLOR_PINK,
+	AC_JACK_COLOR_WHITE = 0xe,
+	AC_JACK_COLOR_OTHER,
+};
+
+/* Jack location (0x0-0x3f) */
+/* common case */
+enum {
+	AC_JACK_LOC_NONE,
+	AC_JACK_LOC_REAR,
+	AC_JACK_LOC_FRONT,
+	AC_JACK_LOC_LEFT,
+	AC_JACK_LOC_RIGHT,
+	AC_JACK_LOC_TOP,
+	AC_JACK_LOC_BOTTOM,
+};
+/* bits 4-5 */
+enum {
+	AC_JACK_LOC_EXTERNAL = 0x00,
+	AC_JACK_LOC_INTERNAL = 0x10,
+	AC_JACK_LOC_SEPARATE = 0x20,
+	AC_JACK_LOC_OTHER    = 0x30,
+};
+enum {
+	/* external on primary chasis */
+	AC_JACK_LOC_REAR_PANEL = 0x07,
+	AC_JACK_LOC_DRIVE_BAY,
+	/* internal */
+	AC_JACK_LOC_RISER = 0x17,
+	AC_JACK_LOC_HDMI,
+	AC_JACK_LOC_ATAPI,
+	/* others */
+	AC_JACK_LOC_MOBILE_IN = 0x37,
+	AC_JACK_LOC_MOBILE_OUT,
+};
+
+/* Port connectivity (0-3) */
+enum {
+	AC_JACK_PORT_COMPLEX,
+	AC_JACK_PORT_NONE,
+	AC_JACK_PORT_FIXED,
+	AC_JACK_PORT_BOTH,
+};
+
+/* max. codec address */
+#define HDA_MAX_CODEC_ADDRESS	0x0f
+
+#endif /* __SOUND_HDA_VERBS_H */
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
new file mode 100644
index 0000000..e2b712c
--- /dev/null
+++ b/include/sound/hdaudio.h
@@ -0,0 +1,552 @@
+/*
+ * HD-audio core stuff
+ */
+
+#ifndef __SOUND_HDAUDIO_H
+#define __SOUND_HDAUDIO_H
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/timecounter.h>
+#include <sound/core.h>
+#include <sound/memalloc.h>
+#include <sound/hda_verbs.h>
+#include <drm/i915_component.h>
+
+/* codec node id */
+typedef u16 hda_nid_t;
+
+struct hdac_bus;
+struct hdac_stream;
+struct hdac_device;
+struct hdac_driver;
+struct hdac_widget_tree;
+struct hda_device_id;
+
+/*
+ * exported bus type
+ */
+extern struct bus_type snd_hda_bus_type;
+
+/*
+ * generic arrays
+ */
+struct snd_array {
+	unsigned int used;
+	unsigned int alloced;
+	unsigned int elem_size;
+	unsigned int alloc_align;
+	void *list;
+};
+
+/*
+ * HD-audio codec base device
+ */
+struct hdac_device {
+	struct device dev;
+	int type;
+	struct hdac_bus *bus;
+	unsigned int addr;		/* codec address */
+	struct list_head list;		/* list point for bus codec_list */
+
+	hda_nid_t afg;			/* AFG node id */
+	hda_nid_t mfg;			/* MFG node id */
+
+	/* ids */
+	unsigned int vendor_id;
+	unsigned int subsystem_id;
+	unsigned int revision_id;
+	unsigned int afg_function_id;
+	unsigned int mfg_function_id;
+	unsigned int afg_unsol:1;
+	unsigned int mfg_unsol:1;
+
+	unsigned int power_caps;	/* FG power caps */
+
+	const char *vendor_name;	/* codec vendor name */
+	const char *chip_name;		/* codec chip name */
+
+	/* verb exec op override */
+	int (*exec_verb)(struct hdac_device *dev, unsigned int cmd,
+			 unsigned int flags, unsigned int *res);
+
+	/* widgets */
+	unsigned int num_nodes;
+	hda_nid_t start_nid, end_nid;
+
+	/* misc flags */
+	atomic_t in_pm;		/* suspend/resume being performed */
+	bool  link_power_control:1;
+
+	/* sysfs */
+	struct hdac_widget_tree *widgets;
+
+	/* regmap */
+	struct regmap *regmap;
+	struct snd_array vendor_verbs;
+	bool lazy_cache:1;	/* don't wake up for writes */
+	bool caps_overwriting:1; /* caps overwrite being in process */
+	bool cache_coef:1;	/* cache COEF read/write too */
+};
+
+/* device/driver type used for matching */
+enum {
+	HDA_DEV_CORE,
+	HDA_DEV_LEGACY,
+	HDA_DEV_ASOC,
+};
+
+/* direction */
+enum {
+	HDA_INPUT, HDA_OUTPUT
+};
+
+#define dev_to_hdac_dev(_dev)	container_of(_dev, struct hdac_device, dev)
+
+int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
+			 const char *name, unsigned int addr);
+void snd_hdac_device_exit(struct hdac_device *dev);
+int snd_hdac_device_register(struct hdac_device *codec);
+void snd_hdac_device_unregister(struct hdac_device *codec);
+int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
+int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
+
+int snd_hdac_refresh_widgets(struct hdac_device *codec);
+int snd_hdac_refresh_widget_sysfs(struct hdac_device *codec);
+
+unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
+			       unsigned int verb, unsigned int parm);
+int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd,
+		       unsigned int flags, unsigned int *res);
+int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
+		  unsigned int verb, unsigned int parm, unsigned int *res);
+int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
+			unsigned int *res);
+int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
+				int parm);
+int snd_hdac_override_parm(struct hdac_device *codec, hda_nid_t nid,
+			   unsigned int parm, unsigned int val);
+int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
+			     hda_nid_t *conn_list, int max_conns);
+int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
+			   hda_nid_t *start_id);
+unsigned int snd_hdac_calc_stream_format(unsigned int rate,
+					 unsigned int channels,
+					 unsigned int format,
+					 unsigned int maxbps,
+					 unsigned short spdif_ctls);
+int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
+				u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
+bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
+				  unsigned int format);
+
+int snd_hdac_codec_read(struct hdac_device *hdac, hda_nid_t nid,
+			int flags, unsigned int verb, unsigned int parm);
+int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
+			int flags, unsigned int verb, unsigned int parm);
+bool snd_hdac_check_power_state(struct hdac_device *hdac,
+		hda_nid_t nid, unsigned int target_state);
+/**
+ * snd_hdac_read_parm - read a codec parameter
+ * @codec: the codec object
+ * @nid: NID to read a parameter
+ * @parm: parameter to read
+ *
+ * Returns -1 for error.  If you need to distinguish the error more
+ * strictly, use _snd_hdac_read_parm() directly.
+ */
+static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
+				     int parm)
+{
+	unsigned int val;
+
+	return _snd_hdac_read_parm(codec, nid, parm, &val) < 0 ? -1 : val;
+}
+
+#ifdef CONFIG_PM
+int snd_hdac_power_up(struct hdac_device *codec);
+int snd_hdac_power_down(struct hdac_device *codec);
+int snd_hdac_power_up_pm(struct hdac_device *codec);
+int snd_hdac_power_down_pm(struct hdac_device *codec);
+#else
+static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
+static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
+#endif
+
+/*
+ * HD-audio codec base driver
+ */
+struct hdac_driver {
+	struct device_driver driver;
+	int type;
+	const struct hda_device_id *id_table;
+	int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
+	void (*unsol_event)(struct hdac_device *dev, unsigned int event);
+};
+
+#define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
+
+const struct hda_device_id *
+hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv);
+
+/*
+ * Bus verb operators
+ */
+struct hdac_bus_ops {
+	/* send a single command */
+	int (*command)(struct hdac_bus *bus, unsigned int cmd);
+	/* get a response from the last command */
+	int (*get_response)(struct hdac_bus *bus, unsigned int addr,
+			    unsigned int *res);
+	/* control the link power  */
+	int (*link_power)(struct hdac_bus *bus, bool enable);
+};
+
+/*
+ * Lowlevel I/O operators
+ */
+struct hdac_io_ops {
+	/* mapped register accesses */
+	void (*reg_writel)(u32 value, u32 __iomem *addr);
+	u32 (*reg_readl)(u32 __iomem *addr);
+	void (*reg_writew)(u16 value, u16 __iomem *addr);
+	u16 (*reg_readw)(u16 __iomem *addr);
+	void (*reg_writeb)(u8 value, u8 __iomem *addr);
+	u8 (*reg_readb)(u8 __iomem *addr);
+	/* Allocation ops */
+	int (*dma_alloc_pages)(struct hdac_bus *bus, int type, size_t size,
+			       struct snd_dma_buffer *buf);
+	void (*dma_free_pages)(struct hdac_bus *bus,
+			       struct snd_dma_buffer *buf);
+};
+
+#define HDA_UNSOL_QUEUE_SIZE	64
+#define HDA_MAX_CODECS		8	/* limit by controller side */
+
+/* HD Audio class code */
+#define PCI_CLASS_MULTIMEDIA_HD_AUDIO	0x0403
+
+/*
+ * CORB/RIRB
+ *
+ * Each CORB entry is 4byte, RIRB is 8byte
+ */
+struct hdac_rb {
+	__le32 *buf;		/* virtual address of CORB/RIRB buffer */
+	dma_addr_t addr;	/* physical address of CORB/RIRB buffer */
+	unsigned short rp, wp;	/* RIRB read/write pointers */
+	int cmds[HDA_MAX_CODECS];	/* number of pending requests */
+	u32 res[HDA_MAX_CODECS];	/* last read value */
+};
+
+/*
+ * HD-audio bus base driver
+ */
+struct hdac_bus {
+	struct device *dev;
+	const struct hdac_bus_ops *ops;
+	const struct hdac_io_ops *io_ops;
+
+	/* h/w resources */
+	unsigned long addr;
+	void __iomem *remap_addr;
+	int irq;
+
+	/* codec linked list */
+	struct list_head codec_list;
+	unsigned int num_codecs;
+
+	/* link caddr -> codec */
+	struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
+
+	/* unsolicited event queue */
+	u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
+	unsigned int unsol_rp, unsol_wp;
+	struct work_struct unsol_work;
+
+	/* bit flags of detected codecs */
+	unsigned long codec_mask;
+
+	/* bit flags of powered codecs */
+	unsigned long codec_powered;
+
+	/* CORB/RIRB */
+	struct hdac_rb corb;
+	struct hdac_rb rirb;
+	unsigned int last_cmd[HDA_MAX_CODECS];	/* last sent command */
+
+	/* CORB/RIRB and position buffers */
+	struct snd_dma_buffer rb;
+	struct snd_dma_buffer posbuf;
+
+	/* hdac_stream linked list */
+	struct list_head stream_list;
+
+	/* operation state */
+	bool chip_init:1;		/* h/w initialized */
+
+	/* behavior flags */
+	bool sync_write:1;		/* sync after verb write */
+	bool use_posbuf:1;		/* use position buffer */
+	bool snoop:1;			/* enable snooping */
+	bool align_bdle_4k:1;		/* BDLE align 4K boundary */
+	bool reverse_assign:1;		/* assign devices in reverse order */
+	bool corbrp_self_clear:1;	/* CORBRP clears itself after reset */
+
+	int bdl_pos_adj;		/* BDL position adjustment */
+
+	/* locks */
+	spinlock_t reg_lock;
+	struct mutex cmd_mutex;
+
+	/* i915 component interface */
+	struct i915_audio_component *audio_component;
+	int i915_power_refcount;
+};
+
+int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
+		      const struct hdac_bus_ops *ops,
+		      const struct hdac_io_ops *io_ops);
+void snd_hdac_bus_exit(struct hdac_bus *bus);
+int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
+			   unsigned int cmd, unsigned int *res);
+int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
+				    unsigned int cmd, unsigned int *res);
+void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
+
+int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
+void snd_hdac_bus_remove_device(struct hdac_bus *bus,
+				struct hdac_device *codec);
+
+static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
+{
+	set_bit(codec->addr, &codec->bus->codec_powered);
+}
+
+static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
+{
+	clear_bit(codec->addr, &codec->bus->codec_powered);
+}
+
+int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
+int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
+			      unsigned int *res);
+int snd_hdac_link_power(struct hdac_device *codec, bool enable);
+
+bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
+void snd_hdac_bus_stop_chip(struct hdac_bus *bus);
+void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus);
+void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
+void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
+void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
+
+void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
+void snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
+				    void (*ack)(struct hdac_bus *,
+						struct hdac_stream *));
+
+int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus);
+void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
+
+/*
+ * macros for easy use
+ */
+#define _snd_hdac_chip_write(type, chip, reg, value) \
+	((chip)->io_ops->reg_write ## type(value, (chip)->remap_addr + (reg)))
+#define _snd_hdac_chip_read(type, chip, reg) \
+	((chip)->io_ops->reg_read ## type((chip)->remap_addr + (reg)))
+
+/* read/write a register, pass without AZX_REG_ prefix */
+#define snd_hdac_chip_writel(chip, reg, value) \
+	_snd_hdac_chip_write(l, chip, AZX_REG_ ## reg, value)
+#define snd_hdac_chip_writew(chip, reg, value) \
+	_snd_hdac_chip_write(w, chip, AZX_REG_ ## reg, value)
+#define snd_hdac_chip_writeb(chip, reg, value) \
+	_snd_hdac_chip_write(b, chip, AZX_REG_ ## reg, value)
+#define snd_hdac_chip_readl(chip, reg) \
+	_snd_hdac_chip_read(l, chip, AZX_REG_ ## reg)
+#define snd_hdac_chip_readw(chip, reg) \
+	_snd_hdac_chip_read(w, chip, AZX_REG_ ## reg)
+#define snd_hdac_chip_readb(chip, reg) \
+	_snd_hdac_chip_read(b, chip, AZX_REG_ ## reg)
+
+/* update a register, pass without AZX_REG_ prefix */
+#define snd_hdac_chip_updatel(chip, reg, mask, val) \
+	snd_hdac_chip_writel(chip, reg, \
+			     (snd_hdac_chip_readl(chip, reg) & ~(mask)) | (val))
+#define snd_hdac_chip_updatew(chip, reg, mask, val) \
+	snd_hdac_chip_writew(chip, reg, \
+			     (snd_hdac_chip_readw(chip, reg) & ~(mask)) | (val))
+#define snd_hdac_chip_updateb(chip, reg, mask, val) \
+	snd_hdac_chip_writeb(chip, reg, \
+			     (snd_hdac_chip_readb(chip, reg) & ~(mask)) | (val))
+
+/*
+ * HD-audio stream
+ */
+struct hdac_stream {
+	struct hdac_bus *bus;
+	struct snd_dma_buffer bdl; /* BDL buffer */
+	__le32 *posbuf;		/* position buffer pointer */
+	int direction;		/* playback / capture (SNDRV_PCM_STREAM_*) */
+
+	unsigned int bufsize;	/* size of the play buffer in bytes */
+	unsigned int period_bytes; /* size of the period in bytes */
+	unsigned int frags;	/* number for period in the play buffer */
+	unsigned int fifo_size;	/* FIFO size */
+
+	void __iomem *sd_addr;	/* stream descriptor pointer */
+
+	u32 sd_int_sta_mask;	/* stream int status mask */
+
+	/* pcm support */
+	struct snd_pcm_substream *substream;	/* assigned substream,
+						 * set in PCM open
+						 */
+	unsigned int format_val;	/* format value to be set in the
+					 * controller and the codec
+					 */
+	unsigned char stream_tag;	/* assigned stream */
+	unsigned char index;		/* stream index */
+	int assigned_key;		/* last device# key assigned to */
+
+	bool opened:1;
+	bool running:1;
+	bool prepared:1;
+	bool no_period_wakeup:1;
+	bool locked:1;
+
+	/* timestamp */
+	unsigned long start_wallclk;	/* start + minimum wallclk */
+	unsigned long period_wallclk;	/* wallclk for period */
+	struct timecounter  tc;
+	struct cyclecounter cc;
+	int delay_negative_threshold;
+
+	struct list_head list;
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+	/* DSP access mutex */
+	struct mutex dsp_mutex;
+#endif
+};
+
+void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
+			  int idx, int direction, int tag);
+struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
+					   struct snd_pcm_substream *substream);
+void snd_hdac_stream_release(struct hdac_stream *azx_dev);
+struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
+					int dir, int stream_tag);
+
+int snd_hdac_stream_setup(struct hdac_stream *azx_dev);
+void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev);
+int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev);
+int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
+				unsigned int format_val);
+void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
+void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
+void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
+void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
+void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
+				  unsigned int streams, unsigned int reg);
+void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
+			  unsigned int streams);
+void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
+				      unsigned int streams);
+/*
+ * macros for easy use
+ */
+#define _snd_hdac_stream_write(type, dev, reg, value)			\
+	((dev)->bus->io_ops->reg_write ## type(value, (dev)->sd_addr + (reg)))
+#define _snd_hdac_stream_read(type, dev, reg)				\
+	((dev)->bus->io_ops->reg_read ## type((dev)->sd_addr + (reg)))
+
+/* read/write a register, pass without AZX_REG_ prefix */
+#define snd_hdac_stream_writel(dev, reg, value) \
+	_snd_hdac_stream_write(l, dev, AZX_REG_ ## reg, value)
+#define snd_hdac_stream_writew(dev, reg, value) \
+	_snd_hdac_stream_write(w, dev, AZX_REG_ ## reg, value)
+#define snd_hdac_stream_writeb(dev, reg, value) \
+	_snd_hdac_stream_write(b, dev, AZX_REG_ ## reg, value)
+#define snd_hdac_stream_readl(dev, reg) \
+	_snd_hdac_stream_read(l, dev, AZX_REG_ ## reg)
+#define snd_hdac_stream_readw(dev, reg) \
+	_snd_hdac_stream_read(w, dev, AZX_REG_ ## reg)
+#define snd_hdac_stream_readb(dev, reg) \
+	_snd_hdac_stream_read(b, dev, AZX_REG_ ## reg)
+
+/* update a register, pass without AZX_REG_ prefix */
+#define snd_hdac_stream_updatel(dev, reg, mask, val) \
+	snd_hdac_stream_writel(dev, reg, \
+			       (snd_hdac_stream_readl(dev, reg) & \
+				~(mask)) | (val))
+#define snd_hdac_stream_updatew(dev, reg, mask, val) \
+	snd_hdac_stream_writew(dev, reg, \
+			       (snd_hdac_stream_readw(dev, reg) & \
+				~(mask)) | (val))
+#define snd_hdac_stream_updateb(dev, reg, mask, val) \
+	snd_hdac_stream_writeb(dev, reg, \
+			       (snd_hdac_stream_readb(dev, reg) & \
+				~(mask)) | (val))
+
+#ifdef CONFIG_SND_HDA_DSP_LOADER
+/* DSP lock helpers */
+#define snd_hdac_dsp_lock_init(dev)	mutex_init(&(dev)->dsp_mutex)
+#define snd_hdac_dsp_lock(dev)		mutex_lock(&(dev)->dsp_mutex)
+#define snd_hdac_dsp_unlock(dev)	mutex_unlock(&(dev)->dsp_mutex)
+#define snd_hdac_stream_is_locked(dev)	((dev)->locked)
+/* DSP loader helpers */
+int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
+			 unsigned int byte_size, struct snd_dma_buffer *bufp);
+void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start);
+void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
+			  struct snd_dma_buffer *dmab);
+#else /* CONFIG_SND_HDA_DSP_LOADER */
+#define snd_hdac_dsp_lock_init(dev)	do {} while (0)
+#define snd_hdac_dsp_lock(dev)		do {} while (0)
+#define snd_hdac_dsp_unlock(dev)	do {} while (0)
+#define snd_hdac_stream_is_locked(dev)	0
+
+static inline int
+snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
+		     unsigned int byte_size, struct snd_dma_buffer *bufp)
+{
+	return 0;
+}
+
+static inline void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start)
+{
+}
+
+static inline void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
+					struct snd_dma_buffer *dmab)
+{
+}
+#endif /* CONFIG_SND_HDA_DSP_LOADER */
+
+
+/*
+ * generic array helpers
+ */
+void *snd_array_new(struct snd_array *array);
+void snd_array_free(struct snd_array *array);
+static inline void snd_array_init(struct snd_array *array, unsigned int size,
+				  unsigned int align)
+{
+	array->elem_size = size;
+	array->alloc_align = align;
+}
+
+static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
+{
+	return array->list + idx * array->elem_size;
+}
+
+static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
+{
+	return (unsigned long)(ptr - array->list) / array->elem_size;
+}
+
+#endif /* __SOUND_HDAUDIO_H */
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
new file mode 100644
index 0000000..a4cadd9
--- /dev/null
+++ b/include/sound/hdaudio_ext.h
@@ -0,0 +1,210 @@
+#ifndef __SOUND_HDAUDIO_EXT_H
+#define __SOUND_HDAUDIO_EXT_H
+
+#include <sound/hdaudio.h>
+
+/**
+ * hdac_ext_bus: HDAC extended bus for extended HDA caps
+ *
+ * @bus: hdac bus
+ * @num_streams: streams supported
+ * @ppcap: pp capabilities pointer
+ * @spbcap: SPIB capabilities pointer
+ * @mlcap: MultiLink capabilities pointer
+ * @gtscap: gts capabilities pointer
+ * @hlink_list: link list of HDA links
+ */
+struct hdac_ext_bus {
+	struct hdac_bus bus;
+	int num_streams;
+	int idx;
+
+	void __iomem *ppcap;
+	void __iomem *spbcap;
+	void __iomem *mlcap;
+	void __iomem *gtscap;
+
+	struct list_head hlink_list;
+};
+
+int snd_hdac_ext_bus_init(struct hdac_ext_bus *sbus, struct device *dev,
+		      const struct hdac_bus_ops *ops,
+		      const struct hdac_io_ops *io_ops);
+
+void snd_hdac_ext_bus_exit(struct hdac_ext_bus *sbus);
+int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *sbus, int addr);
+void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
+void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus);
+
+#define ebus_to_hbus(ebus)	(&(ebus)->bus)
+#define hbus_to_ebus(_bus) \
+	container_of(_bus, struct hdac_ext_bus, bus)
+
+#define HDA_CODEC_REV_EXT_ENTRY(_vid, _rev, _name, drv_data) \
+	{ .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
+	  .api_version = HDA_DEV_ASOC, \
+	  .driver_data = (unsigned long)(drv_data) }
+#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
+	HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
+
+int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus);
+void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable);
+void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable);
+
+void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *chip,
+				 bool enable, int index);
+
+int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *bus);
+struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_ext_bus *bus,
+						const char *codec_name);
+
+enum hdac_ext_stream_type {
+	HDAC_EXT_STREAM_TYPE_COUPLED = 0,
+	HDAC_EXT_STREAM_TYPE_HOST,
+	HDAC_EXT_STREAM_TYPE_LINK
+};
+
+/**
+ * hdac_ext_stream: HDAC extended stream for extended HDA caps
+ *
+ * @hstream: hdac_stream
+ * @pphc_addr: processing pipe host stream pointer
+ * @pplc_addr: processing pipe link stream pointer
+ * @spib_addr: software position in buffers stream pointer
+ * @fifo_addr: software position Max fifos stream pointer
+ * @decoupled: stream host and link is decoupled
+ * @link_locked: link is locked
+ * @link_prepared: link is prepared
+ * link_substream: link substream
+ */
+struct hdac_ext_stream {
+	struct hdac_stream hstream;
+
+	void __iomem *pphc_addr;
+	void __iomem *pplc_addr;
+
+	void __iomem *spib_addr;
+	void __iomem *fifo_addr;
+
+	bool decoupled:1;
+	bool link_locked:1;
+	bool link_prepared;
+
+	struct snd_pcm_substream *link_substream;
+};
+
+#define hdac_stream(s)		(&(s)->hstream)
+#define stream_to_hdac_ext_stream(s) \
+	container_of(s, struct hdac_ext_stream, hstream)
+
+void snd_hdac_ext_stream_init(struct hdac_ext_bus *bus,
+				struct hdac_ext_stream *stream, int idx,
+				int direction, int tag);
+int snd_hdac_ext_stream_init_all(struct hdac_ext_bus *ebus, int start_idx,
+		int num_stream, int dir);
+void snd_hdac_stream_free_all(struct hdac_ext_bus *ebus);
+void snd_hdac_link_free_all(struct hdac_ext_bus *ebus);
+struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_ext_bus *bus,
+					   struct snd_pcm_substream *substream,
+					   int type);
+void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
+void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *bus,
+				struct hdac_ext_stream *azx_dev, bool decouple);
+void snd_hdac_ext_stop_streams(struct hdac_ext_bus *sbus);
+
+int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
+				 struct hdac_ext_stream *stream, u32 value);
+int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
+				 struct hdac_ext_stream *stream);
+
+void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hstream);
+void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hstream);
+void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hstream);
+int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *stream, int fmt);
+
+struct hdac_ext_link {
+	struct hdac_bus *bus;
+	int index;
+	void __iomem *ml_addr; /* link output stream reg pointer */
+	u32 lcaps;   /* link capablities */
+	u16 lsdiid;  /* link sdi identifier */
+	struct list_head list;
+};
+
+int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *link);
+int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *link);
+int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus);
+void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link,
+				 int stream);
+void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
+				 int stream);
+
+/* update register macro */
+#define snd_hdac_updatel(addr, reg, mask, val)		\
+	writel(((readl(addr + reg) & ~(mask)) | (val)), \
+		addr + reg)
+
+#define snd_hdac_updatew(addr, reg, mask, val)		\
+	writew(((readw(addr + reg) & ~(mask)) | (val)), \
+		addr + reg)
+
+
+struct hdac_ext_device;
+
+/* ops common to all codec drivers */
+struct hdac_ext_codec_ops {
+	int (*build_controls)(struct hdac_ext_device *dev);
+	int (*init)(struct hdac_ext_device *dev);
+	void (*free)(struct hdac_ext_device *dev);
+};
+
+struct hda_dai_map {
+	char *dai_name;
+	hda_nid_t nid;
+	u32	maxbps;
+};
+
+#define HDA_MAX_NIDS 16
+
+/**
+ * struct hdac_ext_device - HDAC Ext device
+ *
+ * @hdac: hdac core device
+ * @nid_list - the dai map which matches the dai-name with the nid
+ * @map_cur_idx - the idx in use in dai_map
+ * @ops - the hda codec ops common to all codec drivers
+ * @pvt_data - private data, for asoc contains asoc codec object
+ */
+struct hdac_ext_device {
+	struct hdac_device hdac;
+	struct hdac_ext_bus *ebus;
+
+	/* soc-dai to nid map */
+	struct hda_dai_map nid_list[HDA_MAX_NIDS];
+	unsigned int map_cur_idx;
+
+	/* codec ops */
+	struct hdac_ext_codec_ops ops;
+
+	void *private_data;
+};
+
+#define to_ehdac_device(dev) (container_of((dev), \
+				 struct hdac_ext_device, hdac))
+/*
+ * HD-audio codec base driver
+ */
+struct hdac_ext_driver {
+	struct hdac_driver hdac;
+
+	int	(*probe)(struct hdac_ext_device *dev);
+	int	(*remove)(struct hdac_ext_device *dev);
+	void	(*shutdown)(struct hdac_ext_device *dev);
+};
+
+int snd_hda_ext_driver_register(struct hdac_ext_driver *drv);
+void snd_hda_ext_driver_unregister(struct hdac_ext_driver *drv);
+
+#define to_ehdac_driver(_drv) container_of(_drv, struct hdac_ext_driver, hdac)
+
+#endif /* __SOUND_HDAUDIO_EXT_H */
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
new file mode 100644
index 0000000..ab9fcb2
--- /dev/null
+++ b/include/sound/hwdep.h
@@ -0,0 +1,82 @@
+#ifndef __SOUND_HWDEP_H
+#define __SOUND_HWDEP_H
+
+/*
+ *  Hardware dependent layer 
+ *  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
+ *
+ */
+
+#include <sound/asound.h>
+#include <linux/poll.h>
+
+struct snd_hwdep;
+
+/* hwdep file ops; all ops can be NULL */
+struct snd_hwdep_ops {
+	long long (*llseek)(struct snd_hwdep *hw, struct file *file,
+			    long long offset, int orig);
+	long (*read)(struct snd_hwdep *hw, char __user *buf,
+		     long count, loff_t *offset);
+	long (*write)(struct snd_hwdep *hw, const char __user *buf,
+		      long count, loff_t *offset);
+	int (*open)(struct snd_hwdep *hw, struct file * file);
+	int (*release)(struct snd_hwdep *hw, struct file * file);
+	unsigned int (*poll)(struct snd_hwdep *hw, struct file *file,
+			     poll_table *wait);
+	int (*ioctl)(struct snd_hwdep *hw, struct file *file,
+		     unsigned int cmd, unsigned long arg);
+	int (*ioctl_compat)(struct snd_hwdep *hw, struct file *file,
+			    unsigned int cmd, unsigned long arg);
+	int (*mmap)(struct snd_hwdep *hw, struct file *file,
+		    struct vm_area_struct *vma);
+	int (*dsp_status)(struct snd_hwdep *hw,
+			  struct snd_hwdep_dsp_status *status);
+	int (*dsp_load)(struct snd_hwdep *hw,
+			struct snd_hwdep_dsp_image *image);
+};
+
+struct snd_hwdep {
+	struct snd_card *card;
+	struct list_head list;
+	int device;
+	char id[32];
+	char name[80];
+	int iface;
+
+#ifdef CONFIG_SND_OSSEMUL
+	int oss_type;
+	int ossreg;
+#endif
+
+	struct snd_hwdep_ops ops;
+	wait_queue_head_t open_wait;
+	void *private_data;
+	void (*private_free) (struct snd_hwdep *hwdep);
+	struct device dev;
+
+	struct mutex open_mutex;
+	int used;			/* reference counter */
+	unsigned int dsp_loaded;	/* bit fields of loaded dsp indices */
+	unsigned int exclusive:1;	/* exclusive access mode */
+};
+
+extern int snd_hwdep_new(struct snd_card *card, char *id, int device,
+			 struct snd_hwdep **rhwdep);
+
+#endif /* __SOUND_HWDEP_H */
diff --git a/include/sound/i2c.h b/include/sound/i2c.h
new file mode 100644
index 0000000..d125ff8
--- /dev/null
+++ b/include/sound/i2c.h
@@ -0,0 +1,104 @@
+#ifndef __SOUND_I2C_H
+#define __SOUND_I2C_H
+
+/*
+ *
+ *
+ *   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 SND_I2C_DEVICE_ADDRTEN	(1<<0)	/* 10-bit I2C address */
+
+struct snd_i2c_device {
+	struct list_head list;
+	struct snd_i2c_bus *bus;	/* I2C bus */
+	char name[32];		/* some useful device name */
+	unsigned short flags;	/* device flags */
+	unsigned short addr;	/* device address (might be 10-bit) */
+	unsigned long private_value;
+	void *private_data;
+	void (*private_free)(struct snd_i2c_device *device);
+};
+
+#define snd_i2c_device(n) list_entry(n, struct snd_i2c_device, list)
+
+struct snd_i2c_bit_ops {
+	void (*start)(struct snd_i2c_bus *bus);	/* transfer start */
+	void (*stop)(struct snd_i2c_bus *bus);	/* transfer stop */
+	void (*direction)(struct snd_i2c_bus *bus, int clock, int data);  /* set line direction (0 = write, 1 = read) */
+	void (*setlines)(struct snd_i2c_bus *bus, int clock, int data);
+	int (*getclock)(struct snd_i2c_bus *bus);
+	int (*getdata)(struct snd_i2c_bus *bus, int ack);
+};
+
+struct snd_i2c_ops {
+	int (*sendbytes)(struct snd_i2c_device *device, unsigned char *bytes, int count);
+	int (*readbytes)(struct snd_i2c_device *device, unsigned char *bytes, int count);
+	int (*probeaddr)(struct snd_i2c_bus *bus, unsigned short addr);
+};
+
+struct snd_i2c_bus {
+	struct snd_card *card;	/* card which I2C belongs to */
+	char name[32];		/* some useful label */
+
+	struct mutex lock_mutex;
+
+	struct snd_i2c_bus *master;	/* master bus when SCK/SCL is shared */
+	struct list_head buses;	/* master: slave buses sharing SCK/SCL, slave: link list */
+
+	struct list_head devices; /* attached devices to this bus */
+
+	union {
+		struct snd_i2c_bit_ops *bit;
+		void *ops;
+	} hw_ops;		/* lowlevel operations */
+	struct snd_i2c_ops *ops;	/* midlevel operations */
+
+	unsigned long private_value;
+	void *private_data;
+	void (*private_free)(struct snd_i2c_bus *bus);
+};
+
+#define snd_i2c_slave_bus(n) list_entry(n, struct snd_i2c_bus, buses)
+
+int snd_i2c_bus_create(struct snd_card *card, const char *name,
+		       struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c);
+int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
+			  unsigned char addr, struct snd_i2c_device **rdevice);
+int snd_i2c_device_free(struct snd_i2c_device *device);
+
+static inline void snd_i2c_lock(struct snd_i2c_bus *bus)
+{
+	if (bus->master)
+		mutex_lock(&bus->master->lock_mutex);
+	else
+		mutex_lock(&bus->lock_mutex);
+}
+
+static inline void snd_i2c_unlock(struct snd_i2c_bus *bus)
+{
+	if (bus->master)
+		mutex_unlock(&bus->master->lock_mutex);
+	else
+		mutex_unlock(&bus->lock_mutex);
+}
+
+int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count);
+int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count);
+int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr);
+
+#endif /* __SOUND_I2C_H */
diff --git a/include/sound/info.h b/include/sound/info.h
new file mode 100644
index 0000000..67390ee
--- /dev/null
+++ b/include/sound/info.h
@@ -0,0 +1,215 @@
+#ifndef __SOUND_INFO_H
+#define __SOUND_INFO_H
+
+/*
+ *  Header file for info interface
+ *  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
+ *
+ */
+
+#include <linux/poll.h>
+#include <linux/seq_file.h>
+#include <sound/core.h>
+
+/* buffer for information */
+struct snd_info_buffer {
+	char *buffer;		/* pointer to begin of buffer */
+	unsigned int curr;	/* current position in buffer */
+	unsigned int size;	/* current size */
+	unsigned int len;	/* total length of buffer */
+	int stop;		/* stop flag */
+	int error;		/* error code */
+};
+
+#define SNDRV_INFO_CONTENT_TEXT		0
+#define SNDRV_INFO_CONTENT_DATA		1
+
+struct snd_info_entry;
+
+struct snd_info_entry_text {
+	void (*read)(struct snd_info_entry *entry,
+		     struct snd_info_buffer *buffer);
+	void (*write)(struct snd_info_entry *entry,
+		      struct snd_info_buffer *buffer);
+};
+
+struct snd_info_entry_ops {
+	int (*open)(struct snd_info_entry *entry,
+		    unsigned short mode, void **file_private_data);
+	int (*release)(struct snd_info_entry *entry,
+		       unsigned short mode, void *file_private_data);
+	ssize_t (*read)(struct snd_info_entry *entry, void *file_private_data,
+			struct file *file, char __user *buf,
+			size_t count, loff_t pos);
+	ssize_t (*write)(struct snd_info_entry *entry, void *file_private_data,
+			 struct file *file, const char __user *buf,
+			 size_t count, loff_t pos);
+	loff_t (*llseek)(struct snd_info_entry *entry,
+			 void *file_private_data, struct file *file,
+			 loff_t offset, int orig);
+	unsigned int (*poll)(struct snd_info_entry *entry,
+			     void *file_private_data, struct file *file,
+			     poll_table *wait);
+	int (*ioctl)(struct snd_info_entry *entry, void *file_private_data,
+		     struct file *file, unsigned int cmd, unsigned long arg);
+	int (*mmap)(struct snd_info_entry *entry, void *file_private_data,
+		    struct inode *inode, struct file *file,
+		    struct vm_area_struct *vma);
+};
+
+struct snd_info_entry {
+	const char *name;
+	umode_t mode;
+	long size;
+	unsigned short content;
+	union {
+		struct snd_info_entry_text text;
+		struct snd_info_entry_ops *ops;
+	} c;
+	struct snd_info_entry *parent;
+	struct snd_card *card;
+	struct module *module;
+	void *private_data;
+	void (*private_free)(struct snd_info_entry *entry);
+	struct proc_dir_entry *p;
+	struct mutex access;
+	struct list_head children;
+	struct list_head list;
+};
+
+#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_SND_PROC_FS)
+int snd_info_minor_register(void);
+#else
+#define snd_info_minor_register()	0
+#endif
+
+
+#ifdef CONFIG_SND_PROC_FS
+
+extern struct snd_info_entry *snd_seq_root;
+#ifdef CONFIG_SND_OSSEMUL
+extern struct snd_info_entry *snd_oss_root;
+void snd_card_info_read_oss(struct snd_info_buffer *buffer);
+#else
+#define snd_oss_root NULL
+static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {}
+#endif
+
+/**
+ * snd_iprintf - printf on the procfs buffer
+ * @buf: the procfs buffer
+ * @fmt: the printf format
+ *
+ * Outputs the string on the procfs buffer just like printf().
+ *
+ * Return: zero for success, or a negative error code.
+ */
+#define snd_iprintf(buf, fmt, args...) \
+	seq_printf((struct seq_file *)(buf)->buffer, fmt, ##args)
+
+int snd_info_init(void);
+int snd_info_done(void);
+
+int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len);
+const char *snd_info_get_str(char *dest, const char *src, int len);
+struct snd_info_entry *snd_info_create_module_entry(struct module *module,
+					       const char *name,
+					       struct snd_info_entry *parent);
+struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
+					     const char *name,
+					     struct snd_info_entry *parent);
+void snd_info_free_entry(struct snd_info_entry *entry);
+int snd_info_store_text(struct snd_info_entry *entry);
+int snd_info_restore_text(struct snd_info_entry *entry);
+
+int snd_info_card_create(struct snd_card *card);
+int snd_info_card_register(struct snd_card *card);
+int snd_info_card_free(struct snd_card *card);
+void snd_info_card_disconnect(struct snd_card *card);
+void snd_info_card_id_change(struct snd_card *card);
+int snd_info_register(struct snd_info_entry *entry);
+
+/* for card drivers */
+static inline int snd_card_proc_new(struct snd_card *card, const char *name,
+				    struct snd_info_entry **entryp)
+{
+	*entryp = snd_info_create_card_entry(card, name, card->proc_root);
+	return *entryp ? 0 : -ENOMEM;
+}
+
+static inline void snd_info_set_text_ops(struct snd_info_entry *entry, 
+	void *private_data,
+	void (*read)(struct snd_info_entry *, struct snd_info_buffer *))
+{
+	entry->private_data = private_data;
+	entry->c.text.read = read;
+}
+
+int snd_info_check_reserved_words(const char *str);
+
+#else
+
+#define snd_seq_root NULL
+#define snd_oss_root NULL
+
+static inline int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) { return 0; }
+static inline int snd_info_init(void) { return 0; }
+static inline int snd_info_done(void) { return 0; }
+
+static inline int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) { return 0; }
+static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; }
+static inline struct snd_info_entry *snd_info_create_module_entry(struct module *module, const char *name, struct snd_info_entry *parent) { return NULL; }
+static inline struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, const char *name, struct snd_info_entry *parent) { return NULL; }
+static inline void snd_info_free_entry(struct snd_info_entry *entry) { ; }
+
+static inline int snd_info_card_create(struct snd_card *card) { return 0; }
+static inline int snd_info_card_register(struct snd_card *card) { return 0; }
+static inline int snd_info_card_free(struct snd_card *card) { return 0; }
+static inline void snd_info_card_disconnect(struct snd_card *card) { }
+static inline void snd_info_card_id_change(struct snd_card *card) { }
+static inline int snd_info_register(struct snd_info_entry *entry) { return 0; }
+
+static inline int snd_card_proc_new(struct snd_card *card, const char *name,
+				    struct snd_info_entry **entryp) { return -EINVAL; }
+static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)),
+					 void *private_data,
+					 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {}
+static inline int snd_info_check_reserved_words(const char *str) { return 1; }
+
+#endif
+
+/*
+ * OSS info part
+ */
+
+#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_SND_PROC_FS)
+
+#define SNDRV_OSS_INFO_DEV_AUDIO	0
+#define SNDRV_OSS_INFO_DEV_SYNTH	1
+#define SNDRV_OSS_INFO_DEV_MIDI		2
+#define SNDRV_OSS_INFO_DEV_TIMERS	4
+#define SNDRV_OSS_INFO_DEV_MIXERS	5
+
+#define SNDRV_OSS_INFO_DEV_COUNT	6
+
+int snd_oss_info_register(int dev, int num, char *string);
+#define snd_oss_info_unregister(dev, num) snd_oss_info_register(dev, num, NULL)
+
+#endif /* CONFIG_SND_OSSEMUL && CONFIG_SND_PROC_FS */
+
+#endif /* __SOUND_INFO_H */
diff --git a/include/sound/initval.h b/include/sound/initval.h
new file mode 100644
index 0000000..ac62c67
--- /dev/null
+++ b/include/sound/initval.h
@@ -0,0 +1,104 @@
+#ifndef __SOUND_INITVAL_H
+#define __SOUND_INITVAL_H
+
+/*
+ *  Init values for soundcard modules
+ *  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 SNDRV_AUTO_PORT		1
+#define SNDRV_AUTO_IRQ		0xffff
+#define SNDRV_AUTO_DMA		0xffff
+#define SNDRV_AUTO_DMA_SIZE	(0x7fffffff)
+
+#define SNDRV_DEFAULT_IDX1	(-1)
+#define SNDRV_DEFAULT_STR1	NULL
+#define SNDRV_DEFAULT_ENABLE1	1
+#define SNDRV_DEFAULT_PORT1	SNDRV_AUTO_PORT
+#define SNDRV_DEFAULT_IRQ1	SNDRV_AUTO_IRQ
+#define SNDRV_DEFAULT_DMA1	SNDRV_AUTO_DMA
+#define SNDRV_DEFAULT_DMA_SIZE1	SNDRV_AUTO_DMA_SIZE
+#define SNDRV_DEFAULT_PTR1	SNDRV_DEFAULT_STR1
+
+#define SNDRV_DEFAULT_IDX	{ [0 ... (SNDRV_CARDS-1)] = -1 }
+#define SNDRV_DEFAULT_STR	{ [0 ... (SNDRV_CARDS-1)] = NULL }
+#define SNDRV_DEFAULT_ENABLE	{ 1, [1 ... (SNDRV_CARDS-1)] = 0 }
+#define SNDRV_DEFAULT_ENABLE_PNP { [0 ... (SNDRV_CARDS-1)] = 1 }
+#ifdef CONFIG_PNP
+#define SNDRV_DEFAULT_ENABLE_ISAPNP SNDRV_DEFAULT_ENABLE_PNP
+#else
+#define SNDRV_DEFAULT_ENABLE_ISAPNP SNDRV_DEFAULT_ENABLE
+#endif
+#define SNDRV_DEFAULT_PORT	{ [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_PORT }
+#define SNDRV_DEFAULT_IRQ	{ [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_IRQ }
+#define SNDRV_DEFAULT_DMA	{ [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_DMA }
+#define SNDRV_DEFAULT_DMA_SIZE	{ [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_DMA_SIZE }
+#define SNDRV_DEFAULT_PTR	SNDRV_DEFAULT_STR
+
+#ifdef SNDRV_LEGACY_FIND_FREE_IOPORT
+static long snd_legacy_find_free_ioport(long *port_table, long size)
+{
+	while (*port_table != -1) {
+		if (request_region(*port_table, size, "ALSA test")) {
+			release_region(*port_table, size);
+			return *port_table;
+		}
+		port_table++;
+	}
+	return -1;
+}
+#endif
+
+#ifdef SNDRV_LEGACY_FIND_FREE_IRQ
+#include <linux/interrupt.h>
+
+static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
+static int snd_legacy_find_free_irq(int *irq_table)
+{
+	while (*irq_table != -1) {
+		if (!request_irq(*irq_table, snd_legacy_empty_irq_handler,
+				 IRQF_PROBE_SHARED, "ALSA Test IRQ",
+				 (void *) irq_table)) {
+			free_irq(*irq_table, (void *) irq_table);
+			return *irq_table;
+		}
+		irq_table++;
+	}
+	return -1;
+}
+#endif
+
+#ifdef SNDRV_LEGACY_FIND_FREE_DMA
+static int snd_legacy_find_free_dma(int *dma_table)
+{
+	while (*dma_table != -1) {
+		if (!request_dma(*dma_table, "ALSA Test DMA")) {
+			free_dma(*dma_table);
+			return *dma_table;
+		}
+		dma_table++;
+	}
+	return -1;
+}
+#endif
+
+#endif /* __SOUND_INITVAL_H */
diff --git a/include/sound/jack.h b/include/sound/jack.h
new file mode 100644
index 0000000..23bede1
--- /dev/null
+++ b/include/sound/jack.h
@@ -0,0 +1,128 @@
+#ifndef __SOUND_JACK_H
+#define __SOUND_JACK_H
+
+/*
+ *  Jack abstraction layer
+ *
+ *  Copyright 2008 Wolfson Microelectronics plc
+ *
+ *
+ *   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 <sound/core.h>
+
+struct input_dev;
+
+/**
+ * enum snd_jack_types - Jack types which can be reported
+ * @SND_JACK_HEADPHONE: Headphone
+ * @SND_JACK_MICROPHONE: Microphone
+ * @SND_JACK_HEADSET: Headset
+ * @SND_JACK_LINEOUT: Line out
+ * @SND_JACK_MECHANICAL: Mechanical switch
+ * @SND_JACK_VIDEOOUT: Video out
+ * @SND_JACK_AVOUT: AV (Audio Video) out
+ * @SND_JACK_LINEIN:  Line in
+ * @SND_JACK_BTN_0: Button 0
+ * @SND_JACK_BTN_1: Button 1
+ * @SND_JACK_BTN_2: Button 2
+ * @SND_JACK_BTN_3: Button 3
+ * @SND_JACK_BTN_4: Button 4
+ * @SND_JACK_BTN_5: Button 5
+ *
+ * These values are used as a bitmask.
+ *
+ * Note that this must be kept in sync with the lookup table in
+ * sound/core/jack.c.
+ */
+enum snd_jack_types {
+	SND_JACK_HEADPHONE	= 0x0001,
+	SND_JACK_MICROPHONE	= 0x0002,
+	SND_JACK_HEADSET	= SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
+	SND_JACK_LINEOUT	= 0x0004,
+	SND_JACK_MECHANICAL	= 0x0008, /* If detected separately */
+	SND_JACK_VIDEOOUT	= 0x0010,
+	SND_JACK_AVOUT		= SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
+	SND_JACK_LINEIN		= 0x0020,
+
+	/* Kept separate from switches to facilitate implementation */
+	SND_JACK_BTN_0		= 0x4000,
+	SND_JACK_BTN_1		= 0x2000,
+	SND_JACK_BTN_2		= 0x1000,
+	SND_JACK_BTN_3		= 0x0800,
+	SND_JACK_BTN_4		= 0x0400,
+	SND_JACK_BTN_5		= 0x0200,
+};
+
+/* Keep in sync with definitions above */
+#define SND_JACK_SWITCH_TYPES 6
+
+struct snd_jack {
+	struct input_dev *input_dev;
+	struct list_head kctl_list;
+	struct snd_card *card;
+	int registered;
+	int type;
+	const char *id;
+	char name[100];
+	unsigned int key[6];   /* Keep in sync with definitions above */
+	void *private_data;
+	void (*private_free)(struct snd_jack *);
+};
+
+#ifdef CONFIG_SND_JACK
+
+int snd_jack_new(struct snd_card *card, const char *id, int type,
+		 struct snd_jack **jack, bool initial_kctl, bool phantom_jack);
+int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask);
+void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
+int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
+		     int keytype);
+
+void snd_jack_report(struct snd_jack *jack, int status);
+
+#else
+static inline int snd_jack_new(struct snd_card *card, const char *id, int type,
+			       struct snd_jack **jack, bool initial_kctl, bool phantom_jack)
+{
+	return 0;
+}
+
+static inline int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask)
+{
+	return 0;
+}
+
+static inline void snd_jack_set_parent(struct snd_jack *jack,
+				       struct device *parent)
+{
+}
+
+static inline int snd_jack_set_key(struct snd_jack *jack,
+				   enum snd_jack_types type,
+				   int keytype)
+{
+	return 0;
+}
+
+static inline void snd_jack_report(struct snd_jack *jack, int status)
+{
+}
+
+#endif
+
+#endif
diff --git a/include/sound/l3.h b/include/sound/l3.h
new file mode 100644
index 0000000..423a08f
--- /dev/null
+++ b/include/sound/l3.h
@@ -0,0 +1,18 @@
+#ifndef _L3_H_
+#define _L3_H_ 1
+
+struct l3_pins {
+	void (*setdat)(int);
+	void (*setclk)(int);
+	void (*setmode)(int);
+	int data_hold;
+	int data_setup;
+	int clock_high;
+	int mode_hold;
+	int mode;
+	int mode_setup;
+};
+
+int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
+
+#endif
diff --git a/include/sound/max9768.h b/include/sound/max9768.h
new file mode 100644
index 0000000..0f78b41
--- /dev/null
+++ b/include/sound/max9768.h
@@ -0,0 +1,24 @@
+/*
+ * Platform data for MAX9768
+ * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
+ * same licence as the driver
+ */
+
+#ifndef __SOUND_MAX9768_PDATA_H__
+#define __SOUND_MAX9768_PDATA_H__
+
+/**
+ * struct max9768_pdata - optional platform specific MAX9768 configuration
+ * @shdn_gpio:	GPIO to SHDN pin. If not valid, pin must be hardwired HIGH
+ * @mute_gpio:	GPIO to MUTE pin. If not valid, control for mute won't be added
+ * @flags: configuration flags, e.g. set classic PWM mode (check datasheet
+ *         regarding "filterless modulation" which is default).
+ */
+struct max9768_pdata {
+	int shdn_gpio;
+	int mute_gpio;
+	unsigned flags;
+#define MAX9768_FLAG_CLASSIC_PWM	(1 << 0)
+};
+
+#endif /* __SOUND_MAX9768_PDATA_H__*/
diff --git a/include/sound/max98088.h b/include/sound/max98088.h
new file mode 100644
index 0000000..c3ba823
--- /dev/null
+++ b/include/sound/max98088.h
@@ -0,0 +1,50 @@
+/*
+ * Platform data for MAX98088
+ *
+ * Copyright 2010 Maxim Integrated Products
+ *
+ *  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.
+ *
+ */
+
+#ifndef __SOUND_MAX98088_PDATA_H__
+#define __SOUND_MAX98088_PDATA_H__
+
+/* Equalizer filter response configuration */
+struct max98088_eq_cfg {
+       const char *name;
+       unsigned int rate;
+       u16 band1[5];
+       u16 band2[5];
+       u16 band3[5];
+       u16 band4[5];
+       u16 band5[5];
+};
+
+/* codec platform data */
+struct max98088_pdata {
+
+       /* Equalizers for DAI1 and DAI2 */
+       struct max98088_eq_cfg *eq_cfg;
+       unsigned int eq_cfgcnt;
+
+       /* Receiver output can be configured as power amplifier or LINE out */
+       /* Set receiver_mode to:
+        * 0 = amplifier output, or
+        * 1 = LINE level output
+        */
+       unsigned int receiver_mode:1;
+
+       /* Analog/digital microphone configuration:
+        * 0 = analog microphone input (normal setting)
+        * 1 = digital microphone input
+        */
+       unsigned int digmic_left_mode:1;
+       unsigned int digmic_right_mode:1;
+
+};
+
+#endif
diff --git a/include/sound/max98090.h b/include/sound/max98090.h
new file mode 100644
index 0000000..95efb13
--- /dev/null
+++ b/include/sound/max98090.h
@@ -0,0 +1,29 @@
+/*
+ * Platform data for MAX98090
+ *
+ * Copyright 2011-2012 Maxim Integrated Products
+ *
+ *  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.
+ *
+ */
+
+#ifndef __SOUND_MAX98090_PDATA_H__
+#define __SOUND_MAX98090_PDATA_H__
+
+/* codec platform data */
+struct max98090_pdata {
+
+	/* Analog/digital microphone configuration:
+	 * 0 = analog microphone input (normal setting)
+	 * 1 = digital microphone input
+	 */
+	unsigned int digmic_left_mode:1;
+	unsigned int digmic_right_mode:1;
+	unsigned int digmic_3_mode:1;
+	unsigned int digmic_4_mode:1;
+};
+
+#endif
diff --git a/include/sound/max98095.h b/include/sound/max98095.h
new file mode 100644
index 0000000..e87ae67
--- /dev/null
+++ b/include/sound/max98095.h
@@ -0,0 +1,66 @@
+/*
+ * Platform data for MAX98095
+ *
+ * Copyright 2011 Maxim Integrated Products
+ *
+ *  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.
+ *
+ */
+
+#ifndef __SOUND_MAX98095_PDATA_H__
+#define __SOUND_MAX98095_PDATA_H__
+
+/* Equalizer filter response configuration */
+struct max98095_eq_cfg {
+	const char *name;
+	unsigned int rate;
+	u16 band1[5];
+	u16 band2[5];
+	u16 band3[5];
+	u16 band4[5];
+	u16 band5[5];
+};
+
+/* Biquad filter response configuration */
+struct max98095_biquad_cfg {
+	const char *name;
+	unsigned int rate;
+	u16 band1[5];
+	u16 band2[5];
+};
+
+/* codec platform data */
+struct max98095_pdata {
+
+	/* Equalizers for DAI1 and DAI2 */
+	struct max98095_eq_cfg *eq_cfg;
+	unsigned int eq_cfgcnt;
+
+	/* Biquad filter for DAI1 and DAI2 */
+	struct max98095_biquad_cfg *bq_cfg;
+	unsigned int bq_cfgcnt;
+
+	/* Analog/digital microphone configuration:
+	 * 0 = analog microphone input (normal setting)
+	 * 1 = digital microphone input
+	 */
+	unsigned int digmic_left_mode:1;
+	unsigned int digmic_right_mode:1;
+
+	/* Pin5 is the mechanical method of sensing jack insertion
+	 * but it is something that might not be supported.
+	 * 0 = PIN5 not supported
+	 * 1 = PIN5 supported
+	 */
+	unsigned int jack_detect_pin5en:1;
+
+	/* Slew amount for jack detection. Calculated as 4 * (delay + 1).
+	 * Default delay is 24 to get a time of 100ms.
+	 */
+	unsigned int jack_detect_delay;
+};
+
+#endif
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
new file mode 100644
index 0000000..782d1df
--- /dev/null
+++ b/include/sound/memalloc.h
@@ -0,0 +1,157 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *                   Takashi Iwai <tiwai@suse.de>
+ * 
+ *  Generic memory allocators
+ *
+ *
+ *   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
+ *
+ */
+
+#ifndef __SOUND_MEMALLOC_H
+#define __SOUND_MEMALLOC_H
+
+struct device;
+
+/*
+ * buffer device info
+ */
+struct snd_dma_device {
+	int type;			/* SNDRV_DMA_TYPE_XXX */
+	struct device *dev;		/* generic device */
+};
+
+#ifndef snd_dma_pci_data
+#define snd_dma_pci_data(pci)	(&(pci)->dev)
+#define snd_dma_isa_data()	NULL
+#define snd_dma_continuous_data(x)	((struct device *)(__force unsigned long)(x))
+#endif
+
+
+/*
+ * buffer types
+ */
+#define SNDRV_DMA_TYPE_UNKNOWN		0	/* not defined */
+#define SNDRV_DMA_TYPE_CONTINUOUS	1	/* continuous no-DMA memory */
+#define SNDRV_DMA_TYPE_DEV		2	/* generic device continuous */
+#ifdef CONFIG_SND_DMA_SGBUF
+#define SNDRV_DMA_TYPE_DEV_SG		3	/* generic device SG-buffer */
+#else
+#define SNDRV_DMA_TYPE_DEV_SG	SNDRV_DMA_TYPE_DEV /* no SG-buf support */
+#endif
+#ifdef CONFIG_GENERIC_ALLOCATOR
+#define SNDRV_DMA_TYPE_DEV_IRAM		4	/* generic device iram-buffer */
+#else
+#define SNDRV_DMA_TYPE_DEV_IRAM	SNDRV_DMA_TYPE_DEV
+#endif
+
+/*
+ * info for buffer allocation
+ */
+struct snd_dma_buffer {
+	struct snd_dma_device dev;	/* device type */
+	unsigned char *area;	/* virtual pointer */
+	dma_addr_t addr;	/* physical address */
+	size_t bytes;		/* buffer size in bytes */
+	void *private_data;	/* private for allocator; don't touch */
+};
+
+#ifdef CONFIG_SND_DMA_SGBUF
+/*
+ * Scatter-Gather generic device pages
+ */
+void *snd_malloc_sgbuf_pages(struct device *device,
+			     size_t size, struct snd_dma_buffer *dmab,
+			     size_t *res_size);
+int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
+
+struct snd_sg_page {
+	void *buf;
+	dma_addr_t addr;
+};
+
+struct snd_sg_buf {
+	int size;	/* allocated byte size */
+	int pages;	/* allocated pages */
+	int tblsize;	/* allocated table size */
+	struct snd_sg_page *table;	/* address table */
+	struct page **page_table;	/* page table (for vmap/vunmap) */
+	struct device *dev;
+};
+
+/*
+ * return the pages matching with the given byte size
+ */
+static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
+{
+	return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+}
+
+/*
+ * return the physical address at the corresponding offset
+ */
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
+					   size_t offset)
+{
+	struct snd_sg_buf *sgbuf = dmab->private_data;
+	dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
+	addr &= ~((dma_addr_t)PAGE_SIZE - 1);
+	return addr + offset % PAGE_SIZE;
+}
+
+/*
+ * return the virtual address at the corresponding offset
+ */
+static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
+				     size_t offset)
+{
+	struct snd_sg_buf *sgbuf = dmab->private_data;
+	return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
+}
+
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+				      unsigned int ofs, unsigned int size);
+#else
+/* non-SG versions */
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
+					    size_t offset)
+{
+	return dmab->addr + offset;
+}
+
+static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
+				      size_t offset)
+{
+	return dmab->area + offset;
+}
+
+#define snd_sgbuf_get_chunk_size(dmab, ofs, size)	(size)
+
+#endif /* CONFIG_SND_DMA_SGBUF */
+
+/* allocate/release a buffer */
+int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
+			struct snd_dma_buffer *dmab);
+int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size,
+                                 struct snd_dma_buffer *dmab);
+void snd_dma_free_pages(struct snd_dma_buffer *dmab);
+
+/* basic memory allocation functions */
+void *snd_malloc_pages(size_t size, gfp_t gfp_flags);
+void snd_free_pages(void *ptr, size_t size);
+
+#endif /* __SOUND_MEMALLOC_H */
+
diff --git a/include/sound/minors.h b/include/sound/minors.h
new file mode 100644
index 0000000..5978f9a
--- /dev/null
+++ b/include/sound/minors.h
@@ -0,0 +1,112 @@
+#ifndef __SOUND_MINORS_H
+#define __SOUND_MINORS_H
+
+/*
+ *  MINOR numbers
+ *
+ *
+ *   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 SNDRV_OS_MINORS			256
+
+#define SNDRV_MINOR_DEVICES		32
+#define SNDRV_MINOR_CARD(minor)		((minor) >> 5)
+#define SNDRV_MINOR_DEVICE(minor)	((minor) & 0x001f)
+#define SNDRV_MINOR(card, dev)		(((card) << 5) | (dev))
+
+/* these minors can still be used for autoloading devices (/dev/aload*) */
+#define SNDRV_MINOR_CONTROL		0	/* 0 */
+#define SNDRV_MINOR_GLOBAL		1	/* 1 */
+#define SNDRV_MINOR_SEQUENCER		1	/* SNDRV_MINOR_GLOBAL + 0 * 32 */
+#define SNDRV_MINOR_TIMER		33	/* SNDRV_MINOR_GLOBAL + 1 * 32 */
+
+#ifndef CONFIG_SND_DYNAMIC_MINORS
+#define SNDRV_MINOR_COMPRESS		2	/* 2 - 3 */
+#define SNDRV_MINOR_HWDEP		4	/* 4 - 7 */
+#define SNDRV_MINOR_RAWMIDI		8	/* 8 - 15 */
+#define SNDRV_MINOR_PCM_PLAYBACK	16	/* 16 - 23 */
+#define SNDRV_MINOR_PCM_CAPTURE		24	/* 24 - 31 */
+
+/* same as first respective minor number to make minor allocation easier */
+#define SNDRV_DEVICE_TYPE_CONTROL	SNDRV_MINOR_CONTROL
+#define SNDRV_DEVICE_TYPE_HWDEP		SNDRV_MINOR_HWDEP
+#define SNDRV_DEVICE_TYPE_RAWMIDI	SNDRV_MINOR_RAWMIDI
+#define SNDRV_DEVICE_TYPE_PCM_PLAYBACK	SNDRV_MINOR_PCM_PLAYBACK
+#define SNDRV_DEVICE_TYPE_PCM_CAPTURE	SNDRV_MINOR_PCM_CAPTURE
+#define SNDRV_DEVICE_TYPE_SEQUENCER	SNDRV_MINOR_SEQUENCER
+#define SNDRV_DEVICE_TYPE_TIMER		SNDRV_MINOR_TIMER
+#define SNDRV_DEVICE_TYPE_COMPRESS	SNDRV_MINOR_COMPRESS
+
+#else /* CONFIG_SND_DYNAMIC_MINORS */
+
+enum {
+	SNDRV_DEVICE_TYPE_CONTROL,
+	SNDRV_DEVICE_TYPE_SEQUENCER,
+	SNDRV_DEVICE_TYPE_TIMER,
+	SNDRV_DEVICE_TYPE_HWDEP,
+	SNDRV_DEVICE_TYPE_RAWMIDI,
+	SNDRV_DEVICE_TYPE_PCM_PLAYBACK,
+	SNDRV_DEVICE_TYPE_PCM_CAPTURE,
+	SNDRV_DEVICE_TYPE_COMPRESS,
+};
+
+#endif /* CONFIG_SND_DYNAMIC_MINORS */
+
+#define SNDRV_MINOR_HWDEPS		4
+#define SNDRV_MINOR_RAWMIDIS		8
+#define SNDRV_MINOR_PCMS		8
+
+
+#ifdef CONFIG_SND_OSSEMUL
+
+#define SNDRV_MINOR_OSS_DEVICES		16
+#define SNDRV_MINOR_OSS_CARD(minor)	((minor) >> 4)
+#define SNDRV_MINOR_OSS_DEVICE(minor)	((minor) & 0x000f)
+#define SNDRV_MINOR_OSS(card, dev)	(((card) << 4) | (dev))
+
+#define SNDRV_MINOR_OSS_MIXER		0	/* /dev/mixer - OSS 3.XX compatible */
+#define SNDRV_MINOR_OSS_SEQUENCER	1	/* /dev/sequencer - OSS 3.XX compatible */
+#define	SNDRV_MINOR_OSS_MIDI		2	/* /dev/midi - native midi interface - OSS 3.XX compatible - UART */
+#define SNDRV_MINOR_OSS_PCM		3	/* alias */
+#define SNDRV_MINOR_OSS_PCM_8		3	/* /dev/dsp - 8bit PCM - OSS 3.XX compatible */
+#define SNDRV_MINOR_OSS_AUDIO		4	/* /dev/audio - SunSparc compatible */
+#define SNDRV_MINOR_OSS_PCM_16		5	/* /dev/dsp16 - 16bit PCM - OSS 3.XX compatible */
+#define SNDRV_MINOR_OSS_SNDSTAT		6	/* /dev/sndstat - for compatibility with OSS */
+#define SNDRV_MINOR_OSS_RESERVED7	7	/* reserved for future use */
+#define SNDRV_MINOR_OSS_MUSIC		8	/* /dev/music - OSS 3.XX compatible */
+#define SNDRV_MINOR_OSS_DMMIDI		9	/* /dev/dmmidi0 - this device can have another minor # with OSS */
+#define SNDRV_MINOR_OSS_DMFM		10	/* /dev/dmfm0 - this device can have another minor # with OSS */
+#define SNDRV_MINOR_OSS_MIXER1		11	/* alternate mixer */
+#define SNDRV_MINOR_OSS_PCM1		12	/* alternate PCM (GF-A-1) */
+#define SNDRV_MINOR_OSS_MIDI1		13	/* alternate midi - SYNTH */
+#define SNDRV_MINOR_OSS_DMMIDI1		14	/* alternate dmmidi - SYNTH */
+#define SNDRV_MINOR_OSS_RESERVED15	15	/* reserved for future use */
+
+#define SNDRV_OSS_DEVICE_TYPE_MIXER	0
+#define SNDRV_OSS_DEVICE_TYPE_SEQUENCER	1
+#define SNDRV_OSS_DEVICE_TYPE_PCM	2
+#define SNDRV_OSS_DEVICE_TYPE_MIDI	3
+#define SNDRV_OSS_DEVICE_TYPE_DMFM	4
+#define SNDRV_OSS_DEVICE_TYPE_SNDSTAT	5
+#define SNDRV_OSS_DEVICE_TYPE_MUSIC	6
+
+#define MODULE_ALIAS_SNDRV_MINOR(type) \
+	MODULE_ALIAS("sound-service-?-" __stringify(type))
+
+#endif
+
+#endif /* __SOUND_MINORS_H */
diff --git a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h
new file mode 100644
index 0000000..13cb0b4
--- /dev/null
+++ b/include/sound/mixer_oss.h
@@ -0,0 +1,81 @@
+#ifndef __SOUND_MIXER_OSS_H
+#define __SOUND_MIXER_OSS_H
+
+/*
+ *  OSS MIXER API
+ *  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
+ *
+ */
+
+#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+
+#define SNDRV_OSS_MAX_MIXERS	32
+
+struct snd_mixer_oss_file;
+
+struct snd_mixer_oss_slot {
+	int number;
+	unsigned int stereo: 1;
+	int (*get_volume)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int *left, int *right);
+	int (*put_volume)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int left, int right);
+	int (*get_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int *active);
+	int (*put_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int active);
+	unsigned long private_value;
+	void *private_data;
+	void (*private_free)(struct snd_mixer_oss_slot *slot);
+	int volume[2];
+};
+
+struct snd_mixer_oss {
+	struct snd_card *card;
+	char id[16];
+	char name[32];
+	struct snd_mixer_oss_slot slots[SNDRV_OSS_MAX_MIXERS]; /* OSS mixer slots */
+	unsigned int mask_recsrc;		/* exclusive recsrc mask */
+	int (*get_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  unsigned int *active_index);
+	int (*put_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  unsigned int active_index);
+	void *private_data_recsrc;
+	void (*private_free_recsrc)(struct snd_mixer_oss *mixer);
+	struct mutex reg_mutex;
+	struct snd_info_entry *proc_entry;
+	int oss_dev_alloc;
+	/* --- */
+	int oss_recsrc;
+};
+
+struct snd_mixer_oss_file {
+	struct snd_card *card;
+	struct snd_mixer_oss *mixer;
+};
+
+int snd_mixer_oss_ioctl_card(struct snd_card *card,
+			     unsigned int cmd, unsigned long arg);
+
+#endif /* CONFIG_SND_MIXER_OSS */
+
+#endif /* __SOUND_MIXER_OSS_H */
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
new file mode 100644
index 0000000..e942096
--- /dev/null
+++ b/include/sound/mpu401.h
@@ -0,0 +1,138 @@
+#ifndef __SOUND_MPU401_H
+#define __SOUND_MPU401_H
+
+/*
+ *  Header file for MPU-401 and compatible cards
+ *  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
+ *
+ */
+
+#include <sound/rawmidi.h>
+#include <linux/interrupt.h>
+
+#define MPU401_HW_MPU401		1	/* native MPU401 */
+#define MPU401_HW_SB			2	/* SoundBlaster MPU-401 UART */
+#define MPU401_HW_ES1688		3	/* AudioDrive ES1688 MPU-401 UART */
+#define MPU401_HW_OPL3SA2		4	/* Yamaha OPL3-SA2 */
+#define MPU401_HW_SONICVIBES		5	/* S3 SonicVibes */
+#define MPU401_HW_CS4232		6	/* CS4232 */
+#define MPU401_HW_ES18XX		7	/* AudioDrive ES18XX MPU-401 UART */
+#define MPU401_HW_FM801			8	/* ForteMedia FM801 */
+#define MPU401_HW_TRID4DWAVE		9	/* Trident 4DWave */
+#define MPU401_HW_AZT2320		10	/* Aztech AZT2320 */
+#define MPU401_HW_ALS100		11	/* Avance Logic ALS100 */
+#define MPU401_HW_ICE1712		12	/* Envy24 */
+#define MPU401_HW_VIA686A		13	/* VIA 82C686A */
+#define MPU401_HW_YMFPCI		14	/* YMF DS-XG PCI */
+#define MPU401_HW_CMIPCI		15	/* CMIPCI MPU-401 UART */
+#define MPU401_HW_ALS4000		16	/* Avance Logic ALS4000 */
+#define MPU401_HW_INTEL8X0		17	/* Intel8x0 driver */
+#define MPU401_HW_PC98II		18	/* Roland PC98II */
+#define MPU401_HW_AUREAL		19	/* Aureal Vortex */
+
+#define MPU401_INFO_INPUT	(1 << 0)	/* input stream */
+#define MPU401_INFO_OUTPUT	(1 << 1)	/* output stream */
+#define MPU401_INFO_INTEGRATED	(1 << 2)	/* integrated h/w port */
+#define MPU401_INFO_MMIO	(1 << 3)	/* MMIO access */
+#define MPU401_INFO_TX_IRQ	(1 << 4)	/* independent TX irq */
+#define MPU401_INFO_IRQ_HOOK	(1 << 5)	/* mpu401 irq handler is called
+						   from driver irq handler */
+#define MPU401_INFO_NO_ACK	(1 << 6)	/* No ACK cmd needed */
+#define MPU401_INFO_USE_TIMER	(1 << 15)	/* internal */
+
+#define MPU401_MODE_BIT_INPUT		0
+#define MPU401_MODE_BIT_OUTPUT		1
+#define MPU401_MODE_BIT_INPUT_TRIGGER	2
+#define MPU401_MODE_BIT_OUTPUT_TRIGGER	3
+
+#define MPU401_MODE_INPUT		(1<<MPU401_MODE_BIT_INPUT)
+#define MPU401_MODE_OUTPUT		(1<<MPU401_MODE_BIT_OUTPUT)
+#define MPU401_MODE_INPUT_TRIGGER	(1<<MPU401_MODE_BIT_INPUT_TRIGGER)
+#define MPU401_MODE_OUTPUT_TRIGGER	(1<<MPU401_MODE_BIT_OUTPUT_TRIGGER)
+
+#define MPU401_MODE_INPUT_TIMER		(1<<0)
+#define MPU401_MODE_OUTPUT_TIMER	(1<<1)
+
+struct snd_mpu401 {
+	struct snd_rawmidi *rmidi;
+
+	unsigned short hardware;	/* MPU401_HW_XXXX */
+	unsigned int info_flags;	/* MPU401_INFO_XXX */
+	unsigned long port;		/* base port of MPU-401 chip */
+	unsigned long cport;		/* port + 1 (usually) */
+	struct resource *res;		/* port resource */
+	int irq;			/* IRQ number of MPU-401 chip */
+
+	unsigned long mode;		/* MPU401_MODE_XXXX */
+	int timer_invoked;
+
+	int (*open_input) (struct snd_mpu401 * mpu);
+	void (*close_input) (struct snd_mpu401 * mpu);
+	int (*open_output) (struct snd_mpu401 * mpu);
+	void (*close_output) (struct snd_mpu401 * mpu);
+	void *private_data;
+
+	struct snd_rawmidi_substream *substream_input;
+	struct snd_rawmidi_substream *substream_output;
+
+	spinlock_t input_lock;
+	spinlock_t output_lock;
+	spinlock_t timer_lock;
+	
+	struct timer_list timer;
+
+	void (*write) (struct snd_mpu401 * mpu, unsigned char data, unsigned long addr);
+	unsigned char (*read) (struct snd_mpu401 *mpu, unsigned long addr);
+};
+
+/* I/O ports */
+
+#define MPU401C(mpu) (mpu)->cport
+#define MPU401D(mpu) (mpu)->port
+
+/*
+ * control register bits
+ */
+/* read MPU401C() */
+#define MPU401_RX_EMPTY		0x80
+#define MPU401_TX_FULL		0x40
+
+/* write MPU401C() */
+#define MPU401_RESET		0xff
+#define MPU401_ENTER_UART	0x3f
+
+/* read MPU401D() */
+#define MPU401_ACK		0xfe
+
+
+/*
+
+ */
+
+irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id);
+irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id);
+
+int snd_mpu401_uart_new(struct snd_card *card,
+			int device,
+			unsigned short hardware,
+			unsigned long port,
+			unsigned int info_flags,
+			int irq,
+			struct snd_rawmidi ** rrawmidi);
+
+#endif /* __SOUND_MPU401_H */
diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h
new file mode 100644
index 0000000..afdb416
--- /dev/null
+++ b/include/sound/omap-hdmi-audio.h
@@ -0,0 +1,43 @@
+/*
+ * hdmi-audio.c -- OMAP4+ DSS HDMI audio support library
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Jyri Sarha <jsarha@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <video/omapdss.h>
+
+#ifndef __OMAP_HDMI_AUDIO_H__
+#define __OMAP_HDMI_AUDIO_H__
+
+struct omap_hdmi_audio_ops {
+	int (*audio_startup)(struct device *dev,
+			     void (*abort_cb)(struct device *dev));
+	int (*audio_shutdown)(struct device *dev);
+	int (*audio_start)(struct device *dev);
+	void (*audio_stop)(struct device *dev);
+	int (*audio_config)(struct device *dev,
+			    struct omap_dss_audio *dss_audio);
+};
+
+/* HDMI audio initalization data */
+struct omap_hdmi_audio_pdata {
+	struct device *dev;
+	enum omapdss_version dss_version;
+	phys_addr_t audio_dma_addr;
+
+	const struct omap_hdmi_audio_ops *ops;
+};
+
+#endif /* __OMAP_HDMI_AUDIO_H__ */
diff --git a/include/sound/omap-pcm.h b/include/sound/omap-pcm.h
new file mode 100644
index 0000000..c1d2f31
--- /dev/null
+++ b/include/sound/omap-pcm.h
@@ -0,0 +1,30 @@
+/*
+ * omap-pcm.h - OMAP PCM driver
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __OMAP_PCM_H__
+#define __OMAP_PCM_H__
+
+#if IS_ENABLED(CONFIG_SND_OMAP_SOC)
+int omap_pcm_platform_register(struct device *dev);
+#else
+static inline int omap_pcm_platform_register(struct device *dev)
+{
+	return 0;
+}
+#endif /* CONFIG_SND_OMAP_SOC */
+
+#endif /* __OMAP_PCM_H__ */
diff --git a/include/sound/opl3.h b/include/sound/opl3.h
new file mode 100644
index 0000000..6ba6707
--- /dev/null
+++ b/include/sound/opl3.h
@@ -0,0 +1,393 @@
+#ifndef __SOUND_OPL3_H
+#define __SOUND_OPL3_H
+
+/*
+ * Definitions of the OPL-3 registers.
+ *
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *                  Hannu Savolainen 1993-1996
+ *
+ *
+ *      The OPL-3 mode is switched on by writing 0x01, to the offset 5
+ *      of the right side.
+ *
+ *      Another special register at the right side is at offset 4. It contains
+ *      a bit mask defining which voices are used as 4 OP voices.
+ *
+ *      The percussive mode is implemented in the left side only.
+ *
+ *      With the above exceptions the both sides can be operated independently.
+ *      
+ *      A 4 OP voice can be created by setting the corresponding
+ *      bit at offset 4 of the right side.
+ *
+ *      For example setting the rightmost bit (0x01) changes the
+ *      first voice on the right side to the 4 OP mode. The fourth
+ *      voice is made inaccessible.
+ *
+ *      If a voice is set to the 2 OP mode, it works like 2 OP modes
+ *      of the original YM3812 (AdLib). In addition the voice can 
+ *      be connected the left, right or both stereo channels. It can
+ *      even be left unconnected. This works with 4 OP voices also.
+ *
+ *      The stereo connection bits are located in the FEEDBACK_CONNECTION
+ *      register of the voice (0xC0-0xC8). In 4 OP voices these bits are
+ *      in the second half of the voice.
+ *
+ *
+ *   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 <sound/core.h>
+#include <sound/hwdep.h>
+#include <sound/timer.h>
+#include <sound/seq_midi_emul.h>
+#ifdef CONFIG_SND_SEQUENCER_OSS
+#include <sound/seq_oss.h>
+#include <sound/seq_oss_legacy.h>
+#endif
+#include <sound/seq_device.h>
+#include <sound/asound_fm.h>
+
+/*
+ *    Register numbers for the global registers
+ */
+
+#define OPL3_REG_TEST			0x01
+#define   OPL3_ENABLE_WAVE_SELECT	0x20
+
+#define OPL3_REG_TIMER1			0x02
+#define OPL3_REG_TIMER2			0x03
+#define OPL3_REG_TIMER_CONTROL		0x04	/* Left side */
+#define   OPL3_IRQ_RESET		0x80
+#define   OPL3_TIMER1_MASK		0x40
+#define   OPL3_TIMER2_MASK		0x20
+#define   OPL3_TIMER1_START		0x01
+#define   OPL3_TIMER2_START		0x02
+
+#define OPL3_REG_CONNECTION_SELECT	0x04	/* Right side */
+#define   OPL3_LEFT_4OP_0		0x01
+#define   OPL3_LEFT_4OP_1		0x02
+#define   OPL3_LEFT_4OP_2		0x04
+#define   OPL3_RIGHT_4OP_0		0x08
+#define   OPL3_RIGHT_4OP_1		0x10
+#define   OPL3_RIGHT_4OP_2		0x20
+
+#define OPL3_REG_MODE			0x05	/* Right side */
+#define   OPL3_OPL3_ENABLE		0x01	/* OPL3 mode */
+#define   OPL3_OPL4_ENABLE		0x02	/* OPL4 mode */
+
+#define OPL3_REG_KBD_SPLIT		0x08	/* Left side */
+#define   OPL3_COMPOSITE_SINE_WAVE_MODE	0x80	/* Don't use with OPL-3? */
+#define   OPL3_KEYBOARD_SPLIT		0x40
+
+#define OPL3_REG_PERCUSSION		0xbd	/* Left side only */
+#define   OPL3_TREMOLO_DEPTH		0x80
+#define   OPL3_VIBRATO_DEPTH		0x40
+#define	  OPL3_PERCUSSION_ENABLE	0x20
+#define   OPL3_BASSDRUM_ON		0x10
+#define   OPL3_SNAREDRUM_ON		0x08
+#define   OPL3_TOMTOM_ON		0x04
+#define   OPL3_CYMBAL_ON		0x02
+#define   OPL3_HIHAT_ON			0x01
+
+/*
+ *    Offsets to the register banks for operators. To get the
+ *      register number just add the operator offset to the bank offset
+ *
+ *      AM/VIB/EG/KSR/Multiple (0x20 to 0x35)
+ */
+#define OPL3_REG_AM_VIB			0x20
+#define   OPL3_TREMOLO_ON		0x80
+#define   OPL3_VIBRATO_ON		0x40
+#define   OPL3_SUSTAIN_ON		0x20
+#define   OPL3_KSR			0x10	/* Key scaling rate */
+#define   OPL3_MULTIPLE_MASK		0x0f	/* Frequency multiplier */
+
+ /*
+  *   KSL/Total level (0x40 to 0x55)
+  */
+#define OPL3_REG_KSL_LEVEL		0x40
+#define   OPL3_KSL_MASK			0xc0	/* Envelope scaling bits */
+#define   OPL3_TOTAL_LEVEL_MASK		0x3f	/* Strength (volume) of OP */
+
+/*
+ *    Attack / Decay rate (0x60 to 0x75)
+ */
+#define OPL3_REG_ATTACK_DECAY		0x60
+#define   OPL3_ATTACK_MASK		0xf0
+#define   OPL3_DECAY_MASK		0x0f
+
+/*
+ * Sustain level / Release rate (0x80 to 0x95)
+ */
+#define OPL3_REG_SUSTAIN_RELEASE	0x80
+#define   OPL3_SUSTAIN_MASK		0xf0
+#define   OPL3_RELEASE_MASK		0x0f
+
+/*
+ * Wave select (0xE0 to 0xF5)
+ */
+#define OPL3_REG_WAVE_SELECT		0xe0
+#define   OPL3_WAVE_SELECT_MASK		0x07
+
+/*
+ *    Offsets to the register banks for voices. Just add to the
+ *      voice number to get the register number.
+ *
+ *      F-Number low bits (0xA0 to 0xA8).
+ */
+#define OPL3_REG_FNUM_LOW		0xa0
+
+/*
+ *    F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
+ */
+#define OPL3_REG_KEYON_BLOCK		0xb0
+#define	  OPL3_KEYON_BIT		0x20
+#define	  OPL3_BLOCKNUM_MASK		0x1c
+#define   OPL3_FNUM_HIGH_MASK		0x03
+
+/*
+ *    Feedback / Connection (0xc0 to 0xc8)
+ *
+ *      These registers have two new bits when the OPL-3 mode
+ *      is selected. These bits controls connecting the voice
+ *      to the stereo channels. For 4 OP voices this bit is
+ *      defined in the second half of the voice (add 3 to the
+ *      register offset).
+ *
+ *      For 4 OP voices the connection bit is used in the
+ *      both halves (gives 4 ways to connect the operators).
+ */
+#define OPL3_REG_FEEDBACK_CONNECTION	0xc0
+#define   OPL3_FEEDBACK_MASK		0x0e	/* Valid just for 1st OP of a voice */
+#define   OPL3_CONNECTION_BIT		0x01
+/*
+ *    In the 4 OP mode there is four possible configurations how the
+ *      operators can be connected together (in 2 OP modes there is just
+ *      AM or FM). The 4 OP connection mode is defined by the rightmost
+ *      bit of the FEEDBACK_CONNECTION (0xC0-0xC8) on the both halves.
+ *
+ *      First half      Second half     Mode
+ *
+ *                                       +---+
+ *                                       v   |
+ *      0               0               >+-1-+--2--3--4-->
+ *
+ *
+ *                                      
+ *                                       +---+
+ *                                       |   |
+ *      0               1               >+-1-+--2-+
+ *                                                |->
+ *                                      >--3----4-+
+ *                                      
+ *                                       +---+
+ *                                       |   |
+ *      1               0               >+-1-+-----+
+ *                                                 |->
+ *                                      >--2--3--4-+
+ *
+ *                                       +---+
+ *                                       |   |
+ *      1               1               >+-1-+--+
+ *                                              |
+ *                                      >--2--3-+->
+ *                                              |
+ *                                      >--4----+
+ */
+#define   OPL3_STEREO_BITS		0x30	/* OPL-3 only */
+#define     OPL3_VOICE_TO_LEFT		0x10
+#define     OPL3_VOICE_TO_RIGHT		0x20
+
+/*
+
+ */
+
+#define OPL3_LEFT		0x0000
+#define OPL3_RIGHT		0x0100
+
+#define OPL3_HW_AUTO		0x0000
+#define OPL3_HW_OPL2		0x0200
+#define OPL3_HW_OPL3		0x0300
+#define OPL3_HW_OPL3_SV		0x0301	/* S3 SonicVibes */
+#define OPL3_HW_OPL3_CS		0x0302	/* CS4232/CS4236+ */
+#define OPL3_HW_OPL3_FM801	0x0303	/* FM801 */
+#define OPL3_HW_OPL3_CS4281	0x0304	/* CS4281 */
+#define OPL3_HW_OPL4		0x0400	/* YMF278B/YMF295 */
+#define OPL3_HW_OPL4_ML		0x0401	/* YMF704/YMF721 */
+#define OPL3_HW_MASK		0xff00
+
+#define MAX_OPL2_VOICES		9
+#define MAX_OPL3_VOICES		18
+
+struct snd_opl3;
+
+/*
+ * Instrument record, aka "Patch"
+ */
+
+/* FM operator */
+struct fm_operator {
+	unsigned char am_vib;
+	unsigned char ksl_level;
+	unsigned char attack_decay;
+	unsigned char sustain_release;
+	unsigned char wave_select;
+} __attribute__((packed));
+
+/* Instrument data */
+struct fm_instrument {
+	struct fm_operator op[4];
+	unsigned char feedback_connection[2];
+	unsigned char echo_delay;
+	unsigned char echo_atten;
+	unsigned char chorus_spread;
+	unsigned char trnsps;
+	unsigned char fix_dur;
+	unsigned char modes;
+	unsigned char fix_key;
+};
+
+/* type */
+#define FM_PATCH_OPL2	0x01		/* OPL2 2 operators FM instrument */
+#define FM_PATCH_OPL3	0x02		/* OPL3 4 operators FM instrument */
+
+/* Instrument record */
+struct fm_patch {
+	unsigned char prog;
+	unsigned char bank;
+	unsigned char type;
+	struct fm_instrument inst;
+	char name[24];
+	struct fm_patch *next;
+};
+
+
+/*
+ * A structure to keep track of each hardware voice
+ */
+struct snd_opl3_voice {
+	int  state;		/* status */
+#define SNDRV_OPL3_ST_OFF		0	/* Not playing */
+#define SNDRV_OPL3_ST_ON_2OP	1	/* 2op voice is allocated */
+#define SNDRV_OPL3_ST_ON_4OP	2	/* 4op voice is allocated */
+#define SNDRV_OPL3_ST_NOT_AVAIL	-1	/* voice is not available */
+
+	unsigned int time;	/* An allocation time */
+	unsigned char note;	/* Note currently assigned to this voice */
+
+	unsigned long note_off;	/* note-off time */
+	int note_off_check;	/* check note-off time */
+
+	unsigned char keyon_reg;	/* KON register shadow */
+
+	struct snd_midi_channel *chan;	/* Midi channel for this note */
+};
+
+struct snd_opl3 {
+	unsigned long l_port;
+	unsigned long r_port;
+	struct resource *res_l_port;
+	struct resource *res_r_port;
+	unsigned short hardware;
+	/* hardware access */
+	void (*command) (struct snd_opl3 * opl3, unsigned short cmd, unsigned char val);
+	unsigned short timer_enable;
+	int seq_dev_num;	/* sequencer device number */
+	struct snd_timer *timer1;
+	struct snd_timer *timer2;
+	spinlock_t timer_lock;
+
+	void *private_data;
+	void (*private_free)(struct snd_opl3 *);
+
+	struct snd_hwdep *hwdep;
+	spinlock_t reg_lock;
+	struct snd_card *card;		/* The card that this belongs to */
+	unsigned char fm_mode;		/* OPL mode, see SNDRV_DM_FM_MODE_XXX */
+	unsigned char rhythm;		/* percussion mode flag */
+	unsigned char max_voices;	/* max number of voices */
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#define SNDRV_OPL3_MODE_SYNTH 0		/* OSS - voices allocated by application */
+#define SNDRV_OPL3_MODE_SEQ 1		/* ALSA - driver handles voice allocation */
+	int synth_mode;			/* synth mode */
+	int seq_client;
+
+	struct snd_seq_device *seq_dev;	/* sequencer device */
+	struct snd_midi_channel_set * chset;
+
+#ifdef CONFIG_SND_SEQUENCER_OSS
+	struct snd_seq_device *oss_seq_dev;	/* OSS sequencer device */
+	struct snd_midi_channel_set * oss_chset;
+#endif
+ 
+#define OPL3_PATCH_HASH_SIZE	32
+	struct fm_patch *patch_table[OPL3_PATCH_HASH_SIZE];
+
+	struct snd_opl3_voice voices[MAX_OPL3_VOICES]; /* Voices (OPL3 'channel') */
+	int use_time;			/* allocation counter */
+
+	unsigned short connection_reg;	/* connection reg shadow */
+	unsigned char drum_reg;		/* percussion reg shadow */
+
+	spinlock_t voice_lock;		/* Lock for voice access */
+
+	struct timer_list tlist;	/* timer for note-offs and effects */
+	int sys_timer_status;		/* system timer run status */
+	spinlock_t sys_timer_lock;	/* Lock for system timer access */
+#endif
+};
+
+/* opl3.c */
+void snd_opl3_interrupt(struct snd_hwdep * hw);
+int snd_opl3_new(struct snd_card *card, unsigned short hardware,
+		 struct snd_opl3 **ropl3);
+int snd_opl3_init(struct snd_opl3 *opl3);
+int snd_opl3_create(struct snd_card *card,
+		    unsigned long l_port, unsigned long r_port,
+		    unsigned short hardware,
+		    int integrated,
+		    struct snd_opl3 ** opl3);
+int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev);
+int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device,
+		       struct snd_hwdep ** rhwdep);
+
+/* opl3_synth */
+int snd_opl3_open(struct snd_hwdep * hw, struct file *file);
+int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
+		   unsigned int cmd, unsigned long arg);
+int snd_opl3_release(struct snd_hwdep * hw, struct file *file);
+
+void snd_opl3_reset(struct snd_opl3 * opl3);
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+long snd_opl3_write(struct snd_hwdep *hw, const char __user *buf, long count,
+		    loff_t *offset);
+int snd_opl3_load_patch(struct snd_opl3 *opl3,
+			int prog, int bank, int type,
+			const char *name,
+			const unsigned char *ext,
+			const unsigned char *data);
+struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank,
+				     int create_patch);
+void snd_opl3_clear_patches(struct snd_opl3 *opl3);
+#else
+#define snd_opl3_write	NULL
+static inline void snd_opl3_clear_patches(struct snd_opl3 *opl3) {}
+#endif
+
+#endif /* __SOUND_OPL3_H */
diff --git a/include/sound/opl4.h b/include/sound/opl4.h
new file mode 100644
index 0000000..60ae845
--- /dev/null
+++ b/include/sound/opl4.h
@@ -0,0 +1,32 @@
+#ifndef __SOUND_OPL4_H
+#define __SOUND_OPL4_H
+
+/*
+ * Global definitions for the OPL4 driver
+ * Copyright (c) 2003 by Clemens Ladisch <clemens@ladisch.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/opl3.h>
+
+struct snd_opl4;
+
+extern int snd_opl4_create(struct snd_card *card,
+			   unsigned long fm_port, unsigned long pcm_port,
+			   int seq_device,
+			   struct snd_opl3 **opl3, struct snd_opl4 **opl4);
+
+#endif /* __SOUND_OPL4_H */
diff --git a/include/sound/pcm-indirect.h b/include/sound/pcm-indirect.h
new file mode 100644
index 0000000..1df7aca
--- /dev/null
+++ b/include/sound/pcm-indirect.h
@@ -0,0 +1,177 @@
+/*
+ * Helper functions for indirect PCM data transfer
+ *
+ *  Copyright (c) by Takashi Iwai <tiwai@suse.de>
+ *                   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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SOUND_PCM_INDIRECT_H
+#define __SOUND_PCM_INDIRECT_H
+
+#include <sound/pcm.h>
+
+struct snd_pcm_indirect {
+	unsigned int hw_buffer_size;	/* Byte size of hardware buffer */
+	unsigned int hw_queue_size;	/* Max queue size of hw buffer (0 = buffer size) */
+	unsigned int hw_data;	/* Offset to next dst (or src) in hw ring buffer */
+	unsigned int hw_io;	/* Ring buffer hw pointer */
+	int hw_ready;		/* Bytes ready for play (or captured) in hw ring buffer */
+	unsigned int sw_buffer_size;	/* Byte size of software buffer */
+	unsigned int sw_data;	/* Offset to next dst (or src) in sw ring buffer */
+	unsigned int sw_io;	/* Current software pointer in bytes */
+	int sw_ready;		/* Bytes ready to be transferred to/from hw */
+	snd_pcm_uframes_t appl_ptr;	/* Last seen appl_ptr */
+};
+
+typedef void (*snd_pcm_indirect_copy_t)(struct snd_pcm_substream *substream,
+					struct snd_pcm_indirect *rec, size_t bytes);
+
+/*
+ * helper function for playback ack callback
+ */
+static inline void
+snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream,
+				   struct snd_pcm_indirect *rec,
+				   snd_pcm_indirect_copy_t copy)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
+	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
+	int qsize;
+
+	if (diff) {
+		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
+			diff += runtime->boundary;
+		rec->sw_ready += (int)frames_to_bytes(runtime, diff);
+		rec->appl_ptr = appl_ptr;
+	}
+	qsize = rec->hw_queue_size ? rec->hw_queue_size : rec->hw_buffer_size;
+	while (rec->hw_ready < qsize && rec->sw_ready > 0) {
+		unsigned int hw_to_end = rec->hw_buffer_size - rec->hw_data;
+		unsigned int sw_to_end = rec->sw_buffer_size - rec->sw_data;
+		unsigned int bytes = qsize - rec->hw_ready;
+		if (rec->sw_ready < (int)bytes)
+			bytes = rec->sw_ready;
+		if (hw_to_end < bytes)
+			bytes = hw_to_end;
+		if (sw_to_end < bytes)
+			bytes = sw_to_end;
+		if (! bytes)
+			break;
+		copy(substream, rec, bytes);
+		rec->hw_data += bytes;
+		if (rec->hw_data == rec->hw_buffer_size)
+			rec->hw_data = 0;
+		rec->sw_data += bytes;
+		if (rec->sw_data == rec->sw_buffer_size)
+			rec->sw_data = 0;
+		rec->hw_ready += bytes;
+		rec->sw_ready -= bytes;
+	}
+}
+
+/*
+ * helper function for playback pointer callback
+ * ptr = current byte pointer
+ */
+static inline snd_pcm_uframes_t
+snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream,
+				  struct snd_pcm_indirect *rec, unsigned int ptr)
+{
+	int bytes = ptr - rec->hw_io;
+	if (bytes < 0)
+		bytes += rec->hw_buffer_size;
+	rec->hw_io = ptr;
+	rec->hw_ready -= bytes;
+	rec->sw_io += bytes;
+	if (rec->sw_io >= rec->sw_buffer_size)
+		rec->sw_io -= rec->sw_buffer_size;
+	if (substream->ops->ack)
+		substream->ops->ack(substream);
+	return bytes_to_frames(substream->runtime, rec->sw_io);
+}
+
+
+/*
+ * helper function for capture ack callback
+ */
+static inline void
+snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream,
+				  struct snd_pcm_indirect *rec,
+				  snd_pcm_indirect_copy_t copy)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
+	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
+
+	if (diff) {
+		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
+			diff += runtime->boundary;
+		rec->sw_ready -= frames_to_bytes(runtime, diff);
+		rec->appl_ptr = appl_ptr;
+	}
+	while (rec->hw_ready > 0 && 
+	       rec->sw_ready < (int)rec->sw_buffer_size) {
+		size_t hw_to_end = rec->hw_buffer_size - rec->hw_data;
+		size_t sw_to_end = rec->sw_buffer_size - rec->sw_data;
+		size_t bytes = rec->sw_buffer_size - rec->sw_ready;
+		if (rec->hw_ready < (int)bytes)
+			bytes = rec->hw_ready;
+		if (hw_to_end < bytes)
+			bytes = hw_to_end;
+		if (sw_to_end < bytes)
+			bytes = sw_to_end;
+		if (! bytes)
+			break;
+		copy(substream, rec, bytes);
+		rec->hw_data += bytes;
+		if ((int)rec->hw_data == rec->hw_buffer_size)
+			rec->hw_data = 0;
+		rec->sw_data += bytes;
+		if (rec->sw_data == rec->sw_buffer_size)
+			rec->sw_data = 0;
+		rec->hw_ready -= bytes;
+		rec->sw_ready += bytes;
+	}
+}
+
+/*
+ * helper function for capture pointer callback,
+ * ptr = current byte pointer
+ */
+static inline snd_pcm_uframes_t
+snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream,
+				 struct snd_pcm_indirect *rec, unsigned int ptr)
+{
+	int qsize;
+	int bytes = ptr - rec->hw_io;
+	if (bytes < 0)
+		bytes += rec->hw_buffer_size;
+	rec->hw_io = ptr;
+	rec->hw_ready += bytes;
+	qsize = rec->hw_queue_size ? rec->hw_queue_size : rec->hw_buffer_size;
+	if (rec->hw_ready > qsize)
+		return SNDRV_PCM_POS_XRUN;
+	rec->sw_io += bytes;
+	if (rec->sw_io >= rec->sw_buffer_size)
+		rec->sw_io -= rec->sw_buffer_size;
+	if (substream->ops->ack)
+		substream->ops->ack(substream);
+	return bytes_to_frames(substream->runtime, rec->sw_io);
+}
+
+#endif /* __SOUND_PCM_INDIRECT_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
new file mode 100644
index 0000000..b0be092
--- /dev/null
+++ b/include/sound/pcm.h
@@ -0,0 +1,1410 @@
+#ifndef __SOUND_PCM_H
+#define __SOUND_PCM_H
+
+/*
+ *  Digital Audio (PCM) abstract layer
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *                   Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ *   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 <sound/asound.h>
+#include <sound/memalloc.h>
+#include <sound/minors.h>
+#include <linux/poll.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+#include <linux/pm_qos.h>
+
+#define snd_pcm_substream_chip(substream) ((substream)->private_data)
+#define snd_pcm_chip(pcm) ((pcm)->private_data)
+
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#include <sound/pcm_oss.h>
+#endif
+
+/*
+ *  Hardware (lowlevel) section
+ */
+
+struct snd_pcm_hardware {
+	unsigned int info;		/* SNDRV_PCM_INFO_* */
+	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
+	unsigned int rates;		/* SNDRV_PCM_RATE_* */
+	unsigned int rate_min;		/* min rate */
+	unsigned int rate_max;		/* max rate */
+	unsigned int channels_min;	/* min channels */
+	unsigned int channels_max;	/* max channels */
+	size_t buffer_bytes_max;	/* max buffer size */
+	size_t period_bytes_min;	/* min period size */
+	size_t period_bytes_max;	/* max period size */
+	unsigned int periods_min;	/* min # of periods */
+	unsigned int periods_max;	/* max # of periods */
+	size_t fifo_size;		/* fifo size in bytes */
+};
+
+struct snd_pcm_substream;
+
+struct snd_pcm_audio_tstamp_config; /* definitions further down */
+struct snd_pcm_audio_tstamp_report;
+
+struct snd_pcm_ops {
+	int (*open)(struct snd_pcm_substream *substream);
+	int (*close)(struct snd_pcm_substream *substream);
+	int (*ioctl)(struct snd_pcm_substream * substream,
+		     unsigned int cmd, void *arg);
+	int (*hw_params)(struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params);
+	int (*hw_free)(struct snd_pcm_substream *substream);
+	int (*prepare)(struct snd_pcm_substream *substream);
+	int (*trigger)(struct snd_pcm_substream *substream, int cmd);
+	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
+	int (*get_time_info)(struct snd_pcm_substream *substream,
+			struct timespec *system_ts, struct timespec *audio_ts,
+			struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+			struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
+	int (*copy)(struct snd_pcm_substream *substream, int channel,
+		    snd_pcm_uframes_t pos,
+		    void __user *buf, snd_pcm_uframes_t count);
+	int (*silence)(struct snd_pcm_substream *substream, int channel, 
+		       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
+	struct page *(*page)(struct snd_pcm_substream *substream,
+			     unsigned long offset);
+	int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
+	int (*ack)(struct snd_pcm_substream *substream);
+};
+
+/*
+ *
+ */
+
+#if defined(CONFIG_SND_DYNAMIC_MINORS)
+#define SNDRV_PCM_DEVICES	(SNDRV_OS_MINORS-2)
+#else
+#define SNDRV_PCM_DEVICES	8
+#endif
+
+#define SNDRV_PCM_IOCTL1_RESET		0
+#define SNDRV_PCM_IOCTL1_INFO		1
+#define SNDRV_PCM_IOCTL1_CHANNEL_INFO	2
+#define SNDRV_PCM_IOCTL1_GSTATE		3
+#define SNDRV_PCM_IOCTL1_FIFO_SIZE	4
+
+#define SNDRV_PCM_TRIGGER_STOP		0
+#define SNDRV_PCM_TRIGGER_START		1
+#define SNDRV_PCM_TRIGGER_PAUSE_PUSH	3
+#define SNDRV_PCM_TRIGGER_PAUSE_RELEASE	4
+#define SNDRV_PCM_TRIGGER_SUSPEND	5
+#define SNDRV_PCM_TRIGGER_RESUME	6
+#define SNDRV_PCM_TRIGGER_DRAIN		7
+
+#define SNDRV_PCM_POS_XRUN		((snd_pcm_uframes_t)-1)
+
+/* If you change this don't forget to change rates[] table in pcm_native.c */
+#define SNDRV_PCM_RATE_5512		(1<<0)		/* 5512Hz */
+#define SNDRV_PCM_RATE_8000		(1<<1)		/* 8000Hz */
+#define SNDRV_PCM_RATE_11025		(1<<2)		/* 11025Hz */
+#define SNDRV_PCM_RATE_16000		(1<<3)		/* 16000Hz */
+#define SNDRV_PCM_RATE_22050		(1<<4)		/* 22050Hz */
+#define SNDRV_PCM_RATE_32000		(1<<5)		/* 32000Hz */
+#define SNDRV_PCM_RATE_44100		(1<<6)		/* 44100Hz */
+#define SNDRV_PCM_RATE_48000		(1<<7)		/* 48000Hz */
+#define SNDRV_PCM_RATE_64000		(1<<8)		/* 64000Hz */
+#define SNDRV_PCM_RATE_88200		(1<<9)		/* 88200Hz */
+#define SNDRV_PCM_RATE_96000		(1<<10)		/* 96000Hz */
+#define SNDRV_PCM_RATE_176400		(1<<11)		/* 176400Hz */
+#define SNDRV_PCM_RATE_192000		(1<<12)		/* 192000Hz */
+
+#define SNDRV_PCM_RATE_CONTINUOUS	(1<<30)		/* continuous range */
+#define SNDRV_PCM_RATE_KNOT		(1<<31)		/* supports more non-continuos rates */
+
+#define SNDRV_PCM_RATE_8000_44100	(SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
+					 SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
+					 SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100)
+#define SNDRV_PCM_RATE_8000_48000	(SNDRV_PCM_RATE_8000_44100|SNDRV_PCM_RATE_48000)
+#define SNDRV_PCM_RATE_8000_96000	(SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_64000|\
+					 SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
+#define SNDRV_PCM_RATE_8000_192000	(SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\
+					 SNDRV_PCM_RATE_192000)
+#define _SNDRV_PCM_FMTBIT(fmt)		(1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt)
+#define SNDRV_PCM_FMTBIT_S8		_SNDRV_PCM_FMTBIT(S8)
+#define SNDRV_PCM_FMTBIT_U8		_SNDRV_PCM_FMTBIT(U8)
+#define SNDRV_PCM_FMTBIT_S16_LE		_SNDRV_PCM_FMTBIT(S16_LE)
+#define SNDRV_PCM_FMTBIT_S16_BE		_SNDRV_PCM_FMTBIT(S16_BE)
+#define SNDRV_PCM_FMTBIT_U16_LE		_SNDRV_PCM_FMTBIT(U16_LE)
+#define SNDRV_PCM_FMTBIT_U16_BE		_SNDRV_PCM_FMTBIT(U16_BE)
+#define SNDRV_PCM_FMTBIT_S24_LE		_SNDRV_PCM_FMTBIT(S24_LE)
+#define SNDRV_PCM_FMTBIT_S24_BE		_SNDRV_PCM_FMTBIT(S24_BE)
+#define SNDRV_PCM_FMTBIT_U24_LE		_SNDRV_PCM_FMTBIT(U24_LE)
+#define SNDRV_PCM_FMTBIT_U24_BE		_SNDRV_PCM_FMTBIT(U24_BE)
+#define SNDRV_PCM_FMTBIT_S32_LE		_SNDRV_PCM_FMTBIT(S32_LE)
+#define SNDRV_PCM_FMTBIT_S32_BE		_SNDRV_PCM_FMTBIT(S32_BE)
+#define SNDRV_PCM_FMTBIT_U32_LE		_SNDRV_PCM_FMTBIT(U32_LE)
+#define SNDRV_PCM_FMTBIT_U32_BE		_SNDRV_PCM_FMTBIT(U32_BE)
+#define SNDRV_PCM_FMTBIT_FLOAT_LE	_SNDRV_PCM_FMTBIT(FLOAT_LE)
+#define SNDRV_PCM_FMTBIT_FLOAT_BE	_SNDRV_PCM_FMTBIT(FLOAT_BE)
+#define SNDRV_PCM_FMTBIT_FLOAT64_LE	_SNDRV_PCM_FMTBIT(FLOAT64_LE)
+#define SNDRV_PCM_FMTBIT_FLOAT64_BE	_SNDRV_PCM_FMTBIT(FLOAT64_BE)
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE _SNDRV_PCM_FMTBIT(IEC958_SUBFRAME_LE)
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE _SNDRV_PCM_FMTBIT(IEC958_SUBFRAME_BE)
+#define SNDRV_PCM_FMTBIT_MU_LAW		_SNDRV_PCM_FMTBIT(MU_LAW)
+#define SNDRV_PCM_FMTBIT_A_LAW		_SNDRV_PCM_FMTBIT(A_LAW)
+#define SNDRV_PCM_FMTBIT_IMA_ADPCM	_SNDRV_PCM_FMTBIT(IMA_ADPCM)
+#define SNDRV_PCM_FMTBIT_MPEG		_SNDRV_PCM_FMTBIT(MPEG)
+#define SNDRV_PCM_FMTBIT_GSM		_SNDRV_PCM_FMTBIT(GSM)
+#define SNDRV_PCM_FMTBIT_SPECIAL	_SNDRV_PCM_FMTBIT(SPECIAL)
+#define SNDRV_PCM_FMTBIT_S24_3LE	_SNDRV_PCM_FMTBIT(S24_3LE)
+#define SNDRV_PCM_FMTBIT_U24_3LE	_SNDRV_PCM_FMTBIT(U24_3LE)
+#define SNDRV_PCM_FMTBIT_S24_3BE	_SNDRV_PCM_FMTBIT(S24_3BE)
+#define SNDRV_PCM_FMTBIT_U24_3BE	_SNDRV_PCM_FMTBIT(U24_3BE)
+#define SNDRV_PCM_FMTBIT_S20_3LE	_SNDRV_PCM_FMTBIT(S20_3LE)
+#define SNDRV_PCM_FMTBIT_U20_3LE	_SNDRV_PCM_FMTBIT(U20_3LE)
+#define SNDRV_PCM_FMTBIT_S20_3BE	_SNDRV_PCM_FMTBIT(S20_3BE)
+#define SNDRV_PCM_FMTBIT_U20_3BE	_SNDRV_PCM_FMTBIT(U20_3BE)
+#define SNDRV_PCM_FMTBIT_S18_3LE	_SNDRV_PCM_FMTBIT(S18_3LE)
+#define SNDRV_PCM_FMTBIT_U18_3LE	_SNDRV_PCM_FMTBIT(U18_3LE)
+#define SNDRV_PCM_FMTBIT_S18_3BE	_SNDRV_PCM_FMTBIT(S18_3BE)
+#define SNDRV_PCM_FMTBIT_U18_3BE	_SNDRV_PCM_FMTBIT(U18_3BE)
+#define SNDRV_PCM_FMTBIT_G723_24	_SNDRV_PCM_FMTBIT(G723_24)
+#define SNDRV_PCM_FMTBIT_G723_24_1B	_SNDRV_PCM_FMTBIT(G723_24_1B)
+#define SNDRV_PCM_FMTBIT_G723_40	_SNDRV_PCM_FMTBIT(G723_40)
+#define SNDRV_PCM_FMTBIT_G723_40_1B	_SNDRV_PCM_FMTBIT(G723_40_1B)
+#define SNDRV_PCM_FMTBIT_DSD_U8		_SNDRV_PCM_FMTBIT(DSD_U8)
+#define SNDRV_PCM_FMTBIT_DSD_U16_LE	_SNDRV_PCM_FMTBIT(DSD_U16_LE)
+#define SNDRV_PCM_FMTBIT_DSD_U32_LE	_SNDRV_PCM_FMTBIT(DSD_U32_LE)
+#define SNDRV_PCM_FMTBIT_DSD_U16_BE	_SNDRV_PCM_FMTBIT(DSD_U16_BE)
+#define SNDRV_PCM_FMTBIT_DSD_U32_BE	_SNDRV_PCM_FMTBIT(DSD_U32_BE)
+
+#ifdef SNDRV_LITTLE_ENDIAN
+#define SNDRV_PCM_FMTBIT_S16		SNDRV_PCM_FMTBIT_S16_LE
+#define SNDRV_PCM_FMTBIT_U16		SNDRV_PCM_FMTBIT_U16_LE
+#define SNDRV_PCM_FMTBIT_S24		SNDRV_PCM_FMTBIT_S24_LE
+#define SNDRV_PCM_FMTBIT_U24		SNDRV_PCM_FMTBIT_U24_LE
+#define SNDRV_PCM_FMTBIT_S32		SNDRV_PCM_FMTBIT_S32_LE
+#define SNDRV_PCM_FMTBIT_U32		SNDRV_PCM_FMTBIT_U32_LE
+#define SNDRV_PCM_FMTBIT_FLOAT		SNDRV_PCM_FMTBIT_FLOAT_LE
+#define SNDRV_PCM_FMTBIT_FLOAT64	SNDRV_PCM_FMTBIT_FLOAT64_LE
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
+#endif
+#ifdef SNDRV_BIG_ENDIAN
+#define SNDRV_PCM_FMTBIT_S16		SNDRV_PCM_FMTBIT_S16_BE
+#define SNDRV_PCM_FMTBIT_U16		SNDRV_PCM_FMTBIT_U16_BE
+#define SNDRV_PCM_FMTBIT_S24		SNDRV_PCM_FMTBIT_S24_BE
+#define SNDRV_PCM_FMTBIT_U24		SNDRV_PCM_FMTBIT_U24_BE
+#define SNDRV_PCM_FMTBIT_S32		SNDRV_PCM_FMTBIT_S32_BE
+#define SNDRV_PCM_FMTBIT_U32		SNDRV_PCM_FMTBIT_U32_BE
+#define SNDRV_PCM_FMTBIT_FLOAT		SNDRV_PCM_FMTBIT_FLOAT_BE
+#define SNDRV_PCM_FMTBIT_FLOAT64	SNDRV_PCM_FMTBIT_FLOAT64_BE
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE
+#endif
+
+struct snd_pcm_file {
+	struct snd_pcm_substream *substream;
+	int no_compat_mmap;
+};
+
+struct snd_pcm_hw_rule;
+typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params,
+				      struct snd_pcm_hw_rule *rule);
+
+struct snd_pcm_hw_rule {
+	unsigned int cond;
+	int var;
+	int deps[4];
+
+	snd_pcm_hw_rule_func_t func;
+	void *private;
+};
+
+struct snd_pcm_hw_constraints {
+	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
+			 SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
+			     SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+	unsigned int rules_num;
+	unsigned int rules_all;
+	struct snd_pcm_hw_rule *rules;
+};
+
+static inline struct snd_mask *constrs_mask(struct snd_pcm_hw_constraints *constrs,
+					    snd_pcm_hw_param_t var)
+{
+	return &constrs->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
+}
+
+static inline struct snd_interval *constrs_interval(struct snd_pcm_hw_constraints *constrs,
+						    snd_pcm_hw_param_t var)
+{
+	return &constrs->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
+}
+
+struct snd_ratnum {
+	unsigned int num;
+	unsigned int den_min, den_max, den_step;
+};
+
+struct snd_ratden {
+	unsigned int num_min, num_max, num_step;
+	unsigned int den;
+};
+
+struct snd_pcm_hw_constraint_ratnums {
+	int nrats;
+	const struct snd_ratnum *rats;
+};
+
+struct snd_pcm_hw_constraint_ratdens {
+	int nrats;
+	const struct snd_ratden *rats;
+};
+
+struct snd_pcm_hw_constraint_list {
+	const unsigned int *list;
+	unsigned int count;
+	unsigned int mask;
+};
+
+struct snd_pcm_hw_constraint_ranges {
+	unsigned int count;
+	const struct snd_interval *ranges;
+	unsigned int mask;
+};
+
+/*
+ * userspace-provided audio timestamp config to kernel,
+ * structure is for internal use only and filled with dedicated unpack routine
+ */
+struct snd_pcm_audio_tstamp_config {
+	/* 5 of max 16 bits used */
+	u32 type_requested:4;
+	u32 report_delay:1; /* add total delay to A/D or D/A */
+};
+
+static inline void snd_pcm_unpack_audio_tstamp_config(__u32 data,
+						struct snd_pcm_audio_tstamp_config *config)
+{
+	config->type_requested = data & 0xF;
+	config->report_delay = (data >> 4) & 1;
+}
+
+/*
+ * kernel-provided audio timestamp report to user-space
+ * structure is for internal use only and read by dedicated pack routine
+ */
+struct snd_pcm_audio_tstamp_report {
+	/* 6 of max 16 bits used for bit-fields */
+
+	/* for backwards compatibility */
+	u32 valid:1;
+
+	/* actual type if hardware could not support requested timestamp */
+	u32 actual_type:4;
+
+	/* accuracy represented in ns units */
+	u32 accuracy_report:1; /* 0 if accuracy unknown, 1 if accuracy field is valid */
+	u32 accuracy; /* up to 4.29s, will be packed in separate field  */
+};
+
+static inline void snd_pcm_pack_audio_tstamp_report(__u32 *data, __u32 *accuracy,
+						const struct snd_pcm_audio_tstamp_report *report)
+{
+	u32 tmp;
+
+	tmp = report->accuracy_report;
+	tmp <<= 4;
+	tmp |= report->actual_type;
+	tmp <<= 1;
+	tmp |= report->valid;
+
+	*data &= 0xffff; /* zero-clear MSBs */
+	*data |= (tmp << 16);
+	*accuracy = report->accuracy;
+}
+
+
+struct snd_pcm_runtime {
+	/* -- Status -- */
+	struct snd_pcm_substream *trigger_master;
+	struct timespec trigger_tstamp;	/* trigger timestamp */
+	bool trigger_tstamp_latched;     /* trigger timestamp latched in low-level driver/hardware */
+	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 */
+	unsigned long hw_ptr_jiffies;	/* Time when hw_ptr is updated */
+	unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */
+	snd_pcm_sframes_t delay;	/* extra delay; typically FIFO size */
+	u64 hw_ptr_wrap;                /* offset for hw_ptr due to boundary wrap-around */
+
+	/* -- 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 */
+	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;
+	unsigned int no_period_wakeup: 1;
+
+	/* -- SW params -- */
+	int tstamp_mode;		/* mmap timestamp is updated */
+  	unsigned int period_step;
+	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 silence_start; /* starting pointer to silence area */
+	snd_pcm_uframes_t silence_filled; /* size filled with silence */
+
+	union snd_pcm_sync_id sync;	/* hardware synchronization ID */
+
+	/* -- mmap -- */
+	struct snd_pcm_mmap_status *status;
+	struct snd_pcm_mmap_control *control;
+
+	/* -- locking / scheduling -- */
+	snd_pcm_uframes_t twake; 	/* do transfer (!poll) wakeup if non-zero */
+	wait_queue_head_t sleep;	/* poll sleep */
+	wait_queue_head_t tsleep;	/* transfer sleep */
+	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;
+
+	/* -- timer -- */
+	unsigned int timer_resolution;	/* timer resolution */
+	int tstamp_type;		/* timestamp type */
+
+	/* -- 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 */
+
+	/* -- audio timestamp config -- */
+	struct snd_pcm_audio_tstamp_config audio_tstamp_config;
+	struct snd_pcm_audio_tstamp_report audio_tstamp_report;
+	struct timespec driver_tstamp;
+
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+	/* -- OSS things -- */
+	struct snd_pcm_oss_runtime oss;
+#endif
+};
+
+struct snd_pcm_group {		/* keep linked substreams */
+	spinlock_t lock;
+	struct mutex mutex;
+	struct list_head substreams;
+	int count;
+};
+
+struct pid;
+
+struct snd_pcm_substream {
+	struct snd_pcm *pcm;
+	struct snd_pcm_str *pstr;
+	void *private_data;		/* copied from pcm->private_data */
+	int number;
+	char name[32];			/* substream name */
+	int stream;			/* stream (direction) */
+	struct pm_qos_request latency_pm_qos_req; /* pm_qos request */
+	size_t buffer_bytes_max;	/* limit ring buffer size */
+	struct snd_dma_buffer dma_buffer;
+	size_t dma_max;
+	/* -- hardware operations -- */
+	const struct snd_pcm_ops *ops;
+	/* -- runtime information -- */
+	struct snd_pcm_runtime *runtime;
+        /* -- timer section -- */
+	struct snd_timer *timer;		/* timer */
+	unsigned timer_running: 1;	/* time is running */
+	/* -- next substream -- */
+	struct snd_pcm_substream *next;
+	/* -- linked substreams -- */
+	struct list_head link_list;	/* linked list member */
+	struct snd_pcm_group self_group;	/* fake group for non linked substream (with substream lock inside) */
+	struct snd_pcm_group *group;		/* pointer to current group */
+	/* -- assigned files -- */
+	void *file;
+	int ref_count;
+	atomic_t mmap_count;
+	unsigned int f_flags;
+	void (*pcm_release)(struct snd_pcm_substream *);
+	struct pid *pid;
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+	/* -- OSS things -- */
+	struct snd_pcm_oss_substream oss;
+#endif
+#ifdef CONFIG_SND_VERBOSE_PROCFS
+	struct snd_info_entry *proc_root;
+	struct snd_info_entry *proc_info_entry;
+	struct snd_info_entry *proc_hw_params_entry;
+	struct snd_info_entry *proc_sw_params_entry;
+	struct snd_info_entry *proc_status_entry;
+	struct snd_info_entry *proc_prealloc_entry;
+	struct snd_info_entry *proc_prealloc_max_entry;
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
+	struct snd_info_entry *proc_xrun_injection_entry;
+#endif
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
+	/* misc flags */
+	unsigned int hw_opened: 1;
+};
+
+#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
+
+
+struct snd_pcm_str {
+	int stream;				/* stream (direction) */
+	struct snd_pcm *pcm;
+	/* -- substreams -- */
+	unsigned int substream_count;
+	unsigned int substream_opened;
+	struct snd_pcm_substream *substream;
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+	/* -- OSS things -- */
+	struct snd_pcm_oss_stream oss;
+#endif
+#ifdef CONFIG_SND_VERBOSE_PROCFS
+	struct snd_info_entry *proc_root;
+	struct snd_info_entry *proc_info_entry;
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
+	unsigned int xrun_debug;	/* 0 = disabled, 1 = verbose, 2 = stacktrace */
+	struct snd_info_entry *proc_xrun_debug_entry;
+#endif
+#endif
+	struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
+	struct device dev;
+};
+
+struct snd_pcm {
+	struct snd_card *card;
+	struct list_head list;
+	int device; /* device number */
+	unsigned int info_flags;
+	unsigned short dev_class;
+	unsigned short dev_subclass;
+	char id[64];
+	char name[80];
+	struct snd_pcm_str streams[2];
+	struct mutex open_mutex;
+	wait_queue_head_t open_wait;
+	void *private_data;
+	void (*private_free) (struct snd_pcm *pcm);
+	bool internal; /* pcm is for internal use only */
+	bool nonatomic; /* whole PCM operations are in non-atomic context */
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+	struct snd_pcm_oss oss;
+#endif
+};
+
+struct snd_pcm_notify {
+	int (*n_register) (struct snd_pcm * pcm);
+	int (*n_disconnect) (struct snd_pcm * pcm);
+	int (*n_unregister) (struct snd_pcm * pcm);
+	struct list_head list;
+};
+
+/*
+ *  Registering
+ */
+
+extern const struct file_operations snd_pcm_f_ops[2];
+
+int snd_pcm_new(struct snd_card *card, const char *id, int device,
+		int playback_count, int capture_count,
+		struct snd_pcm **rpcm);
+int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
+		int playback_count, int capture_count,
+		struct snd_pcm **rpcm);
+int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
+
+int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
+
+/*
+ *  Native I/O
+ */
+
+int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info);
+int snd_pcm_info_user(struct snd_pcm_substream *substream,
+		      struct snd_pcm_info __user *info);
+int snd_pcm_status(struct snd_pcm_substream *substream,
+		   struct snd_pcm_status *status);
+int snd_pcm_start(struct snd_pcm_substream *substream);
+int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status);
+int snd_pcm_drain_done(struct snd_pcm_substream *substream);
+int snd_pcm_stop_xrun(struct snd_pcm_substream *substream);
+#ifdef CONFIG_PM
+int snd_pcm_suspend(struct snd_pcm_substream *substream);
+int snd_pcm_suspend_all(struct snd_pcm *pcm);
+#endif
+int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
+int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, struct file *file,
+			   struct snd_pcm_substream **rsubstream);
+void snd_pcm_release_substream(struct snd_pcm_substream *substream);
+int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, struct file *file,
+			     struct snd_pcm_substream **rsubstream);
+void snd_pcm_detach_substream(struct snd_pcm_substream *substream);
+int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area);
+
+
+#ifdef CONFIG_SND_DEBUG
+void snd_pcm_debug_name(struct snd_pcm_substream *substream,
+			   char *name, size_t len);
+#else
+static inline void
+snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
+{
+	*buf = 0;
+}
+#endif
+
+/*
+ *  PCM library
+ */
+
+/**
+ * snd_pcm_stream_linked - Check whether the substream is linked with others
+ * @substream: substream to check
+ *
+ * Returns true if the given substream is being linked with others.
+ */
+static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream)
+{
+	return substream->group != &substream->self_group;
+}
+
+void snd_pcm_stream_lock(struct snd_pcm_substream *substream);
+void snd_pcm_stream_unlock(struct snd_pcm_substream *substream);
+void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream);
+void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream);
+unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
+
+/**
+ * snd_pcm_stream_lock_irqsave - Lock the PCM stream
+ * @substream: PCM substream
+ * @flags: irq flags
+ *
+ * This locks the PCM stream like snd_pcm_stream_lock() but with the local
+ * IRQ (only when nonatomic is false).  In nonatomic case, this is identical
+ * as snd_pcm_stream_lock().
+ */
+#define snd_pcm_stream_lock_irqsave(substream, flags)		 \
+	do {							 \
+		typecheck(unsigned long, flags);		 \
+		flags = _snd_pcm_stream_lock_irqsave(substream); \
+	} while (0)
+void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
+				      unsigned long flags);
+
+/**
+ * snd_pcm_group_for_each_entry - iterate over the linked substreams
+ * @s: the iterator
+ * @substream: the substream
+ *
+ * Iterate over the all linked substreams to the given @substream.
+ * When @substream isn't linked with any others, this gives returns @substream
+ * itself once.
+ */
+#define snd_pcm_group_for_each_entry(s, substream) \
+	list_for_each_entry(s, &substream->group->substreams, link_list)
+
+/**
+ * snd_pcm_running - Check whether the substream is in a running state
+ * @substream: substream to check
+ *
+ * Returns true if the given substream is in the state RUNNING, or in the
+ * state DRAINING for playback.
+ */
+static inline int snd_pcm_running(struct snd_pcm_substream *substream)
+{
+	return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
+		(substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
+		 substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
+}
+
+/**
+ * bytes_to_samples - Unit conversion of the size from bytes to samples
+ * @runtime: PCM runtime instance
+ * @size: size in bytes
+ */
+static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size)
+{
+	return size * 8 / runtime->sample_bits;
+}
+
+/**
+ * bytes_to_frames - Unit conversion of the size from bytes to frames
+ * @runtime: PCM runtime instance
+ * @size: size in bytes
+ */
+static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size)
+{
+	return size * 8 / runtime->frame_bits;
+}
+
+/**
+ * samples_to_bytes - Unit conversion of the size from samples to bytes
+ * @runtime: PCM runtime instance
+ * @size: size in samples
+ */
+static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size)
+{
+	return size * runtime->sample_bits / 8;
+}
+
+/**
+ * frames_to_bytes - Unit conversion of the size from frames to bytes
+ * @runtime: PCM runtime instance
+ * @size: size in frames
+ */
+static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size)
+{
+	return size * runtime->frame_bits / 8;
+}
+
+/**
+ * frame_aligned - Check whether the byte size is aligned to frames
+ * @runtime: PCM runtime instance
+ * @bytes: size in bytes
+ */
+static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes)
+{
+	return bytes % runtime->byte_align == 0;
+}
+
+/**
+ * snd_pcm_lib_buffer_bytes - Get the buffer size of the current PCM in bytes
+ * @substream: PCM substream
+ */
+static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	return frames_to_bytes(runtime, runtime->buffer_size);
+}
+
+/**
+ * snd_pcm_lib_period_bytes - Get the period size of the current PCM in bytes
+ * @substream: PCM substream
+ */
+static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	return frames_to_bytes(runtime, runtime->period_size);
+}
+
+/**
+ * snd_pcm_playback_avail - Get the available (writable) space for playback
+ * @runtime: PCM runtime instance
+ *
+ * Result is between 0 ... (boundary - 1)
+ */
+static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime)
+{
+	snd_pcm_sframes_t avail = runtime->status->hw_ptr + runtime->buffer_size - runtime->control->appl_ptr;
+	if (avail < 0)
+		avail += runtime->boundary;
+	else if ((snd_pcm_uframes_t) avail >= runtime->boundary)
+		avail -= runtime->boundary;
+	return avail;
+}
+
+/**
+ * snd_pcm_playback_avail - Get the available (readable) space for capture
+ * @runtime: PCM runtime instance
+ *
+ * Result is between 0 ... (boundary - 1)
+ */
+static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime)
+{
+	snd_pcm_sframes_t avail = runtime->status->hw_ptr - runtime->control->appl_ptr;
+	if (avail < 0)
+		avail += runtime->boundary;
+	return avail;
+}
+
+/**
+ * snd_pcm_playback_hw_avail - Get the queued space for playback
+ * @runtime: PCM runtime instance
+ */
+static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime)
+{
+	return runtime->buffer_size - snd_pcm_playback_avail(runtime);
+}
+
+/**
+ * snd_pcm_capture_hw_avail - Get the free space for capture
+ * @runtime: PCM runtime instance
+ */
+static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime)
+{
+	return runtime->buffer_size - snd_pcm_capture_avail(runtime);
+}
+
+/**
+ * snd_pcm_playback_ready - check whether the playback buffer is available
+ * @substream: the pcm substream instance
+ *
+ * Checks whether enough free space is available on the playback buffer.
+ *
+ * Return: Non-zero if available, or zero if not.
+ */
+static inline int snd_pcm_playback_ready(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min;
+}
+
+/**
+ * snd_pcm_capture_ready - check whether the capture buffer is available
+ * @substream: the pcm substream instance
+ *
+ * Checks whether enough capture data is available on the capture buffer.
+ *
+ * Return: Non-zero if available, or zero if not.
+ */
+static inline int snd_pcm_capture_ready(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min;
+}
+
+/**
+ * snd_pcm_playback_data - check whether any data exists on the playback buffer
+ * @substream: the pcm substream instance
+ *
+ * Checks whether any data exists on the playback buffer.
+ *
+ * Return: Non-zero if any data exists, or zero if not. If stop_threshold
+ * is bigger or equal to boundary, then this function returns always non-zero.
+ */
+static inline int snd_pcm_playback_data(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	
+	if (runtime->stop_threshold >= runtime->boundary)
+		return 1;
+	return snd_pcm_playback_avail(runtime) < runtime->buffer_size;
+}
+
+/**
+ * snd_pcm_playback_empty - check whether the playback buffer is empty
+ * @substream: the pcm substream instance
+ *
+ * Checks whether the playback buffer is empty.
+ *
+ * Return: Non-zero if empty, or zero if not.
+ */
+static inline int snd_pcm_playback_empty(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
+}
+
+/**
+ * snd_pcm_capture_empty - check whether the capture buffer is empty
+ * @substream: the pcm substream instance
+ *
+ * Checks whether the capture buffer is empty.
+ *
+ * Return: Non-zero if empty, or zero if not.
+ */
+static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	return snd_pcm_capture_avail(runtime) == 0;
+}
+
+/**
+ * snd_pcm_trigger_done - Mark the master substream
+ * @substream: the pcm substream instance
+ * @master: the linked master substream
+ *
+ * When multiple substreams of the same card are linked and the hardware
+ * supports the single-shot operation, the driver calls this in the loop
+ * in snd_pcm_group_for_each_entry() for marking the substream as "done".
+ * Then most of trigger operations are performed only to the given master
+ * substream.
+ *
+ * The trigger_master mark is cleared at timestamp updates at the end
+ * of trigger operations.
+ */
+static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream, 
+					struct snd_pcm_substream *master)
+{
+	substream->runtime->trigger_master = master;
+}
+
+static inline int hw_is_mask(int var)
+{
+	return var >= SNDRV_PCM_HW_PARAM_FIRST_MASK &&
+		var <= SNDRV_PCM_HW_PARAM_LAST_MASK;
+}
+
+static inline int hw_is_interval(int var)
+{
+	return var >= SNDRV_PCM_HW_PARAM_FIRST_INTERVAL &&
+		var <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL;
+}
+
+static inline struct snd_mask *hw_param_mask(struct snd_pcm_hw_params *params,
+				     snd_pcm_hw_param_t var)
+{
+	return &params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
+}
+
+static inline struct snd_interval *hw_param_interval(struct snd_pcm_hw_params *params,
+					     snd_pcm_hw_param_t var)
+{
+	return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
+}
+
+static inline const struct snd_mask *hw_param_mask_c(const struct snd_pcm_hw_params *params,
+					     snd_pcm_hw_param_t var)
+{
+	return &params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
+}
+
+static inline const struct snd_interval *hw_param_interval_c(const struct snd_pcm_hw_params *params,
+						     snd_pcm_hw_param_t var)
+{
+	return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
+}
+
+/**
+ * params_channels - Get the number of channels from the hw params
+ * @p: hw params
+ */
+static inline unsigned int params_channels(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
+}
+
+/**
+ * params_rate - Get the sample rate from the hw params
+ * @p: hw params
+ */
+static inline unsigned int params_rate(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_RATE)->min;
+}
+
+/**
+ * params_period_size - Get the period size (in frames) from the hw params
+ * @p: hw params
+ */
+static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min;
+}
+
+/**
+ * params_periods - Get the number of periods from the hw params
+ * @p: hw params
+ */
+static inline unsigned int params_periods(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIODS)->min;
+}
+
+/**
+ * params_buffer_size - Get the buffer size (in frames) from the hw params
+ * @p: hw params
+ */
+static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min;
+}
+
+/**
+ * params_buffer_bytes - Get the buffer size (in bytes) from the hw params
+ * @p: hw params
+ */
+static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min;
+}
+
+int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v);
+void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c);
+void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c);
+void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b, 
+			  unsigned int k, struct snd_interval *c);
+void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
+			  const struct snd_interval *b, struct snd_interval *c);
+int snd_interval_list(struct snd_interval *i, unsigned int count,
+		      const unsigned int *list, unsigned int mask);
+int snd_interval_ranges(struct snd_interval *i, unsigned int count,
+			const struct snd_interval *list, unsigned int mask);
+int snd_interval_ratnum(struct snd_interval *i,
+			unsigned int rats_count, const struct snd_ratnum *rats,
+			unsigned int *nump, unsigned int *denp);
+
+void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
+void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var);
+int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
+
+int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
+
+int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream);
+int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream);
+
+int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
+			       u_int32_t mask);
+int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
+				 u_int64_t mask);
+int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
+				 unsigned int min, unsigned int max);
+int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var);
+int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, 
+			       unsigned int cond,
+			       snd_pcm_hw_param_t var,
+			       const struct snd_pcm_hw_constraint_list *l);
+int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime,
+				 unsigned int cond,
+				 snd_pcm_hw_param_t var,
+				 const struct snd_pcm_hw_constraint_ranges *r);
+int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, 
+				  unsigned int cond,
+				  snd_pcm_hw_param_t var,
+				  const struct snd_pcm_hw_constraint_ratnums *r);
+int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, 
+				  unsigned int cond,
+				  snd_pcm_hw_param_t var,
+				  const struct snd_pcm_hw_constraint_ratdens *r);
+int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, 
+				 unsigned int cond,
+				 unsigned int width,
+				 unsigned int msbits);
+int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
+			       unsigned int cond,
+			       snd_pcm_hw_param_t var,
+			       unsigned long step);
+int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
+			       unsigned int cond,
+			       snd_pcm_hw_param_t var);
+int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
+			       unsigned int base_rate);
+int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime,
+			unsigned int cond,
+			int var,
+			snd_pcm_hw_rule_func_t func, void *private,
+			int dep, ...);
+
+/**
+ * snd_pcm_hw_constraint_single() - Constrain parameter to a single value
+ * @runtime: PCM runtime instance
+ * @var: The hw_params variable to constrain
+ * @val: The value to constrain to
+ *
+ * Return: Positive if the value is changed, zero if it's not changed, or a
+ * negative error code.
+ */
+static inline int snd_pcm_hw_constraint_single(
+	struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
+	unsigned int val)
+{
+	return snd_pcm_hw_constraint_minmax(runtime, var, val, val);
+}
+
+int snd_pcm_format_signed(snd_pcm_format_t format);
+int snd_pcm_format_unsigned(snd_pcm_format_t format);
+int snd_pcm_format_linear(snd_pcm_format_t format);
+int snd_pcm_format_little_endian(snd_pcm_format_t format);
+int snd_pcm_format_big_endian(snd_pcm_format_t format);
+#if 0 /* just for DocBook */
+/**
+ * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
+ * @format: the format to check
+ *
+ * Return: 1 if the given PCM format is CPU-endian, 0 if
+ * opposite, or a negative error code if endian not specified.
+ */
+int snd_pcm_format_cpu_endian(snd_pcm_format_t format);
+#endif /* DocBook */
+#ifdef SNDRV_LITTLE_ENDIAN
+#define snd_pcm_format_cpu_endian(format) snd_pcm_format_little_endian(format)
+#else
+#define snd_pcm_format_cpu_endian(format) snd_pcm_format_big_endian(format)
+#endif
+int snd_pcm_format_width(snd_pcm_format_t format);			/* in bits */
+int snd_pcm_format_physical_width(snd_pcm_format_t format);		/* in bits */
+ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
+const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
+int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
+
+void snd_pcm_set_ops(struct snd_pcm * pcm, int direction,
+		     const struct snd_pcm_ops *ops);
+void snd_pcm_set_sync(struct snd_pcm_substream *substream);
+int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
+		      unsigned int cmd, void *arg);                      
+int snd_pcm_update_state(struct snd_pcm_substream *substream,
+			 struct snd_pcm_runtime *runtime);
+int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
+void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr);
+void snd_pcm_period_elapsed(struct snd_pcm_substream *substream);
+snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream,
+				    const void __user *buf,
+				    snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream,
+				   void __user *buf, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
+				     void __user **bufs, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
+				    void __user **bufs, snd_pcm_uframes_t frames);
+
+extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates;
+
+int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime);
+unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate);
+unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
+unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
+					 unsigned int rates_b);
+
+/**
+ * snd_pcm_set_runtime_buffer - Set the PCM runtime buffer
+ * @substream: PCM substream to set
+ * @bufp: the buffer information, NULL to clear
+ *
+ * Copy the buffer information to runtime->dma_buffer when @bufp is non-NULL.
+ * Otherwise it clears the current buffer information.
+ */
+static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
+					      struct snd_dma_buffer *bufp)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	if (bufp) {
+		runtime->dma_buffer_p = bufp;
+		runtime->dma_area = bufp->area;
+		runtime->dma_addr = bufp->addr;
+		runtime->dma_bytes = bufp->bytes;
+	} else {
+		runtime->dma_buffer_p = NULL;
+		runtime->dma_area = NULL;
+		runtime->dma_addr = 0;
+		runtime->dma_bytes = 0;
+	}
+}
+
+/*
+ *  Timer interface
+ */
+
+#ifdef CONFIG_SND_PCM_TIMER
+void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
+void snd_pcm_timer_init(struct snd_pcm_substream *substream);
+void snd_pcm_timer_done(struct snd_pcm_substream *substream);
+#else
+static inline void
+snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) {}
+static inline void snd_pcm_timer_init(struct snd_pcm_substream *substream) {}
+static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {}
+#endif
+/**
+ * snd_pcm_gettime - Fill the timespec depending on the timestamp mode
+ * @runtime: PCM runtime instance
+ * @tv: timespec to fill
+ */
+static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime,
+				   struct timespec *tv)
+{
+	switch (runtime->tstamp_type) {
+	case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
+		ktime_get_ts(tv);
+		break;
+	case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
+		getrawmonotonic(tv);
+		break;
+	default:
+		getnstimeofday(tv);
+		break;
+	}
+}
+
+/*
+ *  Memory
+ */
+
+int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream);
+int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm);
+int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
+				  int type, struct device *data,
+				  size_t size, size_t max);
+int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
+					  int type, void *data,
+					  size_t size, size_t max);
+int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
+int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
+
+int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
+				      size_t size, gfp_t gfp_flags);
+int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream);
+struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
+					  unsigned long offset);
+/**
+ * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer
+ * @substream: the substream to allocate the buffer to
+ * @size: the requested buffer size, in bytes
+ *
+ * Allocates the PCM substream buffer using vmalloc(), i.e., the memory is
+ * contiguous in kernel virtual space, but not in physical memory.  Use this
+ * if the buffer is accessed by kernel code but not by device DMA.
+ *
+ * Return: 1 if the buffer was changed, 0 if not changed, or a negative error
+ * code.
+ */
+static inline int snd_pcm_lib_alloc_vmalloc_buffer
+			(struct snd_pcm_substream *substream, size_t size)
+{
+	return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size,
+						 GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
+}
+
+/**
+ * snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer
+ * @substream: the substream to allocate the buffer to
+ * @size: the requested buffer size, in bytes
+ *
+ * This function works like snd_pcm_lib_alloc_vmalloc_buffer(), but uses
+ * vmalloc_32(), i.e., the pages are allocated from 32-bit-addressable memory.
+ *
+ * Return: 1 if the buffer was changed, 0 if not changed, or a negative error
+ * code.
+ */
+static inline int snd_pcm_lib_alloc_vmalloc_32_buffer
+			(struct snd_pcm_substream *substream, size_t size)
+{
+	return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size,
+						 GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
+}
+
+#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p)
+
+#ifdef CONFIG_SND_DMA_SGBUF
+/*
+ * SG-buffer handling
+ */
+#define snd_pcm_substream_sgbuf(substream) \
+	snd_pcm_get_dma_buf(substream)->private_data
+
+struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
+				    unsigned long offset);
+#else /* !SND_DMA_SGBUF */
+/*
+ * fake using a continuous buffer
+ */
+#define snd_pcm_sgbuf_ops_page	NULL
+#endif /* SND_DMA_SGBUF */
+
+/**
+ * snd_pcm_sgbuf_get_addr - Get the DMA address at the corresponding offset
+ * @substream: PCM substream
+ * @ofs: byte offset
+ */
+static inline dma_addr_t
+snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
+{
+	return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs);
+}
+
+/**
+ * snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset
+ * @substream: PCM substream
+ * @ofs: byte offset
+ */
+static inline void *
+snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
+{
+	return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs);
+}
+
+/**
+ * snd_pcm_sgbuf_chunk_size - Compute the max size that fits within the contig.
+ * page from the given size
+ * @substream: PCM substream
+ * @ofs: byte offset
+ * @size: byte size to examine
+ */
+static inline unsigned int
+snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
+			     unsigned int ofs, unsigned int size)
+{
+	return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size);
+}
+
+/**
+ * snd_pcm_mmap_data_open - increase the mmap counter
+ * @area: VMA
+ *
+ * PCM mmap callback should handle this counter properly
+ */
+static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
+{
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
+	atomic_inc(&substream->mmap_count);
+}
+
+/**
+ * snd_pcm_mmap_data_close - decrease the mmap counter
+ * @area: VMA
+ *
+ * PCM mmap callback should handle this counter properly
+ */
+static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
+{
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
+	atomic_dec(&substream->mmap_count);
+}
+
+int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
+			     struct vm_area_struct *area);
+/* mmap for io-memory area */
+#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
+#define SNDRV_PCM_INFO_MMAP_IOMEM	SNDRV_PCM_INFO_MMAP
+int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area);
+#else
+#define SNDRV_PCM_INFO_MMAP_IOMEM	0
+#define snd_pcm_lib_mmap_iomem	NULL
+#endif
+
+#define snd_pcm_lib_mmap_vmalloc NULL
+
+/**
+ * snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
+ * @dma: DMA number
+ * @max: pointer to store the max size
+ */
+static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
+{
+	*max = dma < 4 ? 64 * 1024 : 128 * 1024;
+}
+
+/*
+ *  Misc
+ */
+
+#define SNDRV_PCM_DEFAULT_CON_SPDIF	(IEC958_AES0_CON_EMPHASIS_NONE|\
+					 (IEC958_AES1_CON_ORIGINAL<<8)|\
+					 (IEC958_AES1_CON_PCM_CODER<<8)|\
+					 (IEC958_AES3_CON_FS_48000<<24))
+
+#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
+
+const char *snd_pcm_format_name(snd_pcm_format_t format);
+
+/**
+ * snd_pcm_stream_str - Get a string naming the direction of a stream
+ * @substream: the pcm substream instance
+ *
+ * Return: A string naming the direction of the stream.
+ */
+static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		return "Playback";
+	else
+		return "Capture";
+}
+
+/*
+ * PCM channel-mapping control API
+ */
+/* array element of channel maps */
+struct snd_pcm_chmap_elem {
+	unsigned char channels;
+	unsigned char map[15];
+};
+
+/* channel map information; retrieved via snd_kcontrol_chip() */
+struct snd_pcm_chmap {
+	struct snd_pcm *pcm;	/* assigned PCM instance */
+	int stream;		/* PLAYBACK or CAPTURE */
+	struct snd_kcontrol *kctl;
+	const struct snd_pcm_chmap_elem *chmap;
+	unsigned int max_channels;
+	unsigned int channel_mask;	/* optional: active channels bitmask */
+	void *private_data;	/* optional: private data pointer */
+};
+
+/**
+ * snd_pcm_chmap_substream - get the PCM substream assigned to the given chmap info
+ * @info: chmap information
+ * @idx: the substream number index
+ */
+static inline struct snd_pcm_substream *
+snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx)
+{
+	struct snd_pcm_substream *s;
+	for (s = info->pcm->streams[info->stream].substream; s; s = s->next)
+		if (s->number == idx)
+			return s;
+	return NULL;
+}
+
+/* ALSA-standard channel maps (RL/RR prior to C/LFE) */
+extern const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[];
+/* Other world's standard channel maps (C/LFE prior to RL/RR) */
+extern const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[];
+
+/* bit masks to be passed to snd_pcm_chmap.channel_mask field */
+#define SND_PCM_CHMAP_MASK_24	((1U << 2) | (1U << 4))
+#define SND_PCM_CHMAP_MASK_246	(SND_PCM_CHMAP_MASK_24 | (1U << 6))
+#define SND_PCM_CHMAP_MASK_2468	(SND_PCM_CHMAP_MASK_246 | (1U << 8))
+
+int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+			   const struct snd_pcm_chmap_elem *chmap,
+			   int max_channels,
+			   unsigned long private_value,
+			   struct snd_pcm_chmap **info_ret);
+
+/**
+ * pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise
+ * @pcm_format: PCM format
+ */
+static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
+{
+	return 1ULL << (__force int) pcm_format;
+}
+
+/* printk helpers */
+#define pcm_err(pcm, fmt, args...) \
+	dev_err((pcm)->card->dev, fmt, ##args)
+#define pcm_warn(pcm, fmt, args...) \
+	dev_warn((pcm)->card->dev, fmt, ##args)
+#define pcm_dbg(pcm, fmt, args...) \
+	dev_dbg((pcm)->card->dev, fmt, ##args)
+
+#endif /* __SOUND_PCM_H */
diff --git a/include/sound/pcm_drm_eld.h b/include/sound/pcm_drm_eld.h
new file mode 100644
index 0000000..93357b2
--- /dev/null
+++ b/include/sound/pcm_drm_eld.h
@@ -0,0 +1,6 @@
+#ifndef __SOUND_PCM_DRM_ELD_H
+#define __SOUND_PCM_DRM_ELD_H
+
+int snd_pcm_hw_constraint_eld(struct snd_pcm_runtime *runtime, void *eld);
+
+#endif
diff --git a/include/sound/pcm_iec958.h b/include/sound/pcm_iec958.h
new file mode 100644
index 0000000..0eed397
--- /dev/null
+++ b/include/sound/pcm_iec958.h
@@ -0,0 +1,9 @@
+#ifndef __SOUND_PCM_IEC958_H
+#define __SOUND_PCM_IEC958_H
+
+#include <linux/types.h>
+
+int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
+	size_t len);
+
+#endif
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
new file mode 100644
index 0000000..760c969
--- /dev/null
+++ b/include/sound/pcm_oss.h
@@ -0,0 +1,89 @@
+#ifndef __SOUND_PCM_OSS_H
+#define __SOUND_PCM_OSS_H
+
+/*
+ *  Digital Audio (PCM) - OSS compatibility abstract layer
+ *  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
+ *
+ */
+
+struct snd_pcm_oss_setup {
+	char *task_name;
+	unsigned int disable:1,
+		     direct:1,
+		     block:1,
+		     nonblock:1,
+		     partialfrag:1,
+		     nosilence:1,
+		     buggyptr:1;
+	unsigned int periods;
+	unsigned int period_size;
+	struct snd_pcm_oss_setup *next;
+};
+
+struct snd_pcm_oss_runtime {
+	unsigned params: 1,			/* format/parameter change */
+		 prepare: 1,			/* need to prepare the operation */
+		 trigger: 1,			/* trigger flag */
+		 sync_trigger: 1;		/* sync trigger flag */
+	int rate;				/* requested rate */
+	int format;				/* requested OSS format */
+	unsigned int channels;			/* requested channels */
+	unsigned int fragshift;
+	unsigned int maxfrags;
+	unsigned int subdivision;		/* requested subdivision */
+	size_t period_bytes;			/* requested period size */
+	size_t period_frames;			/* period frames for poll */
+	size_t period_ptr;			/* actual write pointer to period */
+	unsigned int periods;
+	size_t buffer_bytes;			/* requested buffer size */
+	size_t bytes;				/* total # bytes processed */
+	size_t mmap_bytes;
+	char *buffer;				/* vmallocated period */
+	size_t buffer_used;			/* used length from period buffer */
+	struct mutex params_lock;
+#ifdef CONFIG_SND_PCM_OSS_PLUGINS
+	struct snd_pcm_plugin *plugin_first;
+	struct snd_pcm_plugin *plugin_last;
+#endif
+	unsigned int prev_hw_ptr_period;
+};
+
+struct snd_pcm_oss_file {
+	struct snd_pcm_substream *streams[2];
+};
+
+struct snd_pcm_oss_substream {
+	unsigned oss: 1;			/* oss mode */
+	struct snd_pcm_oss_setup setup;		/* active setup */
+};
+
+struct snd_pcm_oss_stream {
+	struct snd_pcm_oss_setup *setup_list;	/* setup list */
+	struct mutex setup_mutex;
+#ifdef CONFIG_SND_VERBOSE_PROCFS
+	struct snd_info_entry *proc_entry;
+#endif
+};
+
+struct snd_pcm_oss {
+	int reg;
+	unsigned int reg_mask;
+};
+
+#endif /* __SOUND_PCM_OSS_H */
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
new file mode 100644
index 0000000..c704357
--- /dev/null
+++ b/include/sound/pcm_params.h
@@ -0,0 +1,376 @@
+#ifndef __SOUND_PCM_PARAMS_H
+#define __SOUND_PCM_PARAMS_H
+
+/*
+ *  PCM params helpers
+ *  Copyright (c) by Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ *   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 <sound/pcm.h>
+
+int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 
+			   struct snd_pcm_hw_params *params,
+			   snd_pcm_hw_param_t var, int *dir);
+int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 
+			  struct snd_pcm_hw_params *params,
+			  snd_pcm_hw_param_t var, int *dir);
+int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
+			   snd_pcm_hw_param_t var, int *dir);
+
+#define SNDRV_MASK_BITS	64	/* we use so far 64bits only */
+#define SNDRV_MASK_SIZE	(SNDRV_MASK_BITS / 32)
+#define MASK_OFS(i)	((i) >> 5)
+#define MASK_BIT(i)	(1U << ((i) & 31))
+
+static inline size_t snd_mask_sizeof(void)
+{
+	return sizeof(struct snd_mask);
+}
+
+static inline void snd_mask_none(struct snd_mask *mask)
+{
+	memset(mask, 0, sizeof(*mask));
+}
+
+static inline void snd_mask_any(struct snd_mask *mask)
+{
+	memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
+}
+
+static inline int snd_mask_empty(const struct snd_mask *mask)
+{
+	int i;
+	for (i = 0; i < SNDRV_MASK_SIZE; i++)
+		if (mask->bits[i])
+			return 0;
+	return 1;
+}
+
+static inline unsigned int snd_mask_min(const struct snd_mask *mask)
+{
+	int i;
+	for (i = 0; i < SNDRV_MASK_SIZE; i++) {
+		if (mask->bits[i])
+			return __ffs(mask->bits[i]) + (i << 5);
+	}
+	return 0;
+}
+
+static inline unsigned int snd_mask_max(const struct snd_mask *mask)
+{
+	int i;
+	for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
+		if (mask->bits[i])
+			return __fls(mask->bits[i]) + (i << 5);
+	}
+	return 0;
+}
+
+static inline void snd_mask_set(struct snd_mask *mask, unsigned int val)
+{
+	mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
+}
+
+static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val)
+{
+	mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
+}
+
+static inline void snd_mask_set_range(struct snd_mask *mask,
+				      unsigned int from, unsigned int to)
+{
+	unsigned int i;
+	for (i = from; i <= to; i++)
+		mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
+}
+
+static inline void snd_mask_reset_range(struct snd_mask *mask,
+					unsigned int from, unsigned int to)
+{
+	unsigned int i;
+	for (i = from; i <= to; i++)
+		mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
+}
+
+static inline void snd_mask_leave(struct snd_mask *mask, unsigned int val)
+{
+	unsigned int v;
+	v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
+	snd_mask_none(mask);
+	mask->bits[MASK_OFS(val)] = v;
+}
+
+static inline void snd_mask_intersect(struct snd_mask *mask,
+				      const struct snd_mask *v)
+{
+	int i;
+	for (i = 0; i < SNDRV_MASK_SIZE; i++)
+		mask->bits[i] &= v->bits[i];
+}
+
+static inline int snd_mask_eq(const struct snd_mask *mask,
+			      const struct snd_mask *v)
+{
+	return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
+}
+
+static inline void snd_mask_copy(struct snd_mask *mask,
+				 const struct snd_mask *v)
+{
+	*mask = *v;
+}
+
+static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val)
+{
+	return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
+}
+
+static inline int snd_mask_single(const struct snd_mask *mask)
+{
+	int i, c = 0;
+	for (i = 0; i < SNDRV_MASK_SIZE; i++) {
+		if (! mask->bits[i])
+			continue;
+		if (mask->bits[i] & (mask->bits[i] - 1))
+			return 0;
+		if (c)
+			return 0;
+		c++;
+	}
+	return 1;
+}
+
+static inline int snd_mask_refine(struct snd_mask *mask,
+				  const struct snd_mask *v)
+{
+	struct snd_mask old;
+	snd_mask_copy(&old, mask);
+	snd_mask_intersect(mask, v);
+	if (snd_mask_empty(mask))
+		return -EINVAL;
+	return !snd_mask_eq(mask, &old);
+}
+
+static inline int snd_mask_refine_first(struct snd_mask *mask)
+{
+	if (snd_mask_single(mask))
+		return 0;
+	snd_mask_leave(mask, snd_mask_min(mask));
+	return 1;
+}
+
+static inline int snd_mask_refine_last(struct snd_mask *mask)
+{
+	if (snd_mask_single(mask))
+		return 0;
+	snd_mask_leave(mask, snd_mask_max(mask));
+	return 1;
+}
+
+static inline int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
+{
+	if (snd_mask_min(mask) >= val)
+		return 0;
+	snd_mask_reset_range(mask, 0, val - 1);
+	if (snd_mask_empty(mask))
+		return -EINVAL;
+	return 1;
+}
+
+static inline int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
+{
+	if (snd_mask_max(mask) <= val)
+		return 0;
+	snd_mask_reset_range(mask, val + 1, SNDRV_MASK_BITS);
+	if (snd_mask_empty(mask))
+		return -EINVAL;
+	return 1;
+}
+
+static inline int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
+{
+	int changed;
+	changed = !snd_mask_single(mask);
+	snd_mask_leave(mask, val);
+	if (snd_mask_empty(mask))
+		return -EINVAL;
+	return changed;
+}
+
+static inline int snd_mask_value(const struct snd_mask *mask)
+{
+	return snd_mask_min(mask);
+}
+
+static inline void snd_interval_any(struct snd_interval *i)
+{
+	i->min = 0;
+	i->openmin = 0;
+	i->max = UINT_MAX;
+	i->openmax = 0;
+	i->integer = 0;
+	i->empty = 0;
+}
+
+static inline void snd_interval_none(struct snd_interval *i)
+{
+	i->empty = 1;
+}
+
+static inline int snd_interval_checkempty(const struct snd_interval *i)
+{
+	return (i->min > i->max ||
+		(i->min == i->max && (i->openmin || i->openmax)));
+}
+
+static inline int snd_interval_empty(const struct snd_interval *i)
+{
+	return i->empty;
+}
+
+static inline int snd_interval_single(const struct snd_interval *i)
+{
+	return (i->min == i->max || 
+		(i->min + 1 == i->max && i->openmax));
+}
+
+static inline int snd_interval_value(const struct snd_interval *i)
+{
+	return i->min;
+}
+
+static inline int snd_interval_min(const struct snd_interval *i)
+{
+	return i->min;
+}
+
+static inline int snd_interval_max(const struct snd_interval *i)
+{
+	unsigned int v;
+	v = i->max;
+	if (i->openmax)
+		v--;
+	return v;
+}
+
+static inline int snd_interval_test(const struct snd_interval *i, unsigned int val)
+{
+	return !((i->min > val || (i->min == val && i->openmin) ||
+		  i->max < val || (i->max == val && i->openmax)));
+}
+
+static inline void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s)
+{
+	*d = *s;
+}
+
+static inline int snd_interval_setinteger(struct snd_interval *i)
+{
+	if (i->integer)
+		return 0;
+	if (i->openmin && i->openmax && i->min == i->max)
+		return -EINVAL;
+	i->integer = 1;
+	return 1;
+}
+
+static inline int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2)
+{
+	if (i1->empty)
+		return i2->empty;
+	if (i2->empty)
+		return i1->empty;
+	return i1->min == i2->min && i1->openmin == i2->openmin &&
+		i1->max == i2->max && i1->openmax == i2->openmax;
+}
+
+/**
+ * params_access - get the access type from the hw params
+ * @p: hw params
+ */
+static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p)
+{
+	return (__force snd_pcm_access_t)snd_mask_min(hw_param_mask_c(p,
+		SNDRV_PCM_HW_PARAM_ACCESS));
+}
+
+/**
+ * params_format - get the sample format from the hw params
+ * @p: hw params
+ */
+static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p)
+{
+	return (__force snd_pcm_format_t)snd_mask_min(hw_param_mask_c(p,
+		SNDRV_PCM_HW_PARAM_FORMAT));
+}
+
+/**
+ * params_subformat - get the sample subformat from the hw params
+ * @p: hw params
+ */
+static inline snd_pcm_subformat_t
+params_subformat(const struct snd_pcm_hw_params *p)
+{
+	return (__force snd_pcm_subformat_t)snd_mask_min(hw_param_mask_c(p,
+		SNDRV_PCM_HW_PARAM_SUBFORMAT));
+}
+
+/**
+ * params_period_bytes - get the period size (in bytes) from the hw params
+ * @p: hw params
+ */
+static inline unsigned int
+params_period_bytes(const struct snd_pcm_hw_params *p)
+{
+	return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_BYTES)->min;
+}
+
+/**
+ * params_width - get the number of bits of the sample format from the hw params
+ * @p: hw params
+ *
+ * This function returns the number of bits per sample that the selected sample
+ * format of the hw params has.
+ */
+static inline int params_width(const struct snd_pcm_hw_params *p)
+{
+	return snd_pcm_format_width(params_format(p));
+}
+
+/*
+ * params_physical_width - get the storage size of the sample format from the hw params
+ * @p: hw params
+ *
+ * This functions returns the number of bits per sample that the selected sample
+ * format of the hw params takes up in memory. This will be equal or larger than
+ * params_width().
+ */
+static inline int params_physical_width(const struct snd_pcm_hw_params *p)
+{
+	return snd_pcm_format_physical_width(params_format(p));
+}
+
+static inline void
+params_set_format(struct snd_pcm_hw_params *p, snd_pcm_format_t fmt)
+{
+	snd_mask_set(hw_param_mask(p, SNDRV_PCM_HW_PARAM_FORMAT),
+		(__force int)fmt);
+}
+
+#endif /* __SOUND_PCM_PARAMS_H */
diff --git a/include/sound/pt2258.h b/include/sound/pt2258.h
new file mode 100644
index 0000000..160f812
--- /dev/null
+++ b/include/sound/pt2258.h
@@ -0,0 +1,37 @@
+/*
+ *   ALSA Driver for the PT2258 volume controller.
+ *
+ *	Copyright (c) 2006  Jochen Voss <voss@seehuhn.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */      
+
+#ifndef __SOUND_PT2258_H
+#define __SOUND_PT2258_H
+
+struct snd_pt2258 {
+	struct snd_card *card;
+	struct snd_i2c_bus *i2c_bus;
+	struct snd_i2c_device *i2c_dev;
+
+	unsigned char volume[6];
+	int mute;
+};
+
+extern int snd_pt2258_reset(struct snd_pt2258 *pt);
+extern int snd_pt2258_build_controls(struct snd_pt2258 *pt);
+
+#endif /* __SOUND_PT2258_H */
diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h
new file mode 100644
index 0000000..6ef629b
--- /dev/null
+++ b/include/sound/pxa2xx-lib.h
@@ -0,0 +1,37 @@
+#ifndef PXA2XX_LIB_H
+#define PXA2XX_LIB_H
+
+#include <linux/platform_device.h>
+#include <sound/ac97_codec.h>
+
+/* PCM */
+
+extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params);
+extern int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
+extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
+extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream);
+extern int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
+extern int __pxa2xx_pcm_open(struct snd_pcm_substream *substream);
+extern int __pxa2xx_pcm_close(struct snd_pcm_substream *substream);
+extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
+	struct vm_area_struct *vma);
+extern int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream);
+extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
+
+/* AC97 */
+
+extern unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
+extern void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
+
+extern bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97);
+extern bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97);
+extern void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97);
+
+extern int pxa2xx_ac97_hw_suspend(void);
+extern int pxa2xx_ac97_hw_resume(void);
+
+extern int pxa2xx_ac97_hw_probe(struct platform_device *dev);
+extern void pxa2xx_ac97_hw_remove(struct platform_device *dev);
+
+#endif
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
new file mode 100644
index 0000000..3b91ad5
--- /dev/null
+++ b/include/sound/rawmidi.h
@@ -0,0 +1,193 @@
+#ifndef __SOUND_RAWMIDI_H
+#define __SOUND_RAWMIDI_H
+
+/*
+ *  Abstract layer for MIDI v1.0 stream
+ *  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
+ *
+ */
+
+#include <sound/asound.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#include <sound/seq_device.h>
+#endif
+
+/*
+ *  Raw MIDI interface
+ */
+
+#define SNDRV_RAWMIDI_DEVICES		8
+
+#define SNDRV_RAWMIDI_LFLG_OUTPUT	(1<<0)
+#define SNDRV_RAWMIDI_LFLG_INPUT	(1<<1)
+#define SNDRV_RAWMIDI_LFLG_OPEN		(3<<0)
+#define SNDRV_RAWMIDI_LFLG_APPEND	(1<<2)
+
+struct snd_rawmidi;
+struct snd_rawmidi_substream;
+struct snd_seq_port_info;
+struct pid;
+
+struct snd_rawmidi_ops {
+	int (*open) (struct snd_rawmidi_substream * substream);
+	int (*close) (struct snd_rawmidi_substream * substream);
+	void (*trigger) (struct snd_rawmidi_substream * substream, int up);
+	void (*drain) (struct snd_rawmidi_substream * substream);
+};
+
+struct snd_rawmidi_global_ops {
+	int (*dev_register) (struct snd_rawmidi * rmidi);
+	int (*dev_unregister) (struct snd_rawmidi * rmidi);
+	void (*get_port_info)(struct snd_rawmidi *rmidi, int number,
+			      struct snd_seq_port_info *info);
+};
+
+struct snd_rawmidi_runtime {
+	struct snd_rawmidi_substream *substream;
+	unsigned int drain: 1,	/* drain stage */
+		     oss: 1;	/* OSS compatible mode */
+	/* midi stream buffer */
+	unsigned char *buffer;	/* buffer for MIDI data */
+	size_t buffer_size;	/* size of buffer */
+	size_t appl_ptr;	/* application pointer */
+	size_t hw_ptr;		/* hardware pointer */
+	size_t avail_min;	/* min avail for wakeup */
+	size_t avail;		/* max used buffer for wakeup */
+	size_t xruns;		/* over/underruns counter */
+	/* misc */
+	spinlock_t lock;
+	wait_queue_head_t sleep;
+	/* event handler (new bytes, input only) */
+	void (*event)(struct snd_rawmidi_substream *substream);
+	/* defers calls to event [input] or ops->trigger [output] */
+	struct work_struct event_work;
+	/* private data */
+	void *private_data;
+	void (*private_free)(struct snd_rawmidi_substream *substream);
+};
+
+struct snd_rawmidi_substream {
+	struct list_head list;		/* list of all substream for given stream */
+	int stream;			/* direction */
+	int number;			/* substream number */
+	unsigned int opened: 1,		/* open flag */
+		     append: 1,		/* append flag (merge more streams) */
+		     active_sensing: 1; /* send active sensing when close */
+	int use_count;			/* use counter (for output) */
+	size_t bytes;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_str *pstr;
+	char name[32];
+	struct snd_rawmidi_runtime *runtime;
+	struct pid *pid;
+	/* hardware layer */
+	struct snd_rawmidi_ops *ops;
+};
+
+struct snd_rawmidi_file {
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *input;
+	struct snd_rawmidi_substream *output;
+};
+
+struct snd_rawmidi_str {
+	unsigned int substream_count;
+	unsigned int substream_opened;
+	struct list_head substreams;
+};
+
+struct snd_rawmidi {
+	struct snd_card *card;
+	struct list_head list;
+	unsigned int device;		/* device number */
+	unsigned int info_flags;	/* SNDRV_RAWMIDI_INFO_XXXX */
+	char id[64];
+	char name[80];
+
+#ifdef CONFIG_SND_OSSEMUL
+	int ossreg;
+#endif
+
+	struct snd_rawmidi_global_ops *ops;
+
+	struct snd_rawmidi_str streams[2];
+
+	void *private_data;
+	void (*private_free) (struct snd_rawmidi *rmidi);
+
+	struct mutex open_mutex;
+	wait_queue_head_t open_wait;
+
+	struct device dev;
+
+	struct snd_info_entry *proc_entry;
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+	struct snd_seq_device *seq_dev;
+#endif
+};
+
+/* main rawmidi functions */
+
+int snd_rawmidi_new(struct snd_card *card, char *id, int device,
+		    int output_count, int input_count,
+		    struct snd_rawmidi **rmidi);
+void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
+			 struct snd_rawmidi_ops *ops);
+
+/* callbacks */
+
+int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
+			const unsigned char *buffer, int count);
+int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count);
+int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
+int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
+			 unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream,
+			       int count);
+
+/* main midi functions */
+
+int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info);
+int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
+			    int mode, struct snd_rawmidi_file *rfile);
+int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile);
+int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
+			      struct snd_rawmidi_params *params);
+int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
+			     struct snd_rawmidi_params *params);
+int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream);
+long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
+			     unsigned char *buf, long count);
+long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
+			      const unsigned char *buf, long count);
+
+#endif /* __SOUND_RAWMIDI_H */
diff --git a/include/sound/rt286.h b/include/sound/rt286.h
new file mode 100644
index 0000000..eb773d1
--- /dev/null
+++ b/include/sound/rt286.h
@@ -0,0 +1,19 @@
+/*
+ * linux/sound/rt286.h -- Platform data for RT286
+ *
+ * Copyright 2013 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT286_H
+#define __LINUX_SND_RT286_H
+
+struct rt286_platform_data {
+	bool cbj_en; /*combo jack enable*/
+	bool gpio2_en; /*GPIO2 enable*/
+};
+
+#endif
diff --git a/include/sound/rt298.h b/include/sound/rt298.h
new file mode 100644
index 0000000..7fffeaa
--- /dev/null
+++ b/include/sound/rt298.h
@@ -0,0 +1,20 @@
+/*
+ * linux/sound/rt286.h -- Platform data for RT286
+ *
+ * Copyright 2013 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT298_H
+#define __LINUX_SND_RT298_H
+
+struct rt298_platform_data {
+	bool cbj_en; /*combo jack enable*/
+	bool gpio2_en; /*GPIO2 enable*/
+	bool suspend_power_off; /* power is off during suspend */
+};
+
+#endif
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
new file mode 100644
index 0000000..e3c84b9
--- /dev/null
+++ b/include/sound/rt5640.h
@@ -0,0 +1,27 @@
+/*
+ * linux/sound/rt5640.h -- Platform data for RT5640
+ *
+ * Copyright 2011 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5640_H
+#define __LINUX_SND_RT5640_H
+
+struct rt5640_platform_data {
+	/* IN1 & IN2 & IN3 can optionally be differential */
+	bool in1_diff;
+	bool in2_diff;
+	bool in3_diff;
+
+	bool dmic_en;
+	bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
+	bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
+
+	int ldo1_en; /* GPIO for LDO1_EN */
+};
+
+#endif
diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h
new file mode 100644
index 0000000..a5cf615
--- /dev/null
+++ b/include/sound/rt5645.h
@@ -0,0 +1,28 @@
+/*
+ * linux/sound/rt5645.h -- Platform data for RT5645
+ *
+ * Copyright 2013 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5645_H
+#define __LINUX_SND_RT5645_H
+
+struct rt5645_platform_data {
+	/* IN2 can optionally be differential */
+	bool in2_diff;
+
+	unsigned int dmic1_data_pin;
+	/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
+	unsigned int dmic2_data_pin;
+	/* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
+
+	unsigned int jd_mode;
+	/* Invert JD when jack insert */
+	bool jd_invert;
+};
+
+#endif
diff --git a/include/sound/rt5651.h b/include/sound/rt5651.h
new file mode 100644
index 0000000..d35de75
--- /dev/null
+++ b/include/sound/rt5651.h
@@ -0,0 +1,21 @@
+/*
+ * linux/sound/rt286.h -- Platform data for RT286
+ *
+ * Copyright 2013 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5651_H
+#define __LINUX_SND_RT5651_H
+
+struct rt5651_platform_data {
+	/* IN2 can optionally be differential */
+	bool in2_diff;
+
+	bool dmic_en;
+};
+
+#endif
diff --git a/include/sound/rt5670.h b/include/sound/rt5670.h
new file mode 100644
index 0000000..b7d6051
--- /dev/null
+++ b/include/sound/rt5670.h
@@ -0,0 +1,28 @@
+/*
+ * linux/sound/rt5670.h -- Platform data for RT5670
+ *
+ * Copyright 2014 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5670_H
+#define __LINUX_SND_RT5670_H
+
+struct rt5670_platform_data {
+	int jd_mode;
+	bool in2_diff;
+	bool dev_gpio;
+
+	bool dmic_en;
+	unsigned int dmic1_data_pin;
+	/* 0 = GPIO6; 1 = IN2P; 3 = GPIO7*/
+	unsigned int dmic2_data_pin;
+	/* 0 = GPIO8; 1 = IN3N; */
+	unsigned int dmic3_data_pin;
+	/* 0 = GPIO9; 1 = GPIO10; 2 = GPIO5*/
+};
+
+#endif
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
new file mode 100644
index 0000000..a620704
--- /dev/null
+++ b/include/sound/rt5677.h
@@ -0,0 +1,45 @@
+/*
+ * linux/sound/rt5677.h -- Platform data for RT5677
+ *
+ * Copyright 2013 Realtek Semiconductor Corp.
+ * Author: Oder Chiou <oder_chiou@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5677_H
+#define __LINUX_SND_RT5677_H
+
+enum rt5677_dmic2_clk {
+	RT5677_DMIC_CLK1 = 0,
+	RT5677_DMIC_CLK2 = 1,
+};
+
+
+struct rt5677_platform_data {
+	/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
+	bool in1_diff;
+	bool in2_diff;
+	bool lout1_diff;
+	bool lout2_diff;
+	bool lout3_diff;
+	/* DMIC2 clock source selection */
+	enum rt5677_dmic2_clk dmic2_clk_pin;
+
+	/* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */
+	u8 gpio_config[6];
+
+	/* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */
+	unsigned int jd1_gpio;
+	/* jd2 and jd3 can select 0 ~ 3 as
+		OFF, GPIO4, GPIO5 and GPIO6 respectively */
+	unsigned int jd2_gpio;
+	unsigned int jd3_gpio;
+
+	/* Set MICBIAS1 VDD 1v8 or 3v3 */
+	bool micbias1_vdd_3v3;
+};
+
+#endif
diff --git a/include/sound/s3c24xx_uda134x.h b/include/sound/s3c24xx_uda134x.h
new file mode 100644
index 0000000..33df4cb
--- /dev/null
+++ b/include/sound/s3c24xx_uda134x.h
@@ -0,0 +1,14 @@
+#ifndef _S3C24XX_UDA134X_H_
+#define _S3C24XX_UDA134X_H_ 1
+
+#include <sound/uda134x.h>
+
+struct s3c24xx_uda134x_platform_data {
+	int l3_clk;
+	int l3_mode;
+	int l3_data;
+	void (*power) (int);
+	int model;
+};
+
+#endif
diff --git a/include/sound/sb.h b/include/sound/sb.h
new file mode 100644
index 0000000..bacefae
--- /dev/null
+++ b/include/sound/sb.h
@@ -0,0 +1,375 @@
+#ifndef __SOUND_SB_H
+#define __SOUND_SB_H
+
+/*
+ *  Header file for SoundBlaster cards
+ *  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
+ *
+ */
+
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+enum sb_hw_type {
+	SB_HW_AUTO,
+	SB_HW_10,
+	SB_HW_20,
+	SB_HW_201,
+	SB_HW_PRO,
+	SB_HW_JAZZ16,		/* Media Vision Jazz16 */
+	SB_HW_16,
+	SB_HW_16CSP,		/* SB16 with CSP chip */
+	SB_HW_ALS100,		/* Avance Logic ALS100 chip */
+	SB_HW_ALS4000,		/* Avance Logic ALS4000 chip */
+	SB_HW_DT019X,		/* Diamond Tech. DT-019X / Avance Logic ALS-007 */
+	SB_HW_CS5530,		/* Cyrix/NatSemi 5530 VSA1 */
+};
+
+#define SB_OPEN_PCM			0x01
+#define SB_OPEN_MIDI_INPUT		0x02
+#define SB_OPEN_MIDI_OUTPUT		0x04
+#define SB_OPEN_MIDI_INPUT_TRIGGER	0x08
+#define SB_OPEN_MIDI_OUTPUT_TRIGGER	0x10
+
+#define SB_MODE_HALT		0x00
+#define SB_MODE_PLAYBACK_8	0x01
+#define SB_MODE_PLAYBACK_16	0x02
+#define SB_MODE_PLAYBACK	(SB_MODE_PLAYBACK_8 | SB_MODE_PLAYBACK_16)
+#define SB_MODE_CAPTURE_8	0x04
+#define SB_MODE_CAPTURE_16	0x08
+#define SB_MODE_CAPTURE		(SB_MODE_CAPTURE_8 | SB_MODE_CAPTURE_16)
+
+#define SB_RATE_LOCK_PLAYBACK	0x10
+#define SB_RATE_LOCK_CAPTURE	0x20
+#define SB_RATE_LOCK		(SB_RATE_LOCK_PLAYBACK | SB_RATE_LOCK_CAPTURE)
+
+#define SB_MPU_INPUT		1
+
+struct snd_sb {
+	unsigned long port;		/* base port of DSP chip */
+	struct resource *res_port;
+	unsigned long mpu_port;		/* MPU port for SB DSP 4.0+ */
+	int irq;			/* IRQ number of DSP chip */
+	int dma8;			/* 8-bit DMA */
+	int dma16;			/* 16-bit DMA */
+	unsigned short version;		/* version of DSP chip */
+	enum sb_hw_type hardware;	/* see to SB_HW_XXXX */
+
+	unsigned long alt_port;		/* alternate port (ALS4000) */
+	struct pci_dev *pci;		/* ALS4000 */
+
+	unsigned int open;		/* see to SB_OPEN_XXXX for sb8 */
+					/* also SNDRV_SB_CSP_MODE_XXX for sb16_csp */
+	unsigned int mode;		/* current mode of stream */
+	unsigned int force_mode16;	/* force 16-bit mode of streams */
+	unsigned int locked_rate;	/* sb16 duplex */
+	unsigned int playback_format;
+	unsigned int capture_format;
+	struct timer_list midi_timer;
+	unsigned int p_dma_size;
+	unsigned int p_period_size;
+	unsigned int c_dma_size;
+	unsigned int c_period_size;
+
+	spinlock_t mixer_lock;
+
+	char name[32];
+
+	void *csp; /* used only when CONFIG_SND_SB16_CSP is set */
+
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_substream_input;
+	struct snd_rawmidi_substream *midi_substream_output;
+	irq_handler_t rmidi_callback;
+
+	spinlock_t reg_lock;
+	spinlock_t open_lock;
+	spinlock_t midi_input_lock;
+
+	struct snd_info_entry *proc_entry;
+
+#ifdef CONFIG_PM
+	unsigned char saved_regs[0x20];
+#endif
+};
+
+/* I/O ports */
+
+#define SBP(chip, x)		((chip)->port + s_b_SB_##x)
+#define SBP1(port, x)		((port) + s_b_SB_##x)
+
+#define s_b_SB_RESET		0x6
+#define s_b_SB_READ		0xa
+#define s_b_SB_WRITE		0xc
+#define s_b_SB_COMMAND		0xc
+#define s_b_SB_STATUS		0xc
+#define s_b_SB_DATA_AVAIL	0xe
+#define s_b_SB_DATA_AVAIL_16 	0xf
+#define s_b_SB_MIXER_ADDR	0x4
+#define s_b_SB_MIXER_DATA	0x5
+#define s_b_SB_OPL3_LEFT	0x0
+#define s_b_SB_OPL3_RIGHT	0x2
+#define s_b_SB_OPL3_BOTH	0x8
+
+#define SB_DSP_OUTPUT		0x14
+#define SB_DSP_INPUT		0x24
+#define SB_DSP_BLOCK_SIZE	0x48
+#define SB_DSP_HI_OUTPUT	0x91
+#define SB_DSP_HI_INPUT		0x99
+#define SB_DSP_LO_OUTPUT_AUTO	0x1c
+#define SB_DSP_LO_INPUT_AUTO	0x2c
+#define SB_DSP_HI_OUTPUT_AUTO	0x90
+#define SB_DSP_HI_INPUT_AUTO	0x98
+#define SB_DSP_IMMED_INT	0xf2
+#define SB_DSP_GET_VERSION	0xe1
+#define SB_DSP_SPEAKER_ON	0xd1
+#define SB_DSP_SPEAKER_OFF	0xd3
+#define SB_DSP_DMA8_OFF		0xd0
+#define SB_DSP_DMA8_ON		0xd4
+#define SB_DSP_DMA8_EXIT	0xda
+#define SB_DSP_DMA16_OFF	0xd5
+#define SB_DSP_DMA16_ON		0xd6
+#define SB_DSP_DMA16_EXIT	0xd9
+#define SB_DSP_SAMPLE_RATE	0x40
+#define SB_DSP_SAMPLE_RATE_OUT	0x41
+#define SB_DSP_SAMPLE_RATE_IN	0x42
+#define SB_DSP_MONO_8BIT	0xa0
+#define SB_DSP_MONO_16BIT	0xa4
+#define SB_DSP_STEREO_8BIT	0xa8
+#define SB_DSP_STEREO_16BIT	0xac
+
+#define SB_DSP_MIDI_INPUT_IRQ	0x31
+#define SB_DSP_MIDI_UART_IRQ	0x35
+#define SB_DSP_MIDI_OUTPUT	0x38
+
+#define SB_DSP4_OUT8_AI		0xc6
+#define SB_DSP4_IN8_AI		0xce
+#define SB_DSP4_OUT16_AI	0xb6
+#define SB_DSP4_IN16_AI		0xbe
+#define SB_DSP4_MODE_UNS_MONO	0x00
+#define SB_DSP4_MODE_SIGN_MONO	0x10
+#define SB_DSP4_MODE_UNS_STEREO	0x20
+#define SB_DSP4_MODE_SIGN_STEREO 0x30
+
+#define SB_DSP4_OUTPUT		0x3c
+#define SB_DSP4_INPUT_LEFT	0x3d
+#define SB_DSP4_INPUT_RIGHT	0x3e
+
+/* registers for SB 2.0 mixer */
+#define SB_DSP20_MASTER_DEV	0x02
+#define SB_DSP20_PCM_DEV	0x0A
+#define SB_DSP20_CD_DEV		0x08
+#define SB_DSP20_FM_DEV		0x06
+
+/* registers for SB PRO mixer */
+#define SB_DSP_MASTER_DEV	0x22
+#define SB_DSP_PCM_DEV		0x04
+#define SB_DSP_LINE_DEV		0x2e
+#define SB_DSP_CD_DEV		0x28
+#define SB_DSP_FM_DEV		0x26
+#define SB_DSP_MIC_DEV		0x0a
+#define SB_DSP_CAPTURE_SOURCE	0x0c
+#define SB_DSP_CAPTURE_FILT	0x0c
+#define SB_DSP_PLAYBACK_FILT	0x0e
+#define SB_DSP_STEREO_SW	0x0e
+
+#define SB_DSP_MIXS_MIC0	0x00	/* same as MIC */
+#define SB_DSP_MIXS_CD		0x01
+#define SB_DSP_MIXS_MIC		0x02
+#define SB_DSP_MIXS_LINE	0x03
+
+/* registers (only for left channel) for SB 16 mixer */
+#define SB_DSP4_MASTER_DEV	0x30
+#define SB_DSP4_BASS_DEV	0x46
+#define SB_DSP4_TREBLE_DEV	0x44
+#define SB_DSP4_SYNTH_DEV	0x34
+#define SB_DSP4_PCM_DEV		0x32
+#define SB_DSP4_SPEAKER_DEV	0x3b
+#define SB_DSP4_LINE_DEV	0x38
+#define SB_DSP4_MIC_DEV		0x3a
+#define SB_DSP4_OUTPUT_SW	0x3c
+#define SB_DSP4_CD_DEV		0x36
+#define SB_DSP4_IGAIN_DEV	0x3f
+#define SB_DSP4_OGAIN_DEV	0x41
+#define SB_DSP4_MIC_AGC		0x43
+
+/* additional registers for SB 16 mixer */
+#define SB_DSP4_IRQSETUP	0x80
+#define SB_DSP4_DMASETUP	0x81
+#define SB_DSP4_IRQSTATUS	0x82
+#define SB_DSP4_MPUSETUP	0x84
+
+#define SB_DSP4_3DSE		0x90
+
+/* Registers for DT-019x / ALS-007 mixer */
+#define SB_DT019X_MASTER_DEV	0x62
+#define SB_DT019X_PCM_DEV	0x64
+#define SB_DT019X_SYNTH_DEV	0x66
+#define SB_DT019X_CD_DEV	0x68
+#define SB_DT019X_MIC_DEV	0x6a
+#define SB_DT019X_SPKR_DEV	0x6a
+#define SB_DT019X_LINE_DEV	0x6e
+#define SB_DT019X_OUTPUT_SW2	0x4c
+#define SB_DT019X_CAPTURE_SW	0x6c
+
+#define SB_DT019X_CAP_CD	0x02
+#define SB_DT019X_CAP_MIC	0x04
+#define SB_DT019X_CAP_LINE	0x06
+#define SB_DT019X_CAP_SYNTH	0x07
+#define SB_DT019X_CAP_MAIN	0x07
+
+#define SB_ALS4000_MONO_IO_CTRL	0x4b
+#define SB_ALS4000_OUT_MIXER_CTRL_2	0x4c
+#define SB_ALS4000_MIC_IN_GAIN	0x4d
+#define SB_ALS4000_ANALOG_REFRNC_VOLT_CTRL 0x4e
+#define SB_ALS4000_FMDAC	0x4f
+#define SB_ALS4000_3D_SND_FX	0x50
+#define SB_ALS4000_3D_TIME_DELAY	0x51
+#define SB_ALS4000_3D_AUTO_MUTE	0x52
+#define SB_ALS4000_ANALOG_BLOCK_CTRL 0x53
+#define SB_ALS4000_3D_DELAYLINE_PATTERN 0x54
+#define SB_ALS4000_CR3_CONFIGURATION	0xc3 /* bit 7 is Digital Loop Enable */
+#define SB_ALS4000_QSOUND	0xdb
+
+/* IRQ setting bitmap */
+#define SB_IRQSETUP_IRQ9	0x01
+#define SB_IRQSETUP_IRQ5	0x02
+#define SB_IRQSETUP_IRQ7	0x04
+#define SB_IRQSETUP_IRQ10	0x08
+
+/* IRQ types */
+#define SB_IRQTYPE_8BIT		0x01
+#define SB_IRQTYPE_16BIT	0x02
+#define SB_IRQTYPE_MPUIN	0x04
+#define ALS4K_IRQTYPE_CR1E_DMA	0x20
+
+/* DMA setting bitmap */
+#define SB_DMASETUP_DMA0	0x01
+#define SB_DMASETUP_DMA1	0x02
+#define SB_DMASETUP_DMA3	0x08
+#define SB_DMASETUP_DMA5	0x20
+#define SB_DMASETUP_DMA6	0x40
+#define SB_DMASETUP_DMA7	0x80
+
+/*
+ *
+ */
+
+static inline void snd_sb_ack_8bit(struct snd_sb *chip)
+{
+	inb(SBP(chip, DATA_AVAIL));
+}
+
+static inline void snd_sb_ack_16bit(struct snd_sb *chip)
+{
+	inb(SBP(chip, DATA_AVAIL_16));
+}
+
+/* sb_common.c */
+int snd_sbdsp_command(struct snd_sb *chip, unsigned char val);
+int snd_sbdsp_get_byte(struct snd_sb *chip);
+int snd_sbdsp_reset(struct snd_sb *chip);
+int snd_sbdsp_create(struct snd_card *card,
+		     unsigned long port,
+		     int irq,
+		     irq_handler_t irq_handler,
+		     int dma8, int dma16,
+		     unsigned short hardware,
+		     struct snd_sb **r_chip);
+/* sb_mixer.c */
+void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data);
+unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg);
+int snd_sbmixer_new(struct snd_sb *chip);
+#ifdef CONFIG_PM
+void snd_sbmixer_suspend(struct snd_sb *chip);
+void snd_sbmixer_resume(struct snd_sb *chip);
+#endif
+
+/* sb8_init.c */
+int snd_sb8dsp_pcm(struct snd_sb *chip, int device);
+/* sb8.c */
+irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip);
+int snd_sb8_playback_open(struct snd_pcm_substream *substream);
+int snd_sb8_capture_open(struct snd_pcm_substream *substream);
+int snd_sb8_playback_close(struct snd_pcm_substream *substream);
+int snd_sb8_capture_close(struct snd_pcm_substream *substream);
+/* midi8.c */
+irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip);
+int snd_sb8dsp_midi(struct snd_sb *chip, int device);
+
+/* sb16_init.c */
+int snd_sb16dsp_pcm(struct snd_sb *chip, int device);
+const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction);
+int snd_sb16dsp_configure(struct snd_sb *chip);
+/* sb16.c */
+irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id);
+
+/* exported mixer stuffs */
+enum {
+	SB_MIX_SINGLE,
+	SB_MIX_DOUBLE,
+	SB_MIX_INPUT_SW,
+	SB_MIX_CAPTURE_PRO,
+	SB_MIX_CAPTURE_DT019X,
+	SB_MIX_MONO_CAPTURE_ALS4K
+};
+
+#define SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) \
+  ((left_reg) | ((right_reg) << 8) | ((left_shift) << 16) | ((right_shift) << 19) | ((mask) << 24))
+#define SB_MIXVAL_SINGLE(reg, shift, mask) \
+  ((reg) | ((shift) << 16) | ((mask) << 24))
+#define SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) \
+  ((reg1) | ((reg2) << 8) | ((left_shift) << 16) | ((right_shift) << 24))
+
+int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int type, unsigned long value);
+
+/* for ease of use */
+struct sbmix_elem {
+	const char *name;
+	int type;
+	unsigned long private_value;
+};
+
+#define SB_SINGLE(xname, reg, shift, mask) \
+{ .name = xname, \
+  .type = SB_MIX_SINGLE, \
+  .private_value = SB_MIXVAL_SINGLE(reg, shift, mask) }
+
+#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \
+{ .name = xname, \
+  .type = SB_MIX_DOUBLE, \
+  .private_value = SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) }
+
+#define SB16_INPUT_SW(xname, reg1, reg2, left_shift, right_shift) \
+{ .name = xname, \
+  .type = SB_MIX_INPUT_SW, \
+  .private_value = SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) }
+
+static inline int snd_sbmixer_add_ctl_elem(struct snd_sb *chip, const struct sbmix_elem *c)
+{
+	return snd_sbmixer_add_ctl(chip, c->name, 0, c->type, c->private_value);
+}
+
+#endif /* __SOUND_SB_H */
diff --git a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h
new file mode 100644
index 0000000..c7c7788
--- /dev/null
+++ b/include/sound/sb16_csp.h
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
+ *                        Takashi Iwai <tiwai@suse.de>
+ *
+ *  SB16ASP/AWE32 CSP control
+ *
+ *   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
+ *
+ */
+#ifndef __SOUND_SB16_CSP_H
+#define __SOUND_SB16_CSP_H
+
+#include <sound/sb.h>
+#include <sound/hwdep.h>
+#include <linux/firmware.h>
+#include <uapi/sound/sb16_csp.h>
+
+struct snd_sb_csp;
+
+/* indices for the known CSP programs */
+enum {
+	CSP_PROGRAM_MULAW,
+	CSP_PROGRAM_ALAW,
+	CSP_PROGRAM_ADPCM_INIT,
+	CSP_PROGRAM_ADPCM_PLAYBACK,
+	CSP_PROGRAM_ADPCM_CAPTURE,
+
+	CSP_PROGRAM_COUNT
+};
+
+/*
+ * CSP operators
+ */
+struct snd_sb_csp_ops {
+	int (*csp_use) (struct snd_sb_csp * p);
+	int (*csp_unuse) (struct snd_sb_csp * p);
+	int (*csp_autoload) (struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode);
+	int (*csp_start) (struct snd_sb_csp * p, int sample_width, int channels);
+	int (*csp_stop) (struct snd_sb_csp * p);
+	int (*csp_qsound_transfer) (struct snd_sb_csp * p);
+};
+
+/*
+ * CSP private data
+ */
+struct snd_sb_csp {
+	struct snd_sb *chip;		/* SB16 DSP */
+	int used;		/* usage flag - exclusive */
+	char codec_name[16];	/* name of codec */
+	unsigned short func_nr;	/* function number */
+	unsigned int acc_format;	/* accepted PCM formats */
+	int acc_channels;	/* accepted channels */
+	int acc_width;		/* accepted sample width */
+	int acc_rates;		/* accepted sample rates */
+	int mode;		/* MODE */
+	int run_channels;	/* current CSP channels */
+	int run_width;		/* current sample width */
+	int version;		/* CSP version (0x10 - 0x1f) */
+	int running;		/* running state */
+
+	struct snd_sb_csp_ops ops;	/* operators */
+
+	spinlock_t q_lock;	/* locking */
+	int q_enabled;		/* enabled flag */
+	int qpos_left;		/* left position */
+	int qpos_right;		/* right position */
+	int qpos_changed;	/* position changed flag */
+
+	struct snd_kcontrol *qsound_switch;
+	struct snd_kcontrol *qsound_space;
+
+	struct mutex access_mutex;	/* locking */
+
+	const struct firmware *csp_programs[CSP_PROGRAM_COUNT];
+};
+
+int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep);
+#endif /* __SOUND_SB16_CSP */
diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h
new file mode 100644
index 0000000..ddc0d50
--- /dev/null
+++ b/include/sound/seq_device.h
@@ -0,0 +1,96 @@
+#ifndef __SOUND_SEQ_DEVICE_H
+#define __SOUND_SEQ_DEVICE_H
+
+/*
+ *  ALSA sequencer device management
+ *  Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/*
+ * registered device information
+ */
+
+struct snd_seq_device {
+	/* device info */
+	struct snd_card *card;	/* sound card */
+	int device;		/* device number */
+	const char *id;		/* driver id */
+	char name[80];		/* device name */
+	int argsize;		/* size of the argument */
+	void *driver_data;	/* private data for driver */
+	void *private_data;	/* private data for the caller */
+	void (*private_free)(struct snd_seq_device *device);
+	struct device dev;
+};
+
+#define to_seq_dev(_dev) \
+	container_of(_dev, struct snd_seq_device, dev)
+
+/* sequencer driver */
+
+/* driver operators
+ * probe:
+ *	Initialize the device with given parameters.
+ *	Typically,
+ *		1. call snd_hwdep_new
+ *		2. allocate private data and initialize it
+ *		3. call snd_hwdep_register
+ *		4. store the instance to dev->driver_data pointer.
+ *		
+ * remove:
+ *	Release the private data.
+ *	Typically, call snd_device_free(dev->card, dev->driver_data)
+ */
+struct snd_seq_driver {
+	struct device_driver driver;
+	char *id;
+	int argsize;
+};
+
+#define to_seq_drv(_drv) \
+	container_of(_drv, struct snd_seq_driver, driver)
+
+/*
+ * prototypes
+ */
+#ifdef CONFIG_MODULES
+void snd_seq_device_load_drivers(void);
+#else
+#define snd_seq_device_load_drivers()
+#endif
+int snd_seq_device_new(struct snd_card *card, int device, const char *id,
+		       int argsize, struct snd_seq_device **result);
+
+#define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(struct snd_seq_device))
+
+int __must_check __snd_seq_driver_register(struct snd_seq_driver *drv,
+					   struct module *mod);
+#define snd_seq_driver_register(drv) \
+	__snd_seq_driver_register(drv, THIS_MODULE)
+void snd_seq_driver_unregister(struct snd_seq_driver *drv);
+
+#define module_snd_seq_driver(drv) \
+	module_driver(drv, snd_seq_driver_register, snd_seq_driver_unregister)
+
+/*
+ * id strings for generic devices
+ */
+#define SNDRV_SEQ_DEV_ID_MIDISYNTH	"seq-midi"
+#define SNDRV_SEQ_DEV_ID_OPL3		"opl3-synth"
+
+#endif /* __SOUND_SEQ_DEVICE_H */
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
new file mode 100644
index 0000000..4b9ee30
--- /dev/null
+++ b/include/sound/seq_kernel.h
@@ -0,0 +1,110 @@
+#ifndef __SOUND_SEQ_KERNEL_H
+#define __SOUND_SEQ_KERNEL_H
+
+/*
+ *  Main kernel header file for the ALSA sequencer
+ *  Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
+ *
+ *
+ *   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/time.h>
+#include <sound/asequencer.h>
+
+typedef struct snd_seq_real_time snd_seq_real_time_t;
+typedef union snd_seq_timestamp snd_seq_timestamp_t;
+
+/* maximum number of queues */
+#define SNDRV_SEQ_MAX_QUEUES		32
+
+/* max number of concurrent clients */
+#define SNDRV_SEQ_MAX_CLIENTS 		192
+
+/* max number of concurrent ports */
+#define SNDRV_SEQ_MAX_PORTS 		254
+
+/* max number of events in memory pool */
+#define SNDRV_SEQ_MAX_EVENTS		2000
+
+/* default number of events in memory pool */
+#define SNDRV_SEQ_DEFAULT_EVENTS	500
+
+/* max number of events in memory pool for one client (outqueue) */
+#define SNDRV_SEQ_MAX_CLIENT_EVENTS	2000
+
+/* default number of events in memory pool for one client (outqueue) */
+#define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS	200
+
+/* max delivery path length */
+/* NOTE: this shouldn't be greater than MAX_LOCKDEP_SUBCLASSES */
+#define SNDRV_SEQ_MAX_HOPS		8
+
+/* max size of event size */
+#define SNDRV_SEQ_MAX_EVENT_LEN		0x3fffffff
+
+/* call-backs for kernel port */
+struct snd_seq_port_callback {
+	struct module *owner;
+	void *private_data;
+	int (*subscribe)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*unsubscribe)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*use)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*unuse)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop);
+	void (*private_free)(void *private_data);
+	/*...*/
+};
+
+/* interface for kernel client */
+__printf(3, 4)
+int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
+				 const char *name_fmt, ...);
+int snd_seq_delete_kernel_client(int client);
+int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev, int atomic, int hop);
+int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event *ev, int atomic, int hop);
+int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
+
+#define SNDRV_SEQ_EXT_MASK	0xc0000000
+#define SNDRV_SEQ_EXT_USRPTR	0x80000000
+#define SNDRV_SEQ_EXT_CHAINED	0x40000000
+
+typedef int (*snd_seq_dump_func_t)(void *ptr, void *buf, int count);
+int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char *buf,
+			     int in_kernel, int size_aligned);
+int snd_seq_dump_var_event(const struct snd_seq_event *event,
+			   snd_seq_dump_func_t func, void *private_data);
+
+/* interface for OSS emulation */
+int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo);
+
+/* port callback routines */
+void snd_port_init_callback(struct snd_seq_port_callback *p);
+struct snd_seq_port_callback *snd_port_alloc_callback(void);
+
+/* port attach/detach */
+int snd_seq_event_port_attach(int client, struct snd_seq_port_callback *pcbp,
+			      int cap, int type, int midi_channels, int midi_voices, char *portname);
+int snd_seq_event_port_detach(int client, int port);
+
+#ifdef CONFIG_MODULES
+void snd_seq_autoload_init(void);
+void snd_seq_autoload_exit(void);
+#else
+#define snd_seq_autoload_init()
+#define snd_seq_autoload_exit()
+#endif
+
+#endif /* __SOUND_SEQ_KERNEL_H */
diff --git a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
new file mode 100644
index 0000000..8139d8c
--- /dev/null
+++ b/include/sound/seq_midi_emul.h
@@ -0,0 +1,197 @@
+#ifndef __SOUND_SEQ_MIDI_EMUL_H
+#define __SOUND_SEQ_MIDI_EMUL_H
+
+/*
+ *  Midi channel definition for optional channel management.
+ *
+ *  Copyright (C) 1999 Steve Ratcliffe
+ *
+ *   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 <sound/seq_kernel.h>
+
+/*
+ * This structure is used to keep track of the current state on each
+ * channel.  All drivers for hardware that does not understand midi
+ * directly will probably need to use this structure.
+ */
+struct snd_midi_channel {
+	void *private;		/* A back pointer to driver data */
+	int  number;		/* The channel number */
+	int  client;		/* The client associated with this channel */
+	int  port;		/* The port associated with this channel */
+
+	unsigned char midi_mode;	/* GM, GS, XG etc */
+	unsigned int 
+		drum_channel:1,		/* Drum channel */
+		param_type:1		/* RPN/NRPN */
+		;
+
+	unsigned char midi_aftertouch;	/* Aftertouch (key pressure) */
+	unsigned char midi_pressure;	/* Channel pressure */
+	unsigned char midi_program;	/* Instrument number */
+	short midi_pitchbend;		/* Pitch bend amount */
+
+	unsigned char control[128];	/* Current value of all controls */
+	unsigned char note[128];	/* Current status for all notes */
+
+	short gm_rpn_pitch_bend_range;	/* Pitch bend range */
+	short gm_rpn_fine_tuning; 	/* Master fine tuning */
+	short gm_rpn_coarse_tuning;	/* Master coarse tuning */
+
+};
+
+/*
+ * A structure that represets a set of channels bound to a port.  There
+ * would usually be 16 channels per port.  But fewer could be used for
+ * particular cases.
+ * The channel set consists of information describing the client and
+ * port for this midi synth and an array of snd_midi_channel structures.
+ * A driver that had no need for snd_midi_channel could still use the
+ * channel set type if it wished with the channel array null.
+ */
+struct snd_midi_channel_set {
+	void *private_data;		/* Driver data */
+	int  client;			/* Client for this port */
+	int  port;			/* The port number */
+
+	int  max_channels;		/* Size of the channels array */
+	struct snd_midi_channel *channels;
+
+	unsigned char midi_mode;	/* MIDI operating mode */
+	unsigned char gs_master_volume;	/* SYSEX master volume: 0-127 */
+	unsigned char gs_chorus_mode;
+	unsigned char gs_reverb_mode;
+
+};
+
+struct snd_midi_op {
+	void (*note_on)(void *private_data, int note, int vel, struct snd_midi_channel *chan);
+	void (*note_off)(void *private_data,int note, int vel, struct snd_midi_channel *chan); /* release note */
+	void (*key_press)(void *private_data, int note, int vel, struct snd_midi_channel *chan);
+	void (*note_terminate)(void *private_data, int note, struct snd_midi_channel *chan); /* terminate note immediately */
+	void (*control)(void *private_data, int type, struct snd_midi_channel *chan);
+	void (*nrpn)(void *private_data, struct snd_midi_channel *chan,
+		     struct snd_midi_channel_set *chset);
+	void (*sysex)(void *private_data, unsigned char *buf, int len, int parsed,
+		      struct snd_midi_channel_set *chset);
+};
+
+/*
+ * These defines are used so that pitchbend, aftertouch etc, can be
+ * distinguished from controller values.
+ */
+/* 0-127 controller values */
+#define MIDI_CTL_PITCHBEND	0x80
+#define MIDI_CTL_AFTERTOUCH	0x81
+#define MIDI_CTL_CHAN_PRESSURE	0x82
+
+/*
+ * These names exist to allow symbolic access to the controls array.
+ * The usage is eg: chan->gm_bank_select.  Another implementation would
+ * be really have these members in the struct, and not the array.
+ */
+#define gm_bank_select		control[0]
+#define gm_modulation		control[1]
+#define gm_breath		control[2]
+#define gm_foot_pedal		control[4]
+#define gm_portamento_time	control[5]
+#define gm_data_entry		control[6]
+#define gm_volume		control[7]
+#define gm_balance		control[8]
+#define gm_pan			control[10]
+#define gm_expression		control[11]
+#define gm_effect_control1	control[12]
+#define gm_effect_control2	control[13]
+#define gm_slider1		control[16]
+#define gm_slider2		control[17]
+#define gm_slider3		control[18]
+#define gm_slider4		control[19]
+
+#define gm_bank_select_lsb	control[32]
+#define gm_modulation_wheel_lsb	control[33]
+#define gm_breath_lsb		control[34]
+#define gm_foot_pedal_lsb	control[36]
+#define gm_portamento_time_lsb	control[37]
+#define gm_data_entry_lsb	control[38]
+#define gm_volume_lsb		control[39]
+#define gm_balance_lsb		control[40]
+#define gm_pan_lsb		control[42]
+#define gm_expression_lsb	control[43]
+#define gm_effect_control1_lsb	control[44]
+#define gm_effect_control2_lsb	control[45]
+
+#define gm_sustain	 	control[MIDI_CTL_SUSTAIN]
+#define gm_hold			gm_sustain
+#define gm_portamento		control[MIDI_CTL_PORTAMENTO]
+#define gm_sostenuto		control[MIDI_CTL_SOSTENUTO]
+
+/*
+ * These macros give the complete value of the controls that consist
+ * of coarse and fine pairs.  Of course the fine controls are seldom used
+ * but there is no harm in being complete.
+ */
+#define SNDRV_GM_BANK_SELECT(cp)		(((cp)->control[0]<<7)|((cp)->control[32]))
+#define SNDRV_GM_MODULATION_WHEEL(cp)	(((cp)->control[1]<<7)|((cp)->control[33]))
+#define SNDRV_GM_BREATH(cp)		(((cp)->control[2]<<7)|((cp)->control[34]))
+#define SNDRV_GM_FOOT_PEDAL(cp)		(((cp)->control[4]<<7)|((cp)->control[36]))
+#define SNDRV_GM_PORTAMENTO_TIME(cp)	(((cp)->control[5]<<7)|((cp)->control[37]))
+#define SNDRV_GM_DATA_ENTRY(cp)		(((cp)->control[6]<<7)|((cp)->control[38]))
+#define SNDRV_GM_VOLUME(cp)		(((cp)->control[7]<<7)|((cp)->control[39]))
+#define SNDRV_GM_BALANCE(cp)		(((cp)->control[8]<<7)|((cp)->control[40]))
+#define SNDRV_GM_PAN(cp)			(((cp)->control[10]<<7)|((cp)->control[42]))
+#define SNDRV_GM_EXPRESSION(cp)		(((cp)->control[11]<<7)|((cp)->control[43]))
+
+
+/* MIDI mode */
+#define SNDRV_MIDI_MODE_NONE	0	/* Generic midi */
+#define SNDRV_MIDI_MODE_GM	1
+#define SNDRV_MIDI_MODE_GS	2
+#define SNDRV_MIDI_MODE_XG	3
+#define SNDRV_MIDI_MODE_MT32	4
+
+/* MIDI note state */
+#define SNDRV_MIDI_NOTE_OFF		0x00
+#define SNDRV_MIDI_NOTE_ON		0x01
+#define SNDRV_MIDI_NOTE_RELEASED		0x02
+#define SNDRV_MIDI_NOTE_SOSTENUTO		0x04
+ 
+#define SNDRV_MIDI_PARAM_TYPE_REGISTERED		0
+#define SNDRV_MIDI_PARAM_TYPE_NONREGISTERED	1
+
+/* SYSEX parse flag */
+enum {
+	SNDRV_MIDI_SYSEX_NOT_PARSED = 0,
+	SNDRV_MIDI_SYSEX_GM_ON,	
+	SNDRV_MIDI_SYSEX_GS_ON,	
+	SNDRV_MIDI_SYSEX_GS_RESET,	
+	SNDRV_MIDI_SYSEX_GS_CHORUS_MODE,
+	SNDRV_MIDI_SYSEX_GS_REVERB_MODE,
+	SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME,
+	SNDRV_MIDI_SYSEX_GS_PROGRAM,
+	SNDRV_MIDI_SYSEX_GS_DRUM_CHANNEL,
+	SNDRV_MIDI_SYSEX_XG_ON,	
+};
+
+/* Prototypes for midi_process.c */
+void snd_midi_process_event(struct snd_midi_op *ops, struct snd_seq_event *ev,
+			    struct snd_midi_channel_set *chanset);
+void snd_midi_channel_set_clear(struct snd_midi_channel_set *chset);
+struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n);
+void snd_midi_channel_free_set(struct snd_midi_channel_set *chset);
+
+#endif /* __SOUND_SEQ_MIDI_EMUL_H */
diff --git a/include/sound/seq_midi_event.h b/include/sound/seq_midi_event.h
new file mode 100644
index 0000000..e40f43e
--- /dev/null
+++ b/include/sound/seq_midi_event.h
@@ -0,0 +1,54 @@
+#ifndef __SOUND_SEQ_MIDI_EVENT_H
+#define __SOUND_SEQ_MIDI_EVENT_H
+
+/*
+ *  MIDI byte <-> sequencer event coder
+ *
+ *  Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>,
+ *                        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
+ */
+
+#include <sound/asequencer.h>
+
+#define MAX_MIDI_EVENT_BUF	256
+
+/* midi status */
+struct snd_midi_event {
+	int qlen;		/* queue length */
+	int read;		/* chars read */
+	int type;		/* current event type */
+	unsigned char lastcmd;	/* last command (for MIDI state handling) */
+	unsigned char nostat;	/* no state flag */
+	int bufsize;		/* allocated buffer size */
+	unsigned char *buf;	/* input buffer */
+	spinlock_t lock;
+};
+
+int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev);
+void snd_midi_event_free(struct snd_midi_event *dev);
+void snd_midi_event_reset_encode(struct snd_midi_event *dev);
+void snd_midi_event_reset_decode(struct snd_midi_event *dev);
+void snd_midi_event_no_status(struct snd_midi_event *dev, int on);
+/* encode from byte stream - return number of written bytes if success */
+long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
+			   struct snd_seq_event *ev);
+int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c, struct snd_seq_event *ev);
+/* decode from event to bytes - return number of written bytes if success */
+long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
+			   struct snd_seq_event *ev);
+
+#endif /* __SOUND_SEQ_MIDI_EVENT_H */
diff --git a/include/sound/seq_oss.h b/include/sound/seq_oss.h
new file mode 100644
index 0000000..d0b27ec
--- /dev/null
+++ b/include/sound/seq_oss.h
@@ -0,0 +1,96 @@
+#ifndef __SOUND_SEQ_OSS_H
+#define __SOUND_SEQ_OSS_H
+
+/*
+ * OSS compatible sequencer driver
+ *
+ * Copyright (C) 1998,99 Takashi Iwai
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/asequencer.h>
+#include <sound/seq_kernel.h>
+
+/*
+ * argument structure for synthesizer operations
+ */
+struct snd_seq_oss_arg {
+	/* given by OSS sequencer */
+	int app_index;	/* application unique index */
+	int file_mode;	/* file mode - see below */
+	int seq_mode;	/* sequencer mode - see below */
+
+	/* following must be initialized in open callback */
+	struct snd_seq_addr addr;	/* opened port address */
+	void *private_data;	/* private data for lowlevel drivers */
+
+	/* note-on event passing mode: initially given by OSS seq,
+	 * but configurable by drivers - see below
+	 */
+	int event_passing;
+};
+
+
+/*
+ * synthesizer operation callbacks
+ */
+struct snd_seq_oss_callback {
+	struct module *owner;
+	int (*open)(struct snd_seq_oss_arg *p, void *closure);
+	int (*close)(struct snd_seq_oss_arg *p);
+	int (*ioctl)(struct snd_seq_oss_arg *p, unsigned int cmd, unsigned long arg);
+	int (*load_patch)(struct snd_seq_oss_arg *p, int format, const char __user *buf, int offs, int count);
+	int (*reset)(struct snd_seq_oss_arg *p);
+	int (*raw_event)(struct snd_seq_oss_arg *p, unsigned char *data);
+};
+
+/* flag: file_mode */
+#define SNDRV_SEQ_OSS_FILE_ACMODE		3
+#define SNDRV_SEQ_OSS_FILE_READ		1
+#define SNDRV_SEQ_OSS_FILE_WRITE		2
+#define SNDRV_SEQ_OSS_FILE_NONBLOCK	4
+
+/* flag: seq_mode */
+#define SNDRV_SEQ_OSS_MODE_SYNTH		0
+#define SNDRV_SEQ_OSS_MODE_MUSIC		1
+
+/* flag: event_passing */
+#define SNDRV_SEQ_OSS_PROCESS_EVENTS	0	/* key == 255 is processed as velocity change */
+#define SNDRV_SEQ_OSS_PASS_EVENTS		1	/* pass all events to callback */
+#define SNDRV_SEQ_OSS_PROCESS_KEYPRESS	2	/* key >= 128 will be processed as key-pressure */
+
+/* default control rate: fixed */
+#define SNDRV_SEQ_OSS_CTRLRATE		100
+
+/* default max queue length: configurable by module option */
+#define SNDRV_SEQ_OSS_MAX_QLEN		1024
+
+
+/*
+ * data pointer to snd_seq_register_device
+ */
+struct snd_seq_oss_reg {
+	int type;
+	int subtype;
+	int nvoices;
+	struct snd_seq_oss_callback oper;
+	void *private_data;
+};
+
+/* device id */
+#define SNDRV_SEQ_DEV_ID_OSS		"seq-oss"
+
+#endif /* __SOUND_SEQ_OSS_H */
diff --git a/include/sound/seq_oss_legacy.h b/include/sound/seq_oss_legacy.h
new file mode 100644
index 0000000..e66269f
--- /dev/null
+++ b/include/sound/seq_oss_legacy.h
@@ -0,0 +1,31 @@
+#ifndef __SOUND_SEQ_OSS_LEGACY_H
+#define __SOUND_SEQ_OSS_LEGACY_H
+
+/*
+ * OSS compatible macro definitions
+ *
+ * Copyright (C) 2000 Abramo Bagnara <abramo@alsa-project.org>
+ *
+ * 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/soundcard.h>
+
+#ifndef SAMPLE_TYPE_AWE32
+#define SAMPLE_TYPE_AWE32		0x20
+#endif
+
+#endif /* __SOUND_SEQ_OSS_LEGACY_H */
+
diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
new file mode 100644
index 0000000..695257a
--- /dev/null
+++ b/include/sound/seq_virmidi.h
@@ -0,0 +1,82 @@
+#ifndef __SOUND_SEQ_VIRMIDI_H
+#define __SOUND_SEQ_VIRMIDI_H
+
+/*
+ *  Virtual Raw MIDI client on Sequencer
+ *  Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>,
+ *                        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
+ *
+ */
+
+#include <sound/rawmidi.h>
+#include <sound/seq_midi_event.h>
+
+/*
+ * device file instance:
+ * This instance is created at each time the midi device file is
+ * opened.  Each instance has its own input buffer and MIDI parser
+ * (buffer), and is associated with the device instance.
+ */
+struct snd_virmidi {
+	struct list_head list;
+	int seq_mode;
+	int client;
+	int port;
+	unsigned int trigger: 1;
+	struct snd_midi_event *parser;
+	struct snd_seq_event event;
+	struct snd_virmidi_dev *rdev;
+	struct snd_rawmidi_substream *substream;
+};
+
+#define SNDRV_VIRMIDI_SUBSCRIBE		(1<<0)
+#define SNDRV_VIRMIDI_USE		(1<<1)
+
+/*
+ * device record:
+ * Each virtual midi device has one device instance.  It contains
+ * common information and the linked-list of opened files, 
+ */
+struct snd_virmidi_dev {
+	struct snd_card *card;		/* associated card */
+	struct snd_rawmidi *rmidi;		/* rawmidi device */
+	int seq_mode;			/* SNDRV_VIRMIDI_XXX */
+	int device;			/* sequencer device */
+	int client;			/* created/attached client */
+	int port;			/* created/attached port */
+	unsigned int flags;		/* SNDRV_VIRMIDI_* */
+	rwlock_t filelist_lock;
+	struct rw_semaphore filelist_sem;
+	struct list_head filelist;
+};
+
+/* sequencer mode:
+ * ATTACH = input/output events from midi device are routed to the
+ *          attached sequencer port.  sequencer port is not created
+ *          by virmidi itself.
+ *          the input to rawmidi must be processed by passing the
+ *          incoming events via snd_virmidi_receive()
+ * DISPATCH = input/output events are routed to subscribers.
+ *            sequencer port is created in virmidi.
+ */
+#define SNDRV_VIRMIDI_SEQ_NONE		0
+#define SNDRV_VIRMIDI_SEQ_ATTACH	1
+#define SNDRV_VIRMIDI_SEQ_DISPATCH	2
+
+int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmidi);
+
+#endif /* __SOUND_SEQ_VIRMIDI */
diff --git a/include/sound/sh_dac_audio.h b/include/sound/sh_dac_audio.h
new file mode 100644
index 0000000..f5deaf1
--- /dev/null
+++ b/include/sound/sh_dac_audio.h
@@ -0,0 +1,21 @@
+/*
+ * SH_DAC specific configuration, for the dac_audio platform_device
+ *
+ * Copyright (C) 2009 Rafael Ignacio Zurita <rizurita@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __INCLUDE_SH_DAC_AUDIO_H
+#define __INCLUDE_SH_DAC_AUDIO_H
+
+struct dac_audio_pdata {
+	int buffer_size;
+	int channel;
+	void (*start)(struct dac_audio_pdata *pd);
+	void (*stop)(struct dac_audio_pdata *pd);
+};
+
+#endif /* __INCLUDE_SH_DAC_AUDIO_H */
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
new file mode 100644
index 0000000..7a9710b
--- /dev/null
+++ b/include/sound/sh_fsi.h
@@ -0,0 +1,35 @@
+#ifndef __SOUND_FSI_H
+#define __SOUND_FSI_H
+
+/*
+ * Fifo-attached Serial Interface (FSI) support for SH7724
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <sound/soc.h>
+
+/*
+ * flags
+ */
+#define SH_FSI_FMT_SPDIF		(1 << 0) /* spdif for HDMI */
+#define SH_FSI_ENABLE_STREAM_MODE	(1 << 1) /* for 16bit data */
+#define SH_FSI_CLK_CPG			(1 << 2) /* FSIxCK + FSI-DIV */
+
+struct sh_fsi_port_info {
+	unsigned long flags;
+	int tx_id;
+	int rx_id;
+};
+
+struct sh_fsi_platform_info {
+	struct sh_fsi_port_info port_a;
+	struct sh_fsi_port_info port_b;
+};
+
+#endif /* __SOUND_FSI_H */
diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h
new file mode 100644
index 0000000..0399352
--- /dev/null
+++ b/include/sound/simple_card.h
@@ -0,0 +1,38 @@
+/*
+ * ASoC simple sound card support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SIMPLE_CARD_H
+#define __SIMPLE_CARD_H
+
+#include <sound/soc.h>
+
+struct asoc_simple_dai {
+	const char *name;
+	unsigned int sysclk;
+	int slots;
+	int slot_width;
+	unsigned int tx_slot_mask;
+	unsigned int rx_slot_mask;
+	struct clk *clk;
+};
+
+struct asoc_simple_card_info {
+	const char *name;
+	const char *card;
+	const char *codec;
+	const char *platform;
+
+	unsigned int daifmt;
+	struct asoc_simple_dai cpu_dai;
+	struct asoc_simple_dai codec_dai;
+};
+
+#endif /* __SIMPLE_CARD_H */
diff --git a/include/sound/snd_wavefront.h b/include/sound/snd_wavefront.h
new file mode 100644
index 0000000..35e94b3
--- /dev/null
+++ b/include/sound/snd_wavefront.h
@@ -0,0 +1,142 @@
+#ifndef __SOUND_SND_WAVEFRONT_H__
+#define __SOUND_SND_WAVEFRONT_H__
+
+#include <sound/mpu401.h>
+#include <sound/hwdep.h>
+#include <sound/rawmidi.h>
+#include <sound/wavefront.h>  /* generic OSS/ALSA/user-level wavefront header */
+
+/* MIDI interface */
+
+struct _snd_wavefront_midi;
+struct _snd_wavefront_card;
+struct _snd_wavefront;
+
+typedef struct _snd_wavefront_midi snd_wavefront_midi_t;
+typedef struct _snd_wavefront_card snd_wavefront_card_t;
+typedef struct _snd_wavefront snd_wavefront_t;
+
+typedef enum { internal_mpu = 0, external_mpu = 1 } snd_wavefront_mpu_id;
+
+struct _snd_wavefront_midi {
+        unsigned long            base;        /* I/O port address */
+	char                     isvirtual;   /* doing virtual MIDI stuff ? */
+	char			 istimer;     /* timer is used */
+        snd_wavefront_mpu_id     output_mpu;  /* most-recently-used */
+        snd_wavefront_mpu_id     input_mpu;   /* most-recently-used */
+        unsigned int             mode[2];     /* MPU401_MODE_XXX */
+	struct snd_rawmidi_substream	 *substream_output[2];
+	struct snd_rawmidi_substream	 *substream_input[2];
+	struct timer_list	 timer;
+        spinlock_t               open;
+        spinlock_t               virtual;     /* protects isvirtual */
+};
+
+#define	OUTPUT_READY	0x40
+#define	INPUT_AVAIL	0x80
+#define	MPU_ACK		0xFE
+#define	UART_MODE_ON	0x3F
+
+extern struct snd_rawmidi_ops snd_wavefront_midi_output;
+extern struct snd_rawmidi_ops snd_wavefront_midi_input;
+
+extern void   snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *);
+extern void   snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *);
+extern void   snd_wavefront_midi_interrupt (snd_wavefront_card_t *);
+extern int    snd_wavefront_midi_start (snd_wavefront_card_t *);
+
+struct _snd_wavefront {
+	unsigned long    irq;   /* "you were one, one of the few ..." */
+	unsigned long    base;  /* low i/o port address */
+	struct resource	 *res_base; /* i/o port resource allocation */
+
+#define mpu_data_port    base 
+#define mpu_command_port base + 1 /* write semantics */
+#define mpu_status_port  base + 1 /* read semantics */
+#define data_port        base + 2 
+#define status_port      base + 3 /* read semantics */
+#define control_port     base + 3 /* write semantics  */
+#define block_port       base + 4 /* 16 bit, writeonly */
+#define last_block_port  base + 6 /* 16 bit, writeonly */
+
+	/* FX ports. These are mapped through the ICS2115 to the YS225.
+	   The ICS2115 takes care of flipping the relevant pins on the
+	   YS225 so that access to each of these ports does the right
+	   thing. Note: these are NOT documented by Turtle Beach.
+	*/
+
+#define fx_status       base + 8 
+#define fx_op           base + 8 
+#define fx_lcr          base + 9 
+#define fx_dsp_addr     base + 0xa
+#define fx_dsp_page     base + 0xb 
+#define fx_dsp_lsb      base + 0xc 
+#define fx_dsp_msb      base + 0xd 
+#define fx_mod_addr     base + 0xe
+#define fx_mod_data     base + 0xf 
+
+	volatile int irq_ok;               /* set by interrupt handler */
+        volatile int irq_cnt;              /* ditto */
+	char debug;                        /* debugging flags */
+	int freemem;                       /* installed RAM, in bytes */ 
+
+	char fw_version[2];                /* major = [0], minor = [1] */
+	char hw_version[2];                /* major = [0], minor = [1] */
+	char israw;                        /* needs Motorola microcode */
+	char has_fx;                       /* has FX processor (Tropez+) */
+	char fx_initialized;               /* FX's register pages initialized */
+	char prog_status[WF_MAX_PROGRAM];  /* WF_SLOT_* */
+	char patch_status[WF_MAX_PATCH];   /* WF_SLOT_* */
+	char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
+	int samples_used;                  /* how many */
+	char interrupts_are_midi;          /* h/w MPU interrupts enabled ? */
+	char rom_samples_rdonly;           /* can we write on ROM samples */
+	spinlock_t irq_lock;
+	wait_queue_head_t interrupt_sleeper; 
+	snd_wavefront_midi_t midi;         /* ICS2115 MIDI interface */
+	struct snd_card *card;
+};
+
+struct _snd_wavefront_card {
+	snd_wavefront_t wavefront;
+#ifdef CONFIG_PNP
+	struct pnp_dev *wss;
+	struct pnp_dev *ctrl;
+	struct pnp_dev *mpu;
+	struct pnp_dev *synth;
+#endif /* CONFIG_PNP */
+};
+
+extern void snd_wavefront_internal_interrupt (snd_wavefront_card_t *card);
+extern int  snd_wavefront_detect_irq (snd_wavefront_t *dev) ;
+extern int  snd_wavefront_check_irq (snd_wavefront_t *dev, int irq);
+extern int  snd_wavefront_restart (snd_wavefront_t *dev);
+extern int  snd_wavefront_start (snd_wavefront_t *dev);
+extern int  snd_wavefront_detect (snd_wavefront_card_t *card);
+extern int  snd_wavefront_config_midi (snd_wavefront_t *dev) ;
+extern int  snd_wavefront_cmd (snd_wavefront_t *, int, unsigned char *,
+			       unsigned char *);
+
+extern int snd_wavefront_synth_ioctl   (struct snd_hwdep *, 
+					struct file *,
+					unsigned int cmd, 
+					unsigned long arg);
+extern int  snd_wavefront_synth_open    (struct snd_hwdep *, struct file *);
+extern int  snd_wavefront_synth_release (struct snd_hwdep *, struct file *);
+
+/* FX processor - see also yss225.[ch] */
+
+extern int  snd_wavefront_fx_start  (snd_wavefront_t *);
+extern int  snd_wavefront_fx_detect (snd_wavefront_t *);
+extern int  snd_wavefront_fx_ioctl  (struct snd_hwdep *, 
+				     struct file *,
+				     unsigned int cmd, 
+				     unsigned long arg);
+extern int snd_wavefront_fx_open    (struct snd_hwdep *, struct file *);
+extern int snd_wavefront_fx_release (struct snd_hwdep *, struct file *);
+
+/* prefix in all snd_printk() delivered messages */
+
+#define LOGNAME "WaveFront: "
+
+#endif  /* __SOUND_SND_WAVEFRONT_H__ */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
new file mode 100644
index 0000000..212eaaf
--- /dev/null
+++ b/include/sound/soc-dai.h
@@ -0,0 +1,331 @@
+/*
+ * linux/sound/soc-dai.h -- ALSA SoC Layer
+ *
+ * Copyright:	2005-2008 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Digital Audio Interface (DAI) API.
+ */
+
+#ifndef __LINUX_SND_SOC_DAI_H
+#define __LINUX_SND_SOC_DAI_H
+
+
+#include <linux/list.h>
+
+struct snd_pcm_substream;
+struct snd_soc_dapm_widget;
+struct snd_compr_stream;
+
+/*
+ * DAI hardware audio formats.
+ *
+ * Describes the physical PCM data formating and clocking. Add new formats
+ * to the end.
+ */
+#define SND_SOC_DAIFMT_I2S		1 /* I2S mode */
+#define SND_SOC_DAIFMT_RIGHT_J		2 /* Right Justified mode */
+#define SND_SOC_DAIFMT_LEFT_J		3 /* Left Justified mode */
+#define SND_SOC_DAIFMT_DSP_A		4 /* L data MSB after FRM LRC */
+#define SND_SOC_DAIFMT_DSP_B		5 /* L data MSB during FRM LRC */
+#define SND_SOC_DAIFMT_AC97		6 /* AC97 */
+#define SND_SOC_DAIFMT_PDM		7 /* Pulse density modulation */
+
+/* left and right justified also known as MSB and LSB respectively */
+#define SND_SOC_DAIFMT_MSB		SND_SOC_DAIFMT_LEFT_J
+#define SND_SOC_DAIFMT_LSB		SND_SOC_DAIFMT_RIGHT_J
+
+/*
+ * DAI Clock gating.
+ *
+ * DAI bit clocks can be be gated (disabled) when the DAI is not
+ * sending or receiving PCM data in a frame. This can be used to save power.
+ */
+#define SND_SOC_DAIFMT_CONT		(1 << 4) /* continuous clock */
+#define SND_SOC_DAIFMT_GATED		(0 << 4) /* clock is gated */
+
+/*
+ * DAI hardware signal polarity.
+ *
+ * Specifies whether the DAI can also support inverted clocks for the specified
+ * format.
+ *
+ * BCLK:
+ * - "normal" polarity means signal is available at rising edge of BCLK
+ * - "inverted" polarity means signal is available at falling edge of BCLK
+ *
+ * FSYNC "normal" polarity depends on the frame format:
+ * - I2S: frame consists of left then right channel data. Left channel starts
+ *      with falling FSYNC edge, right channel starts with rising FSYNC edge.
+ * - Left/Right Justified: frame consists of left then right channel data.
+ *      Left channel starts with rising FSYNC edge, right channel starts with
+ *      falling FSYNC edge.
+ * - DSP A/B: Frame starts with rising FSYNC edge.
+ * - AC97: Frame starts with rising FSYNC edge.
+ *
+ * "Negative" FSYNC polarity is the one opposite of "normal" polarity.
+ */
+#define SND_SOC_DAIFMT_NB_NF		(0 << 8) /* normal bit clock + frame */
+#define SND_SOC_DAIFMT_NB_IF		(2 << 8) /* normal BCLK + inv FRM */
+#define SND_SOC_DAIFMT_IB_NF		(3 << 8) /* invert BCLK + nor FRM */
+#define SND_SOC_DAIFMT_IB_IF		(4 << 8) /* invert BCLK + FRM */
+
+/*
+ * DAI hardware clock masters.
+ *
+ * This is wrt the codec, the inverse is true for the interface
+ * i.e. if the codec is clk and FRM master then the interface is
+ * clk and frame slave.
+ */
+#define SND_SOC_DAIFMT_CBM_CFM		(1 << 12) /* codec clk & FRM master */
+#define SND_SOC_DAIFMT_CBS_CFM		(2 << 12) /* codec clk slave & FRM master */
+#define SND_SOC_DAIFMT_CBM_CFS		(3 << 12) /* codec clk master & frame slave */
+#define SND_SOC_DAIFMT_CBS_CFS		(4 << 12) /* codec clk & FRM slave */
+
+#define SND_SOC_DAIFMT_FORMAT_MASK	0x000f
+#define SND_SOC_DAIFMT_CLOCK_MASK	0x00f0
+#define SND_SOC_DAIFMT_INV_MASK		0x0f00
+#define SND_SOC_DAIFMT_MASTER_MASK	0xf000
+
+/*
+ * Master Clock Directions
+ */
+#define SND_SOC_CLOCK_IN		0
+#define SND_SOC_CLOCK_OUT		1
+
+#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S8 |\
+			       SNDRV_PCM_FMTBIT_S16_LE |\
+			       SNDRV_PCM_FMTBIT_S16_BE |\
+			       SNDRV_PCM_FMTBIT_S20_3LE |\
+			       SNDRV_PCM_FMTBIT_S20_3BE |\
+			       SNDRV_PCM_FMTBIT_S24_3LE |\
+			       SNDRV_PCM_FMTBIT_S24_3BE |\
+                               SNDRV_PCM_FMTBIT_S32_LE |\
+                               SNDRV_PCM_FMTBIT_S32_BE)
+
+struct snd_soc_dai_driver;
+struct snd_soc_dai;
+struct snd_ac97_bus_ops;
+
+/* Digital Audio Interface clocking API.*/
+int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+	unsigned int freq, int dir);
+
+int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
+	int div_id, int div);
+
+int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
+	int pll_id, int source, unsigned int freq_in, unsigned int freq_out);
+
+int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio);
+
+/* Digital Audio interface formatting */
+int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
+
+int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
+	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width);
+
+int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
+	unsigned int tx_num, unsigned int *tx_slot,
+	unsigned int rx_num, unsigned int *rx_slot);
+
+int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
+
+/* Digital Audio Interface mute */
+int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
+			     int direction);
+
+int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
+
+struct snd_soc_dai_ops {
+	/*
+	 * DAI clocking configuration, all optional.
+	 * Called by soc_card drivers, normally in their hw_params.
+	 */
+	int (*set_sysclk)(struct snd_soc_dai *dai,
+		int clk_id, unsigned int freq, int dir);
+	int (*set_pll)(struct snd_soc_dai *dai, int pll_id, int source,
+		unsigned int freq_in, unsigned int freq_out);
+	int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
+	int (*set_bclk_ratio)(struct snd_soc_dai *dai, unsigned int ratio);
+
+	/*
+	 * DAI format configuration
+	 * Called by soc_card drivers, normally in their hw_params.
+	 */
+	int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
+	int (*xlate_tdm_slot_mask)(unsigned int slots,
+		unsigned int *tx_mask, unsigned int *rx_mask);
+	int (*set_tdm_slot)(struct snd_soc_dai *dai,
+		unsigned int tx_mask, unsigned int rx_mask,
+		int slots, int slot_width);
+	int (*set_channel_map)(struct snd_soc_dai *dai,
+		unsigned int tx_num, unsigned int *tx_slot,
+		unsigned int rx_num, unsigned int *rx_slot);
+	int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
+
+	/*
+	 * DAI digital mute - optional.
+	 * Called by soc-core to minimise any pops.
+	 */
+	int (*digital_mute)(struct snd_soc_dai *dai, int mute);
+	int (*mute_stream)(struct snd_soc_dai *dai, int mute, int stream);
+
+	/*
+	 * ALSA PCM audio operations - all optional.
+	 * Called by soc-core during audio PCM operations.
+	 */
+	int (*startup)(struct snd_pcm_substream *,
+		struct snd_soc_dai *);
+	void (*shutdown)(struct snd_pcm_substream *,
+		struct snd_soc_dai *);
+	int (*hw_params)(struct snd_pcm_substream *,
+		struct snd_pcm_hw_params *, struct snd_soc_dai *);
+	int (*hw_free)(struct snd_pcm_substream *,
+		struct snd_soc_dai *);
+	int (*prepare)(struct snd_pcm_substream *,
+		struct snd_soc_dai *);
+	/*
+	 * NOTE: Commands passed to the trigger function are not necessarily
+	 * compatible with the current state of the dai. For example this
+	 * sequence of commands is possible: START STOP STOP.
+	 * So do not unconditionally use refcounting functions in the trigger
+	 * function, e.g. clk_enable/disable.
+	 */
+	int (*trigger)(struct snd_pcm_substream *, int,
+		struct snd_soc_dai *);
+	int (*bespoke_trigger)(struct snd_pcm_substream *, int,
+		struct snd_soc_dai *);
+	/*
+	 * For hardware based FIFO caused delay reporting.
+	 * Optional.
+	 */
+	snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
+		struct snd_soc_dai *);
+};
+
+/*
+ * Digital Audio Interface Driver.
+ *
+ * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
+ * operations and capabilities. Codec and platform drivers will register this
+ * structure for every DAI they have.
+ *
+ * This structure covers the clocking, formating and ALSA operations for each
+ * interface.
+ */
+struct snd_soc_dai_driver {
+	/* DAI description */
+	const char *name;
+	unsigned int id;
+	unsigned int base;
+
+	/* DAI driver callbacks */
+	int (*probe)(struct snd_soc_dai *dai);
+	int (*remove)(struct snd_soc_dai *dai);
+	int (*suspend)(struct snd_soc_dai *dai);
+	int (*resume)(struct snd_soc_dai *dai);
+	/* compress dai */
+	int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
+	/* DAI is also used for the control bus */
+	bool bus_control;
+
+	/* ops */
+	const struct snd_soc_dai_ops *ops;
+
+	/* DAI capabilities */
+	struct snd_soc_pcm_stream capture;
+	struct snd_soc_pcm_stream playback;
+	unsigned int symmetric_rates:1;
+	unsigned int symmetric_channels:1;
+	unsigned int symmetric_samplebits:1;
+
+	/* probe ordering - for components with runtime dependencies */
+	int probe_order;
+	int remove_order;
+};
+
+/*
+ * Digital Audio Interface runtime data.
+ *
+ * Holds runtime data for a DAI.
+ */
+struct snd_soc_dai {
+	const char *name;
+	int id;
+	struct device *dev;
+
+	/* driver ops */
+	struct snd_soc_dai_driver *driver;
+
+	/* DAI runtime info */
+	unsigned int capture_active:1;		/* stream is in use */
+	unsigned int playback_active:1;		/* stream is in use */
+	unsigned int symmetric_rates:1;
+	unsigned int symmetric_channels:1;
+	unsigned int symmetric_samplebits:1;
+	unsigned int active;
+	unsigned char probed:1;
+
+	struct snd_soc_dapm_widget *playback_widget;
+	struct snd_soc_dapm_widget *capture_widget;
+
+	/* DAI DMA data */
+	void *playback_dma_data;
+	void *capture_dma_data;
+
+	/* Symmetry data - only valid if symmetry is being enforced */
+	unsigned int rate;
+	unsigned int channels;
+	unsigned int sample_bits;
+
+	/* parent platform/codec */
+	struct snd_soc_codec *codec;
+	struct snd_soc_component *component;
+
+	/* CODEC TDM slot masks and params (for fixup) */
+	unsigned int tx_mask;
+	unsigned int rx_mask;
+
+	struct list_head list;
+};
+
+static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
+					     const struct snd_pcm_substream *ss)
+{
+	return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+		dai->playback_dma_data : dai->capture_dma_data;
+}
+
+static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
+					    const struct snd_pcm_substream *ss,
+					    void *data)
+{
+	if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		dai->playback_dma_data = data;
+	else
+		dai->capture_dma_data = data;
+}
+
+static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai,
+					     void *playback, void *capture)
+{
+	dai->playback_dma_data = playback;
+	dai->capture_dma_data = capture;
+}
+
+static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
+		void *data)
+{
+	dev_set_drvdata(dai->dev, data);
+}
+
+static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
+{
+	return dev_get_drvdata(dai->dev);
+}
+
+#endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
new file mode 100644
index 0000000..95a937e
--- /dev/null
+++ b/include/sound/soc-dapm.h
@@ -0,0 +1,739 @@
+/*
+ * linux/sound/soc-dapm.h -- ALSA SoC Dynamic Audio Power Management
+ *
+ * Author:		Liam Girdwood
+ * Created:		Aug 11th 2005
+ * Copyright:	Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_SOC_DAPM_H
+#define __LINUX_SND_SOC_DAPM_H
+
+#include <linux/types.h>
+#include <sound/control.h>
+#include <sound/soc-topology.h>
+#include <sound/asoc.h>
+
+struct device;
+
+/* widget has no PM register bit */
+#define SND_SOC_NOPM	-1
+
+/*
+ * SoC dynamic audio power management
+ *
+ * We can have up to 4 power domains
+ *  1. Codec domain - VREF, VMID
+ *     Usually controlled at codec probe/remove, 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 set in the machine
+ *     driver and by userspace e.g when HP are inserted
+ *  3. Path domain - Internal codec path mixers
+ *     Are automatically set when mixer and mux settings are
+ *     changed by the user.
+ *  4. Stream domain - DAC's and ADC's.
+ *     Enabled when stream playback/capture is started.
+ */
+
+/* codec domain */
+#define SND_SOC_DAPM_VMID(wname) \
+{	.id = snd_soc_dapm_vmid, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0}
+
+/* platform domain */
+#define SND_SOC_DAPM_SIGGEN(wname) \
+{	.id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
+#define SND_SOC_DAPM_INPUT(wname) \
+{	.id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
+#define SND_SOC_DAPM_OUTPUT(wname) \
+{	.id = snd_soc_dapm_output, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM }
+#define SND_SOC_DAPM_MIC(wname, wevent) \
+{	.id = snd_soc_dapm_mic, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
+#define SND_SOC_DAPM_HP(wname, wevent) \
+{	.id = snd_soc_dapm_hp, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
+	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
+#define SND_SOC_DAPM_SPK(wname, wevent) \
+{	.id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
+	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
+#define SND_SOC_DAPM_LINE(wname, wevent) \
+{	.id = snd_soc_dapm_line, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
+	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
+
+#define SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert) \
+	.reg = wreg, .mask = 1, .shift = wshift, \
+	.on_val = winvert ? 0 : 1, .off_val = winvert ? 1 : 0
+
+/* path domain */
+#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\
+	 wcontrols, wncontrols) \
+{	.id = snd_soc_dapm_pga, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
+#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
+	 wcontrols, wncontrols) \
+{	.id = snd_soc_dapm_out_drv, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
+#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
+	 wcontrols, wncontrols)\
+{	.id = snd_soc_dapm_mixer, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
+#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \
+	 wcontrols, wncontrols)\
+{       .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
+#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \
+{	.id = snd_soc_dapm_micbias, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = NULL, .num_kcontrols = 0}
+#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \
+{	.id = snd_soc_dapm_switch, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = 1}
+#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
+{	.id = snd_soc_dapm_mux, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = 1}
+#define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols) \
+{	.id = snd_soc_dapm_demux, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = 1}
+
+/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
+#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
+	 wcontrols) \
+{	.id = snd_soc_dapm_pga, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
+#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
+	 wcontrols)\
+{	.id = snd_soc_dapm_mixer, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
+#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
+	 wcontrols)\
+{       .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
+
+/* path domain with event - event handler must return 0 for success */
+#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
+	wncontrols, wevent, wflags) \
+{	.id = snd_soc_dapm_pga, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
+	.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
+	wncontrols, wevent, wflags) \
+{	.id = snd_soc_dapm_out_drv, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
+	.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
+	wncontrols, wevent, wflags) \
+{	.id = snd_soc_dapm_mixer, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
+	.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \
+	wcontrols, wncontrols, wevent, wflags) \
+{       .id = snd_soc_dapm_mixer, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, \
+	.num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \
+	wevent, wflags) \
+{	.id = snd_soc_dapm_switch, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = 1, \
+	.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
+	wevent, wflags) \
+{	.id = snd_soc_dapm_mux, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = 1, \
+	.event = wevent, .event_flags = wflags}
+
+/* additional sequencing control within an event type */
+#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \
+	wevent, wflags) \
+{	.id = snd_soc_dapm_pga, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags, \
+	.subseq = wsubseq}
+#define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
+	wflags)	\
+{	.id = snd_soc_dapm_supply, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags, .subseq = wsubseq}
+
+/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
+#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
+	wevent, wflags) \
+{	.id = snd_soc_dapm_pga, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
+	.event = wevent, .event_flags = wflags}
+#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
+	wevent, wflags) \
+{	.id = snd_soc_dapm_mixer, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
+	.event = wevent, .event_flags = wflags}
+#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
+	wcontrols, wevent, wflags) \
+{       .id = snd_soc_dapm_mixer, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
+	.event = wevent, .event_flags = wflags}
+
+/* events that are pre and post DAPM */
+#define SND_SOC_DAPM_PRE(wname, wevent) \
+{	.id = snd_soc_dapm_pre, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD}
+#define SND_SOC_DAPM_POST(wname, wevent) \
+{	.id = snd_soc_dapm_post, .name = wname, .kcontrol_news = NULL, \
+	.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
+	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
+
+/* stream domain */
+#define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
+{	.id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
+#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wslot, wreg, wshift, winvert, \
+			      wevent, wflags)				\
+{	.id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags }
+#define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
+{	.id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
+#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wslot, wreg, wshift, winvert, \
+			     wevent, wflags)				\
+{	.id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags }
+#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
+{	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert) }
+#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
+			   wevent, wflags)				\
+{	.id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags}
+
+#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
+{	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
+#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
+			   wevent, wflags)				\
+{	.id = snd_soc_dapm_adc, .name = wname, .sname = stname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \
+{	.id = snd_soc_dapm_clock_supply, .name = wname, \
+	.reg = SND_SOC_NOPM, .event = dapm_clock_event, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
+
+/* generic widgets */
+#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
+{	.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
+	.reg = wreg, .shift = wshift, .mask = wmask, \
+	.on_val = won_val, .off_val = woff_val, }
+#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
+{	.id = snd_soc_dapm_supply, .name = wname, \
+	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
+	.event = wevent, .event_flags = wflags}
+#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags)	    \
+{	.id = snd_soc_dapm_regulator_supply, .name = wname, \
+	.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
+	.on_val = wflags}
+
+
+/* dapm kcontrol types */
+#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_volsw, \
+	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
+	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
+#define SOC_DAPM_SINGLE_AUTODISABLE(xname, reg, shift, max, invert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_volsw, \
+	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
+	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
+#define SOC_DAPM_SINGLE_VIRT(xname, max) \
+	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0)
+#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_volsw, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
+	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
+#define SOC_DAPM_SINGLE_TLV_AUTODISABLE(xname, reg, shift, max, invert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_volsw, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
+	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
+#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \
+	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array)
+#define SOC_DAPM_ENUM(xname, xenum) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_enum_double, \
+ 	.get = snd_soc_dapm_get_enum_double, \
+ 	.put = snd_soc_dapm_put_enum_double, \
+  	.private_value = (unsigned long)&xenum }
+#define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_enum_double, \
+	.get = xget, \
+	.put = xput, \
+	.private_value = (unsigned long)&xenum }
+#define SOC_DAPM_PIN_SWITCH(xname) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \
+	.info = snd_soc_dapm_info_pin_switch, \
+	.get = snd_soc_dapm_get_pin_switch, \
+	.put = snd_soc_dapm_put_pin_switch, \
+	.private_value = (unsigned long)xname }
+
+/* dapm stream operations */
+#define SND_SOC_DAPM_STREAM_NOP			0x0
+#define SND_SOC_DAPM_STREAM_START		0x1
+#define SND_SOC_DAPM_STREAM_STOP		0x2
+#define SND_SOC_DAPM_STREAM_SUSPEND		0x4
+#define SND_SOC_DAPM_STREAM_RESUME		0x8
+#define SND_SOC_DAPM_STREAM_PAUSE_PUSH	0x10
+#define SND_SOC_DAPM_STREAM_PAUSE_RELEASE	0x20
+
+/* 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 */
+#define SND_SOC_DAPM_WILL_PMU   0x40    /* called at start of sequence */
+#define SND_SOC_DAPM_WILL_PMD   0x80    /* called at start of sequence */
+#define SND_SOC_DAPM_PRE_POST_PMD \
+				(SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
+
+/* convenience event type detection */
+#define SND_SOC_DAPM_EVENT_ON(e)	\
+	(e & (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU))
+#define SND_SOC_DAPM_EVENT_OFF(e)	\
+	(e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD))
+
+/* regulator widget flags */
+#define SND_SOC_DAPM_REGULATOR_BYPASS     0x1     /* bypass when disabled */
+
+struct snd_soc_dapm_widget;
+enum snd_soc_dapm_type;
+struct snd_soc_dapm_path;
+struct snd_soc_dapm_pin;
+struct snd_soc_dapm_route;
+struct snd_soc_dapm_context;
+struct regulator;
+struct snd_soc_dapm_widget_list;
+struct snd_soc_dapm_update;
+
+int dapm_regulator_event(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event);
+int dapm_clock_event(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event);
+
+/* dapm controls */
+int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo);
+int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *uncontrol);
+int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *uncontrol);
+int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
+	const struct snd_soc_dapm_widget *widget,
+	int num);
+int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
+				 struct snd_soc_dai *dai);
+int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
+void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
+int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
+			 const struct snd_soc_pcm_stream *params,
+			 unsigned int num_params,
+			 struct snd_soc_dapm_widget *source,
+			 struct snd_soc_dapm_widget *sink);
+
+/* dapm path setup */
+int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
+void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
+			    const struct snd_soc_dapm_route *route, int num);
+int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
+			    const struct snd_soc_dapm_route *route, int num);
+int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
+			     const struct snd_soc_dapm_route *route, int num);
+void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
+void snd_soc_dapm_reset_cache(struct snd_soc_dapm_context *dapm);
+
+/* dapm events */
+void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
+	int event);
+void snd_soc_dapm_shutdown(struct snd_soc_card *card);
+
+/* external DAPM widget events */
+int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
+		struct snd_kcontrol *kcontrol, int connect,
+		struct snd_soc_dapm_update *update);
+int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
+		struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
+		struct snd_soc_dapm_update *update);
+
+/* dapm sys fs - used by the core */
+extern struct attribute *soc_dapm_dev_attrs[];
+void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
+				struct dentry *parent);
+
+/* dapm audio pin control and status */
+int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm,
+			    const char *pin);
+int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
+				     const char *pin);
+int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
+			     const char *pin);
+int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm,
+				      const char *pin);
+int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
+int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm,
+				 const char *pin);
+int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
+				const char *pin);
+int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm);
+int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
+				  const char *pin);
+int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
+					   const char *pin);
+int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
+				const char *pin);
+unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
+
+/* Mostly internal - should not normally be used */
+void dapm_mark_endpoints_dirty(struct snd_soc_card *card);
+
+/* dapm path query */
+int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
+	struct snd_soc_dapm_widget_list **list);
+
+struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
+	struct snd_kcontrol *kcontrol);
+
+struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(
+		struct snd_kcontrol *kcontrol);
+
+int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
+	enum snd_soc_bias_level level);
+
+/* dapm widget types */
+enum snd_soc_dapm_type {
+	snd_soc_dapm_input = 0,		/* input pin */
+	snd_soc_dapm_output,		/* output pin */
+	snd_soc_dapm_mux,			/* selects 1 analog signal from many inputs */
+	snd_soc_dapm_demux,			/* connects the input to one of multiple outputs */
+	snd_soc_dapm_mixer,			/* mixes several analog signals together */
+	snd_soc_dapm_mixer_named_ctl,		/* mixer with named controls */
+	snd_soc_dapm_pga,			/* programmable gain/attenuation (volume) */
+	snd_soc_dapm_out_drv,			/* output driver */
+	snd_soc_dapm_adc,			/* analog to digital converter */
+	snd_soc_dapm_dac,			/* digital to analog converter */
+	snd_soc_dapm_micbias,		/* microphone bias (power) */
+	snd_soc_dapm_mic,			/* microphone */
+	snd_soc_dapm_hp,			/* headphones */
+	snd_soc_dapm_spk,			/* speaker */
+	snd_soc_dapm_line,			/* line input/output */
+	snd_soc_dapm_switch,		/* analog switch */
+	snd_soc_dapm_vmid,			/* codec bias/vmid - to minimise pops */
+	snd_soc_dapm_pre,			/* machine specific pre widget - exec first */
+	snd_soc_dapm_post,			/* machine specific post widget - exec last */
+	snd_soc_dapm_supply,		/* power/clock supply */
+	snd_soc_dapm_regulator_supply,	/* external regulator */
+	snd_soc_dapm_clock_supply,	/* external clock */
+	snd_soc_dapm_aif_in,		/* audio interface input */
+	snd_soc_dapm_aif_out,		/* audio interface output */
+	snd_soc_dapm_siggen,		/* signal generator */
+	snd_soc_dapm_dai_in,		/* link to DAI structure */
+	snd_soc_dapm_dai_out,
+	snd_soc_dapm_dai_link,		/* link between two DAI structures */
+	snd_soc_dapm_kcontrol,		/* Auto-disabled kcontrol */
+};
+
+enum snd_soc_dapm_subclass {
+	SND_SOC_DAPM_CLASS_INIT		= 0,
+	SND_SOC_DAPM_CLASS_RUNTIME	= 1,
+};
+
+/*
+ * DAPM audio route definition.
+ *
+ * Defines an audio route originating at source via control and finishing
+ * at sink.
+ */
+struct snd_soc_dapm_route {
+	const char *sink;
+	const char *control;
+	const char *source;
+
+	/* Note: currently only supported for links where source is a supply */
+	int (*connected)(struct snd_soc_dapm_widget *source,
+			 struct snd_soc_dapm_widget *sink);
+};
+
+/* dapm audio path between two widgets */
+struct snd_soc_dapm_path {
+	const char *name;
+
+	/*
+	 * source (input) and sink (output) widgets
+	 * The union is for convience, since it is a lot nicer to type
+	 * p->source, rather than p->node[SND_SOC_DAPM_DIR_IN]
+	 */
+	union {
+		struct {
+			struct snd_soc_dapm_widget *source;
+			struct snd_soc_dapm_widget *sink;
+		};
+		struct snd_soc_dapm_widget *node[2];
+	};
+
+	/* status */
+	u32 connect:1;	/* source and sink widgets are connected */
+	u32 walking:1;  /* path is in the process of being walked */
+	u32 weak:1;	/* path ignored for power management */
+	u32 is_supply:1;	/* At least one of the connected widgets is a supply */
+
+	int (*connected)(struct snd_soc_dapm_widget *source,
+			 struct snd_soc_dapm_widget *sink);
+
+	struct list_head list_node[2];
+	struct list_head list_kcontrol;
+	struct list_head list;
+};
+
+/* dapm widget */
+struct snd_soc_dapm_widget {
+	enum snd_soc_dapm_type id;
+	const char *name;		/* widget name */
+	const char *sname;	/* stream name */
+	struct list_head list;
+	struct snd_soc_dapm_context *dapm;
+
+	void *priv;				/* widget specific data */
+	struct regulator *regulator;		/* attached regulator */
+	const struct snd_soc_pcm_stream *params; /* params for dai links */
+	unsigned int num_params; /* number of params for dai links */
+	unsigned int params_select; /* currently selected param for dai link */
+
+	/* dapm control */
+	int reg;				/* negative reg = no direct dapm */
+	unsigned char shift;			/* bits to shift */
+	unsigned int mask;			/* non-shifted mask */
+	unsigned int on_val;			/* on state value */
+	unsigned int off_val;			/* off state value */
+	unsigned char power:1;			/* block power status */
+	unsigned char active:1;			/* active stream on DAC, ADC's */
+	unsigned char connected:1;		/* connected codec pin */
+	unsigned char new:1;			/* cnew complete */
+	unsigned char force:1;			/* force state */
+	unsigned char ignore_suspend:1;         /* kept enabled over suspend */
+	unsigned char new_power:1;		/* power from this run */
+	unsigned char power_checked:1;		/* power checked this run */
+	unsigned char is_supply:1;		/* Widget is a supply type widget */
+	unsigned char is_ep:2;			/* Widget is a endpoint type widget */
+	int subseq;				/* sort within widget type */
+
+	int (*power_check)(struct snd_soc_dapm_widget *w);
+
+	/* external events */
+	unsigned short event_flags;		/* flags to specify event types */
+	int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int);
+
+	/* kcontrols that relate to this widget */
+	int num_kcontrols;
+	const struct snd_kcontrol_new *kcontrol_news;
+	struct snd_kcontrol **kcontrols;
+	struct snd_soc_dobj dobj;
+
+	/* widget input and output edges */
+	struct list_head edges[2];
+
+	/* used during DAPM updates */
+	struct list_head work_list;
+	struct list_head power_list;
+	struct list_head dirty;
+	int endpoints[2];
+
+	struct clk *clk;
+};
+
+struct snd_soc_dapm_update {
+	struct snd_kcontrol *kcontrol;
+	int reg;
+	int mask;
+	int val;
+};
+
+struct snd_soc_dapm_wcache {
+	struct snd_soc_dapm_widget *widget;
+};
+
+/* DAPM context */
+struct snd_soc_dapm_context {
+	enum snd_soc_bias_level bias_level;
+	unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
+	/* Go to BIAS_OFF in suspend if the DAPM context is idle */
+	unsigned int suspend_bias_off:1;
+	void (*seq_notifier)(struct snd_soc_dapm_context *,
+			     enum snd_soc_dapm_type, int);
+
+	struct device *dev; /* from parent - for debug */
+	struct snd_soc_component *component; /* parent component */
+	struct snd_soc_card *card; /* parent card */
+
+	/* used during DAPM updates */
+	enum snd_soc_bias_level target_bias_level;
+	struct list_head list;
+
+	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
+	int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
+			      enum snd_soc_bias_level level);
+
+	struct snd_soc_dapm_wcache path_sink_cache;
+	struct snd_soc_dapm_wcache path_source_cache;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_dapm;
+#endif
+};
+
+/* A list of widgets associated with an object, typically a snd_kcontrol */
+struct snd_soc_dapm_widget_list {
+	int num_widgets;
+	struct snd_soc_dapm_widget *widgets[0];
+};
+
+struct snd_soc_dapm_stats {
+	int power_checks;
+	int path_checks;
+	int neighbour_checks;
+};
+
+/**
+ * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
+ * @dapm: The DAPM context to initialize
+ * @level: The DAPM level to initialize to
+ *
+ * This function only sets the driver internal state of the DAPM level and will
+ * not modify the state of the device. Hence it should not be used during normal
+ * operation, but only to synchronize the internal state to the device state.
+ * E.g. during driver probe to set the DAPM level to the one corresponding with
+ * the power-on reset state of the device.
+ *
+ * To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
+ */
+static inline void snd_soc_dapm_init_bias_level(
+	struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
+{
+	dapm->bias_level = level;
+}
+
+/**
+ * snd_soc_dapm_get_bias_level() - Get current DAPM bias level
+ * @dapm: The context for which to get the bias level
+ *
+ * Returns: The current bias level of the passed DAPM context.
+ */
+static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
+	struct snd_soc_dapm_context *dapm)
+{
+	return dapm->bias_level;
+}
+
+enum snd_soc_dapm_direction {
+	SND_SOC_DAPM_DIR_IN,
+	SND_SOC_DAPM_DIR_OUT
+};
+
+#define SND_SOC_DAPM_DIR_TO_EP(x) BIT(x)
+
+#define SND_SOC_DAPM_EP_SOURCE SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_IN)
+#define SND_SOC_DAPM_EP_SINK SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_OUT)
+
+/**
+ * snd_soc_dapm_widget_for_each_sink_path - Iterates over all paths in the
+ *   specified direction of a widget
+ * @w: The widget
+ * @dir: Whether to iterate over the paths where the specified widget is the
+ *       incoming or outgoing widgets
+ * @p: The path iterator variable
+ */
+#define snd_soc_dapm_widget_for_each_path(w, dir, p) \
+	list_for_each_entry(p, &w->edges[dir], list_node[dir])
+
+/**
+ * snd_soc_dapm_widget_for_each_sink_path_safe - Iterates over all paths in the
+ *   specified direction of a widget
+ * @w: The widget
+ * @dir: Whether to iterate over the paths where the specified widget is the
+ *       incoming or outgoing widgets
+ * @p: The path iterator variable
+ * @next_p: Temporary storage for the next path
+ *
+ *  This function works like snd_soc_dapm_widget_for_each_sink_path, expect that
+ *  it is safe to remove the current path from the list while iterating
+ */
+#define snd_soc_dapm_widget_for_each_path_safe(w, dir, p, next_p) \
+	list_for_each_entry_safe(p, next_p, &w->edges[dir], list_node[dir])
+
+/**
+ * snd_soc_dapm_widget_for_each_sink_path - Iterates over all paths leaving a
+ *  widget
+ * @w: The widget
+ * @p: The path iterator variable
+ */
+#define snd_soc_dapm_widget_for_each_sink_path(w, p) \
+	snd_soc_dapm_widget_for_each_path(w, SND_SOC_DAPM_DIR_IN, p)
+
+/**
+ * snd_soc_dapm_widget_for_each_source_path - Iterates over all paths leading to
+ *  a widget
+ * @w: The widget
+ * @p: The path iterator variable
+ */
+#define snd_soc_dapm_widget_for_each_source_path(w, p) \
+	snd_soc_dapm_widget_for_each_path(w, SND_SOC_DAPM_DIR_OUT, p)
+
+#endif
diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h
new file mode 100644
index 0000000..8060590
--- /dev/null
+++ b/include/sound/soc-dpcm.h
@@ -0,0 +1,162 @@
+/*
+ * linux/sound/soc-dpcm.h -- ALSA SoC Dynamic PCM Support
+ *
+ * Author:		Liam Girdwood <lrg@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_SOC_DPCM_H
+#define __LINUX_SND_SOC_DPCM_H
+
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <sound/pcm.h>
+
+struct snd_soc_pcm_runtime;
+
+/*
+ * Types of runtime_update to perform. e.g. originated from FE PCM ops
+ * or audio route changes triggered by muxes/mixers.
+ */
+enum snd_soc_dpcm_update {
+	SND_SOC_DPCM_UPDATE_NO	= 0,
+	SND_SOC_DPCM_UPDATE_BE,
+	SND_SOC_DPCM_UPDATE_FE,
+};
+
+/*
+ * Dynamic PCM Frontend -> Backend link management states.
+ */
+enum snd_soc_dpcm_link_state {
+	SND_SOC_DPCM_LINK_STATE_NEW	= 0,	/* newly created link */
+	SND_SOC_DPCM_LINK_STATE_FREE,		/* link to be dismantled */
+};
+
+/*
+ * Dynamic PCM Frontend -> Backend link PCM states.
+ */
+enum snd_soc_dpcm_state {
+	SND_SOC_DPCM_STATE_NEW	= 0,
+	SND_SOC_DPCM_STATE_OPEN,
+	SND_SOC_DPCM_STATE_HW_PARAMS,
+	SND_SOC_DPCM_STATE_PREPARE,
+	SND_SOC_DPCM_STATE_START,
+	SND_SOC_DPCM_STATE_STOP,
+	SND_SOC_DPCM_STATE_PAUSED,
+	SND_SOC_DPCM_STATE_SUSPEND,
+	SND_SOC_DPCM_STATE_HW_FREE,
+	SND_SOC_DPCM_STATE_CLOSE,
+};
+
+/*
+ * Dynamic PCM trigger ordering. Triggering flexibility is required as some
+ * DSPs require triggering before/after their CPU platform and DAIs.
+ *
+ * i.e. some clients may want to manually order this call in their PCM
+ * trigger() whilst others will just use the regular core ordering.
+ */
+enum snd_soc_dpcm_trigger {
+	SND_SOC_DPCM_TRIGGER_PRE		= 0,
+	SND_SOC_DPCM_TRIGGER_POST,
+	SND_SOC_DPCM_TRIGGER_BESPOKE,
+};
+
+/*
+ * Dynamic PCM link
+ * This links together a FE and BE DAI at runtime and stores the link
+ * state information and the hw_params configuration.
+ */
+struct snd_soc_dpcm {
+	/* FE and BE DAIs*/
+	struct snd_soc_pcm_runtime *be;
+	struct snd_soc_pcm_runtime *fe;
+
+	/* link state */
+	enum snd_soc_dpcm_link_state state;
+
+	/* list of BE and FE for this DPCM link */
+	struct list_head list_be;
+	struct list_head list_fe;
+
+	/* hw params for this link - may be different for each link */
+	struct snd_pcm_hw_params hw_params;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_state;
+#endif
+};
+
+/*
+ * Dynamic PCM runtime data.
+ */
+struct snd_soc_dpcm_runtime {
+	struct list_head be_clients;
+	struct list_head fe_clients;
+
+	int users;
+	struct snd_pcm_runtime *runtime;
+	struct snd_pcm_hw_params hw_params;
+
+	/* state and update */
+	enum snd_soc_dpcm_update runtime_update;
+	enum snd_soc_dpcm_state state;
+
+	int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */
+};
+
+/* can this BE stop and free */
+int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
+		struct snd_soc_pcm_runtime *be, int stream);
+
+/* can this BE perform a hw_params() */
+int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
+		struct snd_soc_pcm_runtime *be, int stream);
+
+/* is the current PCM operation for this FE ? */
+int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream);
+
+/* is the current PCM operation for this BE ? */
+int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
+		struct snd_soc_pcm_runtime *be, int stream);
+
+/* get the substream for this BE */
+struct snd_pcm_substream *
+	snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream);
+
+/* get the BE runtime state */
+enum snd_soc_dpcm_state
+	snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream);
+
+/* set the BE runtime state */
+void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream,
+	enum snd_soc_dpcm_state state);
+
+/* internal use only */
+int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
+void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
+int soc_dpcm_runtime_update(struct snd_soc_card *);
+
+int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
+	int stream, struct snd_soc_dapm_widget_list **list_);
+int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
+	int stream, struct snd_soc_dapm_widget_list **list, int new);
+int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream);
+void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream);
+void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);
+int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
+int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
+int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
+	int event);
+
+static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
+{
+	kfree(*list);
+}
+
+
+#endif
diff --git a/include/sound/soc-topology.h b/include/sound/soc-topology.h
new file mode 100644
index 0000000..086cd7f
--- /dev/null
+++ b/include/sound/soc-topology.h
@@ -0,0 +1,191 @@
+/*
+ * linux/sound/soc-topology.h -- ALSA SoC Firmware Controls and DAPM
+ *
+ * Copyright (C) 2012 Texas Instruments Inc.
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
+ * algorithms, equalisers, DAIs, widgets, FE caps, BE caps, codec link caps etc.
+ */
+
+#ifndef __LINUX_SND_SOC_TPLG_H
+#define __LINUX_SND_SOC_TPLG_H
+
+#include <sound/asoc.h>
+#include <linux/list.h>
+
+struct firmware;
+struct snd_kcontrol;
+struct snd_soc_tplg_pcm_be;
+struct snd_ctl_elem_value;
+struct snd_ctl_elem_info;
+struct snd_soc_dapm_widget;
+struct snd_soc_component;
+struct snd_soc_tplg_pcm_fe;
+struct snd_soc_dapm_context;
+struct snd_soc_card;
+
+/* object scan be loaded and unloaded in groups with identfying indexes */
+#define SND_SOC_TPLG_INDEX_ALL	0	/* ID that matches all FW objects */
+
+/* dynamic object type */
+enum snd_soc_dobj_type {
+	SND_SOC_DOBJ_NONE		= 0,	/* object is not dynamic */
+	SND_SOC_DOBJ_MIXER,
+	SND_SOC_DOBJ_ENUM,
+	SND_SOC_DOBJ_BYTES,
+	SND_SOC_DOBJ_PCM,
+	SND_SOC_DOBJ_DAI_LINK,
+	SND_SOC_DOBJ_CODEC_LINK,
+	SND_SOC_DOBJ_WIDGET,
+};
+
+/* dynamic control object */
+struct snd_soc_dobj_control {
+	struct snd_kcontrol *kcontrol;
+	char **dtexts;
+	unsigned long *dvalues;
+};
+
+/* dynamic widget object */
+struct snd_soc_dobj_widget {
+	unsigned int kcontrol_enum:1;	/* this widget is an enum kcontrol */
+};
+
+/* dynamic PCM DAI object */
+struct snd_soc_dobj_pcm_dai {
+	struct snd_soc_tplg_pcm_dai *pd;
+	unsigned int count;
+};
+
+/* generic dynamic object - all dynamic objects belong to this struct */
+struct snd_soc_dobj {
+	enum snd_soc_dobj_type type;
+	unsigned int index;	/* objects can belong in different groups */
+	struct list_head list;
+	struct snd_soc_tplg_ops *ops;
+	union {
+		struct snd_soc_dobj_control control;
+		struct snd_soc_dobj_widget widget;
+		struct snd_soc_dobj_pcm_dai pcm_dai;
+	};
+	void *private; /* core does not touch this */
+};
+
+/*
+ * Kcontrol operations - used to map handlers onto firmware based controls.
+ */
+struct snd_soc_tplg_kcontrol_ops {
+	u32 id;
+	int (*get)(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+	int (*put)(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+	int (*info)(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_info *uinfo);
+};
+
+/* Bytes ext operations, for TLV byte controls */
+struct snd_soc_tplg_bytes_ext_ops {
+	u32 id;
+	int (*get)(unsigned int __user *bytes, unsigned int size);
+	int (*put)(const unsigned int __user *bytes, unsigned int size);
+};
+
+/*
+ * DAPM widget event handlers - used to map handlers onto widgets.
+ */
+struct snd_soc_tplg_widget_events {
+	u16 type;
+	int (*event_handler)(struct snd_soc_dapm_widget *w,
+			struct snd_kcontrol *k, int event);
+};
+
+/*
+ * Public API - Used by component drivers to load and unload dynamic objects
+ * and their resources.
+ */
+struct snd_soc_tplg_ops {
+
+	/* external kcontrol init - used for any driver specific init */
+	int (*control_load)(struct snd_soc_component *,
+		struct snd_kcontrol_new *, struct snd_soc_tplg_ctl_hdr *);
+	int (*control_unload)(struct snd_soc_component *,
+		struct snd_soc_dobj *);
+
+	/* external widget init - used for any driver specific init */
+	int (*widget_load)(struct snd_soc_component *,
+		struct snd_soc_dapm_widget *,
+		struct snd_soc_tplg_dapm_widget *);
+	int (*widget_unload)(struct snd_soc_component *,
+		struct snd_soc_dobj *);
+
+	/* FE - used for any driver specific init */
+	int (*pcm_dai_load)(struct snd_soc_component *,
+		struct snd_soc_tplg_pcm_dai *pcm_dai, int num_fe);
+	int (*pcm_dai_unload)(struct snd_soc_component *,
+		struct snd_soc_dobj *);
+
+	/* callback to handle vendor bespoke data */
+	int (*vendor_load)(struct snd_soc_component *,
+		struct snd_soc_tplg_hdr *);
+	int (*vendor_unload)(struct snd_soc_component *,
+		struct snd_soc_tplg_hdr *);
+
+	/* completion - called at completion of firmware loading */
+	void (*complete)(struct snd_soc_component *);
+
+	/* manifest - optional to inform component of manifest */
+	int (*manifest)(struct snd_soc_component *,
+		struct snd_soc_tplg_manifest *);
+
+	/* vendor specific kcontrol handlers available for binding */
+	const struct snd_soc_tplg_kcontrol_ops *io_ops;
+	int io_ops_count;
+
+	/* vendor specific bytes ext handlers available for binding */
+	const struct snd_soc_tplg_bytes_ext_ops *bytes_ext_ops;
+	int bytes_ext_ops_count;
+};
+
+#ifdef CONFIG_SND_SOC_TOPOLOGY
+
+/* gets a pointer to data from the firmware block header */
+static inline const void *snd_soc_tplg_get_data(struct snd_soc_tplg_hdr *hdr)
+{
+	const void *ptr = hdr;
+
+	return ptr + sizeof(*hdr);
+}
+
+/* Dynamic Object loading and removal for component drivers */
+int snd_soc_tplg_component_load(struct snd_soc_component *comp,
+	struct snd_soc_tplg_ops *ops, const struct firmware *fw,
+	u32 index);
+int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index);
+
+/* Widget removal - widgets also removed wth component API */
+void snd_soc_tplg_widget_remove(struct snd_soc_dapm_widget *w);
+void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm,
+	u32 index);
+
+/* Binds event handlers to dynamic widgets */
+int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w,
+	const struct snd_soc_tplg_widget_events *events, int num_events,
+	u16 event_type);
+
+#else
+
+static inline int snd_soc_tplg_component_remove(struct snd_soc_component *comp,
+						u32 index)
+{
+	return 0;
+}
+
+#endif
+
+#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
new file mode 100644
index 0000000..fb955e6
--- /dev/null
+++ b/include/sound/soc.h
@@ -0,0 +1,1666 @@
+/*
+ * linux/sound/soc.h -- ALSA SoC Layer
+ *
+ * Author:		Liam Girdwood
+ * Created:		Aug 11th 2005
+ * Copyright:	Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_SOC_H
+#define __LINUX_SND_SOC_H
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/regmap.h>
+#include <linux/log2.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/compress_driver.h>
+#include <sound/control.h>
+#include <sound/ac97_codec.h>
+#include <sound/soc-topology.h>
+
+/*
+ * Convenience kcontrol builders
+ */
+#define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert, xautodisable) \
+	((unsigned long)&(struct soc_mixer_control) \
+	{.reg = xreg, .rreg = xreg, .shift = shift_left, \
+	.rshift = shift_right, .max = xmax, .platform_max = xmax, \
+	.invert = xinvert, .autodisable = xautodisable})
+#define SOC_DOUBLE_S_VALUE(xreg, shift_left, shift_right, xmin, xmax, xsign_bit, xinvert, xautodisable) \
+	((unsigned long)&(struct soc_mixer_control) \
+	{.reg = xreg, .rreg = xreg, .shift = shift_left, \
+	.rshift = shift_right, .min = xmin, .max = xmax, .platform_max = xmax, \
+	.sign_bit = xsign_bit, .invert = xinvert, .autodisable = xautodisable})
+#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, xautodisable) \
+	SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert, xautodisable)
+#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
+	((unsigned long)&(struct soc_mixer_control) \
+	{.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
+#define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \
+	((unsigned long)&(struct soc_mixer_control) \
+	{.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
+	.max = xmax, .platform_max = xmax, .invert = xinvert})
+#define SOC_DOUBLE_R_S_VALUE(xlreg, xrreg, xshift, xmin, xmax, xsign_bit, xinvert) \
+	((unsigned long)&(struct soc_mixer_control) \
+	{.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
+	.max = xmax, .min = xmin, .platform_max = xmax, .sign_bit = xsign_bit, \
+	.invert = xinvert})
+#define SOC_DOUBLE_R_RANGE_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \
+	((unsigned long)&(struct soc_mixer_control) \
+	{.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
+	.min = xmin, .max = xmax, .platform_max = xmax, .invert = xinvert})
+#define SOC_SINGLE(xname, reg, shift, max, invert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
+	.put = snd_soc_put_volsw, \
+	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
+#define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \
+	.put = snd_soc_put_volsw_range, \
+	.private_value = (unsigned long)&(struct soc_mixer_control) \
+		{.reg = xreg, .rreg = xreg, .shift = xshift, \
+		 .rshift = xshift,  .min = xmin, .max = xmax, \
+		 .platform_max = xmax, .invert = xinvert} }
+#define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
+	.put = snd_soc_put_volsw, \
+	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
+#define SOC_SINGLE_SX_TLV(xname, xreg, xshift, xmin, xmax, tlv_array) \
+{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+	SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p  = (tlv_array),\
+	.info = snd_soc_info_volsw_sx, \
+	.get = snd_soc_get_volsw_sx,\
+	.put = snd_soc_put_volsw_sx, \
+	.private_value = (unsigned long)&(struct soc_mixer_control) \
+		{.reg = xreg, .rreg = xreg, \
+		.shift = xshift, .rshift = xshift, \
+		.max = xmax, .min = xmin} }
+#define SOC_SINGLE_RANGE_TLV(xname, xreg, xshift, xmin, xmax, xinvert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw_range, \
+	.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
+	.private_value = (unsigned long)&(struct soc_mixer_control) \
+		{.reg = xreg, .rreg = xreg, .shift = xshift, \
+		 .rshift = xshift, .min = xmin, .max = xmax, \
+		 .platform_max = xmax, .invert = xinvert} }
+#define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
+	.put = snd_soc_put_volsw, \
+	.private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
+					  max, invert, 0) }
+#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.info = snd_soc_info_volsw, \
+	.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
+	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
+					    xmax, xinvert) }
+#define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \
+			   xmax, xinvert)		\
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.info = snd_soc_info_volsw_range, \
+	.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
+	.private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
+					    xshift, xmin, xmax, xinvert) }
+#define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
+	.put = snd_soc_put_volsw, \
+	.private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
+					  max, invert, 0) }
+#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, \
+	.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
+	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
+					    xmax, xinvert) }
+#define SOC_DOUBLE_R_RANGE_TLV(xname, reg_left, reg_right, xshift, xmin, \
+			       xmax, xinvert, tlv_array)		\
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw_range, \
+	.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
+	.private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
+					    xshift, xmin, xmax, xinvert) }
+#define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \
+{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+	SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p  = (tlv_array), \
+	.info = snd_soc_info_volsw_sx, \
+	.get = snd_soc_get_volsw_sx, \
+	.put = snd_soc_put_volsw_sx, \
+	.private_value = (unsigned long)&(struct soc_mixer_control) \
+		{.reg = xreg, .rreg = xrreg, \
+		.shift = xshift, .rshift = xshift, \
+		.max = xmax, .min = xmin} }
+#define SOC_DOUBLE_R_S_TLV(xname, reg_left, reg_right, xshift, xmin, xmax, xsign_bit, xinvert, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, \
+	.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
+	.private_value = SOC_DOUBLE_R_S_VALUE(reg_left, reg_right, xshift, \
+					    xmin, xmax, xsign_bit, xinvert) }
+#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
+{	.iface  = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+		  SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p  = (tlv_array), \
+	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
+	.put = snd_soc_put_volsw, \
+	.private_value = SOC_DOUBLE_S_VALUE(xreg, 0, 8, xmin, xmax, 7, 0, 0) }
+#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xitems, xtexts) \
+{	.reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
+	.items = xitems, .texts = xtexts, \
+	.mask = xitems ? roundup_pow_of_two(xitems) - 1 : 0}
+#define SOC_ENUM_SINGLE(xreg, xshift, xitems, xtexts) \
+	SOC_ENUM_DOUBLE(xreg, xshift, xshift, xitems, xtexts)
+#define SOC_ENUM_SINGLE_EXT(xitems, xtexts) \
+{	.items = xitems, .texts = xtexts }
+#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xitems, xtexts, xvalues) \
+{	.reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
+	.mask = xmask, .items = xitems, .texts = xtexts, .values = xvalues}
+#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
+	SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xitems, xtexts, xvalues)
+#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
+{	.reg = xreg, .shift_l = xshift, .shift_r = xshift, \
+	.mask = xmask, .items = xitems, .texts = xtexts, \
+	.values = xvalues, .autodisable = 1}
+#define SOC_ENUM_SINGLE_VIRT(xitems, xtexts) \
+	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts)
+#define SOC_ENUM(xname, xenum) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
+	.info = snd_soc_info_enum_double, \
+	.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
+	.private_value = (unsigned long)&xenum }
+#define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
+	 xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_volsw, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) }
+#define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\
+	 xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.info = snd_soc_info_volsw, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = \
+		SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert, 0) }
+#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\
+	 xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.info = snd_soc_info_volsw, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
+					    xmax, xinvert) }
+#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
+	 xhandler_get, xhandler_put, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert, 0) }
+#define SOC_SINGLE_RANGE_EXT_TLV(xname, xreg, xshift, xmin, xmax, xinvert, \
+				 xhandler_get, xhandler_put, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw_range, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = (unsigned long)&(struct soc_mixer_control) \
+		{.reg = xreg, .rreg = xreg, .shift = xshift, \
+		 .rshift = xshift, .min = xmin, .max = xmax, \
+		 .platform_max = xmax, .invert = xinvert} }
+#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
+	 xhandler_get, xhandler_put, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \
+					  xmax, xinvert, 0) }
+#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
+	 xhandler_get, xhandler_put, tlv_array) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+	.tlv.p = (tlv_array), \
+	.info = snd_soc_info_volsw, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
+					    xmax, xinvert) }
+#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_bool_ext, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = xdata }
+#define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_info_enum_double, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = (unsigned long)&xenum }
+#define SOC_VALUE_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
+	SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put)
+
+#define SND_SOC_BYTES(xname, xbase, xregs)		      \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
+	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
+	.put = snd_soc_bytes_put, .private_value =	      \
+		((unsigned long)&(struct soc_bytes)           \
+		{.base = xbase, .num_regs = xregs }) }
+
+#define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask)	      \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
+	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
+	.put = snd_soc_bytes_put, .private_value =	      \
+		((unsigned long)&(struct soc_bytes)           \
+		{.base = xbase, .num_regs = xregs,	      \
+		 .mask = xmask }) }
+
+#define SND_SOC_BYTES_EXT(xname, xcount, xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_soc_bytes_info_ext, \
+	.get = xhandler_get, .put = xhandler_put, \
+	.private_value = (unsigned long)&(struct soc_bytes_ext) \
+		{.max = xcount} }
+#define SND_SOC_BYTES_TLV(xname, xcount, xhandler_get, xhandler_put) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | \
+		  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
+	.tlv.c = (snd_soc_bytes_tlv_callback), \
+	.info = snd_soc_bytes_info_ext, \
+	.private_value = (unsigned long)&(struct soc_bytes_ext) \
+		{.max = xcount, .get = xhandler_get, .put = xhandler_put, } }
+#define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \
+		xmin, xmax, xinvert) \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+	.info = snd_soc_info_xr_sx, .get = snd_soc_get_xr_sx, \
+	.put = snd_soc_put_xr_sx, \
+	.private_value = (unsigned long)&(struct soc_mreg_control) \
+		{.regbase = xregbase, .regcount = xregcount, .nbits = xnbits, \
+		.invert = xinvert, .min = xmin, .max = xmax} }
+
+#define SOC_SINGLE_STROBE(xname, xreg, xshift, xinvert) \
+	SOC_SINGLE_EXT(xname, xreg, xshift, 1, xinvert, \
+		snd_soc_get_strobe, snd_soc_put_strobe)
+
+/*
+ * Simplified versions of above macros, declaring a struct and calculating
+ * ARRAY_SIZE internally
+ */
+#define SOC_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xtexts) \
+	const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \
+						ARRAY_SIZE(xtexts), xtexts)
+#define SOC_ENUM_SINGLE_DECL(name, xreg, xshift, xtexts) \
+	SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts)
+#define SOC_ENUM_SINGLE_EXT_DECL(name, xtexts) \
+	const struct soc_enum name = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(xtexts), xtexts)
+#define SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xmask, xtexts, xvalues) \
+	const struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \
+							ARRAY_SIZE(xtexts), xtexts, xvalues)
+#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
+	SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
+
+#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
+	const struct soc_enum name = SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, \
+		xshift, xmask, ARRAY_SIZE(xtexts), xtexts, xvalues)
+
+#define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \
+	const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
+
+/*
+ * Component probe and remove ordering levels for components with runtime
+ * dependencies.
+ */
+#define SND_SOC_COMP_ORDER_FIRST		-2
+#define SND_SOC_COMP_ORDER_EARLY		-1
+#define SND_SOC_COMP_ORDER_NORMAL		0
+#define SND_SOC_COMP_ORDER_LATE		1
+#define SND_SOC_COMP_ORDER_LAST		2
+
+/*
+ * Bias levels
+ *
+ * @ON:      Bias is fully on for audio playback and capture operations.
+ * @PREPARE: Prepare for audio operations. Called before DAPM switching for
+ *           stream start and stop operations.
+ * @STANDBY: Low power standby state when no playback/capture operations are
+ *           in progress. NOTE: The transition time between STANDBY and ON
+ *           should be as fast as possible and no longer than 10ms.
+ * @OFF:     Power Off. No restrictions on transition times.
+ */
+enum snd_soc_bias_level {
+	SND_SOC_BIAS_OFF = 0,
+	SND_SOC_BIAS_STANDBY = 1,
+	SND_SOC_BIAS_PREPARE = 2,
+	SND_SOC_BIAS_ON = 3,
+};
+
+struct device_node;
+struct snd_jack;
+struct snd_soc_card;
+struct snd_soc_pcm_stream;
+struct snd_soc_ops;
+struct snd_soc_pcm_runtime;
+struct snd_soc_dai;
+struct snd_soc_dai_driver;
+struct snd_soc_platform;
+struct snd_soc_dai_link;
+struct snd_soc_platform_driver;
+struct snd_soc_codec;
+struct snd_soc_codec_driver;
+struct snd_soc_component;
+struct snd_soc_component_driver;
+struct soc_enum;
+struct snd_soc_jack;
+struct snd_soc_jack_zone;
+struct snd_soc_jack_pin;
+#include <sound/soc-dapm.h>
+#include <sound/soc-dpcm.h>
+
+struct snd_soc_jack_gpio;
+
+typedef int (*hw_write_t)(void *,const char* ,int);
+
+enum snd_soc_pcm_subclass {
+	SND_SOC_PCM_CLASS_PCM	= 0,
+	SND_SOC_PCM_CLASS_BE	= 1,
+};
+
+enum snd_soc_card_subclass {
+	SND_SOC_CARD_CLASS_INIT		= 0,
+	SND_SOC_CARD_CLASS_RUNTIME	= 1,
+};
+
+int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+			     int source, unsigned int freq, int dir);
+int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+			  unsigned int freq_in, unsigned int freq_out);
+
+int snd_soc_register_card(struct snd_soc_card *card);
+int snd_soc_unregister_card(struct snd_soc_card *card);
+int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
+#ifdef CONFIG_PM_SLEEP
+int snd_soc_suspend(struct device *dev);
+int snd_soc_resume(struct device *dev);
+#else
+static inline int snd_soc_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static inline int snd_soc_resume(struct device *dev)
+{
+	return 0;
+}
+#endif
+int snd_soc_poweroff(struct device *dev);
+int snd_soc_register_platform(struct device *dev,
+		const struct snd_soc_platform_driver *platform_drv);
+int devm_snd_soc_register_platform(struct device *dev,
+		const struct snd_soc_platform_driver *platform_drv);
+void snd_soc_unregister_platform(struct device *dev);
+int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
+		const struct snd_soc_platform_driver *platform_drv);
+void snd_soc_remove_platform(struct snd_soc_platform *platform);
+struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev);
+int snd_soc_register_codec(struct device *dev,
+		const struct snd_soc_codec_driver *codec_drv,
+		struct snd_soc_dai_driver *dai_drv, int num_dai);
+void snd_soc_unregister_codec(struct device *dev);
+int snd_soc_register_component(struct device *dev,
+			 const struct snd_soc_component_driver *cmpnt_drv,
+			 struct snd_soc_dai_driver *dai_drv, int num_dai);
+int devm_snd_soc_register_component(struct device *dev,
+			 const struct snd_soc_component_driver *cmpnt_drv,
+			 struct snd_soc_dai_driver *dai_drv, int num_dai);
+void snd_soc_unregister_component(struct device *dev);
+int snd_soc_cache_init(struct snd_soc_codec *codec);
+int snd_soc_cache_exit(struct snd_soc_codec *codec);
+
+int snd_soc_platform_read(struct snd_soc_platform *platform,
+					unsigned int reg);
+int snd_soc_platform_write(struct snd_soc_platform *platform,
+					unsigned int reg, unsigned int val);
+int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
+#ifdef CONFIG_SND_SOC_COMPRESS
+int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
+#endif
+
+struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
+		const char *dai_link, int stream);
+struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
+		const char *dai_link);
+
+bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
+void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
+void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
+
+int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
+	unsigned int dai_fmt);
+
+/* Utility functions to get clock rates from various things */
+int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
+int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
+int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots);
+int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
+
+/* set runtime hw params */
+int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
+	const struct snd_pcm_hardware *hw);
+
+int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
+		int cmd, struct snd_soc_platform *platform);
+
+int soc_dai_hw_params(struct snd_pcm_substream *substream,
+		      struct snd_pcm_hw_params *params,
+		      struct snd_soc_dai *dai);
+
+/* Jack reporting */
+int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
+	struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
+	unsigned int num_pins);
+
+void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
+int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
+			  struct snd_soc_jack_pin *pins);
+void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
+				    struct notifier_block *nb);
+void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
+				      struct notifier_block *nb);
+int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count,
+			  struct snd_soc_jack_zone *zones);
+int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage);
+#ifdef CONFIG_GPIOLIB
+int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
+			struct snd_soc_jack_gpio *gpios);
+int snd_soc_jack_add_gpiods(struct device *gpiod_dev,
+			    struct snd_soc_jack *jack,
+			    int count, struct snd_soc_jack_gpio *gpios);
+void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
+			struct snd_soc_jack_gpio *gpios);
+#else
+static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
+					 struct snd_soc_jack_gpio *gpios)
+{
+	return 0;
+}
+
+static inline int snd_soc_jack_add_gpiods(struct device *gpiod_dev,
+					  struct snd_soc_jack *jack,
+					  int count,
+					  struct snd_soc_jack_gpio *gpios)
+{
+	return 0;
+}
+
+static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
+					   struct snd_soc_jack_gpio *gpios)
+{
+}
+#endif
+
+/* codec register bit access */
+int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
+				unsigned int mask, unsigned int value);
+int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
+			       unsigned int reg, unsigned int mask,
+			       unsigned int value);
+int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
+				unsigned int mask, unsigned int value);
+
+#ifdef CONFIG_SND_SOC_AC97_BUS
+struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
+struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
+	unsigned int id, unsigned int id_mask);
+void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
+
+int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
+int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
+		struct platform_device *pdev);
+
+extern struct snd_ac97_bus_ops *soc_ac97_ops;
+#else
+static inline int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
+	struct platform_device *pdev)
+{
+	return 0;
+}
+
+static inline int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
+{
+	return 0;
+}
+#endif
+
+/*
+ *Controls
+ */
+struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
+				  void *data, const char *long_name,
+				  const char *prefix);
+struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
+					       const char *name);
+int snd_soc_add_component_controls(struct snd_soc_component *component,
+	const struct snd_kcontrol_new *controls, unsigned int num_controls);
+int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
+	const struct snd_kcontrol_new *controls, unsigned int num_controls);
+int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
+	const struct snd_kcontrol_new *controls, unsigned int num_controls);
+int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
+	const struct snd_kcontrol_new *controls, int num_controls);
+int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
+	const struct snd_kcontrol_new *controls, int num_controls);
+int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo);
+int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo);
+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_info *uinfo);
+#define snd_soc_info_bool_ext		snd_ctl_boolean_mono_info
+int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+#define snd_soc_get_volsw_2r snd_soc_get_volsw
+#define snd_soc_put_volsw_2r snd_soc_put_volsw
+int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo);
+int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_limit_volume(struct snd_soc_card *card,
+	const char *name, int max);
+int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_info *uinfo);
+int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol);
+int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol);
+int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *ucontrol);
+int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
+	unsigned int size, unsigned int __user *tlv);
+int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_info *uinfo);
+int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol);
+
+/**
+ * struct snd_soc_jack_pin - Describes a pin to update based on jack detection
+ *
+ * @pin:    name of the pin to update
+ * @mask:   bits to check for in reported jack status
+ * @invert: if non-zero then pin is enabled when status is not reported
+ * @list:   internal list entry
+ */
+struct snd_soc_jack_pin {
+	struct list_head list;
+	const char *pin;
+	int mask;
+	bool invert;
+};
+
+/**
+ * struct snd_soc_jack_zone - Describes voltage zones of jack detection
+ *
+ * @min_mv: start voltage in mv
+ * @max_mv: end voltage in mv
+ * @jack_type: type of jack that is expected for this voltage
+ * @debounce_time: debounce_time for jack, codec driver should wait for this
+ *		duration before reading the adc for voltages
+ * @list:   internal list entry
+ */
+struct snd_soc_jack_zone {
+	unsigned int min_mv;
+	unsigned int max_mv;
+	unsigned int jack_type;
+	unsigned int debounce_time;
+	struct list_head list;
+};
+
+/**
+ * struct snd_soc_jack_gpio - Describes a gpio pin for jack detection
+ *
+ * @gpio:         legacy gpio number
+ * @idx:          gpio descriptor index within the function of the GPIO
+ *                consumer device
+ * @gpiod_dev:    GPIO consumer device
+ * @name:         gpio name. Also as connection ID for the GPIO consumer
+ *                device function name lookup
+ * @report:       value to report when jack detected
+ * @invert:       report presence in low state
+ * @debounce_time: debounce time in ms
+ * @wake:	  enable as wake source
+ * @jack_status_check: callback function which overrides the detection
+ *		       to provide more complex checks (eg, reading an
+ *		       ADC).
+ */
+struct snd_soc_jack_gpio {
+	unsigned int gpio;
+	unsigned int idx;
+	struct device *gpiod_dev;
+	const char *name;
+	int report;
+	int invert;
+	int debounce_time;
+	bool wake;
+
+	/* private: */
+	struct snd_soc_jack *jack;
+	struct delayed_work work;
+	struct gpio_desc *desc;
+
+	void *data;
+	/* public: */
+	int (*jack_status_check)(void *data);
+};
+
+struct snd_soc_jack {
+	struct mutex mutex;
+	struct snd_jack *jack;
+	struct snd_soc_card *card;
+	struct list_head pins;
+	int status;
+	struct blocking_notifier_head notifier;
+	struct list_head jack_zones;
+};
+
+/* SoC PCM stream information */
+struct snd_soc_pcm_stream {
+	const char *stream_name;
+	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
+	unsigned int rates;		/* SNDRV_PCM_RATE_* */
+	unsigned int rate_min;		/* min rate */
+	unsigned int rate_max;		/* max rate */
+	unsigned int channels_min;	/* min channels */
+	unsigned int channels_max;	/* max channels */
+	unsigned int sig_bits;		/* number of bits of content */
+};
+
+/* 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);
+};
+
+struct snd_soc_compr_ops {
+	int (*startup)(struct snd_compr_stream *);
+	void (*shutdown)(struct snd_compr_stream *);
+	int (*set_params)(struct snd_compr_stream *);
+	int (*trigger)(struct snd_compr_stream *);
+};
+
+/* component interface */
+struct snd_soc_component_driver {
+	const char *name;
+
+	/* Default control and setup, added after probe() is run */
+	const struct snd_kcontrol_new *controls;
+	unsigned int num_controls;
+	const struct snd_soc_dapm_widget *dapm_widgets;
+	unsigned int num_dapm_widgets;
+	const struct snd_soc_dapm_route *dapm_routes;
+	unsigned int num_dapm_routes;
+
+	int (*probe)(struct snd_soc_component *);
+	void (*remove)(struct snd_soc_component *);
+
+	/* DT */
+	int (*of_xlate_dai_name)(struct snd_soc_component *component,
+				 struct of_phandle_args *args,
+				 const char **dai_name);
+	void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
+		int subseq);
+	int (*stream_event)(struct snd_soc_component *, int event);
+
+	/* probe ordering - for components with runtime dependencies */
+	int probe_order;
+	int remove_order;
+};
+
+struct snd_soc_component {
+	const char *name;
+	int id;
+	const char *name_prefix;
+	struct device *dev;
+	struct snd_soc_card *card;
+
+	unsigned int active;
+
+	unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
+	unsigned int registered_as_component:1;
+
+	struct list_head list;
+
+	struct snd_soc_dai_driver *dai_drv;
+	int num_dai;
+
+	const struct snd_soc_component_driver *driver;
+
+	struct list_head dai_list;
+
+	int (*read)(struct snd_soc_component *, unsigned int, unsigned int *);
+	int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
+
+	struct regmap *regmap;
+	int val_bytes;
+
+	struct mutex io_mutex;
+
+	/* attached dynamic objects */
+	struct list_head dobj_list;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_root;
+#endif
+
+	/*
+	* DO NOT use any of the fields below in drivers, they are temporary and
+	* are going to be removed again soon. If you use them in driver code the
+	* driver will be marked as BROKEN when these fields are removed.
+	*/
+
+	/* Don't use these, use snd_soc_component_get_dapm() */
+	struct snd_soc_dapm_context dapm;
+
+	const struct snd_kcontrol_new *controls;
+	unsigned int num_controls;
+	const struct snd_soc_dapm_widget *dapm_widgets;
+	unsigned int num_dapm_widgets;
+	const struct snd_soc_dapm_route *dapm_routes;
+	unsigned int num_dapm_routes;
+	struct snd_soc_codec *codec;
+
+	int (*probe)(struct snd_soc_component *);
+	void (*remove)(struct snd_soc_component *);
+
+#ifdef CONFIG_DEBUG_FS
+	void (*init_debugfs)(struct snd_soc_component *component);
+	const char *debugfs_prefix;
+#endif
+};
+
+/* SoC Audio Codec device */
+struct snd_soc_codec {
+	struct device *dev;
+	const struct snd_soc_codec_driver *driver;
+
+	struct list_head list;
+	struct list_head card_list;
+
+	/* runtime */
+	unsigned int cache_bypass:1; /* Suppress access to the cache */
+	unsigned int suspended:1; /* Codec is in suspend PM state */
+	unsigned int cache_init:1; /* codec cache has been initialized */
+
+	/* codec IO */
+	void *control_data; /* codec control (i2c/3wire) data */
+	hw_write_t hw_write;
+	void *reg_cache;
+
+	/* component */
+	struct snd_soc_component component;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_reg;
+#endif
+};
+
+/* codec driver */
+struct snd_soc_codec_driver {
+
+	/* driver ops */
+	int (*probe)(struct snd_soc_codec *);
+	int (*remove)(struct snd_soc_codec *);
+	int (*suspend)(struct snd_soc_codec *);
+	int (*resume)(struct snd_soc_codec *);
+	struct snd_soc_component_driver component_driver;
+
+	/* Default control and setup, added after probe() is run */
+	const struct snd_kcontrol_new *controls;
+	int num_controls;
+	const struct snd_soc_dapm_widget *dapm_widgets;
+	int num_dapm_widgets;
+	const struct snd_soc_dapm_route *dapm_routes;
+	int num_dapm_routes;
+
+	/* codec wide operations */
+	int (*set_sysclk)(struct snd_soc_codec *codec,
+			  int clk_id, int source, unsigned int freq, int dir);
+	int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
+		unsigned int freq_in, unsigned int freq_out);
+
+	/* codec IO */
+	struct regmap *(*get_regmap)(struct device *);
+	unsigned int (*read)(struct snd_soc_codec *, unsigned int);
+	int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
+	unsigned int reg_cache_size;
+	short reg_cache_step;
+	short reg_word_size;
+	const void *reg_cache_default;
+
+	/* codec bias level */
+	int (*set_bias_level)(struct snd_soc_codec *,
+			      enum snd_soc_bias_level level);
+	bool idle_bias_off;
+	bool suspend_bias_off;
+
+	void (*seq_notifier)(struct snd_soc_dapm_context *,
+			     enum snd_soc_dapm_type, int);
+
+	bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
+};
+
+/* SoC platform interface */
+struct snd_soc_platform_driver {
+
+	int (*probe)(struct snd_soc_platform *);
+	int (*remove)(struct snd_soc_platform *);
+	struct snd_soc_component_driver component_driver;
+
+	/* pcm creation and destruction */
+	int (*pcm_new)(struct snd_soc_pcm_runtime *);
+	void (*pcm_free)(struct snd_pcm *);
+
+	/*
+	 * For platform caused delay reporting.
+	 * Optional.
+	 */
+	snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
+		struct snd_soc_dai *);
+
+	/* platform stream pcm ops */
+	const struct snd_pcm_ops *ops;
+
+	/* platform stream compress ops */
+	const struct snd_compr_ops *compr_ops;
+
+	int (*bespoke_trigger)(struct snd_pcm_substream *, int);
+};
+
+struct snd_soc_dai_link_component {
+	const char *name;
+	struct device_node *of_node;
+	const char *dai_name;
+};
+
+struct snd_soc_platform {
+	struct device *dev;
+	const struct snd_soc_platform_driver *driver;
+
+	struct list_head list;
+
+	struct snd_soc_component component;
+};
+
+struct snd_soc_dai_link {
+	/* config - must be set by machine driver */
+	const char *name;			/* Codec name */
+	const char *stream_name;		/* Stream name */
+	/*
+	 * You MAY specify the link's CPU-side device, either by device name,
+	 * or by DT/OF node, but not both. If this information is omitted,
+	 * the CPU-side DAI is matched using .cpu_dai_name only, which hence
+	 * must be globally unique. These fields are currently typically used
+	 * only for codec to codec links, or systems using device tree.
+	 */
+	const char *cpu_name;
+	struct device_node *cpu_of_node;
+	/*
+	 * You MAY specify the DAI name of the CPU DAI. If this information is
+	 * omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node
+	 * only, which only works well when that device exposes a single DAI.
+	 */
+	const char *cpu_dai_name;
+	/*
+	 * You MUST specify the link's codec, either by device name, or by
+	 * DT/OF node, but not both.
+	 */
+	const char *codec_name;
+	struct device_node *codec_of_node;
+	/* You MUST specify the DAI name within the codec */
+	const char *codec_dai_name;
+
+	struct snd_soc_dai_link_component *codecs;
+	unsigned int num_codecs;
+
+	/*
+	 * You MAY specify the link's platform/PCM/DMA driver, either by
+	 * device name, or by DT/OF node, but not both. Some forms of link
+	 * do not need a platform.
+	 */
+	const char *platform_name;
+	struct device_node *platform_of_node;
+	int be_id;	/* optional ID for machine driver BE identification */
+
+	const struct snd_soc_pcm_stream *params;
+	unsigned int num_params;
+
+	unsigned int dai_fmt;           /* format to set on init */
+
+	enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
+
+	/* codec/machine specific init - e.g. add machine controls */
+	int (*init)(struct snd_soc_pcm_runtime *rtd);
+
+	/* optional hw_params re-writing for BE and FE sync */
+	int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
+			struct snd_pcm_hw_params *params);
+
+	/* machine stream operations */
+	const struct snd_soc_ops *ops;
+	const struct snd_soc_compr_ops *compr_ops;
+
+	/* For unidirectional dai links */
+	bool playback_only;
+	bool capture_only;
+
+	/* Mark this pcm with non atomic ops */
+	bool nonatomic;
+
+	/* Keep DAI active over suspend */
+	unsigned int ignore_suspend:1;
+
+	/* Symmetry requirements */
+	unsigned int symmetric_rates:1;
+	unsigned int symmetric_channels:1;
+	unsigned int symmetric_samplebits:1;
+
+	/* Do not create a PCM for this DAI link (Backend link) */
+	unsigned int no_pcm:1;
+
+	/* This DAI link can route to other DAI links at runtime (Frontend)*/
+	unsigned int dynamic:1;
+
+	/* DPCM capture and Playback support */
+	unsigned int dpcm_capture:1;
+	unsigned int dpcm_playback:1;
+
+	/* DPCM used FE & BE merged format */
+	unsigned int dpcm_merged_format:1;
+
+	/* pmdown_time is ignored at stop */
+	unsigned int ignore_pmdown_time:1;
+};
+
+struct snd_soc_codec_conf {
+	/*
+	 * specify device either by device name, or by
+	 * DT/OF node, but not both.
+	 */
+	const char *dev_name;
+	struct device_node *of_node;
+
+	/*
+	 * optional map of kcontrol, widget and path name prefixes that are
+	 * associated per device
+	 */
+	const char *name_prefix;
+};
+
+struct snd_soc_aux_dev {
+	const char *name;		/* Codec name */
+
+	/*
+	 * specify multi-codec either by device name, or by
+	 * DT/OF node, but not both.
+	 */
+	const char *codec_name;
+	struct device_node *codec_of_node;
+
+	/* codec/machine specific init - e.g. add machine controls */
+	int (*init)(struct snd_soc_component *component);
+};
+
+/* SoC card */
+struct snd_soc_card {
+	const char *name;
+	const char *long_name;
+	const char *driver_name;
+	struct device *dev;
+	struct snd_card *snd_card;
+	struct module *owner;
+
+	struct mutex mutex;
+	struct mutex dapm_mutex;
+
+	bool instantiated;
+
+	int (*probe)(struct snd_soc_card *card);
+	int (*late_probe)(struct snd_soc_card *card);
+	int (*remove)(struct snd_soc_card *card);
+
+	/* the pre and post PM functions are used to do any PM work before and
+	 * after the codec and DAI's do any PM work. */
+	int (*suspend_pre)(struct snd_soc_card *card);
+	int (*suspend_post)(struct snd_soc_card *card);
+	int (*resume_pre)(struct snd_soc_card *card);
+	int (*resume_post)(struct snd_soc_card *card);
+
+	/* callbacks */
+	int (*set_bias_level)(struct snd_soc_card *,
+			      struct snd_soc_dapm_context *dapm,
+			      enum snd_soc_bias_level level);
+	int (*set_bias_level_post)(struct snd_soc_card *,
+				   struct snd_soc_dapm_context *dapm,
+				   enum snd_soc_bias_level level);
+
+	long pmdown_time;
+
+	/* CPU <--> Codec DAI links  */
+	struct snd_soc_dai_link *dai_link;
+	int num_links;
+	struct snd_soc_pcm_runtime *rtd;
+	int num_rtd;
+
+	/* optional codec specific configuration */
+	struct snd_soc_codec_conf *codec_conf;
+	int num_configs;
+
+	/*
+	 * optional auxiliary devices such as amplifiers or codecs with DAI
+	 * link unused
+	 */
+	struct snd_soc_aux_dev *aux_dev;
+	int num_aux_devs;
+	struct snd_soc_pcm_runtime *rtd_aux;
+	int num_aux_rtd;
+
+	const struct snd_kcontrol_new *controls;
+	int num_controls;
+
+	/*
+	 * Card-specific routes and widgets.
+	 * Note: of_dapm_xxx for Device Tree; Otherwise for driver build-in.
+	 */
+	const struct snd_soc_dapm_widget *dapm_widgets;
+	int num_dapm_widgets;
+	const struct snd_soc_dapm_route *dapm_routes;
+	int num_dapm_routes;
+	const struct snd_soc_dapm_widget *of_dapm_widgets;
+	int num_of_dapm_widgets;
+	const struct snd_soc_dapm_route *of_dapm_routes;
+	int num_of_dapm_routes;
+	bool fully_routed;
+
+	struct work_struct deferred_resume_work;
+
+	/* lists of probed devices belonging to this card */
+	struct list_head codec_dev_list;
+
+	struct list_head widgets;
+	struct list_head paths;
+	struct list_head dapm_list;
+	struct list_head dapm_dirty;
+
+	/* attached dynamic objects */
+	struct list_head dobj_list;
+
+	/* Generic DAPM context for the card */
+	struct snd_soc_dapm_context dapm;
+	struct snd_soc_dapm_stats dapm_stats;
+	struct snd_soc_dapm_update *update;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_card_root;
+	struct dentry *debugfs_pop_time;
+#endif
+	u32 pop_time;
+
+	void *drvdata;
+};
+
+/* SoC machine DAI configuration, glues a codec and cpu DAI together */
+struct snd_soc_pcm_runtime {
+	struct device *dev;
+	struct snd_soc_card *card;
+	struct snd_soc_dai_link *dai_link;
+	struct mutex pcm_mutex;
+	enum snd_soc_pcm_subclass pcm_subclass;
+	struct snd_pcm_ops ops;
+
+	unsigned int dev_registered:1;
+
+	/* Dynamic PCM BE runtime data */
+	struct snd_soc_dpcm_runtime dpcm[2];
+	int fe_compr;
+
+	long pmdown_time;
+	unsigned char pop_wait:1;
+
+	/* runtime devices */
+	struct snd_pcm *pcm;
+	struct snd_compr *compr;
+	struct snd_soc_codec *codec;
+	struct snd_soc_platform *platform;
+	struct snd_soc_dai *codec_dai;
+	struct snd_soc_dai *cpu_dai;
+	struct snd_soc_component *component; /* Only valid for AUX dev rtds */
+
+	struct snd_soc_dai **codec_dais;
+	unsigned int num_codecs;
+
+	struct delayed_work delayed_work;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_dpcm_root;
+	struct dentry *debugfs_dpcm_state;
+#endif
+};
+
+/* mixer control */
+struct soc_mixer_control {
+	int min, max, platform_max;
+	int reg, rreg;
+	unsigned int shift, rshift;
+	unsigned int sign_bit;
+	unsigned int invert:1;
+	unsigned int autodisable:1;
+	struct snd_soc_dobj dobj;
+};
+
+struct soc_bytes {
+	int base;
+	int num_regs;
+	u32 mask;
+};
+
+struct soc_bytes_ext {
+	int max;
+	struct snd_soc_dobj dobj;
+
+	/* used for TLV byte control */
+	int (*get)(unsigned int __user *bytes, unsigned int size);
+	int (*put)(const unsigned int __user *bytes, unsigned int size);
+};
+
+/* multi register control */
+struct soc_mreg_control {
+	long min, max;
+	unsigned int regbase, regcount, nbits, invert;
+};
+
+/* enumerated kcontrol */
+struct soc_enum {
+	int reg;
+	unsigned char shift_l;
+	unsigned char shift_r;
+	unsigned int items;
+	unsigned int mask;
+	const char * const *texts;
+	const unsigned int *values;
+	unsigned int autodisable:1;
+	struct snd_soc_dobj dobj;
+};
+
+/**
+ * snd_soc_component_to_codec() - Casts a component to the CODEC it is embedded in
+ * @component: The component to cast to a CODEC
+ *
+ * This function must only be used on components that are known to be CODECs.
+ * Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_codec *snd_soc_component_to_codec(
+	struct snd_soc_component *component)
+{
+	return container_of(component, struct snd_soc_codec, component);
+}
+
+/**
+ * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in
+ * @component: The component to cast to a platform
+ *
+ * This function must only be used on components that are known to be platforms.
+ * Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_platform *snd_soc_component_to_platform(
+	struct snd_soc_component *component)
+{
+	return container_of(component, struct snd_soc_platform, component);
+}
+
+/**
+ * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
+ *  embedded in
+ * @dapm: The DAPM context to cast to the component
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a component (e.g. in a component driver). Otherwise the behavior is
+ * undefined.
+ */
+static inline struct snd_soc_component *snd_soc_dapm_to_component(
+	struct snd_soc_dapm_context *dapm)
+{
+	return container_of(dapm, struct snd_soc_component, dapm);
+}
+
+/**
+ * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
+ * @dapm: The DAPM context to cast to the CODEC
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
+	struct snd_soc_dapm_context *dapm)
+{
+	return snd_soc_component_to_codec(snd_soc_dapm_to_component(dapm));
+}
+
+/**
+ * snd_soc_dapm_to_platform() - Casts a DAPM context to the platform it is
+ *  embedded in
+ * @dapm: The DAPM context to cast to the platform.
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a platform (e.g. in a platform driver). Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
+	struct snd_soc_dapm_context *dapm)
+{
+	return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
+}
+
+/**
+ * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
+ *  component
+ * @component: The component for which to get the DAPM context
+ */
+static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
+	struct snd_soc_component *component)
+{
+	return &component->dapm;
+}
+
+/**
+ * snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
+ * @codec: The CODEC for which to get the DAPM context
+ *
+ * Note: Use this function instead of directly accessing the CODEC's dapm field
+ */
+static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
+	struct snd_soc_codec *codec)
+{
+	return snd_soc_component_get_dapm(&codec->component);
+}
+
+/**
+ * snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
+ * @codec: The CODEC for which to initialize the DAPM bias level
+ * @level: The DAPM level to initialize to
+ *
+ * Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
+ */
+static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
+	enum snd_soc_bias_level level)
+{
+	snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
+}
+
+/**
+ * snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
+ * @codec: The CODEC for which to get the DAPM bias level
+ *
+ * Returns: The current DAPM bias level of the CODEC.
+ */
+static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
+	struct snd_soc_codec *codec)
+{
+	return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
+}
+
+/**
+ * snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
+ * @codec: The CODEC for which to set the level
+ * @level: The level to set to
+ *
+ * Forces the CODEC bias level to a specific state. See
+ * snd_soc_dapm_force_bias_level().
+ */
+static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
+	enum snd_soc_bias_level level)
+{
+	return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
+		level);
+}
+
+/**
+ * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
+ * @kcontrol: The kcontrol
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(
+	struct snd_kcontrol *kcontrol)
+{
+	return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
+}
+
+/* codec IO */
+unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
+int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
+	unsigned int val);
+
+/**
+ * snd_soc_cache_sync() - Sync the register cache with the hardware
+ * @codec: CODEC to sync
+ *
+ * Note: This function will call regcache_sync()
+ */
+static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
+{
+	return regcache_sync(codec->component.regmap);
+}
+
+/* component IO */
+int snd_soc_component_read(struct snd_soc_component *component,
+	unsigned int reg, unsigned int *val);
+int snd_soc_component_write(struct snd_soc_component *component,
+	unsigned int reg, unsigned int val);
+int snd_soc_component_update_bits(struct snd_soc_component *component,
+	unsigned int reg, unsigned int mask, unsigned int val);
+int snd_soc_component_update_bits_async(struct snd_soc_component *component,
+	unsigned int reg, unsigned int mask, unsigned int val);
+void snd_soc_component_async_complete(struct snd_soc_component *component);
+int snd_soc_component_test_bits(struct snd_soc_component *component,
+	unsigned int reg, unsigned int mask, unsigned int value);
+
+#ifdef CONFIG_REGMAP
+
+void snd_soc_component_init_regmap(struct snd_soc_component *component,
+	struct regmap *regmap);
+void snd_soc_component_exit_regmap(struct snd_soc_component *component);
+
+/**
+ * snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC
+ * @codec: The CODEC for which to initialize the regmap instance
+ * @regmap: The regmap instance that should be used by the CODEC
+ *
+ * This function allows deferred assignment of the regmap instance that is
+ * associated with the CODEC. Only use this if the regmap instance is not yet
+ * ready when the CODEC is registered. The function must also be called before
+ * the first IO attempt of the CODEC.
+ */
+static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec,
+	struct regmap *regmap)
+{
+	snd_soc_component_init_regmap(&codec->component, regmap);
+}
+
+/**
+ * snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC
+ * @codec: The CODEC for which to de-initialize the regmap instance
+ *
+ * Calls regmap_exit() on the regmap instance associated to the CODEC and
+ * removes the regmap instance from the CODEC.
+ *
+ * This function should only be used if snd_soc_codec_init_regmap() was used to
+ * initialize the regmap instance.
+ */
+static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec)
+{
+	snd_soc_component_exit_regmap(&codec->component);
+}
+
+#endif
+
+/* device driver data */
+
+static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
+		void *data)
+{
+	card->drvdata = data;
+}
+
+static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
+{
+	return card->drvdata;
+}
+
+static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
+		void *data)
+{
+	dev_set_drvdata(c->dev, data);
+}
+
+static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
+{
+	return dev_get_drvdata(c->dev);
+}
+
+static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
+		void *data)
+{
+	snd_soc_component_set_drvdata(&codec->component, data);
+}
+
+static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
+{
+	return snd_soc_component_get_drvdata(&codec->component);
+}
+
+static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
+		void *data)
+{
+	snd_soc_component_set_drvdata(&platform->component, data);
+}
+
+static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
+{
+	return snd_soc_component_get_drvdata(&platform->component);
+}
+
+static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
+		void *data)
+{
+	dev_set_drvdata(rtd->dev, data);
+}
+
+static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
+{
+	return dev_get_drvdata(rtd->dev);
+}
+
+static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
+{
+	INIT_LIST_HEAD(&card->codec_dev_list);
+	INIT_LIST_HEAD(&card->widgets);
+	INIT_LIST_HEAD(&card->paths);
+	INIT_LIST_HEAD(&card->dapm_list);
+}
+
+static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
+{
+	if (mc->reg == mc->rreg && mc->shift == mc->rshift)
+		return 0;
+	/*
+	 * mc->reg == mc->rreg && mc->shift != mc->rshift, or
+	 * mc->reg != mc->rreg means that the control is
+	 * stereo (bits in one register or in two registers)
+	 */
+	return 1;
+}
+
+static inline unsigned int snd_soc_enum_val_to_item(struct soc_enum *e,
+	unsigned int val)
+{
+	unsigned int i;
+
+	if (!e->values)
+		return val;
+
+	for (i = 0; i < e->items; i++)
+		if (val == e->values[i])
+			return i;
+
+	return 0;
+}
+
+static inline unsigned int snd_soc_enum_item_to_val(struct soc_enum *e,
+	unsigned int item)
+{
+	if (!e->values)
+		return item;
+
+	return e->values[item];
+}
+
+static inline bool snd_soc_component_is_active(
+	struct snd_soc_component *component)
+{
+	return component->active != 0;
+}
+
+static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
+{
+	return snd_soc_component_is_active(&codec->component);
+}
+
+/**
+ * snd_soc_kcontrol_component() - Returns the component that registered the
+ *  control
+ * @kcontrol: The control for which to get the component
+ *
+ * Note: This function will work correctly if the control has been registered
+ * for a component. Either with snd_soc_add_codec_controls() or
+ * snd_soc_add_platform_controls() or via  table based setup for either a
+ * CODEC, a platform or component driver. Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_component *snd_soc_kcontrol_component(
+	struct snd_kcontrol *kcontrol)
+{
+	return snd_kcontrol_chip(kcontrol);
+}
+
+/**
+ * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control
+ * @kcontrol: The control for which to get the CODEC
+ *
+ * Note: This function will only work correctly if the control has been
+ * registered with snd_soc_add_codec_controls() or via table based setup of
+ * snd_soc_codec_driver. Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
+	struct snd_kcontrol *kcontrol)
+{
+	return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol));
+}
+
+/**
+ * snd_soc_kcontrol_platform() - Returns the platform that registered the control
+ * @kcontrol: The control for which to get the platform
+ *
+ * Note: This function will only work correctly if the control has been
+ * registered with snd_soc_add_platform_controls() or via table based setup of
+ * a snd_soc_platform_driver. Otherwise the behavior is undefined.
+ */
+static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
+	struct snd_kcontrol *kcontrol)
+{
+	return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol));
+}
+
+int snd_soc_util_init(void);
+void snd_soc_util_exit(void);
+
+int snd_soc_of_parse_card_name(struct snd_soc_card *card,
+			       const char *propname);
+int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
+					  const char *propname);
+int snd_soc_of_parse_tdm_slot(struct device_node *np,
+			      unsigned int *tx_mask,
+			      unsigned int *rx_mask,
+			      unsigned int *slots,
+			      unsigned int *slot_width);
+void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
+				   struct snd_soc_codec_conf *codec_conf,
+				   struct device_node *of_node,
+				   const char *propname);
+int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
+				   const char *propname);
+unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
+				     const char *prefix,
+				     struct device_node **bitclkmaster,
+				     struct device_node **framemaster);
+int snd_soc_of_get_dai_name(struct device_node *of_node,
+			    const char **dai_name);
+int snd_soc_of_get_dai_link_codecs(struct device *dev,
+				   struct device_node *of_node,
+				   struct snd_soc_dai_link *dai_link);
+
+#include <sound/soc-dai.h>
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *snd_soc_debugfs_root;
+#endif
+
+extern const struct dev_pm_ops snd_soc_pm_ops;
+
+/* Helper functions */
+static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm)
+{
+	mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+}
+
+static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
+{
+	mutex_unlock(&dapm->card->dapm_mutex);
+}
+
+#endif
diff --git a/include/sound/soundfont.h b/include/sound/soundfont.h
new file mode 100644
index 0000000..7c93efd
--- /dev/null
+++ b/include/sound/soundfont.h
@@ -0,0 +1,129 @@
+#ifndef __SOUND_SOUNDFONT_H
+#define __SOUND_SOUNDFONT_H
+
+/*
+ *  Soundfont defines and definitions.
+ *
+ *  Copyright (C) 1999 Steve Ratcliffe
+ *  Copyright (c) 1999-2000 Takashi iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/sfnt_info.h>
+#include <sound/util_mem.h>
+
+#define SF_MAX_INSTRUMENTS	128	/* maximum instrument number */
+#define SF_MAX_PRESETS  256	/* drums are mapped from 128 to 256 */
+#define SF_IS_DRUM_BANK(z) ((z) == 128)
+
+struct snd_sf_zone {
+	struct snd_sf_zone *next;	/* Link to next */
+	unsigned char bank;		/* Midi bank for this zone */
+	unsigned char instr;		/* Midi program for this zone */
+	unsigned char mapped;		/* True if mapped to something else */
+
+	struct soundfont_voice_info v;	/* All the soundfont parameters */
+	int counter;
+	struct snd_sf_sample *sample;	/* Link to sample */
+
+	/* The following deals with preset numbers (programs) */
+	struct snd_sf_zone *next_instr;	/* Next zone of this instrument */
+	struct snd_sf_zone *next_zone;	/* Next zone in play list */
+};
+
+struct snd_sf_sample {
+	struct soundfont_sample_info v;
+	int counter;
+	struct snd_util_memblk *block;	/* allocated data block */
+	struct snd_sf_sample *next;
+};
+
+/*
+ * This represents all the information relating to a soundfont.
+ */
+struct snd_soundfont {
+	struct snd_soundfont *next;	/* Link to next */
+	/*struct snd_soundfont *prev;*/	/* Link to previous */
+	short  id;		/* file id */
+	short  type;		/* font type */
+	unsigned char name[SNDRV_SFNT_PATCH_NAME_LEN];	/* identifier */
+	struct snd_sf_zone *zones; /* Font information */
+	struct snd_sf_sample *samples; /* The sample headers */
+};
+
+/*
+ * Type of the sample access callback
+ */
+struct snd_sf_callback {
+	void *private_data;
+	int (*sample_new)(void *private_data, struct snd_sf_sample *sp,
+			  struct snd_util_memhdr *hdr,
+			  const void __user *buf, long count);
+	int (*sample_free)(void *private_data, struct snd_sf_sample *sp,
+			   struct snd_util_memhdr *hdr);
+	void (*sample_reset)(void *private);
+};
+
+/*
+ * List of soundfonts.
+ */
+struct snd_sf_list {
+	struct snd_soundfont *currsf; /* The currently open soundfont */
+	int open_client;	/* client pointer for lock */
+	int mem_used;		/* used memory size */
+	struct snd_sf_zone *presets[SF_MAX_PRESETS];
+	struct snd_soundfont *fonts; /* The list of soundfonts */
+	int fonts_size;	/* number of fonts allocated */
+	int zone_counter;	/* last allocated time for zone */
+	int sample_counter;	/* last allocated time for sample */
+	int zone_locked;	/* locked time for zone */
+	int sample_locked;	/* locked time for sample */
+	struct snd_sf_callback callback;	/* callback functions */
+	int presets_locked;
+	struct mutex presets_mutex;
+	spinlock_t lock;
+	struct snd_util_memhdr *memhdr;
+};
+
+/* Prototypes for soundfont.c */
+int snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
+		       long count, int client);
+int snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
+				long count, int client);
+int snd_soundfont_close_check(struct snd_sf_list *sflist, int client);
+
+struct snd_sf_list *snd_sf_new(struct snd_sf_callback *callback,
+			       struct snd_util_memhdr *hdr);
+void snd_sf_free(struct snd_sf_list *sflist);
+
+int snd_soundfont_remove_samples(struct snd_sf_list *sflist);
+int snd_soundfont_remove_unlocked(struct snd_sf_list *sflist);
+
+int snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
+			      int preset, int bank,
+			      int def_preset, int def_bank,
+			      struct snd_sf_zone **table, int max_layers);
+
+/* Parameter conversions */
+int snd_sf_calc_parm_hold(int msec);
+int snd_sf_calc_parm_attack(int msec);
+int snd_sf_calc_parm_decay(int msec);
+#define snd_sf_calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725)
+extern int snd_sf_vol_table[128];
+int snd_sf_linear_to_log(unsigned int amount, int offset, int ratio);
+
+
+#endif /* __SOUND_SOUNDFONT_H */
diff --git a/include/sound/spear_dma.h b/include/sound/spear_dma.h
new file mode 100644
index 0000000..e290de4
--- /dev/null
+++ b/include/sound/spear_dma.h
@@ -0,0 +1,34 @@
+/*
+* linux/spear_dma.h
+*
+* Copyright (ST) 2012 Rajeev Kumar (rajeevkumar.linux@gmail.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
+*
+*/
+
+#ifndef SPEAR_DMA_H
+#define SPEAR_DMA_H
+
+#include <linux/dmaengine.h>
+
+struct spear_dma_data {
+	void *data;
+	dma_addr_t addr;
+	u32 max_burst;
+	enum dma_slave_buswidth addr_width;
+};
+
+#endif /* SPEAR_DMA_H */
diff --git a/include/sound/spear_spdif.h b/include/sound/spear_spdif.h
new file mode 100644
index 0000000..a12f396
--- /dev/null
+++ b/include/sound/spear_spdif.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (ST) 2012 Vipin Kumar (vipin.kumar@st.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
+ */
+
+#ifndef __SOUND_SPDIF_H
+#define __SOUND_SPDIF_H
+
+struct spear_spdif_platform_data {
+	/* DMA params */
+	void *dma_params;
+	bool (*filter)(struct dma_chan *chan, void *slave);
+	void (*reset_perip)(void);
+};
+
+#endif /* SOUND_SPDIF_H */
diff --git a/include/sound/sta32x.h b/include/sound/sta32x.h
new file mode 100644
index 0000000..a894f7d
--- /dev/null
+++ b/include/sound/sta32x.h
@@ -0,0 +1,43 @@
+/*
+ * Platform data for ST STA32x ASoC codec driver.
+ *
+ * Copyright: 2011 Raumfeld GmbH
+ * Author: Johannes Stezenbach <js@sig21.net>
+ *
+ * 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.
+ */
+#ifndef __LINUX_SND__STA32X_H
+#define __LINUX_SND__STA32X_H
+
+#define STA32X_OCFG_2CH		0
+#define STA32X_OCFG_2_1CH	1
+#define STA32X_OCFG_1CH		3
+
+#define STA32X_OM_CH1		0
+#define STA32X_OM_CH2		1
+#define STA32X_OM_CH3		2
+
+#define STA32X_THERMAL_ADJUSTMENT_ENABLE	1
+#define STA32X_THERMAL_RECOVERY_ENABLE		2
+
+struct sta32x_platform_data {
+	u8 output_conf;
+	u8 ch1_output_mapping;
+	u8 ch2_output_mapping;
+	u8 ch3_output_mapping;
+	int needs_esd_watchdog;
+	u8 drop_compensation_ns;
+	unsigned int thermal_warning_recovery:1;
+	unsigned int thermal_warning_adjustment:1;
+	unsigned int fault_detect_recovery:1;
+	unsigned int max_power_use_mpcc:1;
+	unsigned int max_power_correction:1;
+	unsigned int am_reduction_mode:1;
+	unsigned int odd_pwm_speed_mode:1;
+	unsigned int invalid_input_detect_mute:1;
+};
+
+#endif /* __LINUX_SND__STA32X_H */
diff --git a/include/sound/sta350.h b/include/sound/sta350.h
new file mode 100644
index 0000000..42edceb
--- /dev/null
+++ b/include/sound/sta350.h
@@ -0,0 +1,57 @@
+/*
+ * Platform data for ST STA350 ASoC codec driver.
+ *
+ * Copyright: 2014 Raumfeld GmbH
+ * Author: Sven Brandau <info@brandau.biz>
+ *
+ * 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.
+ */
+#ifndef __LINUX_SND__STA350_H
+#define __LINUX_SND__STA350_H
+
+#define STA350_OCFG_2CH		0
+#define STA350_OCFG_2_1CH	1
+#define STA350_OCFG_1CH		3
+
+#define STA350_OM_CH1		0
+#define STA350_OM_CH2		1
+#define STA350_OM_CH3		2
+
+#define STA350_THERMAL_ADJUSTMENT_ENABLE	1
+#define STA350_THERMAL_RECOVERY_ENABLE		2
+#define STA350_FAULT_DETECT_RECOVERY_BYPASS	1
+
+#define STA350_FFX_PM_DROP_COMP			0
+#define STA350_FFX_PM_TAPERED_COMP		1
+#define STA350_FFX_PM_FULL_POWER		2
+#define STA350_FFX_PM_VARIABLE_DROP_COMP	3
+
+
+struct sta350_platform_data {
+	u8 output_conf;
+	u8 ch1_output_mapping;
+	u8 ch2_output_mapping;
+	u8 ch3_output_mapping;
+	u8 ffx_power_output_mode;
+	u8 drop_compensation_ns;
+	u8 powerdown_delay_divider;
+	unsigned int thermal_warning_recovery:1;
+	unsigned int thermal_warning_adjustment:1;
+	unsigned int fault_detect_recovery:1;
+	unsigned int oc_warning_adjustment:1;
+	unsigned int max_power_use_mpcc:1;
+	unsigned int max_power_correction:1;
+	unsigned int am_reduction_mode:1;
+	unsigned int odd_pwm_speed_mode:1;
+	unsigned int distortion_compensation:1;
+	unsigned int invalid_input_detect_mute:1;
+	unsigned int activate_mute_output:1;
+	unsigned int bridge_immediate_off:1;
+	unsigned int noise_shape_dc_cut:1;
+	unsigned int powerdown_master_vol:1;
+};
+
+#endif /* __LINUX_SND__STA350_H */
diff --git a/include/sound/tas2552-plat.h b/include/sound/tas2552-plat.h
new file mode 100644
index 0000000..65e7627
--- /dev/null
+++ b/include/sound/tas2552-plat.h
@@ -0,0 +1,25 @@
+/*
+ * TAS2552 driver platform header
+ *
+ * Copyright (C) 2014 Texas Instruments Inc.
+ *
+ * Author: Dan Murphy <dmurphy@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef TAS2552_PLAT_H
+#define TAS2552_PLAT_H
+
+struct tas2552_platform_data {
+	int enable_gpio;
+};
+
+#endif
diff --git a/include/sound/tas5086.h b/include/sound/tas5086.h
new file mode 100644
index 0000000..aac481b
--- /dev/null
+++ b/include/sound/tas5086.h
@@ -0,0 +1,7 @@
+#ifndef _SND_SOC_CODEC_TAS5086_H_
+#define _SND_SOC_CODEC_TAS5086_H_
+
+#define TAS5086_CLK_IDX_MCLK	0
+#define TAS5086_CLK_IDX_SCLK	1
+
+#endif /* _SND_SOC_CODEC_TAS5086_H_ */
diff --git a/include/sound/tea6330t.h b/include/sound/tea6330t.h
new file mode 100644
index 0000000..e6beec2
--- /dev/null
+++ b/include/sound/tea6330t.h
@@ -0,0 +1,31 @@
+#ifndef __SOUND_TEA6330T_H
+#define __SOUND_TEA6330T_H
+
+/*
+ *  Routines for control of TEA6330T circuit.
+ *  Sound fader control circuit for car radios.
+ *
+ *   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 <sound/i2c.h>		/* generic i2c support */
+
+int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer);
+int snd_tea6330t_update_mixer(struct snd_card *card, struct snd_i2c_bus *bus,
+			      int equalizer, int fader);
+
+#endif /* __SOUND_TEA6330T_H */
diff --git a/include/sound/timer.h b/include/sound/timer.h
new file mode 100644
index 0000000..7990469
--- /dev/null
+++ b/include/sound/timer.h
@@ -0,0 +1,143 @@
+#ifndef __SOUND_TIMER_H
+#define __SOUND_TIMER_H
+
+/*
+ *  Timer abstract layer
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *		     Abramo Bagnara <abramo@alsa-project.org>
+ *
+ *
+ *   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 <sound/asound.h>
+#include <linux/interrupt.h>
+
+#define snd_timer_chip(timer) ((timer)->private_data)
+
+#define SNDRV_TIMER_DEVICES	16
+
+#define SNDRV_TIMER_DEV_FLG_PCM	0x10000000
+
+#define SNDRV_TIMER_HW_AUTO	0x00000001	/* auto trigger is supported */
+#define SNDRV_TIMER_HW_STOP	0x00000002	/* call stop before start */
+#define SNDRV_TIMER_HW_SLAVE	0x00000004	/* only slave timer (variable resolution) */
+#define SNDRV_TIMER_HW_FIRST	0x00000008	/* first tick can be incomplete */
+#define SNDRV_TIMER_HW_TASKLET	0x00000010	/* timer is called from tasklet */
+
+#define SNDRV_TIMER_IFLG_SLAVE	  0x00000001
+#define SNDRV_TIMER_IFLG_RUNNING  0x00000002
+#define SNDRV_TIMER_IFLG_START	  0x00000004
+#define SNDRV_TIMER_IFLG_AUTO	  0x00000008	/* auto restart */
+#define SNDRV_TIMER_IFLG_FAST	  0x00000010	/* fast callback (do not use tasklet) */
+#define SNDRV_TIMER_IFLG_CALLBACK 0x00000020	/* timer callback is active */
+#define SNDRV_TIMER_IFLG_EXCLUSIVE 0x00000040	/* exclusive owner - no more instances */
+#define SNDRV_TIMER_IFLG_EARLY_EVENT 0x00000080	/* write early event to the poll queue */
+
+#define SNDRV_TIMER_FLG_CHANGE	0x00000001
+#define SNDRV_TIMER_FLG_RESCHED	0x00000002	/* need reschedule */
+
+struct snd_timer;
+
+struct snd_timer_hardware {
+	/* -- must be filled with low-level driver */
+	unsigned int flags;		/* various flags */
+	unsigned long resolution;	/* average timer resolution for one tick in nsec */
+	unsigned long resolution_min;	/* minimal resolution */
+	unsigned long resolution_max;	/* maximal resolution */
+	unsigned long ticks;		/* max timer ticks per interrupt */
+	/* -- low-level functions -- */
+	int (*open) (struct snd_timer * timer);
+	int (*close) (struct snd_timer * timer);
+	unsigned long (*c_resolution) (struct snd_timer * timer);
+	int (*start) (struct snd_timer * timer);
+	int (*stop) (struct snd_timer * timer);
+	int (*set_period) (struct snd_timer * timer, unsigned long period_num, unsigned long period_den);
+	int (*precise_resolution) (struct snd_timer * timer, unsigned long *num, unsigned long *den);
+};
+
+struct snd_timer {
+	int tmr_class;
+	struct snd_card *card;
+	struct module *module;
+	int tmr_device;
+	int tmr_subdevice;
+	char id[64];
+	char name[80];
+	unsigned int flags;
+	int running;			/* running instances */
+	unsigned long sticks;		/* schedule ticks */
+	void *private_data;
+	void (*private_free) (struct snd_timer *timer);
+	struct snd_timer_hardware hw;
+	spinlock_t lock;
+	struct list_head device_list;
+	struct list_head open_list_head;
+	struct list_head active_list_head;
+	struct list_head ack_list_head;
+	struct list_head sack_list_head; /* slow ack list head */
+	struct tasklet_struct task_queue;
+};
+
+struct snd_timer_instance {
+	struct snd_timer *timer;
+	char *owner;
+	unsigned int flags;
+	void *private_data;
+	void (*private_free) (struct snd_timer_instance *ti);
+	void (*callback) (struct snd_timer_instance *timeri,
+			  unsigned long ticks, unsigned long resolution);
+	void (*ccallback) (struct snd_timer_instance * timeri,
+			   int event,
+			   struct timespec * tstamp,
+			   unsigned long resolution);
+	void *callback_data;
+	unsigned long ticks;		/* auto-load ticks when expired */
+	unsigned long cticks;		/* current ticks */
+	unsigned long pticks;		/* accumulated ticks for callback */
+	unsigned long resolution;	/* current resolution for tasklet */
+	unsigned long lost;		/* lost ticks */
+	int slave_class;
+	unsigned int slave_id;
+	struct list_head open_list;
+	struct list_head active_list;
+	struct list_head ack_list;
+	struct list_head slave_list_head;
+	struct list_head slave_active_head;
+	struct snd_timer_instance *master;
+};
+
+/*
+ *  Registering
+ */
+
+int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, struct snd_timer **rtimer);
+void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp);
+int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer);
+int snd_timer_global_free(struct snd_timer *timer);
+int snd_timer_global_register(struct snd_timer *timer);
+
+int snd_timer_open(struct snd_timer_instance **ti, char *owner, struct snd_timer_id *tid, unsigned int slave_id);
+int snd_timer_close(struct snd_timer_instance *timeri);
+unsigned long snd_timer_resolution(struct snd_timer_instance *timeri);
+int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks);
+int snd_timer_stop(struct snd_timer_instance *timeri);
+int snd_timer_continue(struct snd_timer_instance *timeri);
+int snd_timer_pause(struct snd_timer_instance *timeri);
+
+void snd_timer_interrupt(struct snd_timer *timer, unsigned long ticks_left);
+
+#endif /* __SOUND_TIMER_H */
diff --git a/include/sound/tlv.h b/include/sound/tlv.h
new file mode 100644
index 0000000..df97d19
--- /dev/null
+++ b/include/sound/tlv.h
@@ -0,0 +1,88 @@
+#ifndef __SOUND_TLV_H
+#define __SOUND_TLV_H
+
+/*
+ *  Advanced Linux Sound Architecture - ALSA - Driver
+ *  Copyright (c) 2006 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
+ *
+ */
+
+/*
+ * TLV structure is right behind the struct snd_ctl_tlv:
+ *   unsigned int type  	- see SNDRV_CTL_TLVT_*
+ *   unsigned int length
+ *   .... data aligned to sizeof(unsigned int), use
+ *        block_length = (length + (sizeof(unsigned int) - 1)) &
+ *                       ~(sizeof(unsigned int) - 1)) ....
+ */
+
+#include <uapi/sound/tlv.h>
+
+#define TLV_ITEM(type, ...) \
+	(type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__
+#define TLV_LENGTH(...) \
+	((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ }))
+
+#define TLV_CONTAINER_ITEM(...) \
+	TLV_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__)
+#define DECLARE_TLV_CONTAINER(name, ...) \
+	unsigned int name[] = { TLV_CONTAINER_ITEM(__VA_ARGS__) }
+
+#define TLV_DB_SCALE_MASK	0xffff
+#define TLV_DB_SCALE_MUTE	0x10000
+#define TLV_DB_SCALE_ITEM(min, step, mute)			\
+	TLV_ITEM(SNDRV_CTL_TLVT_DB_SCALE,			\
+		 (min),					\
+		 ((step) & TLV_DB_SCALE_MASK) |		\
+			((mute) ? TLV_DB_SCALE_MUTE : 0))
+#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
+	unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
+
+/* dB scale specified with min/max values instead of step */
+#define TLV_DB_MINMAX_ITEM(min_dB, max_dB)			\
+	TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
+#define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB)			\
+	TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB))
+#define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \
+	unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) }
+#define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \
+	unsigned int name[] = { TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) }
+
+/* linear volume between min_dB and max_dB (.01dB unit) */
+#define TLV_DB_LINEAR_ITEM(min_dB, max_dB)		    \
+	TLV_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
+#define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB)	\
+	unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) }
+
+/* dB range container:
+ * Items in dB range container must be ordered by their values and by their
+ * dB values. This implies that larger values must correspond with larger
+ * dB values (which is also required for all other mixer controls).
+ */
+/* Each item is: <min> <max> <TLV> */
+#define TLV_DB_RANGE_ITEM(...) \
+	TLV_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__)
+#define DECLARE_TLV_DB_RANGE(name, ...) \
+	unsigned int name[] = { TLV_DB_RANGE_ITEM(__VA_ARGS__) }
+/* The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR */
+#define TLV_DB_RANGE_HEAD(num)			\
+	SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int)
+
+#define TLV_DB_GAIN_MUTE	-9999999
+
+#endif /* __SOUND_TLV_H */
diff --git a/include/sound/tlv320aic32x4.h b/include/sound/tlv320aic32x4.h
new file mode 100644
index 0000000..24e5d99
--- /dev/null
+++ b/include/sound/tlv320aic32x4.h
@@ -0,0 +1,32 @@
+/*
+ * tlv320aic32x4.h  --  TLV320AIC32X4 Soc Audio driver platform data
+ *
+ * Copyright 2011 Vista Silicon S.L.
+ *
+ * Author: Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _AIC32X4_PDATA_H
+#define _AIC32X4_PDATA_H
+
+#define AIC32X4_PWR_MICBIAS_2075_LDOIN		0x00000001
+#define AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE	0x00000002
+#define AIC32X4_PWR_AIC32X4_LDO_ENABLE		0x00000004
+#define AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36	0x00000008
+#define AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED	0x00000010
+
+#define AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K	0x00000001
+#define AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K	0x00000002
+
+struct aic32x4_pdata {
+	u32 power_cfg;
+	u32 micpga_routing;
+	bool swapdacs;
+	int rstn_gpio;
+};
+
+#endif
diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h
new file mode 100644
index 0000000..9407fd0
--- /dev/null
+++ b/include/sound/tlv320aic3x.h
@@ -0,0 +1,68 @@
+/*
+ * Platform data for Texas Instruments TLV320AIC3x codec
+ *
+ * Author: Jarkko Nikula <jarkko.nikula@bitmer.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __TLV320AIC3x_H__
+#define __TLV320AIC3x_H__
+
+/* GPIO API */
+enum {
+	AIC3X_GPIO1_FUNC_DISABLED		= 0,
+	AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC	= 1,
+	AIC3X_GPIO1_FUNC_CLOCK_MUX		= 2,
+	AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2		= 3,
+	AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4		= 4,
+	AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8		= 5,
+	AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ	= 6,
+	AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ		= 7,
+	AIC3X_GPIO1_FUNC_INPUT			= 8,
+	AIC3X_GPIO1_FUNC_OUTPUT			= 9,
+	AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK	= 10,
+	AIC3X_GPIO1_FUNC_AUDIO_WORDCLK		= 11,
+	AIC3X_GPIO1_FUNC_BUTTON_IRQ		= 12,
+	AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ	= 13,
+	AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ	= 14,
+	AIC3X_GPIO1_FUNC_ALL_IRQ		= 16
+};
+
+enum {
+	AIC3X_GPIO2_FUNC_DISABLED		= 0,
+	AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ	= 2,
+	AIC3X_GPIO2_FUNC_INPUT			= 3,
+	AIC3X_GPIO2_FUNC_OUTPUT			= 4,
+	AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT	= 5,
+	AIC3X_GPIO2_FUNC_AUDIO_BITCLK		= 8,
+	AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
+	AIC3X_GPIO2_FUNC_ALL_IRQ		= 10,
+	AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
+	AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
+	AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ	= 13,
+	AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ		= 14,
+	AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ	= 15
+};
+
+enum aic3x_micbias_voltage {
+	AIC3X_MICBIAS_OFF = 0,
+	AIC3X_MICBIAS_2_0V = 1,
+	AIC3X_MICBIAS_2_5V = 2,
+	AIC3X_MICBIAS_AVDDV = 3,
+};
+
+struct aic3x_setup_data {
+	unsigned int gpio_func[2];
+};
+
+struct aic3x_pdata {
+	int gpio_reset; /* < 0 if not used */
+	struct aic3x_setup_data *setup;
+
+	/* Selects the micbias voltage */
+	enum aic3x_micbias_voltage micbias_vg;
+};
+
+#endif
diff --git a/include/sound/tlv320dac33-plat.h b/include/sound/tlv320dac33-plat.h
new file mode 100644
index 0000000..0b94192
--- /dev/null
+++ b/include/sound/tlv320dac33-plat.h
@@ -0,0 +1,24 @@
+/*
+ * Platform header for Texas Instruments TLV320DAC33 codec driver
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * Copyright:   (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __TLV320DAC33_PLAT_H
+#define __TLV320DAC33_PLAT_H
+
+struct tlv320dac33_platform_data {
+	int power_gpio;
+	int mode1_latency; /* latency caused by the i2c writes in us */
+	int auto_fifo_config; /* FIFO config based on the period size */
+	int keep_bclk;	/* Keep the BCLK running in FIFO modes */
+	u8 burst_bclkdiv;
+};
+
+#endif /* __TLV320DAC33_PLAT_H */
diff --git a/include/sound/tpa6130a2-plat.h b/include/sound/tpa6130a2-plat.h
new file mode 100644
index 0000000..4cc1093
--- /dev/null
+++ b/include/sound/tpa6130a2-plat.h
@@ -0,0 +1,30 @@
+/*
+ * TPA6130A2 driver platform header
+ *
+ * Copyright (C) Nokia Corporation
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef TPA6130A2_PLAT_H
+#define TPA6130A2_PLAT_H
+
+struct tpa6130a2_platform_data {
+	int power_gpio;
+};
+
+#endif
diff --git a/include/sound/uda134x.h b/include/sound/uda134x.h
new file mode 100644
index 0000000..509efb0
--- /dev/null
+++ b/include/sound/uda134x.h
@@ -0,0 +1,27 @@
+/*
+ * uda134x.h  --  UDA134x ALSA SoC Codec driver
+ *
+ * Copyright 2007 Dension Audio Systems Ltd.
+ * Author: Zoltan Devai
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _UDA134X_H
+#define _UDA134X_H
+
+#include <sound/l3.h>
+
+struct uda134x_platform_data {
+	struct l3_pins l3;
+	void (*power) (int);
+	int model;
+#define UDA134X_UDA1340 1
+#define UDA134X_UDA1341 2
+#define UDA134X_UDA1344 3
+#define UDA134X_UDA1345 4
+};
+
+#endif /* _UDA134X_H */
diff --git a/include/sound/uda1380.h b/include/sound/uda1380.h
new file mode 100644
index 0000000..381319c
--- /dev/null
+++ b/include/sound/uda1380.h
@@ -0,0 +1,22 @@
+/*
+ * UDA1380 ALSA SoC Codec driver
+ *
+ * Copyright 2009 Philipp Zabel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __UDA1380_H
+#define __UDA1380_H
+
+struct uda1380_platform_data {
+	int gpio_power;
+	int gpio_reset;
+	int dac_clk;
+#define UDA1380_DAC_CLK_SYSCLK 0
+#define UDA1380_DAC_CLK_WSPLL  1
+};
+
+#endif /* __UDA1380_H */
diff --git a/include/sound/util_mem.h b/include/sound/util_mem.h
new file mode 100644
index 0000000..a1fb706
--- /dev/null
+++ b/include/sound/util_mem.h
@@ -0,0 +1,64 @@
+#ifndef __SOUND_UTIL_MEM_H
+#define __SOUND_UTIL_MEM_H
+
+#include <linux/mutex.h>
+/*
+ *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
+ *
+ *  Generic memory management routines for soundcard memory allocation
+ *
+ *   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
+ */
+
+/*
+ * memory block
+ */
+struct snd_util_memblk {
+	unsigned int size;		/* size of this block */
+	unsigned int offset;		/* zero-offset of this block */
+	struct list_head list;		/* link */
+};
+
+#define snd_util_memblk_argptr(blk)	(void*)((char*)(blk) + sizeof(struct snd_util_memblk))
+
+/*
+ * memory management information
+ */
+struct snd_util_memhdr {
+	unsigned int size;		/* size of whole data */
+	struct list_head block;		/* block linked-list header */
+	int nblocks;			/* # of allocated blocks */
+	unsigned int used;		/* used memory size */
+	int block_extra_size;		/* extra data size of chunk */
+	struct mutex block_mutex;	/* lock */
+};
+
+/*
+ * prototypes
+ */
+struct snd_util_memhdr *snd_util_memhdr_new(int memsize);
+void snd_util_memhdr_free(struct snd_util_memhdr *hdr);
+struct snd_util_memblk *snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size);
+int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk);
+int snd_util_mem_avail(struct snd_util_memhdr *hdr);
+
+/* functions without mutex */
+struct snd_util_memblk *__snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size);
+void __snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk);
+struct snd_util_memblk *__snd_util_memblk_new(struct snd_util_memhdr *hdr,
+					      unsigned int units,
+					      struct list_head *prev);
+
+#endif /* __SOUND_UTIL_MEM_H */
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h
new file mode 100644
index 0000000..cae9c9d
--- /dev/null
+++ b/include/sound/vx_core.h
@@ -0,0 +1,548 @@
+/*
+ * Driver for Digigram VX soundcards
+ *
+ * Hardware core part
+ *
+ * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef __SOUND_VX_COMMON_H
+#define __SOUND_VX_COMMON_H
+
+#include <sound/pcm.h>
+#include <sound/hwdep.h>
+#include <linux/interrupt.h>
+
+struct firmware;
+struct device;
+
+#define VX_DRIVER_VERSION	0x010000	/* 1.0.0 */
+
+/*
+ */
+#define SIZE_MAX_CMD    0x10
+#define SIZE_MAX_STATUS 0x10
+
+struct vx_rmh {
+	u16	LgCmd;		/* length of the command to send (WORDs) */
+	u16	LgStat;		/* length of the status received (WORDs) */
+	u32	Cmd[SIZE_MAX_CMD];
+	u32	Stat[SIZE_MAX_STATUS];
+	u16	DspStat;	/* status type, RMP_SSIZE_XXX */
+};
+	
+typedef u64 pcx_time_t;
+
+#define VX_MAX_PIPES	16
+#define VX_MAX_PERIODS	32
+#define VX_MAX_CODECS	2
+
+struct vx_ibl_info {
+	int size;	/* the current IBL size (0 = query) in bytes */
+	int max_size;	/* max. IBL size in bytes */
+	int min_size;	/* min. IBL size in bytes */
+	int granularity;	/* granularity */
+};
+
+struct vx_pipe {
+	int number;
+	unsigned int is_capture: 1;
+	unsigned int data_mode: 1;
+	unsigned int running: 1;
+	unsigned int prepared: 1;
+	int channels;
+	unsigned int differed_type;
+	pcx_time_t pcx_time;
+	struct snd_pcm_substream *substream;
+
+	int hbuf_size;		/* H-buffer size in bytes */
+	int buffer_bytes;	/* the ALSA pcm buffer size in bytes */
+	int period_bytes;	/* the ALSA pcm period size in bytes */
+	int hw_ptr;		/* the current hardware pointer in bytes */
+	int position;		/* the current position in frames (playback only) */
+	int transferred;	/* the transferred size (per period) in frames */
+	int align;		/* size of alignment */
+	u64 cur_count;		/* current sample position (for playback) */
+
+	unsigned int references;     /* an output pipe may be used for monitoring and/or playback */
+	struct vx_pipe *monitoring_pipe;  /* pointer to the monitoring pipe (capture pipe only)*/
+};
+
+struct vx_core;
+
+struct snd_vx_ops {
+	/* low-level i/o */
+	unsigned char (*in8)(struct vx_core *chip, int reg);
+	unsigned int (*in32)(struct vx_core *chip, int reg);
+	void (*out8)(struct vx_core *chip, int reg, unsigned char val);
+	void (*out32)(struct vx_core *chip, int reg, unsigned int val);
+	/* irq */
+	int (*test_and_ack)(struct vx_core *chip);
+	void (*validate_irq)(struct vx_core *chip, int enable);
+	/* codec */
+	void (*write_codec)(struct vx_core *chip, int codec, unsigned int data);
+	void (*akm_write)(struct vx_core *chip, int reg, unsigned int data);
+	void (*reset_codec)(struct vx_core *chip);
+	void (*change_audio_source)(struct vx_core *chip, int src);
+	void (*set_clock_source)(struct vx_core *chp, int src);
+	/* chip init */
+	int (*load_dsp)(struct vx_core *chip, int idx, const struct firmware *fw);
+	void (*reset_dsp)(struct vx_core *chip);
+	void (*reset_board)(struct vx_core *chip, int cold_reset);
+	int (*add_controls)(struct vx_core *chip);
+	/* pcm */
+	void (*dma_write)(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			  struct vx_pipe *pipe, int count);
+	void (*dma_read)(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			  struct vx_pipe *pipe, int count);
+};
+
+struct snd_vx_hardware {
+	const char *name;
+	int type;	/* VX_TYPE_XXX */
+
+	/* hardware specs */
+	unsigned int num_codecs;
+	unsigned int num_ins;
+	unsigned int num_outs;
+	unsigned int output_level_max;
+	const unsigned int *output_level_db_scale;
+};
+
+/* hwdep id string */
+#define SND_VX_HWDEP_ID		"VX Loader"
+
+/* hardware type */
+enum {
+	/* VX222 PCI */
+	VX_TYPE_BOARD,		/* old VX222 PCI */
+	VX_TYPE_V2,		/* VX222 V2 PCI */
+	VX_TYPE_MIC,		/* VX222 Mic PCI */
+	/* VX-pocket */
+	VX_TYPE_VXPOCKET,	/* VXpocket V2 */
+	VX_TYPE_VXP440,		/* VXpocket 440 */
+	VX_TYPE_NUMS
+};
+
+/* chip status */
+enum {
+	VX_STAT_XILINX_LOADED	= (1 << 0),	/* devices are registered */
+	VX_STAT_DEVICE_INIT	= (1 << 1),	/* devices are registered */
+	VX_STAT_CHIP_INIT	= (1 << 2),	/* all operational */
+	VX_STAT_IN_SUSPEND	= (1 << 10),	/* in suspend phase */
+	VX_STAT_IS_STALE	= (1 << 15)	/* device is stale */
+};
+
+/* min/max values for analog output for old codecs */
+#define VX_ANALOG_OUT_LEVEL_MAX		0xe3
+
+struct vx_core {
+	/* ALSA stuff */
+	struct snd_card *card;
+	struct snd_pcm *pcm[VX_MAX_CODECS];
+	int type;	/* VX_TYPE_XXX */
+
+	int irq;
+	/* ports are defined externally */
+
+	/* low-level functions */
+	struct snd_vx_hardware *hw;
+	struct snd_vx_ops *ops;
+
+	struct mutex lock;
+
+	unsigned int chip_status;
+	unsigned int pcm_running;
+
+	struct device *dev;
+	struct snd_hwdep *hwdep;
+
+	struct vx_rmh irq_rmh;	/* RMH used in interrupts */
+
+	unsigned int audio_info; /* see VX_AUDIO_INFO */
+	unsigned int audio_ins;
+	unsigned int audio_outs;
+	struct vx_pipe **playback_pipes;
+	struct vx_pipe **capture_pipes;
+
+	/* clock and audio sources */
+	unsigned int audio_source;	/* current audio input source */
+	unsigned int audio_source_target;
+	unsigned int clock_mode;	/* clock mode (VX_CLOCK_MODE_XXX) */
+	unsigned int clock_source;	/* current clock source (INTERNAL_QUARTZ or UER_SYNC) */
+	unsigned int freq;		/* current frequency */
+	unsigned int freq_detected;	/* detected frequency from digital in */
+	unsigned int uer_detected;	/* VX_UER_MODE_XXX */
+	unsigned int uer_bits;	/* IEC958 status bits */
+	struct vx_ibl_info ibl;	/* IBL information */
+
+	/* mixer setting */
+	int output_level[VX_MAX_CODECS][2];	/* analog output level */
+	int audio_gain[2][4];			/* digital audio level (playback/capture) */
+	unsigned char audio_active[4];		/* mute/unmute on digital playback */
+	int audio_monitor[4];			/* playback hw-monitor level */
+	unsigned char audio_monitor_active[4];	/* playback hw-monitor mute/unmute */
+
+	struct mutex mixer_mutex;
+
+	const struct firmware *firmware[4]; /* loaded firmware data */
+};
+
+
+/*
+ * constructor
+ */
+struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
+			      struct snd_vx_ops *ops, int extra_size);
+int snd_vx_setup_firmware(struct vx_core *chip);
+int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *dsp);
+int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *dsp);
+int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp);
+
+void snd_vx_free_firmware(struct vx_core *chip);
+
+/*
+ * interrupt handler; exported for pcmcia
+ */
+irqreturn_t snd_vx_irq_handler(int irq, void *dev);
+irqreturn_t snd_vx_threaded_irq_handler(int irq, void *dev);
+
+/*
+ * lowlevel functions
+ */
+static inline int vx_test_and_ack(struct vx_core *chip)
+{
+	return chip->ops->test_and_ack(chip);
+}
+
+static inline void vx_validate_irq(struct vx_core *chip, int enable)
+{
+	chip->ops->validate_irq(chip, enable);
+}
+
+static inline unsigned char snd_vx_inb(struct vx_core *chip, int reg)
+{
+	return chip->ops->in8(chip, reg);
+}
+
+static inline unsigned int snd_vx_inl(struct vx_core *chip, int reg)
+{
+	return chip->ops->in32(chip, reg);
+}
+
+static inline void snd_vx_outb(struct vx_core *chip, int reg, unsigned char val)
+{
+	chip->ops->out8(chip, reg, val);
+}
+
+static inline void snd_vx_outl(struct vx_core *chip, int reg, unsigned int val)
+{
+	chip->ops->out32(chip, reg, val);
+}
+
+#define vx_inb(chip,reg)	snd_vx_inb(chip, VX_##reg)
+#define vx_outb(chip,reg,val)	snd_vx_outb(chip, VX_##reg,val)
+#define vx_inl(chip,reg)	snd_vx_inl(chip, VX_##reg)
+#define vx_outl(chip,reg,val)	snd_vx_outl(chip, VX_##reg,val)
+
+static inline void vx_reset_dsp(struct vx_core *chip)
+{
+	chip->ops->reset_dsp(chip);
+}
+
+int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh);
+int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh);
+int vx_send_rih(struct vx_core *chip, int cmd);
+int vx_send_rih_nolock(struct vx_core *chip, int cmd);
+
+void vx_reset_codec(struct vx_core *chip, int cold_reset);
+
+/*
+ * check the bit on the specified register
+ * returns zero if a bit matches, or a negative error code.
+ * exported for vxpocket driver
+ */
+int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time);
+#define vx_check_isr(chip,mask,bit,time) snd_vx_check_reg_bit(chip, VX_ISR, mask, bit, time)
+#define vx_wait_isr_bit(chip,bit) vx_check_isr(chip, bit, bit, 200)
+#define vx_wait_for_rx_full(chip) vx_wait_isr_bit(chip, ISR_RX_FULL)
+
+
+/*
+ * pseudo-DMA transfer
+ */
+static inline void vx_pseudo_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+				       struct vx_pipe *pipe, int count)
+{
+	chip->ops->dma_write(chip, runtime, pipe, count);
+}
+
+static inline void vx_pseudo_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+				      struct vx_pipe *pipe, int count)
+{
+	chip->ops->dma_read(chip, runtime, pipe, count);
+}
+
+
+
+/* error with hardware code,
+ * the return value is -(VX_ERR_MASK | actual-hw-error-code)
+ */
+#define VX_ERR_MASK	0x1000000
+#define vx_get_error(err)	(-(err) & ~VX_ERR_MASK)
+
+
+/*
+ * pcm stuff
+ */
+int snd_vx_pcm_new(struct vx_core *chip);
+void vx_pcm_update_intr(struct vx_core *chip, unsigned int events);
+
+/*
+ * mixer stuff
+ */
+int snd_vx_mixer_new(struct vx_core *chip);
+void vx_toggle_dac_mute(struct vx_core *chip, int mute);
+int vx_sync_audio_source(struct vx_core *chip);
+int vx_set_monitor_level(struct vx_core *chip, int audio, int level, int active);
+
+/*
+ * IEC958 & clock stuff
+ */
+void vx_set_iec958_status(struct vx_core *chip, unsigned int bits);
+int vx_set_clock(struct vx_core *chip, unsigned int freq);
+void vx_set_internal_clock(struct vx_core *chip, unsigned int freq);
+int vx_change_frequency(struct vx_core *chip);
+
+
+/*
+ * PM
+ */
+int snd_vx_suspend(struct vx_core *card);
+int snd_vx_resume(struct vx_core *card);
+
+/*
+ * hardware constants
+ */
+
+#define vx_has_new_dsp(chip)	((chip)->type != VX_TYPE_BOARD)
+#define vx_is_pcmcia(chip)	((chip)->type >= VX_TYPE_VXPOCKET)
+
+/* audio input source */
+enum {
+	VX_AUDIO_SRC_DIGITAL,
+	VX_AUDIO_SRC_LINE,
+	VX_AUDIO_SRC_MIC
+};
+
+/* clock source */
+enum {
+	INTERNAL_QUARTZ,
+	UER_SYNC
+};
+
+/* clock mode */
+enum {
+	VX_CLOCK_MODE_AUTO,	/* depending on the current audio source */
+	VX_CLOCK_MODE_INTERNAL,	/* fixed to internal quartz */
+	VX_CLOCK_MODE_EXTERNAL	/* fixed to UER sync */
+};
+
+/* SPDIF/UER type */
+enum {
+	VX_UER_MODE_CONSUMER,
+	VX_UER_MODE_PROFESSIONAL,
+	VX_UER_MODE_NOT_PRESENT,
+};
+
+/* register indices */
+enum {
+	VX_ICR,
+	VX_CVR,
+	VX_ISR,
+	VX_IVR,
+	VX_RXH,
+	VX_TXH = VX_RXH,
+	VX_RXM,
+	VX_TXM = VX_RXM,
+	VX_RXL,
+	VX_TXL = VX_RXL,
+	VX_DMA,
+	VX_CDSP,
+	VX_RFREQ,
+	VX_RUER_V2,
+	VX_GAIN,
+	VX_DATA = VX_GAIN,
+	VX_MEMIRQ,
+	VX_ACQ,
+	VX_BIT0,
+	VX_BIT1,
+	VX_MIC0,
+	VX_MIC1,
+	VX_MIC2,
+	VX_MIC3,
+	VX_PLX0,
+	VX_PLX1,
+	VX_PLX2,
+
+	VX_LOFREQ,  // V2: ACQ, VP: RFREQ
+	VX_HIFREQ,  // V2: BIT0, VP: RUER_V2
+	VX_CSUER,   // V2: BIT1, VP: BIT0
+	VX_RUER,    // V2: RUER_V2, VP: BIT1
+
+	VX_REG_MAX,
+
+	/* aliases for VX board */
+	VX_RESET_DMA = VX_ISR,
+	VX_CFG = VX_RFREQ,
+	VX_STATUS = VX_MEMIRQ,
+	VX_SELMIC = VX_MIC0,
+	VX_COMPOT = VX_MIC1,
+	VX_SCOMPR = VX_MIC2,
+	VX_GLIMIT = VX_MIC3,
+	VX_INTCSR = VX_PLX0,
+	VX_CNTRL = VX_PLX1,
+	VX_GPIOC = VX_PLX2,
+
+	/* aliases for VXPOCKET board */
+	VX_MICRO = VX_MEMIRQ,
+	VX_CODEC2 = VX_MEMIRQ,
+	VX_DIALOG = VX_ACQ,
+
+};
+
+/* RMH status type */
+enum {
+	RMH_SSIZE_FIXED = 0,	/* status size given by the driver (in LgStat) */
+	RMH_SSIZE_ARG = 1,	/* status size given in the LSB byte */
+	RMH_SSIZE_MASK = 2,	/* status size given in bitmask */
+};
+
+
+/* bits for ICR register */
+#define ICR_HF1		0x10
+#define ICR_HF0		0x08
+#define ICR_TREQ	0x02	/* Interrupt mode + HREQ set on for transfer (->DSP) request */
+#define ICR_RREQ	0x01	/* Interrupt mode + RREQ set on for transfer (->PC) request */
+
+/* bits for CVR register */
+#define CVR_HC		0x80
+
+/* bits for ISR register */
+#define ISR_HF3		0x10
+#define ISR_HF2		0x08
+#define ISR_CHK		0x10
+#define ISR_ERR		0x08
+#define ISR_TX_READY	0x04
+#define ISR_TX_EMPTY	0x02
+#define ISR_RX_FULL	0x01
+
+/* Constants used to access the DATA register */
+#define VX_DATA_CODEC_MASK	0x80
+#define VX_DATA_XICOR_MASK	0x80
+
+/* Constants used to access the CSUER register (both for VX2 and VXP) */
+#define VX_SUER_FREQ_MASK		0x0c
+#define VX_SUER_FREQ_32KHz_MASK		0x0c
+#define VX_SUER_FREQ_44KHz_MASK		0x00
+#define VX_SUER_FREQ_48KHz_MASK		0x04
+#define VX_SUER_DATA_PRESENT_MASK	0x02
+#define VX_SUER_CLOCK_PRESENT_MASK	0x01
+
+#define VX_CUER_HH_BITC_SEL_MASK	0x08
+#define VX_CUER_MH_BITC_SEL_MASK	0x04
+#define VX_CUER_ML_BITC_SEL_MASK	0x02
+#define VX_CUER_LL_BITC_SEL_MASK	0x01
+
+#define XX_UER_CBITS_OFFSET_MASK	0x1f
+
+
+/* bits for audio_info */
+#define VX_AUDIO_INFO_REAL_TIME	(1<<0)	/* real-time processing available */
+#define VX_AUDIO_INFO_OFFLINE	(1<<1)	/* offline processing available */
+#define VX_AUDIO_INFO_MPEG1	(1<<5)
+#define VX_AUDIO_INFO_MPEG2	(1<<6)
+#define VX_AUDIO_INFO_LINEAR_8	(1<<7)
+#define VX_AUDIO_INFO_LINEAR_16	(1<<8)
+#define VX_AUDIO_INFO_LINEAR_24	(1<<9)
+
+/* DSP Interrupt Request values */
+#define VXP_IRQ_OFFSET		0x40 /* add 0x40 offset for vxpocket and vx222/v2 */
+/* call with vx_send_irq_dsp() */
+#define IRQ_MESS_WRITE_END          0x30
+#define IRQ_MESS_WRITE_NEXT         0x32
+#define IRQ_MESS_READ_NEXT          0x34
+#define IRQ_MESS_READ_END           0x36
+#define IRQ_MESSAGE                 0x38
+#define IRQ_RESET_CHK               0x3A
+#define IRQ_CONNECT_STREAM_NEXT     0x26
+#define IRQ_CONNECT_STREAM_END      0x28
+#define IRQ_PAUSE_START_CONNECT     0x2A
+#define IRQ_END_CONNECTION          0x2C
+
+/* Is there async. events pending ( IT Source Test ) */
+#define ASYNC_EVENTS_PENDING            0x008000
+#define HBUFFER_EVENTS_PENDING          0x004000   // Not always accurate
+#define NOTIF_EVENTS_PENDING            0x002000
+#define TIME_CODE_EVENT_PENDING         0x001000
+#define FREQUENCY_CHANGE_EVENT_PENDING  0x000800
+#define END_OF_BUFFER_EVENTS_PENDING    0x000400
+#define FATAL_DSP_ERROR                 0xff0000
+
+/* Stream Format Header Defines */ 
+#define HEADER_FMT_BASE			0xFED00000
+#define HEADER_FMT_MONO			0x000000C0
+#define HEADER_FMT_INTEL		0x00008000
+#define HEADER_FMT_16BITS		0x00002000
+#define HEADER_FMT_24BITS		0x00004000
+#define HEADER_FMT_UPTO11		0x00000200	/* frequency is less or equ. to 11k.*/
+#define HEADER_FMT_UPTO32		0x00000100	/* frequency is over 11k and less then 32k.*/
+
+/* Constants used to access the Codec */
+#define XX_CODEC_SELECTOR               0x20
+/* codec commands */
+#define XX_CODEC_ADC_CONTROL_REGISTER   0x01
+#define XX_CODEC_DAC_CONTROL_REGISTER   0x02
+#define XX_CODEC_LEVEL_LEFT_REGISTER    0x03
+#define XX_CODEC_LEVEL_RIGHT_REGISTER   0x04
+#define XX_CODEC_PORT_MODE_REGISTER     0x05
+#define XX_CODEC_STATUS_REPORT_REGISTER 0x06
+#define XX_CODEC_CLOCK_CONTROL_REGISTER 0x07
+
+/*
+ * Audio-level control values
+ */
+#define CVAL_M110DB		0x000	/* -110dB */
+#define CVAL_M99DB		0x02C
+#define CVAL_M21DB		0x163
+#define CVAL_M18DB		0x16F
+#define CVAL_M10DB		0x18F
+#define CVAL_0DB		0x1B7
+#define CVAL_18DB		0x1FF	/* +18dB */
+#define CVAL_MAX		0x1FF
+
+#define AUDIO_IO_HAS_MUTE_LEVEL			0x400000
+#define AUDIO_IO_HAS_MUTE_MONITORING_1		0x200000
+#define AUDIO_IO_HAS_MUTE_MONITORING_2		0x100000
+#define VALID_AUDIO_IO_DIGITAL_LEVEL		0x01
+#define VALID_AUDIO_IO_MONITORING_LEVEL		0x02
+#define VALID_AUDIO_IO_MUTE_LEVEL		0x04
+#define VALID_AUDIO_IO_MUTE_MONITORING_1	0x08
+#define VALID_AUDIO_IO_MUTE_MONITORING_2	0x10
+
+
+#endif /* __SOUND_VX_COMMON_H */
diff --git a/include/sound/wavefront.h b/include/sound/wavefront.h
new file mode 100644
index 0000000..15d82e5
--- /dev/null
+++ b/include/sound/wavefront.h
@@ -0,0 +1,695 @@
+#ifndef __SOUND_WAVEFRONT_H__
+#define __SOUND_WAVEFRONT_H__
+
+/*
+ *  Driver for Turtle Beach Wavefront cards (Maui,Tropez,Tropez+)
+ *
+ *  Copyright (c) by Paul Barton-Davis <pbd@op.net>
+ *
+ *   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
+ */
+
+#if (!defined(__GNUC__) && !defined(__GNUG__))
+
+     You will not be able to compile this file correctly without gcc, because
+     it is necessary to pack the "wavefront_alias" structure to a size
+     of 22 bytes, corresponding to 16-bit alignment (as would have been
+     the case on the original platform, MS-DOS). If this is not done,
+     then WavePatch-format files cannot be read/written correctly.
+     The method used to do this here ("__attribute__((packed)") is
+     completely compiler dependent.
+     
+     All other wavefront_* types end up aligned to 32 bit values and
+     still have the same (correct) size.
+
+#else
+
+     /* However, note that as of G++ 2.7.3.2, g++ was unable to
+	correctly parse *type* __attribute__ tags. It will do the
+	right thing if we use the "packed" attribute on each struct
+	member, which has the same semantics anyway. 
+     */
+
+#endif /* __GNUC__ */
+
+/***************************** WARNING ********************************
+  PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO 
+  BE USED WITH EITHER C *OR* C++.
+ **********************************************************************/
+
+#ifndef NUM_MIDIKEYS 
+#define NUM_MIDIKEYS 128
+#endif  /* NUM_MIDIKEYS */
+
+#ifndef NUM_MIDICHANNELS
+#define NUM_MIDICHANNELS 16
+#endif  /* NUM_MIDICHANNELS */
+
+/* These are very useful/important. the original wavefront interface
+   was developed on a 16 bit system, where sizeof(int) = 2
+   bytes. Defining things like this makes the code much more portable, and
+   easier to understand without having to toggle back and forth
+   between a 16-bit view of the world and a 32-bit one. 
+ */   
+
+#ifndef __KERNEL__
+/* keep them for compatibility */
+typedef short s16;
+typedef unsigned short u16;
+typedef int s32;
+typedef unsigned int u32;
+typedef char s8;
+typedef unsigned char u8;
+typedef s16 INT16;
+typedef u16 UINT16;
+typedef s32 INT32;
+typedef u32 UINT32;
+typedef s8 CHAR8;
+typedef u8 UCHAR8;
+#endif
+
+/* Pseudo-commands not part of the WaveFront command set.
+   These are used for various driver controls and direct
+   hardware control.
+ */
+
+#define WFC_DEBUG_DRIVER                0
+#define WFC_FX_IOCTL                    1
+#define WFC_PATCH_STATUS                2
+#define WFC_PROGRAM_STATUS              3
+#define WFC_SAMPLE_STATUS               4
+#define WFC_DISABLE_INTERRUPTS          5
+#define WFC_ENABLE_INTERRUPTS           6
+#define WFC_INTERRUPT_STATUS            7
+#define WFC_ROMSAMPLES_RDONLY           8
+#define WFC_IDENTIFY_SLOT_TYPE          9
+
+/* Wavefront synth commands
+ */
+
+#define WFC_DOWNLOAD_SAMPLE		0x80
+#define WFC_DOWNLOAD_BLOCK		0x81
+#define WFC_DOWNLOAD_MULTISAMPLE	0x82
+#define WFC_DOWNLOAD_SAMPLE_ALIAS	0x83
+#define WFC_DELETE_SAMPLE		0x84
+#define WFC_REPORT_FREE_MEMORY		0x85
+#define WFC_DOWNLOAD_PATCH		0x86
+#define WFC_DOWNLOAD_PROGRAM		0x87
+#define WFC_SET_SYNTHVOL		0x89
+#define WFC_SET_NVOICES			0x8B
+#define WFC_DOWNLOAD_DRUM		0x90
+#define WFC_GET_SYNTHVOL		0x92
+#define WFC_GET_NVOICES			0x94
+#define WFC_DISABLE_CHANNEL		0x9A
+#define WFC_ENABLE_CHANNEL		0x9B
+#define WFC_MISYNTH_OFF			0x9D
+#define WFC_MISYNTH_ON			0x9E
+#define WFC_FIRMWARE_VERSION		0x9F
+#define WFC_GET_NSAMPLES		0xA0
+#define WFC_DISABLE_DRUM_PROGRAM	0xA2
+#define WFC_UPLOAD_PATCH		0xA3
+#define WFC_UPLOAD_PROGRAM		0xA4
+#define WFC_SET_TUNING			0xA6
+#define WFC_GET_TUNING			0xA7
+#define WFC_VMIDI_ON			0xA8
+#define WFC_VMIDI_OFF			0xA9
+#define WFC_MIDI_STATUS			0xAA
+#define WFC_GET_CHANNEL_STATUS		0xAB
+#define WFC_DOWNLOAD_SAMPLE_HEADER	0xAC
+#define WFC_UPLOAD_SAMPLE_HEADER	0xAD
+#define WFC_UPLOAD_MULTISAMPLE		0xAE
+#define WFC_UPLOAD_SAMPLE_ALIAS		0xAF
+#define WFC_IDENTIFY_SAMPLE_TYPE	0xB0
+#define WFC_DOWNLOAD_EDRUM_PROGRAM	0xB1
+#define WFC_UPLOAD_EDRUM_PROGRAM	0xB2
+#define WFC_SET_EDRUM_CHANNEL		0xB3
+#define WFC_INSTOUT_LEVELS		0xB4
+#define WFC_PEAKOUT_LEVELS		0xB5
+#define WFC_REPORT_CHANNEL_PROGRAMS	0xB6
+#define WFC_HARDWARE_VERSION		0xCF
+#define WFC_UPLOAD_SAMPLE_PARAMS	0xD7
+#define WFC_DOWNLOAD_OS			0xF1
+#define WFC_NOOP                        0xFF
+
+#define WF_MAX_SAMPLE   512
+#define WF_MAX_PATCH    256
+#define WF_MAX_PROGRAM  128
+
+#define WF_SECTION_MAX  44   /* longest OS section length */
+
+/* # of bytes we send to the board when sending it various kinds of
+   substantive data, such as samples, patches and programs.
+*/
+
+#define WF_PROGRAM_BYTES 32
+#define WF_PATCH_BYTES 132
+#define WF_SAMPLE_BYTES 27
+#define WF_SAMPLE_HDR_BYTES 25
+#define WF_ALIAS_BYTES 25
+#define WF_DRUM_BYTES 9
+#define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
+
+#define WF_ACK     0x80
+#define WF_DMA_ACK 0x81
+
+/* OR-values for MIDI status bits */
+
+#define WF_MIDI_VIRTUAL_ENABLED 0x1
+#define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
+#define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
+
+/* slot indexes for struct address_info: makes code a little more mnemonic */
+
+#define WF_SYNTH_SLOT         0
+#define WF_INTERNAL_MIDI_SLOT 1
+#define WF_EXTERNAL_MIDI_SLOT 2
+
+/* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
+   emulation. Note these NEVER show up in output from the device and
+   should NEVER be used in input unless Virtual MIDI mode has been 
+   disabled. If they do show up as input, the results are unpredictable.
+*/
+
+#define WF_EXTERNAL_SWITCH  0xFD
+#define WF_INTERNAL_SWITCH  0xF9
+
+/* Debugging flags */
+
+#define WF_DEBUG_CMD 0x1
+#define WF_DEBUG_DATA 0x2
+#define WF_DEBUG_LOAD_PATCH 0x4
+#define WF_DEBUG_IO 0x8
+
+/* WavePatch file format stuff */
+
+#define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
+#define WF_MAX_COMMENT           64    /*  Comment length */
+#define WF_NUM_LAYERS            4
+#define WF_NAME_LENGTH           32
+#define WF_SOURCE_LENGTH         260
+
+#define BankFileID     "Bank"
+#define DrumkitFileID  "DrumKit"
+#define ProgramFileID  "Program"
+
+struct wf_envelope
+{
+    u8 attack_time:7;
+    u8 Unused1:1;
+
+    u8 decay1_time:7;
+    u8 Unused2:1;
+
+    u8 decay2_time:7;
+    u8 Unused3:1;
+
+    u8 sustain_time:7;
+    u8 Unused4:1;
+
+    u8 release_time:7;
+    u8 Unused5:1;
+
+    u8 release2_time:7;
+    u8 Unused6:1;
+
+    s8 attack_level;
+    s8 decay1_level;
+    s8 decay2_level;
+    s8 sustain_level;
+    s8 release_level;
+
+    u8 attack_velocity:7;
+    u8 Unused7:1;
+
+    u8 volume_velocity:7;
+    u8 Unused8:1;
+
+    u8 keyboard_scaling:7;
+    u8 Unused9:1;
+};
+typedef struct wf_envelope wavefront_envelope;
+
+struct wf_lfo
+{
+    u8 sample_number;
+
+    u8 frequency:7;
+    u8 Unused1:1;
+
+    u8 am_src:4;
+    u8 fm_src:4;
+
+    s8 fm_amount;
+    s8 am_amount;
+    s8 start_level;
+    s8 end_level;
+
+    u8 ramp_delay:7;
+    u8 wave_restart:1; /* for LFO2 only */
+
+    u8 ramp_time:7;
+    u8 Unused2:1;
+};
+typedef struct wf_lfo wavefront_lfo;
+
+struct wf_patch
+{
+    s16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
+
+    u8 amplitude_bias:7;
+    u8 Unused1:1;
+
+    u8 portamento:7;
+    u8 Unused2:1;
+
+    u8 sample_number;
+
+    u8 pitch_bend:4;
+    u8 sample_msb:1;
+    u8 Unused3:3;
+
+    u8 mono:1;
+    u8 retrigger:1;
+    u8 nohold:1;
+    u8 restart:1;
+    u8 filterconfig:2; /* SDK says "not used" */
+    u8 reuse:1;
+    u8 reset_lfo:1;    
+
+    u8 fm_src2:4;
+    u8 fm_src1:4;   
+
+    s8 fm_amount1;
+    s8 fm_amount2;
+
+    u8 am_src:4;
+    u8 Unused4:4;
+
+    s8 am_amount;
+
+    u8 fc1_mode:4;
+    u8 fc2_mode:4;
+
+    s8 fc1_mod_amount;
+    s8 fc1_keyboard_scaling;
+    s8 fc1_bias;
+    s8 fc2_mod_amount;
+    s8 fc2_keyboard_scaling;
+    s8 fc2_bias;
+
+    u8 randomizer:7;
+    u8 Unused5:1;
+
+    struct wf_envelope envelope1;
+    struct wf_envelope envelope2;
+    struct wf_lfo lfo1;
+    struct wf_lfo lfo2;
+};
+typedef struct wf_patch wavefront_patch;
+
+struct wf_layer
+{
+    u8 patch_number;
+
+    u8 mix_level:7;
+    u8 mute:1;
+
+    u8 split_point:7;
+    u8 play_below:1;
+
+    u8 pan_mod_src:2;
+    u8 pan_or_mod:1;
+    u8 pan:4;
+    u8 split_type:1;
+};
+typedef struct wf_layer wavefront_layer;
+
+struct wf_program
+{
+    struct wf_layer layer[WF_NUM_LAYERS];
+};
+typedef struct wf_program wavefront_program;
+
+struct wf_sample_offset
+{
+    s32 Fraction:4;
+    s32 Integer:20;
+    s32 Unused:8;
+};
+typedef struct wf_sample_offset wavefront_sample_offset;          
+     
+/* Sample slot types */
+
+#define WF_ST_SAMPLE      0
+#define WF_ST_MULTISAMPLE 1
+#define WF_ST_ALIAS       2
+#define WF_ST_EMPTY       3
+
+/* pseudo's */
+
+#define WF_ST_DRUM        4
+#define WF_ST_PROGRAM     5
+#define WF_ST_PATCH       6
+#define WF_ST_SAMPLEHDR   7
+
+#define WF_ST_MASK        0xf
+
+/* Flags for slot status. These occupy the upper bits of the same byte
+   as a sample type.
+*/
+
+#define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
+#define WF_SLOT_FILLED    0x40
+#define WF_SLOT_ROM       0x20
+
+#define WF_SLOT_MASK      0xf0
+
+/* channel constants */
+
+#define WF_CH_MONO  0
+#define WF_CH_LEFT  1
+#define WF_CH_RIGHT 2
+
+/* Sample formats */
+
+#define LINEAR_16BIT 0
+#define WHITE_NOISE  1
+#define LINEAR_8BIT  2
+#define MULAW_8BIT   3
+
+#define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
+
+
+/* 
+
+  Because most/all of the sample data we pass in via pointers has
+  never been copied (just mmap-ed into user space straight from the
+  disk), it would be nice to allow handling of multi-channel sample
+  data without forcing user-level extraction of the relevant bytes.
+  
+  So, we need a way of specifying which channel to use (the WaveFront
+  only handles mono samples in a given slot), and the only way to do
+  this without using some struct other than wavefront_sample as the
+  interface is the awful hack of using the unused bits in a
+  wavefront_sample:
+  
+  Val      Meaning
+  ---      -------
+  0        no channel selection (use channel 1, sample is MONO)
+  1        use first channel, and skip one
+  2        use second channel, and skip one
+  3        use third channel, and skip two
+  4        use fourth channel, skip three
+  5        use fifth channel, skip four
+  6        use six channel, skip five
+
+
+  This can handle up to 4 channels, and anyone downloading >4 channels
+  of sample data just to select one of them needs to find some tools
+  like sox ...
+
+  NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is 
+  important.
+
+*/
+
+#define WF_SET_CHANNEL(samp,chn) \
+ (samp)->Unused1 = chn & 0x1; \
+ (samp)->Unused2 = chn & 0x2; \
+ (samp)->Unused3 = chn & 0x4 
+  
+#define WF_GET_CHANNEL(samp) \
+  (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
+  
+typedef struct wf_sample {
+    struct wf_sample_offset sampleStartOffset;
+    struct wf_sample_offset loopStartOffset;
+    struct wf_sample_offset loopEndOffset;
+    struct wf_sample_offset sampleEndOffset;
+    s16 FrequencyBias;
+    u8 SampleResolution:2;  /* sample_format */
+    u8 Unused1:1;
+    u8 Loop:1;
+    u8 Bidirectional:1;
+    u8 Unused2:1;
+    u8 Reverse:1;
+    u8 Unused3:1;
+} wavefront_sample;
+
+typedef struct wf_multisample {
+    s16 NumberOfSamples;   /* log2 of the number of samples */
+    s16 SampleNumber[NUM_MIDIKEYS];
+} wavefront_multisample;
+
+typedef struct wf_alias {
+    s16 OriginalSample;
+
+    struct wf_sample_offset sampleStartOffset;
+    struct wf_sample_offset loopStartOffset;
+    struct wf_sample_offset sampleEndOffset;
+    struct wf_sample_offset loopEndOffset;
+
+    s16  FrequencyBias;
+
+    u8 SampleResolution:2;
+    u8 Unused1:1;
+    u8 Loop:1;
+    u8 Bidirectional:1;
+    u8 Unused2:1;
+    u8 Reverse:1;
+    u8 Unused3:1;
+    
+    /* This structure is meant to be padded only to 16 bits on their
+       original. Of course, whoever wrote their documentation didn't
+       realize that sizeof(struct) can be >=
+       sum(sizeof(struct-fields)) and so thought that giving a C level
+       description of the structs used in WavePatch files was
+       sufficient. I suppose it was, as long as you remember the 
+       standard 16->32 bit issues.
+    */
+
+    u8 sixteen_bit_padding;
+} __attribute__((packed)) wavefront_alias;
+
+typedef struct wf_drum {
+    u8 PatchNumber;
+    u8 MixLevel:7;
+    u8 Unmute:1;
+    u8 Group:4;
+    u8 Unused1:4;
+    u8 PanModSource:2;
+    u8 PanModulated:1;
+    u8 PanAmount:4;
+    u8 Unused2:1;
+} wavefront_drum;
+
+typedef struct wf_drumkit {
+    struct wf_drum drum[NUM_MIDIKEYS];
+} wavefront_drumkit;
+
+typedef struct wf_channel_programs {
+    u8 Program[NUM_MIDICHANNELS];
+} wavefront_channel_programs;
+
+/* How to get MIDI channel status from the data returned by
+   a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
+*/
+
+#define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
+
+typedef union wf_any {
+    wavefront_sample s;
+    wavefront_multisample ms;
+    wavefront_alias a;
+    wavefront_program pr;
+    wavefront_patch p;
+    wavefront_drum d;
+} wavefront_any;
+
+/* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
+   might work for other wave-table based patch loading situations.
+   Alas, his fears were correct. The WaveFront doesn't even come with
+   just "patches", but several different kind of structures that
+   control the sound generation process.
+ */
+
+typedef struct wf_patch_info {
+    
+    /* the first two fields are used by the OSS "patch loading" interface
+       only, and are unused by the current user-level library.
+    */
+
+    s16   key;               /* Use WAVEFRONT_PATCH here */
+    u16  devno;             /* fill in when sending */
+    u8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
+
+#define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
+
+    u16  number;            /* patch/sample/prog number */
+
+    u32  size;              /* size of any data included in 
+				  one of the fields in `hdrptr', or
+				  as `dataptr'.
+
+				  NOTE: for actual samples, this is
+				  the size of the *SELECTED CHANNEL*
+				  even if more data is actually available.
+				  
+				  So, a stereo sample (2 channels) of
+				  6000 bytes total has `size' = 3000.
+
+				  See the macros and comments for
+				  WF_{GET,SET}_CHANNEL above.
+
+			       */
+    wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
+    u16 __user *dataptr;            /* actual sample data */
+
+    wavefront_any hdr;          /* kernel-space copy of hdr bytes */         
+} wavefront_patch_info;
+
+/* The maximum number of bytes we will ever move to or from user space
+   in response to a WFC_* command.  This obviously doesn't cover
+   actual sample data.
+*/
+
+#define WF_MAX_READ sizeof(wavefront_multisample)
+#define WF_MAX_WRITE sizeof(wavefront_multisample)
+
+/*
+   This allows us to execute any WF command except the download/upload
+   ones, which are handled differently due to copyin/copyout issues as
+   well as data-nybbling to/from the card.
+ */
+
+typedef struct wavefront_control {
+    int cmd;                           /* WFC_* */
+    char status;                       /* return status to user-space */
+    unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
+    unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
+} wavefront_control;
+
+#define WFCTL_WFCMD    0x1
+#define WFCTL_LOAD_SPP 0x2
+
+/* Modulator table */
+
+#define WF_MOD_LFO1      0
+#define WF_MOD_LFO2      1
+#define WF_MOD_ENV1      2
+#define WF_MOD_ENV2      3
+#define WF_MOD_KEYBOARD  4
+#define WF_MOD_LOGKEY    5
+#define WF_MOD_VELOCITY  6
+#define WF_MOD_LOGVEL    7
+#define WF_MOD_RANDOM    8
+#define WF_MOD_PRESSURE  9
+#define WF_MOD_MOD_WHEEL 10
+#define WF_MOD_1         WF_MOD_MOD_WHEEL 
+#define WF_MOD_BREATH    11
+#define WF_MOD_2         WF_MOD_BREATH
+#define WF_MOD_FOOT      12
+#define WF_MOD_4         WF_MOD_FOOT
+#define WF_MOD_VOLUME    13
+#define WF_MOD_7         WF_MOD_VOLUME
+#define WF_MOD_PAN       14
+#define WF_MOD_10        WF_MOD_PAN
+#define WF_MOD_EXPR      15
+#define WF_MOD_11        WF_MOD_EXPR
+
+/* FX-related material */
+
+typedef struct wf_fx_info {
+    int request;             /* see list below */
+    long data[4];             /* we don't need much */
+} wavefront_fx_info;
+
+/* support for each of these will be forthcoming once I or someone 
+   else has figured out which of the addresses on page 6 and page 7 of 
+   the YSS225 control each parameter. Incidentally, these come from
+   the Windows driver interface, but again, Turtle Beach didn't
+   document the API to use them.
+*/
+
+#define WFFX_SETOUTGAIN		        0
+#define WFFX_SETSTEREOOUTGAIN		1
+#define WFFX_SETREVERBIN1GAIN		2
+#define WFFX_SETREVERBIN2GAIN		3
+#define WFFX_SETREVERBIN3GAIN		4
+#define WFFX_SETCHORUSINPORT		5
+#define WFFX_SETREVERBIN1PORT		6
+#define WFFX_SETREVERBIN2PORT		7
+#define WFFX_SETREVERBIN3PORT		8
+#define WFFX_SETEFFECTPORT		9
+#define WFFX_SETAUXPORT		        10
+#define WFFX_SETREVERBTYPE		11
+#define WFFX_SETREVERBDELAY		12
+#define WFFX_SETCHORUSLFO		13
+#define WFFX_SETCHORUSPMD		14
+#define WFFX_SETCHORUSAMD		15
+#define WFFX_SETEFFECT		        16
+#define WFFX_SETBASEALL		        17
+#define WFFX_SETREVERBALL		18
+#define WFFX_SETCHORUSALL		20
+#define WFFX_SETREVERBDEF		22
+#define WFFX_SETCHORUSDEF		23
+#define WFFX_DELAYSETINGAIN		24
+#define WFFX_DELAYSETFBGAIN	        25
+#define WFFX_DELAYSETFBLPF		26
+#define WFFX_DELAYSETGAIN		27
+#define WFFX_DELAYSETTIME		28
+#define WFFX_DELAYSETFBTIME		29
+#define WFFX_DELAYSETALL		30
+#define WFFX_DELAYSETDEF		32
+#define WFFX_SDELAYSETINGAIN		33
+#define WFFX_SDELAYSETFBGAIN		34
+#define WFFX_SDELAYSETFBLPF		35
+#define WFFX_SDELAYSETGAIN		36
+#define WFFX_SDELAYSETTIME		37
+#define WFFX_SDELAYSETFBTIME		38
+#define WFFX_SDELAYSETALL		39
+#define WFFX_SDELAYSETDEF		41
+#define WFFX_DEQSETINGAIN		42
+#define WFFX_DEQSETFILTER		43
+#define WFFX_DEQSETALL		        44
+#define WFFX_DEQSETDEF		        46
+#define WFFX_MUTE		        47
+#define WFFX_FLANGESETBALANCE	        48	
+#define WFFX_FLANGESETDELAY		49
+#define WFFX_FLANGESETDWFFX_TH		50
+#define WFFX_FLANGESETFBGAIN		51
+#define WFFX_FLANGESETINGAIN		52
+#define WFFX_FLANGESETLFO		53
+#define WFFX_FLANGESETALL		54
+#define WFFX_FLANGESETDEF		56
+#define WFFX_PITCHSETSHIFT		57
+#define WFFX_PITCHSETBALANCE		58
+#define WFFX_PITCHSETALL		59
+#define WFFX_PITCHSETDEF		61
+#define WFFX_SRSSETINGAIN		62
+#define WFFX_SRSSETSPACE		63
+#define WFFX_SRSSETCENTER		64
+#define WFFX_SRSSETGAIN		        65
+#define WFFX_SRSSETMODE	        	66
+#define WFFX_SRSSETDEF		        68
+
+/* Allow direct user-space control over FX memory/coefficient data.
+   In theory this could be used to download the FX microprogram,
+   but it would be a little slower, and involve some weird code.
+ */
+
+#define WFFX_MEMSET              69
+
+#endif /* __SOUND_WAVEFRONT_H__ */
diff --git a/include/sound/wm0010.h b/include/sound/wm0010.h
new file mode 100644
index 0000000..3261e90
--- /dev/null
+++ b/include/sound/wm0010.h
@@ -0,0 +1,27 @@
+/*
+ * wm0010.h -- Platform data for WM0010 DSP Driver
+ *
+ * Copyright 2012 Wolfson Microelectronics PLC.
+ *
+ * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.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.
+ */
+
+#ifndef WM0010_PDATA_H
+#define WM0010_PDATA_H
+
+struct wm0010_pdata {
+	int gpio_reset;
+
+	/* Set if there is an inverter between the GPIO controlling
+	 * the reset signal and the device.
+	 */
+	int reset_active_high;
+	int irq_flags;
+};
+
+#endif
diff --git a/include/sound/wm1250-ev1.h b/include/sound/wm1250-ev1.h
new file mode 100644
index 0000000..7dff828
--- /dev/null
+++ b/include/sound/wm1250-ev1.h
@@ -0,0 +1,27 @@
+/*
+ * linux/sound/wm1250-ev1.h - Platform data for WM1250-EV1
+ *
+ * Copyright 2011 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM1250_EV1_H
+#define __LINUX_SND_WM1250_EV1_H
+
+#define WM1250_EV1_NUM_GPIOS 5
+
+#define WM1250_EV1_GPIO_CLK_ENA  0
+#define WM1250_EV1_GPIO_CLK_SEL0 1
+#define WM1250_EV1_GPIO_CLK_SEL1 2
+#define WM1250_EV1_GPIO_OSR      3
+#define WM1250_EV1_GPIO_MASTER   4
+
+
+struct wm1250_ev1_pdata {
+	int gpios[WM1250_EV1_NUM_GPIOS];
+};
+
+#endif
diff --git a/include/sound/wm2000.h b/include/sound/wm2000.h
new file mode 100644
index 0000000..4de81f4
--- /dev/null
+++ b/include/sound/wm2000.h
@@ -0,0 +1,23 @@
+/*
+ * linux/sound/wm2000.h -- Platform data for WM2000
+ *
+ * Copyright 2010 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM2000_H
+#define __LINUX_SND_WM2000_H
+
+struct wm2000_platform_data {
+	/** Filename for system-specific image to download to device. */
+	const char *download_file;
+
+	/** Disable speech clarity enhancement, for use when an
+	 * external algorithm is used. */
+	unsigned int speech_enh_disable:1;
+};
+
+#endif
diff --git a/include/sound/wm2200.h b/include/sound/wm2200.h
new file mode 100644
index 0000000..bc7ab1a
--- /dev/null
+++ b/include/sound/wm2200.h
@@ -0,0 +1,61 @@
+/*
+ * linux/sound/wm2200.h -- Platform data for WM2200
+ *
+ * Copyright 2012 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM2200_H
+#define __LINUX_SND_WM2200_H
+
+#define WM2200_GPIO_SET 0x10000
+#define WM2200_MAX_MICBIAS 2
+
+enum wm2200_in_mode {
+	WM2200_IN_SE = 0,
+	WM2200_IN_DIFF = 1,
+	WM2200_IN_DMIC = 2,
+};
+
+enum wm2200_dmic_sup {
+	WM2200_DMIC_SUP_MICVDD = 0,
+	WM2200_DMIC_SUP_MICBIAS1 = 1,
+	WM2200_DMIC_SUP_MICBIAS2 = 2,
+};
+
+enum wm2200_mbias_lvl {
+	WM2200_MBIAS_LVL_1V5 = 1,
+	WM2200_MBIAS_LVL_1V8 = 2,
+	WM2200_MBIAS_LVL_1V9 = 3,
+	WM2200_MBIAS_LVL_2V0 = 4,
+	WM2200_MBIAS_LVL_2V2 = 5,
+	WM2200_MBIAS_LVL_2V4 = 6,
+	WM2200_MBIAS_LVL_2V5 = 7,
+	WM2200_MBIAS_LVL_2V6 = 8,
+};
+
+struct wm2200_micbias {
+	enum wm2200_mbias_lvl mb_lvl;      /** Regulated voltage */
+	unsigned int discharge:1;          /** Actively discharge */
+	unsigned int fast_start:1;         /** Enable aggressive startup ramp rate */
+	unsigned int bypass:1;             /** Use bypass mode */
+};
+
+struct wm2200_pdata {
+	int reset;      /** GPIO controlling /RESET, if any */
+	int ldo_ena;    /** GPIO controlling LODENA, if any */
+	int irq_flags;
+
+	int gpio_defaults[4];
+
+	enum wm2200_in_mode in_mode[3];
+	enum wm2200_dmic_sup dmic_sup[3];
+
+	/** MICBIAS configurations */
+	struct wm2200_micbias micbias[WM2200_MAX_MICBIAS];
+};
+
+#endif
diff --git a/include/sound/wm5100.h b/include/sound/wm5100.h
new file mode 100644
index 0000000..617d0c4
--- /dev/null
+++ b/include/sound/wm5100.h
@@ -0,0 +1,59 @@
+/*
+ * linux/sound/wm5100.h -- Platform data for WM5100
+ *
+ * Copyright 2011 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM5100_H
+#define __LINUX_SND_WM5100_H
+
+enum wm5100_in_mode {
+	WM5100_IN_SE = 0,
+	WM5100_IN_DIFF = 1,
+	WM5100_IN_DMIC = 2,
+};
+
+enum wm5100_dmic_sup {
+	WM5100_DMIC_SUP_MICVDD = 0,
+	WM5100_DMIC_SUP_MICBIAS1 = 1,
+	WM5100_DMIC_SUP_MICBIAS2 = 2,
+	WM5100_DMIC_SUP_MICBIAS3 = 3,
+};
+
+enum wm5100_micdet_bias {
+	WM5100_MICDET_MICBIAS1 = 0,
+	WM5100_MICDET_MICBIAS2 = 1,
+	WM5100_MICDET_MICBIAS3 = 2,
+};
+
+struct wm5100_jack_mode {
+	enum wm5100_micdet_bias bias;
+	int hp_pol;
+	int micd_src;
+};
+
+#define WM5100_GPIO_SET 0x10000
+
+struct wm5100_pdata {
+	int reset;      /** GPIO controlling /RESET, if any */
+	int ldo_ena;    /** GPIO controlling LODENA, if any */
+	int hp_pol;     /** GPIO controlling headset polarity, if any */
+	int irq_flags;
+	int gpio_base;
+
+	struct wm5100_jack_mode jack_modes[2];
+
+	/* Input pin mode selection */
+	enum wm5100_in_mode in_mode[4];
+
+	/* DMIC supply selection */
+	enum wm5100_dmic_sup dmic_sup[4];
+
+	int gpio_defaults[6];
+};
+
+#endif
diff --git a/include/sound/wm8903.h b/include/sound/wm8903.h
new file mode 100644
index 0000000..b310c5a
--- /dev/null
+++ b/include/sound/wm8903.h
@@ -0,0 +1,266 @@
+/*
+ * linux/sound/wm8903.h -- Platform data for WM8903
+ *
+ * Copyright 2010 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM8903_H
+#define __LINUX_SND_WM8903_H
+
+/*
+ * Used to enable configuration of a GPIO to all zeros; a gpio_cfg value of
+ * zero in platform data means "don't touch this pin".
+ */
+#define WM8903_GPIO_CONFIG_ZERO 0x8000
+
+/*
+ * R6 (0x06) - Mic Bias Control 0
+ */
+#define WM8903_MICDET_THR_MASK                  0x0030  /* MICDET_THR - [5:4] */
+#define WM8903_MICDET_THR_SHIFT                      4  /* MICDET_THR - [5:4] */
+#define WM8903_MICDET_THR_WIDTH                      2  /* MICDET_THR - [5:4] */
+#define WM8903_MICSHORT_THR_MASK                0x000C  /* MICSHORT_THR - [3:2] */
+#define WM8903_MICSHORT_THR_SHIFT                    2  /* MICSHORT_THR - [3:2] */
+#define WM8903_MICSHORT_THR_WIDTH                    2  /* MICSHORT_THR - [3:2] */
+#define WM8903_MICDET_ENA                       0x0002  /* MICDET_ENA */
+#define WM8903_MICDET_ENA_MASK                  0x0002  /* MICDET_ENA */
+#define WM8903_MICDET_ENA_SHIFT                      1  /* MICDET_ENA */
+#define WM8903_MICDET_ENA_WIDTH                      1  /* MICDET_ENA */
+#define WM8903_MICBIAS_ENA                      0x0001  /* MICBIAS_ENA */
+#define WM8903_MICBIAS_ENA_MASK                 0x0001  /* MICBIAS_ENA */
+#define WM8903_MICBIAS_ENA_SHIFT                     0  /* MICBIAS_ENA */
+#define WM8903_MICBIAS_ENA_WIDTH                     1  /* MICBIAS_ENA */
+
+/*
+ * WM8903_GPn_FN values
+ *
+ * See datasheets for list of valid values per pin
+ */
+#define WM8903_GPn_FN_GPIO_OUTPUT                    0
+#define WM8903_GPn_FN_BCLK                           1
+#define WM8903_GPn_FN_IRQ_OUTPT                      2
+#define WM8903_GPn_FN_GPIO_INPUT                     3
+#define WM8903_GPn_FN_MICBIAS_CURRENT_DETECT         4
+#define WM8903_GPn_FN_MICBIAS_SHORT_DETECT           5
+#define WM8903_GPn_FN_DMIC_LR_CLK_OUTPUT             6
+#define WM8903_GPn_FN_FLL_LOCK_OUTPUT                8
+#define WM8903_GPn_FN_FLL_CLOCK_OUTPUT               9
+
+/*
+ * R116 (0x74) - GPIO Control 1
+ */
+#define WM8903_GP1_FN_MASK                      0x1F00  /* GP1_FN - [12:8] */
+#define WM8903_GP1_FN_SHIFT                          8  /* GP1_FN - [12:8] */
+#define WM8903_GP1_FN_WIDTH                          5  /* GP1_FN - [12:8] */
+#define WM8903_GP1_DIR                          0x0080  /* GP1_DIR */
+#define WM8903_GP1_DIR_MASK                     0x0080  /* GP1_DIR */
+#define WM8903_GP1_DIR_SHIFT                         7  /* GP1_DIR */
+#define WM8903_GP1_DIR_WIDTH                         1  /* GP1_DIR */
+#define WM8903_GP1_OP_CFG                       0x0040  /* GP1_OP_CFG */
+#define WM8903_GP1_OP_CFG_MASK                  0x0040  /* GP1_OP_CFG */
+#define WM8903_GP1_OP_CFG_SHIFT                      6  /* GP1_OP_CFG */
+#define WM8903_GP1_OP_CFG_WIDTH                      1  /* GP1_OP_CFG */
+#define WM8903_GP1_IP_CFG                       0x0020  /* GP1_IP_CFG */
+#define WM8903_GP1_IP_CFG_MASK                  0x0020  /* GP1_IP_CFG */
+#define WM8903_GP1_IP_CFG_SHIFT                      5  /* GP1_IP_CFG */
+#define WM8903_GP1_IP_CFG_WIDTH                      1  /* GP1_IP_CFG */
+#define WM8903_GP1_LVL                          0x0010  /* GP1_LVL */
+#define WM8903_GP1_LVL_MASK                     0x0010  /* GP1_LVL */
+#define WM8903_GP1_LVL_SHIFT                         4  /* GP1_LVL */
+#define WM8903_GP1_LVL_WIDTH                         1  /* GP1_LVL */
+#define WM8903_GP1_PD                           0x0008  /* GP1_PD */
+#define WM8903_GP1_PD_MASK                      0x0008  /* GP1_PD */
+#define WM8903_GP1_PD_SHIFT                          3  /* GP1_PD */
+#define WM8903_GP1_PD_WIDTH                          1  /* GP1_PD */
+#define WM8903_GP1_PU                           0x0004  /* GP1_PU */
+#define WM8903_GP1_PU_MASK                      0x0004  /* GP1_PU */
+#define WM8903_GP1_PU_SHIFT                          2  /* GP1_PU */
+#define WM8903_GP1_PU_WIDTH                          1  /* GP1_PU */
+#define WM8903_GP1_INTMODE                      0x0002  /* GP1_INTMODE */
+#define WM8903_GP1_INTMODE_MASK                 0x0002  /* GP1_INTMODE */
+#define WM8903_GP1_INTMODE_SHIFT                     1  /* GP1_INTMODE */
+#define WM8903_GP1_INTMODE_WIDTH                     1  /* GP1_INTMODE */
+#define WM8903_GP1_DB                           0x0001  /* GP1_DB */
+#define WM8903_GP1_DB_MASK                      0x0001  /* GP1_DB */
+#define WM8903_GP1_DB_SHIFT                          0  /* GP1_DB */
+#define WM8903_GP1_DB_WIDTH                          1  /* GP1_DB */
+
+/*
+ * R117 (0x75) - GPIO Control 2
+ */
+#define WM8903_GP2_FN_MASK                      0x1F00  /* GP2_FN - [12:8] */
+#define WM8903_GP2_FN_SHIFT                          8  /* GP2_FN - [12:8] */
+#define WM8903_GP2_FN_WIDTH                          5  /* GP2_FN - [12:8] */
+#define WM8903_GP2_DIR                          0x0080  /* GP2_DIR */
+#define WM8903_GP2_DIR_MASK                     0x0080  /* GP2_DIR */
+#define WM8903_GP2_DIR_SHIFT                         7  /* GP2_DIR */
+#define WM8903_GP2_DIR_WIDTH                         1  /* GP2_DIR */
+#define WM8903_GP2_OP_CFG                       0x0040  /* GP2_OP_CFG */
+#define WM8903_GP2_OP_CFG_MASK                  0x0040  /* GP2_OP_CFG */
+#define WM8903_GP2_OP_CFG_SHIFT                      6  /* GP2_OP_CFG */
+#define WM8903_GP2_OP_CFG_WIDTH                      1  /* GP2_OP_CFG */
+#define WM8903_GP2_IP_CFG                       0x0020  /* GP2_IP_CFG */
+#define WM8903_GP2_IP_CFG_MASK                  0x0020  /* GP2_IP_CFG */
+#define WM8903_GP2_IP_CFG_SHIFT                      5  /* GP2_IP_CFG */
+#define WM8903_GP2_IP_CFG_WIDTH                      1  /* GP2_IP_CFG */
+#define WM8903_GP2_LVL                          0x0010  /* GP2_LVL */
+#define WM8903_GP2_LVL_MASK                     0x0010  /* GP2_LVL */
+#define WM8903_GP2_LVL_SHIFT                         4  /* GP2_LVL */
+#define WM8903_GP2_LVL_WIDTH                         1  /* GP2_LVL */
+#define WM8903_GP2_PD                           0x0008  /* GP2_PD */
+#define WM8903_GP2_PD_MASK                      0x0008  /* GP2_PD */
+#define WM8903_GP2_PD_SHIFT                          3  /* GP2_PD */
+#define WM8903_GP2_PD_WIDTH                          1  /* GP2_PD */
+#define WM8903_GP2_PU                           0x0004  /* GP2_PU */
+#define WM8903_GP2_PU_MASK                      0x0004  /* GP2_PU */
+#define WM8903_GP2_PU_SHIFT                          2  /* GP2_PU */
+#define WM8903_GP2_PU_WIDTH                          1  /* GP2_PU */
+#define WM8903_GP2_INTMODE                      0x0002  /* GP2_INTMODE */
+#define WM8903_GP2_INTMODE_MASK                 0x0002  /* GP2_INTMODE */
+#define WM8903_GP2_INTMODE_SHIFT                     1  /* GP2_INTMODE */
+#define WM8903_GP2_INTMODE_WIDTH                     1  /* GP2_INTMODE */
+#define WM8903_GP2_DB                           0x0001  /* GP2_DB */
+#define WM8903_GP2_DB_MASK                      0x0001  /* GP2_DB */
+#define WM8903_GP2_DB_SHIFT                          0  /* GP2_DB */
+#define WM8903_GP2_DB_WIDTH                          1  /* GP2_DB */
+
+/*
+ * R118 (0x76) - GPIO Control 3
+ */
+#define WM8903_GP3_FN_MASK                      0x1F00  /* GP3_FN - [12:8] */
+#define WM8903_GP3_FN_SHIFT                          8  /* GP3_FN - [12:8] */
+#define WM8903_GP3_FN_WIDTH                          5  /* GP3_FN - [12:8] */
+#define WM8903_GP3_DIR                          0x0080  /* GP3_DIR */
+#define WM8903_GP3_DIR_MASK                     0x0080  /* GP3_DIR */
+#define WM8903_GP3_DIR_SHIFT                         7  /* GP3_DIR */
+#define WM8903_GP3_DIR_WIDTH                         1  /* GP3_DIR */
+#define WM8903_GP3_OP_CFG                       0x0040  /* GP3_OP_CFG */
+#define WM8903_GP3_OP_CFG_MASK                  0x0040  /* GP3_OP_CFG */
+#define WM8903_GP3_OP_CFG_SHIFT                      6  /* GP3_OP_CFG */
+#define WM8903_GP3_OP_CFG_WIDTH                      1  /* GP3_OP_CFG */
+#define WM8903_GP3_IP_CFG                       0x0020  /* GP3_IP_CFG */
+#define WM8903_GP3_IP_CFG_MASK                  0x0020  /* GP3_IP_CFG */
+#define WM8903_GP3_IP_CFG_SHIFT                      5  /* GP3_IP_CFG */
+#define WM8903_GP3_IP_CFG_WIDTH                      1  /* GP3_IP_CFG */
+#define WM8903_GP3_LVL                          0x0010  /* GP3_LVL */
+#define WM8903_GP3_LVL_MASK                     0x0010  /* GP3_LVL */
+#define WM8903_GP3_LVL_SHIFT                         4  /* GP3_LVL */
+#define WM8903_GP3_LVL_WIDTH                         1  /* GP3_LVL */
+#define WM8903_GP3_PD                           0x0008  /* GP3_PD */
+#define WM8903_GP3_PD_MASK                      0x0008  /* GP3_PD */
+#define WM8903_GP3_PD_SHIFT                          3  /* GP3_PD */
+#define WM8903_GP3_PD_WIDTH                          1  /* GP3_PD */
+#define WM8903_GP3_PU                           0x0004  /* GP3_PU */
+#define WM8903_GP3_PU_MASK                      0x0004  /* GP3_PU */
+#define WM8903_GP3_PU_SHIFT                          2  /* GP3_PU */
+#define WM8903_GP3_PU_WIDTH                          1  /* GP3_PU */
+#define WM8903_GP3_INTMODE                      0x0002  /* GP3_INTMODE */
+#define WM8903_GP3_INTMODE_MASK                 0x0002  /* GP3_INTMODE */
+#define WM8903_GP3_INTMODE_SHIFT                     1  /* GP3_INTMODE */
+#define WM8903_GP3_INTMODE_WIDTH                     1  /* GP3_INTMODE */
+#define WM8903_GP3_DB                           0x0001  /* GP3_DB */
+#define WM8903_GP3_DB_MASK                      0x0001  /* GP3_DB */
+#define WM8903_GP3_DB_SHIFT                          0  /* GP3_DB */
+#define WM8903_GP3_DB_WIDTH                          1  /* GP3_DB */
+
+/*
+ * R119 (0x77) - GPIO Control 4
+ */
+#define WM8903_GP4_FN_MASK                      0x1F00  /* GP4_FN - [12:8] */
+#define WM8903_GP4_FN_SHIFT                          8  /* GP4_FN - [12:8] */
+#define WM8903_GP4_FN_WIDTH                          5  /* GP4_FN - [12:8] */
+#define WM8903_GP4_DIR                          0x0080  /* GP4_DIR */
+#define WM8903_GP4_DIR_MASK                     0x0080  /* GP4_DIR */
+#define WM8903_GP4_DIR_SHIFT                         7  /* GP4_DIR */
+#define WM8903_GP4_DIR_WIDTH                         1  /* GP4_DIR */
+#define WM8903_GP4_OP_CFG                       0x0040  /* GP4_OP_CFG */
+#define WM8903_GP4_OP_CFG_MASK                  0x0040  /* GP4_OP_CFG */
+#define WM8903_GP4_OP_CFG_SHIFT                      6  /* GP4_OP_CFG */
+#define WM8903_GP4_OP_CFG_WIDTH                      1  /* GP4_OP_CFG */
+#define WM8903_GP4_IP_CFG                       0x0020  /* GP4_IP_CFG */
+#define WM8903_GP4_IP_CFG_MASK                  0x0020  /* GP4_IP_CFG */
+#define WM8903_GP4_IP_CFG_SHIFT                      5  /* GP4_IP_CFG */
+#define WM8903_GP4_IP_CFG_WIDTH                      1  /* GP4_IP_CFG */
+#define WM8903_GP4_LVL                          0x0010  /* GP4_LVL */
+#define WM8903_GP4_LVL_MASK                     0x0010  /* GP4_LVL */
+#define WM8903_GP4_LVL_SHIFT                         4  /* GP4_LVL */
+#define WM8903_GP4_LVL_WIDTH                         1  /* GP4_LVL */
+#define WM8903_GP4_PD                           0x0008  /* GP4_PD */
+#define WM8903_GP4_PD_MASK                      0x0008  /* GP4_PD */
+#define WM8903_GP4_PD_SHIFT                          3  /* GP4_PD */
+#define WM8903_GP4_PD_WIDTH                          1  /* GP4_PD */
+#define WM8903_GP4_PU                           0x0004  /* GP4_PU */
+#define WM8903_GP4_PU_MASK                      0x0004  /* GP4_PU */
+#define WM8903_GP4_PU_SHIFT                          2  /* GP4_PU */
+#define WM8903_GP4_PU_WIDTH                          1  /* GP4_PU */
+#define WM8903_GP4_INTMODE                      0x0002  /* GP4_INTMODE */
+#define WM8903_GP4_INTMODE_MASK                 0x0002  /* GP4_INTMODE */
+#define WM8903_GP4_INTMODE_SHIFT                     1  /* GP4_INTMODE */
+#define WM8903_GP4_INTMODE_WIDTH                     1  /* GP4_INTMODE */
+#define WM8903_GP4_DB                           0x0001  /* GP4_DB */
+#define WM8903_GP4_DB_MASK                      0x0001  /* GP4_DB */
+#define WM8903_GP4_DB_SHIFT                          0  /* GP4_DB */
+#define WM8903_GP4_DB_WIDTH                          1  /* GP4_DB */
+
+/*
+ * R120 (0x78) - GPIO Control 5
+ */
+#define WM8903_GP5_FN_MASK                      0x1F00  /* GP5_FN - [12:8] */
+#define WM8903_GP5_FN_SHIFT                          8  /* GP5_FN - [12:8] */
+#define WM8903_GP5_FN_WIDTH                          5  /* GP5_FN - [12:8] */
+#define WM8903_GP5_DIR                          0x0080  /* GP5_DIR */
+#define WM8903_GP5_DIR_MASK                     0x0080  /* GP5_DIR */
+#define WM8903_GP5_DIR_SHIFT                         7  /* GP5_DIR */
+#define WM8903_GP5_DIR_WIDTH                         1  /* GP5_DIR */
+#define WM8903_GP5_OP_CFG                       0x0040  /* GP5_OP_CFG */
+#define WM8903_GP5_OP_CFG_MASK                  0x0040  /* GP5_OP_CFG */
+#define WM8903_GP5_OP_CFG_SHIFT                      6  /* GP5_OP_CFG */
+#define WM8903_GP5_OP_CFG_WIDTH                      1  /* GP5_OP_CFG */
+#define WM8903_GP5_IP_CFG                       0x0020  /* GP5_IP_CFG */
+#define WM8903_GP5_IP_CFG_MASK                  0x0020  /* GP5_IP_CFG */
+#define WM8903_GP5_IP_CFG_SHIFT                      5  /* GP5_IP_CFG */
+#define WM8903_GP5_IP_CFG_WIDTH                      1  /* GP5_IP_CFG */
+#define WM8903_GP5_LVL                          0x0010  /* GP5_LVL */
+#define WM8903_GP5_LVL_MASK                     0x0010  /* GP5_LVL */
+#define WM8903_GP5_LVL_SHIFT                         4  /* GP5_LVL */
+#define WM8903_GP5_LVL_WIDTH                         1  /* GP5_LVL */
+#define WM8903_GP5_PD                           0x0008  /* GP5_PD */
+#define WM8903_GP5_PD_MASK                      0x0008  /* GP5_PD */
+#define WM8903_GP5_PD_SHIFT                          3  /* GP5_PD */
+#define WM8903_GP5_PD_WIDTH                          1  /* GP5_PD */
+#define WM8903_GP5_PU                           0x0004  /* GP5_PU */
+#define WM8903_GP5_PU_MASK                      0x0004  /* GP5_PU */
+#define WM8903_GP5_PU_SHIFT                          2  /* GP5_PU */
+#define WM8903_GP5_PU_WIDTH                          1  /* GP5_PU */
+#define WM8903_GP5_INTMODE                      0x0002  /* GP5_INTMODE */
+#define WM8903_GP5_INTMODE_MASK                 0x0002  /* GP5_INTMODE */
+#define WM8903_GP5_INTMODE_SHIFT                     1  /* GP5_INTMODE */
+#define WM8903_GP5_INTMODE_WIDTH                     1  /* GP5_INTMODE */
+#define WM8903_GP5_DB                           0x0001  /* GP5_DB */
+#define WM8903_GP5_DB_MASK                      0x0001  /* GP5_DB */
+#define WM8903_GP5_DB_SHIFT                          0  /* GP5_DB */
+#define WM8903_GP5_DB_WIDTH                          1  /* GP5_DB */
+
+#define WM8903_NUM_GPIO 5
+
+struct wm8903_platform_data {
+	bool irq_active_low;   /* Set if IRQ active low, default high */
+
+        /* Default register value for R6 (Mic bias), used to configure
+	 * microphone detection.  In conjunction with gpio_cfg this
+	 * can be used to route the microphone status signals out onto
+	 * the GPIOs for use with snd_soc_jack_add_gpios().
+	 */
+	u16 micdet_cfg;
+
+	int micdet_delay;      /* Delay after microphone detection (ms) */
+
+	int gpio_base;
+	u32 gpio_cfg[WM8903_NUM_GPIO]; /* Default register values for GPIO pin mux */
+};
+
+#endif
diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h
new file mode 100644
index 0000000..6d8f8fb
--- /dev/null
+++ b/include/sound/wm8904.h
@@ -0,0 +1,163 @@
+/*
+ * Platform data for WM8904
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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.
+ *
+ */
+
+#ifndef __MFD_WM8994_PDATA_H__
+#define __MFD_WM8994_PDATA_H__
+
+/* Used to enable configuration of a GPIO to all zeros */
+#define WM8904_GPIO_NO_CONFIG 0x8000
+
+/*
+ * R6 (0x06) - Mic Bias Control 0
+ */
+#define WM8904_MICDET_THR_MASK                  0x0070  /* MICDET_THR - [6:4] */
+#define WM8904_MICDET_THR_SHIFT                      4  /* MICDET_THR - [6:4] */
+#define WM8904_MICDET_THR_WIDTH                      3  /* MICDET_THR - [6:4] */
+#define WM8904_MICSHORT_THR_MASK                0x000C  /* MICSHORT_THR - [3:2] */
+#define WM8904_MICSHORT_THR_SHIFT                    2  /* MICSHORT_THR - [3:2] */
+#define WM8904_MICSHORT_THR_WIDTH                    2  /* MICSHORT_THR - [3:2] */
+#define WM8904_MICDET_ENA                       0x0002  /* MICDET_ENA */
+#define WM8904_MICDET_ENA_MASK                  0x0002  /* MICDET_ENA */
+#define WM8904_MICDET_ENA_SHIFT                      1  /* MICDET_ENA */
+#define WM8904_MICDET_ENA_WIDTH                      1  /* MICDET_ENA */
+#define WM8904_MICBIAS_ENA                      0x0001  /* MICBIAS_ENA */
+#define WM8904_MICBIAS_ENA_MASK                 0x0001  /* MICBIAS_ENA */
+#define WM8904_MICBIAS_ENA_SHIFT                     0  /* MICBIAS_ENA */
+#define WM8904_MICBIAS_ENA_WIDTH                     1  /* MICBIAS_ENA */
+
+/*
+ * R7 (0x07) - Mic Bias Control 1
+ */
+#define WM8904_MIC_DET_FILTER_ENA               0x8000  /* MIC_DET_FILTER_ENA */
+#define WM8904_MIC_DET_FILTER_ENA_MASK          0x8000  /* MIC_DET_FILTER_ENA */
+#define WM8904_MIC_DET_FILTER_ENA_SHIFT             15  /* MIC_DET_FILTER_ENA */
+#define WM8904_MIC_DET_FILTER_ENA_WIDTH              1  /* MIC_DET_FILTER_ENA */
+#define WM8904_MIC_SHORT_FILTER_ENA             0x4000  /* MIC_SHORT_FILTER_ENA */
+#define WM8904_MIC_SHORT_FILTER_ENA_MASK        0x4000  /* MIC_SHORT_FILTER_ENA */
+#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT           14  /* MIC_SHORT_FILTER_ENA */
+#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH            1  /* MIC_SHORT_FILTER_ENA */
+#define WM8904_MICBIAS_SEL_MASK                 0x0007  /* MICBIAS_SEL - [2:0] */
+#define WM8904_MICBIAS_SEL_SHIFT                     0  /* MICBIAS_SEL - [2:0] */
+#define WM8904_MICBIAS_SEL_WIDTH                     3  /* MICBIAS_SEL - [2:0] */
+
+
+/*
+ * R121 (0x79) - GPIO Control 1
+ */
+#define WM8904_GPIO1_PU                         0x0020  /* GPIO1_PU */
+#define WM8904_GPIO1_PU_MASK                    0x0020  /* GPIO1_PU */
+#define WM8904_GPIO1_PU_SHIFT                        5  /* GPIO1_PU */
+#define WM8904_GPIO1_PU_WIDTH                        1  /* GPIO1_PU */
+#define WM8904_GPIO1_PD                         0x0010  /* GPIO1_PD */
+#define WM8904_GPIO1_PD_MASK                    0x0010  /* GPIO1_PD */
+#define WM8904_GPIO1_PD_SHIFT                        4  /* GPIO1_PD */
+#define WM8904_GPIO1_PD_WIDTH                        1  /* GPIO1_PD */
+#define WM8904_GPIO1_SEL_MASK                   0x000F  /* GPIO1_SEL - [3:0] */
+#define WM8904_GPIO1_SEL_SHIFT                       0  /* GPIO1_SEL - [3:0] */
+#define WM8904_GPIO1_SEL_WIDTH                       4  /* GPIO1_SEL - [3:0] */
+
+/*
+ * R122 (0x7A) - GPIO Control 2
+ */
+#define WM8904_GPIO2_PU                         0x0020  /* GPIO2_PU */
+#define WM8904_GPIO2_PU_MASK                    0x0020  /* GPIO2_PU */
+#define WM8904_GPIO2_PU_SHIFT                        5  /* GPIO2_PU */
+#define WM8904_GPIO2_PU_WIDTH                        1  /* GPIO2_PU */
+#define WM8904_GPIO2_PD                         0x0010  /* GPIO2_PD */
+#define WM8904_GPIO2_PD_MASK                    0x0010  /* GPIO2_PD */
+#define WM8904_GPIO2_PD_SHIFT                        4  /* GPIO2_PD */
+#define WM8904_GPIO2_PD_WIDTH                        1  /* GPIO2_PD */
+#define WM8904_GPIO2_SEL_MASK                   0x000F  /* GPIO2_SEL - [3:0] */
+#define WM8904_GPIO2_SEL_SHIFT                       0  /* GPIO2_SEL - [3:0] */
+#define WM8904_GPIO2_SEL_WIDTH                       4  /* GPIO2_SEL - [3:0] */
+
+/*
+ * R123 (0x7B) - GPIO Control 3
+ */
+#define WM8904_GPIO3_PU                         0x0020  /* GPIO3_PU */
+#define WM8904_GPIO3_PU_MASK                    0x0020  /* GPIO3_PU */
+#define WM8904_GPIO3_PU_SHIFT                        5  /* GPIO3_PU */
+#define WM8904_GPIO3_PU_WIDTH                        1  /* GPIO3_PU */
+#define WM8904_GPIO3_PD                         0x0010  /* GPIO3_PD */
+#define WM8904_GPIO3_PD_MASK                    0x0010  /* GPIO3_PD */
+#define WM8904_GPIO3_PD_SHIFT                        4  /* GPIO3_PD */
+#define WM8904_GPIO3_PD_WIDTH                        1  /* GPIO3_PD */
+#define WM8904_GPIO3_SEL_MASK                   0x000F  /* GPIO3_SEL - [3:0] */
+#define WM8904_GPIO3_SEL_SHIFT                       0  /* GPIO3_SEL - [3:0] */
+#define WM8904_GPIO3_SEL_WIDTH                       4  /* GPIO3_SEL - [3:0] */
+
+/*
+ * R124 (0x7C) - GPIO Control 4
+ */
+#define WM8904_GPI7_ENA                         0x0200  /* GPI7_ENA */
+#define WM8904_GPI7_ENA_MASK                    0x0200  /* GPI7_ENA */
+#define WM8904_GPI7_ENA_SHIFT                        9  /* GPI7_ENA */
+#define WM8904_GPI7_ENA_WIDTH                        1  /* GPI7_ENA */
+#define WM8904_GPI8_ENA                         0x0100  /* GPI8_ENA */
+#define WM8904_GPI8_ENA_MASK                    0x0100  /* GPI8_ENA */
+#define WM8904_GPI8_ENA_SHIFT                        8  /* GPI8_ENA */
+#define WM8904_GPI8_ENA_WIDTH                        1  /* GPI8_ENA */
+#define WM8904_GPIO_BCLK_MODE_ENA               0x0080  /* GPIO_BCLK_MODE_ENA */
+#define WM8904_GPIO_BCLK_MODE_ENA_MASK          0x0080  /* GPIO_BCLK_MODE_ENA */
+#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT              7  /* GPIO_BCLK_MODE_ENA */
+#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH              1  /* GPIO_BCLK_MODE_ENA */
+#define WM8904_GPIO_BCLK_SEL_MASK               0x000F  /* GPIO_BCLK_SEL - [3:0] */
+#define WM8904_GPIO_BCLK_SEL_SHIFT                   0  /* GPIO_BCLK_SEL - [3:0] */
+#define WM8904_GPIO_BCLK_SEL_WIDTH                   4  /* GPIO_BCLK_SEL - [3:0] */
+
+#define WM8904_MIC_REGS  2
+#define WM8904_GPIO_REGS 4
+#define WM8904_DRC_REGS  4
+#define WM8904_EQ_REGS   24
+
+/**
+ * DRC configurations are specified with a label and a set of register
+ * values to write (the enable bits will be ignored).  At runtime an
+ * enumerated control will be presented for each DRC block allowing
+ * the user to choose the configration to use.
+ *
+ * Configurations may be generated by hand or by using the DRC control
+ * panel provided by the WISCE - see  http://www.wolfsonmicro.com/wisce/
+ * for details.
+ */
+struct wm8904_drc_cfg {
+	const char *name;
+	u16 regs[WM8904_DRC_REGS];
+};
+
+/**
+ * ReTune Mobile configurations are specified with a label, sample
+ * rate and set of values to write (the enable bits will be ignored).
+ *
+ * Configurations are expected to be generated using the ReTune Mobile
+ * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
+ */
+struct wm8904_retune_mobile_cfg {
+	const char *name;
+	unsigned int rate;
+	u16 regs[WM8904_EQ_REGS];
+};
+
+struct wm8904_pdata {
+	int num_drc_cfgs;
+	struct wm8904_drc_cfg *drc_cfgs;
+
+	int num_retune_mobile_cfgs;
+	struct wm8904_retune_mobile_cfg *retune_mobile_cfgs;
+
+	u32 gpio_cfg[WM8904_GPIO_REGS];
+	u32 mic_cfg[WM8904_MIC_REGS];
+};
+
+#endif
diff --git a/include/sound/wm8955.h b/include/sound/wm8955.h
new file mode 100644
index 0000000..5074ef4
--- /dev/null
+++ b/include/sound/wm8955.h
@@ -0,0 +1,26 @@
+/*
+ * Platform data for WM8955
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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.
+ *
+ */
+
+#ifndef __WM8955_PDATA_H__
+#define __WM8955_PDATA_H__
+
+struct wm8955_pdata {
+	/* Configure LOUT2/ROUT2 to drive a speaker */
+	unsigned int out2_speaker:1;
+
+	/* Configure MONOIN+/- in differential mode */
+	unsigned int monoin_diff:1;
+};
+
+#endif
diff --git a/include/sound/wm8960.h b/include/sound/wm8960.h
new file mode 100644
index 0000000..e8ce8ee
--- /dev/null
+++ b/include/sound/wm8960.h
@@ -0,0 +1,24 @@
+/*
+ * wm8960.h  --  WM8960 Soc Audio driver platform data
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8960_PDATA_H
+#define _WM8960_PDATA_H
+
+#define WM8960_DRES_400R 0
+#define WM8960_DRES_200R 1
+#define WM8960_DRES_600R 2
+#define WM8960_DRES_150R 3
+#define WM8960_DRES_MAX  3
+
+struct wm8960_data {
+	bool capless;  /* Headphone outputs configured in capless mode */
+
+	bool shared_lrclk;  /* DAC and ADC LRCLKs are wired together */
+};
+
+#endif
diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h
new file mode 100644
index 0000000..0af7c16
--- /dev/null
+++ b/include/sound/wm8962.h
@@ -0,0 +1,61 @@
+/*
+ * wm8962.h  --  WM8962 Soc Audio driver platform data
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8962_PDATA_H
+#define _WM8962_PDATA_H
+
+#define WM8962_MAX_GPIO 6
+
+/* Use to set GPIO default values to zero */
+#define WM8962_GPIO_SET 0x10000
+
+#define WM8962_GPIO_FN_CLKOUT           0
+#define WM8962_GPIO_FN_LOGIC            1
+#define WM8962_GPIO_FN_SDOUT            2
+#define WM8962_GPIO_FN_IRQ              3
+#define WM8962_GPIO_FN_THERMAL          4
+#define WM8962_GPIO_FN_PLL2_LOCK        6
+#define WM8962_GPIO_FN_PLL3_LOCK        7
+#define WM8962_GPIO_FN_FLL_LOCK         9
+#define WM8962_GPIO_FN_DRC_ACT         10
+#define WM8962_GPIO_FN_WSEQ_DONE       11
+#define WM8962_GPIO_FN_ALC_NG_ACT      12
+#define WM8962_GPIO_FN_ALC_PEAK_LIMIT  13
+#define WM8962_GPIO_FN_ALC_SATURATION  14
+#define WM8962_GPIO_FN_ALC_LEVEL_THR   15
+#define WM8962_GPIO_FN_ALC_LEVEL_LOCK  16
+#define WM8962_GPIO_FN_FIFO_ERR        17
+#define WM8962_GPIO_FN_OPCLK           18
+#define WM8962_GPIO_FN_DMICCLK         19
+#define WM8962_GPIO_FN_DMICDAT         20
+#define WM8962_GPIO_FN_MICD            21
+#define WM8962_GPIO_FN_MICSCD          22
+
+struct wm8962_pdata {
+	struct clk *mclk;
+	int gpio_base;
+	u32 gpio_init[WM8962_MAX_GPIO];
+
+	/* Setup for microphone detection, raw value to be written to
+	 * R48(0x30) - only microphone related bits will be updated.
+	 * Detection may be enabled here for use with signals brought
+	 * out on the GPIOs. */
+	u32 mic_cfg;
+
+	bool irq_active_low;
+
+	bool spk_mono;   /* Speaker outputs tied together as mono */
+
+	/**
+	 * This flag should be set if one or both IN4 inputs is wired
+	 * in a DC measurement configuration.
+	 */
+	bool in4_dc_measure;
+};
+
+#endif
diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h
new file mode 100644
index 0000000..8016fd8
--- /dev/null
+++ b/include/sound/wm8993.h
@@ -0,0 +1,48 @@
+/*
+ * linux/sound/wm8993.h -- Platform data for WM8993
+ *
+ * Copyright 2009 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM8993_H
+#define __LINUX_SND_WM8993_H
+
+/* Note that EQ1 only contains the enable/disable bit so will be
+   ignored but is included for simplicity.
+ */
+struct wm8993_retune_mobile_setting {
+	const char *name;
+	unsigned int rate;
+	u16 config[24];
+};
+
+struct wm8993_platform_data {
+	struct wm8993_retune_mobile_setting *retune_configs;
+	int num_retune_configs;
+
+	/* LINEOUT can be differential or single ended */
+	unsigned int lineout1_diff:1;
+	unsigned int lineout2_diff:1;
+
+	/* Common mode feedback */
+	unsigned int lineout1fb:1;
+	unsigned int lineout2fb:1;
+
+	/* Delay to add for microphones to stabalise after power up */
+	int micbias1_delay;
+	int micbias2_delay;
+
+	/* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
+	unsigned int micbias1_lvl:1;
+	unsigned int micbias2_lvl:1;
+
+	/* Jack detect threshold levels, see datasheet for values */
+	unsigned int jd_scthr:2;
+	unsigned int jd_thr:2;
+};
+
+#endif
diff --git a/include/sound/wm8996.h b/include/sound/wm8996.h
new file mode 100644
index 0000000..ea4d88f
--- /dev/null
+++ b/include/sound/wm8996.h
@@ -0,0 +1,55 @@
+/*
+ * linux/sound/wm8996.h -- Platform data for WM8996
+ *
+ * Copyright 2011 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM8996_H
+#define __LINUX_SND_WM8996_H
+
+enum wm8996_inmode {
+	WM8996_DIFFERRENTIAL_1 = 0,   /* IN1xP - IN1xN */
+	WM8996_INVERTING = 1,         /* IN1xN */
+	WM8996_NON_INVERTING = 2,     /* IN1xP */
+	WM8996_DIFFERENTIAL_2 = 3,    /* IN2xP - IN2xP */
+};
+
+/**
+ * ReTune Mobile configurations are specified with a label, sample
+ * rate and set of values to write (the enable bits will be ignored).
+ *
+ * Configurations are expected to be generated using the ReTune Mobile
+ * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
+ */
+struct wm8996_retune_mobile_config {
+	const char *name;
+	int rate;
+	u16 regs[20];
+};
+
+#define WM8996_SET_DEFAULT 0x10000
+
+struct wm8996_pdata {
+	int irq_flags;  /** Set IRQ trigger flags; default active low */
+
+	int ldo_ena;  /** GPIO for LDO1; -1 for none */
+
+	int micdet_def;  /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */
+
+	enum wm8996_inmode inl_mode;
+	enum wm8996_inmode inr_mode;
+
+	u32 spkmute_seq;  /** Value for register 0x802 */
+
+	int gpio_base;
+	u32 gpio_default[5];
+
+	int num_retune_mobile_cfgs;
+	struct wm8996_retune_mobile_config *retune_mobile_cfgs;
+};
+
+#endif
diff --git a/include/sound/wm9081.h b/include/sound/wm9081.h
new file mode 100644
index 0000000..f34b0b1
--- /dev/null
+++ b/include/sound/wm9081.h
@@ -0,0 +1,28 @@
+/*
+ * linux/sound/wm9081.h -- Platform data for WM9081
+ *
+ * Copyright 2009 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM_9081_H
+#define __LINUX_SND_WM_9081_H
+
+struct wm9081_retune_mobile_setting {
+	const char *name;
+	unsigned int rate;
+	u16 config[20];
+};
+
+struct wm9081_pdata {
+	bool irq_high;   /* IRQ is active high */
+	bool irq_cmos;   /* IRQ is in CMOS mode */
+
+	struct wm9081_retune_mobile_setting *retune_configs;
+	int num_retune_configs;
+};
+
+#endif
diff --git a/include/sound/wm9090.h b/include/sound/wm9090.h
new file mode 100644
index 0000000..3718928
--- /dev/null
+++ b/include/sound/wm9090.h
@@ -0,0 +1,28 @@
+/*
+ * linux/sound/wm9090.h -- Platform data for WM9090
+ *
+ * Copyright 2009, 2010 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM9090_H
+#define __LINUX_SND_WM9090_H
+
+struct wm9090_platform_data {
+	/* Line inputs 1 & 2 can optionally be differential */
+	unsigned int lin1_diff:1;
+	unsigned int lin2_diff:1;
+
+	/* AGC configuration.  This is intended to protect the speaker
+	 * against overdriving and will therefore depend on the
+	 * hardware setup with incorrect runtime configuration
+	 * potentially causing hardware damage.
+	 */
+	unsigned int agc_ena:1;
+	u16 agc[3];
+};
+
+#endif
diff --git a/include/sound/wss.h b/include/sound/wss.h
new file mode 100644
index 0000000..1823e3a
--- /dev/null
+++ b/include/sound/wss.h
@@ -0,0 +1,235 @@
+#ifndef __SOUND_WSS_H
+#define __SOUND_WSS_H
+
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ *  Definitions for CS4231 & InterWave chips & compatible chips
+ *
+ *
+ *   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 <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/timer.h>
+
+#include <sound/cs4231-regs.h>
+
+/* defines for codec.mode */
+
+#define WSS_MODE_NONE	0x0000
+#define WSS_MODE_PLAY	0x0001
+#define WSS_MODE_RECORD	0x0002
+#define WSS_MODE_TIMER	0x0004
+#define WSS_MODE_OPEN	(WSS_MODE_PLAY|WSS_MODE_RECORD|WSS_MODE_TIMER)
+
+/* defines for codec.hardware */
+
+#define WSS_HW_DETECT        0x0000	/* let CS4231 driver detect chip */
+#define WSS_HW_DETECT3	0x0001	/* allow mode 3 */
+#define WSS_HW_TYPE_MASK	0xff00	/* type mask */
+#define WSS_HW_CS4231_MASK   0x0100	/* CS4231 serie */
+#define WSS_HW_CS4231        0x0100	/* CS4231 chip */
+#define WSS_HW_CS4231A       0x0101	/* CS4231A chip */
+#define WSS_HW_AD1845	0x0102	/* AD1845 chip */
+#define WSS_HW_CS4232_MASK   0x0200	/* CS4232 serie (has control ports) */
+#define WSS_HW_CS4232        0x0200	/* CS4232 */
+#define WSS_HW_CS4232A       0x0201	/* CS4232A */
+#define WSS_HW_CS4236	0x0202	/* CS4236 */
+#define WSS_HW_CS4236B_MASK	0x0400	/* CS4236B serie (has extended control regs) */
+#define WSS_HW_CS4235	0x0400	/* CS4235 - Crystal Clear (tm) stereo enhancement */
+#define WSS_HW_CS4236B       0x0401	/* CS4236B */
+#define WSS_HW_CS4237B       0x0402	/* CS4237B - SRS 3D */
+#define WSS_HW_CS4238B	0x0403	/* CS4238B - QSOUND 3D */
+#define WSS_HW_CS4239	0x0404	/* CS4239 - Crystal Clear (tm) stereo enhancement */
+#define WSS_HW_AD1848_MASK	0x0800	/* AD1848 serie (half duplex) */
+#define WSS_HW_AD1847		0x0801	/* AD1847 chip */
+#define WSS_HW_AD1848		0x0802	/* AD1848 chip */
+#define WSS_HW_CS4248		0x0803	/* CS4248 chip */
+#define WSS_HW_CMI8330		0x0804	/* CMI8330 chip */
+#define WSS_HW_THINKPAD		0x0805	/* Thinkpad 360/750/755 */
+/* compatible, but clones */
+#define WSS_HW_INTERWAVE     0x1000	/* InterWave chip */
+#define WSS_HW_OPL3SA2       0x1101	/* OPL3-SA2 chip, similar to cs4231 */
+#define WSS_HW_OPTI93X 	0x1102	/* Opti 930/931/933 */
+
+/* defines for codec.hwshare */
+#define WSS_HWSHARE_IRQ	(1<<0)
+#define WSS_HWSHARE_DMA1	(1<<1)
+#define WSS_HWSHARE_DMA2	(1<<2)
+
+/* IBM Thinkpad specific stuff */
+#define AD1848_THINKPAD_CTL_PORT1		0x15e8
+#define AD1848_THINKPAD_CTL_PORT2		0x15e9
+#define AD1848_THINKPAD_CS4248_ENABLE_BIT	0x02
+
+struct snd_wss {
+	unsigned long port;		/* base i/o port */
+	struct resource *res_port;
+	unsigned long cport;		/* control base i/o port (CS4236) */
+	struct resource *res_cport;
+	int irq;			/* IRQ line */
+	int dma1;			/* playback DMA */
+	int dma2;			/* record DMA */
+	unsigned short version;		/* version of CODEC chip */
+	unsigned short mode;		/* see to WSS_MODE_XXXX */
+	unsigned short hardware;	/* see to WSS_HW_XXXX */
+	unsigned short hwshare;		/* shared resources */
+	unsigned short single_dma:1,	/* forced single DMA mode (GUS 16-bit */
+					/* daughter board) or dma1 == dma2 */
+		       ebus_flag:1,	/* SPARC: EBUS present */
+		       thinkpad_flag:1;	/* Thinkpad CS4248 needs extra help */
+
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	struct snd_timer *timer;
+
+	unsigned char image[32];	/* registers image */
+	unsigned char eimage[32];	/* extended registers image */
+	unsigned char cimage[16];	/* control registers image */
+	int mce_bit;
+	int calibrate_mute;
+	int sw_3d_bit;
+	unsigned int p_dma_size;
+	unsigned int c_dma_size;
+
+	spinlock_t reg_lock;
+	struct mutex mce_mutex;
+	struct mutex open_mutex;
+
+	int (*rate_constraint) (struct snd_pcm_runtime *runtime);
+	void (*set_playback_format) (struct snd_wss *chip,
+				     struct snd_pcm_hw_params *hw_params,
+				     unsigned char pdfr);
+	void (*set_capture_format) (struct snd_wss *chip,
+				    struct snd_pcm_hw_params *hw_params,
+				    unsigned char cdfr);
+	void (*trigger) (struct snd_wss *chip, unsigned int what, int start);
+#ifdef CONFIG_PM
+	void (*suspend) (struct snd_wss *chip);
+	void (*resume) (struct snd_wss *chip);
+#endif
+	void *dma_private_data;
+	int (*claim_dma) (struct snd_wss *chip,
+			  void *dma_private_data, int dma);
+	int (*release_dma) (struct snd_wss *chip,
+			    void *dma_private_data, int dma);
+};
+
+/* exported functions */
+
+void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char val);
+unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg);
+void snd_cs4236_ext_out(struct snd_wss *chip,
+			unsigned char reg, unsigned char val);
+unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg);
+void snd_wss_mce_up(struct snd_wss *chip);
+void snd_wss_mce_down(struct snd_wss *chip);
+
+void snd_wss_overrange(struct snd_wss *chip);
+
+irqreturn_t snd_wss_interrupt(int irq, void *dev_id);
+
+const char *snd_wss_chip_id(struct snd_wss *chip);
+
+int snd_wss_create(struct snd_card *card,
+		      unsigned long port,
+		      unsigned long cport,
+		      int irq, int dma1, int dma2,
+		      unsigned short hardware,
+		      unsigned short hwshare,
+		      struct snd_wss **rchip);
+int snd_wss_pcm(struct snd_wss *chip, int device);
+int snd_wss_timer(struct snd_wss *chip, int device);
+int snd_wss_mixer(struct snd_wss *chip);
+
+const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction);
+
+int snd_cs4236_create(struct snd_card *card,
+		      unsigned long port,
+		      unsigned long cport,
+		      int irq, int dma1, int dma2,
+		      unsigned short hardware,
+		      unsigned short hwshare,
+		      struct snd_wss **rchip);
+int snd_cs4236_pcm(struct snd_wss *chip, int device);
+int snd_cs4236_mixer(struct snd_wss *chip);
+
+/*
+ *  mixer library
+ */
+
+#define WSS_SINGLE(xname, xindex, reg, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_wss_info_single, \
+  .get = snd_wss_get_single, \
+  .put = snd_wss_put_single, \
+  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
+
+int snd_wss_info_single(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_info *uinfo);
+int snd_wss_get_single(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+int snd_wss_put_single(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+
+#define WSS_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_wss_info_double, \
+  .get = snd_wss_get_double, \
+  .put = snd_wss_put_double, \
+  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
+		   (shift_right << 19) | (mask << 24) | (invert << 22) }
+
+#define WSS_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_wss_info_single, \
+  .get = snd_wss_get_single, \
+  .put = snd_wss_put_single, \
+  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
+  .tlv = { .p = (xtlv) } }
+
+#define WSS_DOUBLE_TLV(xname, xindex, left_reg, right_reg, \
+			shift_left, shift_right, mask, invert, xtlv) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_wss_info_double, \
+  .get = snd_wss_get_double, \
+  .put = snd_wss_put_double, \
+  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
+		   (shift_right << 19) | (mask << 24) | (invert << 22), \
+  .tlv = { .p = (xtlv) } }
+
+
+int snd_wss_info_double(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_info *uinfo);
+int snd_wss_get_double(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+int snd_wss_put_double(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol);
+
+#endif /* __SOUND_WSS_H */