summaryrefslogtreecommitdiffstats
path: root/include/sound
diff options
context:
space:
mode:
Diffstat (limited to 'include/sound')
-rw-r--r--include/sound/ac97_codec.h598
-rw-r--r--include/sound/ad1816a.h174
-rw-r--r--include/sound/ad1848.h206
-rw-r--r--include/sound/ainstr_fm.h130
-rw-r--r--include/sound/ainstr_gf1.h225
-rw-r--r--include/sound/ainstr_iw.h373
-rw-r--r--include/sound/ainstr_simple.h156
-rw-r--r--include/sound/ak4114.h205
-rw-r--r--include/sound/ak4117.h191
-rw-r--r--include/sound/ak4531_codec.h80
-rw-r--r--include/sound/ak4xxx-adda.h69
-rw-r--r--include/sound/asequencer.h908
-rw-r--r--include/sound/asound.h927
-rw-r--r--include/sound/asound_fm.h115
-rw-r--r--include/sound/asoundef.h227
-rw-r--r--include/sound/control.h162
-rw-r--r--include/sound/core.h502
-rw-r--r--include/sound/cs4231.h366
-rw-r--r--include/sound/cs46xx.h1756
-rw-r--r--include/sound/cs46xx_dsp_scb_types.h1216
-rw-r--r--include/sound/cs46xx_dsp_spos.h233
-rw-r--r--include/sound/cs46xx_dsp_task_types.h253
-rw-r--r--include/sound/cs8403.h257
-rw-r--r--include/sound/cs8427.h196
-rw-r--r--include/sound/driver.h64
-rw-r--r--include/sound/emu10k1.h1544
-rw-r--r--include/sound/emu10k1_synth.h39
-rw-r--r--include/sound/emu8000.h120
-rw-r--r--include/sound/emu8000_reg.h207
-rw-r--r--include/sound/emux_legacy.h146
-rw-r--r--include/sound/emux_synth.h243
-rw-r--r--include/sound/es1688.h123
-rw-r--r--include/sound/gus.h718
-rw-r--r--include/sound/hdsp.h110
-rw-r--r--include/sound/hwdep.h73
-rw-r--r--include/sound/i2c.h102
-rw-r--r--include/sound/info.h193
-rw-r--r--include/sound/initval.h103
-rw-r--r--include/sound/memalloc.h118
-rw-r--r--include/sound/minors.h89
-rw-r--r--include/sound/mixer_oss.h76
-rw-r--r--include/sound/mpu401.h115
-rw-r--r--include/sound/opl3.h339
-rw-r--r--include/sound/opl4.h32
-rw-r--r--include/sound/pcm-indirect.h177
-rw-r--r--include/sound/pcm.h1040
-rw-r--r--include/sound/pcm_oss.h87
-rw-r--r--include/sound/pcm_params.h366
-rw-r--r--include/sound/rawmidi.h180
-rw-r--r--include/sound/sb.h360
-rw-r--r--include/sound/sb16_csp.h167
-rw-r--r--include/sound/seq_device.h88
-rw-r--r--include/sound/seq_instr.h112
-rw-r--r--include/sound/seq_kernel.h191
-rw-r--r--include/sound/seq_midi_emul.h195
-rw-r--r--include/sound/seq_midi_event.h56
-rw-r--r--include/sound/seq_oss.h102
-rw-r--r--include/sound/seq_oss_legacy.h31
-rw-r--r--include/sound/seq_virmidi.h84
-rw-r--r--include/sound/sfnt_info.h214
-rw-r--r--include/sound/snd_wavefront.h141
-rw-r--r--include/sound/soundfont.h130
-rw-r--r--include/sound/sscape_ioctl.h21
-rw-r--r--include/sound/tea575x-tuner.h53
-rw-r--r--include/sound/tea6330t.h42
-rw-r--r--include/sound/timer.h157
-rw-r--r--include/sound/trident.h479
-rw-r--r--include/sound/uda1341.h233
-rw-r--r--include/sound/util_mem.h64
-rw-r--r--include/sound/version.h3
-rw-r--r--include/sound/vx_core.h562
-rw-r--r--include/sound/wavefront.h695
-rw-r--r--include/sound/wavefront_fx.h9
-rw-r--r--include/sound/ymfpci.h396
74 files changed, 20514 insertions, 0 deletions
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
new file mode 100644
index 0000000..2433e27
--- /dev/null
+++ b/include/sound/ac97_codec.h
@@ -0,0 +1,598 @@
+#ifndef __SOUND_AC97_CODEC_H
+#define __SOUND_AC97_CODEC_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "pcm.h"
+#include "control.h"
+#include "info.h"
+
+/*
+ * AC'97 codec registers
+ */
+
+#define AC97_RESET 0x00 /* Reset */
+#define AC97_MASTER 0x02 /* Master Volume */
+#define AC97_HEADPHONE 0x04 /* Headphone Volume (optional) */
+#define AC97_MASTER_MONO 0x06 /* Master Volume Mono (optional) */
+#define AC97_MASTER_TONE 0x08 /* Master Tone (Bass & Treble) (optional) */
+#define AC97_PC_BEEP 0x0a /* PC Beep Volume (optinal) */
+#define AC97_PHONE 0x0c /* Phone Volume (optional) */
+#define AC97_MIC 0x0e /* MIC Volume */
+#define AC97_LINE 0x10 /* Line In Volume */
+#define AC97_CD 0x12 /* CD Volume */
+#define AC97_VIDEO 0x14 /* Video Volume (optional) */
+#define AC97_AUX 0x16 /* AUX Volume (optional) */
+#define AC97_PCM 0x18 /* PCM Volume */
+#define AC97_REC_SEL 0x1a /* Record Select */
+#define AC97_REC_GAIN 0x1c /* Record Gain */
+#define AC97_REC_GAIN_MIC 0x1e /* Record Gain MIC (optional) */
+#define AC97_GENERAL_PURPOSE 0x20 /* General Purpose (optional) */
+#define AC97_3D_CONTROL 0x22 /* 3D Control (optional) */
+#define AC97_INT_PAGING 0x24 /* Audio Interrupt & Paging (AC'97 2.3) */
+#define AC97_POWERDOWN 0x26 /* Powerdown control / status */
+/* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */
+#define AC97_EXTENDED_ID 0x28 /* Extended Audio ID */
+#define AC97_EXTENDED_STATUS 0x2a /* Extended Audio Status and Control */
+#define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */
+#define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */
+#define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */
+#define AC97_SPDIF 0x3a /* S/PDIF control */
+/* range 0x3c-0x58 - MODEM */
+#define AC97_EXTENDED_MID 0x3c /* Extended Modem ID */
+#define AC97_EXTENDED_MSTATUS 0x3e /* Extended Modem Status and Control */
+#define AC97_LINE1_RATE 0x40 /* Line1 DAC/ADC Rate */
+#define AC97_LINE2_RATE 0x42 /* Line2 DAC/ADC Rate */
+#define AC97_HANDSET_RATE 0x44 /* Handset DAC/ADC Rate */
+#define AC97_LINE1_LEVEL 0x46 /* Line1 DAC/ADC Level */
+#define AC97_LINE2_LEVEL 0x48 /* Line2 DAC/ADC Level */
+#define AC97_HANDSET_LEVEL 0x4a /* Handset DAC/ADC Level */
+#define AC97_GPIO_CFG 0x4c /* GPIO Configuration */
+#define AC97_GPIO_POLARITY 0x4e /* GPIO Pin Polarity/Type, 0=low, 1=high active */
+#define AC97_GPIO_STICKY 0x50 /* GPIO Pin Sticky, 0=not, 1=sticky */
+#define AC97_GPIO_WAKEUP 0x52 /* GPIO Pin Wakeup, 0=no int, 1=yes int */
+#define AC97_GPIO_STATUS 0x54 /* GPIO Pin Status, slot 12 */
+#define AC97_MISC_AFE 0x56 /* Miscellaneous Modem AFE Status and Control */
+/* range 0x5a-0x7b - Vendor Specific */
+#define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */
+#define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */
+/* range 0x60-0x6f (page 1) - extended codec registers */
+#define AC97_CODEC_CLASS_REV 0x60 /* Codec Class/Revision */
+#define AC97_PCI_SVID 0x62 /* PCI Subsystem Vendor ID */
+#define AC97_PCI_SID 0x64 /* PCI Subsystem ID */
+#define AC97_FUNC_SELECT 0x66 /* Function Select */
+#define AC97_FUNC_INFO 0x68 /* Function Information */
+#define AC97_SENSE_INFO 0x6a /* Sense Details */
+
+/* slot allocation */
+#define AC97_SLOT_TAG 0
+#define AC97_SLOT_CMD_ADDR 1
+#define AC97_SLOT_CMD_DATA 2
+#define AC97_SLOT_PCM_LEFT 3
+#define AC97_SLOT_PCM_RIGHT 4
+#define AC97_SLOT_MODEM_LINE1 5
+#define AC97_SLOT_PCM_CENTER 6
+#define AC97_SLOT_MIC 6 /* input */
+#define AC97_SLOT_SPDIF_LEFT1 6
+#define AC97_SLOT_PCM_SLEFT 7 /* surround left */
+#define AC97_SLOT_PCM_LEFT_0 7 /* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT 7
+#define AC97_SLOT_PCM_SRIGHT 8 /* surround right */
+#define AC97_SLOT_PCM_RIGHT_0 8 /* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT 8
+#define AC97_SLOT_LFE 9
+#define AC97_SLOT_SPDIF_RIGHT1 9
+#define AC97_SLOT_MODEM_LINE2 10
+#define AC97_SLOT_PCM_LEFT_1 10 /* double rate operation */
+#define AC97_SLOT_SPDIF_LEFT2 10
+#define AC97_SLOT_HANDSET 11 /* output */
+#define AC97_SLOT_PCM_RIGHT_1 11 /* double rate operation */
+#define AC97_SLOT_SPDIF_RIGHT2 11
+#define AC97_SLOT_MODEM_GPIO 12 /* modem GPIO */
+#define AC97_SLOT_PCM_CENTER_1 12 /* double rate operation */
+
+/* basic capabilities (reset register) */
+#define AC97_BC_DEDICATED_MIC 0x0001 /* Dedicated Mic PCM In Channel */
+#define AC97_BC_RESERVED1 0x0002 /* Reserved (was Modem Line Codec support) */
+#define AC97_BC_BASS_TREBLE 0x0004 /* Bass & Treble Control */
+#define AC97_BC_SIM_STEREO 0x0008 /* Simulated stereo */
+#define AC97_BC_HEADPHONE 0x0010 /* Headphone Out Support */
+#define AC97_BC_LOUDNESS 0x0020 /* Loudness (bass boost) Support */
+#define AC97_BC_16BIT_DAC 0x0000 /* 16-bit DAC resolution */
+#define AC97_BC_18BIT_DAC 0x0040 /* 18-bit DAC resolution */
+#define AC97_BC_20BIT_DAC 0x0080 /* 20-bit DAC resolution */
+#define AC97_BC_DAC_MASK 0x00c0
+#define AC97_BC_16BIT_ADC 0x0000 /* 16-bit ADC resolution */
+#define AC97_BC_18BIT_ADC 0x0100 /* 18-bit ADC resolution */
+#define AC97_BC_20BIT_ADC 0x0200 /* 20-bit ADC resolution */
+#define AC97_BC_ADC_MASK 0x0300
+
+/* general purpose */
+#define AC97_GP_DRSS_MASK 0x0c00 /* double rate slot select */
+#define AC97_GP_DRSS_1011 0x0000 /* LR(C) 10+11(+12) */
+#define AC97_GP_DRSS_78 0x0400 /* LR 7+8 */
+
+/* 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_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 */
+
+/* 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 YMF753 */
+#define AC97_YMF753_DIT_CTRL2 0x66 /* DIT Control 2 */
+#define AC97_YMF753_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 */
+
+/* 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 */
+
+/* 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
+
+/* shared controllers */
+enum {
+ AC97_SHARED_TYPE_NONE,
+ AC97_SHARED_TYPE_ICH,
+ AC97_SHARED_TYPE_ATIIXP,
+ AC97_SHARED_TYPE_VIA,
+ AC97_SHARED_TYPES
+};
+
+/*
+ *
+ */
+
+typedef struct _snd_ac97_bus ac97_bus_t;
+typedef struct _snd_ac97_bus_ops ac97_bus_ops_t;
+typedef struct _snd_ac97_template ac97_template_t;
+typedef struct _snd_ac97 ac97_t;
+
+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
+};
+
+/* PCM allocation */
+struct ac97_pcm {
+ ac97_bus_t *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 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];
+ ac97_t *codec[4]; /* allocated codecs */
+ } r[2]; /* 0 = standard rates, 1 = double rates */
+ unsigned long private_value; /* used by the hardware driver */
+};
+
+struct snd_ac97_build_ops {
+ int (*build_3d) (ac97_t *ac97);
+ int (*build_specific) (ac97_t *ac97);
+ int (*build_spdif) (ac97_t *ac97);
+ int (*build_post_spdif) (ac97_t *ac97);
+#ifdef CONFIG_PM
+ void (*suspend) (ac97_t *ac97);
+ void (*resume) (ac97_t *ac97);
+#endif
+};
+
+struct _snd_ac97_bus_ops {
+ void (*reset) (ac97_t *ac97);
+ void (*write) (ac97_t *ac97, unsigned short reg, unsigned short val);
+ unsigned short (*read) (ac97_t *ac97, unsigned short reg);
+ void (*wait) (ac97_t *ac97);
+ void (*init) (ac97_t *ac97);
+};
+
+struct _snd_ac97_bus {
+ /* -- lowlevel (hardware) driver specific -- */
+ ac97_bus_ops_t *ops;
+ void *private_data;
+ void (*private_free) (ac97_bus_t *bus);
+ /* --- */
+ snd_card_t *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;
+ unsigned int shared_type; /* type of shared controller betwen audio and modem */
+ ac97_t *codec[4];
+ snd_info_entry_t *proc;
+};
+
+struct _snd_ac97_template {
+ void *private_data;
+ void (*private_free) (ac97_t *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 */
+ unsigned int limited_regs; /* allow limited registers only */
+ DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
+};
+
+struct _snd_ac97 {
+ /* -- lowlevel (hardware) driver specific -- */
+ struct snd_ac97_build_ops * build_ops;
+ void *private_data;
+ void (*private_free) (ac97_t *ac97);
+ /* --- */
+ ac97_bus_t *bus;
+ struct pci_dev *pci; /* assigned PCI device - used for quirks */
+ snd_info_entry_t *proc;
+ snd_info_entry_t *proc_regs;
+ unsigned short subsystem_vendor;
+ unsigned short subsystem_device;
+ struct semaphore reg_mutex;
+ struct semaphore 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) */
+ 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 */
+ unsigned int limited_regs; /* allow limited registers only */
+ 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
+ } ad18xx;
+ unsigned int dev_flags; /* device specific */
+ } spec;
+};
+
+/* conditions */
+static inline int ac97_is_audio(ac97_t * ac97)
+{
+ return (ac97->scaps & AC97_SCAP_AUDIO);
+}
+static inline int ac97_is_modem(ac97_t * ac97)
+{
+ return (ac97->scaps & AC97_SCAP_MODEM);
+}
+static inline int ac97_is_rev22(ac97_t * ac97)
+{
+ return (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_22;
+}
+static inline int ac97_can_amap(ac97_t * ac97)
+{
+ return (ac97->ext_id & AC97_EI_AMAP) != 0;
+}
+static inline int ac97_can_spdif(ac97_t * ac97)
+{
+ return (ac97->ext_id & AC97_EI_SPDIF) != 0;
+}
+
+/* functions */
+int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, void *private_data, ac97_bus_t **rbus); /* create new AC97 bus */
+int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97); /* create mixer controls */
+const char *snd_ac97_get_short_name(ac97_t *ac97);
+
+void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value);
+unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg);
+void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value);
+int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value);
+int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value);
+#ifdef CONFIG_PM
+void snd_ac97_suspend(ac97_t *ac97);
+void snd_ac97_resume(ac97_t *ac97);
+#endif
+
+/* quirk types */
+enum {
+ AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
+ AC97_TUNE_NONE = 0, /* nothing extra to do */
+ AC97_TUNE_HP_ONLY, /* headphone (true line-out) control as master only */
+ AC97_TUNE_SWAP_HP, /* swap headphone and master controls */
+ AC97_TUNE_SWAP_SURROUND, /* swap master and surround controls */
+ AC97_TUNE_AD_SHARING, /* for AD1985, turn on OMS bit and use headphone */
+ AC97_TUNE_ALC_JACK, /* for Realtek, enable JACK detection */
+ AC97_TUNE_INV_EAPD, /* inverted EAPD implementation */
+ AC97_TUNE_MUTE_LED, /* EAPD bit works as mute LED */
+};
+
+struct ac97_quirk {
+ unsigned short vendor; /* PCI vendor id */
+ unsigned short device; /* PCI 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(ac97_t *ac97, struct ac97_quirk *quirk, const char *override);
+int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate);
+
+int snd_ac97_pcm_assign(ac97_bus_t *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(snd_pcm_runtime_t *runtime);
+
+struct ac97_enum {
+ unsigned char reg;
+ unsigned char shift_l;
+ unsigned char shift_r;
+ unsigned short mask;
+ const char **texts;
+};
+#endif /* __SOUND_AC97_CODEC_H */
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
new file mode 100644
index 0000000..395978e
--- /dev/null
+++ b/include/sound/ad1816a.h
@@ -0,0 +1,174 @@
+#ifndef __SOUND_AD1816A_H
+#define __SOUND_AD1816A_H
+
+/*
+ ad1816a.h - definitions for ADI SoundPort AD1816A chip.
+ Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "control.h"
+#include "pcm.h"
+#include "timer.h"
+
+#define AD1816A_REG(r) (chip->port + r)
+
+#define AD1816A_CHIP_STATUS 0x00
+#define AD1816A_INDIR_ADDR 0x00
+#define AD1816A_INTERRUPT_STATUS 0x01
+#define AD1816A_INDIR_DATA_LOW 0x02
+#define AD1816A_INDIR_DATA_HIGH 0x03
+#define AD1816A_PIO_DEBUG 0x04
+#define AD1816A_PIO_STATUS 0x05
+#define AD1816A_PIO_DATA 0x06
+#define AD1816A_RESERVED_7 0x07
+#define AD1816A_PLAYBACK_CONFIG 0x08
+#define AD1816A_CAPTURE_CONFIG 0x09
+#define AD1816A_RESERVED_10 0x0a
+#define AD1816A_RESERVED_11 0x0b
+#define AD1816A_JOYSTICK_RAW_DATA 0x0c
+#define AD1816A_JOYSTICK_CTRL 0x0d
+#define AD1816A_JOY_POS_DATA_LOW 0x0e
+#define AD1816A_JOY_POS_DATA_HIGH 0x0f
+
+#define AD1816A_LOW_BYTE_TMP 0x00
+#define AD1816A_INTERRUPT_ENABLE 0x01
+#define AD1816A_EXTERNAL_CTRL 0x01
+#define AD1816A_PLAYBACK_SAMPLE_RATE 0x02
+#define AD1816A_CAPTURE_SAMPLE_RATE 0x03
+#define AD1816A_VOICE_ATT 0x04
+#define AD1816A_FM_ATT 0x05
+#define AD1816A_I2S_1_ATT 0x06
+#define AD1816A_I2S_0_ATT 0x07
+#define AD1816A_PLAYBACK_BASE_COUNT 0x08
+#define AD1816A_PLAYBACK_CURR_COUNT 0x09
+#define AD1816A_CAPTURE_BASE_COUNT 0x0a
+#define AD1816A_CAPTURE_CURR_COUNT 0x0b
+#define AD1816A_TIMER_BASE_COUNT 0x0c
+#define AD1816A_TIMER_CURR_COUNT 0x0d
+#define AD1816A_MASTER_ATT 0x0e
+#define AD1816A_CD_GAIN_ATT 0x0f
+#define AD1816A_SYNTH_GAIN_ATT 0x10
+#define AD1816A_VID_GAIN_ATT 0x11
+#define AD1816A_LINE_GAIN_ATT 0x12
+#define AD1816A_MIC_GAIN_ATT 0x13
+#define AD1816A_PHONE_IN_GAIN_ATT 0x13
+#define AD1816A_ADC_SOURCE_SEL 0x14
+#define AD1816A_ADC_PGA 0x14
+#define AD1816A_CHIP_CONFIG 0x20
+#define AD1816A_DSP_CONFIG 0x21
+#define AD1816A_FM_SAMPLE_RATE 0x22
+#define AD1816A_I2S_1_SAMPLE_RATE 0x23
+#define AD1816A_I2S_0_SAMPLE_RATE 0x24
+#define AD1816A_RESERVED_37 0x25
+#define AD1816A_PROGRAM_CLOCK_RATE 0x26
+#define AD1816A_3D_PHAT_CTRL 0x27
+#define AD1816A_PHONE_OUT_ATT 0x27
+#define AD1816A_RESERVED_40 0x28
+#define AD1816A_HW_VOL_BUT 0x29
+#define AD1816A_DSP_MAILBOX_0 0x2a
+#define AD1816A_DSP_MAILBOX_1 0x2b
+#define AD1816A_POWERDOWN_CTRL 0x2c
+#define AD1816A_TIMER_CTRL 0x2c
+#define AD1816A_VERSION_ID 0x2d
+#define AD1816A_RESERVED_46 0x2e
+
+#define AD1816A_READY 0x80
+
+#define AD1816A_PLAYBACK_IRQ_PENDING 0x80
+#define AD1816A_CAPTURE_IRQ_PENDING 0x40
+#define AD1816A_TIMER_IRQ_PENDING 0x20
+
+#define AD1816A_PLAYBACK_ENABLE 0x01
+#define AD1816A_PLAYBACK_PIO 0x02
+#define AD1816A_CAPTURE_ENABLE 0x01
+#define AD1816A_CAPTURE_PIO 0x02
+
+#define AD1816A_FMT_LINEAR_8 0x00
+#define AD1816A_FMT_ULAW_8 0x08
+#define AD1816A_FMT_LINEAR_16_LIT 0x10
+#define AD1816A_FMT_ALAW_8 0x18
+#define AD1816A_FMT_LINEAR_16_BIG 0x30
+#define AD1816A_FMT_ALL 0x38
+#define AD1816A_FMT_STEREO 0x04
+
+#define AD1816A_PLAYBACK_IRQ_ENABLE 0x8000
+#define AD1816A_CAPTURE_IRQ_ENABLE 0x4000
+#define AD1816A_TIMER_IRQ_ENABLE 0x2000
+#define AD1816A_TIMER_ENABLE 0x0080
+
+#define AD1816A_SRC_LINE 0x00
+#define AD1816A_SRC_OUT 0x10
+#define AD1816A_SRC_CD 0x20
+#define AD1816A_SRC_SYNTH 0x30
+#define AD1816A_SRC_VIDEO 0x40
+#define AD1816A_SRC_MIC 0x50
+#define AD1816A_SRC_MONO 0x50
+#define AD1816A_SRC_PHONE_IN 0x60
+#define AD1816A_SRC_MASK 0x70
+
+#define AD1816A_CAPTURE_NOT_EQUAL 0x1000
+#define AD1816A_WSS_ENABLE 0x8000
+
+typedef struct _snd_ad1816a ad1816a_t;
+
+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;
+
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+
+ snd_pcm_substream_t *playback_substream;
+ snd_pcm_substream_t *capture_substream;
+ unsigned int p_dma_size;
+ unsigned int c_dma_size;
+
+ snd_timer_t *timer;
+};
+
+
+#define AD1816A_HW_AUTO 0
+#define AD1816A_HW_AD1816A 1
+#define AD1816A_HW_AD1815 2
+#define AD1816A_HW_AD18MAX10 3
+
+#define AD1816A_MODE_PLAYBACK 0x01
+#define AD1816A_MODE_CAPTURE 0x02
+#define AD1816A_MODE_TIMER 0x04
+#define AD1816A_MODE_OPEN (AD1816A_MODE_PLAYBACK | \
+ AD1816A_MODE_CAPTURE | \
+ AD1816A_MODE_TIMER)
+
+
+extern int snd_ad1816a_create(snd_card_t *card, unsigned long port,
+ int irq, int dma1, int dma2,
+ ad1816a_t **chip);
+
+extern int snd_ad1816a_pcm(ad1816a_t *chip, int device, snd_pcm_t **rpcm);
+extern int snd_ad1816a_mixer(ad1816a_t *chip);
+
+#endif /* __SOUND_AD1816A_H */
diff --git a/include/sound/ad1848.h b/include/sound/ad1848.h
new file mode 100644
index 0000000..7e33b11
--- /dev/null
+++ b/include/sound/ad1848.h
@@ -0,0 +1,206 @@
+#ifndef __SOUND_AD1848_H
+#define __SOUND_AD1848_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Definitions for AD1847/AD1848/CS4248 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 "pcm.h"
+#include <linux/interrupt.h>
+
+/* IO ports */
+
+#define AD1848P( codec, x ) ( (chip) -> port + c_d_c_AD1848##x )
+
+#define c_d_c_AD1848REGSEL 0
+#define c_d_c_AD1848REG 1
+#define c_d_c_AD1848STATUS 2
+#define c_d_c_AD1848PIO 3
+
+/* codec registers */
+
+#define AD1848_LEFT_INPUT 0x00 /* left input control */
+#define AD1848_RIGHT_INPUT 0x01 /* right input control */
+#define AD1848_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */
+#define AD1848_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */
+#define AD1848_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */
+#define AD1848_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */
+#define AD1848_LEFT_OUTPUT 0x06 /* left output control register */
+#define AD1848_RIGHT_OUTPUT 0x07 /* right output control register */
+#define AD1848_DATA_FORMAT 0x08 /* clock and data format - playback/capture - bits 7-0 MCE */
+#define AD1848_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */
+#define AD1848_PIN_CTRL 0x0a /* pin control */
+#define AD1848_TEST_INIT 0x0b /* test and initialization */
+#define AD1848_MISC_INFO 0x0c /* miscellaneaous information */
+#define AD1848_LOOPBACK 0x0d /* loopback control */
+#define AD1848_DATA_UPR_CNT 0x0e /* playback/capture upper base count */
+#define AD1848_DATA_LWR_CNT 0x0f /* playback/capture lower base count */
+
+/* definitions for codec register select port - CODECP( REGSEL ) */
+
+#define AD1848_INIT 0x80 /* CODEC is initializing */
+#define AD1848_MCE 0x40 /* mode change enable */
+#define AD1848_TRD 0x20 /* transfer request disable */
+
+/* definitions for codec status register - CODECP( STATUS ) */
+
+#define AD1848_GLOBALIRQ 0x01 /* IRQ is active */
+
+/* definitions for AD1848_LEFT_INPUT and AD1848_RIGHT_INPUT registers */
+
+#define AD1848_ENABLE_MIC_GAIN 0x20
+
+#define AD1848_MIXS_LINE1 0x00
+#define AD1848_MIXS_AUX1 0x40
+#define AD1848_MIXS_LINE2 0x80
+#define AD1848_MIXS_ALL 0xc0
+
+/* definitions for clock and data format register - AD1848_PLAYBK_FORMAT */
+
+#define AD1848_LINEAR_8 0x00 /* 8-bit unsigned data */
+#define AD1848_ALAW_8 0x60 /* 8-bit A-law companded */
+#define AD1848_ULAW_8 0x20 /* 8-bit U-law companded */
+#define AD1848_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */
+#define AD1848_STEREO 0x10 /* stereo mode */
+/* bits 3-1 define frequency divisor */
+#define AD1848_XTAL1 0x00 /* 24.576 crystal */
+#define AD1848_XTAL2 0x01 /* 16.9344 crystal */
+
+/* definitions for interface control register - AD1848_IFACE_CTRL */
+
+#define AD1848_CAPTURE_PIO 0x80 /* capture PIO enable */
+#define AD1848_PLAYBACK_PIO 0x40 /* playback PIO enable */
+#define AD1848_CALIB_MODE 0x18 /* calibration mode bits */
+#define AD1848_AUTOCALIB 0x08 /* auto calibrate */
+#define AD1848_SINGLE_DMA 0x04 /* use single DMA channel */
+#define AD1848_CAPTURE_ENABLE 0x02 /* capture enable */
+#define AD1848_PLAYBACK_ENABLE 0x01 /* playback enable */
+
+/* definitions for pin control register - AD1848_PIN_CTRL */
+
+#define AD1848_IRQ_ENABLE 0x02 /* enable IRQ */
+#define AD1848_XCTL1 0x40 /* external control #1 */
+#define AD1848_XCTL0 0x80 /* external control #0 */
+
+/* definitions for test and init register - AD1848_TEST_INIT */
+
+#define AD1848_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */
+#define AD1848_DMA_REQUEST 0x10 /* DMA request in progress */
+
+/* defines for codec.mode */
+
+#define AD1848_MODE_NONE 0x0000
+#define AD1848_MODE_PLAY 0x0001
+#define AD1848_MODE_CAPTURE 0x0002
+#define AD1848_MODE_TIMER 0x0004
+#define AD1848_MODE_OPEN (AD1848_MODE_PLAY|AD1848_MODE_CAPTURE|AD1848_MODE_TIMER)
+#define AD1848_MODE_RUNNING 0x0010
+
+/* defines for codec.hardware */
+
+#define AD1848_HW_DETECT 0x0000 /* let AD1848 driver detect chip */
+#define AD1848_HW_AD1847 0x0001 /* AD1847 chip */
+#define AD1848_HW_AD1848 0x0002 /* AD1848 chip */
+#define AD1848_HW_CS4248 0x0003 /* CS4248 chip */
+#define AD1848_HW_CMI8330 0x0004 /* CMI8330 chip */
+#define AD1848_HW_THINKPAD 0x0005 /* Thinkpad 360/750/755 */
+
+/* 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_ad1848 {
+ unsigned long port; /* i/o port */
+ struct resource *res_port;
+ int irq; /* IRQ line */
+ int dma; /* data DMA */
+ unsigned short version; /* version of CODEC chip */
+ unsigned short mode; /* see to AD1848_MODE_XXXX */
+ unsigned short hardware; /* see to AD1848_HW_XXXX */
+ unsigned short single_dma:1; /* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
+
+ snd_pcm_t *pcm;
+ snd_pcm_substream_t *playback_substream;
+ snd_pcm_substream_t *capture_substream;
+ snd_card_t *card;
+
+ unsigned char image[32]; /* SGalaxy needs an access to extended registers */
+ int mce_bit;
+ int calibrate_mute;
+ int dma_size;
+ int thinkpad_flag; /* Thinkpad CS4248 needs some extra help */
+
+ spinlock_t reg_lock;
+ struct semaphore open_mutex;
+};
+
+typedef struct _snd_ad1848 ad1848_t;
+
+/* exported functions */
+
+void snd_ad1848_out(ad1848_t *chip, unsigned char reg, unsigned char value);
+
+int snd_ad1848_create(snd_card_t * card,
+ unsigned long port,
+ int irq, int dma,
+ unsigned short hardware,
+ ad1848_t ** chip);
+
+int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm);
+const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction);
+int snd_ad1848_mixer(ad1848_t * chip);
+
+/* exported mixer stuffs */
+enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
+
+#define AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) \
+ ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
+#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \
+ ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22))
+
+int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value);
+
+/* for ease of use */
+struct ad1848_mix_elem {
+ const char *name;
+ int index;
+ int type;
+ unsigned long private_value;
+};
+
+#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
+{ .name = xname, \
+ .index = xindex, \
+ .type = AD1848_MIX_SINGLE, \
+ .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) }
+
+#define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
+{ .name = xname, \
+ .index = xindex, \
+ .type = AD1848_MIX_DOUBLE, \
+ .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) }
+
+static inline int snd_ad1848_add_ctl_elem(ad1848_t *chip, const struct ad1848_mix_elem *c)
+{
+ return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value);
+}
+
+#endif /* __SOUND_AD1848_H */
diff --git a/include/sound/ainstr_fm.h b/include/sound/ainstr_fm.h
new file mode 100644
index 0000000..0ec0295
--- /dev/null
+++ b/include/sound/ainstr_fm.h
@@ -0,0 +1,130 @@
+/*
+ * Advanced Linux Sound Architecture
+ *
+ * FM (OPL2/3) Instrument Format
+ * Copyright (c) 2000 Uros Bizjak <uros@kss-loka.si>
+ *
+ *
+ * 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_AINSTR_FM_H
+#define __SOUND_AINSTR_FM_H
+
+#ifndef __KERNEL__
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#endif
+
+/*
+ * share types (share ID 1)
+ */
+
+#define FM_SHARE_FILE 0
+
+/*
+ * FM operator
+ */
+
+typedef struct fm_operator {
+ unsigned char am_vib;
+ unsigned char ksl_level;
+ unsigned char attack_decay;
+ unsigned char sustain_release;
+ unsigned char wave_select;
+} fm_operator_t;
+
+/*
+ * Instrument
+ */
+
+#define FM_PATCH_OPL2 0x01 /* OPL2 2 operators FM instrument */
+#define FM_PATCH_OPL3 0x02 /* OPL3 4 operators FM instrument */
+
+typedef struct {
+ unsigned int share_id[4]; /* share id - zero = no sharing */
+ unsigned char type; /* instrument type */
+
+ fm_operator_t 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;
+} fm_instrument_t;
+
+/*
+ *
+ * Kernel <-> user space
+ * Hardware (CPU) independent section
+ *
+ * * = zero or more
+ * + = one or more
+ *
+ * fm_xinstrument FM_STRU_INSTR
+ *
+ */
+
+#define FM_STRU_INSTR __cpu_to_be32(('I'<<24)|('N'<<16)|('S'<<8)|'T')
+
+/*
+ * FM operator
+ */
+
+typedef struct fm_xoperator {
+ __u8 am_vib;
+ __u8 ksl_level;
+ __u8 attack_decay;
+ __u8 sustain_release;
+ __u8 wave_select;
+} fm_xoperator_t;
+
+/*
+ * Instrument
+ */
+
+typedef struct fm_xinstrument {
+ __u32 stype; /* structure type */
+
+ __u32 share_id[4]; /* share id - zero = no sharing */
+ __u8 type; /* instrument type */
+
+ fm_xoperator_t op[4]; /* fm operators */
+ __u8 feedback_connection[2];
+
+ __u8 echo_delay;
+ __u8 echo_atten;
+ __u8 chorus_spread;
+ __u8 trnsps;
+ __u8 fix_dur;
+ __u8 modes;
+ __u8 fix_key;
+} fm_xinstrument_t;
+
+#ifdef __KERNEL__
+
+#include "seq_instr.h"
+
+int snd_seq_fm_init(snd_seq_kinstr_ops_t * ops,
+ snd_seq_kinstr_ops_t * next);
+
+#endif
+
+#endif /* __SOUND_AINSTR_FM_H */
diff --git a/include/sound/ainstr_gf1.h b/include/sound/ainstr_gf1.h
new file mode 100644
index 0000000..ae2ddda
--- /dev/null
+++ b/include/sound/ainstr_gf1.h
@@ -0,0 +1,225 @@
+/*
+ * Advanced Linux Sound Architecture
+ *
+ * GF1 (GUS) Patch Instrument Format
+ * Copyright (c) 1994-99 by Jaroslav Kysela <perex@suse.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_AINSTR_GF1_H
+#define __SOUND_AINSTR_GF1_H
+
+#ifndef __KERNEL__
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#endif
+
+/*
+ * share types (share ID 1)
+ */
+
+#define GF1_SHARE_FILE 0
+
+/*
+ * wave formats
+ */
+
+#define GF1_WAVE_16BIT 0x0001 /* 16-bit wave */
+#define GF1_WAVE_UNSIGNED 0x0002 /* unsigned wave */
+#define GF1_WAVE_INVERT 0x0002 /* same as unsigned wave */
+#define GF1_WAVE_BACKWARD 0x0004 /* backward mode (maybe used for reverb or ping-ping loop) */
+#define GF1_WAVE_LOOP 0x0008 /* loop mode */
+#define GF1_WAVE_BIDIR 0x0010 /* bidirectional mode */
+#define GF1_WAVE_STEREO 0x0100 /* stereo mode */
+#define GF1_WAVE_ULAW 0x0200 /* uLaw compression mode */
+
+/*
+ * Wavetable definitions
+ */
+
+typedef struct gf1_wave {
+ unsigned int share_id[4]; /* share id - zero = no sharing */
+ unsigned int format; /* wave format */
+
+ struct {
+ unsigned int number; /* some other ID for this instrument */
+ unsigned int memory; /* begin of waveform in onboard memory */
+ unsigned char *ptr; /* pointer to waveform in system memory */
+ } address;
+
+ unsigned int size; /* size of waveform in samples */
+ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned int loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned int loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned short loop_repeat; /* loop repeat - 0 = forever */
+
+ unsigned char flags; /* GF1 patch flags */
+ unsigned char pad;
+ unsigned int sample_rate; /* sample rate in Hz */
+ unsigned int low_frequency; /* low frequency range */
+ unsigned int high_frequency; /* high frequency range */
+ unsigned int root_frequency; /* root frequency range */
+ signed short tune;
+ unsigned char balance;
+ unsigned char envelope_rate[6];
+ unsigned char envelope_offset[6];
+ unsigned char tremolo_sweep;
+ unsigned char tremolo_rate;
+ unsigned char tremolo_depth;
+ unsigned char vibrato_sweep;
+ unsigned char vibrato_rate;
+ unsigned char vibrato_depth;
+ unsigned short scale_frequency;
+ unsigned short scale_factor; /* 0-2048 or 0-2 */
+
+ struct gf1_wave *next;
+} gf1_wave_t;
+
+/*
+ * Instrument
+ */
+
+#define IWFFFF_EXCLUDE_NONE 0x0000 /* exclusion mode - none */
+#define IWFFFF_EXCLUDE_SINGLE 0x0001 /* exclude single - single note from the instrument group */
+#define IWFFFF_EXCLUDE_MULTIPLE 0x0002 /* exclude multiple - stop only same note from this instrument */
+
+#define IWFFFF_EFFECT_NONE 0
+#define IWFFFF_EFFECT_REVERB 1
+#define IWFFFF_EFFECT_CHORUS 2
+#define IWFFFF_EFFECT_ECHO 3
+
+typedef struct {
+ unsigned short exclusion;
+ unsigned short exclusion_group; /* 0 - none, 1-65535 */
+
+ unsigned char effect1; /* effect 1 */
+ unsigned char effect1_depth; /* 0-127 */
+ unsigned char effect2; /* effect 2 */
+ unsigned char effect2_depth; /* 0-127 */
+
+ gf1_wave_t *wave; /* first waveform */
+} gf1_instrument_t;
+
+/*
+ *
+ * Kernel <-> user space
+ * Hardware (CPU) independent section
+ *
+ * * = zero or more
+ * + = one or more
+ *
+ * gf1_xinstrument IWFFFF_STRU_INSTR
+ * +gf1_xwave IWFFFF_STRU_WAVE
+ *
+ */
+
+#define GF1_STRU_WAVE __cpu_to_be32(('W'<<24)|('A'<<16)|('V'<<8)|'E')
+#define GF1_STRU_INSTR __cpu_to_be32(('I'<<24)|('N'<<16)|('S'<<8)|'T')
+
+/*
+ * Wavetable definitions
+ */
+
+typedef struct gf1_xwave {
+ __u32 stype; /* structure type */
+
+ __u32 share_id[4]; /* share id - zero = no sharing */
+ __u32 format; /* wave format */
+
+ __u32 size; /* size of waveform in samples */
+ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u16 loop_repeat; /* loop repeat - 0 = forever */
+
+ __u8 flags; /* GF1 patch flags */
+ __u8 pad;
+ __u32 sample_rate; /* sample rate in Hz */
+ __u32 low_frequency; /* low frequency range */
+ __u32 high_frequency; /* high frequency range */
+ __u32 root_frequency; /* root frequency range */
+ __s16 tune;
+ __u8 balance;
+ __u8 envelope_rate[6];
+ __u8 envelope_offset[6];
+ __u8 tremolo_sweep;
+ __u8 tremolo_rate;
+ __u8 tremolo_depth;
+ __u8 vibrato_sweep;
+ __u8 vibrato_rate;
+ __u8 vibrato_depth;
+ __u16 scale_frequency;
+ __u16 scale_factor; /* 0-2048 or 0-2 */
+} gf1_xwave_t;
+
+/*
+ * Instrument
+ */
+
+typedef struct gf1_xinstrument {
+ __u32 stype;
+
+ __u16 exclusion;
+ __u16 exclusion_group; /* 0 - none, 1-65535 */
+
+ __u8 effect1; /* effect 1 */
+ __u8 effect1_depth; /* 0-127 */
+ __u8 effect2; /* effect 2 */
+ __u8 effect2_depth; /* 0-127 */
+} gf1_xinstrument_t;
+
+/*
+ * Instrument info
+ */
+
+#define GF1_INFO_ENVELOPE (1<<0)
+#define GF1_INFO_TREMOLO (1<<1)
+#define GF1_INFO_VIBRATO (1<<2)
+
+typedef struct gf1_info {
+ unsigned char flags; /* supported wave flags */
+ unsigned char pad[3];
+ unsigned int features; /* supported features */
+ unsigned int max8_len; /* maximum 8-bit wave length */
+ unsigned int max16_len; /* maximum 16-bit wave length */
+} gf1_info_t;
+
+#ifdef __KERNEL__
+
+#include "seq_instr.h"
+
+typedef struct {
+ void *private_data;
+ int (*info)(void *private_data, gf1_info_t *info);
+ int (*put_sample)(void *private_data, gf1_wave_t *wave,
+ char __user *data, long len, int atomic);
+ int (*get_sample)(void *private_data, gf1_wave_t *wave,
+ char __user *data, long len, int atomic);
+ int (*remove_sample)(void *private_data, gf1_wave_t *wave,
+ int atomic);
+ void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
+ snd_seq_kinstr_ops_t kops;
+} snd_gf1_ops_t;
+
+int snd_seq_gf1_init(snd_gf1_ops_t *ops,
+ void *private_data,
+ snd_seq_kinstr_ops_t *next);
+
+#endif
+
+#endif /* __SOUND_AINSTR_GF1_H */
diff --git a/include/sound/ainstr_iw.h b/include/sound/ainstr_iw.h
new file mode 100644
index 0000000..8adf744
--- /dev/null
+++ b/include/sound/ainstr_iw.h
@@ -0,0 +1,373 @@
+/*
+ * Advanced Linux Sound Architecture
+ *
+ * InterWave FFFF Instrument Format
+ * Copyright (c) 1994-99 by Jaroslav Kysela <perex@suse.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_AINSTR_IW_H
+#define __SOUND_AINSTR_IW_H
+
+#ifndef __KERNEL__
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#endif
+
+/*
+ * share types (share ID 1)
+ */
+
+#define IWFFFF_SHARE_FILE 0
+
+/*
+ * wave formats
+ */
+
+#define IWFFFF_WAVE_16BIT 0x0001 /* 16-bit wave */
+#define IWFFFF_WAVE_UNSIGNED 0x0002 /* unsigned wave */
+#define IWFFFF_WAVE_INVERT 0x0002 /* same as unsigned wave */
+#define IWFFFF_WAVE_BACKWARD 0x0004 /* backward mode (maybe used for reverb or ping-ping loop) */
+#define IWFFFF_WAVE_LOOP 0x0008 /* loop mode */
+#define IWFFFF_WAVE_BIDIR 0x0010 /* bidirectional mode */
+#define IWFFFF_WAVE_ULAW 0x0020 /* uLaw compressed wave */
+#define IWFFFF_WAVE_RAM 0x0040 /* wave is _preloaded_ in RAM (it is used for ROM simulation) */
+#define IWFFFF_WAVE_ROM 0x0080 /* wave is in ROM */
+#define IWFFFF_WAVE_STEREO 0x0100 /* wave is stereo */
+
+/*
+ * Wavetable definitions
+ */
+
+typedef struct iwffff_wave {
+ unsigned int share_id[4]; /* share id - zero = no sharing */
+ unsigned int format; /* wave format */
+
+ struct {
+ unsigned int number; /* some other ID for this wave */
+ unsigned int memory; /* begin of waveform in onboard memory */
+ unsigned char *ptr; /* pointer to waveform in system memory */
+ } address;
+
+ unsigned int size; /* size of waveform in samples */
+ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned int loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned int loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned short loop_repeat; /* loop repeat - 0 = forever */
+ unsigned int sample_ratio; /* sample ratio (44100 * 1024 / rate) */
+ unsigned char attenuation; /* 0 - 127 (no corresponding midi controller) */
+ unsigned char low_note; /* lower frequency range for this waveform */
+ unsigned char high_note; /* higher frequency range for this waveform */
+ unsigned char pad;
+
+ struct iwffff_wave *next;
+} iwffff_wave_t;
+
+/*
+ * Layer
+ */
+
+#define IWFFFF_LFO_SHAPE_TRIANGLE 0
+#define IWFFFF_LFO_SHAPE_POSTRIANGLE 1
+
+typedef struct iwffff_lfo {
+ unsigned short freq; /* (0-2047) 0.01Hz - 21.5Hz */
+ signed short depth; /* volume +- (0-255) 0.48675dB/step */
+ signed short sweep; /* 0 - 950 deciseconds */
+ unsigned char shape; /* see to IWFFFF_LFO_SHAPE_XXXX */
+ unsigned char delay; /* 0 - 255 deciseconds */
+} iwffff_lfo_t;
+
+#define IWFFFF_ENV_FLAG_RETRIGGER 0x0001 /* flag - retrigger */
+
+#define IWFFFF_ENV_MODE_ONE_SHOT 0x0001 /* mode - one shot */
+#define IWFFFF_ENV_MODE_SUSTAIN 0x0002 /* mode - sustain */
+#define IWFFFF_ENV_MODE_NO_SUSTAIN 0x0003 /* mode - no sustain */
+
+#define IWFFFF_ENV_INDEX_VELOCITY 0x0001 /* index - velocity */
+#define IWFFFF_ENV_INDEX_FREQUENCY 0x0002 /* index - frequency */
+
+typedef struct iwffff_env_point {
+ unsigned short offset;
+ unsigned short rate;
+} iwffff_env_point_t;
+
+typedef struct iwffff_env_record {
+ unsigned short nattack;
+ unsigned short nrelease;
+ unsigned short sustain_offset;
+ unsigned short sustain_rate;
+ unsigned short release_rate;
+ unsigned char hirange;
+ unsigned char pad;
+ struct iwffff_env_record *next;
+ /* points are stored here */
+ /* count of points = nattack + nrelease */
+} iwffff_env_record_t;
+
+typedef struct iwffff_env {
+ unsigned char flags;
+ unsigned char mode;
+ unsigned char index;
+ unsigned char pad;
+ struct iwffff_env_record *record;
+} iwffff_env_t;
+
+#define IWFFFF_LAYER_FLAG_RETRIGGER 0x0001 /* retrigger */
+
+#define IWFFFF_LAYER_VELOCITY_TIME 0x0000 /* velocity mode = time */
+#define IWFFFF_LAYER_VELOCITY_RATE 0x0001 /* velocity mode = rate */
+
+#define IWFFFF_LAYER_EVENT_KUP 0x0000 /* layer event - key up */
+#define IWFFFF_LAYER_EVENT_KDOWN 0x0001 /* layer event - key down */
+#define IWFFFF_LAYER_EVENT_RETRIG 0x0002 /* layer event - retrigger */
+#define IWFFFF_LAYER_EVENT_LEGATO 0x0003 /* layer event - legato */
+
+typedef struct iwffff_layer {
+ unsigned char flags;
+ unsigned char velocity_mode;
+ unsigned char layer_event;
+ unsigned char low_range; /* range for layer based */
+ unsigned char high_range; /* on either velocity or frequency */
+ unsigned char pan; /* pan offset from CC1 (0 left - 127 right) */
+ unsigned char pan_freq_scale; /* position based on frequency (0-127) */
+ unsigned char attenuation; /* 0-127 (no corresponding midi controller) */
+ iwffff_lfo_t tremolo; /* tremolo effect */
+ iwffff_lfo_t vibrato; /* vibrato effect */
+ unsigned short freq_scale; /* 0-2048, 1024 is equal to semitone scaling */
+ unsigned char freq_center; /* center for keyboard frequency scaling */
+ unsigned char pad;
+ iwffff_env_t penv; /* pitch envelope */
+ iwffff_env_t venv; /* volume envelope */
+
+ iwffff_wave_t *wave;
+ struct iwffff_layer *next;
+} iwffff_layer_t;
+
+/*
+ * Instrument
+ */
+
+#define IWFFFF_EXCLUDE_NONE 0x0000 /* exclusion mode - none */
+#define IWFFFF_EXCLUDE_SINGLE 0x0001 /* exclude single - single note from the instrument group */
+#define IWFFFF_EXCLUDE_MULTIPLE 0x0002 /* exclude multiple - stop only same note from this instrument */
+
+#define IWFFFF_LAYER_NONE 0x0000 /* not layered */
+#define IWFFFF_LAYER_ON 0x0001 /* layered */
+#define IWFFFF_LAYER_VELOCITY 0x0002 /* layered by velocity */
+#define IWFFFF_LAYER_FREQUENCY 0x0003 /* layered by frequency */
+
+#define IWFFFF_EFFECT_NONE 0
+#define IWFFFF_EFFECT_REVERB 1
+#define IWFFFF_EFFECT_CHORUS 2
+#define IWFFFF_EFFECT_ECHO 3
+
+typedef struct {
+ unsigned short exclusion;
+ unsigned short layer_type;
+ unsigned short exclusion_group; /* 0 - none, 1-65535 */
+
+ unsigned char effect1; /* effect 1 */
+ unsigned char effect1_depth; /* 0-127 */
+ unsigned char effect2; /* effect 2 */
+ unsigned char effect2_depth; /* 0-127 */
+
+ iwffff_layer_t *layer; /* first layer */
+} iwffff_instrument_t;
+
+/*
+ *
+ * Kernel <-> user space
+ * Hardware (CPU) independent section
+ *
+ * * = zero or more
+ * + = one or more
+ *
+ * iwffff_xinstrument IWFFFF_STRU_INSTR
+ * +iwffff_xlayer IWFFFF_STRU_LAYER
+ * *iwffff_xenv_record IWFFFF_STRU_ENV_RECT (tremolo)
+ * *iwffff_xenv_record IWFFFF_STRU_EVN_RECT (vibrato)
+ * +iwffff_xwave IWFFFF_STRU_WAVE
+ *
+ */
+
+#define IWFFFF_STRU_WAVE __cpu_to_be32(('W'<<24)|('A'<<16)|('V'<<8)|'E')
+#define IWFFFF_STRU_ENV_RECP __cpu_to_be32(('E'<<24)|('N'<<16)|('R'<<8)|'P')
+#define IWFFFF_STRU_ENV_RECV __cpu_to_be32(('E'<<24)|('N'<<16)|('R'<<8)|'V')
+#define IWFFFF_STRU_LAYER __cpu_to_be32(('L'<<24)|('A'<<16)|('Y'<<8)|'R')
+#define IWFFFF_STRU_INSTR __cpu_to_be32(('I'<<24)|('N'<<16)|('S'<<8)|'T')
+
+/*
+ * Wavetable definitions
+ */
+
+typedef struct iwffff_xwave {
+ __u32 stype; /* structure type */
+
+ __u32 share_id[4]; /* share id - zero = no sharing */
+
+ __u32 format; /* wave format */
+ __u32 offset; /* offset to ROM (address) */
+
+ __u32 size; /* size of waveform in samples */
+ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u16 loop_repeat; /* loop repeat - 0 = forever */
+ __u32 sample_ratio; /* sample ratio (44100 * 1024 / rate) */
+ __u8 attenuation; /* 0 - 127 (no corresponding midi controller) */
+ __u8 low_note; /* lower frequency range for this waveform */
+ __u8 high_note; /* higher frequency range for this waveform */
+ __u8 pad;
+} iwffff_xwave_t;
+
+/*
+ * Layer
+ */
+
+typedef struct iwffff_xlfo {
+ __u16 freq; /* (0-2047) 0.01Hz - 21.5Hz */
+ __s16 depth; /* volume +- (0-255) 0.48675dB/step */
+ __s16 sweep; /* 0 - 950 deciseconds */
+ __u8 shape; /* see to ULTRA_IW_LFO_SHAPE_XXXX */
+ __u8 delay; /* 0 - 255 deciseconds */
+} iwffff_xlfo_t;
+
+typedef struct iwffff_xenv_point {
+ __u16 offset;
+ __u16 rate;
+} iwffff_xenv_point_t;
+
+typedef struct iwffff_xenv_record {
+ __u32 stype;
+ __u16 nattack;
+ __u16 nrelease;
+ __u16 sustain_offset;
+ __u16 sustain_rate;
+ __u16 release_rate;
+ __u8 hirange;
+ __u8 pad;
+ /* points are stored here.. */
+ /* count of points = nattack + nrelease */
+} iwffff_xenv_record_t;
+
+typedef struct iwffff_xenv {
+ __u8 flags;
+ __u8 mode;
+ __u8 index;
+ __u8 pad;
+} iwffff_xenv_t;
+
+typedef struct iwffff_xlayer {
+ __u32 stype;
+ __u8 flags;
+ __u8 velocity_mode;
+ __u8 layer_event;
+ __u8 low_range; /* range for layer based */
+ __u8 high_range; /* on either velocity or frequency */
+ __u8 pan; /* pan offset from CC1 (0 left - 127 right) */
+ __u8 pan_freq_scale; /* position based on frequency (0-127) */
+ __u8 attenuation; /* 0-127 (no corresponding midi controller) */
+ iwffff_xlfo_t tremolo; /* tremolo effect */
+ iwffff_xlfo_t vibrato; /* vibrato effect */
+ __u16 freq_scale; /* 0-2048, 1024 is equal to semitone scaling */
+ __u8 freq_center; /* center for keyboard frequency scaling */
+ __u8 pad;
+ iwffff_xenv_t penv; /* pitch envelope */
+ iwffff_xenv_t venv; /* volume envelope */
+} iwffff_xlayer_t;
+
+/*
+ * Instrument
+ */
+
+typedef struct iwffff_xinstrument {
+ __u32 stype;
+
+ __u16 exclusion;
+ __u16 layer_type;
+ __u16 exclusion_group; /* 0 - none, 1-65535 */
+
+ __u8 effect1; /* effect 1 */
+ __u8 effect1_depth; /* 0-127 */
+ __u8 effect2; /* effect 2 */
+ __u8 effect2_depth; /* 0-127 */
+} iwffff_xinstrument_t;
+
+/*
+ * ROM support
+ * InterWave ROMs are Little-Endian (x86)
+ */
+
+#define IWFFFF_ROM_HDR_SIZE 512
+
+typedef struct {
+ __u8 iwave[8];
+ __u8 revision;
+ __u8 series_number;
+ __u8 series_name[16];
+ __u8 date[10];
+ __u16 vendor_revision_major;
+ __u16 vendor_revision_minor;
+ __u32 rom_size;
+ __u8 copyright[128];
+ __u8 vendor_name[64];
+ __u8 description[128];
+} iwffff_rom_header_t;
+
+/*
+ * Instrument info
+ */
+
+#define IWFFFF_INFO_LFO_VIBRATO (1<<0)
+#define IWFFFF_INFO_LFO_VIBRATO_SHAPE (1<<1)
+#define IWFFFF_INFO_LFO_TREMOLO (1<<2)
+#define IWFFFF_INFO_LFO_TREMOLO_SHAPE (1<<3)
+
+typedef struct iwffff_info {
+ unsigned int format; /* supported format bits */
+ unsigned int effects; /* supported effects (1 << IWFFFF_EFFECT*) */
+ unsigned int lfos; /* LFO effects */
+ unsigned int max8_len; /* maximum 8-bit wave length */
+ unsigned int max16_len; /* maximum 16-bit wave length */
+} iwffff_info_t;
+
+#ifdef __KERNEL__
+
+#include "seq_instr.h"
+
+typedef struct {
+ void *private_data;
+ int (*info)(void *private_data, iwffff_info_t *info);
+ int (*put_sample)(void *private_data, iwffff_wave_t *wave,
+ char __user *data, long len, int atomic);
+ int (*get_sample)(void *private_data, iwffff_wave_t *wave,
+ char __user *data, long len, int atomic);
+ int (*remove_sample)(void *private_data, iwffff_wave_t *wave,
+ int atomic);
+ void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
+ snd_seq_kinstr_ops_t kops;
+} snd_iwffff_ops_t;
+
+int snd_seq_iwffff_init(snd_iwffff_ops_t *ops,
+ void *private_data,
+ snd_seq_kinstr_ops_t *next);
+
+#endif
+
+#endif /* __SOUND_AINSTR_IW_H */
diff --git a/include/sound/ainstr_simple.h b/include/sound/ainstr_simple.h
new file mode 100644
index 0000000..40824b4
--- /dev/null
+++ b/include/sound/ainstr_simple.h
@@ -0,0 +1,156 @@
+/*
+ * Advanced Linux Sound Architecture
+ *
+ * Simple (MOD player) Instrument Format
+ * Copyright (c) 1994-99 by Jaroslav Kysela <perex@suse.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_AINSTR_SIMPLE_H
+#define __SOUND_AINSTR_SIMPLE_H
+
+#ifndef __KERNEL__
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#endif
+
+/*
+ * share types (share ID 1)
+ */
+
+#define SIMPLE_SHARE_FILE 0
+
+/*
+ * wave formats
+ */
+
+#define SIMPLE_WAVE_16BIT 0x0001 /* 16-bit wave */
+#define SIMPLE_WAVE_UNSIGNED 0x0002 /* unsigned wave */
+#define SIMPLE_WAVE_INVERT 0x0002 /* same as unsigned wave */
+#define SIMPLE_WAVE_BACKWARD 0x0004 /* backward mode (maybe used for reverb or ping-ping loop) */
+#define SIMPLE_WAVE_LOOP 0x0008 /* loop mode */
+#define SIMPLE_WAVE_BIDIR 0x0010 /* bidirectional mode */
+#define SIMPLE_WAVE_STEREO 0x0100 /* stereo wave */
+#define SIMPLE_WAVE_ULAW 0x0200 /* uLaw compression mode */
+
+/*
+ * instrument effects
+ */
+
+#define SIMPLE_EFFECT_NONE 0
+#define SIMPLE_EFFECT_REVERB 1
+#define SIMPLE_EFFECT_CHORUS 2
+#define SIMPLE_EFFECT_ECHO 3
+
+/*
+ * instrument info
+ */
+
+typedef struct simple_instrument_info {
+ unsigned int format; /* supported format bits */
+ unsigned int effects; /* supported effects (1 << SIMPLE_EFFECT_*) */
+ unsigned int max8_len; /* maximum 8-bit wave length */
+ unsigned int max16_len; /* maximum 16-bit wave length */
+} simple_instrument_info_t;
+
+/*
+ * Instrument
+ */
+
+typedef struct {
+ unsigned int share_id[4]; /* share id - zero = no sharing */
+ unsigned int format; /* wave format */
+
+ struct {
+ unsigned int number; /* some other ID for this instrument */
+ unsigned int memory; /* begin of waveform in onboard memory */
+ unsigned char *ptr; /* pointer to waveform in system memory */
+ } address;
+
+ unsigned int size; /* size of waveform in samples */
+ unsigned int start; /* start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned int loop_start; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned int loop_end; /* loop end offset in samples * 16 (lowest 4 bits - fraction) */
+ unsigned short loop_repeat; /* loop repeat - 0 = forever */
+
+ unsigned char effect1; /* effect 1 */
+ unsigned char effect1_depth; /* 0-127 */
+ unsigned char effect2; /* effect 2 */
+ unsigned char effect2_depth; /* 0-127 */
+} simple_instrument_t;
+
+/*
+ *
+ * Kernel <-> user space
+ * Hardware (CPU) independent section
+ *
+ * * = zero or more
+ * + = one or more
+ *
+ * simple_xinstrument SIMPLE_STRU_INSTR
+ *
+ */
+
+#define SIMPLE_STRU_INSTR __cpu_to_be32(('I'<<24)|('N'<<16)|('S'<<8)|'T')
+
+/*
+ * Instrument
+ */
+
+typedef struct simple_xinstrument {
+ __u32 stype;
+
+ __u32 share_id[4]; /* share id - zero = no sharing */
+ __u32 format; /* wave format */
+
+ __u32 size; /* size of waveform in samples */
+ __u32 start; /* start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u32 loop_start; /* bits loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u32 loop_end; /* loop start offset in samples * 16 (lowest 4 bits - fraction) */
+ __u16 loop_repeat; /* loop repeat - 0 = forever */
+
+ __u8 effect1; /* effect 1 */
+ __u8 effect1_depth; /* 0-127 */
+ __u8 effect2; /* effect 2 */
+ __u8 effect2_depth; /* 0-127 */
+} simple_xinstrument_t;
+
+#ifdef __KERNEL__
+
+#include "seq_instr.h"
+
+typedef struct {
+ void *private_data;
+ int (*info)(void *private_data, simple_instrument_info_t *info);
+ int (*put_sample)(void *private_data, simple_instrument_t *instr,
+ char __user *data, long len, int atomic);
+ int (*get_sample)(void *private_data, simple_instrument_t *instr,
+ char __user *data, long len, int atomic);
+ int (*remove_sample)(void *private_data, simple_instrument_t *instr,
+ int atomic);
+ void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
+ snd_seq_kinstr_ops_t kops;
+} snd_simple_ops_t;
+
+int snd_seq_simple_init(snd_simple_ops_t *ops,
+ void *private_data,
+ snd_seq_kinstr_ops_t *next);
+
+#endif
+
+#endif /* __SOUND_AINSTR_SIMPLE_H */
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
new file mode 100644
index 0000000..f3f2c3e
--- /dev/null
+++ b/include/sound/ak4114.h
@@ -0,0 +1,205 @@
+#ifndef __SOUND_AK4114_H
+#define __SOUND_AK4114_H
+
+/*
+ * Routines for Asahi Kasei AK4114
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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<<5) /* Audio Data Control */
+#define AK4114_DIF1 (1<<5) /* Audio Data Control */
+#define AK4114_DIF0 (1<<4) /* Audio Data Control */
+#define AK4114_DIF_16R (0) /* STDO: 16-bit, right justified */
+#define AK4114_DIF_18R (AK4114_DIF0) /* STDO: 18-bit, right justified */
+#define AK4114_DIF_20R (AK4114_DIF1) /* STDO: 20-bit, right justified */
+#define AK4114_DIF_24R (AK4114_DIF1|AK4114_DIF0) /* STDO: 24-bit, right justified */
+#define AK4114_DIF_24L (AK4114_DIF2) /* STDO: 24-bit, left justified */
+#define AK4114_DIF_24I2S (AK4114_DIF2|AK4114_DIF0) /* STDO: I2S */
+#define AK4114_DIF_I24L (AK4114_DIF2|AK4114_DIF1) /* STDO: 24-bit, left justified; LRCLK, BICK = Input */
+#define AK4114_DIF_I24I2S (AK4114_DIF2|AK4114_DIF1|AK4114_DIF0) /* STDO: I2S; LRCLK, BICK = Input */
+#define AK4114_DEAU (1<<3) /* Deemphasis Autodetect Enable (1 = enable) */
+#define AK4114_DEM1 (1<<2) /* 32kHz-48kHz Deemphasis Control */
+#define AK4114_DEM0 (1<<1) /* 32kHz-48kHz Deemphasis Control */
+#define AK4114_DEM_44KHZ (0)
+#define AK4114_DEM_48KHZ (AK4114_DEM1)
+#define AK4114_DEM_32KHZ (AK4114_DEM0|AK4114_DEM1)
+#define AK4114_DEM_96KHZ (AK4114_DEM1) /* DFS must be set */
+#define AK4114_DFS (1<<0) /* 96kHz Deemphasis Control */
+
+/* AK4114_REG_IO0 */
+#define AK4114_TX1E (1<<7) /* TX1 Output Enable (1 = enable) */
+#define AK4114_OPS12 (1<<2) /* Output Though Data Selector for TX1 pin */
+#define AK4114_OPS11 (1<<1) /* Output Though Data Selector for TX1 pin */
+#define AK4114_OPS10 (1<<0) /* Output Though Data Selector for TX1 pin */
+#define AK4114_TX0E (1<<3) /* TX0 Output Enable (1 = enable) */
+#define AK4114_OPS02 (1<<2) /* Output Though Data Selector for TX0 pin */
+#define AK4114_OPS01 (1<<1) /* Output Though Data Selector for TX0 pin */
+#define AK4114_OPS00 (1<<0) /* Output Though Data Selector for TX0 pin */
+
+/* AK4114_REG_IO1 */
+#define AK4114_EFH1 (1<<7) /* Interrupt 0 pin Hold */
+#define AK4114_EFH0 (1<<6) /* Interrupt 0 pin Hold */
+#define AK4114_EFH_512 (0)
+#define AK4114_EFH_1024 (AK4114_EFH0)
+#define AK4114_EFH_2048 (AK4114_EFH1)
+#define AK4114_EFH_4096 (AK4114_EFH1|AK4114_EFH0)
+#define AK4114_UDIT (1<<5) /* U-bit Control for DIT (0 = fixed '0', 1 = recovered) */
+#define AK4114_TLR (1<<4) /* Double Sampling Frequency Select for DIT (0 = L channel, 1 = R channel) */
+#define AK4114_DIT (1<<3) /* TX1 out: 0 = Through Data (RX data), 1 = Transmit Data (DAUX data) */
+#define AK4114_IPS2 (1<<2) /* Input Recovery Data Select */
+#define AK4114_IPS1 (1<<1) /* Input Recovery Data Select */
+#define AK4114_IPS0 (1<<0) /* Input Recovery Data Select */
+#define AK4114_IPS(x) ((x)&7)
+
+/* AK4114_REG_INT0_MASK && AK4114_REG_INT1_MASK*/
+#define AK4117_MQI (1<<7) /* mask enable for QINT bit */
+#define AK4117_MAT (1<<6) /* mask enable for AUTO bit */
+#define AK4117_MCI (1<<5) /* mask enable for CINT bit */
+#define AK4117_MUL (1<<4) /* mask enable for UNLOCK bit */
+#define AK4117_MDTS (1<<3) /* mask enable for DTSCD bit */
+#define AK4117_MPE (1<<2) /* mask enable for PEM bit */
+#define AK4117_MAN (1<<1) /* mask enable for AUDN bit */
+#define AK4117_MPR (1<<0) /* mask enable for PAR bit */
+
+/* AK4114_REG_RCS0 */
+#define AK4114_QINT (1<<7) /* Q-subcode buffer interrupt, 0 = no change, 1 = changed */
+#define AK4114_AUTO (1<<6) /* Non-PCM or DTS stream auto detection, 0 = no detect, 1 = detect */
+#define AK4114_CINT (1<<5) /* channel status buffer interrupt, 0 = no change, 1 = change */
+#define AK4114_UNLCK (1<<4) /* PLL lock status, 0 = lock, 1 = unlock */
+#define AK4114_DTSCD (1<<3) /* DTS-CD Detect, 0 = No detect, 1 = Detect */
+#define AK4114_PEM (1<<2) /* Pre-emphasis Detect, 0 = OFF, 1 = ON */
+#define AK4114_AUDION (1<<1) /* audio bit output, 0 = audio, 1 = non-audio */
+#define AK4114_PAR (1<<0) /* parity error or biphase error status, 0 = no error, 1 = error */
+
+/* AK4114_REG_RCS1 */
+#define AK4114_FS3 (1<<7) /* sampling frequency detection */
+#define AK4114_FS2 (1<<6)
+#define AK4114_FS1 (1<<5)
+#define AK4114_FS0 (1<<4)
+#define AK4114_FS_44100HZ (0)
+#define AK4114_FS_48000HZ (AK4114_FS1)
+#define AK4114_FS_32000HZ (AK4114_FS1|AK4114_FS0)
+#define AK4114_FS_88200HZ (AK4114_FS3)
+#define AK4114_FS_96000HZ (AK4114_FS3|AK4114_FS1)
+#define AK4114_FS_176400HZ (AK4114_FS3|AK4114_FS2)
+#define AK4114_FS_192000HZ (AK4114_FS3|AK4114_FS2|AK4114_FS1)
+#define AK4114_V (1<<3) /* Validity of Channel Status, 0 = Valid, 1 = Invalid */
+#define AK4114_QCRC (1<<1) /* CRC for Q-subcode, 0 = no error, 1 = error */
+#define AK4114_CCRC (1<<0) /* CRC for channel status, 0 = no error, 1 = error */
+
+/* flags for snd_ak4114_check_rate_and_errors() */
+#define AK4114_CHECK_NO_STAT (1<<0) /* no statistics */
+#define AK4114_CHECK_NO_RATE (1<<1) /* no rate check */
+
+#define AK4114_CONTROLS 14
+
+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);
+
+typedef struct ak4114 ak4114_t;
+
+struct ak4114 {
+ snd_card_t * card;
+ ak4114_write_t * write;
+ ak4114_read_t * read;
+ void * private_data;
+ unsigned int init: 1;
+ spinlock_t lock;
+ unsigned char regmap[7];
+ unsigned char txcsb[5];
+ snd_kcontrol_t *kctls[AK4114_CONTROLS];
+ snd_pcm_substream_t *playback_substream;
+ snd_pcm_substream_t *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 workqueue_struct *workqueue;
+ struct work_struct work;
+ void *change_callback_private;
+ void (*change_callback)(ak4114_t *ak4114, unsigned char c0, unsigned char c1);
+};
+
+int snd_ak4114_create(snd_card_t *card,
+ ak4114_read_t *read, ak4114_write_t *write,
+ unsigned char pgm[7], unsigned char txcsb[5],
+ void *private_data, ak4114_t **r_ak4114);
+void snd_ak4114_reg_write(ak4114_t *ak4114, unsigned char reg, unsigned char mask, unsigned char val);
+void snd_ak4114_reinit(ak4114_t *ak4114);
+int snd_ak4114_build(ak4114_t *ak4114,
+ snd_pcm_substream_t *playback_substream,
+ snd_pcm_substream_t *capture_substream);
+int snd_ak4114_external_rate(ak4114_t *ak4114);
+int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags);
+
+#endif /* __SOUND_AK4114_H */
+
diff --git a/include/sound/ak4117.h b/include/sound/ak4117.h
new file mode 100644
index 0000000..9e1dab1
--- /dev/null
+++ b/include/sound/ak4117.h
@@ -0,0 +1,191 @@
+#ifndef __SOUND_AK4117_H
+#define __SOUND_AK4117_H
+
+/*
+ * Routines for Asahi Kasei AK4117
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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);
+
+typedef struct ak4117 ak4117_t;
+
+struct ak4117 {
+ snd_card_t * card;
+ ak4117_write_t * write;
+ ak4117_read_t * read;
+ void * private_data;
+ unsigned int init: 1;
+ spinlock_t lock;
+ unsigned char regmap[5];
+ snd_kcontrol_t *kctls[AK4117_CONTROLS];
+ snd_pcm_substream_t *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)(ak4117_t *ak4117, unsigned char c0, unsigned char c1);
+};
+
+int snd_ak4117_create(snd_card_t *card, ak4117_read_t *read, ak4117_write_t *write,
+ unsigned char pgm[5], void *private_data, ak4117_t **r_ak4117);
+void snd_ak4117_reg_write(ak4117_t *ak4117, unsigned char reg, unsigned char mask, unsigned char val);
+void snd_ak4117_reinit(ak4117_t *ak4117);
+int snd_ak4117_build(ak4117_t *ak4117, snd_pcm_substream_t *capture_substream);
+int snd_ak4117_external_rate(ak4117_t *ak4117);
+int snd_ak4117_check_rate_and_errors(ak4117_t *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..8b18992
--- /dev/null
+++ b/include/sound/ak4531_codec.h
@@ -0,0 +1,80 @@
+#ifndef __SOUND_AK4531_CODEC_H
+#define __SOUND_AK4531_CODEC_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "info.h"
+#include "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 */
+
+typedef struct _snd_ak4531 ak4531_t;
+
+struct _snd_ak4531 {
+ void (*write) (ak4531_t *ak4531, unsigned short reg, unsigned short val);
+ void *private_data;
+ void (*private_free) (ak4531_t *ak4531);
+ /* --- */
+ unsigned char regs[0x20];
+ struct semaphore reg_mutex;
+};
+
+int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531);
+
+#endif /* __SOUND_AK4531_CODEC_H */
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h
new file mode 100644
index 0000000..e94ac02
--- /dev/null
+++ b/include/sound/ak4xxx-adda.h
@@ -0,0 +1,69 @@
+#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@suse.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
+
+typedef struct snd_akm4xxx akm4xxx_t;
+
+struct snd_ak4xxx_ops {
+ void (*lock)(akm4xxx_t *ak, int chip);
+ void (*unlock)(akm4xxx_t *ak, int chip);
+ void (*write)(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
+ // unsigned char (*read)(akm4xxx_t *ak, int chip, unsigned char reg);
+ void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
+};
+
+#define AK4XXX_IMAGE_SIZE (AK4XXX_MAX_CHIPS * 16) /* 64 bytes */
+
+struct snd_akm4xxx {
+ snd_card_t *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 ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image for IPGA (AK4528) */
+ 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
+ } type;
+ struct snd_ak4xxx_ops ops;
+};
+
+void snd_akm4xxx_write(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
+void snd_akm4xxx_reset(akm4xxx_t *ak, int state);
+void snd_akm4xxx_init(akm4xxx_t *ak);
+int snd_akm4xxx_build_controls(akm4xxx_t *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_ipga(ak,chip,reg) (ak)->ipga_gain[chip][(reg)-4]
+#define snd_akm4xxx_set_ipga(ak,chip,reg,val) ((ak)->ipga_gain[chip][(reg)-4] = (val))
+
+#endif /* __SOUND_AK4XXX_ADDA_H */
diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h
new file mode 100644
index 0000000..728efd5
--- /dev/null
+++ b/include/sound/asequencer.h
@@ -0,0 +1,908 @@
+/*
+ * 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@suse.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
+
+#ifndef __KERNEL__
+#include <linux/ioctl.h>
+#endif
+
+#include <sound/asound.h>
+
+/** version of the sequencer */
+#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION (1, 0, 1)
+
+/**
+ * definition of sequencer event types
+ */
+
+/** system messages
+ * event data type = #sndrv_seq_result_t
+ */
+#define SNDRV_SEQ_EVENT_SYSTEM 0
+#define SNDRV_SEQ_EVENT_RESULT 1
+
+/** note messages (channel specific)
+ * event data type = #sndrv_seq_ev_note
+ */
+#define SNDRV_SEQ_EVENT_NOTE 5
+#define SNDRV_SEQ_EVENT_NOTEON 6
+#define SNDRV_SEQ_EVENT_NOTEOFF 7
+#define SNDRV_SEQ_EVENT_KEYPRESS 8
+
+/** control messages (channel specific)
+ * event data type = #sndrv_seq_ev_ctrl
+ */
+#define SNDRV_SEQ_EVENT_CONTROLLER 10
+#define SNDRV_SEQ_EVENT_PGMCHANGE 11
+#define SNDRV_SEQ_EVENT_CHANPRESS 12
+#define SNDRV_SEQ_EVENT_PITCHBEND 13 /**< from -8192 to 8191 */
+#define SNDRV_SEQ_EVENT_CONTROL14 14 /**< 14 bit controller value */
+#define SNDRV_SEQ_EVENT_NONREGPARAM 15 /**< 14 bit NRPN address + 14 bit unsigned value */
+#define SNDRV_SEQ_EVENT_REGPARAM 16 /**< 14 bit RPN address + 14 bit unsigned value */
+
+/** synchronisation messages
+ * event data type = #sndrv_seq_ev_ctrl
+ */
+#define SNDRV_SEQ_EVENT_SONGPOS 20 /* Song Position Pointer with LSB and MSB values */
+#define SNDRV_SEQ_EVENT_SONGSEL 21 /* Song Select with song ID number */
+#define SNDRV_SEQ_EVENT_QFRAME 22 /* midi time code quarter frame */
+#define SNDRV_SEQ_EVENT_TIMESIGN 23 /* SMF Time Signature event */
+#define SNDRV_SEQ_EVENT_KEYSIGN 24 /* SMF Key Signature event */
+
+/** timer messages
+ * event data type = sndrv_seq_ev_queue_control_t
+ */
+#define SNDRV_SEQ_EVENT_START 30 /* midi Real Time Start message */
+#define SNDRV_SEQ_EVENT_CONTINUE 31 /* midi Real Time Continue message */
+#define SNDRV_SEQ_EVENT_STOP 32 /* midi Real Time Stop message */
+#define SNDRV_SEQ_EVENT_SETPOS_TICK 33 /* set tick queue position */
+#define SNDRV_SEQ_EVENT_SETPOS_TIME 34 /* set realtime queue position */
+#define SNDRV_SEQ_EVENT_TEMPO 35 /* (SMF) Tempo event */
+#define SNDRV_SEQ_EVENT_CLOCK 36 /* midi Real Time Clock message */
+#define SNDRV_SEQ_EVENT_TICK 37 /* midi Real Time Tick message */
+#define SNDRV_SEQ_EVENT_QUEUE_SKEW 38 /* skew queue tempo */
+
+/** others
+ * event data type = none
+ */
+#define SNDRV_SEQ_EVENT_TUNE_REQUEST 40 /* tune request */
+#define SNDRV_SEQ_EVENT_RESET 41 /* reset to power-on state */
+#define SNDRV_SEQ_EVENT_SENSING 42 /* "active sensing" event */
+
+/** echo back, kernel private messages
+ * event data type = any type
+ */
+#define SNDRV_SEQ_EVENT_ECHO 50 /* echo event */
+#define SNDRV_SEQ_EVENT_OSS 51 /* OSS raw event */
+
+/** system status messages (broadcast for subscribers)
+ * event data type = sndrv_seq_addr_t
+ */
+#define SNDRV_SEQ_EVENT_CLIENT_START 60 /* new client has connected */
+#define SNDRV_SEQ_EVENT_CLIENT_EXIT 61 /* client has left the system */
+#define SNDRV_SEQ_EVENT_CLIENT_CHANGE 62 /* client status/info has changed */
+#define SNDRV_SEQ_EVENT_PORT_START 63 /* new port was created */
+#define SNDRV_SEQ_EVENT_PORT_EXIT 64 /* port was deleted from system */
+#define SNDRV_SEQ_EVENT_PORT_CHANGE 65 /* port status/info has changed */
+
+/** port connection changes
+ * event data type = sndrv_seq_connect_t
+ */
+#define SNDRV_SEQ_EVENT_PORT_SUBSCRIBED 66 /* ports connected */
+#define SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED 67 /* ports disconnected */
+
+/** synthesizer events
+ * event data type = sndrv_seq_eve_sample_control_t
+ */
+#define SNDRV_SEQ_EVENT_SAMPLE 70 /* sample select */
+#define SNDRV_SEQ_EVENT_SAMPLE_CLUSTER 71 /* sample cluster select */
+#define SNDRV_SEQ_EVENT_SAMPLE_START 72 /* voice start */
+#define SNDRV_SEQ_EVENT_SAMPLE_STOP 73 /* voice stop */
+#define SNDRV_SEQ_EVENT_SAMPLE_FREQ 74 /* playback frequency */
+#define SNDRV_SEQ_EVENT_SAMPLE_VOLUME 75 /* volume and balance */
+#define SNDRV_SEQ_EVENT_SAMPLE_LOOP 76 /* sample loop */
+#define SNDRV_SEQ_EVENT_SAMPLE_POSITION 77 /* sample position */
+#define SNDRV_SEQ_EVENT_SAMPLE_PRIVATE1 78 /* private (hardware dependent) event */
+
+/** user-defined events with fixed length
+ * event data type = any
+ */
+#define SNDRV_SEQ_EVENT_USR0 90
+#define SNDRV_SEQ_EVENT_USR1 91
+#define SNDRV_SEQ_EVENT_USR2 92
+#define SNDRV_SEQ_EVENT_USR3 93
+#define SNDRV_SEQ_EVENT_USR4 94
+#define SNDRV_SEQ_EVENT_USR5 95
+#define SNDRV_SEQ_EVENT_USR6 96
+#define SNDRV_SEQ_EVENT_USR7 97
+#define SNDRV_SEQ_EVENT_USR8 98
+#define SNDRV_SEQ_EVENT_USR9 99
+
+/** instrument layer
+ * variable length data can be passed directly to the driver
+ */
+#define SNDRV_SEQ_EVENT_INSTR_BEGIN 100 /* begin of instrument management */
+#define SNDRV_SEQ_EVENT_INSTR_END 101 /* end of instrument management */
+#define SNDRV_SEQ_EVENT_INSTR_INFO 102 /* instrument interface info */
+#define SNDRV_SEQ_EVENT_INSTR_INFO_RESULT 103 /* result */
+#define SNDRV_SEQ_EVENT_INSTR_FINFO 104 /* get format info */
+#define SNDRV_SEQ_EVENT_INSTR_FINFO_RESULT 105 /* get format info */
+#define SNDRV_SEQ_EVENT_INSTR_RESET 106 /* reset instrument memory */
+#define SNDRV_SEQ_EVENT_INSTR_STATUS 107 /* instrument interface status */
+#define SNDRV_SEQ_EVENT_INSTR_STATUS_RESULT 108 /* result */
+#define SNDRV_SEQ_EVENT_INSTR_PUT 109 /* put instrument to port */
+#define SNDRV_SEQ_EVENT_INSTR_GET 110 /* get instrument from port */
+#define SNDRV_SEQ_EVENT_INSTR_GET_RESULT 111 /* result */
+#define SNDRV_SEQ_EVENT_INSTR_FREE 112 /* free instrument(s) */
+#define SNDRV_SEQ_EVENT_INSTR_LIST 113 /* instrument list */
+#define SNDRV_SEQ_EVENT_INSTR_LIST_RESULT 114 /* result */
+#define SNDRV_SEQ_EVENT_INSTR_CLUSTER 115 /* cluster parameters */
+#define SNDRV_SEQ_EVENT_INSTR_CLUSTER_GET 116 /* get cluster parameters */
+#define SNDRV_SEQ_EVENT_INSTR_CLUSTER_RESULT 117 /* result */
+#define SNDRV_SEQ_EVENT_INSTR_CHANGE 118 /* instrument change */
+/* 119-129: reserved */
+
+/* 130-139: variable length events
+ * event data type = sndrv_seq_ev_ext
+ * (SNDRV_SEQ_EVENT_LENGTH_VARIABLE must be set)
+ */
+#define SNDRV_SEQ_EVENT_SYSEX 130 /* system exclusive data (variable length) */
+#define SNDRV_SEQ_EVENT_BOUNCE 131 /* error event */
+/* 132-134: reserved */
+#define SNDRV_SEQ_EVENT_USR_VAR0 135
+#define SNDRV_SEQ_EVENT_USR_VAR1 136
+#define SNDRV_SEQ_EVENT_USR_VAR2 137
+#define SNDRV_SEQ_EVENT_USR_VAR3 138
+#define SNDRV_SEQ_EVENT_USR_VAR4 139
+
+/* 150-151: kernel events with quote - DO NOT use in user clients */
+#define SNDRV_SEQ_EVENT_KERNEL_ERROR 150
+#define SNDRV_SEQ_EVENT_KERNEL_QUOTE 151 /* obsolete */
+
+/* 152-191: reserved */
+
+/* 192-254: hardware specific events */
+
+/* 255: special event */
+#define SNDRV_SEQ_EVENT_NONE 255
+
+
+typedef unsigned char sndrv_seq_event_type_t;
+
+/** event address */
+struct sndrv_seq_addr {
+ unsigned char client; /**< Client number: 0..255, 255 = broadcast to all clients */
+ unsigned char port; /**< Port within client: 0..255, 255 = broadcast to all ports */
+};
+
+/** port connection */
+struct sndrv_seq_connect {
+ struct sndrv_seq_addr sender;
+ struct sndrv_seq_addr dest;
+};
+
+
+#define SNDRV_SEQ_ADDRESS_UNKNOWN 253 /* unknown source */
+#define SNDRV_SEQ_ADDRESS_SUBSCRIBERS 254 /* send event to all subscribed ports */
+#define SNDRV_SEQ_ADDRESS_BROADCAST 255 /* send event to all queues/clients/ports/channels */
+#define SNDRV_SEQ_QUEUE_DIRECT 253 /* direct dispatch */
+
+ /* event mode flag - NOTE: only 8 bits available! */
+#define SNDRV_SEQ_TIME_STAMP_TICK (0<<0) /* timestamp in clock ticks */
+#define SNDRV_SEQ_TIME_STAMP_REAL (1<<0) /* timestamp in real time */
+#define SNDRV_SEQ_TIME_STAMP_MASK (1<<0)
+
+#define SNDRV_SEQ_TIME_MODE_ABS (0<<1) /* absolute timestamp */
+#define SNDRV_SEQ_TIME_MODE_REL (1<<1) /* relative to current time */
+#define SNDRV_SEQ_TIME_MODE_MASK (1<<1)
+
+#define SNDRV_SEQ_EVENT_LENGTH_FIXED (0<<2) /* fixed event size */
+#define SNDRV_SEQ_EVENT_LENGTH_VARIABLE (1<<2) /* variable event size */
+#define SNDRV_SEQ_EVENT_LENGTH_VARUSR (2<<2) /* variable event size - user memory space */
+#define SNDRV_SEQ_EVENT_LENGTH_MASK (3<<2)
+
+#define SNDRV_SEQ_PRIORITY_NORMAL (0<<4) /* normal priority */
+#define SNDRV_SEQ_PRIORITY_HIGH (1<<4) /* event should be processed before others */
+#define SNDRV_SEQ_PRIORITY_MASK (1<<4)
+
+
+ /* note event */
+struct sndrv_seq_ev_note {
+ unsigned char channel;
+ unsigned char note;
+ unsigned char velocity;
+ unsigned char off_velocity; /* only for SNDRV_SEQ_EVENT_NOTE */
+ unsigned int duration; /* only for SNDRV_SEQ_EVENT_NOTE */
+};
+
+ /* controller event */
+struct sndrv_seq_ev_ctrl {
+ unsigned char channel;
+ unsigned char unused1, unused2, unused3; /* pad */
+ unsigned int param;
+ signed int value;
+};
+
+ /* generic set of bytes (12x8 bit) */
+struct sndrv_seq_ev_raw8 {
+ unsigned char d[12]; /* 8 bit value */
+};
+
+ /* generic set of integers (3x32 bit) */
+struct sndrv_seq_ev_raw32 {
+ unsigned int d[3]; /* 32 bit value */
+};
+
+ /* external stored data */
+struct sndrv_seq_ev_ext {
+ unsigned int len; /* length of data */
+ void *ptr; /* pointer to data (note: maybe 64-bit) */
+} __attribute__((packed));
+
+/* Instrument cluster type */
+typedef unsigned int sndrv_seq_instr_cluster_t;
+
+/* Instrument type */
+struct sndrv_seq_instr {
+ sndrv_seq_instr_cluster_t cluster;
+ unsigned int std; /* the upper byte means a private instrument (owner - client #) */
+ unsigned short bank;
+ unsigned short prg;
+};
+
+ /* sample number */
+struct sndrv_seq_ev_sample {
+ unsigned int std;
+ unsigned short bank;
+ unsigned short prg;
+};
+
+ /* sample cluster */
+struct sndrv_seq_ev_cluster {
+ sndrv_seq_instr_cluster_t cluster;
+};
+
+ /* sample position */
+typedef unsigned int sndrv_seq_position_t; /* playback position (in samples) * 16 */
+
+ /* sample stop mode */
+enum sndrv_seq_stop_mode {
+ SAMPLE_STOP_IMMEDIATELY = 0, /* terminate playing immediately */
+ SAMPLE_STOP_VENVELOPE = 1, /* finish volume envelope */
+ SAMPLE_STOP_LOOP = 2 /* terminate loop and finish wave */
+};
+
+ /* sample frequency */
+typedef int sndrv_seq_frequency_t; /* playback frequency in HZ * 16 */
+
+ /* sample volume control; if any value is set to -1 == do not change */
+struct sndrv_seq_ev_volume {
+ signed short volume; /* range: 0-16383 */
+ signed short lr; /* left-right balance; range: 0-16383 */
+ signed short fr; /* front-rear balance; range: 0-16383 */
+ signed short du; /* down-up balance; range: 0-16383 */
+};
+
+ /* simple loop redefinition */
+struct sndrv_seq_ev_loop {
+ unsigned int start; /* loop start (in samples) * 16 */
+ unsigned int end; /* loop end (in samples) * 16 */
+};
+
+struct sndrv_seq_ev_sample_control {
+ unsigned char channel;
+ unsigned char unused1, unused2, unused3; /* pad */
+ union {
+ struct sndrv_seq_ev_sample sample;
+ struct sndrv_seq_ev_cluster cluster;
+ sndrv_seq_position_t position;
+ enum sndrv_seq_stop_mode stop_mode;
+ sndrv_seq_frequency_t frequency;
+ struct sndrv_seq_ev_volume volume;
+ struct sndrv_seq_ev_loop loop;
+ unsigned char raw8[8];
+ } param;
+};
+
+
+
+/* INSTR_BEGIN event */
+struct sndrv_seq_ev_instr_begin {
+ int timeout; /* zero = forever, otherwise timeout in ms */
+};
+
+struct sndrv_seq_result {
+ int event; /* processed event type */
+ int result;
+};
+
+
+struct sndrv_seq_real_time {
+ unsigned int tv_sec; /* seconds */
+ unsigned int tv_nsec; /* nanoseconds */
+};
+
+typedef unsigned int sndrv_seq_tick_time_t; /* midi ticks */
+
+union sndrv_seq_timestamp {
+ sndrv_seq_tick_time_t tick;
+ struct sndrv_seq_real_time time;
+};
+
+struct sndrv_seq_queue_skew {
+ unsigned int value;
+ unsigned int base;
+};
+
+ /* queue timer control */
+struct sndrv_seq_ev_queue_control {
+ unsigned char queue; /* affected queue */
+ unsigned char pad[3]; /* reserved */
+ union {
+ signed int value; /* affected value (e.g. tempo) */
+ union sndrv_seq_timestamp time; /* time */
+ unsigned int position; /* sync position */
+ struct sndrv_seq_queue_skew skew;
+ unsigned int d32[2];
+ unsigned char d8[8];
+ } param;
+};
+
+ /* quoted event - inside the kernel only */
+struct sndrv_seq_ev_quote {
+ struct sndrv_seq_addr origin; /* original sender */
+ unsigned short value; /* optional data */
+ struct sndrv_seq_event *event; /* quoted event */
+} __attribute__((packed));
+
+
+ /* sequencer event */
+struct sndrv_seq_event {
+ sndrv_seq_event_type_t type; /* event type */
+ unsigned char flags; /* event flags */
+ char tag;
+
+ unsigned char queue; /* schedule queue */
+ union sndrv_seq_timestamp time; /* schedule time */
+
+
+ struct sndrv_seq_addr source; /* source address */
+ struct sndrv_seq_addr dest; /* destination address */
+
+ union { /* event data... */
+ struct sndrv_seq_ev_note note;
+ struct sndrv_seq_ev_ctrl control;
+ struct sndrv_seq_ev_raw8 raw8;
+ struct sndrv_seq_ev_raw32 raw32;
+ struct sndrv_seq_ev_ext ext;
+ struct sndrv_seq_ev_queue_control queue;
+ union sndrv_seq_timestamp time;
+ struct sndrv_seq_addr addr;
+ struct sndrv_seq_connect connect;
+ struct sndrv_seq_result result;
+ struct sndrv_seq_ev_instr_begin instr_begin;
+ struct sndrv_seq_ev_sample_control sample;
+ struct sndrv_seq_ev_quote quote;
+ } data;
+};
+
+
+/*
+ * bounce event - stored as variable size data
+ */
+struct sndrv_seq_event_bounce {
+ int err;
+ struct sndrv_seq_event event;
+ /* external data follows here. */
+};
+
+#define sndrv_seq_event_bounce_ext_data(ev) ((void*)((char *)(ev)->data.ext.ptr + sizeof(sndrv_seq_event_bounce_t)))
+
+/*
+ * type check macros
+ */
+/* result events: 0-4 */
+#define sndrv_seq_ev_is_result_type(ev) ((ev)->type < 5)
+/* channel specific events: 5-19 */
+#define sndrv_seq_ev_is_channel_type(ev) ((ev)->type >= 5 && (ev)->type < 20)
+/* note events: 5-9 */
+#define sndrv_seq_ev_is_note_type(ev) ((ev)->type >= 5 && (ev)->type < 10)
+/* control events: 10-19 */
+#define sndrv_seq_ev_is_control_type(ev) ((ev)->type >= 10 && (ev)->type < 20)
+/* queue control events: 30-39 */
+#define sndrv_seq_ev_is_queue_type(ev) ((ev)->type >= 30 && (ev)->type < 40)
+/* system status messages */
+#define sndrv_seq_ev_is_message_type(ev) ((ev)->type >= 60 && (ev)->type < 69)
+/* sample messages */
+#define sndrv_seq_ev_is_sample_type(ev) ((ev)->type >= 70 && (ev)->type < 79)
+/* user-defined messages */
+#define sndrv_seq_ev_is_user_type(ev) ((ev)->type >= 90 && (ev)->type < 99)
+/* fixed length events: 0-99 */
+#define sndrv_seq_ev_is_fixed_type(ev) ((ev)->type < 100)
+/* instrument layer events: 100-129 */
+#define sndrv_seq_ev_is_instr_type(ev) ((ev)->type >= 100 && (ev)->type < 130)
+/* variable length events: 130-139 */
+#define sndrv_seq_ev_is_variable_type(ev) ((ev)->type >= 130 && (ev)->type < 140)
+/* reserved for kernel */
+#define sndrv_seq_ev_is_reserved(ev) ((ev)->type >= 150)
+
+/* direct dispatched events */
+#define sndrv_seq_ev_is_direct(ev) ((ev)->queue == SNDRV_SEQ_QUEUE_DIRECT)
+
+/*
+ * macros to check event flags
+ */
+/* prior events */
+#define sndrv_seq_ev_is_prior(ev) (((ev)->flags & SNDRV_SEQ_PRIORITY_MASK) == SNDRV_SEQ_PRIORITY_HIGH)
+
+/* event length type */
+#define sndrv_seq_ev_length_type(ev) ((ev)->flags & SNDRV_SEQ_EVENT_LENGTH_MASK)
+#define sndrv_seq_ev_is_fixed(ev) (sndrv_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_FIXED)
+#define sndrv_seq_ev_is_variable(ev) (sndrv_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
+#define sndrv_seq_ev_is_varusr(ev) (sndrv_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARUSR)
+
+/* time-stamp type */
+#define sndrv_seq_ev_timestamp_type(ev) ((ev)->flags & SNDRV_SEQ_TIME_STAMP_MASK)
+#define sndrv_seq_ev_is_tick(ev) (sndrv_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_TICK)
+#define sndrv_seq_ev_is_real(ev) (sndrv_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_REAL)
+
+/* time-mode type */
+#define sndrv_seq_ev_timemode_type(ev) ((ev)->flags & SNDRV_SEQ_TIME_MODE_MASK)
+#define sndrv_seq_ev_is_abstime(ev) (sndrv_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_ABS)
+#define sndrv_seq_ev_is_reltime(ev) (sndrv_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_REL)
+
+/* queue sync port */
+#define sndrv_seq_queue_sync_port(q) ((q) + 16)
+
+ /* system information */
+struct sndrv_seq_system_info {
+ int queues; /* maximum queues count */
+ int clients; /* maximum clients count */
+ int ports; /* maximum ports per client */
+ int channels; /* maximum channels per port */
+ int cur_clients; /* current clients */
+ int cur_queues; /* current queues */
+ char reserved[24];
+};
+
+
+ /* system running information */
+struct sndrv_seq_running_info {
+ unsigned char client; /* client id */
+ unsigned char big_endian; /* 1 = big-endian */
+ unsigned char cpu_mode; /* 4 = 32bit, 8 = 64bit */
+ unsigned char pad; /* reserved */
+ unsigned char reserved[12];
+};
+
+
+ /* known client numbers */
+#define SNDRV_SEQ_CLIENT_SYSTEM 0
+#define SNDRV_SEQ_CLIENT_DUMMY 62 /* dummy ports */
+#define SNDRV_SEQ_CLIENT_OSS 63 /* oss sequencer emulator */
+
+
+ /* client types */
+enum sndrv_seq_client_type {
+ NO_CLIENT = 0,
+ USER_CLIENT = 1,
+ KERNEL_CLIENT = 2
+};
+
+ /* event filter flags */
+#define SNDRV_SEQ_FILTER_BROADCAST (1<<0) /* accept broadcast messages */
+#define SNDRV_SEQ_FILTER_MULTICAST (1<<1) /* accept multicast messages */
+#define SNDRV_SEQ_FILTER_BOUNCE (1<<2) /* accept bounce event in error */
+#define SNDRV_SEQ_FILTER_USE_EVENT (1<<31) /* use event filter */
+
+struct sndrv_seq_client_info {
+ int client; /* client number to inquire */
+ enum sndrv_seq_client_type type; /* client type */
+ char name[64]; /* client name */
+ unsigned int filter; /* filter flags */
+ unsigned char multicast_filter[8]; /* multicast filter bitmap */
+ unsigned char event_filter[32]; /* event filter bitmap */
+ int num_ports; /* RO: number of ports */
+ int event_lost; /* number of lost events */
+ char reserved[64]; /* for future use */
+};
+
+
+/* client pool size */
+struct sndrv_seq_client_pool {
+ int client; /* client number to inquire */
+ int output_pool; /* outgoing (write) pool size */
+ int input_pool; /* incoming (read) pool size */
+ int output_room; /* minimum free pool size for select/blocking mode */
+ int output_free; /* unused size */
+ int input_free; /* unused size */
+ char reserved[64];
+};
+
+
+/* Remove events by specified criteria */
+
+#define SNDRV_SEQ_REMOVE_INPUT (1<<0) /* Flush input queues */
+#define SNDRV_SEQ_REMOVE_OUTPUT (1<<1) /* Flush output queues */
+#define SNDRV_SEQ_REMOVE_DEST (1<<2) /* Restrict by destination q:client:port */
+#define SNDRV_SEQ_REMOVE_DEST_CHANNEL (1<<3) /* Restrict by channel */
+#define SNDRV_SEQ_REMOVE_TIME_BEFORE (1<<4) /* Restrict to before time */
+#define SNDRV_SEQ_REMOVE_TIME_AFTER (1<<5) /* Restrict to time or after */
+#define SNDRV_SEQ_REMOVE_TIME_TICK (1<<6) /* Time is in ticks */
+#define SNDRV_SEQ_REMOVE_EVENT_TYPE (1<<7) /* Restrict to event type */
+#define SNDRV_SEQ_REMOVE_IGNORE_OFF (1<<8) /* Do not flush off events */
+#define SNDRV_SEQ_REMOVE_TAG_MATCH (1<<9) /* Restrict to events with given tag */
+
+struct sndrv_seq_remove_events {
+ unsigned int remove_mode; /* Flags that determine what gets removed */
+
+ union sndrv_seq_timestamp time;
+
+ unsigned char queue; /* Queue for REMOVE_DEST */
+ struct sndrv_seq_addr dest; /* Address for REMOVE_DEST */
+ unsigned char channel; /* Channel for REMOVE_DEST */
+
+ int type; /* For REMOVE_EVENT_TYPE */
+ char tag; /* Tag for REMOVE_TAG */
+
+ int reserved[10]; /* To allow for future binary compatibility */
+
+};
+
+
+ /* known port numbers */
+#define SNDRV_SEQ_PORT_SYSTEM_TIMER 0
+#define SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE 1
+
+ /* port capabilities (32 bits) */
+#define SNDRV_SEQ_PORT_CAP_READ (1<<0) /* readable from this port */
+#define SNDRV_SEQ_PORT_CAP_WRITE (1<<1) /* writable to this port */
+
+#define SNDRV_SEQ_PORT_CAP_SYNC_READ (1<<2)
+#define SNDRV_SEQ_PORT_CAP_SYNC_WRITE (1<<3)
+
+#define SNDRV_SEQ_PORT_CAP_DUPLEX (1<<4)
+
+#define SNDRV_SEQ_PORT_CAP_SUBS_READ (1<<5) /* allow read subscription */
+#define SNDRV_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /* allow write subscription */
+#define SNDRV_SEQ_PORT_CAP_NO_EXPORT (1<<7) /* routing not allowed */
+
+ /* port type */
+#define SNDRV_SEQ_PORT_TYPE_SPECIFIC (1<<0) /* hardware specific */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1) /* generic MIDI device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GM (1<<2) /* General MIDI compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GS (1<<3) /* GS compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_XG (1<<4) /* XG compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) /* MT-32 compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GM2 (1<<6) /* General MIDI 2 compatible device */
+
+/* other standards...*/
+#define SNDRV_SEQ_PORT_TYPE_SYNTH (1<<10) /* Synth device (no MIDI compatible - direct wavetable) */
+#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */
+#define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */
+/*...*/
+#define SNDRV_SEQ_PORT_TYPE_APPLICATION (1<<20) /* application (sequencer/editor) */
+
+/* misc. conditioning flags */
+#define SNDRV_SEQ_PORT_FLG_GIVEN_PORT (1<<0)
+#define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1<<1)
+#define SNDRV_SEQ_PORT_FLG_TIME_REAL (1<<2)
+
+struct sndrv_seq_port_info {
+ struct sndrv_seq_addr addr; /* client/port numbers */
+ char name[64]; /* port name */
+
+ unsigned int capability; /* port capability bits */
+ unsigned int type; /* port type bits */
+ int midi_channels; /* channels per MIDI port */
+ int midi_voices; /* voices per MIDI port */
+ int synth_voices; /* voices per SYNTH port */
+
+ int read_use; /* R/O: subscribers for output (from this port) */
+ int write_use; /* R/O: subscribers for input (to this port) */
+
+ void *kernel; /* reserved for kernel use (must be NULL) */
+ unsigned int flags; /* misc. conditioning */
+ unsigned char time_queue; /* queue # for timestamping */
+ char reserved[59]; /* for future use */
+};
+
+
+/* queue flags */
+#define SNDRV_SEQ_QUEUE_FLG_SYNC (1<<0) /* sync enabled */
+
+/* queue information */
+struct sndrv_seq_queue_info {
+ int queue; /* queue id */
+
+ /*
+ * security settings, only owner of this queue can start/stop timer
+ * etc. if the queue is locked for other clients
+ */
+ int owner; /* client id for owner of the queue */
+ unsigned locked:1; /* timing queue locked for other queues */
+ char name[64]; /* name of this queue */
+ unsigned int flags; /* flags */
+ char reserved[60]; /* for future use */
+
+};
+
+/* queue info/status */
+struct sndrv_seq_queue_status {
+ int queue; /* queue id */
+ int events; /* read-only - queue size */
+ sndrv_seq_tick_time_t tick; /* current tick */
+ struct sndrv_seq_real_time time; /* current time */
+ int running; /* running state of queue */
+ int flags; /* various flags */
+ char reserved[64]; /* for the future */
+};
+
+
+/* queue tempo */
+struct sndrv_seq_queue_tempo {
+ int queue; /* sequencer queue */
+ unsigned int tempo; /* current tempo, us/tick */
+ int ppq; /* time resolution, ticks/quarter */
+ unsigned int skew_value; /* queue skew */
+ unsigned int skew_base; /* queue skew base */
+ char reserved[24]; /* for the future */
+};
+
+
+/* sequencer timer sources */
+#define SNDRV_SEQ_TIMER_ALSA 0 /* ALSA timer */
+#define SNDRV_SEQ_TIMER_MIDI_CLOCK 1 /* Midi Clock (CLOCK event) */
+#define SNDRV_SEQ_TIMER_MIDI_TICK 2 /* Midi Timer Tick (TICK event) */
+
+/* queue timer info */
+struct sndrv_seq_queue_timer {
+ int queue; /* sequencer queue */
+ int type; /* source timer type */
+ union {
+ struct {
+ struct sndrv_timer_id id; /* ALSA's timer ID */
+ unsigned int resolution; /* resolution in Hz */
+ } alsa;
+ } u;
+ char reserved[64]; /* for the future use */
+};
+
+
+struct sndrv_seq_queue_client {
+ int queue; /* sequencer queue */
+ int client; /* sequencer client */
+ int used; /* queue is used with this client
+ (must be set for accepting events) */
+ /* per client watermarks */
+ char reserved[64]; /* for future use */
+};
+
+
+#define SNDRV_SEQ_PORT_SUBS_EXCLUSIVE (1<<0) /* exclusive connection */
+#define SNDRV_SEQ_PORT_SUBS_TIMESTAMP (1<<1)
+#define SNDRV_SEQ_PORT_SUBS_TIME_REAL (1<<2)
+
+struct sndrv_seq_port_subscribe {
+ struct sndrv_seq_addr sender; /* sender address */
+ struct sndrv_seq_addr dest; /* destination address */
+ unsigned int voices; /* number of voices to be allocated (0 = don't care) */
+ unsigned int flags; /* modes */
+ unsigned char queue; /* input time-stamp queue (optional) */
+ unsigned char pad[3]; /* reserved */
+ char reserved[64];
+};
+
+/* type of query subscription */
+#define SNDRV_SEQ_QUERY_SUBS_READ 0
+#define SNDRV_SEQ_QUERY_SUBS_WRITE 1
+
+struct sndrv_seq_query_subs {
+ struct sndrv_seq_addr root; /* client/port id to be searched */
+ int type; /* READ or WRITE */
+ int index; /* 0..N-1 */
+ int num_subs; /* R/O: number of subscriptions on this port */
+ struct sndrv_seq_addr addr; /* R/O: result */
+ unsigned char queue; /* R/O: result */
+ unsigned int flags; /* R/O: result */
+ char reserved[64]; /* for future use */
+};
+
+
+/*
+ * Instrument abstraction layer
+ * - based on events
+ */
+
+/* instrument types */
+#define SNDRV_SEQ_INSTR_ATYPE_DATA 0 /* instrument data */
+#define SNDRV_SEQ_INSTR_ATYPE_ALIAS 1 /* instrument alias */
+
+/* instrument ASCII identifiers */
+#define SNDRV_SEQ_INSTR_ID_DLS1 "DLS1"
+#define SNDRV_SEQ_INSTR_ID_DLS2 "DLS2"
+#define SNDRV_SEQ_INSTR_ID_SIMPLE "Simple Wave"
+#define SNDRV_SEQ_INSTR_ID_SOUNDFONT "SoundFont"
+#define SNDRV_SEQ_INSTR_ID_GUS_PATCH "GUS Patch"
+#define SNDRV_SEQ_INSTR_ID_INTERWAVE "InterWave FFFF"
+#define SNDRV_SEQ_INSTR_ID_OPL2_3 "OPL2/3 FM"
+#define SNDRV_SEQ_INSTR_ID_OPL4 "OPL4"
+
+/* instrument types */
+#define SNDRV_SEQ_INSTR_TYPE0_DLS1 (1<<0) /* MIDI DLS v1 */
+#define SNDRV_SEQ_INSTR_TYPE0_DLS2 (1<<1) /* MIDI DLS v2 */
+#define SNDRV_SEQ_INSTR_TYPE1_SIMPLE (1<<0) /* Simple Wave */
+#define SNDRV_SEQ_INSTR_TYPE1_SOUNDFONT (1<<1) /* EMU SoundFont */
+#define SNDRV_SEQ_INSTR_TYPE1_GUS_PATCH (1<<2) /* Gravis UltraSound Patch */
+#define SNDRV_SEQ_INSTR_TYPE1_INTERWAVE (1<<3) /* InterWave FFFF */
+#define SNDRV_SEQ_INSTR_TYPE2_OPL2_3 (1<<0) /* Yamaha OPL2/3 FM */
+#define SNDRV_SEQ_INSTR_TYPE2_OPL4 (1<<1) /* Yamaha OPL4 */
+
+/* put commands */
+#define SNDRV_SEQ_INSTR_PUT_CMD_CREATE 0
+#define SNDRV_SEQ_INSTR_PUT_CMD_REPLACE 1
+#define SNDRV_SEQ_INSTR_PUT_CMD_MODIFY 2
+#define SNDRV_SEQ_INSTR_PUT_CMD_ADD 3
+#define SNDRV_SEQ_INSTR_PUT_CMD_REMOVE 4
+
+/* get commands */
+#define SNDRV_SEQ_INSTR_GET_CMD_FULL 0
+#define SNDRV_SEQ_INSTR_GET_CMD_PARTIAL 1
+
+/* query flags */
+#define SNDRV_SEQ_INSTR_QUERY_FOLLOW_ALIAS (1<<0)
+
+/* free commands */
+#define SNDRV_SEQ_INSTR_FREE_CMD_ALL 0
+#define SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE 1
+#define SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER 2
+#define SNDRV_SEQ_INSTR_FREE_CMD_SINGLE 3
+
+/* size of ROM/RAM */
+typedef unsigned int sndrv_seq_instr_size_t;
+
+/* INSTR_INFO */
+
+struct sndrv_seq_instr_info {
+ int result; /* operation result */
+ unsigned int formats[8]; /* bitmap of supported formats */
+ int ram_count; /* count of RAM banks */
+ sndrv_seq_instr_size_t ram_sizes[16]; /* size of RAM banks */
+ int rom_count; /* count of ROM banks */
+ sndrv_seq_instr_size_t rom_sizes[8]; /* size of ROM banks */
+ char reserved[128];
+};
+
+/* INSTR_STATUS */
+
+struct sndrv_seq_instr_status {
+ int result; /* operation result */
+ sndrv_seq_instr_size_t free_ram[16]; /* free RAM in banks */
+ int instrument_count; /* count of downloaded instruments */
+ char reserved[128];
+};
+
+/* INSTR_FORMAT_INFO */
+
+struct sndrv_seq_instr_format_info {
+ char format[16]; /* format identifier - SNDRV_SEQ_INSTR_ID_* */
+ unsigned int len; /* max data length (without this structure) */
+};
+
+struct sndrv_seq_instr_format_info_result {
+ int result; /* operation result */
+ char format[16]; /* format identifier */
+ unsigned int len; /* filled data length (without this structure) */
+};
+
+/* instrument data */
+struct sndrv_seq_instr_data {
+ char name[32]; /* instrument name */
+ char reserved[16]; /* for the future use */
+ int type; /* instrument type */
+ union {
+ char format[16]; /* format identifier */
+ struct sndrv_seq_instr alias;
+ } data;
+};
+
+/* INSTR_PUT/GET, data are stored in one block (extended), header + data */
+
+struct sndrv_seq_instr_header {
+ union {
+ struct sndrv_seq_instr instr;
+ sndrv_seq_instr_cluster_t cluster;
+ } id; /* instrument identifier */
+ unsigned int cmd; /* get/put/free command */
+ unsigned int flags; /* query flags (only for get) */
+ unsigned int len; /* real instrument data length (without header) */
+ int result; /* operation result */
+ char reserved[16]; /* for the future */
+ struct sndrv_seq_instr_data data; /* instrument data (for put/get result) */
+};
+
+/* INSTR_CLUSTER_SET */
+
+struct sndrv_seq_instr_cluster_set {
+ sndrv_seq_instr_cluster_t cluster; /* cluster identifier */
+ char name[32]; /* cluster name */
+ int priority; /* cluster priority */
+ char reserved[64]; /* for the future use */
+};
+
+/* INSTR_CLUSTER_GET */
+
+struct sndrv_seq_instr_cluster_get {
+ sndrv_seq_instr_cluster_t cluster; /* cluster identifier */
+ char name[32]; /* cluster name */
+ int priority; /* cluster priority */
+ char reserved[64]; /* for the future use */
+};
+
+/*
+ * IOCTL commands
+ */
+
+#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int)
+#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int)
+#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info)
+#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info)
+
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info)
+
+#define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct sndrv_seq_port_info)
+#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct sndrv_seq_port_info)
+#define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct sndrv_seq_port_info)
+#define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW ('S', 0x23, struct sndrv_seq_port_info)
+
+#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW ('S', 0x30, struct sndrv_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe)
+
+#define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct sndrv_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW ('S', 0x33, struct sndrv_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct sndrv_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct sndrv_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct sndrv_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct sndrv_seq_queue_tempo)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct sndrv_seq_queue_tempo)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct sndrv_seq_queue_owner)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct sndrv_seq_queue_owner)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct sndrv_seq_queue_timer)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct sndrv_seq_queue_timer)
+/* XXX
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct sndrv_seq_queue_sync)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct sndrv_seq_queue_sync)
+*/
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct sndrv_seq_queue_client)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct sndrv_seq_queue_client)
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct sndrv_seq_client_pool)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW ('S', 0x4c, struct sndrv_seq_client_pool)
+#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW ('S', 0x4e, struct sndrv_seq_remove_events)
+#define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct sndrv_seq_query_subs)
+#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct sndrv_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct sndrv_seq_client_info)
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct sndrv_seq_port_info)
+
+#endif /* __SOUND_ASEQUENCER_H */
diff --git a/include/sound/asound.h b/include/sound/asound.h
new file mode 100644
index 0000000..a4d149f
--- /dev/null
+++ b/include/sound/asound.h
@@ -0,0 +1,927 @@
+/*
+ * Advanced Linux Sound Architecture - ALSA - Driver
+ * Copyright (c) 1994-2003 by Jaroslav Kysela <perex@suse.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
+
+#if defined(LINUX) || defined(__LINUX__) || defined(__linux__)
+
+#include <linux/ioctl.h>
+
+#ifdef __KERNEL__
+
+#include <linux/types.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
+
+#else /* !__KERNEL__ */
+
+#include <endian.h>
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define SNDRV_LITTLE_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define SNDRV_BIG_ENDIAN
+#else
+#error "Unsupported endian..."
+#endif
+
+#endif /* __KERNEL **/
+
+#endif /* LINUX */
+
+#ifndef __KERNEL__
+#include <sys/time.h>
+#include <sys/types.h>
+#endif
+
+/*
+ * protocol version
+ */
+
+#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor))
+#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff)
+#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff)
+#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff)
+#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) \
+ (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || \
+ (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && \
+ SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
+
+/****************************************************************************
+ * *
+ * Digital audio interface *
+ * *
+ ****************************************************************************/
+
+struct sndrv_aes_iec958 {
+ unsigned char status[24]; /* AES/IEC958 channel status bits */
+ unsigned char subcode[147]; /* AES/IEC958 subcode bits */
+ unsigned char pad; /* nothing */
+ unsigned char dig_subframe[4]; /* AES/IEC958 subframe bits */
+};
+
+/****************************************************************************
+ * *
+ * Section for driver hardware dependent interface - /dev/snd/hw? *
+ * *
+ ****************************************************************************/
+
+#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1)
+
+enum sndrv_hwdep_iface {
+ SNDRV_HWDEP_IFACE_OPL2 = 0,
+ SNDRV_HWDEP_IFACE_OPL3,
+ SNDRV_HWDEP_IFACE_OPL4,
+ SNDRV_HWDEP_IFACE_SB16CSP, /* Creative Signal Processor */
+ SNDRV_HWDEP_IFACE_EMU10K1, /* FX8010 processor in EMU10K1 chip */
+ SNDRV_HWDEP_IFACE_YSS225, /* Yamaha FX processor */
+ SNDRV_HWDEP_IFACE_ICS2115, /* Wavetable synth */
+ SNDRV_HWDEP_IFACE_SSCAPE, /* Ensoniq SoundScape ISA card (MC68EC000) */
+ SNDRV_HWDEP_IFACE_VX, /* Digigram VX cards */
+ SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */
+ SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */
+ SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */
+ SNDRV_HWDEP_IFACE_BLUETOOTH, /* Bluetooth audio */
+ SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */
+ SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
+
+ /* Don't forget to change the following: */
+ SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_PCXHR
+};
+
+struct sndrv_hwdep_info {
+ unsigned int device; /* WR: device number */
+ int card; /* R: card number */
+ unsigned char id[64]; /* ID (user selectable) */
+ unsigned char name[80]; /* hwdep name */
+ enum sndrv_hwdep_iface iface; /* hwdep interface */
+ unsigned char reserved[64]; /* reserved for future */
+};
+
+/* generic DSP loader */
+struct sndrv_hwdep_dsp_status {
+ unsigned int version; /* R: driver-specific version */
+ unsigned char id[32]; /* R: driver-specific ID string */
+ unsigned int num_dsps; /* R: number of DSP images to transfer */
+ unsigned int dsp_loaded; /* R: bit flags indicating the loaded DSPs */
+ unsigned int chip_ready; /* R: 1 = initialization finished */
+ unsigned char reserved[16]; /* reserved for future use */
+};
+
+struct sndrv_hwdep_dsp_image {
+ unsigned int index; /* W: DSP index */
+ unsigned char name[64]; /* W: ID (e.g. file name) */
+ unsigned char __user *image; /* W: binary image */
+ size_t length; /* W: size of image in bytes */
+ unsigned long driver_data; /* W: driver-specific data */
+};
+
+enum {
+ SNDRV_HWDEP_IOCTL_PVERSION = _IOR ('H', 0x00, int),
+ SNDRV_HWDEP_IOCTL_INFO = _IOR ('H', 0x01, struct sndrv_hwdep_info),
+ SNDRV_HWDEP_IOCTL_DSP_STATUS = _IOR('H', 0x02, struct sndrv_hwdep_dsp_status),
+ SNDRV_HWDEP_IOCTL_DSP_LOAD = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image)
+};
+
+/*****************************************************************************
+ * *
+ * Digital Audio (PCM) interface - /dev/snd/pcm?? *
+ * *
+ *****************************************************************************/
+
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
+
+typedef unsigned long sndrv_pcm_uframes_t;
+typedef long sndrv_pcm_sframes_t;
+
+enum sndrv_pcm_class {
+ SNDRV_PCM_CLASS_GENERIC = 0, /* standard mono or stereo device */
+ SNDRV_PCM_CLASS_MULTI, /* multichannel device */
+ SNDRV_PCM_CLASS_MODEM, /* software modem class */
+ SNDRV_PCM_CLASS_DIGITIZER, /* digitizer class */
+ /* Don't forget to change the following: */
+ SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER,
+};
+
+enum sndrv_pcm_subclass {
+ SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */
+ SNDRV_PCM_SUBCLASS_MULTI_MIX, /* multichannel subdevices are mixed together */
+ /* Don't forget to change the following: */
+ SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX,
+};
+
+enum sndrv_pcm_stream {
+ SNDRV_PCM_STREAM_PLAYBACK = 0,
+ SNDRV_PCM_STREAM_CAPTURE,
+ SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
+};
+
+enum sndrv_pcm_access {
+ SNDRV_PCM_ACCESS_MMAP_INTERLEAVED = 0, /* interleaved mmap */
+ SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED, /* noninterleaved mmap */
+ SNDRV_PCM_ACCESS_MMAP_COMPLEX, /* complex mmap */
+ SNDRV_PCM_ACCESS_RW_INTERLEAVED, /* readi/writei */
+ SNDRV_PCM_ACCESS_RW_NONINTERLEAVED, /* readn/writen */
+ SNDRV_PCM_ACCESS_LAST = SNDRV_PCM_ACCESS_RW_NONINTERLEAVED,
+};
+
+enum sndrv_pcm_format {
+ SNDRV_PCM_FORMAT_S8 = 0,
+ SNDRV_PCM_FORMAT_U8,
+ SNDRV_PCM_FORMAT_S16_LE,
+ SNDRV_PCM_FORMAT_S16_BE,
+ SNDRV_PCM_FORMAT_U16_LE,
+ SNDRV_PCM_FORMAT_U16_BE,
+ SNDRV_PCM_FORMAT_S24_LE, /* low three bytes */
+ SNDRV_PCM_FORMAT_S24_BE, /* low three bytes */
+ SNDRV_PCM_FORMAT_U24_LE, /* low three bytes */
+ SNDRV_PCM_FORMAT_U24_BE, /* low three bytes */
+ SNDRV_PCM_FORMAT_S32_LE,
+ SNDRV_PCM_FORMAT_S32_BE,
+ SNDRV_PCM_FORMAT_U32_LE,
+ SNDRV_PCM_FORMAT_U32_BE,
+ SNDRV_PCM_FORMAT_FLOAT_LE, /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
+ SNDRV_PCM_FORMAT_FLOAT_BE, /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
+ SNDRV_PCM_FORMAT_FLOAT64_LE, /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
+ SNDRV_PCM_FORMAT_FLOAT64_BE, /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
+ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE, /* IEC-958 subframe, Little Endian */
+ SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE, /* IEC-958 subframe, Big Endian */
+ SNDRV_PCM_FORMAT_MU_LAW,
+ SNDRV_PCM_FORMAT_A_LAW,
+ SNDRV_PCM_FORMAT_IMA_ADPCM,
+ SNDRV_PCM_FORMAT_MPEG,
+ SNDRV_PCM_FORMAT_GSM,
+ SNDRV_PCM_FORMAT_SPECIAL = 31,
+ SNDRV_PCM_FORMAT_S24_3LE = 32, /* in three bytes */
+ SNDRV_PCM_FORMAT_S24_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U24_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U24_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S20_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S20_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U20_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U20_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S18_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_S18_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U18_3LE, /* in three bytes */
+ SNDRV_PCM_FORMAT_U18_3BE, /* in three bytes */
+ SNDRV_PCM_FORMAT_LAST = SNDRV_PCM_FORMAT_U18_3BE,
+
+#ifdef SNDRV_LITTLE_ENDIAN
+ SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_LE,
+ SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_LE,
+ SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_LE,
+ SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_LE,
+ SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_LE,
+ SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_LE,
+ SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_LE,
+ SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_LE,
+ SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE,
+#endif
+#ifdef SNDRV_BIG_ENDIAN
+ SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_BE,
+ SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_BE,
+ SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_BE,
+ SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_BE,
+ SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_BE,
+ SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_BE,
+ SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_BE,
+ SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_BE,
+ SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,
+#endif
+};
+
+enum sndrv_pcm_subformat {
+ SNDRV_PCM_SUBFORMAT_STD = 0,
+ SNDRV_PCM_SUBFORMAT_LAST = SNDRV_PCM_SUBFORMAT_STD,
+};
+
+#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */
+#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */
+#define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */
+#define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */
+#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */
+#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */
+#define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */
+#define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000 /* hardware transfer block of samples */
+#define SNDRV_PCM_INFO_OVERRANGE 0x00020000 /* hardware supports ADC (capture) overrange detection */
+#define SNDRV_PCM_INFO_RESUME 0x00040000 /* hardware supports stream resume after suspend */
+#define SNDRV_PCM_INFO_PAUSE 0x00080000 /* pause ioctl is supported */
+#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */
+#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */
+#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */
+
+enum sndrv_pcm_state {
+ SNDRV_PCM_STATE_OPEN = 0, /* stream is open */
+ SNDRV_PCM_STATE_SETUP, /* stream has a setup */
+ SNDRV_PCM_STATE_PREPARED, /* stream is ready to start */
+ SNDRV_PCM_STATE_RUNNING, /* stream is running */
+ SNDRV_PCM_STATE_XRUN, /* stream reached an xrun */
+ SNDRV_PCM_STATE_DRAINING, /* stream is draining */
+ SNDRV_PCM_STATE_PAUSED, /* stream is paused */
+ SNDRV_PCM_STATE_SUSPENDED, /* hardware is suspended */
+ SNDRV_PCM_STATE_DISCONNECTED, /* hardware is disconnected */
+ SNDRV_PCM_STATE_LAST = SNDRV_PCM_STATE_DISCONNECTED,
+};
+
+enum {
+ SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
+ SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
+ SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
+};
+
+union sndrv_pcm_sync_id {
+ unsigned char id[16];
+ unsigned short id16[8];
+ unsigned int id32[4];
+};
+
+struct sndrv_pcm_info {
+ unsigned int device; /* RO/WR (control): device number */
+ unsigned int subdevice; /* RO/WR (control): subdevice number */
+ enum sndrv_pcm_stream stream; /* RO/WR (control): stream number */
+ int card; /* R: card number */
+ unsigned char id[64]; /* ID (user selectable) */
+ unsigned char name[80]; /* name of this device */
+ unsigned char subname[32]; /* subdevice name */
+ enum sndrv_pcm_class dev_class; /* SNDRV_PCM_CLASS_* */
+ enum sndrv_pcm_subclass dev_subclass; /* SNDRV_PCM_SUBCLASS_* */
+ unsigned int subdevices_count;
+ unsigned int subdevices_avail;
+ union sndrv_pcm_sync_id sync; /* hardware synchronization ID */
+ unsigned char reserved[64]; /* reserved for future... */
+};
+
+enum sndrv_pcm_hw_param {
+ SNDRV_PCM_HW_PARAM_ACCESS = 0, /* Access type */
+ SNDRV_PCM_HW_PARAM_FIRST_MASK = SNDRV_PCM_HW_PARAM_ACCESS,
+ SNDRV_PCM_HW_PARAM_FORMAT, /* Format */
+ SNDRV_PCM_HW_PARAM_SUBFORMAT, /* Subformat */
+ SNDRV_PCM_HW_PARAM_LAST_MASK = SNDRV_PCM_HW_PARAM_SUBFORMAT,
+
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS = 8, /* Bits per sample */
+ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL = SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ SNDRV_PCM_HW_PARAM_FRAME_BITS, /* Bits per frame */
+ SNDRV_PCM_HW_PARAM_CHANNELS, /* Channels */
+ SNDRV_PCM_HW_PARAM_RATE, /* Approx rate */
+ SNDRV_PCM_HW_PARAM_PERIOD_TIME, /* Approx distance between interrupts
+ in us */
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, /* Approx frames between interrupts */
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, /* Approx bytes between interrupts */
+ SNDRV_PCM_HW_PARAM_PERIODS, /* Approx interrupts per buffer */
+ SNDRV_PCM_HW_PARAM_BUFFER_TIME, /* Approx duration of buffer in us */
+ SNDRV_PCM_HW_PARAM_BUFFER_SIZE, /* Size of buffer in frames */
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, /* Size of buffer in bytes */
+ SNDRV_PCM_HW_PARAM_TICK_TIME, /* Approx tick duration in us */
+ SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME
+};
+
+#define SNDRV_PCM_HW_PARAMS_RUNTIME (1<<0)
+
+struct sndrv_interval {
+ unsigned int min, max;
+ unsigned int openmin:1,
+ openmax:1,
+ integer:1,
+ empty:1;
+};
+
+#define SNDRV_MASK_MAX 256
+
+struct sndrv_mask {
+ u_int32_t bits[(SNDRV_MASK_MAX+31)/32];
+};
+
+struct sndrv_pcm_hw_params {
+ unsigned int flags;
+ struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
+ SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+ struct sndrv_mask mres[5]; /* reserved masks */
+ struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
+ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+ struct sndrv_interval ires[9]; /* reserved intervals */
+ unsigned int rmask; /* W: requested masks */
+ unsigned int cmask; /* R: changed masks */
+ unsigned int info; /* R: Info flags for returned setup */
+ unsigned int msbits; /* R: used most significant bits */
+ unsigned int rate_num; /* R: rate numerator */
+ unsigned int rate_den; /* R: rate denominator */
+ sndrv_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */
+ unsigned char reserved[64]; /* reserved for future */
+};
+
+enum sndrv_pcm_tstamp {
+ SNDRV_PCM_TSTAMP_NONE = 0,
+ SNDRV_PCM_TSTAMP_MMAP,
+ SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_MMAP,
+};
+
+struct sndrv_pcm_sw_params {
+ enum sndrv_pcm_tstamp tstamp_mode; /* timestamp mode */
+ unsigned int period_step;
+ unsigned int sleep_min; /* min ticks to sleep */
+ sndrv_pcm_uframes_t avail_min; /* min avail frames for wakeup */
+ sndrv_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */
+ sndrv_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */
+ sndrv_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */
+ sndrv_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */
+ sndrv_pcm_uframes_t silence_size; /* silence block size */
+ sndrv_pcm_uframes_t boundary; /* pointers wrap point */
+ unsigned char reserved[64]; /* reserved for future */
+};
+
+struct sndrv_pcm_channel_info {
+ unsigned int channel;
+ off_t offset; /* mmap offset */
+ unsigned int first; /* offset to first sample in bits */
+ unsigned int step; /* samples distance in bits */
+};
+
+struct sndrv_pcm_status {
+ enum sndrv_pcm_state state; /* stream state */
+ struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */
+ struct timespec tstamp; /* reference timestamp */
+ sndrv_pcm_uframes_t appl_ptr; /* appl ptr */
+ sndrv_pcm_uframes_t hw_ptr; /* hw ptr */
+ sndrv_pcm_sframes_t delay; /* current delay in frames */
+ sndrv_pcm_uframes_t avail; /* number of frames available */
+ sndrv_pcm_uframes_t avail_max; /* max frames available on hw since last status */
+ sndrv_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */
+ enum sndrv_pcm_state suspended_state; /* suspended stream state */
+ unsigned char reserved[60]; /* must be filled with zero */
+};
+
+struct sndrv_pcm_mmap_status {
+ enum sndrv_pcm_state state; /* RO: state - SNDRV_PCM_STATE_XXXX */
+ int pad1; /* Needed for 64 bit alignment */
+ sndrv_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */
+ struct timespec tstamp; /* Timestamp */
+ enum sndrv_pcm_state suspended_state; /* RO: suspended stream state */
+};
+
+struct sndrv_pcm_mmap_control {
+ sndrv_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */
+ sndrv_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */
+};
+
+#define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0) /* execute hwsync */
+#define SNDRV_PCM_SYNC_PTR_APPL (1<<1) /* get appl_ptr from driver (r/w op) */
+#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) /* get avail_min from driver */
+
+struct sndrv_pcm_sync_ptr {
+ unsigned int flags;
+ union {
+ struct sndrv_pcm_mmap_status status;
+ unsigned char reserved[64];
+ } s;
+ union {
+ struct sndrv_pcm_mmap_control control;
+ unsigned char reserved[64];
+ } c;
+};
+
+struct sndrv_xferi {
+ sndrv_pcm_sframes_t result;
+ void __user *buf;
+ sndrv_pcm_uframes_t frames;
+};
+
+struct sndrv_xfern {
+ sndrv_pcm_sframes_t result;
+ void __user * __user *bufs;
+ sndrv_pcm_uframes_t frames;
+};
+
+enum {
+ SNDRV_PCM_IOCTL_PVERSION = _IOR('A', 0x00, int),
+ SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, struct sndrv_pcm_info),
+ SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int),
+ SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, struct sndrv_pcm_hw_params),
+ SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, struct sndrv_pcm_hw_params),
+ SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12),
+ SNDRV_PCM_IOCTL_SW_PARAMS = _IOWR('A', 0x13, struct sndrv_pcm_sw_params),
+ SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, struct sndrv_pcm_status),
+ SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, sndrv_pcm_sframes_t),
+ SNDRV_PCM_IOCTL_HWSYNC = _IO('A', 0x22),
+ SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr),
+ SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct sndrv_pcm_channel_info),
+ SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40),
+ SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41),
+ SNDRV_PCM_IOCTL_START = _IO('A', 0x42),
+ SNDRV_PCM_IOCTL_DROP = _IO('A', 0x43),
+ SNDRV_PCM_IOCTL_DRAIN = _IO('A', 0x44),
+ SNDRV_PCM_IOCTL_PAUSE = _IOW('A', 0x45, int),
+ SNDRV_PCM_IOCTL_REWIND = _IOW('A', 0x46, sndrv_pcm_uframes_t),
+ SNDRV_PCM_IOCTL_RESUME = _IO('A', 0x47),
+ SNDRV_PCM_IOCTL_XRUN = _IO('A', 0x48),
+ SNDRV_PCM_IOCTL_FORWARD = _IOW('A', 0x49, sndrv_pcm_uframes_t),
+ SNDRV_PCM_IOCTL_WRITEI_FRAMES = _IOW('A', 0x50, struct sndrv_xferi),
+ SNDRV_PCM_IOCTL_READI_FRAMES = _IOR('A', 0x51, struct sndrv_xferi),
+ SNDRV_PCM_IOCTL_WRITEN_FRAMES = _IOW('A', 0x52, struct sndrv_xfern),
+ SNDRV_PCM_IOCTL_READN_FRAMES = _IOR('A', 0x53, struct sndrv_xfern),
+ SNDRV_PCM_IOCTL_LINK = _IOW('A', 0x60, int),
+ SNDRV_PCM_IOCTL_UNLINK = _IO('A', 0x61),
+};
+
+/* Trick to make alsa-lib/acinclude.m4 happy */
+#define SNDRV_PCM_IOCTL_REWIND SNDRV_PCM_IOCTL_REWIND
+
+/*****************************************************************************
+ * *
+ * MIDI v1.0 interface *
+ * *
+ *****************************************************************************/
+
+/*
+ * Raw MIDI section - /dev/snd/midi??
+ */
+
+#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0)
+
+enum sndrv_rawmidi_stream {
+ SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
+ SNDRV_RAWMIDI_STREAM_INPUT,
+ SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
+};
+
+#define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001
+#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
+#define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004
+
+struct sndrv_rawmidi_info {
+ unsigned int device; /* RO/WR (control): device number */
+ unsigned int subdevice; /* RO/WR (control): subdevice number */
+ enum sndrv_rawmidi_stream stream; /* WR: stream */
+ int card; /* R: card number */
+ unsigned int flags; /* SNDRV_RAWMIDI_INFO_XXXX */
+ unsigned char id[64]; /* ID (user selectable) */
+ unsigned char name[80]; /* name of device */
+ unsigned char subname[32]; /* name of active or selected subdevice */
+ unsigned int subdevices_count;
+ unsigned int subdevices_avail;
+ unsigned char reserved[64]; /* reserved for future use */
+};
+
+struct sndrv_rawmidi_params {
+ enum sndrv_rawmidi_stream stream;
+ size_t buffer_size; /* queue size in bytes */
+ size_t avail_min; /* minimum avail bytes for wakeup */
+ unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */
+ unsigned char reserved[16]; /* reserved for future use */
+};
+
+struct sndrv_rawmidi_status {
+ enum sndrv_rawmidi_stream stream;
+ struct timespec tstamp; /* Timestamp */
+ size_t avail; /* available bytes */
+ size_t xruns; /* count of overruns since last status (in bytes) */
+ unsigned char reserved[16]; /* reserved for future use */
+};
+
+enum {
+ SNDRV_RAWMIDI_IOCTL_PVERSION = _IOR('W', 0x00, int),
+ SNDRV_RAWMIDI_IOCTL_INFO = _IOR('W', 0x01, struct sndrv_rawmidi_info),
+ SNDRV_RAWMIDI_IOCTL_PARAMS = _IOWR('W', 0x10, struct sndrv_rawmidi_params),
+ SNDRV_RAWMIDI_IOCTL_STATUS = _IOWR('W', 0x20, struct sndrv_rawmidi_status),
+ SNDRV_RAWMIDI_IOCTL_DROP = _IOW('W', 0x30, int),
+ SNDRV_RAWMIDI_IOCTL_DRAIN = _IOW('W', 0x31, int),
+};
+
+/*
+ * Timer section - /dev/snd/timer
+ */
+
+#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
+
+enum sndrv_timer_class {
+ SNDRV_TIMER_CLASS_NONE = -1,
+ SNDRV_TIMER_CLASS_SLAVE = 0,
+ SNDRV_TIMER_CLASS_GLOBAL,
+ SNDRV_TIMER_CLASS_CARD,
+ SNDRV_TIMER_CLASS_PCM,
+ SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM,
+};
+
+/* slave timer classes */
+enum sndrv_timer_slave_class {
+ SNDRV_TIMER_SCLASS_NONE = 0,
+ SNDRV_TIMER_SCLASS_APPLICATION,
+ SNDRV_TIMER_SCLASS_SEQUENCER, /* alias */
+ SNDRV_TIMER_SCLASS_OSS_SEQUENCER, /* alias */
+ SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
+};
+
+/* global timers (device member) */
+#define SNDRV_TIMER_GLOBAL_SYSTEM 0
+#define SNDRV_TIMER_GLOBAL_RTC 1
+#define SNDRV_TIMER_GLOBAL_HPET 2
+
+/* info flags */
+#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */
+
+struct sndrv_timer_id {
+ enum sndrv_timer_class dev_class;
+ enum sndrv_timer_slave_class dev_sclass;
+ int card;
+ int device;
+ int subdevice;
+};
+
+struct sndrv_timer_ginfo {
+ struct sndrv_timer_id tid; /* requested timer ID */
+ unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */
+ int card; /* card number */
+ unsigned char id[64]; /* timer identification */
+ unsigned char name[80]; /* timer name */
+ unsigned long reserved0; /* reserved for future use */
+ unsigned long resolution; /* average period resolution in ns */
+ unsigned long resolution_min; /* minimal period resolution in ns */
+ unsigned long resolution_max; /* maximal period resolution in ns */
+ unsigned int clients; /* active timer clients */
+ unsigned char reserved[32];
+};
+
+struct sndrv_timer_gparams {
+ struct sndrv_timer_id tid; /* requested timer ID */
+ unsigned long period_num; /* requested precise period duration (in seconds) - numerator */
+ unsigned long period_den; /* requested precise period duration (in seconds) - denominator */
+ unsigned char reserved[32];
+};
+
+struct sndrv_timer_gstatus {
+ struct sndrv_timer_id tid; /* requested timer ID */
+ unsigned long resolution; /* current period resolution in ns */
+ unsigned long resolution_num; /* precise current period resolution (in seconds) - numerator */
+ unsigned long resolution_den; /* precise current period resolution (in seconds) - denominator */
+ unsigned char reserved[32];
+};
+
+struct sndrv_timer_select {
+ struct sndrv_timer_id id; /* bind to timer ID */
+ unsigned char reserved[32]; /* reserved */
+};
+
+struct sndrv_timer_info {
+ unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */
+ int card; /* card number */
+ unsigned char id[64]; /* timer identificator */
+ unsigned char name[80]; /* timer name */
+ unsigned long reserved0; /* reserved for future use */
+ unsigned long resolution; /* average period resolution in ns */
+ unsigned char reserved[64]; /* reserved */
+};
+
+#define SNDRV_TIMER_PSFLG_AUTO (1<<0) /* auto start, otherwise one-shot */
+#define SNDRV_TIMER_PSFLG_EXCLUSIVE (1<<1) /* exclusive use, precise start/stop/pause/continue */
+#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2) /* write early event to the poll queue */
+
+struct sndrv_timer_params {
+ unsigned int flags; /* flags - SNDRV_MIXER_PSFLG_* */
+ unsigned int ticks; /* requested resolution in ticks */
+ unsigned int queue_size; /* total size of queue (32-1024) */
+ unsigned int reserved0; /* reserved, was: failure locations */
+ unsigned int filter; /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */
+ unsigned char reserved[60]; /* reserved */
+};
+
+struct sndrv_timer_status {
+ struct timespec tstamp; /* Timestamp - last update */
+ unsigned int resolution; /* current period resolution in ns */
+ unsigned int lost; /* counter of master tick lost */
+ unsigned int overrun; /* count of read queue overruns */
+ unsigned int queue; /* used queue size */
+ unsigned char reserved[64]; /* reserved */
+};
+
+enum {
+ SNDRV_TIMER_IOCTL_PVERSION = _IOR('T', 0x00, int),
+ SNDRV_TIMER_IOCTL_NEXT_DEVICE = _IOWR('T', 0x01, struct sndrv_timer_id),
+ SNDRV_TIMER_IOCTL_TREAD = _IOW('T', 0x02, int),
+ SNDRV_TIMER_IOCTL_GINFO = _IOWR('T', 0x03, struct sndrv_timer_ginfo),
+ SNDRV_TIMER_IOCTL_GPARAMS = _IOW('T', 0x04, struct sndrv_timer_gparams),
+ SNDRV_TIMER_IOCTL_GSTATUS = _IOWR('T', 0x05, struct sndrv_timer_gstatus),
+ SNDRV_TIMER_IOCTL_SELECT = _IOW('T', 0x10, struct sndrv_timer_select),
+ SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct sndrv_timer_info),
+ SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct sndrv_timer_params),
+ SNDRV_TIMER_IOCTL_STATUS = _IOR('T', 0x14, struct sndrv_timer_status),
+ SNDRV_TIMER_IOCTL_START = _IO('T', 0x20),
+ SNDRV_TIMER_IOCTL_STOP = _IO('T', 0x21),
+ SNDRV_TIMER_IOCTL_CONTINUE = _IO('T', 0x22),
+ SNDRV_TIMER_IOCTL_PAUSE = _IO('T', 0x23),
+};
+
+struct sndrv_timer_read {
+ unsigned int resolution;
+ unsigned int ticks;
+};
+
+enum sndrv_timer_event {
+ SNDRV_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */
+ SNDRV_TIMER_EVENT_TICK, /* val = ticks */
+ SNDRV_TIMER_EVENT_START, /* val = resolution in ns */
+ SNDRV_TIMER_EVENT_STOP, /* val = 0 */
+ SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */
+ SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */
+ SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */
+ /* master timer events for slave timer instances */
+ SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
+ SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
+ SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
+ SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
+};
+
+struct sndrv_timer_tread {
+ enum sndrv_timer_event event;
+ struct timespec tstamp;
+ unsigned int val;
+};
+
+/****************************************************************************
+ * *
+ * Section for driver control interface - /dev/snd/control? *
+ * *
+ ****************************************************************************/
+
+#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 3)
+
+struct sndrv_ctl_card_info {
+ int card; /* card number */
+ int pad; /* reserved for future (was type) */
+ unsigned char id[16]; /* ID of card (user selectable) */
+ unsigned char driver[16]; /* Driver name */
+ unsigned char name[32]; /* Short name of soundcard */
+ unsigned char longname[80]; /* name + info text about soundcard */
+ unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */
+ unsigned char mixername[80]; /* visual mixer identification */
+ unsigned char components[80]; /* card components / fine identification, delimited with one space (AC97 etc..) */
+ unsigned char reserved[48]; /* reserved for future */
+};
+
+enum sndrv_ctl_elem_type {
+ SNDRV_CTL_ELEM_TYPE_NONE = 0, /* invalid */
+ SNDRV_CTL_ELEM_TYPE_BOOLEAN, /* boolean type */
+ SNDRV_CTL_ELEM_TYPE_INTEGER, /* integer type */
+ SNDRV_CTL_ELEM_TYPE_ENUMERATED, /* enumerated type */
+ SNDRV_CTL_ELEM_TYPE_BYTES, /* byte array */
+ SNDRV_CTL_ELEM_TYPE_IEC958, /* IEC958 (S/PDIF) setup */
+ SNDRV_CTL_ELEM_TYPE_INTEGER64, /* 64-bit integer type */
+ SNDRV_CTL_ELEM_TYPE_LAST = SNDRV_CTL_ELEM_TYPE_INTEGER64,
+};
+
+enum sndrv_ctl_elem_iface {
+ SNDRV_CTL_ELEM_IFACE_CARD = 0, /* global control */
+ SNDRV_CTL_ELEM_IFACE_HWDEP, /* hardware dependent device */
+ SNDRV_CTL_ELEM_IFACE_MIXER, /* virtual mixer device */
+ SNDRV_CTL_ELEM_IFACE_PCM, /* PCM device */
+ SNDRV_CTL_ELEM_IFACE_RAWMIDI, /* RawMidi device */
+ SNDRV_CTL_ELEM_IFACE_TIMER, /* timer device */
+ SNDRV_CTL_ELEM_IFACE_SEQUENCER, /* sequencer client */
+ SNDRV_CTL_ELEM_IFACE_LAST = SNDRV_CTL_ELEM_IFACE_SEQUENCER,
+};
+
+#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0)
+#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1)
+#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
+#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */
+#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<2) /* when was control changed */
+#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) /* control does actually nothing, but may be updated */
+#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) /* write lock */
+#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */
+#define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) /* user space element */
+#define SNDRV_CTL_ELEM_ACCESS_DINDIRECT (1<<30) /* indirect access for matrix dimensions in the info structure */
+#define SNDRV_CTL_ELEM_ACCESS_INDIRECT (1<<31) /* indirect access for element value in the value structure */
+
+/* for further details see the ACPI and PCI power management specification */
+#define SNDRV_CTL_POWER_D0 0x0000 /* full On */
+#define SNDRV_CTL_POWER_D1 0x0100 /* partial On */
+#define SNDRV_CTL_POWER_D2 0x0200 /* partial On */
+#define SNDRV_CTL_POWER_D3 0x0300 /* Off */
+#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000) /* Off, with power */
+#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001) /* Off, without power */
+
+struct sndrv_ctl_elem_id {
+ unsigned int numid; /* numeric identifier, zero = invalid */
+ enum sndrv_ctl_elem_iface iface; /* interface identifier */
+ unsigned int device; /* device/client number */
+ unsigned int subdevice; /* subdevice (substream) number */
+ unsigned char name[44]; /* ASCII name of item */
+ unsigned int index; /* index of item */
+};
+
+struct sndrv_ctl_elem_list {
+ unsigned int offset; /* W: first element ID to get */
+ unsigned int space; /* W: count of element IDs to get */
+ unsigned int used; /* R: count of element IDs set */
+ unsigned int count; /* R: count of all elements */
+ struct sndrv_ctl_elem_id __user *pids; /* R: IDs */
+ unsigned char reserved[50];
+};
+
+struct sndrv_ctl_elem_info {
+ struct sndrv_ctl_elem_id id; /* W: element ID */
+ enum sndrv_ctl_elem_type type; /* R: value type - SNDRV_CTL_ELEM_TYPE_* */
+ unsigned int access; /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */
+ unsigned int count; /* count of values */
+ pid_t owner; /* owner's PID of this control */
+ union {
+ struct {
+ long min; /* R: minimum value */
+ long max; /* R: maximum value */
+ long step; /* R: step (0 variable) */
+ } integer;
+ struct {
+ long long min; /* R: minimum value */
+ long long max; /* R: maximum value */
+ long long step; /* R: step (0 variable) */
+ } integer64;
+ struct {
+ unsigned int items; /* R: number of items */
+ unsigned int item; /* W: item number */
+ char name[64]; /* R: value name */
+ } enumerated;
+ unsigned char reserved[128];
+ } value;
+ union {
+ unsigned short d[4]; /* dimensions */
+ unsigned short *d_ptr; /* indirect */
+ } dimen;
+ unsigned char reserved[64-4*sizeof(unsigned short)];
+};
+
+struct sndrv_ctl_elem_value {
+ struct sndrv_ctl_elem_id id; /* W: element ID */
+ unsigned int indirect: 1; /* W: use indirect pointer (xxx_ptr member) */
+ union {
+ union {
+ long value[128];
+ long *value_ptr;
+ } integer;
+ union {
+ long long value[64];
+ long long *value_ptr;
+ } integer64;
+ union {
+ unsigned int item[128];
+ unsigned int *item_ptr;
+ } enumerated;
+ union {
+ unsigned char data[512];
+ unsigned char *data_ptr;
+ } bytes;
+ struct sndrv_aes_iec958 iec958;
+ } value; /* RO */
+ struct timespec tstamp;
+ unsigned char reserved[128-sizeof(struct timespec)];
+};
+
+enum {
+ SNDRV_CTL_IOCTL_PVERSION = _IOR('U', 0x00, int),
+ SNDRV_CTL_IOCTL_CARD_INFO = _IOR('U', 0x01, struct sndrv_ctl_card_info),
+ SNDRV_CTL_IOCTL_ELEM_LIST = _IOWR('U', 0x10, struct sndrv_ctl_elem_list),
+ SNDRV_CTL_IOCTL_ELEM_INFO = _IOWR('U', 0x11, struct sndrv_ctl_elem_info),
+ SNDRV_CTL_IOCTL_ELEM_READ = _IOWR('U', 0x12, struct sndrv_ctl_elem_value),
+ SNDRV_CTL_IOCTL_ELEM_WRITE = _IOWR('U', 0x13, struct sndrv_ctl_elem_value),
+ SNDRV_CTL_IOCTL_ELEM_LOCK = _IOW('U', 0x14, struct sndrv_ctl_elem_id),
+ SNDRV_CTL_IOCTL_ELEM_UNLOCK = _IOW('U', 0x15, struct sndrv_ctl_elem_id),
+ SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS = _IOWR('U', 0x16, int),
+ SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct sndrv_ctl_elem_info),
+ SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct sndrv_ctl_elem_info),
+ SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct sndrv_ctl_elem_id),
+ SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE = _IOWR('U', 0x20, int),
+ SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct sndrv_hwdep_info),
+ SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE = _IOR('U', 0x30, int),
+ SNDRV_CTL_IOCTL_PCM_INFO = _IOWR('U', 0x31, struct sndrv_pcm_info),
+ SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE = _IOW('U', 0x32, int),
+ SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE = _IOWR('U', 0x40, int),
+ SNDRV_CTL_IOCTL_RAWMIDI_INFO = _IOWR('U', 0x41, struct sndrv_rawmidi_info),
+ SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE = _IOW('U', 0x42, int),
+ SNDRV_CTL_IOCTL_POWER = _IOWR('U', 0xd0, int),
+ SNDRV_CTL_IOCTL_POWER_STATE = _IOR('U', 0xd1, int),
+};
+
+/*
+ * Read interface.
+ */
+
+enum sndrv_ctl_event_type {
+ SNDRV_CTL_EVENT_ELEM = 0,
+ SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM,
+};
+
+#define SNDRV_CTL_EVENT_MASK_VALUE (1<<0) /* element value was changed */
+#define SNDRV_CTL_EVENT_MASK_INFO (1<<1) /* element info was changed */
+#define SNDRV_CTL_EVENT_MASK_ADD (1<<2) /* element was added */
+#define SNDRV_CTL_EVENT_MASK_REMOVE (~0U) /* element was removed */
+
+struct sndrv_ctl_event {
+ enum sndrv_ctl_event_type type; /* event type - SNDRV_CTL_EVENT_* */
+ union {
+ struct {
+ unsigned int mask;
+ struct sndrv_ctl_elem_id id;
+ } elem;
+ unsigned char data8[60];
+ } data;
+};
+
+/*
+ * Control names
+ */
+
+#define SNDRV_CTL_NAME_NONE ""
+#define SNDRV_CTL_NAME_PLAYBACK "Playback "
+#define SNDRV_CTL_NAME_CAPTURE "Capture "
+
+#define SNDRV_CTL_NAME_IEC958_NONE ""
+#define SNDRV_CTL_NAME_IEC958_SWITCH "Switch"
+#define SNDRV_CTL_NAME_IEC958_VOLUME "Volume"
+#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default"
+#define SNDRV_CTL_NAME_IEC958_MASK "Mask"
+#define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask"
+#define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask"
+#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream"
+#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what
+
+/*
+ *
+ */
+
+struct sndrv_xferv {
+ const struct iovec *vector;
+ unsigned long count;
+};
+
+enum {
+ SNDRV_IOCTL_READV = _IOW('K', 0x00, struct sndrv_xferv),
+ SNDRV_IOCTL_WRITEV = _IOW('K', 0x01, struct sndrv_xferv),
+};
+
+#endif /* __SOUND_ASOUND_H */
diff --git a/include/sound/asound_fm.h b/include/sound/asound_fm.h
new file mode 100644
index 0000000..b0da677
--- /dev/null
+++ b/include/sound/asound_fm.h
@@ -0,0 +1,115 @@
+#ifndef __SOUND_ASOUND_FM_H
+#define __SOUND_ASOUND_FM_H
+
+/*
+ * Advanced Linux Sound Architecture - ALSA
+ *
+ * Interface file between ALSA driver & user space
+ * Copyright (c) 1994-98 by Jaroslav Kysela <perex@suse.cz>,
+ * 4Front Technologies
+ *
+ * Direct FM 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
+ *
+ */
+
+#define SNDRV_DM_FM_MODE_OPL2 0x00
+#define SNDRV_DM_FM_MODE_OPL3 0x01
+
+typedef struct snd_dm_fm_info {
+ unsigned char fm_mode; /* OPL mode, see SNDRV_DM_FM_MODE_XXX */
+ unsigned char rhythm; /* percussion mode flag */
+} snd_dm_fm_info_t;
+
+/*
+ * Data structure composing an FM "note" or sound event.
+ */
+
+typedef struct snd_dm_fm_voice {
+ unsigned char op; /* operator cell (0 or 1) */
+ unsigned char voice; /* FM voice (0 to 17) */
+
+ unsigned char am; /* amplitude modulation */
+ unsigned char vibrato; /* vibrato effect */
+ unsigned char do_sustain; /* sustain phase */
+ unsigned char kbd_scale; /* keyboard scaling */
+ unsigned char harmonic; /* 4 bits: harmonic and multiplier */
+ unsigned char scale_level; /* 2 bits: decrease output freq rises */
+ unsigned char volume; /* 6 bits: volume */
+
+ unsigned char attack; /* 4 bits: attack rate */
+ unsigned char decay; /* 4 bits: decay rate */
+ unsigned char sustain; /* 4 bits: sustain level */
+ unsigned char release; /* 4 bits: release rate */
+
+ unsigned char feedback; /* 3 bits: feedback for op0 */
+ unsigned char connection; /* 0 for serial, 1 for parallel */
+ unsigned char left; /* stereo left */
+ unsigned char right; /* stereo right */
+ unsigned char waveform; /* 3 bits: waveform shape */
+} snd_dm_fm_voice_t;
+
+/*
+ * This describes an FM note by its voice, octave, frequency number (10bit)
+ * and key on/off.
+ */
+
+typedef struct snd_dm_fm_note {
+ unsigned char voice; /* 0-17 voice channel */
+ unsigned char octave; /* 3 bits: what octave to play */
+ unsigned int fnum; /* 10 bits: frequency number */
+ unsigned char key_on; /* set for active, clear for silent */
+} snd_dm_fm_note_t;
+
+/*
+ * FM parameters that apply globally to all voices, and thus are not "notes"
+ */
+
+typedef struct snd_dm_fm_params {
+ unsigned char am_depth; /* amplitude modulation depth (1=hi) */
+ unsigned char vib_depth; /* vibrato depth (1=hi) */
+ unsigned char kbd_split; /* keyboard split */
+ unsigned char rhythm; /* percussion mode select */
+
+ /* This block is the percussion instrument data */
+ unsigned char bass;
+ unsigned char snare;
+ unsigned char tomtom;
+ unsigned char cymbal;
+ unsigned char hihat;
+} snd_dm_fm_params_t;
+
+/*
+ * FM mode ioctl settings
+ */
+
+#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, snd_dm_fm_info_t)
+#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21)
+#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, snd_dm_fm_note_t)
+#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, snd_dm_fm_voice_t)
+#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, snd_dm_fm_params_t)
+#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int)
+/* for OPL3 only */
+#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int)
+
+#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
+#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
+#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
+#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
+#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
+#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
+
+#endif /* __SOUND_ASOUND_FM_H */
diff --git a/include/sound/asoundef.h b/include/sound/asoundef.h
new file mode 100644
index 0000000..58c9ef3
--- /dev/null
+++ b/include/sound/asoundef.h
@@ -0,0 +1,227 @@
+#ifndef __SOUND_ASOUNDEF_H
+#define __SOUND_ASOUNDEF_H
+
+/*
+ * Advanced Linux Sound Architecture - ALSA - Driver
+ * Copyright (c) 1994-2000 by Jaroslav Kysela <perex@suse.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_EXPERIMENTAL 0x40
+#define IEC958_AES1_CON_SOLIDMEM_MASK 0x0f
+#define IEC958_AES1_CON_SOLIDMEM_ID 0x08
+#define IEC958_AES1_CON_BROADCAST1_MASK 0x07
+#define IEC958_AES1_CON_BROADCAST1_ID 0x04
+#define IEC958_AES1_CON_DIGDIGCONV_MASK 0x07
+#define IEC958_AES1_CON_DIGDIGCONV_ID 0x02
+#define IEC958_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
+#define IEC958_AES1_CON_ADC_COPYRIGHT_ID 0x06
+#define IEC958_AES1_CON_ADC_MASK 0x1f
+#define IEC958_AES1_CON_ADC_ID 0x16
+#define IEC958_AES1_CON_BROADCAST2_MASK 0x0f
+#define IEC958_AES1_CON_BROADCAST2_ID 0x0e
+#define IEC958_AES1_CON_LASEROPT_MASK 0x07
+#define IEC958_AES1_CON_LASEROPT_ID 0x01
+#define IEC958_AES1_CON_MUSICAL_MASK 0x07
+#define IEC958_AES1_CON_MUSICAL_ID 0x05
+#define IEC958_AES1_CON_MAGNETIC_MASK 0x07
+#define IEC958_AES1_CON_MAGNETIC_ID 0x03
+#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_PCM_CODER (IEC958_AES1_CON_DIGDIGCONV_ID|0x00)
+#define IEC958_AES1_CON_SAMPLER (IEC958_AES1_CON_DIGDIGCONV_ID|0x20)
+#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_SYNTHESIZER (IEC958_AES1_CON_MUSICAL_ID|0x00)
+#define IEC958_AES1_CON_MICROPHONE (IEC958_AES1_CON_MUSICAL_ID|0x08)
+#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_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_48000 (2<<0) /* 48kHz */
+#define IEC958_AES3_CON_FS_32000 (3<<0) /* 32kHz */
+#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 */
+
+/*****************************************************************************
+ * *
+ * 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/control.h b/include/sound/control.h
new file mode 100644
index 0000000..7b9444c
--- /dev/null
+++ b/include/sound/control.h
@@ -0,0 +1,162 @@
+#ifndef __SOUND_CONTROL_H
+#define __SOUND_CONTROL_H
+
+/*
+ * Header file for control interface
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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>
+
+typedef struct sndrv_aes_iec958 snd_aes_iec958_t;
+typedef struct sndrv_ctl_card_info snd_ctl_card_info_t;
+typedef enum sndrv_ctl_elem_type snd_ctl_elem_type_t;
+typedef enum sndrv_ctl_elem_iface snd_ctl_elem_iface_t;
+typedef struct sndrv_ctl_elem_id snd_ctl_elem_id_t;
+typedef struct sndrv_ctl_elem_list snd_ctl_elem_list_t;
+typedef struct sndrv_ctl_elem_info snd_ctl_elem_info_t;
+typedef struct sndrv_ctl_elem_value snd_ctl_elem_value_t;
+typedef enum sndrv_ctl_event_type snd_ctl_event_type_t;
+typedef struct sndrv_ctl_event snd_ctl_event_t;
+
+#define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
+
+typedef int (snd_kcontrol_info_t) (snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo);
+typedef int (snd_kcontrol_get_t) (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+typedef int (snd_kcontrol_put_t) (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+
+typedef struct _snd_kcontrol_new {
+ snd_ctl_elem_iface_t iface; /* interface identifier */
+ unsigned int device; /* device/client number */
+ unsigned int subdevice; /* subdevice (substream) number */
+ 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;
+ unsigned long private_value;
+} snd_kcontrol_new_t;
+
+typedef struct _snd_kcontrol_volatile {
+ snd_ctl_file_t *owner; /* locked */
+ pid_t owner_pid;
+ unsigned int access; /* access rights */
+} snd_kcontrol_volatile_t;
+
+struct _snd_kcontrol {
+ struct list_head list; /* list of controls */
+ snd_ctl_elem_id_t id;
+ unsigned int count; /* count of same elements */
+ snd_kcontrol_info_t *info;
+ snd_kcontrol_get_t *get;
+ snd_kcontrol_put_t *put;
+ unsigned long private_value;
+ void *private_data;
+ void (*private_free)(snd_kcontrol_t *kcontrol);
+ snd_kcontrol_volatile_t vd[0]; /* volatile data */
+};
+
+#define snd_kcontrol(n) list_entry(n, snd_kcontrol_t, list)
+
+typedef struct _snd_kctl_event {
+ struct list_head list; /* list of events */
+ snd_ctl_elem_id_t id;
+ unsigned int mask;
+} snd_kctl_event_t;
+
+#define snd_kctl_event(n) list_entry(n, snd_kctl_event_t, list)
+
+struct _snd_ctl_file {
+ struct list_head list; /* list of all control files */
+ snd_card_t *card;
+ pid_t pid;
+ int prefer_pcm_subdevice;
+ int prefer_rawmidi_subdevice;
+ 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, snd_ctl_file_t, list)
+
+typedef int (*snd_kctl_ioctl_func_t) (snd_card_t * card,
+ snd_ctl_file_t * control,
+ unsigned int cmd, unsigned long arg);
+
+void snd_ctl_notify(snd_card_t * card, unsigned int mask, snd_ctl_elem_id_t * id);
+
+snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * kcontrol, unsigned int access);
+snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * kcontrolnew, void * private_data);
+void snd_ctl_free_one(snd_kcontrol_t * kcontrol);
+int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol);
+int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol);
+int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id);
+int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id);
+snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid);
+snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id);
+
+int snd_ctl_create(snd_card_t *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_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control);
+int snd_ctl_elem_write(snd_card_t *card, snd_ctl_file_t *file, snd_ctl_elem_value_t *control);
+
+static inline unsigned int snd_ctl_get_ioffnum(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+{
+ return id->numid - kctl->id.numid;
+}
+
+static inline unsigned int snd_ctl_get_ioffidx(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+{
+ return id->index - kctl->id.index;
+}
+
+static inline unsigned int snd_ctl_get_ioff(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+{
+ if (id->numid) {
+ return snd_ctl_get_ioffnum(kctl, id);
+ } else {
+ return snd_ctl_get_ioffidx(kctl, id);
+ }
+}
+
+static inline snd_ctl_elem_id_t *snd_ctl_build_ioff(snd_ctl_elem_id_t *dst_id,
+ snd_kcontrol_t *src_kctl,
+ unsigned int offset)
+{
+ *dst_id = src_kctl->id;
+ dst_id->index += offset;
+ dst_id->numid += offset;
+ return dst_id;
+}
+
+#endif /* __SOUND_CONTROL_H */
diff --git a/include/sound/core.h b/include/sound/core.h
new file mode 100644
index 0000000..9117c23
--- /dev/null
+++ b/include/sound/core.h
@@ -0,0 +1,502 @@
+#ifndef __SOUND_CORE_H
+#define __SOUND_CORE_H
+
+/*
+ * Main header file for the ALSA driver
+ * Copyright (c) 1994-2001 by Jaroslav Kysela <perex@suse.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/sched.h> /* wake_up() */
+#include <asm/semaphore.h> /* struct semaphore */
+#include <linux/rwsem.h> /* struct rw_semaphore */
+#include <linux/workqueue.h> /* struct workqueue_struct */
+#include <linux/pm.h> /* pm_message_t */
+
+/* Typedef's */
+typedef struct timespec snd_timestamp_t;
+typedef struct sndrv_interval snd_interval_t;
+typedef enum sndrv_card_type snd_card_type;
+typedef struct sndrv_xferi snd_xferi_t;
+typedef struct sndrv_xfern snd_xfern_t;
+typedef struct sndrv_xferv snd_xferv_t;
+
+/* forward declarations */
+#ifdef CONFIG_PCI
+struct pci_dev;
+#endif
+#ifdef CONFIG_SBUS
+struct sbus_dev;
+#endif
+
+/* device allocation stuff */
+
+#define SNDRV_DEV_TYPE_RANGE_SIZE 0x1000
+
+typedef enum {
+ SNDRV_DEV_TOPLEVEL = (0*SNDRV_DEV_TYPE_RANGE_SIZE),
+ SNDRV_DEV_CONTROL,
+ SNDRV_DEV_LOWLEVEL_PRE,
+ SNDRV_DEV_LOWLEVEL_NORMAL = (1*SNDRV_DEV_TYPE_RANGE_SIZE),
+ SNDRV_DEV_PCM,
+ SNDRV_DEV_RAWMIDI,
+ SNDRV_DEV_TIMER,
+ SNDRV_DEV_SEQUENCER,
+ SNDRV_DEV_HWDEP,
+ SNDRV_DEV_INFO,
+ SNDRV_DEV_BUS,
+ SNDRV_DEV_CODEC,
+ SNDRV_DEV_LOWLEVEL = (2*SNDRV_DEV_TYPE_RANGE_SIZE)
+} snd_device_type_t;
+
+typedef enum {
+ SNDRV_DEV_BUILD,
+ SNDRV_DEV_REGISTERED,
+ SNDRV_DEV_DISCONNECTED
+} snd_device_state_t;
+
+typedef enum {
+ SNDRV_DEV_CMD_PRE = 0,
+ SNDRV_DEV_CMD_NORMAL = 1,
+ SNDRV_DEV_CMD_POST = 2
+} snd_device_cmd_t;
+
+typedef struct _snd_card snd_card_t;
+typedef struct _snd_device snd_device_t;
+
+typedef int (snd_dev_free_t)(snd_device_t *device);
+typedef int (snd_dev_register_t)(snd_device_t *device);
+typedef int (snd_dev_disconnect_t)(snd_device_t *device);
+typedef int (snd_dev_unregister_t)(snd_device_t *device);
+
+typedef struct {
+ snd_dev_free_t *dev_free;
+ snd_dev_register_t *dev_register;
+ snd_dev_disconnect_t *dev_disconnect;
+ snd_dev_unregister_t *dev_unregister;
+} snd_device_ops_t;
+
+struct _snd_device {
+ struct list_head list; /* list of registered devices */
+ snd_card_t *card; /* card which holds this device */
+ snd_device_state_t state; /* state of the device */
+ snd_device_type_t type; /* device type */
+ void *device_data; /* device structure */
+ snd_device_ops_t *ops; /* operations */
+};
+
+#define snd_device(n) list_entry(n, snd_device_t, list)
+
+/* various typedefs */
+
+typedef struct snd_info_entry snd_info_entry_t;
+typedef struct _snd_pcm snd_pcm_t;
+typedef struct _snd_pcm_str snd_pcm_str_t;
+typedef struct _snd_pcm_substream snd_pcm_substream_t;
+typedef struct _snd_mixer snd_kmixer_t;
+typedef struct _snd_rawmidi snd_rawmidi_t;
+typedef struct _snd_ctl_file snd_ctl_file_t;
+typedef struct _snd_kcontrol snd_kcontrol_t;
+typedef struct _snd_timer snd_timer_t;
+typedef struct _snd_timer_instance snd_timer_instance_t;
+typedef struct _snd_hwdep snd_hwdep_t;
+#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+typedef struct _snd_oss_mixer snd_mixer_oss_t;
+#endif
+
+/* monitor files for graceful shutdown (hotplug) */
+
+struct snd_monitor_file {
+ struct file *file;
+ struct snd_monitor_file *next;
+};
+
+struct snd_shutdown_f_ops; /* define it later */
+
+/* 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[80]; /* card components delimited with space */
+
+ struct module *module; /* top-level module */
+
+ void *private_data; /* private data for soundcard */
+ void (*private_free) (snd_card_t *card); /* callback for freeing of private data */
+
+ struct list_head devices; /* devices */
+
+ 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 */
+
+ snd_info_entry_t *proc_root; /* root for soundcard specific files */
+ snd_info_entry_t *proc_id; /* the card id */
+ struct proc_dir_entry *proc_root_link; /* number link to real id */
+
+ struct snd_monitor_file *files; /* 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 */
+ wait_queue_head_t shutdown_sleep;
+ struct work_struct free_workq; /* for free in workqueue */
+ struct device *dev;
+
+#ifdef CONFIG_PM
+ int (*pm_suspend)(snd_card_t *card, pm_message_t state);
+ int (*pm_resume)(snd_card_t *card);
+ void *pm_private_data;
+ unsigned int power_state; /* power state */
+ struct semaphore power_lock; /* power lock */
+ wait_queue_head_t power_sleep;
+#ifdef CONFIG_SND_GENERIC_PM
+ struct snd_generic_device *pm_dev; /* for ISA */
+#endif
+#endif
+
+#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+ snd_mixer_oss_t *mixer_oss;
+ int mixer_oss_change_count;
+#endif
+};
+
+#ifdef CONFIG_PM
+static inline void snd_power_lock(snd_card_t *card)
+{
+ down(&card->power_lock);
+}
+
+static inline void snd_power_unlock(snd_card_t *card)
+{
+ up(&card->power_lock);
+}
+
+int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file);
+
+static inline unsigned int snd_power_get_state(snd_card_t *card)
+{
+ return card->power_state;
+}
+
+static inline void snd_power_change_state(snd_card_t *card, unsigned int state)
+{
+ card->power_state = state;
+ wake_up(&card->power_sleep);
+}
+int snd_card_set_pm_callback(snd_card_t *card,
+ int (*suspend)(snd_card_t *, pm_message_t),
+ int (*resume)(snd_card_t *),
+ void *private_data);
+int snd_card_set_generic_pm_callback(snd_card_t *card,
+ int (*suspend)(snd_card_t *, pm_message_t),
+ int (*resume)(snd_card_t *),
+ void *private_data);
+#define snd_card_set_isa_pm_callback(card,suspend,resume,data) \
+ snd_card_set_generic_pm_callback(card, suspend, resume, data)
+struct pci_dev;
+int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state);
+int snd_card_pci_resume(struct pci_dev *dev);
+#define SND_PCI_PM_CALLBACKS \
+ .suspend = snd_card_pci_suspend, .resume = snd_card_pci_resume
+
+#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(snd_card_t *card, unsigned int state, struct file *file) { return 0; }
+#define snd_power_get_state(card) SNDRV_CTL_POWER_D0
+#define snd_power_change_state(card, state) do { (void)(card); } while (0)
+#define snd_card_set_pm_callback(card,suspend,resume,data)
+#define snd_card_set_generic_pm_callback(card,suspend,resume,data)
+#define snd_card_set_isa_pm_callback(card,suspend,resume,data)
+#define SND_PCI_PM_CALLBACKS
+
+#endif /* CONFIG_PM */
+
+/* device.c */
+
+struct _snd_minor {
+ struct list_head list; /* list of all minors per card */
+ int number; /* minor number */
+ int device; /* device number */
+ const char *comment; /* for /proc/asound/devices */
+ struct file_operations *f_ops; /* file operations */
+ char name[0]; /* device name (keep at the end of structure) */
+};
+
+typedef struct _snd_minor snd_minor_t;
+
+/* sound.c */
+
+extern int snd_ecards_limit;
+
+void snd_request_card(int card);
+
+int snd_register_device(int type, snd_card_t *card, int dev, snd_minor_t *reg, const char *name);
+int snd_unregister_device(int type, snd_card_t *card, int dev);
+
+#ifdef CONFIG_SND_OSSEMUL
+int snd_register_oss_device(int type, snd_card_t *card, int dev, snd_minor_t *reg, const char *name);
+int snd_unregister_oss_device(int type, snd_card_t *card, int dev);
+#endif
+
+int snd_minor_info_init(void);
+int snd_minor_info_done(void);
+
+/* sound_oss.c */
+
+#ifdef CONFIG_SND_OSSEMUL
+int snd_minor_info_oss_init(void);
+int snd_minor_info_oss_done(void);
+int snd_oss_init_module(void);
+#else
+#define snd_minor_info_oss_init() /*NOP*/
+#define snd_minor_info_oss_done() /*NOP*/
+#define snd_oss_init_module() 0
+#endif
+
+/* memory.c */
+
+#ifdef CONFIG_SND_DEBUG_MEMORY
+void snd_memory_init(void);
+void snd_memory_done(void);
+int snd_memory_info_init(void);
+int snd_memory_info_done(void);
+void *snd_hidden_kmalloc(size_t size, int flags);
+void *snd_hidden_kcalloc(size_t n, size_t size, int flags);
+void snd_hidden_kfree(const void *obj);
+void *snd_hidden_vmalloc(unsigned long size);
+void snd_hidden_vfree(void *obj);
+#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
+#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
+#define kfree(obj) snd_hidden_kfree(obj)
+#define vmalloc(size) snd_hidden_vmalloc(size)
+#define vfree(obj) snd_hidden_vfree(obj)
+#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
+#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
+#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
+#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
+#else
+#define snd_memory_init() /*NOP*/
+#define snd_memory_done() /*NOP*/
+#define snd_memory_info_init() /*NOP*/
+#define snd_memory_info_done() /*NOP*/
+#define kmalloc_nocheck(size, flags) kmalloc(size, flags)
+#define vmalloc_nocheck(size) vmalloc(size)
+#define kfree_nocheck(obj) kfree(obj)
+#define vfree_nocheck(obj) vfree(obj)
+#endif
+char *snd_kmalloc_strdup(const char *string, int flags);
+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 unsigned int snd_cards_lock;
+extern snd_card_t *snd_cards[SNDRV_CARDS];
+extern rwlock_t snd_card_rwlock;
+#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)(snd_card_t *card, int cmd);
+#endif
+
+snd_card_t *snd_card_new(int idx, const char *id,
+ struct module *module, int extra_size);
+int snd_card_disconnect(snd_card_t *card);
+int snd_card_free(snd_card_t *card);
+int snd_card_free_in_thread(snd_card_t *card);
+int snd_card_register(snd_card_t *card);
+int snd_card_info_init(void);
+int snd_card_info_done(void);
+int snd_component_add(snd_card_t *card, const char *component);
+int snd_card_file_add(snd_card_t *card, struct file *file);
+int snd_card_file_remove(snd_card_t *card, struct file *file);
+
+#ifndef snd_card_set_dev
+#define snd_card_set_dev(card,devptr) ((card)->dev = (devptr))
+#endif
+
+/* device.c */
+
+int snd_device_new(snd_card_t *card, snd_device_type_t type,
+ void *device_data, snd_device_ops_t *ops);
+int snd_device_register(snd_card_t *card, void *device_data);
+int snd_device_register_all(snd_card_t *card);
+int snd_device_disconnect(snd_card_t *card, void *device_data);
+int snd_device_disconnect_all(snd_card_t *card);
+int snd_device_free(snd_card_t *card, void *device_data);
+int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd);
+
+/* isadma.c */
+
+#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);
+
+/* misc.c */
+
+int snd_task_name(struct task_struct *task, char *name, size_t size);
+#ifdef CONFIG_SND_VERBOSE_PRINTK
+void snd_verbose_printk(const char *file, int line, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
+void snd_verbose_printd(const char *file, int line, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+/* --- */
+
+#ifdef CONFIG_SND_VERBOSE_PRINTK
+/**
+ * snd_printk - printk wrapper
+ * @fmt: format string
+ *
+ * Works like print() but prints the file and the line of the caller
+ * when configured with CONFIG_SND_VERBOSE_PRINTK.
+ */
+#define snd_printk(fmt, args...) \
+ snd_verbose_printk(__FILE__, __LINE__, fmt ,##args)
+#else
+#define snd_printk(fmt, args...) \
+ printk(fmt ,##args)
+#endif
+
+#ifdef CONFIG_SND_DEBUG
+
+#define __ASTRING__(x) #x
+
+#ifdef CONFIG_SND_VERBOSE_PRINTK
+/**
+ * snd_printd - debug printk
+ * @format: format string
+ *
+ * Compiled only when Works like snd_printk() for debugging purpose.
+ * Ignored when CONFIG_SND_DEBUG is not set.
+ */
+#define snd_printd(fmt, args...) \
+ snd_verbose_printd(__FILE__, __LINE__, fmt ,##args)
+#else
+#define snd_printd(fmt, args...) \
+ printk(fmt ,##args)
+#endif
+/**
+ * snd_assert - run-time assersion macro
+ * @expr: expression
+ * @args...: the action
+ *
+ * This macro checks the expression in run-time and invokes the commands
+ * given in the rest arguments if the assertion is failed.
+ * When CONFIG_SND_DEBUG is not set, the expression is executed but
+ * not checked.
+ */
+#define snd_assert(expr, args...) do {\
+ if (unlikely(!(expr))) { \
+ snd_printk(KERN_ERR "BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
+ args;\
+ }\
+} while (0)
+/**
+ * snd_runtime_check - run-time assersion macro
+ * @expr: expression
+ * @args...: the action
+ *
+ * This macro checks the expression in run-time and invokes the commands
+ * given in the rest arguments if the assertion is failed.
+ * Unlike snd_assert(), the action commands are executed even if
+ * CONFIG_SND_DEBUG is not set but without any error messages.
+ */
+#define snd_runtime_check(expr, args...) do {\
+ if (unlikely(!(expr))) { \
+ snd_printk(KERN_ERR "ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
+ args;\
+ }\
+} while (0)
+
+#else /* !CONFIG_SND_DEBUG */
+
+#define snd_printd(fmt, args...) /* nothing */
+#define snd_assert(expr, args...) (void)(expr)
+#define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0)
+
+#endif /* CONFIG_SND_DEBUG */
+
+#ifdef CONFIG_SND_DEBUG_DETECT
+/**
+ * snd_printdd - debug printk
+ * @format: format string
+ *
+ * Compiled only when Works like snd_printk() for debugging purpose.
+ * Ignored when CONFIG_SND_DEBUG_DETECT is not set.
+ */
+#define snd_printdd(format, args...) snd_printk(format, ##args)
+#else
+#define snd_printdd(format, args...) /* nothing */
+#endif
+
+#define snd_BUG() snd_assert(0, )
+
+
+static inline void snd_timestamp_now(struct timespec *tstamp, int timespec)
+{
+ struct timeval val;
+ /* FIXME: use a linear time source */
+ do_gettimeofday(&val);
+ tstamp->tv_sec = val.tv_sec;
+ tstamp->tv_nsec = val.tv_usec;
+ if (timespec)
+ tstamp->tv_nsec *= 1000L;
+}
+
+static inline void snd_timestamp_zero(struct timespec *tstamp)
+{
+ tstamp->tv_sec = 0;
+ tstamp->tv_nsec = 0;
+}
+
+static inline int snd_timestamp_null(struct timespec *tstamp)
+{
+ return tstamp->tv_sec == 0 && tstamp->tv_nsec == 0;
+}
+
+#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)
+#ifndef gameport_set_dev_parent
+#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
+#endif
+
+#endif /* __SOUND_CORE_H */
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h
new file mode 100644
index 0000000..d7f9082
--- /dev/null
+++ b/include/sound/cs4231.h
@@ -0,0 +1,366 @@
+#ifndef __SOUND_CS4231_H
+#define __SOUND_CS4231_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "control.h"
+#include "pcm.h"
+#include "timer.h"
+
+#ifdef CONFIG_SBUS
+#define SBUS_SUPPORT
+#include <asm/sbus.h>
+#endif
+
+#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
+#define EBUS_SUPPORT
+#include <linux/pci.h>
+#include <asm/ebus.h>
+#endif
+
+#if !defined(SBUS_SUPPORT) && !defined(EBUS_SUPPORT)
+#define LEGACY_SUPPORT
+#endif
+
+/* 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 /* miscellaneaous 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 CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */
+#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 */
+
+/* defines for codec.mode */
+
+#define CS4231_MODE_NONE 0x0000
+#define CS4231_MODE_PLAY 0x0001
+#define CS4231_MODE_RECORD 0x0002
+#define CS4231_MODE_TIMER 0x0004
+#define CS4231_MODE_OPEN (CS4231_MODE_PLAY|CS4231_MODE_RECORD|CS4231_MODE_TIMER)
+
+/* defines for codec.hardware */
+
+#define CS4231_HW_DETECT 0x0000 /* let CS4231 driver detect chip */
+#define CS4231_HW_DETECT3 0x0001 /* allow mode 3 */
+#define CS4231_HW_TYPE_MASK 0xff00 /* type mask */
+#define CS4231_HW_CS4231_MASK 0x0100 /* CS4231 serie */
+#define CS4231_HW_CS4231 0x0100 /* CS4231 chip */
+#define CS4231_HW_CS4231A 0x0101 /* CS4231A chip */
+#define CS4231_HW_AD1845 0x0102 /* AD1845 chip */
+#define CS4231_HW_CS4232_MASK 0x0200 /* CS4232 serie (has control ports) */
+#define CS4231_HW_CS4232 0x0200 /* CS4232 */
+#define CS4231_HW_CS4232A 0x0201 /* CS4232A */
+#define CS4231_HW_CS4236 0x0202 /* CS4236 */
+#define CS4231_HW_CS4236B_MASK 0x0400 /* CS4236B serie (has extended control regs) */
+#define CS4231_HW_CS4235 0x0400 /* CS4235 - Crystal Clear (tm) stereo enhancement */
+#define CS4231_HW_CS4236B 0x0401 /* CS4236B */
+#define CS4231_HW_CS4237B 0x0402 /* CS4237B - SRS 3D */
+#define CS4231_HW_CS4238B 0x0403 /* CS4238B - QSOUND 3D */
+#define CS4231_HW_CS4239 0x0404 /* CS4239 - Crystal Clear (tm) stereo enhancement */
+/* compatible, but clones */
+#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */
+#define CS4231_HW_OPL3SA2 0x1001 /* OPL3-SA2 chip */
+
+/* defines for codec.hwshare */
+#define CS4231_HWSHARE_IRQ (1<<0)
+#define CS4231_HWSHARE_DMA1 (1<<1)
+#define CS4231_HWSHARE_DMA2 (1<<2)
+
+typedef struct _snd_cs4231 cs4231_t;
+
+struct _snd_cs4231 {
+ unsigned long port; /* base i/o port */
+#ifdef LEGACY_SUPPORT
+ 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 */
+#endif
+ unsigned short version; /* version of CODEC chip */
+ unsigned short mode; /* see to CS4231_MODE_XXXX */
+ unsigned short hardware; /* see to CS4231_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 */
+
+#ifdef EBUS_SUPPORT
+ struct ebus_dma_info eb2c;
+ struct ebus_dma_info eb2p;
+#endif
+
+#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT)
+ union {
+#ifdef SBUS_SUPPORT
+ struct sbus_dev *sdev;
+#endif
+#ifdef EBUS_SUPPORT
+ struct pci_dev *pdev;
+#endif
+ } dev_u;
+ unsigned int p_periods_sent;
+ unsigned int c_periods_sent;
+#endif
+
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+ snd_pcm_substream_t *playback_substream;
+ snd_pcm_substream_t *capture_substream;
+ snd_timer_t *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;
+#ifdef LEGACY_SUPPORT
+ unsigned int p_dma_size;
+ unsigned int c_dma_size;
+#endif
+
+ spinlock_t reg_lock;
+ struct semaphore mce_mutex;
+ struct semaphore open_mutex;
+
+ int (*rate_constraint) (snd_pcm_runtime_t *runtime);
+ void (*set_playback_format) (cs4231_t *chip, snd_pcm_hw_params_t *hw_params, unsigned char pdfr);
+ void (*set_capture_format) (cs4231_t *chip, snd_pcm_hw_params_t *hw_params, unsigned char cdfr);
+ void (*trigger) (cs4231_t *chip, unsigned int what, int start);
+#ifdef CONFIG_PM
+ void (*suspend) (cs4231_t *chip);
+ void (*resume) (cs4231_t *chip);
+#endif
+ void *dma_private_data;
+#ifdef LEGACY_SUPPORT
+ int (*claim_dma) (cs4231_t *chip, void *dma_private_data, int dma);
+ int (*release_dma) (cs4231_t *chip, void *dma_private_data, int dma);
+#endif
+};
+
+/* exported functions */
+
+void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char val);
+unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg);
+void snd_cs4236_ext_out(cs4231_t *chip, unsigned char reg, unsigned char val);
+unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg);
+void snd_cs4231_mce_up(cs4231_t *chip);
+void snd_cs4231_mce_down(cs4231_t *chip);
+
+irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+const char *snd_cs4231_chip_id(cs4231_t *chip);
+
+int snd_cs4231_create(snd_card_t * card,
+ unsigned long port,
+ unsigned long cport,
+ int irq, int dma1, int dma2,
+ unsigned short hardware,
+ unsigned short hwshare,
+ cs4231_t ** rchip);
+int snd_cs4231_pcm(cs4231_t * chip, int device, snd_pcm_t **rpcm);
+int snd_cs4231_timer(cs4231_t * chip, int device, snd_timer_t **rtimer);
+int snd_cs4231_mixer(cs4231_t * chip);
+
+int snd_cs4236_create(snd_card_t * card,
+ unsigned long port,
+ unsigned long cport,
+ int irq, int dma1, int dma2,
+ unsigned short hardware,
+ unsigned short hwshare,
+ cs4231_t ** rchip);
+int snd_cs4236_pcm(cs4231_t * chip, int device, snd_pcm_t **rpcm);
+int snd_cs4236_mixer(cs4231_t * chip);
+
+/*
+ * mixer library
+ */
+
+#define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
+ .info = snd_cs4231_info_single, \
+ .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
+ .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
+
+int snd_cs4231_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
+int snd_cs4231_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_cs4231_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+
+#define CS4231_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_cs4231_info_double, \
+ .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
+ .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
+
+int snd_cs4231_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
+int snd_cs4231_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_cs4231_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+
+#endif /* __SOUND_CS4231_H */
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h
new file mode 100644
index 0000000..182dd27
--- /dev/null
+++ b/include/sound/cs46xx.h
@@ -0,0 +1,1756 @@
+#ifndef __SOUND_CS46XX_H
+#define __SOUND_CS46XX_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Cirrus Logic, Inc.
+ * Definitions for Cirrus Logic CS46xx 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 "pcm.h"
+#include "pcm-indirect.h"
+#include "rawmidi.h"
+#include "ac97_codec.h"
+#include "cs46xx_dsp_spos.h"
+
+#ifndef PCI_VENDOR_ID_CIRRUS
+#define PCI_VENDOR_ID_CIRRUS 0x1013
+#endif
+#ifndef PCI_DEVICE_ID_CIRRUS_4610
+#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
+#endif
+#ifndef PCI_DEVICE_ID_CIRRUS_4612
+#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
+#endif
+#ifndef PCI_DEVICE_ID_CIRRUS_4615
+#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
+#endif
+
+/*
+ * Direct registers
+ */
+
+/*
+ * The following define the offsets of the registers accessed via base address
+ * register zero on the CS46xx part.
+ */
+#define BA0_HISR 0x00000000
+#define BA0_HSR0 0x00000004
+#define BA0_HICR 0x00000008
+#define BA0_DMSR 0x00000100
+#define BA0_HSAR 0x00000110
+#define BA0_HDAR 0x00000114
+#define BA0_HDMR 0x00000118
+#define BA0_HDCR 0x0000011C
+#define BA0_PFMC 0x00000200
+#define BA0_PFCV1 0x00000204
+#define BA0_PFCV2 0x00000208
+#define BA0_PCICFG00 0x00000300
+#define BA0_PCICFG04 0x00000304
+#define BA0_PCICFG08 0x00000308
+#define BA0_PCICFG0C 0x0000030C
+#define BA0_PCICFG10 0x00000310
+#define BA0_PCICFG14 0x00000314
+#define BA0_PCICFG18 0x00000318
+#define BA0_PCICFG1C 0x0000031C
+#define BA0_PCICFG20 0x00000320
+#define BA0_PCICFG24 0x00000324
+#define BA0_PCICFG28 0x00000328
+#define BA0_PCICFG2C 0x0000032C
+#define BA0_PCICFG30 0x00000330
+#define BA0_PCICFG34 0x00000334
+#define BA0_PCICFG38 0x00000338
+#define BA0_PCICFG3C 0x0000033C
+#define BA0_CLKCR1 0x00000400
+#define BA0_CLKCR2 0x00000404
+#define BA0_PLLM 0x00000408
+#define BA0_PLLCC 0x0000040C
+#define BA0_FRR 0x00000410
+#define BA0_CFL1 0x00000414
+#define BA0_CFL2 0x00000418
+#define BA0_SERMC1 0x00000420
+#define BA0_SERMC2 0x00000424
+#define BA0_SERC1 0x00000428
+#define BA0_SERC2 0x0000042C
+#define BA0_SERC3 0x00000430
+#define BA0_SERC4 0x00000434
+#define BA0_SERC5 0x00000438
+#define BA0_SERBSP 0x0000043C
+#define BA0_SERBST 0x00000440
+#define BA0_SERBCM 0x00000444
+#define BA0_SERBAD 0x00000448
+#define BA0_SERBCF 0x0000044C
+#define BA0_SERBWP 0x00000450
+#define BA0_SERBRP 0x00000454
+#ifndef NO_CS4612
+#define BA0_ASER_FADDR 0x00000458
+#endif
+#define BA0_ACCTL 0x00000460
+#define BA0_ACSTS 0x00000464
+#define BA0_ACOSV 0x00000468
+#define BA0_ACCAD 0x0000046C
+#define BA0_ACCDA 0x00000470
+#define BA0_ACISV 0x00000474
+#define BA0_ACSAD 0x00000478
+#define BA0_ACSDA 0x0000047C
+#define BA0_JSPT 0x00000480
+#define BA0_JSCTL 0x00000484
+#define BA0_JSC1 0x00000488
+#define BA0_JSC2 0x0000048C
+#define BA0_MIDCR 0x00000490
+#define BA0_MIDSR 0x00000494
+#define BA0_MIDWP 0x00000498
+#define BA0_MIDRP 0x0000049C
+#define BA0_JSIO 0x000004A0
+#ifndef NO_CS4612
+#define BA0_ASER_MASTER 0x000004A4
+#endif
+#define BA0_CFGI 0x000004B0
+#define BA0_SSVID 0x000004B4
+#define BA0_GPIOR 0x000004B8
+#ifndef NO_CS4612
+#define BA0_EGPIODR 0x000004BC
+#define BA0_EGPIOPTR 0x000004C0
+#define BA0_EGPIOTR 0x000004C4
+#define BA0_EGPIOWR 0x000004C8
+#define BA0_EGPIOSR 0x000004CC
+#define BA0_SERC6 0x000004D0
+#define BA0_SERC7 0x000004D4
+#define BA0_SERACC 0x000004D8
+#define BA0_ACCTL2 0x000004E0
+#define BA0_ACSTS2 0x000004E4
+#define BA0_ACOSV2 0x000004E8
+#define BA0_ACCAD2 0x000004EC
+#define BA0_ACCDA2 0x000004F0
+#define BA0_ACISV2 0x000004F4
+#define BA0_ACSAD2 0x000004F8
+#define BA0_ACSDA2 0x000004FC
+#define BA0_IOTAC0 0x00000500
+#define BA0_IOTAC1 0x00000504
+#define BA0_IOTAC2 0x00000508
+#define BA0_IOTAC3 0x0000050C
+#define BA0_IOTAC4 0x00000510
+#define BA0_IOTAC5 0x00000514
+#define BA0_IOTAC6 0x00000518
+#define BA0_IOTAC7 0x0000051C
+#define BA0_IOTAC8 0x00000520
+#define BA0_IOTAC9 0x00000524
+#define BA0_IOTAC10 0x00000528
+#define BA0_IOTAC11 0x0000052C
+#define BA0_IOTFR0 0x00000540
+#define BA0_IOTFR1 0x00000544
+#define BA0_IOTFR2 0x00000548
+#define BA0_IOTFR3 0x0000054C
+#define BA0_IOTFR4 0x00000550
+#define BA0_IOTFR5 0x00000554
+#define BA0_IOTFR6 0x00000558
+#define BA0_IOTFR7 0x0000055C
+#define BA0_IOTFIFO 0x00000580
+#define BA0_IOTRRD 0x00000584
+#define BA0_IOTFP 0x00000588
+#define BA0_IOTCR 0x0000058C
+#define BA0_DPCID 0x00000590
+#define BA0_DPCIA 0x00000594
+#define BA0_DPCIC 0x00000598
+#define BA0_PCPCIR 0x00000600
+#define BA0_PCPCIG 0x00000604
+#define BA0_PCPCIEN 0x00000608
+#define BA0_EPCIPMC 0x00000610
+#endif
+
+/*
+ * The following define the offsets of the registers and memories accessed via
+ * base address register one on the CS46xx part.
+ */
+#define BA1_SP_DMEM0 0x00000000
+#define BA1_SP_DMEM1 0x00010000
+#define BA1_SP_PMEM 0x00020000
+#define BA1_SP_REG 0x00030000
+#define BA1_SPCR 0x00030000
+#define BA1_DREG 0x00030004
+#define BA1_DSRWP 0x00030008
+#define BA1_TWPR 0x0003000C
+#define BA1_SPWR 0x00030010
+#define BA1_SPIR 0x00030014
+#define BA1_FGR1 0x00030020
+#define BA1_SPCS 0x00030028
+#define BA1_SDSR 0x0003002C
+#define BA1_FRMT 0x00030030
+#define BA1_FRCC 0x00030034
+#define BA1_FRSC 0x00030038
+#define BA1_OMNI_MEM 0x000E0000
+
+
+/*
+ * The following defines are for the flags in the host interrupt status
+ * register.
+ */
+#define HISR_VC_MASK 0x0000FFFF
+#define HISR_VC0 0x00000001
+#define HISR_VC1 0x00000002
+#define HISR_VC2 0x00000004
+#define HISR_VC3 0x00000008
+#define HISR_VC4 0x00000010
+#define HISR_VC5 0x00000020
+#define HISR_VC6 0x00000040
+#define HISR_VC7 0x00000080
+#define HISR_VC8 0x00000100
+#define HISR_VC9 0x00000200
+#define HISR_VC10 0x00000400
+#define HISR_VC11 0x00000800
+#define HISR_VC12 0x00001000
+#define HISR_VC13 0x00002000
+#define HISR_VC14 0x00004000
+#define HISR_VC15 0x00008000
+#define HISR_INT0 0x00010000
+#define HISR_INT1 0x00020000
+#define HISR_DMAI 0x00040000
+#define HISR_FROVR 0x00080000
+#define HISR_MIDI 0x00100000
+#ifdef NO_CS4612
+#define HISR_RESERVED 0x0FE00000
+#else
+#define HISR_SBINT 0x00200000
+#define HISR_RESERVED 0x0FC00000
+#endif
+#define HISR_H0P 0x40000000
+#define HISR_INTENA 0x80000000
+
+/*
+ * The following defines are for the flags in the host signal register 0.
+ */
+#define HSR0_VC_MASK 0xFFFFFFFF
+#define HSR0_VC16 0x00000001
+#define HSR0_VC17 0x00000002
+#define HSR0_VC18 0x00000004
+#define HSR0_VC19 0x00000008
+#define HSR0_VC20 0x00000010
+#define HSR0_VC21 0x00000020
+#define HSR0_VC22 0x00000040
+#define HSR0_VC23 0x00000080
+#define HSR0_VC24 0x00000100
+#define HSR0_VC25 0x00000200
+#define HSR0_VC26 0x00000400
+#define HSR0_VC27 0x00000800
+#define HSR0_VC28 0x00001000
+#define HSR0_VC29 0x00002000
+#define HSR0_VC30 0x00004000
+#define HSR0_VC31 0x00008000
+#define HSR0_VC32 0x00010000
+#define HSR0_VC33 0x00020000
+#define HSR0_VC34 0x00040000
+#define HSR0_VC35 0x00080000
+#define HSR0_VC36 0x00100000
+#define HSR0_VC37 0x00200000
+#define HSR0_VC38 0x00400000
+#define HSR0_VC39 0x00800000
+#define HSR0_VC40 0x01000000
+#define HSR0_VC41 0x02000000
+#define HSR0_VC42 0x04000000
+#define HSR0_VC43 0x08000000
+#define HSR0_VC44 0x10000000
+#define HSR0_VC45 0x20000000
+#define HSR0_VC46 0x40000000
+#define HSR0_VC47 0x80000000
+
+/*
+ * The following defines are for the flags in the host interrupt control
+ * register.
+ */
+#define HICR_IEV 0x00000001
+#define HICR_CHGM 0x00000002
+
+/*
+ * The following defines are for the flags in the DMA status register.
+ */
+#define DMSR_HP 0x00000001
+#define DMSR_HR 0x00000002
+#define DMSR_SP 0x00000004
+#define DMSR_SR 0x00000008
+
+/*
+ * The following defines are for the flags in the host DMA source address
+ * register.
+ */
+#define HSAR_HOST_ADDR_MASK 0xFFFFFFFF
+#define HSAR_DSP_ADDR_MASK 0x0000FFFF
+#define HSAR_MEMID_MASK 0x000F0000
+#define HSAR_MEMID_SP_DMEM0 0x00000000
+#define HSAR_MEMID_SP_DMEM1 0x00010000
+#define HSAR_MEMID_SP_PMEM 0x00020000
+#define HSAR_MEMID_SP_DEBUG 0x00030000
+#define HSAR_MEMID_OMNI_MEM 0x000E0000
+#define HSAR_END 0x40000000
+#define HSAR_ERR 0x80000000
+
+/*
+ * The following defines are for the flags in the host DMA destination address
+ * register.
+ */
+#define HDAR_HOST_ADDR_MASK 0xFFFFFFFF
+#define HDAR_DSP_ADDR_MASK 0x0000FFFF
+#define HDAR_MEMID_MASK 0x000F0000
+#define HDAR_MEMID_SP_DMEM0 0x00000000
+#define HDAR_MEMID_SP_DMEM1 0x00010000
+#define HDAR_MEMID_SP_PMEM 0x00020000
+#define HDAR_MEMID_SP_DEBUG 0x00030000
+#define HDAR_MEMID_OMNI_MEM 0x000E0000
+#define HDAR_END 0x40000000
+#define HDAR_ERR 0x80000000
+
+/*
+ * The following defines are for the flags in the host DMA control register.
+ */
+#define HDMR_AC_MASK 0x0000F000
+#define HDMR_AC_8_16 0x00001000
+#define HDMR_AC_M_S 0x00002000
+#define HDMR_AC_B_L 0x00004000
+#define HDMR_AC_S_U 0x00008000
+
+/*
+ * The following defines are for the flags in the host DMA control register.
+ */
+#define HDCR_COUNT_MASK 0x000003FF
+#define HDCR_DONE 0x00004000
+#define HDCR_OPT 0x00008000
+#define HDCR_WBD 0x00400000
+#define HDCR_WBS 0x00800000
+#define HDCR_DMS_MASK 0x07000000
+#define HDCR_DMS_LINEAR 0x00000000
+#define HDCR_DMS_16_DWORDS 0x01000000
+#define HDCR_DMS_32_DWORDS 0x02000000
+#define HDCR_DMS_64_DWORDS 0x03000000
+#define HDCR_DMS_128_DWORDS 0x04000000
+#define HDCR_DMS_256_DWORDS 0x05000000
+#define HDCR_DMS_512_DWORDS 0x06000000
+#define HDCR_DMS_1024_DWORDS 0x07000000
+#define HDCR_DH 0x08000000
+#define HDCR_SMS_MASK 0x70000000
+#define HDCR_SMS_LINEAR 0x00000000
+#define HDCR_SMS_16_DWORDS 0x10000000
+#define HDCR_SMS_32_DWORDS 0x20000000
+#define HDCR_SMS_64_DWORDS 0x30000000
+#define HDCR_SMS_128_DWORDS 0x40000000
+#define HDCR_SMS_256_DWORDS 0x50000000
+#define HDCR_SMS_512_DWORDS 0x60000000
+#define HDCR_SMS_1024_DWORDS 0x70000000
+#define HDCR_SH 0x80000000
+#define HDCR_COUNT_SHIFT 0
+
+/*
+ * The following defines are for the flags in the performance monitor control
+ * register.
+ */
+#define PFMC_C1SS_MASK 0x0000001F
+#define PFMC_C1EV 0x00000020
+#define PFMC_C1RS 0x00008000
+#define PFMC_C2SS_MASK 0x001F0000
+#define PFMC_C2EV 0x00200000
+#define PFMC_C2RS 0x80000000
+#define PFMC_C1SS_SHIFT 0
+#define PFMC_C2SS_SHIFT 16
+#define PFMC_BUS_GRANT 0
+#define PFMC_GRANT_AFTER_REQ 1
+#define PFMC_TRANSACTION 2
+#define PFMC_DWORD_TRANSFER 3
+#define PFMC_SLAVE_READ 4
+#define PFMC_SLAVE_WRITE 5
+#define PFMC_PREEMPTION 6
+#define PFMC_DISCONNECT_RETRY 7
+#define PFMC_INTERRUPT 8
+#define PFMC_BUS_OWNERSHIP 9
+#define PFMC_TRANSACTION_LAG 10
+#define PFMC_PCI_CLOCK 11
+#define PFMC_SERIAL_CLOCK 12
+#define PFMC_SP_CLOCK 13
+
+/*
+ * The following defines are for the flags in the performance counter value 1
+ * register.
+ */
+#define PFCV1_PC1V_MASK 0xFFFFFFFF
+#define PFCV1_PC1V_SHIFT 0
+
+/*
+ * The following defines are for the flags in the performance counter value 2
+ * register.
+ */
+#define PFCV2_PC2V_MASK 0xFFFFFFFF
+#define PFCV2_PC2V_SHIFT 0
+
+/*
+ * The following defines are for the flags in the clock control register 1.
+ */
+#define CLKCR1_OSCS 0x00000001
+#define CLKCR1_OSCP 0x00000002
+#define CLKCR1_PLLSS_MASK 0x0000000C
+#define CLKCR1_PLLSS_SERIAL 0x00000000
+#define CLKCR1_PLLSS_CRYSTAL 0x00000004
+#define CLKCR1_PLLSS_PCI 0x00000008
+#define CLKCR1_PLLSS_RESERVED 0x0000000C
+#define CLKCR1_PLLP 0x00000010
+#define CLKCR1_SWCE 0x00000020
+#define CLKCR1_PLLOS 0x00000040
+
+/*
+ * The following defines are for the flags in the clock control register 2.
+ */
+#define CLKCR2_PDIVS_MASK 0x0000000F
+#define CLKCR2_PDIVS_1 0x00000001
+#define CLKCR2_PDIVS_2 0x00000002
+#define CLKCR2_PDIVS_4 0x00000004
+#define CLKCR2_PDIVS_7 0x00000007
+#define CLKCR2_PDIVS_8 0x00000008
+#define CLKCR2_PDIVS_16 0x00000000
+
+/*
+ * The following defines are for the flags in the PLL multiplier register.
+ */
+#define PLLM_MASK 0x000000FF
+#define PLLM_SHIFT 0
+
+/*
+ * The following defines are for the flags in the PLL capacitor coefficient
+ * register.
+ */
+#define PLLCC_CDR_MASK 0x00000007
+#ifndef NO_CS4610
+#define PLLCC_CDR_240_350_MHZ 0x00000000
+#define PLLCC_CDR_184_265_MHZ 0x00000001
+#define PLLCC_CDR_144_205_MHZ 0x00000002
+#define PLLCC_CDR_111_160_MHZ 0x00000003
+#define PLLCC_CDR_87_123_MHZ 0x00000004
+#define PLLCC_CDR_67_96_MHZ 0x00000005
+#define PLLCC_CDR_52_74_MHZ 0x00000006
+#define PLLCC_CDR_45_58_MHZ 0x00000007
+#endif
+#ifndef NO_CS4612
+#define PLLCC_CDR_271_398_MHZ 0x00000000
+#define PLLCC_CDR_227_330_MHZ 0x00000001
+#define PLLCC_CDR_167_239_MHZ 0x00000002
+#define PLLCC_CDR_150_215_MHZ 0x00000003
+#define PLLCC_CDR_107_154_MHZ 0x00000004
+#define PLLCC_CDR_98_140_MHZ 0x00000005
+#define PLLCC_CDR_73_104_MHZ 0x00000006
+#define PLLCC_CDR_63_90_MHZ 0x00000007
+#endif
+#define PLLCC_LPF_MASK 0x000000F8
+#ifndef NO_CS4610
+#define PLLCC_LPF_23850_60000_KHZ 0x00000000
+#define PLLCC_LPF_7960_26290_KHZ 0x00000008
+#define PLLCC_LPF_4160_10980_KHZ 0x00000018
+#define PLLCC_LPF_1740_4580_KHZ 0x00000038
+#define PLLCC_LPF_724_1910_KHZ 0x00000078
+#define PLLCC_LPF_317_798_KHZ 0x000000F8
+#endif
+#ifndef NO_CS4612
+#define PLLCC_LPF_25580_64530_KHZ 0x00000000
+#define PLLCC_LPF_14360_37270_KHZ 0x00000008
+#define PLLCC_LPF_6100_16020_KHZ 0x00000018
+#define PLLCC_LPF_2540_6690_KHZ 0x00000038
+#define PLLCC_LPF_1050_2780_KHZ 0x00000078
+#define PLLCC_LPF_450_1160_KHZ 0x000000F8
+#endif
+
+/*
+ * The following defines are for the flags in the feature reporting register.
+ */
+#define FRR_FAB_MASK 0x00000003
+#define FRR_MASK_MASK 0x0000001C
+#ifdef NO_CS4612
+#define FRR_CFOP_MASK 0x000000E0
+#else
+#define FRR_CFOP_MASK 0x00000FE0
+#endif
+#define FRR_CFOP_NOT_DVD 0x00000020
+#define FRR_CFOP_A3D 0x00000040
+#define FRR_CFOP_128_PIN 0x00000080
+#ifndef NO_CS4612
+#define FRR_CFOP_CS4280 0x00000800
+#endif
+#define FRR_FAB_SHIFT 0
+#define FRR_MASK_SHIFT 2
+#define FRR_CFOP_SHIFT 5
+
+/*
+ * The following defines are for the flags in the configuration load 1
+ * register.
+ */
+#define CFL1_CLOCK_SOURCE_MASK 0x00000003
+#define CFL1_CLOCK_SOURCE_CS423X 0x00000000
+#define CFL1_CLOCK_SOURCE_AC97 0x00000001
+#define CFL1_CLOCK_SOURCE_CRYSTAL 0x00000002
+#define CFL1_CLOCK_SOURCE_DUAL_AC97 0x00000003
+#define CFL1_VALID_DATA_MASK 0x000000FF
+
+/*
+ * The following defines are for the flags in the configuration load 2
+ * register.
+ */
+#define CFL2_VALID_DATA_MASK 0x000000FF
+
+/*
+ * The following defines are for the flags in the serial port master control
+ * register 1.
+ */
+#define SERMC1_MSPE 0x00000001
+#define SERMC1_PTC_MASK 0x0000000E
+#define SERMC1_PTC_CS423X 0x00000000
+#define SERMC1_PTC_AC97 0x00000002
+#define SERMC1_PTC_DAC 0x00000004
+#define SERMC1_PLB 0x00000010
+#define SERMC1_XLB 0x00000020
+
+/*
+ * The following defines are for the flags in the serial port master control
+ * register 2.
+ */
+#define SERMC2_LROE 0x00000001
+#define SERMC2_MCOE 0x00000002
+#define SERMC2_MCDIV 0x00000004
+
+/*
+ * The following defines are for the flags in the serial port 1 configuration
+ * register.
+ */
+#define SERC1_SO1EN 0x00000001
+#define SERC1_SO1F_MASK 0x0000000E
+#define SERC1_SO1F_CS423X 0x00000000
+#define SERC1_SO1F_AC97 0x00000002
+#define SERC1_SO1F_DAC 0x00000004
+#define SERC1_SO1F_SPDIF 0x00000006
+
+/*
+ * The following defines are for the flags in the serial port 2 configuration
+ * register.
+ */
+#define SERC2_SI1EN 0x00000001
+#define SERC2_SI1F_MASK 0x0000000E
+#define SERC2_SI1F_CS423X 0x00000000
+#define SERC2_SI1F_AC97 0x00000002
+#define SERC2_SI1F_ADC 0x00000004
+#define SERC2_SI1F_SPDIF 0x00000006
+
+/*
+ * The following defines are for the flags in the serial port 3 configuration
+ * register.
+ */
+#define SERC3_SO2EN 0x00000001
+#define SERC3_SO2F_MASK 0x00000006
+#define SERC3_SO2F_DAC 0x00000000
+#define SERC3_SO2F_SPDIF 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port 4 configuration
+ * register.
+ */
+#define SERC4_SO3EN 0x00000001
+#define SERC4_SO3F_MASK 0x00000006
+#define SERC4_SO3F_DAC 0x00000000
+#define SERC4_SO3F_SPDIF 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port 5 configuration
+ * register.
+ */
+#define SERC5_SI2EN 0x00000001
+#define SERC5_SI2F_MASK 0x00000006
+#define SERC5_SI2F_ADC 0x00000000
+#define SERC5_SI2F_SPDIF 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port backdoor sample
+ * pointer register.
+ */
+#define SERBSP_FSP_MASK 0x0000000F
+#define SERBSP_FSP_SHIFT 0
+
+/*
+ * The following defines are for the flags in the serial port backdoor status
+ * register.
+ */
+#define SERBST_RRDY 0x00000001
+#define SERBST_WBSY 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port backdoor command
+ * register.
+ */
+#define SERBCM_RDC 0x00000001
+#define SERBCM_WRC 0x00000002
+
+/*
+ * The following defines are for the flags in the serial port backdoor address
+ * register.
+ */
+#ifdef NO_CS4612
+#define SERBAD_FAD_MASK 0x000000FF
+#else
+#define SERBAD_FAD_MASK 0x000001FF
+#endif
+#define SERBAD_FAD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the serial port backdoor
+ * configuration register.
+ */
+#define SERBCF_HBP 0x00000001
+
+/*
+ * The following defines are for the flags in the serial port backdoor write
+ * port register.
+ */
+#define SERBWP_FWD_MASK 0x000FFFFF
+#define SERBWP_FWD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the serial port backdoor read
+ * port register.
+ */
+#define SERBRP_FRD_MASK 0x000FFFFF
+#define SERBRP_FRD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the async FIFO address register.
+ */
+#ifndef NO_CS4612
+#define ASER_FADDR_A1_MASK 0x000001FF
+#define ASER_FADDR_EN1 0x00008000
+#define ASER_FADDR_A2_MASK 0x01FF0000
+#define ASER_FADDR_EN2 0x80000000
+#define ASER_FADDR_A1_SHIFT 0
+#define ASER_FADDR_A2_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 control register.
+ */
+#define ACCTL_RSTN 0x00000001
+#define ACCTL_ESYN 0x00000002
+#define ACCTL_VFRM 0x00000004
+#define ACCTL_DCV 0x00000008
+#define ACCTL_CRW 0x00000010
+#define ACCTL_ASYN 0x00000020
+#ifndef NO_CS4612
+#define ACCTL_TC 0x00000040
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status register.
+ */
+#define ACSTS_CRDY 0x00000001
+#define ACSTS_VSTS 0x00000002
+#ifndef NO_CS4612
+#define ACSTS_WKUP 0x00000004
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 output slot valid
+ * register.
+ */
+#define ACOSV_SLV3 0x00000001
+#define ACOSV_SLV4 0x00000002
+#define ACOSV_SLV5 0x00000004
+#define ACOSV_SLV6 0x00000008
+#define ACOSV_SLV7 0x00000010
+#define ACOSV_SLV8 0x00000020
+#define ACOSV_SLV9 0x00000040
+#define ACOSV_SLV10 0x00000080
+#define ACOSV_SLV11 0x00000100
+#define ACOSV_SLV12 0x00000200
+
+/*
+ * The following defines are for the flags in the AC97 command address
+ * register.
+ */
+#define ACCAD_CI_MASK 0x0000007F
+#define ACCAD_CI_SHIFT 0
+
+/*
+ * The following defines are for the flags in the AC97 command data register.
+ */
+#define ACCDA_CD_MASK 0x0000FFFF
+#define ACCDA_CD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the AC97 input slot valid
+ * register.
+ */
+#define ACISV_ISV3 0x00000001
+#define ACISV_ISV4 0x00000002
+#define ACISV_ISV5 0x00000004
+#define ACISV_ISV6 0x00000008
+#define ACISV_ISV7 0x00000010
+#define ACISV_ISV8 0x00000020
+#define ACISV_ISV9 0x00000040
+#define ACISV_ISV10 0x00000080
+#define ACISV_ISV11 0x00000100
+#define ACISV_ISV12 0x00000200
+
+/*
+ * The following defines are for the flags in the AC97 status address
+ * register.
+ */
+#define ACSAD_SI_MASK 0x0000007F
+#define ACSAD_SI_SHIFT 0
+
+/*
+ * The following defines are for the flags in the AC97 status data register.
+ */
+#define ACSDA_SD_MASK 0x0000FFFF
+#define ACSDA_SD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the joystick poll/trigger
+ * register.
+ */
+#define JSPT_CAX 0x00000001
+#define JSPT_CAY 0x00000002
+#define JSPT_CBX 0x00000004
+#define JSPT_CBY 0x00000008
+#define JSPT_BA1 0x00000010
+#define JSPT_BA2 0x00000020
+#define JSPT_BB1 0x00000040
+#define JSPT_BB2 0x00000080
+
+/*
+ * The following defines are for the flags in the joystick control register.
+ */
+#define JSCTL_SP_MASK 0x00000003
+#define JSCTL_SP_SLOW 0x00000000
+#define JSCTL_SP_MEDIUM_SLOW 0x00000001
+#define JSCTL_SP_MEDIUM_FAST 0x00000002
+#define JSCTL_SP_FAST 0x00000003
+#define JSCTL_ARE 0x00000004
+
+/*
+ * The following defines are for the flags in the joystick coordinate pair 1
+ * readback register.
+ */
+#define JSC1_Y1V_MASK 0x0000FFFF
+#define JSC1_X1V_MASK 0xFFFF0000
+#define JSC1_Y1V_SHIFT 0
+#define JSC1_X1V_SHIFT 16
+
+/*
+ * The following defines are for the flags in the joystick coordinate pair 2
+ * readback register.
+ */
+#define JSC2_Y2V_MASK 0x0000FFFF
+#define JSC2_X2V_MASK 0xFFFF0000
+#define JSC2_Y2V_SHIFT 0
+#define JSC2_X2V_SHIFT 16
+
+/*
+ * The following defines are for the flags in the MIDI control register.
+ */
+#define MIDCR_TXE 0x00000001 /* Enable transmitting. */
+#define MIDCR_RXE 0x00000002 /* Enable receiving. */
+#define MIDCR_RIE 0x00000004 /* Interrupt upon tx ready. */
+#define MIDCR_TIE 0x00000008 /* Interrupt upon rx ready. */
+#define MIDCR_MLB 0x00000010 /* Enable midi loopback. */
+#define MIDCR_MRST 0x00000020 /* Reset interface. */
+
+/*
+ * The following defines are for the flags in the MIDI status register.
+ */
+#define MIDSR_TBF 0x00000001 /* Tx FIFO is full. */
+#define MIDSR_RBE 0x00000002 /* Rx FIFO is empty. */
+
+/*
+ * The following defines are for the flags in the MIDI write port register.
+ */
+#define MIDWP_MWD_MASK 0x000000FF
+#define MIDWP_MWD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the MIDI read port register.
+ */
+#define MIDRP_MRD_MASK 0x000000FF
+#define MIDRP_MRD_SHIFT 0
+
+/*
+ * The following defines are for the flags in the joystick GPIO register.
+ */
+#define JSIO_DAX 0x00000001
+#define JSIO_DAY 0x00000002
+#define JSIO_DBX 0x00000004
+#define JSIO_DBY 0x00000008
+#define JSIO_AXOE 0x00000010
+#define JSIO_AYOE 0x00000020
+#define JSIO_BXOE 0x00000040
+#define JSIO_BYOE 0x00000080
+
+/*
+ * The following defines are for the flags in the master async/sync serial
+ * port enable register.
+ */
+#ifndef NO_CS4612
+#define ASER_MASTER_ME 0x00000001
+#endif
+
+/*
+ * The following defines are for the flags in the configuration interface
+ * register.
+ */
+#define CFGI_CLK 0x00000001
+#define CFGI_DOUT 0x00000002
+#define CFGI_DIN_EEN 0x00000004
+#define CFGI_EELD 0x00000008
+
+/*
+ * The following defines are for the flags in the subsystem ID and vendor ID
+ * register.
+ */
+#define SSVID_VID_MASK 0x0000FFFF
+#define SSVID_SID_MASK 0xFFFF0000
+#define SSVID_VID_SHIFT 0
+#define SSVID_SID_SHIFT 16
+
+/*
+ * The following defines are for the flags in the GPIO pin interface register.
+ */
+#define GPIOR_VOLDN 0x00000001
+#define GPIOR_VOLUP 0x00000002
+#define GPIOR_SI2D 0x00000004
+#define GPIOR_SI2OE 0x00000008
+
+/*
+ * The following defines are for the flags in the extended GPIO pin direction
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIODR_GPOE0 0x00000001
+#define EGPIODR_GPOE1 0x00000002
+#define EGPIODR_GPOE2 0x00000004
+#define EGPIODR_GPOE3 0x00000008
+#define EGPIODR_GPOE4 0x00000010
+#define EGPIODR_GPOE5 0x00000020
+#define EGPIODR_GPOE6 0x00000040
+#define EGPIODR_GPOE7 0x00000080
+#define EGPIODR_GPOE8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO pin polarity/
+ * type register.
+ */
+#ifndef NO_CS4612
+#define EGPIOPTR_GPPT0 0x00000001
+#define EGPIOPTR_GPPT1 0x00000002
+#define EGPIOPTR_GPPT2 0x00000004
+#define EGPIOPTR_GPPT3 0x00000008
+#define EGPIOPTR_GPPT4 0x00000010
+#define EGPIOPTR_GPPT5 0x00000020
+#define EGPIOPTR_GPPT6 0x00000040
+#define EGPIOPTR_GPPT7 0x00000080
+#define EGPIOPTR_GPPT8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO pin sticky
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIOTR_GPS0 0x00000001
+#define EGPIOTR_GPS1 0x00000002
+#define EGPIOTR_GPS2 0x00000004
+#define EGPIOTR_GPS3 0x00000008
+#define EGPIOTR_GPS4 0x00000010
+#define EGPIOTR_GPS5 0x00000020
+#define EGPIOTR_GPS6 0x00000040
+#define EGPIOTR_GPS7 0x00000080
+#define EGPIOTR_GPS8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO ping wakeup
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIOWR_GPW0 0x00000001
+#define EGPIOWR_GPW1 0x00000002
+#define EGPIOWR_GPW2 0x00000004
+#define EGPIOWR_GPW3 0x00000008
+#define EGPIOWR_GPW4 0x00000010
+#define EGPIOWR_GPW5 0x00000020
+#define EGPIOWR_GPW6 0x00000040
+#define EGPIOWR_GPW7 0x00000080
+#define EGPIOWR_GPW8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the extended GPIO pin status
+ * register.
+ */
+#ifndef NO_CS4612
+#define EGPIOSR_GPS0 0x00000001
+#define EGPIOSR_GPS1 0x00000002
+#define EGPIOSR_GPS2 0x00000004
+#define EGPIOSR_GPS3 0x00000008
+#define EGPIOSR_GPS4 0x00000010
+#define EGPIOSR_GPS5 0x00000020
+#define EGPIOSR_GPS6 0x00000040
+#define EGPIOSR_GPS7 0x00000080
+#define EGPIOSR_GPS8 0x00000100
+#endif
+
+/*
+ * The following defines are for the flags in the serial port 6 configuration
+ * register.
+ */
+#ifndef NO_CS4612
+#define SERC6_ASDO2EN 0x00000001
+#endif
+
+/*
+ * The following defines are for the flags in the serial port 7 configuration
+ * register.
+ */
+#ifndef NO_CS4612
+#define SERC7_ASDI2EN 0x00000001
+#define SERC7_POSILB 0x00000002
+#define SERC7_SIPOLB 0x00000004
+#define SERC7_SOSILB 0x00000008
+#define SERC7_SISOLB 0x00000010
+#endif
+
+/*
+ * The following defines are for the flags in the serial port AC link
+ * configuration register.
+ */
+#ifndef NO_CS4612
+#define SERACC_CHIP_TYPE_MASK 0x00000001
+#define SERACC_CHIP_TYPE_1_03 0x00000000
+#define SERACC_CHIP_TYPE_2_0 0x00000001
+#define SERACC_TWO_CODECS 0x00000002
+#define SERACC_MDM 0x00000004
+#define SERACC_HSP 0x00000008
+#define SERACC_ODT 0x00000010 /* only CS4630 */
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 control register 2.
+ */
+#ifndef NO_CS4612
+#define ACCTL2_RSTN 0x00000001
+#define ACCTL2_ESYN 0x00000002
+#define ACCTL2_VFRM 0x00000004
+#define ACCTL2_DCV 0x00000008
+#define ACCTL2_CRW 0x00000010
+#define ACCTL2_ASYN 0x00000020
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status register 2.
+ */
+#ifndef NO_CS4612
+#define ACSTS2_CRDY 0x00000001
+#define ACSTS2_VSTS 0x00000002
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 output slot valid
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACOSV2_SLV3 0x00000001
+#define ACOSV2_SLV4 0x00000002
+#define ACOSV2_SLV5 0x00000004
+#define ACOSV2_SLV6 0x00000008
+#define ACOSV2_SLV7 0x00000010
+#define ACOSV2_SLV8 0x00000020
+#define ACOSV2_SLV9 0x00000040
+#define ACOSV2_SLV10 0x00000080
+#define ACOSV2_SLV11 0x00000100
+#define ACOSV2_SLV12 0x00000200
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 command address
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACCAD2_CI_MASK 0x0000007F
+#define ACCAD2_CI_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 command data register
+ * 2.
+ */
+#ifndef NO_CS4612
+#define ACCDA2_CD_MASK 0x0000FFFF
+#define ACCDA2_CD_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 input slot valid
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACISV2_ISV3 0x00000001
+#define ACISV2_ISV4 0x00000002
+#define ACISV2_ISV5 0x00000004
+#define ACISV2_ISV6 0x00000008
+#define ACISV2_ISV7 0x00000010
+#define ACISV2_ISV8 0x00000020
+#define ACISV2_ISV9 0x00000040
+#define ACISV2_ISV10 0x00000080
+#define ACISV2_ISV11 0x00000100
+#define ACISV2_ISV12 0x00000200
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status address
+ * register 2.
+ */
+#ifndef NO_CS4612
+#define ACSAD2_SI_MASK 0x0000007F
+#define ACSAD2_SI_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the AC97 status data register 2.
+ */
+#ifndef NO_CS4612
+#define ACSDA2_SD_MASK 0x0000FFFF
+#define ACSDA2_SD_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap address and control
+ * registers (all 12).
+ */
+#ifndef NO_CS4612
+#define IOTAC_SA_MASK 0x0000FFFF
+#define IOTAC_MSK_MASK 0x000F0000
+#define IOTAC_IODC_MASK 0x06000000
+#define IOTAC_IODC_16_BIT 0x00000000
+#define IOTAC_IODC_10_BIT 0x02000000
+#define IOTAC_IODC_12_BIT 0x04000000
+#define IOTAC_WSPI 0x08000000
+#define IOTAC_RSPI 0x10000000
+#define IOTAC_WSE 0x20000000
+#define IOTAC_WE 0x40000000
+#define IOTAC_RE 0x80000000
+#define IOTAC_SA_SHIFT 0
+#define IOTAC_MSK_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap fast read registers
+ * (all 8).
+ */
+#ifndef NO_CS4612
+#define IOTFR_D_MASK 0x0000FFFF
+#define IOTFR_A_MASK 0x000F0000
+#define IOTFR_R_MASK 0x0F000000
+#define IOTFR_ALL 0x40000000
+#define IOTFR_VL 0x80000000
+#define IOTFR_D_SHIFT 0
+#define IOTFR_A_SHIFT 16
+#define IOTFR_R_SHIFT 24
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap FIFO register.
+ */
+#ifndef NO_CS4612
+#define IOTFIFO_BA_MASK 0x00003FFF
+#define IOTFIFO_S_MASK 0x00FF0000
+#define IOTFIFO_OF 0x40000000
+#define IOTFIFO_SPIOF 0x80000000
+#define IOTFIFO_BA_SHIFT 0
+#define IOTFIFO_S_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap retry read data
+ * register.
+ */
+#ifndef NO_CS4612
+#define IOTRRD_D_MASK 0x0000FFFF
+#define IOTRRD_RDV 0x80000000
+#define IOTRRD_D_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap FIFO pointer
+ * register.
+ */
+#ifndef NO_CS4612
+#define IOTFP_CA_MASK 0x00003FFF
+#define IOTFP_PA_MASK 0x3FFF0000
+#define IOTFP_CA_SHIFT 0
+#define IOTFP_PA_SHIFT 16
+#endif
+
+/*
+ * The following defines are for the flags in the I/O trap control register.
+ */
+#ifndef NO_CS4612
+#define IOTCR_ITD 0x00000001
+#define IOTCR_HRV 0x00000002
+#define IOTCR_SRV 0x00000004
+#define IOTCR_DTI 0x00000008
+#define IOTCR_DFI 0x00000010
+#define IOTCR_DDP 0x00000020
+#define IOTCR_JTE 0x00000040
+#define IOTCR_PPE 0x00000080
+#endif
+
+/*
+ * The following defines are for the flags in the direct PCI data register.
+ */
+#ifndef NO_CS4612
+#define DPCID_D_MASK 0xFFFFFFFF
+#define DPCID_D_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the direct PCI address register.
+ */
+#ifndef NO_CS4612
+#define DPCIA_A_MASK 0xFFFFFFFF
+#define DPCIA_A_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the direct PCI command register.
+ */
+#ifndef NO_CS4612
+#define DPCIC_C_MASK 0x0000000F
+#define DPCIC_C_IOREAD 0x00000002
+#define DPCIC_C_IOWRITE 0x00000003
+#define DPCIC_BE_MASK 0x000000F0
+#endif
+
+/*
+ * The following defines are for the flags in the PC/PCI request register.
+ */
+#ifndef NO_CS4612
+#define PCPCIR_RDC_MASK 0x00000007
+#define PCPCIR_C_MASK 0x00007000
+#define PCPCIR_REQ 0x00008000
+#define PCPCIR_RDC_SHIFT 0
+#define PCPCIR_C_SHIFT 12
+#endif
+
+/*
+ * The following defines are for the flags in the PC/PCI grant register.
+ */
+#ifndef NO_CS4612
+#define PCPCIG_GDC_MASK 0x00000007
+#define PCPCIG_VL 0x00008000
+#define PCPCIG_GDC_SHIFT 0
+#endif
+
+/*
+ * The following defines are for the flags in the PC/PCI master enable
+ * register.
+ */
+#ifndef NO_CS4612
+#define PCPCIEN_EN 0x00000001
+#endif
+
+/*
+ * The following defines are for the flags in the extended PCI power
+ * management control register.
+ */
+#ifndef NO_CS4612
+#define EPCIPMC_GWU 0x00000001
+#define EPCIPMC_FSPC 0x00000002
+#endif
+
+/*
+ * The following defines are for the flags in the SP control register.
+ */
+#define SPCR_RUN 0x00000001
+#define SPCR_STPFR 0x00000002
+#define SPCR_RUNFR 0x00000004
+#define SPCR_TICK 0x00000008
+#define SPCR_DRQEN 0x00000020
+#define SPCR_RSTSP 0x00000040
+#define SPCR_OREN 0x00000080
+#ifndef NO_CS4612
+#define SPCR_PCIINT 0x00000100
+#define SPCR_OINTD 0x00000200
+#define SPCR_CRE 0x00008000
+#endif
+
+/*
+ * The following defines are for the flags in the debug index register.
+ */
+#define DREG_REGID_MASK 0x0000007F
+#define DREG_DEBUG 0x00000080
+#define DREG_RGBK_MASK 0x00000700
+#define DREG_TRAP 0x00000800
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX 0x00001000
+#endif
+#endif
+#define DREG_REGID_SHIFT 0
+#define DREG_RGBK_SHIFT 8
+#define DREG_RGBK_REGID_MASK 0x0000077F
+#define DREG_REGID_R0 0x00000010
+#define DREG_REGID_R1 0x00000011
+#define DREG_REGID_R2 0x00000012
+#define DREG_REGID_R3 0x00000013
+#define DREG_REGID_R4 0x00000014
+#define DREG_REGID_R5 0x00000015
+#define DREG_REGID_R6 0x00000016
+#define DREG_REGID_R7 0x00000017
+#define DREG_REGID_R8 0x00000018
+#define DREG_REGID_R9 0x00000019
+#define DREG_REGID_RA 0x0000001A
+#define DREG_REGID_RB 0x0000001B
+#define DREG_REGID_RC 0x0000001C
+#define DREG_REGID_RD 0x0000001D
+#define DREG_REGID_RE 0x0000001E
+#define DREG_REGID_RF 0x0000001F
+#define DREG_REGID_RA_BUS_LOW 0x00000020
+#define DREG_REGID_RA_BUS_HIGH 0x00000038
+#define DREG_REGID_YBUS_LOW 0x00000050
+#define DREG_REGID_YBUS_HIGH 0x00000058
+#define DREG_REGID_TRAP_0 0x00000100
+#define DREG_REGID_TRAP_1 0x00000101
+#define DREG_REGID_TRAP_2 0x00000102
+#define DREG_REGID_TRAP_3 0x00000103
+#define DREG_REGID_TRAP_4 0x00000104
+#define DREG_REGID_TRAP_5 0x00000105
+#define DREG_REGID_TRAP_6 0x00000106
+#define DREG_REGID_TRAP_7 0x00000107
+#define DREG_REGID_INDIRECT_ADDRESS 0x0000010E
+#define DREG_REGID_TOP_OF_STACK 0x0000010F
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8 0x00000110
+#define DREG_REGID_TRAP_9 0x00000111
+#define DREG_REGID_TRAP_10 0x00000112
+#define DREG_REGID_TRAP_11 0x00000113
+#define DREG_REGID_TRAP_12 0x00000114
+#define DREG_REGID_TRAP_13 0x00000115
+#define DREG_REGID_TRAP_14 0x00000116
+#define DREG_REGID_TRAP_15 0x00000117
+#define DREG_REGID_TRAP_16 0x00000118
+#define DREG_REGID_TRAP_17 0x00000119
+#define DREG_REGID_TRAP_18 0x0000011A
+#define DREG_REGID_TRAP_19 0x0000011B
+#define DREG_REGID_TRAP_20 0x0000011C
+#define DREG_REGID_TRAP_21 0x0000011D
+#define DREG_REGID_TRAP_22 0x0000011E
+#define DREG_REGID_TRAP_23 0x0000011F
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW 0x00000200
+#define DREG_REGID_RSA0_HIGH 0x00000201
+#define DREG_REGID_RSA1_LOW 0x00000202
+#define DREG_REGID_RSA1_HIGH 0x00000203
+#define DREG_REGID_RSA2 0x00000204
+#define DREG_REGID_RSA3 0x00000205
+#define DREG_REGID_RSI0_LOW 0x00000206
+#define DREG_REGID_RSI0_HIGH 0x00000207
+#define DREG_REGID_RSI1 0x00000208
+#define DREG_REGID_RSI2 0x00000209
+#define DREG_REGID_SAGUSTATUS 0x0000020A
+#define DREG_REGID_RSCONFIG01_LOW 0x0000020B
+#define DREG_REGID_RSCONFIG01_HIGH 0x0000020C
+#define DREG_REGID_RSCONFIG23_LOW 0x0000020D
+#define DREG_REGID_RSCONFIG23_HIGH 0x0000020E
+#define DREG_REGID_RSDMA01E 0x0000020F
+#define DREG_REGID_RSDMA23E 0x00000210
+#define DREG_REGID_RSD0_LOW 0x00000211
+#define DREG_REGID_RSD0_HIGH 0x00000212
+#define DREG_REGID_RSD1_LOW 0x00000213
+#define DREG_REGID_RSD1_HIGH 0x00000214
+#define DREG_REGID_RSD2_LOW 0x00000215
+#define DREG_REGID_RSD2_HIGH 0x00000216
+#define DREG_REGID_RSD3_LOW 0x00000217
+#define DREG_REGID_RSD3_HIGH 0x00000218
+#define DREG_REGID_SRAR_HIGH 0x0000021A
+#define DREG_REGID_SRAR_LOW 0x0000021B
+#define DREG_REGID_DMA_STATE 0x0000021C
+#define DREG_REGID_CURRENT_DMA_STREAM 0x0000021D
+#define DREG_REGID_NEXT_DMA_STREAM 0x0000021E
+#define DREG_REGID_CPU_STATUS 0x00000300
+#define DREG_REGID_MAC_MODE 0x00000301
+#define DREG_REGID_STACK_AND_REPEAT 0x00000302
+#define DREG_REGID_INDEX0 0x00000304
+#define DREG_REGID_INDEX1 0x00000305
+#define DREG_REGID_DMA_STATE_0_3 0x00000400
+#define DREG_REGID_DMA_STATE_4_7 0x00000404
+#define DREG_REGID_DMA_STATE_8_11 0x00000408
+#define DREG_REGID_DMA_STATE_12_15 0x0000040C
+#define DREG_REGID_DMA_STATE_16_19 0x00000410
+#define DREG_REGID_DMA_STATE_20_23 0x00000414
+#define DREG_REGID_DMA_STATE_24_27 0x00000418
+#define DREG_REGID_DMA_STATE_28_31 0x0000041C
+#define DREG_REGID_DMA_STATE_32_35 0x00000420
+#define DREG_REGID_DMA_STATE_36_39 0x00000424
+#define DREG_REGID_DMA_STATE_40_43 0x00000428
+#define DREG_REGID_DMA_STATE_44_47 0x0000042C
+#define DREG_REGID_DMA_STATE_48_51 0x00000430
+#define DREG_REGID_DMA_STATE_52_55 0x00000434
+#define DREG_REGID_DMA_STATE_56_59 0x00000438
+#define DREG_REGID_DMA_STATE_60_63 0x0000043C
+#define DREG_REGID_DMA_STATE_64_67 0x00000440
+#define DREG_REGID_DMA_STATE_68_71 0x00000444
+#define DREG_REGID_DMA_STATE_72_75 0x00000448
+#define DREG_REGID_DMA_STATE_76_79 0x0000044C
+#define DREG_REGID_DMA_STATE_80_83 0x00000450
+#define DREG_REGID_DMA_STATE_84_87 0x00000454
+#define DREG_REGID_DMA_STATE_88_91 0x00000458
+#define DREG_REGID_DMA_STATE_92_95 0x0000045C
+#define DREG_REGID_TRAP_SELECT 0x00000500
+#define DREG_REGID_TRAP_WRITE_0 0x00000500
+#define DREG_REGID_TRAP_WRITE_1 0x00000501
+#define DREG_REGID_TRAP_WRITE_2 0x00000502
+#define DREG_REGID_TRAP_WRITE_3 0x00000503
+#define DREG_REGID_TRAP_WRITE_4 0x00000504
+#define DREG_REGID_TRAP_WRITE_5 0x00000505
+#define DREG_REGID_TRAP_WRITE_6 0x00000506
+#define DREG_REGID_TRAP_WRITE_7 0x00000507
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8 0x00000510
+#define DREG_REGID_TRAP_WRITE_9 0x00000511
+#define DREG_REGID_TRAP_WRITE_10 0x00000512
+#define DREG_REGID_TRAP_WRITE_11 0x00000513
+#define DREG_REGID_TRAP_WRITE_12 0x00000514
+#define DREG_REGID_TRAP_WRITE_13 0x00000515
+#define DREG_REGID_TRAP_WRITE_14 0x00000516
+#define DREG_REGID_TRAP_WRITE_15 0x00000517
+#define DREG_REGID_TRAP_WRITE_16 0x00000518
+#define DREG_REGID_TRAP_WRITE_17 0x00000519
+#define DREG_REGID_TRAP_WRITE_18 0x0000051A
+#define DREG_REGID_TRAP_WRITE_19 0x0000051B
+#define DREG_REGID_TRAP_WRITE_20 0x0000051C
+#define DREG_REGID_TRAP_WRITE_21 0x0000051D
+#define DREG_REGID_TRAP_WRITE_22 0x0000051E
+#define DREG_REGID_TRAP_WRITE_23 0x0000051F
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW 0x00000600
+#define DREG_REGID_MAC0_ACC1_LOW 0x00000601
+#define DREG_REGID_MAC0_ACC2_LOW 0x00000602
+#define DREG_REGID_MAC0_ACC3_LOW 0x00000603
+#define DREG_REGID_MAC1_ACC0_LOW 0x00000604
+#define DREG_REGID_MAC1_ACC1_LOW 0x00000605
+#define DREG_REGID_MAC1_ACC2_LOW 0x00000606
+#define DREG_REGID_MAC1_ACC3_LOW 0x00000607
+#define DREG_REGID_MAC0_ACC0_MID 0x00000608
+#define DREG_REGID_MAC0_ACC1_MID 0x00000609
+#define DREG_REGID_MAC0_ACC2_MID 0x0000060A
+#define DREG_REGID_MAC0_ACC3_MID 0x0000060B
+#define DREG_REGID_MAC1_ACC0_MID 0x0000060C
+#define DREG_REGID_MAC1_ACC1_MID 0x0000060D
+#define DREG_REGID_MAC1_ACC2_MID 0x0000060E
+#define DREG_REGID_MAC1_ACC3_MID 0x0000060F
+#define DREG_REGID_MAC0_ACC0_HIGH 0x00000610
+#define DREG_REGID_MAC0_ACC1_HIGH 0x00000611
+#define DREG_REGID_MAC0_ACC2_HIGH 0x00000612
+#define DREG_REGID_MAC0_ACC3_HIGH 0x00000613
+#define DREG_REGID_MAC1_ACC0_HIGH 0x00000614
+#define DREG_REGID_MAC1_ACC1_HIGH 0x00000615
+#define DREG_REGID_MAC1_ACC2_HIGH 0x00000616
+#define DREG_REGID_MAC1_ACC3_HIGH 0x00000617
+#define DREG_REGID_RSHOUT_LOW 0x00000620
+#define DREG_REGID_RSHOUT_MID 0x00000628
+#define DREG_REGID_RSHOUT_HIGH 0x00000630
+
+/*
+ * The following defines are for the flags in the DMA stream requestor write
+ */
+#define DSRWP_DSR_MASK 0x0000000F
+#define DSRWP_DSR_BG_RQ 0x00000001
+#define DSRWP_DSR_PRIORITY_MASK 0x00000006
+#define DSRWP_DSR_PRIORITY_0 0x00000000
+#define DSRWP_DSR_PRIORITY_1 0x00000002
+#define DSRWP_DSR_PRIORITY_2 0x00000004
+#define DSRWP_DSR_PRIORITY_3 0x00000006
+#define DSRWP_DSR_RQ_PENDING 0x00000008
+
+/*
+ * The following defines are for the flags in the trap write port register.
+ */
+#define TWPR_TW_MASK 0x0000FFFF
+#define TWPR_TW_SHIFT 0
+
+/*
+ * The following defines are for the flags in the stack pointer write
+ * register.
+ */
+#define SPWR_STKP_MASK 0x0000000F
+#define SPWR_STKP_SHIFT 0
+
+/*
+ * The following defines are for the flags in the SP interrupt register.
+ */
+#define SPIR_FRI 0x00000001
+#define SPIR_DOI 0x00000002
+#define SPIR_GPI2 0x00000004
+#define SPIR_GPI3 0x00000008
+#define SPIR_IP0 0x00000010
+#define SPIR_IP1 0x00000020
+#define SPIR_IP2 0x00000040
+#define SPIR_IP3 0x00000080
+
+/*
+ * The following defines are for the flags in the functional group 1 register.
+ */
+#define FGR1_F1S_MASK 0x0000FFFF
+#define FGR1_F1S_SHIFT 0
+
+/*
+ * The following defines are for the flags in the SP clock status register.
+ */
+#define SPCS_FRI 0x00000001
+#define SPCS_DOI 0x00000002
+#define SPCS_GPI2 0x00000004
+#define SPCS_GPI3 0x00000008
+#define SPCS_IP0 0x00000010
+#define SPCS_IP1 0x00000020
+#define SPCS_IP2 0x00000040
+#define SPCS_IP3 0x00000080
+#define SPCS_SPRUN 0x00000100
+#define SPCS_SLEEP 0x00000200
+#define SPCS_FG 0x00000400
+#define SPCS_ORUN 0x00000800
+#define SPCS_IRQ 0x00001000
+#define SPCS_FGN_MASK 0x0000E000
+#define SPCS_FGN_SHIFT 13
+
+/*
+ * The following defines are for the flags in the SP DMA requestor status
+ * register.
+ */
+#define SDSR_DCS_MASK 0x000000FF
+#define SDSR_DCS_SHIFT 0
+#define SDSR_DCS_NONE 0x00000007
+
+/*
+ * The following defines are for the flags in the frame timer register.
+ */
+#define FRMT_FTV_MASK 0x0000FFFF
+#define FRMT_FTV_SHIFT 0
+
+/*
+ * The following defines are for the flags in the frame timer current count
+ * register.
+ */
+#define FRCC_FCC_MASK 0x0000FFFF
+#define FRCC_FCC_SHIFT 0
+
+/*
+ * The following defines are for the flags in the frame timer save count
+ * register.
+ */
+#define FRSC_FCS_MASK 0x0000FFFF
+#define FRSC_FCS_SHIFT 0
+
+/*
+ * The following define the various flags stored in the scatter/gather
+ * descriptors.
+ */
+#define DMA_SG_NEXT_ENTRY_MASK 0x00000FF8
+#define DMA_SG_SAMPLE_END_MASK 0x0FFF0000
+#define DMA_SG_SAMPLE_END_FLAG 0x10000000
+#define DMA_SG_LOOP_END_FLAG 0x20000000
+#define DMA_SG_SIGNAL_END_FLAG 0x40000000
+#define DMA_SG_SIGNAL_PAGE_FLAG 0x80000000
+#define DMA_SG_NEXT_ENTRY_SHIFT 3
+#define DMA_SG_SAMPLE_END_SHIFT 16
+
+/*
+ * The following define the offsets of the fields within the on-chip generic
+ * DMA requestor.
+ */
+#define DMA_RQ_CONTROL1 0x00000000
+#define DMA_RQ_CONTROL2 0x00000004
+#define DMA_RQ_SOURCE_ADDR 0x00000008
+#define DMA_RQ_DESTINATION_ADDR 0x0000000C
+#define DMA_RQ_NEXT_PAGE_ADDR 0x00000010
+#define DMA_RQ_NEXT_PAGE_SGDESC 0x00000014
+#define DMA_RQ_LOOP_START_ADDR 0x00000018
+#define DMA_RQ_POST_LOOP_ADDR 0x0000001C
+#define DMA_RQ_PAGE_MAP_ADDR 0x00000020
+
+/*
+ * The following defines are for the flags in the first control word of the
+ * on-chip generic DMA requestor.
+ */
+#define DMA_RQ_C1_COUNT_MASK 0x000003FF
+#define DMA_RQ_C1_DESTINATION_SCATTER 0x00001000
+#define DMA_RQ_C1_SOURCE_GATHER 0x00002000
+#define DMA_RQ_C1_DONE_FLAG 0x00004000
+#define DMA_RQ_C1_OPTIMIZE_STATE 0x00008000
+#define DMA_RQ_C1_SAMPLE_END_STATE_MASK 0x00030000
+#define DMA_RQ_C1_FULL_PAGE 0x00000000
+#define DMA_RQ_C1_BEFORE_SAMPLE_END 0x00010000
+#define DMA_RQ_C1_PAGE_MAP_ERROR 0x00020000
+#define DMA_RQ_C1_AT_SAMPLE_END 0x00030000
+#define DMA_RQ_C1_LOOP_END_STATE_MASK 0x000C0000
+#define DMA_RQ_C1_NOT_LOOP_END 0x00000000
+#define DMA_RQ_C1_BEFORE_LOOP_END 0x00040000
+#define DMA_RQ_C1_2PAGE_LOOP_BEGIN 0x00080000
+#define DMA_RQ_C1_LOOP_BEGIN 0x000C0000
+#define DMA_RQ_C1_PAGE_MAP_MASK 0x00300000
+#define DMA_RQ_C1_PM_NONE_PENDING 0x00000000
+#define DMA_RQ_C1_PM_NEXT_PENDING 0x00100000
+#define DMA_RQ_C1_PM_RESERVED 0x00200000
+#define DMA_RQ_C1_PM_LOOP_NEXT_PENDING 0x00300000
+#define DMA_RQ_C1_WRITEBACK_DEST_FLAG 0x00400000
+#define DMA_RQ_C1_WRITEBACK_SRC_FLAG 0x00800000
+#define DMA_RQ_C1_DEST_SIZE_MASK 0x07000000
+#define DMA_RQ_C1_DEST_LINEAR 0x00000000
+#define DMA_RQ_C1_DEST_MOD16 0x01000000
+#define DMA_RQ_C1_DEST_MOD32 0x02000000
+#define DMA_RQ_C1_DEST_MOD64 0x03000000
+#define DMA_RQ_C1_DEST_MOD128 0x04000000
+#define DMA_RQ_C1_DEST_MOD256 0x05000000
+#define DMA_RQ_C1_DEST_MOD512 0x06000000
+#define DMA_RQ_C1_DEST_MOD1024 0x07000000
+#define DMA_RQ_C1_DEST_ON_HOST 0x08000000
+#define DMA_RQ_C1_SOURCE_SIZE_MASK 0x70000000
+#define DMA_RQ_C1_SOURCE_LINEAR 0x00000000
+#define DMA_RQ_C1_SOURCE_MOD16 0x10000000
+#define DMA_RQ_C1_SOURCE_MOD32 0x20000000
+#define DMA_RQ_C1_SOURCE_MOD64 0x30000000
+#define DMA_RQ_C1_SOURCE_MOD128 0x40000000
+#define DMA_RQ_C1_SOURCE_MOD256 0x50000000
+#define DMA_RQ_C1_SOURCE_MOD512 0x60000000
+#define DMA_RQ_C1_SOURCE_MOD1024 0x70000000
+#define DMA_RQ_C1_SOURCE_ON_HOST 0x80000000
+#define DMA_RQ_C1_COUNT_SHIFT 0
+
+/*
+ * The following defines are for the flags in the second control word of the
+ * on-chip generic DMA requestor.
+ */
+#define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK 0x0000003F
+#define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK 0x00000300
+#define DMA_RQ_C2_NO_VIRTUAL_SIGNAL 0x00000000
+#define DMA_RQ_C2_SIGNAL_EVERY_DMA 0x00000100
+#define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG 0x00000200
+#define DMA_RQ_C2_SIGNAL_DEST_PINGPONG 0x00000300
+#define DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000
+#define DMA_RQ_C2_AC_NONE 0x00000000
+#define DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000
+#define DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000
+#define DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000
+#define DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000
+#define DMA_RQ_C2_LOOP_END_MASK 0x0FFF0000
+#define DMA_RQ_C2_LOOP_MASK 0x30000000
+#define DMA_RQ_C2_NO_LOOP 0x00000000
+#define DMA_RQ_C2_ONE_PAGE_LOOP 0x10000000
+#define DMA_RQ_C2_TWO_PAGE_LOOP 0x20000000
+#define DMA_RQ_C2_MULTI_PAGE_LOOP 0x30000000
+#define DMA_RQ_C2_SIGNAL_LOOP_BACK 0x40000000
+#define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE 0x80000000
+#define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT 0
+#define DMA_RQ_C2_LOOP_END_SHIFT 16
+
+/*
+ * The following defines are for the flags in the source and destination words
+ * of the on-chip generic DMA requestor.
+ */
+#define DMA_RQ_SD_ADDRESS_MASK 0x0000FFFF
+#define DMA_RQ_SD_MEMORY_ID_MASK 0x000F0000
+#define DMA_RQ_SD_SP_PARAM_ADDR 0x00000000
+#define DMA_RQ_SD_SP_SAMPLE_ADDR 0x00010000
+#define DMA_RQ_SD_SP_PROGRAM_ADDR 0x00020000
+#define DMA_RQ_SD_SP_DEBUG_ADDR 0x00030000
+#define DMA_RQ_SD_OMNIMEM_ADDR 0x000E0000
+#define DMA_RQ_SD_END_FLAG 0x40000000
+#define DMA_RQ_SD_ERROR_FLAG 0x80000000
+#define DMA_RQ_SD_ADDRESS_SHIFT 0
+
+/*
+ * The following defines are for the flags in the page map address word of the
+ * on-chip generic DMA requestor.
+ */
+#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK 0x00000FF8
+#define DMA_RQ_PMA_PAGE_TABLE_MASK 0xFFFFF000
+#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT 3
+#define DMA_RQ_PMA_PAGE_TABLE_SHIFT 12
+
+#define BA1_VARIDEC_BUF_1 0x000
+
+#define BA1_PDTC 0x0c0 /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */
+#define BA1_PFIE 0x0c4 /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */
+#define BA1_PBA 0x0c8 /* BA1_PLAY_BUFFER_ADDRESS */
+#define BA1_PVOL 0x0f8 /* BA1_PLAY_VOLUME_REG */
+#define BA1_PSRC 0x288 /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */
+#define BA1_PCTL 0x2a4 /* BA1_PLAY_CONTROL_REG */
+#define BA1_PPI 0x2b4 /* BA1_PLAY_PHASE_INCREMENT_REG */
+
+#define BA1_CCTL 0x064 /* BA1_CAPTURE_CONTROL_REG */
+#define BA1_CIE 0x104 /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */
+#define BA1_CBA 0x10c /* BA1_CAPTURE_BUFFER_ADDRESS */
+#define BA1_CSRC 0x2c8 /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */
+#define BA1_CCI 0x2d8 /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */
+#define BA1_CD 0x2e0 /* BA1_CAPTURE_DELAY_REG */
+#define BA1_CPI 0x2f4 /* BA1_CAPTURE_PHASE_INCREMENT_REG */
+#define BA1_CVOL 0x2f8 /* BA1_CAPTURE_VOLUME_REG */
+
+#define BA1_CFG1 0x134 /* BA1_CAPTURE_FRAME_GROUP_1_REG */
+#define BA1_CFG2 0x138 /* BA1_CAPTURE_FRAME_GROUP_2_REG */
+#define BA1_CCST 0x13c /* BA1_CAPTURE_CONSTANT_REG */
+#define BA1_CSPB 0x340 /* BA1_CAPTURE_SPB_ADDRESS */
+
+/*
+ *
+ */
+
+#define CS46XX_MODE_OUTPUT (1<<0) /* MIDI UART - output */
+#define CS46XX_MODE_INPUT (1<<1) /* MIDI UART - input */
+
+/*
+ *
+ */
+
+#define SAVE_REG_MAX 0x10
+#define POWER_DOWN_ALL 0x7f0f
+
+/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
+#define MAX_NR_AC97 4
+#define CS46XX_PRIMARY_CODEC_INDEX 0
+#define CS46XX_SECONDARY_CODEC_INDEX 1
+#define CS46XX_SECONDARY_CODEC_OFFSET 0x80
+#define CS46XX_DSP_CAPTURE_CHANNEL 1
+
+/* capture */
+#define CS46XX_DSP_CAPTURE_CHANNEL 1
+
+/* mixer */
+#define CS46XX_MIXER_SPDIF_INPUT_ELEMENT 1
+#define CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT 2
+
+typedef struct _snd_cs46xx cs46xx_t;
+
+typedef struct _snd_cs46xx_pcm_t {
+ struct snd_dma_buffer hw_buf;
+
+ unsigned int ctl;
+ unsigned int shift; /* Shift count to trasform frames in bytes */
+ snd_pcm_indirect_t pcm_rec;
+ snd_pcm_substream_t *substream;
+
+ pcm_channel_descriptor_t * pcm_channel;
+
+ int pcm_channel_id; /* Fron Rear, Center Lfe ... */
+} cs46xx_pcm_t;
+
+typedef struct {
+ char name[24];
+ unsigned long base;
+ void __iomem *remap_addr;
+ unsigned long size;
+ struct resource *resource;
+} snd_cs46xx_region_t;
+
+struct _snd_cs46xx {
+ int irq;
+ unsigned long ba0_addr;
+ unsigned long ba1_addr;
+ union {
+ struct {
+ snd_cs46xx_region_t ba0;
+ snd_cs46xx_region_t data0;
+ snd_cs46xx_region_t data1;
+ snd_cs46xx_region_t pmem;
+ snd_cs46xx_region_t reg;
+ } name;
+ snd_cs46xx_region_t idx[5];
+ } region;
+
+ unsigned int mode;
+
+ struct {
+ struct snd_dma_buffer hw_buf;
+
+ unsigned int ctl;
+ unsigned int shift; /* Shift count to trasform frames in bytes */
+ snd_pcm_indirect_t pcm_rec;
+ snd_pcm_substream_t *substream;
+ } capt;
+
+
+ int nr_ac97_codecs;
+ ac97_bus_t *ac97_bus;
+ ac97_t *ac97[MAX_NR_AC97];
+
+ struct pci_dev *pci;
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_substream_t *midi_input;
+ snd_rawmidi_substream_t *midi_output;
+
+ spinlock_t reg_lock;
+ unsigned int midcr;
+ unsigned int uartm;
+
+ int amplifier;
+ void (*amplifier_ctrl)(cs46xx_t *, int);
+ void (*active_ctrl)(cs46xx_t *, int);
+ void (*mixer_init)(cs46xx_t *);
+
+ struct pci_dev *acpi_dev;
+ int acpi_port;
+ snd_kcontrol_t *eapd_switch; /* for amplifier hack */
+ int accept_valid; /* accept mmap valid (for OSS) */
+
+ struct gameport *gameport;
+
+#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
+ int current_gpio;
+#endif
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+ struct semaphore spos_mutex;
+
+ dsp_spos_instance_t * dsp_spos_instance;
+
+ snd_pcm_t *pcm_rear;
+ snd_pcm_t *pcm_center_lfe;
+ snd_pcm_t *pcm_iec958;
+#else /* for compatibility */
+ cs46xx_pcm_t *playback_pcm;
+ unsigned int play_ctl;
+#endif
+};
+
+int snd_cs46xx_create(snd_card_t *card,
+ struct pci_dev *pci,
+ int external_amp, int thinkpad,
+ cs46xx_t **rcodec);
+
+int snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
+int snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
+int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
+int snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
+int snd_cs46xx_mixer(cs46xx_t *chip);
+int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi);
+int snd_cs46xx_start_dsp(cs46xx_t *chip);
+int snd_cs46xx_gameport(cs46xx_t *chip);
+
+#endif /* __SOUND_CS46XX_H */
diff --git a/include/sound/cs46xx_dsp_scb_types.h b/include/sound/cs46xx_dsp_scb_types.h
new file mode 100644
index 0000000..3f990a3
--- /dev/null
+++ b/include/sound/cs46xx_dsp_scb_types.h
@@ -0,0 +1,1216 @@
+/*
+ * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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
+ *
+ *
+ * NOTE: comments are copy/paste from cwcemb80.lst
+ * provided by Tom Woller at Cirrus (my only
+ * documentation about the SP OS running inside
+ * the DSP)
+ */
+
+#ifndef __CS46XX_DSP_SCB_TYPES_H__
+#define __CS46XX_DSP_SCB_TYPES_H__
+
+#include <asm/byteorder.h>
+
+#ifndef ___DSP_DUAL_16BIT_ALLOC
+#if defined(__LITTLE_ENDIAN)
+#define ___DSP_DUAL_16BIT_ALLOC(a,b) u16 a; u16 b;
+#elif defined(__BIG_ENDIAN)
+#define ___DSP_DUAL_16BIT_ALLOC(a,b) u16 b; u16 a;
+#else
+#error Not __LITTLE_ENDIAN and not __BIG_ENDIAN, then what ???
+#endif
+#endif
+
+/* This structs are used internally by the SP */
+
+typedef struct _basic_dma_req_t {
+ /* DMA Requestor Word 0 (DCW) fields:
+
+ 31 [30-28]27 [26:24] 23 22 21 20 [19:18] [17:16] 15 14 13 12 11 10 9 8 7 6 [5:0]
+ _______________________________________________________________________________________
+ |S| SBT |D| DBT |wb|wb| | | LS | SS |Opt|Do|SSG|DSG| | | | | | | Dword |
+ |H|_____ |H|_________|S_|D |__|__|______|_______|___|ne|__ |__ |__|__|_|_|_|_|_Count -1|
+ */
+ u32 dcw; /* DMA Control Word */
+ u32 dmw; /* DMA Mode Word */
+ u32 saw; /* Source Address Word */
+ u32 daw; /* Destination Address Word */
+} basic_dma_req_t;
+
+typedef struct _scatter_gather_ext_t {
+ u32 npaw; /* Next-Page Address Word */
+
+ /* DMA Requestor Word 5 (NPCW) fields:
+
+ 31-30 29 28 [27:16] [15:12] [11:3] [2:0]
+ _________________________________________________________________________________________
+ |SV |LE|SE| Sample-end byte offset | | Page-map entry offset for next | |
+ |page|__|__| ___________________________|_________|__page, if !sample-end___________|____|
+ */
+ u32 npcw; /* Next-Page Control Word */
+ u32 lbaw; /* Loop-Begin Address Word */
+ u32 nplbaw; /* Next-Page after Loop-Begin Address Word */
+ u32 sgaw; /* Scatter/Gather Address Word */
+} scatter_gather_ext_t;
+
+typedef struct _volume_control_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ rightTarg, /* Target volume for left & right channels */
+ leftTarg
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ rightVol, /* Current left & right channel volumes */
+ leftVol
+ )
+} volume_control_t;
+
+/* Generic stream control block (SCB) structure definition */
+typedef struct _generic_scb_t {
+ /* For streaming I/O, the DSP should never alter any words in the DMA
+ requestor or the scatter/gather extension. Only ad hoc DMA request
+ streams are free to alter the requestor (currently only occur in the
+ DOS-based MIDI controller and in debugger-inserted code).
+
+ If an SCB does not have any associated DMA requestor, these 9 ints
+ may be freed for use by other tasks, but the pointer to the SCB must
+ still be such that the insOrd:nextSCB appear at offset 9 from the
+ SCB pointer.
+
+ Basic (non scatter/gather) DMA requestor (4 ints)
+ */
+
+ /* Initialized by the host, only modified by DMA
+ R/O for the DSP task */
+ basic_dma_req_t basic_req; /* Optional */
+
+ /* Scatter/gather DMA requestor extension (5 ints)
+ Initialized by the host, only modified by DMA
+ DSP task never needs to even read these.
+ */
+ scatter_gather_ext_t sg_ext; /* Optional */
+
+ /* Sublist pointer & next stream control block (SCB) link.
+ Initialized & modified by the host R/O for the DSP task
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ /* Pointer to this tasks parameter block & stream function pointer
+ Initialized by the host R/O for the DSP task */
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ /* rsConfig register for stream buffer (rsDMA reg.
+ is loaded from basicReq.daw for incoming streams, or
+ basicReq.saw, for outgoing streams)
+
+ 31 30 29 [28:24] [23:16] 15 14 13 12 11 10 9 8 7 6 5 4 [3:0]
+ ______________________________________________________________________________
+ |DMA |D|maxDMAsize| streamNum|dir|p| | | | | | |ds |shr 1|rev Cy | mod |
+ |prio |_|__________|__________|___|_|__|__|__|__|_|_|___|_____|_______|_______|
+ 31 30 29 [28:24] [23:16] 15 14 13 12 11 10 9 8 7 6 5 4 [3:0]
+
+
+ Initialized by the host R/O for the DSP task
+ */
+ u32 strm_rs_config; /* REQUIRED */
+ //
+ /* On mixer input streams: indicates mixer input stream configuration
+ On Tees, this is copied from the stream being snooped
+
+ Stream sample pointer & MAC-unit mode for this stream
+
+ Initialized by the host Updated by the DSP task
+ */
+ u32 strm_buf_ptr; /* REQUIRED */
+
+ /* On mixer input streams: points to next mixer input and is updated by the
+ mixer subroutine in the "parent" DSP task
+ (least-significant 16 bits are preserved, unused)
+
+ On Tees, the pointer is copied from the stream being snooped on
+ initialization, and, subsequently, it is copied into the
+ stream being snooped.
+
+ On wavetable/3D voices: the strmBufPtr will use all 32 bits to allow for
+ fractional phase accumulation
+
+ Fractional increment per output sample in the input sample buffer
+
+ (Not used on mixer input streams & redefined on Tees)
+ On wavetable/3D voices: this 32-bit word specifies the integer.fractional
+ increment per output sample.
+ */
+ u32 strmPhiIncr;
+
+
+ /* Standard stereo volume control
+ Initialized by the host (host updates target volumes)
+
+ Current volumes update by the DSP task
+ On mixer input streams: required & updated by the mixer subroutine in the
+ "parent" DSP task
+
+ On Tees, both current & target volumes are copied up on initialization,
+ and, subsequently, the target volume is copied up while the current
+ volume is copied down.
+
+ These two 32-bit words are redefined for wavetable & 3-D voices.
+ */
+ volume_control_t vol_ctrl_t; /* Optional */
+} generic_scb_t;
+
+
+typedef struct _spos_control_block_t {
+ /* WARNING: Certain items in this structure are modified by the host
+ Any dword that can be modified by the host, must not be
+ modified by the SP as the host can only do atomic dword
+ writes, and to do otherwise, even a read modify write,
+ may lead to corrupted data on the SP.
+
+ This rule does not apply to one off boot time initialisation prior to starting the SP
+ */
+
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* First element on the Hyper forground task tree */
+ hfg_tree_root_ptr, /* HOST */
+ /* First 3 dwords are written by the host and read-only on the DSP */
+ hfg_stack_base /* HOST */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Point to this data structure to enable easy access */
+ spos_cb_ptr, /* SP */
+ prev_task_tree_ptr /* SP && HOST */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Currently Unused */
+ xxinterval_timer_period,
+ /* Enable extension of SPOS data structure */
+ HFGSPB_ptr
+ )
+
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ xxnum_HFG_ticks_thisInterval,
+ /* Modified by the DSP */
+ xxnum_tntervals
+ )
+
+
+ /* Set by DSP upon encountering a trap (breakpoint) or a spurious
+ interrupt. The host must clear this dword after reading it
+ upon receiving spInt1. */
+ ___DSP_DUAL_16BIT_ALLOC(
+ spurious_int_flag, /* (Host & SP) Nature of the spurious interrupt */
+ trap_flag /* (Host & SP) Nature of detected Trap */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused2,
+ invalid_IP_flag /* (Host & SP ) Indicate detection of invalid instruction pointer */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* pointer to forground task tree header for use in next task search */
+ fg_task_tree_hdr_ptr, /* HOST */
+ /* Data structure for controlling synchronous link update */
+ hfg_sync_update_ptr /* HOST */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ begin_foreground_FCNT, /* SP */
+ /* Place holder for holding sleep timing */
+ last_FCNT_before_sleep /* SP */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused7, /* SP */
+ next_task_treePtr /* SP */
+ )
+
+ u32 unused5;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ active_flags, /* SP */
+ /* State flags, used to assist control of execution of Hyper Forground */
+ HFG_flags /* SP */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused9,
+ unused8
+ )
+
+ /* Space for saving enough context so that we can set up enough
+ to save some more context.
+ */
+ u32 rFE_save_for_invalid_IP;
+ u32 r32_save_for_spurious_int;
+ u32 r32_save_for_trap;
+ u32 r32_save_for_HFG;
+} spos_control_block_t;
+
+/* SPB for MIX_TO_OSTREAM algorithm family */
+typedef struct _mix2_ostream_spb_t
+{
+ /* 16b.16b integer.frac approximation to the
+ number of 3 sample triplets to output each
+ frame. (approximation must be floor, to
+ insure that the fractional error is always
+ positive)
+ */
+ u32 outTripletsPerFrame;
+
+ /* 16b.16b integer.frac accumulated number of
+ output triplets since the start of group
+ */
+ u32 accumOutTriplets;
+} mix2_ostream_spb_t;
+
+/* SCB for Timing master algorithm */
+typedef struct _timing_master_scb_t {
+ /* First 12 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Initial values are 0000:xxxx */
+ reserved,
+ extra_sample_accum
+ )
+
+
+ /* Initial values are xxxx:0000
+ hi: Current CODEC output FIFO pointer
+ (0 to 0x0f)
+ lo: Flag indicating that the CODEC
+ FIFO is sync'd (host clears to
+ resynchronize the FIFO pointer
+ upon start/restart)
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ codec_FIFO_syncd,
+ codec_FIFO_ptr
+ )
+
+ /* Init. 8000:0005 for 44.1k
+ 8000:0001 for 48k
+ hi: Fractional sample accumulator 0.16b
+ lo: Number of frames remaining to be
+ processed in the current group of
+ frames
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ frac_samp_accum_qm1,
+ TM_frms_left_in_group
+ )
+
+ /* Init. 0001:0005 for 44.1k
+ 0000:0001 for 48k
+ hi: Fractional sample correction factor 0.16b
+ to be added every frameGroupLength frames
+ to correct for truncation error in
+ nsamp_per_frm_q15
+ lo: Number of frames in the group
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ frac_samp_correction_qm1,
+ TM_frm_group_length
+ )
+
+ /* Init. 44.1k*65536/8k = 0x00058333 for 44.1k
+ 48k*65536/8k = 0x00060000 for 48k
+ 16b.16b integer.frac approximation to the
+ number of samples to output each frame.
+ (approximation must be floor, to insure */
+ u32 nsamp_per_frm_q15;
+} timing_master_scb_t;
+
+/* SCB for CODEC output algorithm */
+typedef struct _codec_output_scb_t {
+ /* First 13 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ u32 strm_rs_config; /* REQUIRED */
+
+ u32 strm_buf_ptr; /* REQUIRED */
+
+ /* NOTE: The CODEC output task reads samples from the first task on its
+ sublist at the stream buffer pointer (init. to lag DMA destination
+ address word). After the required number of samples is transferred,
+ the CODEC output task advances sub_list_ptr->strm_buf_ptr past the samples
+ consumed.
+ */
+
+ /* Init. 0000:0010 for SDout
+ 0060:0010 for SDout2
+ 0080:0010 for SDout3
+ hi: Base IO address of FIFO to which
+ the left-channel samples are to
+ be written.
+ lo: Displacement for the base IO
+ address for left-channel to obtain
+ the base IO address for the FIFO
+ to which the right-channel samples
+ are to be written.
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ left_chan_base_IO_addr,
+ right_chan_IO_disp
+ )
+
+
+ /* Init: 0x0080:0004 for non-AC-97
+ Init: 0x0080:0000 for AC-97
+ hi: Exponential volume change rate
+ for input stream
+ lo: Positive shift count to shift the
+ 16-bit input sample to obtain the
+ 32-bit output word
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ CO_scale_shift_count,
+ CO_exp_vol_change_rate
+ )
+
+ /* Pointer to SCB at end of input chain */
+ ___DSP_DUAL_16BIT_ALLOC(
+ reserved,
+ last_sub_ptr
+ )
+} codec_output_scb_t;
+
+/* SCB for CODEC input algorithm */
+typedef struct _codec_input_scb_t {
+ /* First 13 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ u32 strm_rs_config; /* REQUIRED */
+ u32 strm_buf_ptr; /* REQUIRED */
+
+ /* NOTE: The CODEC input task reads samples from the hardware FIFO
+ sublist at the DMA source address word (sub_list_ptr->basic_req.saw).
+ After the required number of samples is transferred, the CODEC
+ output task advances sub_list_ptr->basic_req.saw past the samples
+ consumed. SPuD must initialize the sub_list_ptr->basic_req.saw
+ to point half-way around from the initial sub_list_ptr->strm_nuf_ptr
+ to allow for lag/lead.
+ */
+
+ /* Init. 0000:0010 for SDout
+ 0060:0010 for SDout2
+ 0080:0010 for SDout3
+ hi: Base IO address of FIFO to which
+ the left-channel samples are to
+ be written.
+ lo: Displacement for the base IO
+ address for left-channel to obtain
+ the base IO address for the FIFO
+ to which the right-channel samples
+ are to be written.
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ rightChanINdisp,
+ left_chan_base_IN_addr
+ )
+ /* Init. ?:fffc
+ lo: Negative shift count to shift the
+ 32-bit input dword to obtain the
+ 16-bit sample msb-aligned (count
+ is negative to shift left)
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ scaleShiftCount,
+ reserver1
+ )
+
+ u32 reserved2;
+} codec_input_scb_t;
+
+
+typedef struct _pcm_serial_input_scb_t {
+ /* First 13 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ u32 strm_buf_ptr; /* REQUIRED */
+ u32 strm_rs_config; /* REQUIRED */
+
+ /* Init. Ptr to CODEC input SCB
+ hi: Pointer to the SCB containing the
+ input buffer to which CODEC input
+ samples are written
+ lo: Flag indicating the link to the CODEC
+ input task is to be initialized
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ init_codec_input_link,
+ codec_input_buf_scb
+ )
+
+ /* Initialized by the host (host updates target volumes) */
+ volume_control_t psi_vol_ctrl;
+
+} pcm_serial_input_scb_t;
+
+typedef struct _src_task_scb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ frames_left_in_gof,
+ gofs_left_in_sec
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ const2_thirds,
+ num_extra_tnput_samples
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ cor_per_gof,
+ correction_per_sec
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ output_buf_producer_ptr,
+ junk_DMA_MID
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ gof_length,
+ gofs_per_sec
+ )
+
+ u32 input_buf_strm_config;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ reserved_for_SRC_use,
+ input_buf_consumer_ptr
+ )
+
+ u32 accum_phi;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ exp_src_vol_change_rate,
+ input_buf_producer_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ src_next_scb,
+ src_sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ src_entry_point,
+ src_this_sbp
+ )
+
+ u32 src_strm_rs_config;
+ u32 src_strm_buf_ptr;
+
+ u32 phiIncr6int_26frac;
+
+ volume_control_t src_vol_ctrl;
+} src_task_scb_t;
+
+typedef struct _decimate_by_pow2_scb_t {
+ /* decimationFactor = 2, 4, or 8 (larger factors waste too much memory
+ when compared to cascading decimators)
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_coef_base_ptr,
+ dec2_coef_increment
+ )
+
+ /* coefIncrement = 128 / decimationFactor (for our ROM filter)
+ coefBasePtr = 0x8000 (for our ROM filter)
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_in_samples_per_out_triplet,
+ dec2_extra_in_samples
+ )
+ /* extraInSamples: # of accumulated, unused input samples (init. to 0)
+ inSamplesPerOutTriplet = 3 * decimationFactor
+ */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_const2_thirds,
+ dec2_half_num_taps_mp5
+ )
+ /* halfNumTapsM5: (1/2 number of taps in decimation filter) minus 5
+ const2thirds: constant 2/3 in 16Q0 format (sign.15)
+ */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_output_buf_producer_ptr,
+ dec2_junkdma_mid
+ )
+
+ u32 dec2_reserved2;
+
+ u32 dec2_input_nuf_strm_config;
+ /* inputBufStrmConfig: rsConfig for the input buffer to the decimator
+ (buffer size = decimationFactor * 32 dwords)
+ */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_phi_incr,
+ dec2_input_buf_consumer_ptr
+ )
+ /* inputBufConsumerPtr: Input buffer read pointer (into SRC filter)
+ phiIncr = decimationFactor * 4
+ */
+
+ u32 dec2_reserved3;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_exp_vol_change_rate,
+ dec2_input_buf_producer_ptr
+ )
+ /* inputBufProducerPtr: Input buffer write pointer
+ expVolChangeRate: Exponential volume change rate for possible
+ future mixer on input streams
+ */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_next_scb,
+ dec2_sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ dec2_entry_point,
+ dec2_this_spb
+ )
+
+ u32 dec2_strm_rs_config;
+ u32 dec2_strm_buf_ptr;
+
+ u32 dec2_reserved4;
+
+ volume_control_t dec2_vol_ctrl; /* Not used! */
+} decimate_by_pow2_scb_t;
+
+typedef struct _vari_decimate_scb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_frames_left_in_gof,
+ vdec_gofs_left_in_sec
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_const2_thirds,
+ vdec_extra_in_samples
+ )
+ /* extraInSamples: # of accumulated, unused input samples (init. to 0)
+ const2thirds: constant 2/3 in 16Q0 format (sign.15) */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_cor_per_gof,
+ vdec_correction_per_sec
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_output_buf_producer_ptr,
+ vdec_input_buf_consumer_ptr
+ )
+ /* inputBufConsumerPtr: Input buffer read pointer (into SRC filter) */
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_gof_length,
+ vdec_gofs_per_sec
+ )
+
+ u32 vdec_input_buf_strm_config;
+ /* inputBufStrmConfig: rsConfig for the input buffer to the decimator
+ (buffer size = 64 dwords) */
+ u32 vdec_coef_increment;
+ /* coefIncrement = - 128.0 / decimationFactor (as a 32Q15 number) */
+
+ u32 vdec_accumphi;
+ /* accumPhi: accumulated fractional phase increment (6.26) */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_exp_vol_change_rate,
+ vdec_input_buf_producer_ptr
+ )
+ /* inputBufProducerPtr: Input buffer write pointer
+ expVolChangeRate: Exponential volume change rate for possible
+ future mixer on input streams */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_next_scb,
+ vdec_sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ vdec_entry_point,
+ vdec_this_spb
+ )
+
+ u32 vdec_strm_rs_config;
+ u32 vdec_strm_buf_ptr;
+
+ u32 vdec_phi_incr_6int_26frac;
+
+ volume_control_t vdec_vol_ctrl;
+} vari_decimate_scb_t;
+
+
+/* SCB for MIX_TO_OSTREAM algorithm family */
+typedef struct _mix2_ostream_scb_t {
+ /* First 13 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ u32 strm_rs_config; /* REQUIRED */
+ u32 strm_buf_ptr; /* REQUIRED */
+
+
+ /* hi: Number of mixed-down input triplets
+ computed since start of group
+ lo: Number of frames remaining to be
+ processed in the current group of
+ frames
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ frames_left_in_group,
+ accum_input_triplets
+ )
+
+ /* hi: Exponential volume change rate
+ for mixer on input streams
+ lo: Number of frames in the group
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ frame_group_length,
+ exp_vol_change_rate
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ const_FFFF,
+ const_zero
+ )
+} mix2_ostream_scb_t;
+
+
+/* SCB for S16_MIX algorithm */
+typedef struct _mix_only_scb_t {
+ /* First 13 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ u32 strm_rs_config; /* REQUIRED */
+ u32 strm_buf_ptr; /* REQUIRED */
+
+ u32 reserved;
+ volume_control_t vol_ctrl;
+} mix_only_scb_t;
+
+/* SCB for the async. CODEC input algorithm */
+typedef struct _async_codec_input_scb_t {
+ u32 io_free2;
+
+ u32 io_current_total;
+ u32 io_previous_total;
+
+ u16 io_count;
+ u16 io_count_limit;
+
+ u16 o_fifo_base_addr;
+ u16 ost_mo_format;
+ /* 1 = stereo; 0 = mono
+ xxx for ASER 1 (not allowed); 118 for ASER2 */
+
+ u32 ostrm_rs_config;
+ u32 ostrm_buf_ptr;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ io_sclks_per_lr_clk,
+ io_io_enable
+ )
+
+ u32 io_free4;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ io_next_scb,
+ io_sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ io_entry_point,
+ io_this_spb
+ )
+
+ u32 istrm_rs_config;
+ u32 istrm_buf_ptr;
+
+ /* Init. 0000:8042: for ASER1
+ 0000:8044: for ASER2 */
+ ___DSP_DUAL_16BIT_ALLOC(
+ io_stat_reg_addr,
+ iofifo_pointer
+ )
+
+ /* Init 1 stero:100 ASER1
+ Init 0 mono:110 ASER2
+ */
+ ___DSP_DUAL_16BIT_ALLOC(
+ ififo_base_addr,
+ ist_mo_format
+ )
+
+ u32 i_free;
+} async_codec_input_scb_t;
+
+
+/* SCB for the SP/DIF CODEC input and output */
+typedef struct _spdifiscb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ status_ptr,
+ status_start_ptr
+ )
+
+ u32 current_total;
+ u32 previous_total;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ count,
+ count_limit
+ )
+
+ u32 status_data;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ status,
+ free4
+ )
+
+ u32 free3;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ free2,
+ bit_count
+ )
+
+ u32 temp_status;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_SCB,
+ sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point,
+ this_spb
+ )
+
+ u32 strm_rs_config;
+ u32 strm_buf_ptr;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ stat_reg_addr,
+ fifo_pointer
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ fifo_base_addr,
+ st_mo_format
+ )
+
+ u32 free1;
+} spdifiscb_t;
+
+
+/* SCB for the SP/DIF CODEC input and output */
+typedef struct _spdifoscb_t {
+
+
+ u32 free2;
+
+ u32 free3[4];
+
+ /* Need to be here for compatibility with AsynchFGTxCode */
+ u32 strm_rs_config;
+
+ u32 strm_buf_ptr;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ status,
+ free5
+ )
+
+ u32 free4;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb,
+ sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point,
+ this_spb
+ )
+
+ u32 free6[2];
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ stat_reg_addr,
+ fifo_pointer
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ fifo_base_addr,
+ st_mo_format
+ )
+
+ u32 free1;
+} spdifoscb_t;
+
+
+
+typedef struct _asynch_fg_rx_scb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ bot_buf_mask,
+ buf_Mask
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ max,
+ min
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ old_producer_pointer,
+ hfg_scb_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ delta,
+ adjust_count
+ )
+
+ u32 unused2[5];
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ sibling_ptr,
+ child_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ code_ptr,
+ this_ptr
+ )
+
+ u32 strm_rs_config;
+
+ u32 strm_buf_ptr;
+
+ u32 unused_phi_incr;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ right_targ,
+ left_targ
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ right_vol,
+ left_vol
+ )
+} asynch_fg_rx_scb_t;
+
+
+
+typedef struct _asynch_fg_tx_scb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ not_buf_mask,
+ buf_mask
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ max,
+ min
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused1,
+ hfg_scb_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ delta,
+ adjust_count
+ )
+
+ u32 accum_phi;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused2,
+ const_one_third
+ )
+
+ u32 unused3[3];
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ sibling_ptr,
+ child_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ codePtr,
+ this_ptr
+ )
+
+ u32 strm_rs_config;
+
+ u32 strm_buf_ptr;
+
+ u32 phi_incr;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused_right_targ,
+ unused_left_targ
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused_right_vol,
+ unused_left_vol
+ )
+} asynch_fg_tx_scb_t;
+
+
+typedef struct _output_snoop_scb_t {
+ /* First 13 dwords from generic_scb_t */
+ basic_dma_req_t basic_req; /* Optional */
+ scatter_gather_ext_t sg_ext; /* Optional */
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb, /* REQUIRED */
+ sub_list_ptr /* REQUIRED */
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* REQUIRED */
+ this_spb /* REQUIRED */
+ )
+
+ u32 strm_rs_config; /* REQUIRED */
+ u32 strm_buf_ptr; /* REQUIRED */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ init_snoop_input_link,
+ snoop_child_input_scb
+ )
+
+ u32 snoop_input_buf_ptr;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ reserved,
+ input_scb
+ )
+} output_snoop_scb_t;
+
+typedef struct _spio_write_scb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ address1,
+ address2
+ )
+
+ u32 data1;
+
+ u32 data2;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ address3,
+ address4
+ )
+
+ u32 data3;
+
+ u32 data4;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ unused1,
+ data_ptr
+ )
+
+ u32 unused2[2];
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ sibling_ptr,
+ child_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point,
+ this_ptr
+ )
+
+ u32 unused3[5];
+} spio_write_scb_t;
+
+typedef struct _magic_snoop_task_t {
+ u32 i0;
+ u32 i1;
+
+ u32 strm_buf_ptr1;
+
+ u16 i2;
+ u16 snoop_scb;
+
+ u32 i3;
+ u32 i4;
+ u32 i5;
+ u32 i6;
+
+ u32 i7;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb,
+ sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point,
+ this_ptr
+ )
+
+ u32 strm_buf_config;
+ u32 strm_buf_ptr2;
+
+ u32 i8;
+
+ volume_control_t vdec_vol_ctrl;
+} magic_snoop_task_t;
+
+
+typedef struct _filter_scb_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ a0_right, /* 0x00 */
+ a0_left
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ a1_right, /* 0x01 */
+ a1_left
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ a2_right, /* 0x02 */
+ a2_left
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ output_buf_ptr, /* 0x03 */
+ init
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ filter_unused3, /* 0x04 */
+ filter_unused2
+ )
+
+ u32 prev_sample_output1; /* 0x05 */
+ u32 prev_sample_output2; /* 0x06 */
+ u32 prev_sample_input1; /* 0x07 */
+ u32 prev_sample_input2; /* 0x08 */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ next_scb_ptr, /* 0x09 */
+ sub_list_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ entry_point, /* 0x0A */
+ spb_ptr
+ )
+
+ u32 strm_rs_config; /* 0x0B */
+ u32 strm_buf_ptr; /* 0x0C */
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ b0_right, /* 0x0D */
+ b0_left
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ b1_right, /* 0x0E */
+ b1_left
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ b2_right, /* 0x0F */
+ b2_left
+ )
+} filter_scb_t;
+#endif /* __DSP_SCB_TYPES_H__ */
diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h
new file mode 100644
index 0000000..10014cb6
--- /dev/null
+++ b/include/sound/cs46xx_dsp_spos.h
@@ -0,0 +1,233 @@
+/*
+ * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 __CS46XX_DSP_SPOS_H__
+#define __CS46XX_DSP_SPOS_H__
+
+#include "cs46xx_dsp_scb_types.h"
+#include "cs46xx_dsp_task_types.h"
+
+#define SYMBOL_CONSTANT 0x0
+#define SYMBOL_SAMPLE 0x1
+#define SYMBOL_PARAMETER 0x2
+#define SYMBOL_CODE 0x3
+
+#define SEGTYPE_SP_PROGRAM 0x00000001
+#define SEGTYPE_SP_PARAMETER 0x00000002
+#define SEGTYPE_SP_SAMPLE 0x00000003
+#define SEGTYPE_SP_COEFFICIENT 0x00000004
+
+#define DSP_SPOS_UU 0x0deadul /* unused */
+#define DSP_SPOS_DC 0x0badul /* don't care */
+#define DSP_SPOS_DC_DC 0x0bad0badul /* don't care */
+#define DSP_SPOS_UUUU 0xdeadc0edul /* unused */
+#define DSP_SPOS_UUHI 0xdeadul
+#define DSP_SPOS_UULO 0xc0edul
+#define DSP_SPOS_DCDC 0x0badf1d0ul /* don't care */
+#define DSP_SPOS_DCDCHI 0x0badul
+#define DSP_SPOS_DCDCLO 0xf1d0ul
+
+#define DSP_MAX_TASK_NAME 60
+#define DSP_MAX_SYMBOL_NAME 100
+#define DSP_MAX_SCB_NAME 60
+#define DSP_MAX_SCB_DESC 200
+#define DSP_MAX_TASK_DESC 50
+
+#define DSP_MAX_PCM_CHANNELS 32
+#define DSP_MAX_SRC_NR 14
+
+#define DSP_PCM_MAIN_CHANNEL 1
+#define DSP_PCM_REAR_CHANNEL 2
+#define DSP_PCM_CENTER_LFE_CHANNEL 3
+#define DSP_PCM_S71_CHANNEL 4 /* surround 7.1 */
+#define DSP_IEC958_CHANNEL 5
+
+#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
+#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
+#define DSP_SPDIF_STATUS_HW_ENABLED 4
+#define DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED 8
+
+struct _dsp_module_desc_t;
+
+typedef struct _symbol_entry_t {
+ u32 address;
+ char symbol_name[DSP_MAX_SYMBOL_NAME];
+ int symbol_type;
+
+ /* initialized by driver */
+ struct _dsp_module_desc_t * module;
+ int deleted;
+} symbol_entry_t;
+
+typedef struct _symbol_desc_t {
+ int nsymbols;
+
+ symbol_entry_t * symbols;
+
+ /* initialized by driver */
+ int highest_frag_index;
+} symbol_desc_t;
+
+
+typedef struct _segment_desc_t {
+ int segment_type;
+ u32 offset;
+ u32 size;
+ u32 * data;
+} segment_desc_t;
+
+typedef struct _dsp_module_desc_t {
+ char * module_name;
+ symbol_desc_t symbol_table;
+ int nsegments;
+ segment_desc_t * segments;
+
+ /* initialized by driver */
+ u32 overlay_begin_address;
+ u32 load_address;
+ int nfixups;
+} dsp_module_desc_t;
+
+typedef struct _dsp_scb_descriptor_t {
+ char scb_name[DSP_MAX_SCB_NAME];
+ u32 address;
+ int index;
+
+ struct _dsp_scb_descriptor_t * sub_list_ptr;
+ struct _dsp_scb_descriptor_t * next_scb_ptr;
+ struct _dsp_scb_descriptor_t * parent_scb_ptr;
+
+ symbol_entry_t * task_entry;
+ symbol_entry_t * scb_symbol;
+
+ snd_info_entry_t *proc_info;
+ int ref_count;
+ spinlock_t lock;
+
+ int deleted;
+} dsp_scb_descriptor_t;
+
+typedef struct _dsp_task_descriptor_t {
+ char task_name[DSP_MAX_TASK_NAME];
+ int size;
+ u32 address;
+ int index;
+} dsp_task_descriptor_t;
+
+typedef struct _pcm_channel_descriptor_t {
+ int active;
+ int src_slot;
+ int pcm_slot;
+ u32 sample_rate;
+ u32 unlinked;
+ dsp_scb_descriptor_t * pcm_reader_scb;
+ dsp_scb_descriptor_t * src_scb;
+ dsp_scb_descriptor_t * mixer_scb;
+
+ void * private_data;
+} pcm_channel_descriptor_t;
+
+typedef struct _dsp_spos_instance_t {
+ symbol_desc_t symbol_table; /* currently availble loaded symbols in SP */
+
+ int nmodules;
+ dsp_module_desc_t * modules; /* modules loaded into SP */
+
+ segment_desc_t code;
+
+ /* Main PCM playback mixer */
+ dsp_scb_descriptor_t * master_mix_scb;
+ u16 dac_volume_right;
+ u16 dac_volume_left;
+
+ /* Rear/surround PCM playback mixer */
+ dsp_scb_descriptor_t * rear_mix_scb;
+
+ /* Center/LFE mixer */
+ dsp_scb_descriptor_t * center_lfe_mix_scb;
+
+ int npcm_channels;
+ int nsrc_scb;
+ pcm_channel_descriptor_t pcm_channels[DSP_MAX_PCM_CHANNELS];
+ int src_scb_slots[DSP_MAX_SRC_NR];
+
+ /* cache this symbols */
+ symbol_entry_t * null_algorithm; /* used by PCMreaderSCB's */
+ symbol_entry_t * s16_up; /* used by SRCtaskSCB's */
+
+ /* proc fs */
+ snd_card_t * snd_card;
+ snd_info_entry_t * proc_dsp_dir;
+ snd_info_entry_t * proc_sym_info_entry;
+ snd_info_entry_t * proc_modules_info_entry;
+ snd_info_entry_t * proc_parameter_dump_info_entry;
+ snd_info_entry_t * proc_sample_dump_info_entry;
+
+ /* SCB's descriptors */
+ int nscb;
+ int scb_highest_frag_index;
+ dsp_scb_descriptor_t scbs[DSP_MAX_SCB_DESC];
+ snd_info_entry_t * proc_scb_info_entry;
+ dsp_scb_descriptor_t * the_null_scb;
+
+ /* Task's descriptors */
+ int ntask;
+ dsp_task_descriptor_t tasks[DSP_MAX_TASK_DESC];
+ snd_info_entry_t * proc_task_info_entry;
+
+ /* SPDIF status */
+ int spdif_status_out;
+ int spdif_status_in;
+ u16 spdif_input_volume_right;
+ u16 spdif_input_volume_left;
+ /* spdif channel status,
+ left right and user validity bits */
+ unsigned int spdif_csuv_default;
+ unsigned int spdif_csuv_stream;
+
+ /* SPDIF input sample rate converter */
+ dsp_scb_descriptor_t * spdif_in_src;
+ /* SPDIF input asynch. receiver */
+ dsp_scb_descriptor_t * asynch_rx_scb;
+
+ /* Capture record mixer SCB */
+ dsp_scb_descriptor_t * record_mixer_scb;
+
+ /* CODEC input SCB */
+ dsp_scb_descriptor_t * codec_in_scb;
+
+ /* reference snooper */
+ dsp_scb_descriptor_t * ref_snoop_scb;
+
+ /* SPDIF output PCM reference */
+ dsp_scb_descriptor_t * spdif_pcm_input_scb;
+
+ /* asynch TX task */
+ dsp_scb_descriptor_t * asynch_tx_scb;
+
+ /* record sources */
+ dsp_scb_descriptor_t * pcm_input;
+ dsp_scb_descriptor_t * adc_input;
+
+ int spdif_in_sample_rate;
+} dsp_spos_instance_t;
+
+#endif /* __DSP_SPOS_H__ */
diff --git a/include/sound/cs46xx_dsp_task_types.h b/include/sound/cs46xx_dsp_task_types.h
new file mode 100644
index 0000000..5dd3bf6
--- /dev/null
+++ b/include/sound/cs46xx_dsp_task_types.h
@@ -0,0 +1,253 @@
+/*
+ * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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
+ *
+ *
+ * NOTE: comments are copy/paste from cwcemb80.lst
+ * provided by Tom Woller at Cirrus (my only
+ * documentation about the SP OS running inside
+ * the DSP)
+ */
+
+#ifndef __CS46XX_DSP_TASK_TYPES_H__
+#define __CS46XX_DSP_TASK_TYPES_H__
+
+#include "cs46xx_dsp_scb_types.h"
+
+/*********************************************************************************************
+Example hierarchy of stream control blocks in the SP
+
+hfgTree
+Ptr____Call (c)
+ \
+ -------+------ ------------- ------------- ------------- -----
+| SBlaster IF |______\| Foreground |___\| Middlegr'nd |___\| Background |___\| Nul |
+| |Goto /| tree header |g /| tree header |g /| tree header |g /| SCB |r
+ -------------- (g) ------------- ------------- ------------- -----
+ |c |c |c |c
+ | | | |
+ \/ ------------- ------------- -------------
+ | Foreground |_\ | Middlegr'nd |_\ | Background |_\
+ | tree |g/ | tree |g/ | tree |g/
+ ------------- ------------- -------------
+ |c |c |c
+ | | |
+ \/ \/ \/
+
+*********************************************************************************************/
+
+#define HFG_FIRST_EXECUTE_MODE 0x0001
+#define HFG_FIRST_EXECUTE_MODE_BIT 0
+#define HFG_CONTEXT_SWITCH_MODE 0x0002
+#define HFG_CONTEXT_SWITCH_MODE_BIT 1
+
+#define MAX_FG_STACK_SIZE 32 /* THESE NEED TO BE COMPUTED PROPERLY */
+#define MAX_MG_STACK_SIZE 16
+#define MAX_BG_STACK_SIZE 9
+#define MAX_HFG_STACK_SIZE 4
+
+#define SLEEP_ACTIVE_INCREMENT 0 /* Enable task tree thread to go to sleep
+ This should only ever be used on the Background thread */
+#define STANDARD_ACTIVE_INCREMENT 1 /* Task tree thread normal operation */
+#define SUSPEND_ACTIVE_INCREMENT 2 /* Cause execution to suspend in the task tree thread
+ This should only ever be used on the Background thread */
+
+#define HOSTFLAGS_DISABLE_BG_SLEEP 0 /* Host-controlled flag that determines whether we go to sleep
+ at the end of BG */
+
+/* Minimal context save area for Hyper Forground */
+typedef struct _hf_save_area_t {
+ u32 r10_save;
+ u32 r54_save;
+ u32 r98_save;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ status_save,
+ ind_save
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ rci1_save,
+ rci0_save
+ )
+
+ u32 r32_save;
+ u32 r76_save;
+ u32 rsd2_save;
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ rsi2_save, /* See TaskTreeParameterBlock for
+ remainder of registers */
+ rsa2Save
+ )
+ /* saved as part of HFG context */
+} hf_save_area_t;
+
+
+/* Task link data structure */
+typedef struct _tree_link_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Pointer to sibling task control block */
+ next_scb,
+ /* Pointer to child task control block */
+ sub_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Pointer to code entry point */
+ entry_point,
+ /* Pointer to local data */
+ this_spb
+ )
+} tree_link_t;
+
+
+typedef struct _task_tree_data_t {
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Initial tock count; controls task tree execution rate */
+ tock_count_limit,
+ /* Tock down counter */
+ tock_count
+ )
+
+ /* Add to ActiveCount when TockCountLimit reached:
+ Subtract on task tree termination */
+ ___DSP_DUAL_16BIT_ALLOC(
+ active_tncrement,
+ /* Number of pending activations for task tree */
+ active_count
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* BitNumber to enable modification of correct bit in ActiveTaskFlags */
+ active_bit,
+ /* Pointer to OS location for indicating current activity on task level */
+ active_task_flags_ptr
+ )
+
+ /* Data structure for controlling movement of memory blocks:-
+ currently unused */
+ ___DSP_DUAL_16BIT_ALLOC(
+ mem_upd_ptr,
+ /* Data structure for controlling synchronous link update */
+ link_upd_ptr
+ )
+
+ ___DSP_DUAL_16BIT_ALLOC(
+ /* Save area for remainder of full context. */
+ save_area,
+ /* Address of start of local stack for data storage */
+ data_stack_base_ptr
+ )
+
+} task_tree_data_t;
+
+
+
+typedef struct _interval_timer_data_t
+{
+ /* These data items have the same relative locations to those */
+ ___DSP_DUAL_16BIT_ALLOC(
+ interval_timer_period,
+ itd_unused
+ )
+
+ /* used for this data in the SPOS control block for SPOS 1.0 */
+ ___DSP_DUAL_16BIT_ALLOC(
+ num_FG_ticks_this_interval,
+ num_intervals
+ )
+} interval_timer_data_t;
+
+
+/* This structure contains extra storage for the task tree
+ Currently, this additional data is related only to a full context save */
+typedef struct _task_tree_context_block_t {
+ /* Up to 10 values are saved onto the stack. 8 for the task tree, 1 for
+ The access to the context switch (call or interrupt), and 1 spare that
+ users should never use. This last may be required by the system */
+ ___DSP_DUAL_16BIT_ALLOC(
+ stack1,
+ stack0
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ stack3,
+ stack2
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ stack5,
+ stack4
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ stack7,
+ stack6
+ )
+ ___DSP_DUAL_16BIT_ALLOC(
+ stack9,
+ stack8
+ )
+
+ u32 saverfe;
+
+ /* Value may be overwriten by stack save algorithm.
+ Retain the size of the stack data saved here if used */
+ ___DSP_DUAL_16BIT_ALLOC(
+ reserved1,
+ stack_size
+ )
+ u32 saverba; /* (HFG) */
+ u32 saverdc;
+ u32 savers_config_23; /* (HFG) */
+ u32 savers_DMA23; /* (HFG) */
+ u32 saversa0;
+ u32 saversi0;
+ u32 saversa1;
+ u32 saversi1;
+ u32 saversa3;
+ u32 saversd0;
+ u32 saversd1;
+ u32 saversd3;
+ u32 savers_config01;
+ u32 savers_DMA01;
+ u32 saveacc0hl;
+ u32 saveacc1hl;
+ u32 saveacc0xacc1x;
+ u32 saveacc2hl;
+ u32 saveacc3hl;
+ u32 saveacc2xacc3x;
+ u32 saveaux0hl;
+ u32 saveaux1hl;
+ u32 saveaux0xaux1x;
+ u32 saveaux2hl;
+ u32 saveaux3hl;
+ u32 saveaux2xaux3x;
+ u32 savershouthl;
+ u32 savershoutxmacmode;
+} task_tree_context_block_t;
+
+
+typedef struct _task_tree_control_block_t {
+ hf_save_area_t context;
+ tree_link_t links;
+ task_tree_data_t data;
+ task_tree_context_block_t context_blk;
+ interval_timer_data_t int_timer;
+} task_tree_control_block_t;
+
+
+#endif /* __DSP_TASK_TYPES_H__ */
diff --git a/include/sound/cs8403.h b/include/sound/cs8403.h
new file mode 100644
index 0000000..0b7d216
--- /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@suse.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(snd_aes_iec958_t *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(snd_aes_iec958_t *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(snd_aes_iec958_t *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(snd_aes_iec958_t *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..e725b70
--- /dev/null
+++ b/include/sound/cs8427.h
@@ -0,0 +1,196 @@
+#ifndef __SOUND_CS8427_H
+#define __SOUND_CS8427_H
+
+/*
+ * Routines for Cirrus Logic CS8427
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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
+
+int snd_cs8427_create(snd_i2c_bus_t *bus, unsigned char addr,
+ unsigned int reset_timeout, snd_i2c_device_t **r_cs8427);
+int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned char val);
+int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *playback_substream, snd_pcm_substream_t *capture_substream);
+int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active);
+int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate);
+
+#endif /* __SOUND_CS8427_H */
diff --git a/include/sound/driver.h b/include/sound/driver.h
new file mode 100644
index 0000000..948e9a1
--- /dev/null
+++ b/include/sound/driver.h
@@ -0,0 +1,64 @@
+#ifndef __SOUND_DRIVER_H
+#define __SOUND_DRIVER_H
+
+/*
+ * Main header file for the ALSA driver
+ * Copyright (c) 1994-2000 by Jaroslav Kysela <perex@suse.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
+ *
+ */
+
+#ifdef ALSA_BUILD
+#include "config.h"
+#endif
+
+#include <linux/config.h>
+
+#define SNDRV_CARDS 8 /* number of supported soundcards - don't change - minor numbers */
+
+#ifndef CONFIG_SND_MAJOR /* standard configuration */
+#define CONFIG_SND_MAJOR 116
+#endif
+
+#ifndef CONFIG_SND_DEBUG
+#undef CONFIG_SND_DEBUG_MEMORY
+#endif
+
+#ifdef ALSA_BUILD
+#include "adriver.h"
+#endif
+
+#include <linux/module.h>
+
+/*
+ * ==========================================================================
+ */
+
+#ifdef CONFIG_SND_DEBUG_MEMORY
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+void *snd_wrapper_kmalloc(size_t, int);
+#undef kmalloc
+void snd_wrapper_kfree(const void *);
+#undef kfree
+void *snd_wrapper_vmalloc(size_t);
+#undef vmalloc
+void snd_wrapper_vfree(void *);
+#undef vfree
+#endif
+
+#endif /* __SOUND_DRIVER_H */
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
new file mode 100644
index 0000000..43b6786
--- /dev/null
+++ b/include/sound/emu10k1.h
@@ -0,0 +1,1544 @@
+#ifndef __SOUND_EMU10K1_H
+#define __SOUND_EMU10K1_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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
+ *
+ */
+
+#ifdef __KERNEL__
+
+#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 <asm/io.h>
+
+#ifndef PCI_VENDOR_ID_CREATIVE
+#define PCI_VENDOR_ID_CREATIVE 0x1102
+#endif
+#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
+#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
+#endif
+
+/* ------------------- DEFINES -------------------- */
+
+#define EMUPAGESIZE 4096
+#define MAXREQVOICES 8
+#define MAXPAGES 8192
+#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 */
+
+#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_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_CODECFORMAT_MASK 0x00070000 /* CODEC format */
+#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_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 MAPA 0x0c /* Cache map A */
+
+#define MAPB 0x0d /* Cache map B */
+
+#define MAP_PTE_MASK 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */
+#define MAP_PTI_MASK 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */
+
+#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. */
+
+/* 1f something */
+
+#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 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 */
+
+/* 0x48 something - 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
+
+
+#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 */
+
+#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) */
+
+/* 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 */
+
+// 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_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 */
+
+// 0x6a,6b,6c used for some recording
+// 0x6d unused
+// 0x6e,6f - tanktable base / offset
+
+/* 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 */
+
+#define A_SPDIF_SAMPLERATE 0x76 /* Set the sample rate of SPDIF output */
+#define A_SPDIF_RATE_MASK 0x000000c0
+#define A_SPDIF_48000 0x00000000
+#define A_SPDIF_44100 0x00000080
+#define A_SPDIF_96000 0x00000040
+
+/* 0x77,0x78,0x79 "something i2s-related" - default to 0x01080000 on my audigy 2 ZS --rlrevell */
+/* 0x7a, 0x7b - lookup tables */
+
+#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
+
+
+/* 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
+
+
+/* ------------------- STRUCTURES -------------------- */
+
+typedef struct _snd_emu10k1 emu10k1_t;
+typedef struct _snd_emu10k1_voice emu10k1_voice_t;
+typedef struct _snd_emu10k1_pcm emu10k1_pcm_t;
+
+typedef enum {
+ EMU10K1_EFX,
+ EMU10K1_PCM,
+ EMU10K1_SYNTH,
+ EMU10K1_MIDI
+} emu10k1_voice_type_t;
+
+struct _snd_emu10k1_voice {
+ emu10k1_t *emu;
+ int number;
+ unsigned int use: 1,
+ pcm: 1,
+ efx: 1,
+ synth: 1,
+ midi: 1;
+ void (*interrupt)(emu10k1_t *emu, emu10k1_voice_t *pvoice);
+
+ emu10k1_pcm_t *epcm;
+};
+
+typedef enum {
+ PLAYBACK_EMUVOICE,
+ PLAYBACK_EFX,
+ CAPTURE_AC97ADC,
+ CAPTURE_AC97MIC,
+ CAPTURE_EFX
+} snd_emu10k1_pcm_type_t;
+
+struct _snd_emu10k1_pcm {
+ emu10k1_t *emu;
+ snd_emu10k1_pcm_type_t type;
+ snd_pcm_substream_t *substream;
+ emu10k1_voice_t *voices[NUM_EFX_PLAYBACK];
+ emu10k1_voice_t *extra;
+ unsigned short running;
+ unsigned short first_ptr;
+ snd_util_memblk_t *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 */
+};
+
+typedef struct {
+ /* 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];
+ emu10k1_pcm_t *epcm;
+} emu10k1_pcm_mixer_t;
+
+#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))
+
+typedef struct snd_emu10k1_memblk {
+ snd_util_memblk_t 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;
+} emu10k1_memblk_t;
+
+#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
+
+typedef struct {
+ 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*) */
+ snd_kcontrol_t *kcontrol;
+} snd_emu10k1_fx8010_ctl_t;
+
+typedef void (snd_fx8010_irq_handler_t)(emu10k1_t *emu, void *private_data);
+
+typedef struct _snd_emu10k1_fx8010_irq {
+ struct _snd_emu10k1_fx8010_irq *next;
+ snd_fx8010_irq_handler_t *handler;
+ unsigned short gpr_running;
+ void *private_data;
+} snd_emu10k1_fx8010_irq_t;
+
+typedef struct {
+ 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 */
+ snd_pcm_indirect_t pcm_rec;
+ unsigned int tram_pos;
+ unsigned int tram_shift;
+ snd_emu10k1_fx8010_irq_t *irq;
+} snd_emu10k1_fx8010_pcm_t;
+
+typedef struct {
+ 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 semaphore lock;
+ snd_emu10k1_fx8010_pcm_t pcm[8];
+ spinlock_t irq_lock;
+ snd_emu10k1_fx8010_irq_t *irq_handlers;
+} snd_emu10k1_fx8010_t;
+
+#define emu10k1_gpr_ctl(n) list_entry(n, snd_emu10k1_fx8010_ctl_t, list)
+
+typedef struct {
+ struct _snd_emu10k1 *emu;
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_substream_t *substream_input;
+ snd_rawmidi_substream_t *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)(emu10k1_t *emu, unsigned int status);
+} emu10k1_midi_t;
+
+typedef struct {
+ u32 vendor;
+ u32 device;
+ u32 subsystem;
+ 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 ca0151_chip; /* P16V */
+ unsigned char spk71; /* Has 7.1 speakers */
+ unsigned char spdif_bug; /* Has Spdif phasing bug */
+ unsigned char ac97_chip; /* Has an AC97 chip */
+ unsigned char ecard; /* APS EEPROM */
+ char * driver;
+ char * name;
+} emu_chip_details_t;
+
+struct _snd_emu10k1 {
+ int irq;
+
+ unsigned long port; /* I/O port number */
+ unsigned int APS: 1, /* APS flag */
+ no_ac97: 1, /* no AC'97 */
+ tos_link: 1, /* tos link detected */
+ rear_ac97: 1, /* rear channels are on AC'97 */
+ spk71:1; /* 7.1 configuration (Audigy 2 ZS) */
+ const emu_chip_details_t *card_capabilities; /* Contains profile of 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 long dma_mask; /* PCI DMA mask */
+ 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;
+
+ snd_util_memhdr_t *memhdr; /* page allocation list */
+ emu10k1_memblk_t *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 */
+
+ snd_emu10k1_fx8010_t fx8010; /* FX8010 info */
+ int gpr_base;
+
+ ac97_t *ac97;
+
+ struct pci_dev *pci;
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+ snd_pcm_t *pcm_mic;
+ snd_pcm_t *pcm_efx;
+ snd_pcm_t *pcm_p16v;
+
+ spinlock_t synth_lock;
+ void *synth;
+ int (*get_synth_voice)(emu10k1_t *emu);
+
+ spinlock_t reg_lock;
+ spinlock_t emu_lock;
+ spinlock_t voice_lock;
+ struct semaphore ptb_lock;
+
+ emu10k1_voice_t voices[NUM_G];
+ emu10k1_voice_t p16v_voices[4];
+ int p16v_device_offset;
+ emu10k1_pcm_mixer_t pcm_mixer[32];
+ emu10k1_pcm_mixer_t efx_pcm_mixer[NUM_EFX_PLAYBACK];
+ snd_kcontrol_t *ctl_send_routing;
+ snd_kcontrol_t *ctl_send_volume;
+ snd_kcontrol_t *ctl_attn;
+ snd_kcontrol_t *ctl_efx_send_routing;
+ snd_kcontrol_t *ctl_efx_send_volume;
+ snd_kcontrol_t *ctl_efx_attn;
+
+ void (*hwvol_interrupt)(emu10k1_t *emu, unsigned int status);
+ void (*capture_interrupt)(emu10k1_t *emu, unsigned int status);
+ void (*capture_mic_interrupt)(emu10k1_t *emu, unsigned int status);
+ void (*capture_efx_interrupt)(emu10k1_t *emu, unsigned int status);
+ void (*spdif_interrupt)(emu10k1_t *emu, unsigned int status);
+ void (*dsp_interrupt)(emu10k1_t *emu);
+
+ snd_pcm_substream_t *pcm_capture_substream;
+ snd_pcm_substream_t *pcm_capture_mic_substream;
+ snd_pcm_substream_t *pcm_capture_efx_substream;
+ snd_pcm_substream_t *pcm_playback_efx_substream;
+
+ snd_timer_t *timer;
+
+ emu10k1_midi_t midi;
+ emu10k1_midi_t midi2; /* for audigy */
+
+ unsigned int efx_voices_mask[2];
+ unsigned int next_free_voice;
+};
+
+int snd_emu10k1_create(snd_card_t * card,
+ struct pci_dev *pci,
+ unsigned short extin_mask,
+ unsigned short extout_mask,
+ long max_cache_bytes,
+ int enable_ir,
+ emu10k1_t ** remu);
+
+int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_p16v_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_p16v_free(emu10k1_t * emu);
+int snd_p16v_mixer(emu10k1_t * emu);
+int snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
+int snd_emu10k1_mixer(emu10k1_t * emu);
+int snd_emu10k1_timer(emu10k1_t * emu, int device);
+int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep);
+
+irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* initialization */
+void snd_emu10k1_voice_init(emu10k1_t * emu, int voice);
+int snd_emu10k1_init_efx(emu10k1_t *emu);
+void snd_emu10k1_free_efx(emu10k1_t *emu);
+int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size);
+
+/* I/O functions */
+unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
+unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr20_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
+unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
+void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
+void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
+void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_enable(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_disable(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_ack(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum);
+void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait);
+static inline unsigned int snd_emu10k1_wc(emu10k1_t *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
+unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg);
+void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data);
+unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
+
+/* memory allocation */
+snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream);
+int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk);
+snd_util_memblk_t *snd_emu10k1_synth_alloc(emu10k1_t *emu, unsigned int size);
+int snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *blk);
+int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size);
+int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
+int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk);
+
+/* voice allocation */
+int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int pair, emu10k1_voice_t **rvoice);
+int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice);
+
+/* MIDI uart */
+int snd_emu10k1_midi(emu10k1_t * emu);
+int snd_emu10k1_audigy_midi(emu10k1_t * emu);
+
+/* proc interface */
+int snd_emu10k1_proc_init(emu10k1_t * emu);
+
+/* fx8010 irq handler */
+int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
+ snd_fx8010_irq_handler_t *handler,
+ unsigned char gpr_running,
+ void *private_data,
+ snd_emu10k1_fx8010_irq_t **r_irq);
+int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
+ snd_emu10k1_fx8010_irq_t *irq);
+
+#endif /* __KERNEL__ */
+
+/*
+ * ---- FX8010 ----
+ */
+
+#define EMU10K1_CARD_CREATIVE 0x00000000
+#define EMU10K1_CARD_EMUAPS 0x00000001
+
+#define EMU10K1_FX8010_PCM_COUNT 8
+
+/* instruction set */
+#define iMAC0 0x00 /* R = A + (X * Y >> 31) ; saturation */
+#define iMAC1 0x01 /* R = A + (-X * Y >> 31) ; saturation */
+#define iMAC2 0x02 /* R = A + (X * Y >> 31) ; wraparound */
+#define iMAC3 0x03 /* R = A + (-X * Y >> 31) ; wraparound */
+#define iMACINT0 0x04 /* R = A + X * Y ; saturation */
+#define iMACINT1 0x05 /* R = A + X * Y ; wraparound (31-bit) */
+#define iACC3 0x06 /* R = A + X + Y ; saturation */
+#define iMACMV 0x07 /* R = A, acc += X * Y >> 31 */
+#define iANDXOR 0x08 /* R = (A & X) ^ Y */
+#define iTSTNEG 0x09 /* R = (A >= Y) ? X : ~X */
+#define iLIMITGE 0x0a /* R = (A >= Y) ? X : Y */
+#define iLIMITLT 0x0b /* R = (A < Y) ? X : Y */
+#define iLOG 0x0c /* R = linear_data, A (log_data), X (max_exp), Y (format_word) */
+#define iEXP 0x0d /* R = log_data, A (linear_data), X (max_exp), Y (format_word) */
+#define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */
+#define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */
+
+/* GPRs */
+#define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */
+#define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */
+#define EXTOUT(x) (0x20 + (x)) /* x = 0x00 - 0x0f physical outs -> FXWC low 16 bits */
+#define FXBUS2(x) (0x30 + (x)) /* x = 0x00 - 0x0f copies of fx buses for capture -> FXWC high 16 bits */
+ /* NB: 0x31 and 0x32 are shared with Center/LFE on SB live 5.1 */
+
+#define C_00000000 0x40
+#define C_00000001 0x41
+#define C_00000002 0x42
+#define C_00000003 0x43
+#define C_00000004 0x44
+#define C_00000008 0x45
+#define C_00000010 0x46
+#define C_00000020 0x47
+#define C_00000100 0x48
+#define C_00010000 0x49
+#define C_00080000 0x4a
+#define C_10000000 0x4b
+#define C_20000000 0x4c
+#define C_40000000 0x4d
+#define C_80000000 0x4e
+#define C_7fffffff 0x4f
+#define C_ffffffff 0x50
+#define C_fffffffe 0x51
+#define C_c0000000 0x52
+#define C_4f1bbcdc 0x53
+#define C_5a7ef9db 0x54
+#define C_00100000 0x55 /* ?? */
+#define GPR_ACCU 0x56 /* ACCUM, accumulator */
+#define GPR_COND 0x57 /* CCR, condition register */
+#define GPR_NOISE0 0x58 /* noise source */
+#define GPR_NOISE1 0x59 /* noise source */
+#define GPR_IRQ 0x5a /* IRQ register */
+#define GPR_DBAC 0x5b /* TRAM Delay Base Address Counter */
+#define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
+#define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+#define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+
+#define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+#define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+#define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+
+#define A_FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x3f FX buses */
+#define A_EXTIN(x) (0x40 + (x)) /* x = 0x00 - 0x0f physical ins */
+#define A_P16VIN(x) (0x50 + (x)) /* x = 0x00 - 0x0f p16v ins (A2 only) "EMU32 inputs" */
+#define A_EXTOUT(x) (0x60 + (x)) /* x = 0x00 - 0x1f physical outs -> A_FXWC1 0x79-7f unknown */
+#define A_FXBUS2(x) (0x80 + (x)) /* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
+#define A_EMU32OUTH(x) (0xa0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" - ??? */
+#define A_EMU32OUTL(x) (0xb0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_1 - _F" - ??? */
+#define A_GPR(x) (A_FXGPREGBASE + (x))
+
+/* cc_reg constants */
+#define CC_REG_NORMALIZED C_00000001
+#define CC_REG_BORROW C_00000002
+#define CC_REG_MINUS C_00000004
+#define CC_REG_ZERO C_00000008
+#define CC_REG_SATURATE C_00000010
+#define CC_REG_NONZERO C_00000100
+
+/* FX buses */
+#define FXBUS_PCM_LEFT 0x00
+#define FXBUS_PCM_RIGHT 0x01
+#define FXBUS_PCM_LEFT_REAR 0x02
+#define FXBUS_PCM_RIGHT_REAR 0x03
+#define FXBUS_MIDI_LEFT 0x04
+#define FXBUS_MIDI_RIGHT 0x05
+#define FXBUS_PCM_CENTER 0x06
+#define FXBUS_PCM_LFE 0x07
+#define FXBUS_PCM_LEFT_FRONT 0x08
+#define FXBUS_PCM_RIGHT_FRONT 0x09
+#define FXBUS_MIDI_REVERB 0x0c
+#define FXBUS_MIDI_CHORUS 0x0d
+#define FXBUS_PCM_LEFT_SIDE 0x0e
+#define FXBUS_PCM_RIGHT_SIDE 0x0f
+#define FXBUS_PT_LEFT 0x14
+#define FXBUS_PT_RIGHT 0x15
+
+/* Inputs */
+#define EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */
+#define EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */
+#define EXTIN_SPDIF_CD_L 0x02 /* internal S/PDIF CD - onboard - left */
+#define EXTIN_SPDIF_CD_R 0x03 /* internal S/PDIF CD - onboard - right */
+#define EXTIN_ZOOM_L 0x04 /* Zoom Video I2S - left */
+#define EXTIN_ZOOM_R 0x05 /* Zoom Video I2S - right */
+#define EXTIN_TOSLINK_L 0x06 /* LiveDrive - TOSLink Optical - left */
+#define EXTIN_TOSLINK_R 0x07 /* LiveDrive - TOSLink Optical - right */
+#define EXTIN_LINE1_L 0x08 /* LiveDrive - Line/Mic 1 - left */
+#define EXTIN_LINE1_R 0x09 /* LiveDrive - Line/Mic 1 - right */
+#define EXTIN_COAX_SPDIF_L 0x0a /* LiveDrive - Coaxial S/PDIF - left */
+#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */
+#define EXTIN_LINE2_L 0x0c /* LiveDrive - Line/Mic 2 - left */
+#define EXTIN_LINE2_R 0x0d /* LiveDrive - Line/Mic 2 - right */
+
+/* Outputs */
+#define EXTOUT_AC97_L 0x00 /* AC'97 playback channel - left */
+#define EXTOUT_AC97_R 0x01 /* AC'97 playback channel - right */
+#define EXTOUT_TOSLINK_L 0x02 /* LiveDrive - TOSLink Optical - left */
+#define EXTOUT_TOSLINK_R 0x03 /* LiveDrive - TOSLink Optical - right */
+#define EXTOUT_AC97_CENTER 0x04 /* SB Live 5.1 - center */
+#define EXTOUT_AC97_LFE 0x05 /* SB Live 5.1 - LFE */
+#define EXTOUT_HEADPHONE_L 0x06 /* LiveDrive - Headphone - left */
+#define EXTOUT_HEADPHONE_R 0x07 /* LiveDrive - Headphone - right */
+#define EXTOUT_REAR_L 0x08 /* Rear channel - left */
+#define EXTOUT_REAR_R 0x09 /* Rear channel - right */
+#define EXTOUT_ADC_CAP_L 0x0a /* ADC Capture buffer - left */
+#define EXTOUT_ADC_CAP_R 0x0b /* ADC Capture buffer - right */
+#define EXTOUT_MIC_CAP 0x0c /* MIC Capture buffer */
+#define EXTOUT_AC97_REAR_L 0x0d /* SB Live 5.1 (c) 2003 - Rear Left */
+#define EXTOUT_AC97_REAR_R 0x0e /* SB Live 5.1 (c) 2003 - Rear Right */
+#define EXTOUT_ACENTER 0x11 /* Analog Center */
+#define EXTOUT_ALFE 0x12 /* Analog LFE */
+
+/* Audigy Inputs */
+#define A_EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */
+#define A_EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */
+#define A_EXTIN_SPDIF_CD_L 0x02 /* digital CD left */
+#define A_EXTIN_SPDIF_CD_R 0x03 /* digital CD left */
+#define A_EXTIN_OPT_SPDIF_L 0x04 /* audigy drive Optical SPDIF - left */
+#define A_EXTIN_OPT_SPDIF_R 0x05 /* right */
+#define A_EXTIN_LINE2_L 0x08 /* audigy drive line2/mic2 - left */
+#define A_EXTIN_LINE2_R 0x09 /* right */
+#define A_EXTIN_ADC_L 0x0a /* Philips ADC - left */
+#define A_EXTIN_ADC_R 0x0b /* right */
+#define A_EXTIN_AUX2_L 0x0c /* audigy drive aux2 - left */
+#define A_EXTIN_AUX2_R 0x0d /* - right */
+
+/* Audigiy Outputs */
+#define A_EXTOUT_FRONT_L 0x00 /* digital front left */
+#define A_EXTOUT_FRONT_R 0x01 /* right */
+#define A_EXTOUT_CENTER 0x02 /* digital front center */
+#define A_EXTOUT_LFE 0x03 /* digital front lfe */
+#define A_EXTOUT_HEADPHONE_L 0x04 /* headphone audigy drive left */
+#define A_EXTOUT_HEADPHONE_R 0x05 /* right */
+#define A_EXTOUT_REAR_L 0x06 /* digital rear left */
+#define A_EXTOUT_REAR_R 0x07 /* right */
+#define A_EXTOUT_AFRONT_L 0x08 /* analog front left */
+#define A_EXTOUT_AFRONT_R 0x09 /* right */
+#define A_EXTOUT_ACENTER 0x0a /* analog center */
+#define A_EXTOUT_ALFE 0x0b /* analog LFE */
+#define A_EXTOUT_ASIDE_L 0x0c /* analog side left - Audigy 2 ZS */
+#define A_EXTOUT_ASIDE_R 0x0d /* right - Audigy 2 ZS */
+#define A_EXTOUT_AREAR_L 0x0e /* analog rear left */
+#define A_EXTOUT_AREAR_R 0x0f /* right */
+#define A_EXTOUT_AC97_L 0x10 /* AC97 left (front) */
+#define A_EXTOUT_AC97_R 0x11 /* right */
+#define A_EXTOUT_ADC_CAP_L 0x16 /* ADC capture buffer left */
+#define A_EXTOUT_ADC_CAP_R 0x17 /* right */
+#define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */
+
+/* Audigy constants */
+#define A_C_00000000 0xc0
+#define A_C_00000001 0xc1
+#define A_C_00000002 0xc2
+#define A_C_00000003 0xc3
+#define A_C_00000004 0xc4
+#define A_C_00000008 0xc5
+#define A_C_00000010 0xc6
+#define A_C_00000020 0xc7
+#define A_C_00000100 0xc8
+#define A_C_00010000 0xc9
+#define A_C_00000800 0xca
+#define A_C_10000000 0xcb
+#define A_C_20000000 0xcc
+#define A_C_40000000 0xcd
+#define A_C_80000000 0xce
+#define A_C_7fffffff 0xcf
+#define A_C_ffffffff 0xd0
+#define A_C_fffffffe 0xd1
+#define A_C_c0000000 0xd2
+#define A_C_4f1bbcdc 0xd3
+#define A_C_5a7ef9db 0xd4
+#define A_C_00100000 0xd5
+#define A_GPR_ACCU 0xd6 /* ACCUM, accumulator */
+#define A_GPR_COND 0xd7 /* CCR, condition register */
+#define A_GPR_NOISE0 0xd8 /* noise source */
+#define A_GPR_NOISE1 0xd9 /* noise source */
+#define A_GPR_IRQ 0xda /* IRQ register */
+#define A_GPR_DBAC 0xdb /* TRAM Delay Base Address Counter - internal */
+#define A_GPR_DBACE 0xde /* TRAM Delay Base Address Counter - external */
+
+/* definitions for debug register */
+#define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */
+#define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */
+#define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */
+#define EMU10K1_DBG_SINGLE_STEP 0x00008000 /* single step mode */
+#define EMU10K1_DBG_STEP 0x00004000 /* start single step */
+#define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */
+#define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */
+
+/* tank memory address line */
+#ifndef __KERNEL__
+#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 */
+#endif
+
+typedef struct {
+ unsigned int card; /* card type */
+ unsigned int internal_tram_size; /* in samples */
+ unsigned int external_tram_size; /* in samples */
+ char fxbus_names[16][32]; /* names of FXBUSes */
+ char extin_names[16][32]; /* names of external inputs */
+ char extout_names[32][32]; /* names of external outputs */
+ unsigned int gpr_controls; /* count of GPR controls */
+} emu10k1_fx8010_info_t;
+
+#define EMU10K1_GPR_TRANSLATION_NONE 0
+#define EMU10K1_GPR_TRANSLATION_TABLE100 1
+#define EMU10K1_GPR_TRANSLATION_BASS 2
+#define EMU10K1_GPR_TRANSLATION_TREBLE 3
+#define EMU10K1_GPR_TRANSLATION_ONOFF 4
+
+typedef struct {
+ snd_ctl_elem_id_t id; /* full control ID definition */
+ unsigned int vcount; /* visible count */
+ unsigned int count; /* count of GPR (1..16) */
+ unsigned short gpr[32]; /* GPR number(s) */
+ unsigned int value[32]; /* initial values */
+ unsigned int min; /* minimum range */
+ unsigned int max; /* maximum range */
+ unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */
+} emu10k1_fx8010_control_gpr_t;
+
+typedef struct {
+ char name[128];
+
+ DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
+ u_int32_t __user *gpr_map; /* initializers */
+
+ unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
+ emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */
+
+ unsigned int gpr_del_control_count; /* count of GPR controls to remove */
+ snd_ctl_elem_id_t __user *gpr_del_controls; /* IDs of GPR controls to remove */
+
+ unsigned int gpr_list_control_count; /* count of GPR controls to list */
+ unsigned int gpr_list_control_total; /* total count of GPR controls */
+ emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */
+
+ DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
+ u_int32_t __user *tram_data_map; /* data initializers */
+ u_int32_t __user *tram_addr_map; /* map initializers */
+
+ DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
+ u_int32_t __user *code; /* one instruction - 64 bits */
+} emu10k1_fx8010_code_t;
+
+typedef struct {
+ unsigned int address; /* 31.bit == 1 -> external TRAM */
+ unsigned int size; /* size in samples (4 bytes) */
+ unsigned int *samples; /* pointer to samples (20-bit) */
+ /* NULL->clear memory */
+} emu10k1_fx8010_tram_t;
+
+typedef struct {
+ unsigned int substream; /* substream number */
+ unsigned int res1; /* reserved */
+ unsigned int channels; /* 16-bit channels count, zero = remove this substream */
+ unsigned int tram_start; /* ring buffer position in TRAM (in samples) */
+ unsigned int buffer_size; /* count of buffered samples */
+ unsigned short gpr_size; /* GPR containing size of ringbuffer 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 pad; /* reserved */
+ unsigned char etram[32]; /* external TRAM address & data (one per channel) */
+ unsigned int res2; /* reserved */
+} emu10k1_fx8010_pcm_t;
+
+#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t)
+#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int)
+#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t)
+#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80)
+#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81)
+#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
+#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int)
+#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int)
+
+#endif /* __SOUND_EMU10K1_H */
diff --git a/include/sound/emu10k1_synth.h b/include/sound/emu10k1_synth.h
new file mode 100644
index 0000000..df0df1d
--- /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 "emu10k1.h"
+#include "emux_synth.h"
+
+/* sequencer device id */
+#define SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH "emu10k1-synth"
+
+/* argument for snd_seq_device_new */
+typedef struct snd_emu10k1_synth_arg {
+ emu10k1_t *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 */
+} snd_emu10k1_synth_arg_t;
+
+#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..4362c54
--- /dev/null
+++ b/include/sound/emu8000.h
@@ -0,0 +1,120 @@
+#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 "emux_synth.h"
+#include "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.
+ */
+typedef struct snd_emu8000 {
+
+ snd_emux_t *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;
+
+ snd_card_t *card; /* The card that this belongs to */
+
+ int chorus_mode;
+ int reverb_mode;
+ int bass_level;
+ int treble_level;
+
+ snd_util_memhdr_t *memhdr;
+
+ spinlock_t control_lock;
+ snd_kcontrol_t *controls[EMU8000_NUM_CONTROLS];
+
+ snd_pcm_t *pcm; /* pcm on emu8000 wavetable */
+
+} emu8000_t;
+
+/* sequencer device id */
+#define SNDRV_SEQ_DEV_ID_EMU8000 "emu8000-synth"
+
+
+/* exported functions */
+int snd_emu8000_new(snd_card_t *card, int device, long port, int seq_ports, snd_seq_device_t **ret);
+void snd_emu8000_poke(emu8000_t *emu, unsigned int port, unsigned int reg,
+ unsigned int val);
+unsigned short snd_emu8000_peek(emu8000_t *emu, unsigned int port,
+ unsigned int reg);
+void snd_emu8000_poke_dw(emu8000_t *emu, unsigned int port, unsigned int reg,
+ unsigned int val);
+unsigned int snd_emu8000_peek_dw(emu8000_t *emu, unsigned int port,
+ unsigned int reg);
+void snd_emu8000_dma_chan(emu8000_t *emu, int ch, int mode);
+
+void snd_emu8000_init_fm(emu8000_t *emu);
+
+void snd_emu8000_update_chorus_mode(emu8000_t *emu);
+void snd_emu8000_update_reverb_mode(emu8000_t *emu);
+void snd_emu8000_update_equalizer(emu8000_t *emu);
+int snd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void __user *buf, long len);
+int snd_emu8000_load_reverb_fx(emu8000_t *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..6fe3da2
--- /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 "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..c6970aa
--- /dev/null
+++ b/include/sound/emux_synth.h
@@ -0,0 +1,243 @@
+#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 "seq_kernel.h"
+#include "seq_device.h"
+#include "soundfont.h"
+#include "seq_midi_emul.h"
+#ifdef CONFIG_SND_SEQUENCER_OSS
+#include "seq_oss.h"
+#endif
+#include "emux_legacy.h"
+#include "seq_virmidi.h"
+
+/*
+ * compile flags
+ */
+#define SNDRV_EMUX_USE_RAW_EFFECT
+
+
+/*
+ * typedefs
+ */
+typedef struct snd_emux_effect_table snd_emux_effect_table_t;
+typedef struct snd_emux_port snd_emux_port_t;
+typedef struct snd_emux_voice snd_emux_voice_t;
+typedef struct snd_emux snd_emux_t;
+
+
+/*
+ * operators
+ */
+typedef struct snd_emux_operators {
+ struct module *owner;
+ snd_emux_voice_t *(*get_voice)(snd_emux_t *emu, snd_emux_port_t *port);
+ int (*prepare)(snd_emux_voice_t *vp);
+ void (*trigger)(snd_emux_voice_t *vp);
+ void (*release)(snd_emux_voice_t *vp);
+ void (*update)(snd_emux_voice_t *vp, int update);
+ void (*terminate)(snd_emux_voice_t *vp);
+ void (*free_voice)(snd_emux_voice_t *vp);
+ void (*reset)(snd_emux_t *emu, int ch);
+ /* the first parameters are snd_emux_t */
+ int (*sample_new)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *data, long count);
+ int (*sample_free)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
+ void (*sample_reset)(snd_emux_t *emu);
+ int (*load_fx)(snd_emux_t *emu, int type, int arg, const void __user *data, long count);
+ void (*sysex)(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
+#ifdef CONFIG_SND_SEQUENCER_OSS
+ int (*oss_ioctl)(snd_emux_t *emu, int cmd, int p1, int p2);
+#endif
+} snd_emux_operators_t;
+
+
+/*
+ * 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 {
+
+ snd_card_t *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) */
+ snd_emux_operators_t 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 */
+ snd_hwdep_t *hwdep; /* hwdep device */
+
+ /* private */
+ int num_voices; /* current number of voices */
+ snd_sf_list_t *sflist; /* root of SoundFont list */
+ snd_emux_voice_t *voices; /* Voices (EMU 'channel') */
+ int use_time; /* allocation counter */
+ spinlock_t voice_lock; /* Lock for voice access */
+ struct semaphore register_mutex;
+ int client; /* For the sequencer client */
+ int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */
+ snd_emux_port_t *portptrs[SNDRV_EMUX_MAX_PORTS];
+ int used; /* use counter */
+ char *name; /* name of the device (internal) */
+ snd_rawmidi_t **vmidi;
+ struct timer_list tlist; /* for pending note-offs */
+ int timer_active;
+
+ snd_util_memhdr_t *memhdr; /* memory chunk information */
+
+#ifdef CONFIG_PROC_FS
+ snd_info_entry_t *proc;
+#endif
+
+#ifdef CONFIG_SND_SEQUENCER_OSS
+ snd_seq_device_t *oss_synth;
+#endif
+};
+
+
+/*
+ * sequencer port information
+ */
+struct snd_emux_port {
+
+ snd_midi_channel_set_t chset;
+ snd_emux_t *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
+ snd_emux_effect_table_t *effect;
+#endif
+#ifdef CONFIG_SND_SEQUENCER_OSS
+ snd_seq_oss_arg_t *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 */
+
+ snd_sf_zone_t *zone; /* Zone assigned to this note */
+ void *block; /* sample block pointer (optional) */
+ snd_midi_channel_t *chan; /* Midi channel for this note */
+ snd_emux_port_t *port; /* associated port */
+ snd_emux_t *emu; /* assigned root info */
+ void *hw; /* hardware pointer (emu8000_t or emu10k1_t) */
+ unsigned long ontime; /* jiffies at note triggered */
+
+ /* Emu8k/Emu10k1 registers */
+ soundfont_voice_info_t 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(snd_emux_t **remu);
+int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name);
+int snd_emux_free(snd_emux_t *emu);
+
+/*
+ * exported functions
+ */
+void snd_emux_terminate_all(snd_emux_t *emu);
+void snd_emux_lock_voice(snd_emux_t *emu, int voice);
+void snd_emux_unlock_voice(snd_emux_t *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..604f495
--- /dev/null
+++ b/include/sound/es1688.h
@@ -0,0 +1,123 @@
+#ifndef __SOUND_ES1688_H
+#define __SOUND_ES1688_H
+
+/*
+ * Header file for ES488/ES1688
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "control.h"
+#include "pcm.h"
+#include <linux/interrupt.h>
+
+#define ES1688_HW_AUTO 0x0000
+#define ES1688_HW_688 0x0001
+#define ES1688_HW_1688 0x0002
+
+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;
+
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+ snd_pcm_substream_t *playback_substream;
+ snd_pcm_substream_t *capture_substream;
+
+ spinlock_t reg_lock;
+ spinlock_t mixer_lock;
+};
+
+typedef struct _snd_es1688 es1688_t;
+
+/* 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(es1688_t *chip, unsigned char reg, unsigned char data);
+
+int snd_es1688_create(snd_card_t * card,
+ unsigned long port,
+ unsigned long mpu_port,
+ int irq,
+ int mpu_irq,
+ int dma8,
+ unsigned short hardware,
+ es1688_t ** rchip);
+int snd_es1688_pcm(es1688_t *chip, int device, snd_pcm_t ** rpcm);
+int snd_es1688_mixer(es1688_t *chip);
+
+#endif /* __SOUND_ES1688_H */
diff --git a/include/sound/gus.h b/include/sound/gus.h
new file mode 100644
index 0000000..8b6287a
--- /dev/null
+++ b/include/sound/gus.h
@@ -0,0 +1,718 @@
+#ifndef __SOUND_GUS_H
+#define __SOUND_GUS_H
+
+/*
+ * Global structures used for GUS part of ALSA driver
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "pcm.h"
+#include "rawmidi.h"
+#include "timer.h"
+#include "seq_midi_emul.h"
+#include "seq_device.h"
+#include "ainstr_iw.h"
+#include "ainstr_gf1.h"
+#include "ainstr_simple.h"
+#include <asm/io.h>
+
+#define SNDRV_SEQ_DEV_ID_GUS "gus-synth"
+
+/* 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;
+typedef struct _snd_gus_card snd_gus_card_t;
+
+/* GF1 specific structure */
+
+typedef struct _snd_gf1_bank_info {
+ unsigned int address;
+ unsigned int size;
+} snd_gf1_bank_info_t;
+
+typedef 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;
+} snd_gf1_mem_block_t;
+
+typedef struct _snd_gf1_mem {
+ snd_gf1_bank_info_t banks_8[4];
+ snd_gf1_bank_info_t banks_16[4];
+ snd_gf1_mem_block_t *first;
+ snd_gf1_mem_block_t *last;
+ struct semaphore memory_mutex;
+} snd_gf1_mem_t;
+
+typedef 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)(snd_gus_card_t * gus, void *private_data);
+ void *private_data;
+ struct snd_gf1_dma_block *next;
+} snd_gf1_dma_block_t;
+
+typedef struct {
+ snd_midi_channel_set_t * chset;
+ snd_gus_card_t * gus;
+ int mode; /* operation mode */
+ int client; /* sequencer client number */
+ int port; /* sequencer port number */
+ unsigned int midi_has_voices: 1;
+} snd_gus_port_t;
+
+typedef struct _snd_gus_voice snd_gus_voice_t;
+
+typedef struct {
+ void (*sample_start)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position);
+ void (*sample_stop)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode);
+ void (*sample_freq)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq);
+ void (*sample_volume)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume);
+ void (*sample_loop)(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop);
+ void (*sample_pos)(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_position_t position);
+ void (*sample_private1)(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data);
+} snd_gus_sample_ops_t;
+
+#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)
+
+typedef enum {
+ VENV_BEFORE,
+ VENV_ATTACK,
+ VENV_SUSTAIN,
+ VENV_RELEASE,
+ VENV_DONE,
+ VENV_VOLUME
+} snd_gus_volume_state_t;
+
+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) (snd_gus_card_t * gus, snd_gus_voice_t * voice);
+ void (*handler_volume) (snd_gus_card_t * gus, snd_gus_voice_t * voice);
+ void (*handler_effect) (snd_gus_card_t * gus, snd_gus_voice_t * voice);
+ void (*volume_change) (snd_gus_card_t * gus);
+
+ snd_gus_sample_ops_t *sample_ops;
+
+ snd_seq_instr_t instr;
+
+ /* running status / registers */
+
+ snd_seq_ev_volume_t sample_volume;
+
+ 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;
+ snd_gus_volume_state_t venv_state;
+ snd_gus_volume_state_t venv_state_prev;
+ unsigned short vlo;
+ unsigned short vro;
+ unsigned short gf1_effect_volume;
+
+ /* --- */
+
+ void *private_data;
+ void (*private_free)(snd_gus_voice_t *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 */
+
+ snd_gf1_mem_t 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) */
+
+ snd_gus_voice_t 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) (snd_gus_card_t * gus);
+ void (*interrupt_handler_midi_in) (snd_gus_card_t * gus);
+ void (*interrupt_handler_timer1) (snd_gus_card_t * gus);
+ void (*interrupt_handler_timer2) (snd_gus_card_t * gus);
+ void (*interrupt_handler_dma_write) (snd_gus_card_t * gus);
+ void (*interrupt_handler_dma_read) (snd_gus_card_t * 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;
+ snd_gus_port_t seq_ports[4];
+ snd_seq_kinstr_list_t *ilist;
+ snd_iwffff_ops_t iwffff_ops;
+ snd_gf1_ops_t gf1_ops;
+ snd_simple_ops_t simple_ops;
+
+ /* timer */
+
+ unsigned short timer_enabled;
+ snd_timer_t *timer1;
+ snd_timer_t *timer2;
+
+ /* midi */
+
+ unsigned short uart_cmd;
+ unsigned int uart_framing;
+ unsigned int uart_overrun;
+
+ /* dma operations */
+
+ unsigned int dma_flags;
+ unsigned int dma_shared;
+ snd_gf1_dma_block_t *dma_data_pcm;
+ snd_gf1_dma_block_t *dma_data_pcm_last;
+ snd_gf1_dma_block_t *dma_data_synth;
+ snd_gf1_dma_block_t *dma_data_synth_last;
+ void (*dma_ack)(snd_gus_card_t * 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 {
+ snd_card_t *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 */
+ snd_pcm_t *pcm;
+ snd_pcm_substream_t *pcm_cap_substream;
+ unsigned int c_dma_size;
+ unsigned int c_period_size;
+ unsigned int c_pos;
+
+ snd_rawmidi_t *midi_uart;
+ snd_rawmidi_substream_t *midi_substream_output;
+ snd_rawmidi_substream_t *midi_substream_input;
+
+ snd_seq_device_t *seq_dev;
+
+ 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 semaphore dma_mutex;
+ struct semaphore register_mutex;
+};
+
+/* I/O functions for GF1/InterWave chip - gus_io.c */
+
+static inline void snd_gf1_select_voice(snd_gus_card_t * 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(snd_gus_card_t * gus, unsigned char b)
+{
+ outb(gus->gf1.uart_cmd = b, GUSP(gus, MIDICTRL));
+}
+
+static inline unsigned char snd_gf1_uart_stat(snd_gus_card_t * gus)
+{
+ return inb(GUSP(gus, MIDISTAT));
+}
+
+static inline void snd_gf1_uart_put(snd_gus_card_t * gus, unsigned char b)
+{
+ outb(b, GUSP(gus, MIDIDATA));
+}
+
+static inline unsigned char snd_gf1_uart_get(snd_gus_card_t * gus)
+{
+ return inb(GUSP(gus, MIDIDATA));
+}
+
+extern void snd_gf1_delay(snd_gus_card_t * gus);
+
+extern void snd_gf1_ctrl_stop(snd_gus_card_t * gus, unsigned char reg);
+
+extern void snd_gf1_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
+extern unsigned char snd_gf1_look8(snd_gus_card_t * gus, unsigned char reg);
+extern inline unsigned char snd_gf1_read8(snd_gus_card_t * gus, unsigned char reg)
+{
+ return snd_gf1_look8(gus, reg | 0x80);
+}
+extern void snd_gf1_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data);
+extern unsigned short snd_gf1_look16(snd_gus_card_t * gus, unsigned char reg);
+extern inline unsigned short snd_gf1_read16(snd_gus_card_t * gus, unsigned char reg)
+{
+ return snd_gf1_look16(gus, reg | 0x80);
+}
+extern void snd_gf1_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
+extern void snd_gf1_dram_addr(snd_gus_card_t * gus, unsigned int addr);
+extern void snd_gf1_poke(snd_gus_card_t * gus, unsigned int addr, unsigned char data);
+extern unsigned char snd_gf1_peek(snd_gus_card_t * gus, unsigned int addr);
+extern void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data);
+extern unsigned short snd_gf1_peekw(snd_gus_card_t * gus, unsigned int addr);
+extern void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr, unsigned short value, unsigned int count);
+extern void snd_gf1_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit);
+extern unsigned int snd_gf1_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit);
+extern void snd_gf1_i_ctrl_stop(snd_gus_card_t * gus, unsigned char reg);
+extern void snd_gf1_i_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
+extern unsigned char snd_gf1_i_look8(snd_gus_card_t * gus, unsigned char reg);
+extern void snd_gf1_i_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data);
+extern inline unsigned char snd_gf1_i_read8(snd_gus_card_t * gus, unsigned char reg)
+{
+ return snd_gf1_i_look8(gus, reg | 0x80);
+}
+extern unsigned short snd_gf1_i_look16(snd_gus_card_t * gus, unsigned char reg);
+extern inline unsigned short snd_gf1_i_read16(snd_gus_card_t * gus, unsigned char reg)
+{
+ return snd_gf1_i_look16(gus, reg | 0x80);
+}
+extern void snd_gf1_i_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
+extern void snd_gf1_i_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit);
+extern unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit);
+
+extern void snd_gf1_select_active_voices(snd_gus_card_t * 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(snd_gus_card_t * gus, snd_gf1_voice_t * voice);
+#endif
+extern void snd_gf1_lfo_init(snd_gus_card_t * gus);
+extern void snd_gf1_lfo_done(snd_gus_card_t * gus);
+extern void snd_gf1_lfo_program(snd_gus_card_t * gus, int voice, int lfo_type, struct _SND_IW_LFO_PROGRAM *program);
+extern void snd_gf1_lfo_enable(snd_gus_card_t * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_disable(snd_gus_card_t * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_change_freq(snd_gus_card_t * gus, int voice, int lfo_type, int freq);
+extern void snd_gf1_lfo_change_depth(snd_gus_card_t * gus, int voice, int lfo_type, int depth);
+extern void snd_gf1_lfo_setup(snd_gus_card_t * gus, int voice, int lfo_type, int freq, int current_depth, int depth, int sweep, int shape);
+extern void snd_gf1_lfo_shutdown(snd_gus_card_t * gus, int voice, int lfo_type);
+#if 0
+extern void snd_gf1_lfo_command(snd_gus_card_t * gus, int voice, unsigned char *command);
+#endif
+
+/* gus_mem.c */
+
+void snd_gf1_mem_lock(snd_gf1_mem_t * alloc, int xup);
+int snd_gf1_mem_xfree(snd_gf1_mem_t * alloc, snd_gf1_mem_block_t * block);
+snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc,
+ unsigned int address);
+snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc,
+ unsigned int *share_id);
+snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
+ char *name, int size, int w_16,
+ int align, unsigned int *share_id);
+int snd_gf1_mem_free(snd_gf1_mem_t * alloc, unsigned int address);
+int snd_gf1_mem_free_owner(snd_gf1_mem_t * alloc, int owner);
+int snd_gf1_mem_init(snd_gus_card_t * gus);
+int snd_gf1_mem_done(snd_gus_card_t * gus);
+
+/* gus_mem_proc.c */
+
+int snd_gf1_mem_proc_init(snd_gus_card_t * gus);
+
+/* gus_dma.c */
+
+int snd_gf1_dma_init(snd_gus_card_t * gus);
+int snd_gf1_dma_done(snd_gus_card_t * gus);
+int snd_gf1_dma_transfer_block(snd_gus_card_t * gus,
+ snd_gf1_dma_block_t * block,
+ int atomic,
+ int synth);
+
+/* gus_volume.c */
+
+unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol);
+unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol);
+unsigned int snd_gf1_calc_ramp_rate(snd_gus_card_t * gus,
+ unsigned short start,
+ unsigned short end,
+ unsigned int us);
+unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq2);
+unsigned short snd_gf1_compute_pitchbend(unsigned short pitchbend, unsigned short sens);
+unsigned short snd_gf1_compute_freq(unsigned int freq,
+ unsigned int rate,
+ unsigned short mix_rate);
+
+/* gus_reset.c */
+
+void snd_gf1_set_default_handlers(snd_gus_card_t * gus, unsigned int what);
+void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice);
+void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice);
+void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max);
+void snd_gf1_stop_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max);
+snd_gus_voice_t *snd_gf1_alloc_voice(snd_gus_card_t * gus, int type, int client, int port);
+void snd_gf1_free_voice(snd_gus_card_t * gus, snd_gus_voice_t *voice);
+int snd_gf1_start(snd_gus_card_t * gus);
+int snd_gf1_stop(snd_gus_card_t * gus);
+
+/* gus_mixer.c */
+
+int snd_gf1_new_mixer(snd_gus_card_t * gus);
+
+/* gus_pcm.c */
+
+int snd_gf1_pcm_new(snd_gus_card_t * gus, int pcm_dev, int control_index, snd_pcm_t ** rpcm);
+
+#ifdef CONFIG_SND_DEBUG
+extern void snd_gf1_print_voice_registers(snd_gus_card_t * gus);
+extern void snd_gf1_print_global_registers(snd_gus_card_t * gus);
+extern void snd_gf1_print_setup_registers(snd_gus_card_t * gus);
+extern void snd_gf1_peek_print_block(snd_gus_card_t * gus, unsigned int addr, int count, int w_16bit);
+#endif
+
+/* gus.c */
+
+int snd_gus_use_inc(snd_gus_card_t * gus);
+void snd_gus_use_dec(snd_gus_card_t * gus);
+int snd_gus_create(snd_card_t * card,
+ unsigned long port,
+ int irq, int dma1, int dma2,
+ int timer_dev,
+ int voices,
+ int pcm_channels,
+ int effect,
+ snd_gus_card_t ** rgus);
+int snd_gus_initialize(snd_gus_card_t * gus);
+
+/* gus_irq.c */
+
+irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+#ifdef CONFIG_SND_DEBUG
+void snd_gus_irq_profile_init(snd_gus_card_t *gus);
+#endif
+
+/* gus_uart.c */
+
+int snd_gf1_rawmidi_new(snd_gus_card_t * gus, int device, snd_rawmidi_t **rrawmidi);
+
+#if 0
+extern void snd_engine_instrument_register(unsigned short mode,
+ struct _SND_INSTRUMENT_VOICE_COMMANDS *voice_cmds,
+ struct _SND_INSTRUMENT_NOTE_COMMANDS *note_cmds,
+ struct _SND_INSTRUMENT_CHANNEL_COMMANDS *channel_cmds);
+extern int snd_engine_instrument_register_ask(unsigned short mode);
+#endif
+
+/* gus_dram.c */
+int snd_gus_dram_write(snd_gus_card_t *gus, char __user *ptr,
+ unsigned int addr, unsigned int size);
+int snd_gus_dram_read(snd_gus_card_t *gus, char __user *ptr,
+ unsigned int addr, unsigned int size, int rom);
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+
+/* gus_sample.c */
+void snd_gus_sample_event(snd_seq_event_t *ev, snd_gus_port_t *p);
+
+/* gus_simple.c */
+void snd_gf1_simple_init(snd_gus_voice_t *voice);
+
+/* gus_instr.c */
+int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
+ char __user *data, long len, int atomic);
+int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
+ char __user *data, long len, int atomic);
+int snd_gus_iwffff_remove_sample(void *private_data, iwffff_wave_t *wave,
+ int atomic);
+int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
+ char __user *data, long len, int atomic);
+int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
+ char __user *data, long len, int atomic);
+int snd_gus_gf1_remove_sample(void *private_data, gf1_wave_t *wave,
+ int atomic);
+int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
+ char __user *data, long len, int atomic);
+int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
+ char __user *data, long len, int atomic);
+int snd_gus_simple_remove_sample(void *private_data, simple_instrument_t *instr,
+ int atomic);
+
+#endif /* CONFIG_SND_SEQUENCER */
+
+#endif /* __SOUND_GUS_H */
diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h
new file mode 100644
index 0000000..7ce3aa6
--- /dev/null
+++ b/include/sound/hdsp.h
@@ -0,0 +1,110 @@
+#ifndef __SOUND_HDSP_H
+#define __SOUND_HDSP_H
+
+/*
+ * Copyright (C) 2003 Thomas Charbonnel (thomas@undata.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define HDSP_MATRIX_MIXER_SIZE 2048
+
+typedef enum {
+ Digiface,
+ Multiface,
+ H9652,
+ H9632,
+ Undefined,
+} HDSP_IO_Type;
+
+typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t;
+
+struct _snd_hdsp_peak_rms {
+ u32 input_peaks[26];
+ u32 playback_peaks[26];
+ u32 output_peaks[28];
+ u64 input_rms[26];
+ u64 playback_rms[26];
+ /* These are only used for H96xx cards */
+ u64 output_rms[26];
+};
+
+#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
+
+typedef struct _snd_hdsp_config_info hdsp_config_info_t;
+
+struct _snd_hdsp_config_info {
+ unsigned char pref_sync_ref;
+ unsigned char wordclock_sync_check;
+ unsigned char spdif_sync_check;
+ unsigned char adatsync_sync_check;
+ unsigned char adat_sync_check[3];
+ unsigned char spdif_in;
+ unsigned char spdif_out;
+ unsigned char spdif_professional;
+ unsigned char spdif_emphasis;
+ unsigned char spdif_nonaudio;
+ unsigned int spdif_sample_rate;
+ unsigned int system_sample_rate;
+ unsigned int autosync_sample_rate;
+ unsigned char system_clock_mode;
+ unsigned char clock_source;
+ unsigned char autosync_ref;
+ unsigned char line_out;
+ unsigned char passthru;
+ unsigned char da_gain;
+ unsigned char ad_gain;
+ unsigned char phone_gain;
+ unsigned char xlr_breakout_cable;
+ unsigned char analog_extension_board;
+};
+
+#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t)
+
+typedef struct _snd_hdsp_firmware hdsp_firmware_t;
+
+struct _snd_hdsp_firmware {
+ void __user *firmware_data; /* 24413 x 4 bytes */
+};
+
+#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
+
+typedef struct _snd_hdsp_version hdsp_version_t;
+
+struct _snd_hdsp_version {
+ HDSP_IO_Type io_type;
+ unsigned short firmware_rev;
+};
+
+#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t)
+
+typedef struct _snd_hdsp_mixer hdsp_mixer_t;
+
+struct _snd_hdsp_mixer {
+ unsigned short matrix[HDSP_MATRIX_MIXER_SIZE];
+};
+
+#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t)
+
+typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t;
+
+struct _snd_hdsp_9632_aeb {
+ int aebi;
+ int aebo;
+};
+
+#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t)
+
+#endif /* __SOUND_HDSP_H */
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
new file mode 100644
index 0000000..0438763
--- /dev/null
+++ b/include/sound/hwdep.h
@@ -0,0 +1,73 @@
+#ifndef __SOUND_HWDEP_H
+#define __SOUND_HWDEP_H
+
+/*
+ * Hardware dependent layer
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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>
+
+typedef enum sndrv_hwdep_iface snd_hwdep_iface_t;
+typedef struct sndrv_hwdep_info snd_hwdep_info_t;
+typedef struct sndrv_hwdep_dsp_status snd_hwdep_dsp_status_t;
+typedef struct sndrv_hwdep_dsp_image snd_hwdep_dsp_image_t;
+
+typedef struct _snd_hwdep_ops {
+ long long (*llseek) (snd_hwdep_t *hw, struct file * file, long long offset, int orig);
+ long (*read) (snd_hwdep_t * hw, char __user *buf, long count, loff_t *offset);
+ long (*write) (snd_hwdep_t * hw, const char __user *buf, long count, loff_t *offset);
+ int (*open) (snd_hwdep_t * hw, struct file * file);
+ int (*release) (snd_hwdep_t * hw, struct file * file);
+ unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
+ int (*ioctl) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
+ int (*ioctl_compat) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
+ int (*mmap) (snd_hwdep_t * hw, struct file * file, struct vm_area_struct * vma);
+ int (*dsp_status) (snd_hwdep_t * hw, snd_hwdep_dsp_status_t * status);
+ int (*dsp_load) (snd_hwdep_t * hw, snd_hwdep_dsp_image_t * image);
+} snd_hwdep_ops_t;
+
+struct _snd_hwdep {
+ snd_card_t *card;
+ int device;
+ char id[32];
+ char name[80];
+ int iface;
+
+#ifdef CONFIG_SND_OSSEMUL
+ char oss_dev[32];
+ int oss_type;
+ int ossreg;
+#endif
+
+ snd_hwdep_ops_t ops;
+ wait_queue_head_t open_wait;
+ void *private_data;
+ void (*private_free) (snd_hwdep_t *hwdep);
+
+ struct semaphore open_mutex;
+ int used;
+ unsigned int dsp_loaded;
+ unsigned int exclusive: 1;
+};
+
+extern int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep);
+
+#endif /* __SOUND_HWDEP_H */
diff --git a/include/sound/i2c.h b/include/sound/i2c.h
new file mode 100644
index 0000000..a665ddf
--- /dev/null
+++ b/include/sound/i2c.h
@@ -0,0 +1,102 @@
+#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
+ *
+ *
+ */
+
+typedef struct _snd_i2c_device snd_i2c_device_t;
+typedef struct _snd_i2c_bus snd_i2c_bus_t;
+
+#define SND_I2C_DEVICE_ADDRTEN (1<<0) /* 10-bit I2C address */
+
+struct _snd_i2c_device {
+ struct list_head list;
+ snd_i2c_bus_t *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)(snd_i2c_device_t *device);
+};
+
+#define snd_i2c_device(n) list_entry(n, snd_i2c_device_t, list)
+
+typedef struct _snd_i2c_bit_ops {
+ void (*start)(snd_i2c_bus_t *bus); /* transfer start */
+ void (*stop)(snd_i2c_bus_t *bus); /* transfer stop */
+ void (*direction)(snd_i2c_bus_t *bus, int clock, int data); /* set line direction (0 = write, 1 = read) */
+ void (*setlines)(snd_i2c_bus_t *bus, int clock, int data);
+ int (*getclock)(snd_i2c_bus_t *bus);
+ int (*getdata)(snd_i2c_bus_t *bus, int ack);
+} snd_i2c_bit_ops_t;
+
+typedef struct _snd_i2c_ops {
+ int (*sendbytes)(snd_i2c_device_t *device, unsigned char *bytes, int count);
+ int (*readbytes)(snd_i2c_device_t *device, unsigned char *bytes, int count);
+ int (*probeaddr)(snd_i2c_bus_t *bus, unsigned short addr);
+} snd_i2c_ops_t;
+
+struct _snd_i2c_bus {
+ snd_card_t *card; /* card which I2C belongs to */
+ char name[32]; /* some useful label */
+
+ struct semaphore lock_mutex;
+
+ snd_i2c_bus_t *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 {
+ snd_i2c_bit_ops_t *bit;
+ void *ops;
+ } hw_ops; /* lowlevel operations */
+ snd_i2c_ops_t *ops; /* midlevel operations */
+
+ unsigned long private_value;
+ void *private_data;
+ void (*private_free)(snd_i2c_bus_t *bus);
+};
+
+#define snd_i2c_slave_bus(n) list_entry(n, snd_i2c_bus_t, buses)
+
+int snd_i2c_bus_create(snd_card_t *card, const char *name, snd_i2c_bus_t *master, snd_i2c_bus_t **ri2c);
+int snd_i2c_device_create(snd_i2c_bus_t *bus, const char *name, unsigned char addr, snd_i2c_device_t **rdevice);
+int snd_i2c_device_free(snd_i2c_device_t *device);
+
+static inline void snd_i2c_lock(snd_i2c_bus_t *bus) {
+ if (bus->master)
+ down(&bus->master->lock_mutex);
+ else
+ down(&bus->lock_mutex);
+}
+static inline void snd_i2c_unlock(snd_i2c_bus_t *bus) {
+ if (bus->master)
+ up(&bus->master->lock_mutex);
+ else
+ up(&bus->lock_mutex);
+}
+
+int snd_i2c_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
+int snd_i2c_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
+int snd_i2c_probeaddr(snd_i2c_bus_t *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..1d76bf3
--- /dev/null
+++ b/include/sound/info.h
@@ -0,0 +1,193 @@
+#ifndef __SOUND_INFO_H
+#define __SOUND_INFO_H
+
+/*
+ * Header file for info interface
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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>
+
+/* buffer for information */
+struct snd_info_buffer {
+ char *buffer; /* pointer to begin of buffer */
+ char *curr; /* current position in buffer */
+ unsigned long size; /* current size */
+ unsigned long len; /* total length of buffer */
+ int stop; /* stop flag */
+ int error; /* error code */
+};
+
+typedef struct snd_info_buffer snd_info_buffer_t;
+
+#define SNDRV_INFO_CONTENT_TEXT 0
+#define SNDRV_INFO_CONTENT_DATA 1
+
+struct snd_info_entry;
+
+struct snd_info_entry_text {
+ unsigned long read_size;
+ unsigned long write_size;
+ void (*read) (snd_info_entry_t *entry, snd_info_buffer_t * buffer);
+ void (*write) (snd_info_entry_t *entry, snd_info_buffer_t * buffer);
+};
+
+struct snd_info_entry_ops {
+ int (*open) (snd_info_entry_t *entry,
+ unsigned short mode, void **file_private_data);
+ int (*release) (snd_info_entry_t * entry,
+ unsigned short mode, void *file_private_data);
+ long (*read) (snd_info_entry_t *entry, void *file_private_data,
+ struct file * file, char __user *buf,
+ unsigned long count, unsigned long pos);
+ long (*write) (snd_info_entry_t *entry, void *file_private_data,
+ struct file * file, const char __user *buf,
+ unsigned long count, unsigned long pos);
+ long long (*llseek) (snd_info_entry_t *entry, void *file_private_data,
+ struct file * file, long long offset, int orig);
+ unsigned int (*poll) (snd_info_entry_t *entry, void *file_private_data,
+ struct file * file, poll_table * wait);
+ int (*ioctl) (snd_info_entry_t *entry, void *file_private_data,
+ struct file * file, unsigned int cmd, unsigned long arg);
+ int (*mmap) (snd_info_entry_t *entry, void *file_private_data,
+ struct inode * inode, struct file * file,
+ struct vm_area_struct * vma);
+};
+
+struct snd_info_entry {
+ const char *name;
+ mode_t mode;
+ long size;
+ unsigned short content;
+ unsigned short disconnected: 1;
+ union {
+ struct snd_info_entry_text text;
+ struct snd_info_entry_ops *ops;
+ } c;
+ snd_info_entry_t *parent;
+ snd_card_t *card;
+ struct module *module;
+ void *private_data;
+ void (*private_free)(snd_info_entry_t *entry);
+ struct proc_dir_entry *p;
+ struct semaphore access;
+};
+
+extern int snd_info_check_reserved_words(const char *str);
+
+#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
+extern int snd_info_minor_register(void);
+extern int snd_info_minor_unregister(void);
+#else
+#define snd_info_minor_register() /* NOP */
+#define snd_info_minor_unregister() /* NOP */
+#endif
+
+
+#ifdef CONFIG_PROC_FS
+
+extern snd_info_entry_t *snd_seq_root;
+#ifdef CONFIG_SND_OSSEMUL
+extern snd_info_entry_t *snd_oss_root;
+#else
+#define snd_oss_root NULL
+#endif
+
+int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) __attribute__ ((format (printf, 2, 3)));
+int snd_info_init(void);
+int snd_info_done(void);
+
+int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len);
+char *snd_info_get_str(char *dest, char *src, int len);
+snd_info_entry_t *snd_info_create_module_entry(struct module * module,
+ const char *name,
+ snd_info_entry_t * parent);
+snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,
+ const char *name,
+ snd_info_entry_t * parent);
+void snd_info_free_entry(snd_info_entry_t * entry);
+int snd_info_store_text(snd_info_entry_t * entry);
+int snd_info_restore_text(snd_info_entry_t * entry);
+
+int snd_info_card_create(snd_card_t * card);
+int snd_info_card_register(snd_card_t * card);
+int snd_info_card_free(snd_card_t * card);
+int snd_info_register(snd_info_entry_t * entry);
+int snd_info_unregister(snd_info_entry_t * entry);
+
+/* for card drivers */
+int snd_card_proc_new(snd_card_t *card, const char *name, snd_info_entry_t **entryp);
+
+static inline void snd_info_set_text_ops(snd_info_entry_t *entry,
+ void *private_data,
+ long read_size,
+ void (*read)(snd_info_entry_t *, snd_info_buffer_t *))
+{
+ entry->private_data = private_data;
+ entry->c.text.read_size = read_size;
+ entry->c.text.read = read;
+}
+
+
+#else
+
+#define snd_seq_root NULL
+#define snd_oss_root NULL
+
+static inline int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) { return 0; }
+static inline int snd_info_init(void) { return 0; }
+static inline int snd_info_done(void) { return 0; }
+
+static inline int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) { return 0; }
+static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; }
+static inline snd_info_entry_t *snd_info_create_module_entry(struct module * module, const char *name, snd_info_entry_t * parent) { return NULL; }
+static inline snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card, const char *name, snd_info_entry_t * parent) { return NULL; }
+static inline void snd_info_free_entry(snd_info_entry_t * entry) { ; }
+
+static inline int snd_info_card_create(snd_card_t * card) { return 0; }
+static inline int snd_info_card_register(snd_card_t * card) { return 0; }
+static inline int snd_info_card_free(snd_card_t * card) { return 0; }
+static inline int snd_info_register(snd_info_entry_t * entry) { return 0; }
+static inline int snd_info_unregister(snd_info_entry_t * entry) { return 0; }
+
+#define snd_card_proc_new(card,name,entryp) 0 /* always success */
+#define snd_info_set_text_ops(entry,private_data,read_size,read) /*NOP*/
+
+#endif
+
+/*
+ * OSS info part
+ */
+
+#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_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
+
+extern 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_PROC_FS */
+
+#endif /* __SOUND_INFO_H */
diff --git a/include/sound/initval.h b/include/sound/initval.h
new file mode 100644
index 0000000..2bf1508
--- /dev/null
+++ b/include/sound/initval.h
@@ -0,0 +1,103 @@
+#ifndef __SOUND_INITVAL_H
+#define __SOUND_INITVAL_H
+
+/*
+ * Init values for soundcard modules
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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_AUTO_PROBE
+static int snd_legacy_auto_probe(unsigned long *ports, int (*probe)(unsigned long port))
+{
+ int result = 0; /* number of detected cards */
+
+ while ((signed long)*ports != -1) {
+ if (probe(*ports) >= 0)
+ result++;
+ ports++;
+ }
+ return result;
+}
+#endif
+
+#ifdef SNDRV_LEGACY_FIND_FREE_IRQ
+#include <linux/interrupt.h>
+
+static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ 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,
+ SA_INTERRUPT, "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/memalloc.h b/include/sound/memalloc.h
new file mode 100644
index 0000000..3a2fd2c
--- /dev/null
+++ b/include/sound/memalloc.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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_sbus_data(sbus) ((struct device *)(sbus))
+#define snd_dma_continuous_data(x) ((struct device *)(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 */
+#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
+#define SNDRV_DMA_TYPE_SBUS 4 /* SBUS continuous */
+
+/*
+ * 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 */
+};
+
+/*
+ * Scatter-Gather generic device pages
+ */
+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_sg_buf *sgbuf, size_t offset)
+{
+ return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
+}
+
+
+/* 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);
+
+/* buffer-preservation managements */
+
+#define snd_dma_pci_buf_id(pci) (((unsigned int)(pci)->vendor << 16) | (pci)->device)
+
+size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id);
+int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id);
+
+/* basic memory allocation functions */
+void *snd_malloc_pages(size_t size, unsigned int 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..b7b0d83
--- /dev/null
+++ b/include/sound/minors.h
@@ -0,0 +1,89 @@
+#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_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))
+
+#define SNDRV_MINOR_CONTROL 0 /* 0 - 0 */
+#define SNDRV_MINOR_SEQUENCER 1
+#define SNDRV_MINOR_TIMER (1+32)
+#define SNDRV_MINOR_HWDEP 4 /* 4 - 7 */
+#define SNDRV_MINOR_HWDEPS 4
+#define SNDRV_MINOR_RAWMIDI 8 /* 8 - 15 */
+#define SNDRV_MINOR_RAWMIDIS 8
+#define SNDRV_MINOR_PCM_PLAYBACK 16 /* 16 - 23 */
+#define SNDRV_MINOR_PCM_CAPTURE 24 /* 24 - 31 */
+#define SNDRV_MINOR_PCMS 8
+
+#define SNDRV_DEVICE_TYPE_CONTROL SNDRV_MINOR_CONTROL
+#define SNDRV_DEVICE_TYPE_HWDEP SNDRV_MINOR_HWDEP
+#define SNDRV_DEVICE_TYPE_MIXER SNDRV_MINOR_MIXER
+#define SNDRV_DEVICE_TYPE_RAWMIDI SNDRV_MINOR_RAWMIDI
+#define SNDRV_DEVICE_TYPE_PCM_PLAYBACK SNDRV_MINOR_PCM_PLAYBACK
+#define SNDRV_DEVICE_TYPE_PCM_PLOOP SNDRV_MINOR_PCM_PLOOP
+#define SNDRV_DEVICE_TYPE_PCM_CAPTURE SNDRV_MINOR_PCM_CAPTURE
+#define SNDRV_DEVICE_TYPE_PCM_CLOOP SNDRV_MINOR_PCM_CLOOP
+#define SNDRV_DEVICE_TYPE_SEQUENCER SNDRV_MINOR_SEQUENCER
+#define SNDRV_DEVICE_TYPE_TIMER SNDRV_MINOR_TIMER
+
+#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..ed75b2f
--- /dev/null
+++ b/include/sound/mixer_oss.h
@@ -0,0 +1,76 @@
+#ifndef __SOUND_MIXER_OSS_H
+#define __SOUND_MIXER_OSS_H
+
+/*
+ * OSS MIXER API
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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)
+
+typedef struct _snd_oss_mixer_slot snd_mixer_oss_slot_t;
+typedef struct _snd_oss_file snd_mixer_oss_file_t;
+
+typedef int (*snd_mixer_oss_get_volume_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int *left, int *right);
+typedef int (*snd_mixer_oss_put_volume_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int left, int right);
+typedef int (*snd_mixer_oss_get_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int *active);
+typedef int (*snd_mixer_oss_put_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int active);
+typedef int (*snd_mixer_oss_get_recsrce_t)(snd_mixer_oss_file_t *fmixer, unsigned int *active_index);
+typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, unsigned int active_index);
+
+#define SNDRV_OSS_MAX_MIXERS 32
+
+struct _snd_oss_mixer_slot {
+ int number;
+ unsigned int stereo: 1;
+ snd_mixer_oss_get_volume_t get_volume;
+ snd_mixer_oss_put_volume_t put_volume;
+ snd_mixer_oss_get_recsrc_t get_recsrc;
+ snd_mixer_oss_put_recsrc_t put_recsrc;
+ unsigned long private_value;
+ void *private_data;
+ void (*private_free)(snd_mixer_oss_slot_t *slot);
+ int volume[2];
+};
+
+struct _snd_oss_mixer {
+ snd_card_t *card;
+ char id[16];
+ char name[32];
+ snd_mixer_oss_slot_t slots[SNDRV_OSS_MAX_MIXERS]; /* OSS mixer slots */
+ unsigned int mask_recsrc; /* exclusive recsrc mask */
+ snd_mixer_oss_get_recsrce_t get_recsrc;
+ snd_mixer_oss_put_recsrce_t put_recsrc;
+ void *private_data_recsrc;
+ void (*private_free_recsrc)(snd_mixer_oss_t *mixer);
+ struct semaphore reg_mutex;
+ snd_info_entry_t *proc_entry;
+ int oss_dev_alloc;
+ /* --- */
+ int oss_recsrc;
+};
+
+struct _snd_oss_file {
+ snd_card_t *card;
+ snd_mixer_oss_t *mixer;
+};
+
+#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..ae39e38
--- /dev/null
+++ b/include/sound/mpu401.h
@@ -0,0 +1,115 @@
+#ifndef __SOUND_MPU401_H
+#define __SOUND_MPU401_H
+
+/*
+ * Header file for MPU-401 and compatible cards
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "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_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)
+
+typedef struct _snd_mpu401 mpu401_t;
+
+struct _snd_mpu401 {
+ snd_rawmidi_t *rmidi;
+
+ unsigned short hardware; /* MPU401_HW_XXXX */
+ 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 (-1 = poll) */
+ int irq_flags;
+
+ unsigned long mode; /* MPU401_MODE_XXXX */
+ int timer_invoked;
+
+ int (*open_input) (mpu401_t * mpu);
+ void (*close_input) (mpu401_t * mpu);
+ int (*open_output) (mpu401_t * mpu);
+ void (*close_output) (mpu401_t * mpu);
+ void *private_data;
+
+ snd_rawmidi_substream_t *substream_input;
+ snd_rawmidi_substream_t *substream_output;
+
+ spinlock_t input_lock;
+ spinlock_t output_lock;
+ spinlock_t timer_lock;
+
+ struct timer_list timer;
+
+ void (*write) (mpu401_t * mpu, unsigned char data, unsigned long addr);
+ unsigned char (*read) (mpu401_t * mpu, unsigned long addr);
+};
+
+/* I/O ports */
+
+#define MPU401C(mpu) (mpu)->cport
+#define MPU401D(mpu) (mpu)->port
+
+/*
+
+ */
+
+irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+int snd_mpu401_uart_new(snd_card_t * card,
+ int device,
+ unsigned short hardware,
+ unsigned long port,
+ int integrated,
+ int irq,
+ int irq_flags,
+ snd_rawmidi_t ** rrawmidi);
+
+#endif /* __SOUND_MPU401_H */
diff --git a/include/sound/opl3.h b/include/sound/opl3.h
new file mode 100644
index 0000000..19f657d
--- /dev/null
+++ b/include/sound/opl3.h
@@ -0,0 +1,339 @@
+#ifndef __SOUND_OPL3_H
+#define __SOUND_OPL3_H
+
+/*
+ * Definitions of the OPL-3 registers.
+ *
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "driver.h"
+#include <linux/time.h>
+#include "core.h"
+#include "hwdep.h"
+#include "timer.h"
+#include "seq_midi_emul.h"
+#ifdef CONFIG_SND_SEQUENCER_OSS
+#include "seq_oss.h"
+#include "seq_oss_legacy.h"
+#endif
+#include "seq_device.h"
+#include "ainstr_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_OPL3_PC98 0x0305 /* PC9800 */
+#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
+
+typedef struct snd_opl3 opl3_t;
+
+/*
+ * A structure to keep track of each hardware voice
+ */
+typedef 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 */
+
+ snd_midi_channel_t *chan; /* Midi channel for this note */
+} snd_opl3_voice_t;
+
+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) (opl3_t * opl3, unsigned short cmd, unsigned char val);
+ unsigned short timer_enable;
+ int seq_dev_num; /* sequencer device number */
+ snd_timer_t *timer1;
+ snd_timer_t *timer2;
+ spinlock_t timer_lock;
+
+ void *private_data;
+ void (*private_free)(opl3_t *);
+
+ spinlock_t reg_lock;
+ snd_card_t *card; /* The card that this belongs to */
+ int used; /* usage flag - exclusive */
+ 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;
+
+ snd_seq_device_t *seq_dev; /* sequencer device */
+ snd_midi_channel_set_t * chset;
+
+#ifdef CONFIG_SND_SEQUENCER_OSS
+ snd_seq_device_t *oss_seq_dev; /* OSS sequencer device */
+ snd_midi_channel_set_t * oss_chset;
+#endif
+
+ snd_seq_kinstr_ops_t fm_ops;
+ snd_seq_kinstr_list_t *ilist;
+
+ snd_opl3_voice_t 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
+ struct semaphore access_mutex; /* locking */
+};
+
+/* opl3.c */
+void snd_opl3_interrupt(snd_hwdep_t * hw);
+int snd_opl3_new(snd_card_t *card, unsigned short hardware, opl3_t **ropl3);
+int snd_opl3_init(opl3_t *opl3);
+int snd_opl3_create(snd_card_t * card,
+ unsigned long l_port, unsigned long r_port,
+ unsigned short hardware,
+ int integrated,
+ opl3_t ** opl3);
+int snd_opl3_timer_new(opl3_t * opl3, int timer1_dev, int timer2_dev);
+int snd_opl3_hwdep_new(opl3_t * opl3, int device, int seq_device,
+ snd_hwdep_t ** rhwdep);
+
+/* opl3_synth */
+int snd_opl3_open(snd_hwdep_t * hw, struct file *file);
+int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
+ unsigned int cmd, unsigned long arg);
+int snd_opl3_release(snd_hwdep_t * hw, struct file *file);
+
+void snd_opl3_reset(opl3_t * opl3);
+
+#endif /* __SOUND_OPL3_H */
diff --git a/include/sound/opl4.h b/include/sound/opl4.h
new file mode 100644
index 0000000..20c0442
--- /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>
+
+typedef struct opl4 opl4_t;
+
+extern int snd_opl4_create(snd_card_t *card,
+ unsigned long fm_port, unsigned long pcm_port,
+ int seq_device,
+ opl3_t **opl3, opl4_t **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..31fa7a5
--- /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@suse.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>
+
+typedef struct sndrv_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 */
+} snd_pcm_indirect_t;
+
+typedef void (*snd_pcm_indirect_copy_t)(snd_pcm_substream_t *substream,
+ snd_pcm_indirect_t *rec, size_t bytes);
+
+/*
+ * helper function for playback ack callback
+ */
+static inline void
+snd_pcm_indirect_playback_transfer(snd_pcm_substream_t *substream,
+ snd_pcm_indirect_t *rec,
+ snd_pcm_indirect_copy_t copy)
+{
+ snd_pcm_runtime_t *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(snd_pcm_substream_t *substream,
+ snd_pcm_indirect_t *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(snd_pcm_substream_t *substream,
+ snd_pcm_indirect_t *rec,
+ snd_pcm_indirect_copy_t copy)
+{
+ snd_pcm_runtime_t *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(snd_pcm_substream_t *substream,
+ snd_pcm_indirect_t *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..53fc04d
--- /dev/null
+++ b/include/sound/pcm.h
@@ -0,0 +1,1040 @@
+#ifndef __SOUND_PCM_H
+#define __SOUND_PCM_H
+
+/*
+ * Digital Audio (PCM) abstract layer
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 <linux/poll.h>
+#include <linux/bitops.h>
+
+typedef sndrv_pcm_uframes_t snd_pcm_uframes_t;
+typedef sndrv_pcm_sframes_t snd_pcm_sframes_t;
+typedef enum sndrv_pcm_class snd_pcm_class_t;
+typedef enum sndrv_pcm_subclass snd_pcm_subclass_t;
+typedef enum sndrv_pcm_stream snd_pcm_stream_t;
+typedef enum sndrv_pcm_access snd_pcm_access_t;
+typedef enum sndrv_pcm_format snd_pcm_format_t;
+typedef enum sndrv_pcm_subformat snd_pcm_subformat_t;
+typedef enum sndrv_pcm_state snd_pcm_state_t;
+typedef union sndrv_pcm_sync_id snd_pcm_sync_id_t;
+typedef struct sndrv_pcm_info snd_pcm_info_t;
+typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
+typedef struct sndrv_pcm_hw_params snd_pcm_hw_params_t;
+typedef enum sndrv_pcm_start snd_pcm_start_t;
+typedef enum sndrv_pcm_xrun snd_pcm_xrun_t;
+typedef enum sndrv_pcm_tstamp snd_pcm_tstamp_t;
+typedef struct sndrv_pcm_sw_params snd_pcm_sw_params_t;
+typedef struct sndrv_pcm_channel_info snd_pcm_channel_info_t;
+typedef struct sndrv_pcm_status snd_pcm_status_t;
+typedef struct sndrv_pcm_mmap_status snd_pcm_mmap_status_t;
+typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
+typedef struct sndrv_mask snd_mask_t;
+typedef struct snd_sg_buf snd_pcm_sgbuf_t;
+
+#define snd_pcm_substream_chip(substream) ((substream)->private_data)
+#define snd_pcm_chip(pcm) ((pcm)->private_data)
+
+typedef struct _snd_pcm_file snd_pcm_file_t;
+typedef struct _snd_pcm_runtime snd_pcm_runtime_t;
+
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#include "pcm_oss.h"
+#endif
+
+/*
+ * Hardware (lowlevel) section
+ */
+
+typedef 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 */
+} snd_pcm_hardware_t;
+
+typedef struct _snd_pcm_ops {
+ int (*open)(snd_pcm_substream_t *substream);
+ int (*close)(snd_pcm_substream_t *substream);
+ int (*ioctl)(snd_pcm_substream_t * substream,
+ unsigned int cmd, void *arg);
+ int (*hw_params)(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * params);
+ int (*hw_free)(snd_pcm_substream_t *substream);
+ int (*prepare)(snd_pcm_substream_t * substream);
+ int (*trigger)(snd_pcm_substream_t * substream, int cmd);
+ snd_pcm_uframes_t (*pointer)(snd_pcm_substream_t * substream);
+ int (*copy)(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos,
+ void __user *buf, snd_pcm_uframes_t count);
+ int (*silence)(snd_pcm_substream_t *substream, int channel,
+ snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
+ struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
+ int (*mmap)(snd_pcm_substream_t *substream, struct vm_area_struct *vma);
+ int (*ack)(snd_pcm_substream_t *substream);
+} snd_pcm_ops_t;
+
+/*
+ *
+ */
+
+#define SNDRV_PCM_DEVICES 8
+
+#define SNDRV_PCM_IOCTL1_FALSE ((void *)0)
+#define SNDRV_PCM_IOCTL1_TRUE ((void *)1)
+
+#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_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_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_S8 (1ULL << SNDRV_PCM_FORMAT_S8)
+#define SNDRV_PCM_FMTBIT_U8 (1ULL << SNDRV_PCM_FORMAT_U8)
+#define SNDRV_PCM_FMTBIT_S16_LE (1ULL << SNDRV_PCM_FORMAT_S16_LE)
+#define SNDRV_PCM_FMTBIT_S16_BE (1ULL << SNDRV_PCM_FORMAT_S16_BE)
+#define SNDRV_PCM_FMTBIT_U16_LE (1ULL << SNDRV_PCM_FORMAT_U16_LE)
+#define SNDRV_PCM_FMTBIT_U16_BE (1ULL << SNDRV_PCM_FORMAT_U16_BE)
+#define SNDRV_PCM_FMTBIT_S24_LE (1ULL << SNDRV_PCM_FORMAT_S24_LE)
+#define SNDRV_PCM_FMTBIT_S24_BE (1ULL << SNDRV_PCM_FORMAT_S24_BE)
+#define SNDRV_PCM_FMTBIT_U24_LE (1ULL << SNDRV_PCM_FORMAT_U24_LE)
+#define SNDRV_PCM_FMTBIT_U24_BE (1ULL << SNDRV_PCM_FORMAT_U24_BE)
+#define SNDRV_PCM_FMTBIT_S32_LE (1ULL << SNDRV_PCM_FORMAT_S32_LE)
+#define SNDRV_PCM_FMTBIT_S32_BE (1ULL << SNDRV_PCM_FORMAT_S32_BE)
+#define SNDRV_PCM_FMTBIT_U32_LE (1ULL << SNDRV_PCM_FORMAT_U32_LE)
+#define SNDRV_PCM_FMTBIT_U32_BE (1ULL << SNDRV_PCM_FORMAT_U32_BE)
+#define SNDRV_PCM_FMTBIT_FLOAT_LE (1ULL << SNDRV_PCM_FORMAT_FLOAT_LE)
+#define SNDRV_PCM_FMTBIT_FLOAT_BE (1ULL << SNDRV_PCM_FORMAT_FLOAT_BE)
+#define SNDRV_PCM_FMTBIT_FLOAT64_LE (1ULL << SNDRV_PCM_FORMAT_FLOAT64_LE)
+#define SNDRV_PCM_FMTBIT_FLOAT64_BE (1ULL << SNDRV_PCM_FORMAT_FLOAT64_BE)
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE (1ULL << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
+#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE (1ULL << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE)
+#define SNDRV_PCM_FMTBIT_MU_LAW (1ULL << SNDRV_PCM_FORMAT_MU_LAW)
+#define SNDRV_PCM_FMTBIT_A_LAW (1ULL << SNDRV_PCM_FORMAT_A_LAW)
+#define SNDRV_PCM_FMTBIT_IMA_ADPCM (1ULL << SNDRV_PCM_FORMAT_IMA_ADPCM)
+#define SNDRV_PCM_FMTBIT_MPEG (1ULL << SNDRV_PCM_FORMAT_MPEG)
+#define SNDRV_PCM_FMTBIT_GSM (1ULL << SNDRV_PCM_FORMAT_GSM)
+#define SNDRV_PCM_FMTBIT_SPECIAL (1ULL << SNDRV_PCM_FORMAT_SPECIAL)
+#define SNDRV_PCM_FMTBIT_S24_3LE (1ULL << SNDRV_PCM_FORMAT_S24_3LE)
+#define SNDRV_PCM_FMTBIT_U24_3LE (1ULL << SNDRV_PCM_FORMAT_U24_3LE)
+#define SNDRV_PCM_FMTBIT_S24_3BE (1ULL << SNDRV_PCM_FORMAT_S24_3BE)
+#define SNDRV_PCM_FMTBIT_U24_3BE (1ULL << SNDRV_PCM_FORMAT_U24_3BE)
+#define SNDRV_PCM_FMTBIT_S20_3LE (1ULL << SNDRV_PCM_FORMAT_S20_3LE)
+#define SNDRV_PCM_FMTBIT_U20_3LE (1ULL << SNDRV_PCM_FORMAT_U20_3LE)
+#define SNDRV_PCM_FMTBIT_S20_3BE (1ULL << SNDRV_PCM_FORMAT_S20_3BE)
+#define SNDRV_PCM_FMTBIT_U20_3BE (1ULL << SNDRV_PCM_FORMAT_U20_3BE)
+#define SNDRV_PCM_FMTBIT_S18_3LE (1ULL << SNDRV_PCM_FORMAT_S18_3LE)
+#define SNDRV_PCM_FMTBIT_U18_3LE (1ULL << SNDRV_PCM_FORMAT_U18_3LE)
+#define SNDRV_PCM_FMTBIT_S18_3BE (1ULL << SNDRV_PCM_FORMAT_S18_3BE)
+#define SNDRV_PCM_FMTBIT_U18_3BE (1ULL << SNDRV_PCM_FORMAT_U18_3BE)
+
+#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 {
+ snd_pcm_substream_t * substream;
+ struct _snd_pcm_file * next;
+};
+
+typedef struct _snd_pcm_hw_rule snd_pcm_hw_rule_t;
+
+typedef int (*snd_pcm_hw_rule_func_t)(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_rule_t *rule);
+
+struct _snd_pcm_hw_rule {
+ unsigned int cond;
+ snd_pcm_hw_rule_func_t func;
+ int var;
+ int deps[4];
+ void *private;
+};
+
+typedef struct _snd_pcm_hw_constraints {
+ snd_mask_t masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
+ SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+ snd_interval_t intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
+ SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+ unsigned int rules_num;
+ unsigned int rules_all;
+ snd_pcm_hw_rule_t *rules;
+} snd_pcm_hw_constraints_t;
+
+static inline snd_mask_t *constrs_mask(snd_pcm_hw_constraints_t *constrs,
+ snd_pcm_hw_param_t var)
+{
+ return &constrs->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
+}
+
+static inline snd_interval_t *constrs_interval(snd_pcm_hw_constraints_t *constrs,
+ snd_pcm_hw_param_t var)
+{
+ return &constrs->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
+}
+
+typedef struct {
+ unsigned int num;
+ unsigned int den_min, den_max, den_step;
+} ratnum_t;
+
+typedef struct {
+ unsigned int num_min, num_max, num_step;
+ unsigned int den;
+} ratden_t;
+
+typedef struct {
+ int nrats;
+ ratnum_t *rats;
+} snd_pcm_hw_constraint_ratnums_t;
+
+typedef struct {
+ int nrats;
+ ratden_t *rats;
+} snd_pcm_hw_constraint_ratdens_t;
+
+typedef struct {
+ unsigned int count;
+ unsigned int *list;
+ unsigned int mask;
+} snd_pcm_hw_constraint_list_t;
+
+struct _snd_pcm_runtime {
+ /* -- Status -- */
+ snd_pcm_substream_t *trigger_master;
+ snd_timestamp_t trigger_tstamp; /* trigger timestamp */
+ int overrange;
+ snd_pcm_uframes_t avail_max;
+ snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
+ snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time*/
+
+ /* -- HW params -- */
+ snd_pcm_access_t access; /* access mode */
+ snd_pcm_format_t format; /* SNDRV_PCM_FORMAT_* */
+ snd_pcm_subformat_t subformat; /* subformat */
+ unsigned int rate; /* rate in Hz */
+ unsigned int channels; /* channels */
+ snd_pcm_uframes_t period_size; /* period size */
+ unsigned int periods; /* periods */
+ snd_pcm_uframes_t buffer_size; /* buffer size */
+ unsigned int tick_time; /* tick time */
+ snd_pcm_uframes_t min_align; /* Min alignment for the format */
+ size_t byte_align;
+ unsigned int frame_bits;
+ unsigned int sample_bits;
+ unsigned int info;
+ unsigned int rate_num;
+ unsigned int rate_den;
+
+ /* -- SW params -- */
+ int tstamp_timespec; /* use timeval (0) or timespec (1) */
+ snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */
+ unsigned int period_step;
+ unsigned int sleep_min; /* min ticks to sleep */
+ snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */
+ snd_pcm_uframes_t start_threshold;
+ snd_pcm_uframes_t stop_threshold;
+ snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
+ noise is nearest than this */
+ snd_pcm_uframes_t silence_size; /* Silence filling size */
+ snd_pcm_uframes_t boundary; /* pointers wrap point */
+
+ snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
+ snd_pcm_uframes_t silence_filled; /* size filled with silence */
+
+ snd_pcm_sync_id_t sync; /* hardware synchronization ID */
+
+ /* -- mmap -- */
+ volatile snd_pcm_mmap_status_t *status;
+ volatile snd_pcm_mmap_control_t *control;
+ atomic_t mmap_count;
+
+ /* -- locking / scheduling -- */
+ wait_queue_head_t sleep;
+ struct timer_list tick_timer;
+ struct fasync_struct *fasync;
+
+ /* -- private section -- */
+ void *private_data;
+ void (*private_free)(snd_pcm_runtime_t *runtime);
+
+ /* -- hardware description -- */
+ snd_pcm_hardware_t hw;
+ snd_pcm_hw_constraints_t hw_constraints;
+
+ /* -- interrupt callbacks -- */
+ void (*transfer_ack_begin)(snd_pcm_substream_t *substream);
+ void (*transfer_ack_end)(snd_pcm_substream_t *substream);
+
+ /* -- timer -- */
+ unsigned int timer_resolution; /* timer resolution */
+
+ /* -- DMA -- */
+ unsigned char *dma_area; /* DMA area */
+ dma_addr_t dma_addr; /* physical bus address (not accessible from main CPU) */
+ size_t dma_bytes; /* size of DMA area */
+
+ struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */
+
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+ /* -- OSS things -- */
+ snd_pcm_oss_runtime_t oss;
+#endif
+};
+
+typedef struct _snd_pcm_group { /* keep linked substreams */
+ spinlock_t lock;
+ struct list_head substreams;
+ int count;
+} snd_pcm_group_t;
+
+struct _snd_pcm_substream {
+ snd_pcm_t *pcm;
+ snd_pcm_str_t *pstr;
+ void *private_data; /* copied from pcm->private_data */
+ int number;
+ char name[32]; /* substream name */
+ int stream; /* stream (direction) */
+ size_t buffer_bytes_max; /* limit ring buffer size */
+ struct snd_dma_buffer dma_buffer;
+ unsigned int dma_buf_id;
+ size_t dma_max;
+ /* -- hardware operations -- */
+ unsigned int open_flag: 1; /* lowlevel device has been opened */
+ snd_pcm_ops_t *ops;
+ /* -- runtime information -- */
+ snd_pcm_runtime_t *runtime;
+ /* -- timer section -- */
+ snd_timer_t *timer; /* timer */
+ unsigned timer_running: 1; /* time is running */
+ spinlock_t timer_lock;
+ /* -- next substream -- */
+ snd_pcm_substream_t *next;
+ /* -- linked substreams -- */
+ struct list_head link_list; /* linked list member */
+ snd_pcm_group_t self_group; /* fake group for non linked substream (with substream lock inside) */
+ snd_pcm_group_t *group; /* pointer to current group */
+ /* -- assigned files -- */
+ snd_pcm_file_t *file;
+ struct file *ffile;
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+ /* -- OSS things -- */
+ snd_pcm_oss_substream_t oss;
+#endif
+ snd_info_entry_t *proc_root;
+ snd_info_entry_t *proc_info_entry;
+ snd_info_entry_t *proc_hw_params_entry;
+ snd_info_entry_t *proc_sw_params_entry;
+ snd_info_entry_t *proc_status_entry;
+ snd_info_entry_t *proc_prealloc_entry;
+ /* misc flags */
+ unsigned int no_mmap_ctrl: 1;
+};
+
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL || ((substream)->oss.file != NULL))
+#else
+#define SUBSTREAM_BUSY(substream) ((substream)->file != NULL)
+#endif
+
+
+struct _snd_pcm_str {
+ int stream; /* stream (direction) */
+ snd_pcm_t *pcm;
+ /* -- substreams -- */
+ unsigned int substream_count;
+ unsigned int substream_opened;
+ snd_pcm_substream_t *substream;
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+ /* -- OSS things -- */
+ snd_pcm_oss_stream_t oss;
+#endif
+ snd_pcm_file_t *files;
+ snd_minor_t *reg;
+ snd_info_entry_t *proc_root;
+ snd_info_entry_t *proc_info_entry;
+#ifdef CONFIG_SND_DEBUG
+ unsigned int xrun_debug; /* 0 = disabled, 1 = verbose, 2 = stacktrace */
+ snd_info_entry_t *proc_xrun_debug_entry;
+#endif
+};
+
+struct _snd_pcm {
+ snd_card_t *card;
+ unsigned int device; /* device number */
+ unsigned int info_flags;
+ unsigned short dev_class;
+ unsigned short dev_subclass;
+ char id[64];
+ char name[80];
+ snd_pcm_str_t streams[2];
+ struct semaphore open_mutex;
+ wait_queue_head_t open_wait;
+ void *private_data;
+ void (*private_free) (snd_pcm_t *pcm);
+#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+ snd_pcm_oss_t oss;
+#endif
+};
+
+typedef struct _snd_pcm_notify {
+ int (*n_register) (snd_pcm_t * pcm);
+ int (*n_disconnect) (snd_pcm_t * pcm);
+ int (*n_unregister) (snd_pcm_t * pcm);
+ struct list_head list;
+} snd_pcm_notify_t;
+
+/*
+ * Registering
+ */
+
+extern snd_pcm_t *snd_pcm_devices[];
+extern snd_minor_t snd_pcm_reg[2];
+
+int snd_pcm_new(snd_card_t * card, char *id, int device,
+ int playback_count, int capture_count,
+ snd_pcm_t **rpcm);
+int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count);
+
+int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree);
+
+/*
+ * Native I/O
+ */
+
+extern rwlock_t snd_pcm_link_rwlock;
+
+int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
+int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user *info);
+int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status);
+int snd_pcm_prepare(snd_pcm_substream_t *substream);
+int snd_pcm_start(snd_pcm_substream_t *substream);
+int snd_pcm_stop(snd_pcm_substream_t *substream, int status);
+int snd_pcm_drain_done(snd_pcm_substream_t *substream);
+#ifdef CONFIG_PM
+int snd_pcm_suspend(snd_pcm_substream_t *substream);
+int snd_pcm_suspend_all(snd_pcm_t *pcm);
+#endif
+int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
+int snd_pcm_kernel_capture_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
+int snd_pcm_kernel_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
+int snd_pcm_open_substream(snd_pcm_t *pcm, int stream, snd_pcm_substream_t **rsubstream);
+void snd_pcm_release_substream(snd_pcm_substream_t *substream);
+void snd_pcm_vma_notify_data(void *client, void *data);
+int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file, struct vm_area_struct *area);
+
+#if BITS_PER_LONG >= 64
+
+static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
+{
+ *rem = *n % div;
+ *n /= div;
+}
+
+#elif defined(i386)
+
+static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
+{
+ u_int32_t low, high;
+ low = *n & 0xffffffff;
+ high = *n >> 32;
+ if (high) {
+ u_int32_t high1 = high % div;
+ high /= div;
+ asm("divl %2":"=a" (low), "=d" (*rem):"rm" (div), "a" (low), "d" (high1));
+ *n = (u_int64_t)high << 32 | low;
+ } else {
+ *n = low / div;
+ *rem = low % div;
+ }
+}
+#else
+
+static inline void divl(u_int32_t high, u_int32_t low,
+ u_int32_t div,
+ u_int32_t *q, u_int32_t *r)
+{
+ u_int64_t n = (u_int64_t)high << 32 | low;
+ u_int64_t d = (u_int64_t)div << 31;
+ u_int32_t q1 = 0;
+ int c = 32;
+ while (n > 0xffffffffU) {
+ q1 <<= 1;
+ if (n >= d) {
+ n -= d;
+ q1 |= 1;
+ }
+ d >>= 1;
+ c--;
+ }
+ q1 <<= c;
+ if (n) {
+ low = n;
+ *q = q1 | (low / div);
+ *r = low % div;
+ } else {
+ *r = 0;
+ *q = q1;
+ }
+ return;
+}
+
+static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
+{
+ u_int32_t low, high;
+ low = *n & 0xffffffff;
+ high = *n >> 32;
+ if (high) {
+ u_int32_t high1 = high % div;
+ u_int32_t low1 = low;
+ high /= div;
+ divl(high1, low1, div, &low, rem);
+ *n = (u_int64_t)high << 32 | low;
+ } else {
+ *n = low / div;
+ *rem = low % div;
+ }
+}
+#endif
+
+/*
+ * PCM library
+ */
+
+static inline int snd_pcm_stream_linked(snd_pcm_substream_t *substream)
+{
+ return substream->group != &substream->self_group;
+}
+
+static inline void snd_pcm_stream_lock(snd_pcm_substream_t *substream)
+{
+ read_lock(&snd_pcm_link_rwlock);
+ spin_lock(&substream->self_group.lock);
+}
+
+static inline void snd_pcm_stream_unlock(snd_pcm_substream_t *substream)
+{
+ spin_unlock(&substream->self_group.lock);
+ read_unlock(&snd_pcm_link_rwlock);
+}
+
+static inline void snd_pcm_stream_lock_irq(snd_pcm_substream_t *substream)
+{
+ read_lock_irq(&snd_pcm_link_rwlock);
+ spin_lock(&substream->self_group.lock);
+}
+
+static inline void snd_pcm_stream_unlock_irq(snd_pcm_substream_t *substream)
+{
+ spin_unlock(&substream->self_group.lock);
+ read_unlock_irq(&snd_pcm_link_rwlock);
+}
+
+#define snd_pcm_stream_lock_irqsave(substream, flags) \
+do { \
+ read_lock_irqsave(&snd_pcm_link_rwlock, (flags)); \
+ spin_lock(&substream->self_group.lock); \
+} while (0)
+
+#define snd_pcm_stream_unlock_irqrestore(substream, flags) \
+do { \
+ spin_unlock(&substream->self_group.lock); \
+ read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
+} while (0)
+
+#define snd_pcm_group_for_each(pos, substream) \
+ list_for_each(pos, &substream->group->substreams)
+
+#define snd_pcm_group_substream_entry(pos) \
+ list_entry(pos, snd_pcm_substream_t, link_list)
+
+static inline int snd_pcm_running(snd_pcm_substream_t *substream)
+{
+ return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
+ (substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
+}
+
+static inline ssize_t bytes_to_samples(snd_pcm_runtime_t *runtime, ssize_t size)
+{
+ return size * 8 / runtime->sample_bits;
+}
+
+static inline snd_pcm_sframes_t bytes_to_frames(snd_pcm_runtime_t *runtime, ssize_t size)
+{
+ return size * 8 / runtime->frame_bits;
+}
+
+static inline ssize_t samples_to_bytes(snd_pcm_runtime_t *runtime, ssize_t size)
+{
+ return size * runtime->sample_bits / 8;
+}
+
+static inline ssize_t frames_to_bytes(snd_pcm_runtime_t *runtime, snd_pcm_sframes_t size)
+{
+ return size * runtime->frame_bits / 8;
+}
+
+static inline int frame_aligned(snd_pcm_runtime_t *runtime, ssize_t bytes)
+{
+ return bytes % runtime->byte_align == 0;
+}
+
+static inline size_t snd_pcm_lib_buffer_bytes(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ return frames_to_bytes(runtime, runtime->buffer_size);
+}
+
+static inline size_t snd_pcm_lib_period_bytes(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ return frames_to_bytes(runtime, runtime->period_size);
+}
+
+/*
+ * result is: 0 ... (boundary - 1)
+ */
+static inline snd_pcm_uframes_t snd_pcm_playback_avail(snd_pcm_runtime_t *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;
+}
+
+/*
+ * result is: 0 ... (boundary - 1)
+ */
+static inline snd_pcm_uframes_t snd_pcm_capture_avail(snd_pcm_runtime_t *runtime)
+{
+ snd_pcm_sframes_t avail = runtime->status->hw_ptr - runtime->control->appl_ptr;
+ if (avail < 0)
+ avail += runtime->boundary;
+ return avail;
+}
+
+static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(snd_pcm_runtime_t *runtime)
+{
+ return runtime->buffer_size - snd_pcm_playback_avail(runtime);
+}
+
+static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(snd_pcm_runtime_t *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.
+ *
+ * Returns non-zero if available, or zero if not.
+ */
+static inline int snd_pcm_playback_ready(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *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.
+ *
+ * Returns non-zero if available, or zero if not.
+ */
+static inline int snd_pcm_capture_ready(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *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. If stop_threshold
+ * is bigger or equal to boundary, then this function returns always non-zero.
+ *
+ * Returns non-zero if exists, or zero if not.
+ */
+static inline int snd_pcm_playback_data(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *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.
+ *
+ * Returns non-zero if empty, or zero if not.
+ */
+static inline int snd_pcm_playback_empty(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *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.
+ *
+ * Returns non-zero if empty, or zero if not.
+ */
+static inline int snd_pcm_capture_empty(snd_pcm_substream_t *substream)
+{
+ snd_pcm_runtime_t *runtime = substream->runtime;
+ return snd_pcm_capture_avail(runtime) == 0;
+}
+
+static inline void snd_pcm_trigger_done(snd_pcm_substream_t *substream,
+ snd_pcm_substream_t *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 snd_mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
+{
+ return &params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
+}
+
+static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
+{
+ return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
+}
+
+static inline const snd_mask_t *hw_param_mask_c(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
+{
+ return (const snd_mask_t *)hw_param_mask((snd_pcm_hw_params_t*) params, var);
+}
+
+static inline const snd_interval_t *hw_param_interval_c(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var)
+{
+ return (const snd_interval_t *)hw_param_interval((snd_pcm_hw_params_t*) params, var);
+}
+
+#define params_access(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_ACCESS))
+#define params_format(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_FORMAT))
+#define params_subformat(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_SUBFORMAT))
+#define params_channels(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min
+#define params_rate(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_RATE)->min
+#define params_period_size(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min
+#define params_period_bytes(p) ((params_period_size(p)*snd_pcm_format_physical_width(params_format(p))*params_channels(p))/8)
+#define params_periods(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_PERIODS)->min
+#define params_buffer_size(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min
+#define params_buffer_bytes(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min
+#define params_tick_time(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_TICK_TIME)->min
+
+
+int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v);
+void snd_interval_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
+void snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
+void snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b,
+ unsigned int k, snd_interval_t *c);
+void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k,
+ const snd_interval_t *b, snd_interval_t *c);
+int snd_interval_list(snd_interval_t *i, unsigned int count, unsigned int *list, unsigned int mask);
+int snd_interval_ratnum(snd_interval_t *i,
+ unsigned int rats_count, ratnum_t *rats,
+ unsigned int *nump, unsigned int *denp);
+
+void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
+void _snd_pcm_hw_param_setempty(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var);
+int snd_pcm_hw_param_min(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir);
+int snd_pcm_hw_param_max(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir);
+int snd_pcm_hw_param_setinteger(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var);
+int snd_pcm_hw_param_first(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, int *dir);
+int snd_pcm_hw_param_last(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, int *dir);
+int snd_pcm_hw_param_near(snd_pcm_substream_t *substream,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ unsigned int val, int *dir);
+int snd_pcm_hw_param_set(snd_pcm_substream_t *pcm,
+ snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var,
+ unsigned int val, int dir);
+int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+
+int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+
+int snd_pcm_hw_constraints_init(snd_pcm_substream_t *substream);
+int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream);
+
+int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+ u_int32_t mask);
+int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+ u_int64_t mask);
+int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+ unsigned int min, unsigned int max);
+int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var);
+int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ snd_pcm_hw_param_t var,
+ snd_pcm_hw_constraint_list_t *l);
+int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ snd_pcm_hw_param_t var,
+ snd_pcm_hw_constraint_ratnums_t *r);
+int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ snd_pcm_hw_param_t var,
+ snd_pcm_hw_constraint_ratdens_t *r);
+int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ unsigned int width,
+ unsigned int msbits);
+int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ snd_pcm_hw_param_t var,
+ unsigned long step);
+int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ snd_pcm_hw_param_t var);
+int snd_pcm_hw_rule_add(snd_pcm_runtime_t *runtime,
+ unsigned int cond,
+ int var,
+ snd_pcm_hw_rule_func_t func, void *private,
+ int dep, ...);
+
+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);
+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 */
+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);
+snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian);
+const char *snd_pcm_format_name(snd_pcm_format_t format);
+
+void snd_pcm_set_ops(snd_pcm_t * pcm, int direction, snd_pcm_ops_t *ops);
+void snd_pcm_set_sync(snd_pcm_substream_t * substream);
+int snd_pcm_lib_interleave_len(snd_pcm_substream_t *substream);
+int snd_pcm_lib_ioctl(snd_pcm_substream_t *substream,
+ unsigned int cmd, void *arg);
+int snd_pcm_update_hw_ptr(snd_pcm_substream_t *substream);
+int snd_pcm_playback_xrun_check(snd_pcm_substream_t *substream);
+int snd_pcm_capture_xrun_check(snd_pcm_substream_t *substream);
+int snd_pcm_playback_xrun_asap(snd_pcm_substream_t *substream);
+int snd_pcm_capture_xrun_asap(snd_pcm_substream_t *substream);
+void snd_pcm_playback_silence(snd_pcm_substream_t *substream, snd_pcm_uframes_t new_hw_ptr);
+void snd_pcm_tick_prepare(snd_pcm_substream_t *substream);
+void snd_pcm_tick_set(snd_pcm_substream_t *substream, unsigned long ticks);
+void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream);
+void snd_pcm_period_elapsed(snd_pcm_substream_t *substream);
+snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream,
+ const void __user *buf,
+ snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream,
+ void __user *buf, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
+ void __user **bufs, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
+ void __user **bufs, snd_pcm_uframes_t frames);
+
+int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime);
+
+static inline void snd_pcm_set_runtime_buffer(snd_pcm_substream_t *substream,
+ struct snd_dma_buffer *bufp)
+{
+ snd_pcm_runtime_t *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
+ */
+
+void snd_pcm_timer_resolution_change(snd_pcm_substream_t *substream);
+void snd_pcm_timer_init(snd_pcm_substream_t * substream);
+void snd_pcm_timer_done(snd_pcm_substream_t * substream);
+
+/*
+ * Memory
+ */
+
+int snd_pcm_lib_preallocate_free(snd_pcm_substream_t *substream);
+int snd_pcm_lib_preallocate_free_for_all(snd_pcm_t *pcm);
+int snd_pcm_lib_preallocate_pages(snd_pcm_substream_t *substream,
+ int type, struct device *data,
+ size_t size, size_t max);
+int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm,
+ int type, void *data,
+ size_t size, size_t max);
+int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size);
+int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream);
+
+#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_buffer_p->private_data)
+#define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size)
+#define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
+struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
+
+/* handle mmap counter - PCM mmap callback should handle this counter properly */
+static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
+{
+ snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+ atomic_inc(&substream->runtime->mmap_count);
+}
+
+static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
+{
+ snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+ atomic_dec(&substream->runtime->mmap_count);
+}
+
+/* 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(snd_pcm_substream_t *substream, struct vm_area_struct *area);
+#else
+#define SNDRV_PCM_INFO_MMAP_IOMEM 0
+#define snd_pcm_lib_mmap_iomem NULL
+#endif
+
+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))
+
+#endif /* __SOUND_PCM_H */
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
new file mode 100644
index 0000000..5187285
--- /dev/null
+++ b/include/sound/pcm_oss.h
@@ -0,0 +1,87 @@
+#ifndef __SOUND_PCM_OSS_H
+#define __SOUND_PCM_OSS_H
+
+/*
+ * Digital Audio (PCM) - OSS compatibility abstract layer
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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
+ *
+ */
+
+typedef struct _snd_pcm_plugin snd_pcm_plugin_t;
+typedef struct _snd_pcm_oss_setup snd_pcm_oss_setup_t;
+
+struct _snd_pcm_oss_setup {
+ char *task_name;
+ unsigned int disable:1,
+ direct:1,
+ block:1,
+ nonblock:1,
+ partialfrag:1,
+ nosilence:1;
+ unsigned int periods;
+ unsigned int period_size;
+ snd_pcm_oss_setup_t *next;
+};
+
+typedef 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 */
+ snd_pcm_plugin_t *plugin_first;
+ snd_pcm_plugin_t *plugin_last;
+ unsigned int prev_hw_ptr_interrupt;
+} snd_pcm_oss_runtime_t;
+
+typedef struct _snd_pcm_oss_file {
+ snd_pcm_substream_t *streams[2];
+} snd_pcm_oss_file_t;
+
+typedef struct _snd_pcm_oss_substream {
+ unsigned oss: 1; /* oss mode */
+ snd_pcm_oss_setup_t *setup; /* active setup */
+ snd_pcm_oss_file_t *file;
+} snd_pcm_oss_substream_t;
+
+typedef struct _snd_pcm_oss_stream {
+ snd_pcm_oss_setup_t *setup_list; /* setup list */
+ struct semaphore setup_mutex;
+ snd_info_entry_t *proc_entry;
+} snd_pcm_oss_stream_t;
+
+typedef struct _snd_pcm_oss {
+ int reg;
+ unsigned int reg_mask;
+} snd_pcm_oss_t;
+
+#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..60b0e92
--- /dev/null
+++ b/include/sound/pcm_params.h
@@ -0,0 +1,366 @@
+#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
+ *
+ */
+
+extern int snd_pcm_hw_param_mask(snd_pcm_substream_t *pcm, snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, const snd_mask_t *val);
+extern unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, int *dir);
+extern unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, int *dir);
+extern int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, unsigned int val, int dir);
+extern int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var);
+extern int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+ snd_pcm_hw_param_t var, unsigned int val, int dir);
+
+/* To share the same code we have alsa-lib */
+#define INLINE static inline
+#define assert(a) (void)(a)
+
+#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))
+
+INLINE unsigned int ld2(u_int32_t v)
+{
+ unsigned r = 0;
+
+ if (v >= 0x10000) {
+ v >>= 16;
+ r += 16;
+ }
+ if (v >= 0x100) {
+ v >>= 8;
+ r += 8;
+ }
+ if (v >= 0x10) {
+ v >>= 4;
+ r += 4;
+ }
+ if (v >= 4) {
+ v >>= 2;
+ r += 2;
+ }
+ if (v >= 2)
+ r++;
+ return r;
+}
+
+INLINE size_t snd_mask_sizeof(void)
+{
+ return sizeof(snd_mask_t);
+}
+
+INLINE void snd_mask_none(snd_mask_t *mask)
+{
+ memset(mask, 0, sizeof(*mask));
+}
+
+INLINE void snd_mask_any(snd_mask_t *mask)
+{
+ memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
+}
+
+INLINE int snd_mask_empty(const snd_mask_t *mask)
+{
+ int i;
+ for (i = 0; i < SNDRV_MASK_SIZE; i++)
+ if (mask->bits[i])
+ return 0;
+ return 1;
+}
+
+INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
+{
+ int i;
+ assert(!snd_mask_empty(mask));
+ for (i = 0; i < SNDRV_MASK_SIZE; i++) {
+ if (mask->bits[i])
+ return ffs(mask->bits[i]) - 1 + (i << 5);
+ }
+ return 0;
+}
+
+INLINE unsigned int snd_mask_max(const snd_mask_t *mask)
+{
+ int i;
+ assert(!snd_mask_empty(mask));
+ for (i = SNDRV_MASK_SIZE - 1; i >= 0; i--) {
+ if (mask->bits[i])
+ return ld2(mask->bits[i]) + (i << 5);
+ }
+ return 0;
+}
+
+INLINE void snd_mask_set(snd_mask_t *mask, unsigned int val)
+{
+ assert(val <= SNDRV_MASK_BITS);
+ mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
+}
+
+INLINE void snd_mask_reset(snd_mask_t *mask, unsigned int val)
+{
+ assert(val <= SNDRV_MASK_BITS);
+ mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
+}
+
+INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
+{
+ unsigned int i;
+ assert(to <= SNDRV_MASK_BITS && from <= to);
+ for (i = from; i <= to; i++)
+ mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
+}
+
+INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
+{
+ unsigned int i;
+ assert(to <= SNDRV_MASK_BITS && from <= to);
+ for (i = from; i <= to; i++)
+ mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
+}
+
+INLINE void snd_mask_leave(snd_mask_t *mask, unsigned int val)
+{
+ unsigned int v;
+ assert(val <= SNDRV_MASK_BITS);
+ v = mask->bits[MASK_OFS(val)] & MASK_BIT(val);
+ snd_mask_none(mask);
+ mask->bits[MASK_OFS(val)] = v;
+}
+
+INLINE void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v)
+{
+ int i;
+ for (i = 0; i < SNDRV_MASK_SIZE; i++)
+ mask->bits[i] &= v->bits[i];
+}
+
+INLINE int snd_mask_eq(const snd_mask_t *mask, const snd_mask_t *v)
+{
+ return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
+}
+
+INLINE void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v)
+{
+ *mask = *v;
+}
+
+INLINE int snd_mask_test(const snd_mask_t *mask, unsigned int val)
+{
+ assert(val <= SNDRV_MASK_BITS);
+ return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
+}
+
+INLINE int snd_mask_single(const snd_mask_t *mask)
+{
+ int i, c = 0;
+ assert(!snd_mask_empty(mask));
+ 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;
+}
+
+INLINE int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v)
+{
+ snd_mask_t old;
+ assert(!snd_mask_empty(mask));
+ snd_mask_copy(&old, mask);
+ snd_mask_intersect(mask, v);
+ if (snd_mask_empty(mask))
+ return -EINVAL;
+ return !snd_mask_eq(mask, &old);
+}
+
+INLINE int snd_mask_refine_first(snd_mask_t *mask)
+{
+ assert(!snd_mask_empty(mask));
+ if (snd_mask_single(mask))
+ return 0;
+ snd_mask_leave(mask, snd_mask_min(mask));
+ return 1;
+}
+
+INLINE int snd_mask_refine_last(snd_mask_t *mask)
+{
+ assert(!snd_mask_empty(mask));
+ if (snd_mask_single(mask))
+ return 0;
+ snd_mask_leave(mask, snd_mask_max(mask));
+ return 1;
+}
+
+INLINE int snd_mask_refine_min(snd_mask_t *mask, unsigned int val)
+{
+ assert(!snd_mask_empty(mask));
+ 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;
+}
+
+INLINE int snd_mask_refine_max(snd_mask_t *mask, unsigned int val)
+{
+ assert(!snd_mask_empty(mask));
+ 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;
+}
+
+INLINE int snd_mask_refine_set(snd_mask_t *mask, unsigned int val)
+{
+ int changed;
+ assert(!snd_mask_empty(mask));
+ changed = !snd_mask_single(mask);
+ snd_mask_leave(mask, val);
+ if (snd_mask_empty(mask))
+ return -EINVAL;
+ return changed;
+}
+
+INLINE int snd_mask_value(const snd_mask_t *mask)
+{
+ assert(!snd_mask_empty(mask));
+ return snd_mask_min(mask);
+}
+
+INLINE void snd_interval_any(snd_interval_t *i)
+{
+ i->min = 0;
+ i->openmin = 0;
+ i->max = UINT_MAX;
+ i->openmax = 0;
+ i->integer = 0;
+ i->empty = 0;
+}
+
+INLINE void snd_interval_none(snd_interval_t *i)
+{
+ i->empty = 1;
+}
+
+INLINE int snd_interval_checkempty(const snd_interval_t *i)
+{
+ return (i->min > i->max ||
+ (i->min == i->max && (i->openmin || i->openmax)));
+}
+
+INLINE int snd_interval_empty(const snd_interval_t *i)
+{
+ return i->empty;
+}
+
+INLINE int snd_interval_single(const snd_interval_t *i)
+{
+ assert(!snd_interval_empty(i));
+ return (i->min == i->max ||
+ (i->min + 1 == i->max && i->openmax));
+}
+
+INLINE int snd_interval_value(const snd_interval_t *i)
+{
+ assert(snd_interval_single(i));
+ return i->min;
+}
+
+INLINE int snd_interval_min(const snd_interval_t *i)
+{
+ assert(!snd_interval_empty(i));
+ return i->min;
+}
+
+INLINE int snd_interval_max(const snd_interval_t *i)
+{
+ unsigned int v;
+ assert(!snd_interval_empty(i));
+ v = i->max;
+ if (i->openmax)
+ v--;
+ return v;
+}
+
+INLINE int snd_interval_test(const snd_interval_t *i, unsigned int val)
+{
+ return !((i->min > val || (i->min == val && i->openmin) ||
+ i->max < val || (i->max == val && i->openmax)));
+}
+
+INLINE void snd_interval_copy(snd_interval_t *d, const snd_interval_t *s)
+{
+ *d = *s;
+}
+
+INLINE int snd_interval_setinteger(snd_interval_t *i)
+{
+ if (i->integer)
+ return 0;
+ if (i->openmin && i->openmax && i->min == i->max)
+ return -EINVAL;
+ i->integer = 1;
+ return 1;
+}
+
+INLINE int snd_interval_eq(const snd_interval_t *i1, const snd_interval_t *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;
+}
+
+static inline unsigned int add(unsigned int a, unsigned int b)
+{
+ if (a >= UINT_MAX - b)
+ return UINT_MAX;
+ return a + b;
+}
+
+static inline unsigned int sub(unsigned int a, unsigned int b)
+{
+ if (a > b)
+ return a - b;
+ return 0;
+}
+
+#undef INLINE
+#undef assert
+
+#endif /* __SOUND_PCM_PARAMS_H */
+
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
new file mode 100644
index 0000000..3f9db51
--- /dev/null
+++ b/include/sound/rawmidi.h
@@ -0,0 +1,180 @@
+#ifndef __SOUND_RAWMIDI_H
+#define __SOUND_RAWMIDI_H
+
+/*
+ * Abstract layer for MIDI v1.0 stream
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 <asm/semaphore.h>
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#include "seq_device.h"
+#endif
+
+/*
+ * Raw MIDI interface
+ */
+
+typedef enum sndrv_rawmidi_stream snd_rawmidi_stream_t;
+typedef struct sndrv_rawmidi_info snd_rawmidi_info_t;
+typedef struct sndrv_rawmidi_params snd_rawmidi_params_t;
+typedef struct sndrv_rawmidi_status snd_rawmidi_status_t;
+
+#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)
+#define SNDRV_RAWMIDI_LFLG_NOOPENLOCK (1<<3)
+
+typedef struct _snd_rawmidi_runtime snd_rawmidi_runtime_t;
+typedef struct _snd_rawmidi_substream snd_rawmidi_substream_t;
+typedef struct _snd_rawmidi_str snd_rawmidi_str_t;
+
+typedef struct _snd_rawmidi_ops {
+ int (*open) (snd_rawmidi_substream_t * substream);
+ int (*close) (snd_rawmidi_substream_t * substream);
+ void (*trigger) (snd_rawmidi_substream_t * substream, int up);
+ void (*drain) (snd_rawmidi_substream_t * substream);
+} snd_rawmidi_ops_t;
+
+typedef struct _snd_rawmidi_global_ops {
+ int (*dev_register) (snd_rawmidi_t * rmidi);
+ int (*dev_unregister) (snd_rawmidi_t * rmidi);
+} snd_rawmidi_global_ops_t;
+
+struct _snd_rawmidi_runtime {
+ 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)(snd_rawmidi_substream_t *substream);
+ /* defers calls to event [input] or ops->trigger [output] */
+ struct tasklet_struct tasklet;
+ /* private data */
+ void *private_data;
+ void (*private_free)(snd_rawmidi_substream_t *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;
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_str_t *pstr;
+ char name[32];
+ snd_rawmidi_runtime_t *runtime;
+ /* hardware layer */
+ snd_rawmidi_ops_t *ops;
+};
+
+typedef struct _snd_rawmidi_file {
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_substream_t *input;
+ snd_rawmidi_substream_t *output;
+} snd_rawmidi_file_t;
+
+struct _snd_rawmidi_str {
+ unsigned int substream_count;
+ unsigned int substream_opened;
+ struct list_head substreams;
+};
+
+struct _snd_rawmidi {
+ snd_card_t *card;
+
+ 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
+
+ snd_rawmidi_global_ops_t *ops;
+
+ snd_rawmidi_str_t streams[2];
+
+ void *private_data;
+ void (*private_free) (snd_rawmidi_t *rmidi);
+
+ struct semaphore open_mutex;
+ wait_queue_head_t open_wait;
+
+ snd_info_entry_t *dev;
+ snd_info_entry_t *proc_entry;
+
+#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+ snd_seq_device_t *seq_dev;
+#endif
+};
+
+/* main rawmidi functions */
+
+int snd_rawmidi_new(snd_card_t * card, char *id, int device,
+ int output_count, int input_count,
+ snd_rawmidi_t ** rmidi);
+void snd_rawmidi_set_ops(snd_rawmidi_t * rmidi, int stream, snd_rawmidi_ops_t * ops);
+
+/* callbacks */
+
+void snd_rawmidi_receive_reset(snd_rawmidi_substream_t * substream);
+int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count);
+void snd_rawmidi_transmit_reset(snd_rawmidi_substream_t * substream);
+int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream);
+int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count);
+int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count);
+int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count);
+
+/* main midi functions */
+
+int snd_rawmidi_info_select(snd_card_t *card, snd_rawmidi_info_t *info);
+int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, int mode, snd_rawmidi_file_t * rfile);
+int snd_rawmidi_kernel_release(snd_rawmidi_file_t * rfile);
+int snd_rawmidi_output_params(snd_rawmidi_substream_t * substream, snd_rawmidi_params_t * params);
+int snd_rawmidi_input_params(snd_rawmidi_substream_t * substream, snd_rawmidi_params_t * params);
+int snd_rawmidi_drop_output(snd_rawmidi_substream_t * substream);
+int snd_rawmidi_drain_output(snd_rawmidi_substream_t * substream);
+int snd_rawmidi_drain_input(snd_rawmidi_substream_t * substream);
+long snd_rawmidi_kernel_read(snd_rawmidi_substream_t * substream, unsigned char *buf, long count);
+long snd_rawmidi_kernel_write(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count);
+
+#endif /* __SOUND_RAWMIDI_H */
diff --git a/include/sound/sb.h b/include/sound/sb.h
new file mode 100644
index 0000000..7960452
--- /dev/null
+++ b/include/sound/sb.h
@@ -0,0 +1,360 @@
+#ifndef __SOUND_SB_H
+#define __SOUND_SB_H
+
+/*
+ * Header file for SoundBlaster cards
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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 "pcm.h"
+#include "rawmidi.h"
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+enum sb_hw_type {
+ SB_HW_AUTO,
+ SB_HW_10,
+ SB_HW_20,
+ SB_HW_201,
+ SB_HW_PRO,
+ 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 */
+};
+
+#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 */
+
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+ snd_pcm_substream_t *playback_substream;
+ snd_pcm_substream_t *capture_substream;
+
+ snd_rawmidi_t *rmidi;
+ snd_rawmidi_substream_t *midi_substream_input;
+ snd_rawmidi_substream_t *midi_substream_output;
+ irqreturn_t (*rmidi_callback)(int irq, void *dev_id, struct pt_regs *regs);
+
+ spinlock_t reg_lock;
+ spinlock_t open_lock;
+ spinlock_t midi_input_lock;
+
+ snd_info_entry_t *proc_entry;
+};
+
+typedef struct _snd_sb sb_t;
+
+/* 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_MIC_IN_GAIN 0x4d
+#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_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
+
+/* 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(sb_t *chip)
+{
+ inb(SBP(chip, DATA_AVAIL));
+}
+
+static inline void snd_sb_ack_16bit(sb_t *chip)
+{
+ inb(SBP(chip, DATA_AVAIL_16));
+}
+
+/* sb_common.c */
+int snd_sbdsp_command(sb_t *chip, unsigned char val);
+int snd_sbdsp_get_byte(sb_t *chip);
+int snd_sbdsp_reset(sb_t *chip);
+int snd_sbdsp_create(snd_card_t *card,
+ unsigned long port,
+ int irq,
+ irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
+ int dma8, int dma16,
+ unsigned short hardware,
+ sb_t **r_chip);
+/* sb_mixer.c */
+void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data);
+unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg);
+int snd_sbmixer_new(sb_t *chip);
+
+/* sb8_init.c */
+int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
+/* sb8.c */
+irqreturn_t snd_sb8dsp_interrupt(sb_t *chip);
+int snd_sb8_playback_open(snd_pcm_substream_t *substream);
+int snd_sb8_capture_open(snd_pcm_substream_t *substream);
+int snd_sb8_playback_close(snd_pcm_substream_t *substream);
+int snd_sb8_capture_close(snd_pcm_substream_t *substream);
+/* midi8.c */
+irqreturn_t snd_sb8dsp_midi_interrupt(sb_t *chip);
+int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi);
+
+/* sb16_init.c */
+int snd_sb16dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
+const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction);
+int snd_sb16dsp_configure(sb_t *chip);
+/* sb16.c */
+irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* exported mixer stuffs */
+enum {
+ SB_MIX_SINGLE,
+ SB_MIX_DOUBLE,
+ SB_MIX_INPUT_SW,
+ SB_MIX_CAPTURE_PRO,
+ SB_MIX_CAPTURE_DT019X
+};
+
+#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(sb_t *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(sb_t *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..eb8368b
--- /dev/null
+++ b/include/sound/sb16_csp.h
@@ -0,0 +1,167 @@
+#ifndef __SOUND_SB16_CSP_H
+#define __SOUND_SB16_CSP_H
+
+/*
+ * 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
+ *
+ */
+
+/* CSP modes */
+#define SNDRV_SB_CSP_MODE_NONE 0x00
+#define SNDRV_SB_CSP_MODE_DSP_READ 0x01 /* Record from DSP */
+#define SNDRV_SB_CSP_MODE_DSP_WRITE 0x02 /* Play to DSP */
+#define SNDRV_SB_CSP_MODE_QSOUND 0x04 /* QSound */
+
+/* CSP load flags */
+#define SNDRV_SB_CSP_LOAD_FROMUSER 0x01
+#define SNDRV_SB_CSP_LOAD_INITBLOCK 0x02
+
+/* CSP sample width */
+#define SNDRV_SB_CSP_SAMPLE_8BIT 0x01
+#define SNDRV_SB_CSP_SAMPLE_16BIT 0x02
+
+/* CSP channels */
+#define SNDRV_SB_CSP_MONO 0x01
+#define SNDRV_SB_CSP_STEREO 0x02
+
+/* CSP rates */
+#define SNDRV_SB_CSP_RATE_8000 0x01
+#define SNDRV_SB_CSP_RATE_11025 0x02
+#define SNDRV_SB_CSP_RATE_22050 0x04
+#define SNDRV_SB_CSP_RATE_44100 0x08
+#define SNDRV_SB_CSP_RATE_ALL 0x0f
+
+/* CSP running state */
+#define SNDRV_SB_CSP_ST_IDLE 0x00
+#define SNDRV_SB_CSP_ST_LOADED 0x01
+#define SNDRV_SB_CSP_ST_RUNNING 0x02
+#define SNDRV_SB_CSP_ST_PAUSED 0x04
+#define SNDRV_SB_CSP_ST_AUTO 0x08
+#define SNDRV_SB_CSP_ST_QSOUND 0x10
+
+/* maximum QSound value (180 degrees right) */
+#define SNDRV_SB_CSP_QSOUND_MAX_RIGHT 0x20
+
+/* maximum microcode RIFF file size */
+#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE 0x3000
+
+/* microcode header */
+typedef struct snd_sb_csp_mc_header {
+ char codec_name[16]; /* id name of codec */
+ unsigned short func_req; /* requested function */
+} snd_sb_csp_mc_header_t;
+
+/* microcode to be loaded */
+typedef struct snd_sb_csp_microcode {
+ snd_sb_csp_mc_header_t info;
+ unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE];
+} snd_sb_csp_microcode_t;
+
+/* start CSP with sample_width in mono/stereo */
+typedef struct snd_sb_csp_start {
+ int sample_width; /* sample width, look above */
+ int channels; /* channels, look above */
+} snd_sb_csp_start_t;
+
+/* CSP information */
+typedef struct snd_sb_csp_info {
+ char codec_name[16]; /* id name of codec */
+ unsigned short func_nr; /* function number */
+ unsigned int acc_format; /* accepted PCM formats */
+ unsigned short acc_channels; /* accepted channels */
+ unsigned short acc_width; /* accepted sample width */
+ unsigned short acc_rates; /* accepted sample rates */
+ unsigned short csp_mode; /* CSP mode, see above */
+ unsigned short run_channels; /* current channels */
+ unsigned short run_width; /* current sample width */
+ unsigned short version; /* version id: 0x10 - 0x1f */
+ unsigned short state; /* state bits */
+} snd_sb_csp_info_t;
+
+/* HWDEP controls */
+/* get CSP information */
+#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t)
+/* load microcode to CSP */
+#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t)
+/* unload microcode from CSP */
+#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12)
+/* start CSP */
+#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t)
+/* stop CSP */
+#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14)
+/* pause CSP and DMA transfer */
+#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15)
+/* restart CSP and DMA transfer */
+#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16)
+
+#ifdef __KERNEL__
+#include "sb.h"
+#include "hwdep.h"
+
+typedef struct snd_sb_csp snd_sb_csp_t;
+
+/*
+ * CSP operators
+ */
+typedef struct {
+ int (*csp_use) (snd_sb_csp_t * p);
+ int (*csp_unuse) (snd_sb_csp_t * p);
+ int (*csp_autoload) (snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode);
+ int (*csp_start) (snd_sb_csp_t * p, int sample_width, int channels);
+ int (*csp_stop) (snd_sb_csp_t * p);
+ int (*csp_qsound_transfer) (snd_sb_csp_t * p);
+} snd_sb_csp_ops_t;
+
+/*
+ * CSP private data
+ */
+struct snd_sb_csp {
+ sb_t *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 */
+
+ snd_sb_csp_ops_t 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 */
+
+ snd_kcontrol_t *qsound_switch;
+ snd_kcontrol_t *qsound_space;
+
+ struct semaphore access_mutex; /* locking */
+};
+
+int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep);
+#endif
+
+#endif /* __SOUND_SB16_CSP */
diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h
new file mode 100644
index 0000000..204ca54
--- /dev/null
+++ b/include/sound/seq_device.h
@@ -0,0 +1,88 @@
+#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
+ *
+ */
+
+typedef struct snd_seq_device snd_seq_device_t;
+typedef struct snd_seq_dev_ops snd_seq_dev_ops_t;
+
+/*
+ * registered device information
+ */
+
+#define ID_LEN 32
+
+/* status flag */
+#define SNDRV_SEQ_DEVICE_FREE 0
+#define SNDRV_SEQ_DEVICE_REGISTERED 1
+
+struct snd_seq_device {
+ /* device info */
+ snd_card_t *card; /* sound card */
+ int device; /* device number */
+ char id[ID_LEN]; /* driver id */
+ char name[80]; /* device name */
+ int argsize; /* size of the argument */
+ void *driver_data; /* private data for driver */
+ int status; /* flag - read only */
+ void *private_data; /* private data for the caller */
+ void (*private_free)(snd_seq_device_t *device);
+ struct list_head list; /* link to next device */
+};
+
+
+/* driver operators
+ * init_device:
+ * 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.
+ *
+ * free_device:
+ * Release the private data.
+ * Typically, call snd_device_free(dev->card, dev->driver_data)
+ */
+struct snd_seq_dev_ops {
+ int (*init_device)(snd_seq_device_t *dev);
+ int (*free_device)(snd_seq_device_t *dev);
+};
+
+/*
+ * prototypes
+ */
+void snd_seq_device_load_drivers(void);
+int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize, snd_seq_device_t **result);
+int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsize);
+int snd_seq_device_unregister_driver(char *id);
+
+#define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(snd_seq_device_t))
+
+
+/*
+ * 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_instr.h b/include/sound/seq_instr.h
new file mode 100644
index 0000000..1a654df
--- /dev/null
+++ b/include/sound/seq_instr.h
@@ -0,0 +1,112 @@
+#ifndef __SOUND_SEQ_INSTR_H
+#define __SOUND_SEQ_INSTR_H
+
+/*
+ * Main kernel header file for the ALSA sequencer
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.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 "seq_kernel.h"
+
+/* Instrument cluster */
+typedef struct _snd_seq_kcluster {
+ snd_seq_instr_cluster_t cluster;
+ char name[32];
+ int priority;
+ struct _snd_seq_kcluster *next;
+} snd_seq_kcluster_t;
+
+/* return pointer to private data */
+#define KINSTR_DATA(kinstr) (void *)(((char *)kinstr) + sizeof(snd_seq_kinstr_t))
+
+typedef struct snd_seq_kinstr_ops snd_seq_kinstr_ops_t;
+
+/* Instrument structure */
+typedef struct _snd_seq_kinstr {
+ snd_seq_instr_t instr;
+ char name[32];
+ int type; /* instrument type */
+ int use; /* use count */
+ int busy; /* not useable */
+ int add_len; /* additional length */
+ snd_seq_kinstr_ops_t *ops; /* operations */
+ struct _snd_seq_kinstr *next;
+} snd_seq_kinstr_t;
+
+#define SNDRV_SEQ_INSTR_HASH_SIZE 32
+
+/* Instrument flags */
+#define SNDRV_SEQ_INSTR_FLG_DIRECT (1<<0) /* accept only direct events */
+
+/* List of all instruments */
+typedef struct {
+ snd_seq_kinstr_t *hash[SNDRV_SEQ_INSTR_HASH_SIZE];
+ int count; /* count of all instruments */
+
+ snd_seq_kcluster_t *chash[SNDRV_SEQ_INSTR_HASH_SIZE];
+ int ccount; /* count of all clusters */
+
+ int owner; /* current owner of the instrument list */
+ unsigned int flags;
+
+ spinlock_t lock;
+ spinlock_t ops_lock;
+ struct semaphore ops_mutex;
+ unsigned long ops_flags;
+} snd_seq_kinstr_list_t;
+
+#define SNDRV_SEQ_INSTR_NOTIFY_REMOVE 0
+#define SNDRV_SEQ_INSTR_NOTIFY_CHANGE 1
+
+struct snd_seq_kinstr_ops {
+ void *private_data;
+ long add_len; /* additional length */
+ char *instr_type;
+ int (*info)(void *private_data, char *info_data, long len);
+ int (*put)(void *private_data, snd_seq_kinstr_t *kinstr,
+ char __user *instr_data, long len, int atomic, int cmd);
+ int (*get)(void *private_data, snd_seq_kinstr_t *kinstr,
+ char __user *instr_data, long len, int atomic, int cmd);
+ int (*get_size)(void *private_data, snd_seq_kinstr_t *kinstr, long *size);
+ int (*remove)(void *private_data, snd_seq_kinstr_t *kinstr, int atomic);
+ void (*notify)(void *private_data, snd_seq_kinstr_t *kinstr, int what);
+ struct snd_seq_kinstr_ops *next;
+};
+
+
+/* instrument operations */
+snd_seq_kinstr_list_t *snd_seq_instr_list_new(void);
+void snd_seq_instr_list_free(snd_seq_kinstr_list_t **list);
+int snd_seq_instr_list_free_cond(snd_seq_kinstr_list_t *list,
+ snd_seq_instr_header_t *ifree,
+ int client,
+ int atomic);
+snd_seq_kinstr_t *snd_seq_instr_find(snd_seq_kinstr_list_t *list,
+ snd_seq_instr_t *instr,
+ int exact,
+ int follow_alias);
+void snd_seq_instr_free_use(snd_seq_kinstr_list_t *list,
+ snd_seq_kinstr_t *instr);
+int snd_seq_instr_event(snd_seq_kinstr_ops_t *ops,
+ snd_seq_kinstr_list_t *list,
+ snd_seq_event_t *ev,
+ int client,
+ int atomic,
+ int hop);
+
+#endif /* __SOUND_SEQ_INSTR_H */
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
new file mode 100644
index 0000000..4beca19
--- /dev/null
+++ b/include/sound/seq_kernel.h
@@ -0,0 +1,191 @@
+#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 "asequencer.h"
+
+typedef sndrv_seq_tick_time_t snd_seq_tick_time_t;
+typedef sndrv_seq_position_t snd_seq_position_t;
+typedef sndrv_seq_frequency_t snd_seq_frequency_t;
+typedef sndrv_seq_instr_cluster_t snd_seq_instr_cluster_t;
+typedef enum sndrv_seq_client_type snd_seq_client_type_t;
+typedef enum sndrv_seq_stop_mode snd_seq_stop_mode_t;
+typedef struct sndrv_seq_port_info snd_seq_port_info_t;
+typedef struct sndrv_seq_port_subscribe snd_seq_port_subscribe_t;
+typedef struct sndrv_seq_event snd_seq_event_t;
+typedef struct sndrv_seq_addr snd_seq_addr_t;
+typedef struct sndrv_seq_ev_volume snd_seq_ev_volume_t;
+typedef struct sndrv_seq_ev_loop snd_seq_ev_loop_t;
+typedef struct sndrv_seq_remove_events snd_seq_remove_events_t;
+typedef struct sndrv_seq_query_subs snd_seq_query_subs_t;
+typedef struct sndrv_seq_real_time snd_seq_real_time_t;
+typedef struct sndrv_seq_system_info snd_seq_system_info_t;
+typedef struct sndrv_seq_client_info snd_seq_client_info_t;
+typedef struct sndrv_seq_queue_info snd_seq_queue_info_t;
+typedef struct sndrv_seq_queue_status snd_seq_queue_status_t;
+typedef struct sndrv_seq_queue_tempo snd_seq_queue_tempo_t;
+typedef struct sndrv_seq_queue_owner snd_seq_queue_owner_t;
+typedef struct sndrv_seq_queue_timer snd_seq_queue_timer_t;
+typedef struct sndrv_seq_queue_client snd_seq_queue_client_t;
+typedef struct sndrv_seq_client_pool snd_seq_client_pool_t;
+typedef struct sndrv_seq_instr snd_seq_instr_t;
+typedef struct sndrv_seq_instr_data snd_seq_instr_data_t;
+typedef struct sndrv_seq_instr_header snd_seq_instr_header_t;
+typedef union sndrv_seq_timestamp snd_seq_timestamp_t;
+
+#define snd_seq_event_bounce_ext_data sndrv_seq_event_bounce_ext_data
+#define snd_seq_ev_is_result_type sndrv_seq_ev_is_result_type
+#define snd_seq_ev_is_channel_type sndrv_seq_ev_is_channel_type
+#define snd_seq_ev_is_note_type sndrv_seq_ev_is_note_type
+#define snd_seq_ev_is_control_type sndrv_seq_ev_is_control_type
+#define snd_seq_ev_is_queue_type sndrv_seq_ev_is_queue_type
+#define snd_seq_ev_is_message_type sndrv_seq_ev_is_message_type
+#define snd_seq_ev_is_sample_type sndrv_seq_ev_is_sample_type
+#define snd_seq_ev_is_user_type sndrv_seq_ev_is_user_type
+#define snd_seq_ev_is_fixed_type sndrv_seq_ev_is_fixed_type
+#define snd_seq_ev_is_instr_type sndrv_seq_ev_is_instr_type
+#define snd_seq_ev_is_variable_type sndrv_seq_ev_is_variable_type
+#define snd_seq_ev_is_reserved sndrv_seq_ev_is_reserved
+#define snd_seq_ev_is_direct sndrv_seq_ev_is_direct
+#define snd_seq_ev_is_prior sndrv_seq_ev_is_prior
+#define snd_seq_ev_length_type sndrv_seq_ev_length_type
+#define snd_seq_ev_is_fixed sndrv_seq_ev_is_fixed
+#define snd_seq_ev_is_variable sndrv_seq_ev_is_variable
+#define snd_seq_ev_is_varusr sndrv_seq_ev_is_varusr
+#define snd_seq_ev_timestamp_type sndrv_seq_ev_timestamp_type
+#define snd_seq_ev_is_tick sndrv_seq_ev_is_tick
+#define snd_seq_ev_is_real sndrv_seq_ev_is_real
+#define snd_seq_ev_timemode_type sndrv_seq_ev_timemode_type
+#define snd_seq_ev_is_abstime sndrv_seq_ev_is_abstime
+#define snd_seq_ev_is_reltime sndrv_seq_ev_is_reltime
+#define snd_seq_queue_sync_port sndrv_seq_queue_sync_port
+#define snd_seq_queue_owner sndrv_seq_queue_owner
+
+/* maximum number of events dequeued per schedule interval */
+#define SNDRV_SEQ_MAX_DEQUEUE 50
+
+/* maximum number of queues */
+#define SNDRV_SEQ_MAX_QUEUES 8
+
+/* 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 chunk */
+#define SNDRV_SEQ_DEFAULT_CHUNK_EVENTS 64
+
+/* 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 */
+#define SNDRV_SEQ_MAX_HOPS 10
+
+/* max size of event size */
+#define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff
+
+/* typedefs */
+struct _snd_seq_user_client;
+struct _snd_seq_kernel_client;
+struct _snd_seq_client;
+struct _snd_seq_queue;
+
+typedef struct _snd_seq_user_client user_client_t;
+typedef struct _snd_seq_kernel_client kernel_client_t;
+typedef struct _snd_seq_client client_t;
+typedef struct _snd_seq_queue queue_t;
+
+/* call-backs for kernel client */
+
+typedef struct {
+ void *private_data;
+ unsigned allow_input: 1,
+ allow_output: 1;
+ /*...*/
+} snd_seq_client_callback_t;
+
+/* call-backs for kernel port */
+typedef int (snd_seq_kernel_port_open_t)(void *private_data, snd_seq_port_subscribe_t *info);
+typedef int (snd_seq_kernel_port_close_t)(void *private_data, snd_seq_port_subscribe_t *info);
+typedef int (snd_seq_kernel_port_input_t)(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop);
+typedef void (snd_seq_kernel_port_private_free_t)(void *private_data);
+
+typedef struct {
+ struct module *owner;
+ void *private_data;
+ snd_seq_kernel_port_open_t *subscribe;
+ snd_seq_kernel_port_close_t *unsubscribe;
+ snd_seq_kernel_port_open_t *use;
+ snd_seq_kernel_port_close_t *unuse;
+ snd_seq_kernel_port_input_t *event_input;
+ snd_seq_kernel_port_private_free_t *private_free;
+ unsigned int callback_all; /* call subscribe callbacks at each connection/disconnection */
+ /*...*/
+} snd_seq_port_callback_t;
+
+/* interface for kernel client */
+extern int snd_seq_create_kernel_client(snd_card_t *card, int client_index, snd_seq_client_callback_t *callback);
+extern int snd_seq_delete_kernel_client(int client);
+extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
+extern int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t *ev, int atomic, int hop);
+extern 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 snd_seq_event_t *event, int count, char *buf, int in_kernel, int size_aligned);
+int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t func, void *private_data);
+
+/* interface for OSS emulation */
+int snd_seq_set_queue_tempo(int client, snd_seq_queue_tempo_t *tempo);
+
+/* port callback routines */
+void snd_port_init_callback(snd_seq_port_callback_t *p);
+snd_seq_port_callback_t *snd_port_alloc_callback(void);
+
+/* port attach/detach */
+int snd_seq_event_port_attach(int client, snd_seq_port_callback_t *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_KMOD
+void snd_seq_autoload_lock(void);
+void snd_seq_autoload_unlock(void);
+#else
+#define snd_seq_autoload_lock()
+#define snd_seq_autoload_unlock()
+#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..e58ca45
--- /dev/null
+++ b/include/sound/seq_midi_emul.h
@@ -0,0 +1,195 @@
+#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 "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.
+ */
+typedef 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 */
+
+} snd_midi_channel_t;
+
+/*
+ * 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_t structures.
+ * A driver that had no need for snd_midi_channel_t could still use the
+ * channel set type if it wished with the channel array null.
+ */
+typedef 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 */
+ snd_midi_channel_t *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;
+
+} snd_midi_channel_set_t;
+
+typedef struct snd_seq_midi_op {
+ void (*note_on)(void *private_data, int note, int vel, snd_midi_channel_t *chan);
+ void (*note_off)(void *private_data,int note, int vel, snd_midi_channel_t *chan); /* release note */
+ void (*key_press)(void *private_data, int note, int vel, snd_midi_channel_t *chan);
+ void (*note_terminate)(void *private_data, int note, snd_midi_channel_t *chan); /* terminate note immediately */
+ void (*control)(void *private_data, int type, snd_midi_channel_t *chan);
+ void (*nrpn)(void *private_data, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
+ void (*sysex)(void *private_data, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
+} snd_midi_op_t;
+
+/*
+ * 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(snd_midi_op_t *ops, snd_seq_event_t *ev,
+ snd_midi_channel_set_t *chanset);
+void snd_midi_channel_set_clear(snd_midi_channel_set_t *chset);
+snd_midi_channel_set_t *snd_midi_channel_alloc_set(int n);
+void snd_midi_channel_free_set(snd_midi_channel_set_t *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..4357cac
--- /dev/null
+++ b/include/sound/seq_midi_event.h
@@ -0,0 +1,56 @@
+#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@suse.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 "asequencer.h"
+
+#define MAX_MIDI_EVENT_BUF 256
+
+typedef struct snd_midi_event_t snd_midi_event_t;
+
+/* midi status */
+struct snd_midi_event_t {
+ 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, snd_midi_event_t **rdev);
+int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize);
+void snd_midi_event_free(snd_midi_event_t *dev);
+void snd_midi_event_init(snd_midi_event_t *dev);
+void snd_midi_event_reset_encode(snd_midi_event_t *dev);
+void snd_midi_event_reset_decode(snd_midi_event_t *dev);
+void snd_midi_event_no_status(snd_midi_event_t *dev, int on);
+/* encode from byte stream - return number of written bytes if success */
+long snd_midi_event_encode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev);
+int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev);
+/* decode from event to bytes - return number of written bytes if success */
+long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *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..bd7e573
--- /dev/null
+++ b/include/sound/seq_oss.h
@@ -0,0 +1,102 @@
+#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 "asequencer.h"
+#include "seq_kernel.h"
+
+/*
+ * type definitions
+ */
+typedef struct snd_seq_oss_arg_t snd_seq_oss_arg_t;
+typedef struct snd_seq_oss_callback_t snd_seq_oss_callback_t;
+
+/*
+ * argument structure for synthesizer operations
+ */
+struct snd_seq_oss_arg_t {
+ /* 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 */
+ snd_seq_addr_t 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_t {
+ struct module *owner;
+ int (*open)(snd_seq_oss_arg_t *p, void *closure);
+ int (*close)(snd_seq_oss_arg_t *p);
+ int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg);
+ int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char __user *buf, int offs, int count);
+ int (*reset)(snd_seq_oss_arg_t *p);
+ int (*raw_event)(snd_seq_oss_arg_t *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
+ */
+typedef struct snd_seq_oss_reg {
+ int type;
+ int subtype;
+ int nvoices;
+ snd_seq_oss_callback_t oper;
+ void *private_data;
+} snd_seq_oss_reg_t;
+
+/* 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..cf4e238
--- /dev/null
+++ b/include/sound/seq_virmidi.h
@@ -0,0 +1,84 @@
+#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@suse.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 "rawmidi.h"
+#include "seq_midi_event.h"
+
+typedef struct _snd_virmidi_dev snd_virmidi_dev_t;
+
+/*
+ * 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.
+ */
+typedef struct _snd_virmidi {
+ struct list_head list;
+ int seq_mode;
+ int client;
+ int port;
+ unsigned int trigger: 1;
+ snd_midi_event_t *parser;
+ snd_seq_event_t event;
+ snd_virmidi_dev_t *rdev;
+ snd_rawmidi_substream_t *substream;
+} snd_virmidi_t;
+
+#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 {
+ snd_card_t *card; /* associated card */
+ snd_rawmidi_t *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 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(snd_card_t *card, int device, snd_rawmidi_t **rrmidi);
+int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev);
+
+#endif /* __SOUND_SEQ_VIRMIDI */
diff --git a/include/sound/sfnt_info.h b/include/sound/sfnt_info.h
new file mode 100644
index 0000000..674585f
--- /dev/null
+++ b/include/sound/sfnt_info.h
@@ -0,0 +1,214 @@
+#ifndef __SOUND_SFNT_INFO_H
+#define __SOUND_SFNT_INFO_H
+
+/*
+ * Patch record compatible with AWE driver on OSS
+ *
+ * Copyright (C) 1999-2000 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/asound.h>
+
+/*
+ * patch information record
+ */
+
+#ifdef SNDRV_BIG_ENDIAN
+#define SNDRV_OSS_PATCHKEY(id) (0xfd00|id)
+#else
+#define SNDRV_OSS_PATCHKEY(id) ((id<<8)|0xfd)
+#endif
+
+/* patch interface header: 16 bytes */
+typedef struct soundfont_patch_info_t {
+ unsigned short key; /* use the key below */
+#define SNDRV_OSS_SOUNDFONT_PATCH SNDRV_OSS_PATCHKEY(0x07)
+
+ short device_no; /* synthesizer number */
+ unsigned short sf_id; /* file id (should be zero) */
+ short optarg; /* optional argument */
+ int len; /* data length (without this header) */
+
+ short type; /* patch operation type */
+#define SNDRV_SFNT_LOAD_INFO 0 /* awe_voice_rec */
+#define SNDRV_SFNT_LOAD_DATA 1 /* awe_sample_info */
+#define SNDRV_SFNT_OPEN_PATCH 2 /* awe_open_parm */
+#define SNDRV_SFNT_CLOSE_PATCH 3 /* none */
+ /* 4 is obsolete */
+#define SNDRV_SFNT_REPLACE_DATA 5 /* awe_sample_info (optarg=#channels)*/
+#define SNDRV_SFNT_MAP_PRESET 6 /* awe_voice_map */
+ /* 7 is not used */
+#define SNDRV_SFNT_PROBE_DATA 8 /* optarg=sample */
+#define SNDRV_SFNT_REMOVE_INFO 9 /* optarg=(bank<<8)|instr */
+
+ short reserved; /* word alignment data */
+
+ /* the actual patch data begins after this */
+} soundfont_patch_info_t;
+
+
+/*
+ * open patch
+ */
+
+#define SNDRV_SFNT_PATCH_NAME_LEN 32
+
+typedef struct soundfont_open_parm_t {
+ unsigned short type; /* sample type */
+#define SNDRV_SFNT_PAT_TYPE_MISC 0
+#define SNDRV_SFNT_PAT_TYPE_GUS 6
+#define SNDRV_SFNT_PAT_TYPE_MAP 7
+#define SNDRV_SFNT_PAT_LOCKED 0x100 /* lock the samples */
+#define SNDRV_SFNT_PAT_SHARED 0x200 /* sample is shared */
+
+ short reserved;
+ char name[SNDRV_SFNT_PATCH_NAME_LEN];
+} soundfont_open_parm_t;
+
+
+/*
+ * raw voice information record
+ */
+
+/* wave table envelope & effect parameters to control EMU8000 */
+typedef struct soundfont_voice_parm_t {
+ unsigned short moddelay; /* modulation delay (0x8000) */
+ unsigned short modatkhld; /* modulation attack & hold time (0x7f7f) */
+ unsigned short moddcysus; /* modulation decay & sustain (0x7f7f) */
+ unsigned short modrelease; /* modulation release time (0x807f) */
+ short modkeyhold, modkeydecay; /* envelope change per key (not used) */
+ unsigned short voldelay; /* volume delay (0x8000) */
+ unsigned short volatkhld; /* volume attack & hold time (0x7f7f) */
+ unsigned short voldcysus; /* volume decay & sustain (0x7f7f) */
+ unsigned short volrelease; /* volume release time (0x807f) */
+ short volkeyhold, volkeydecay; /* envelope change per key (not used) */
+ unsigned short lfo1delay; /* LFO1 delay (0x8000) */
+ unsigned short lfo2delay; /* LFO2 delay (0x8000) */
+ unsigned short pefe; /* modulation pitch & cutoff (0x0000) */
+ unsigned short fmmod; /* LFO1 pitch & cutoff (0x0000) */
+ unsigned short tremfrq; /* LFO1 volume & freq (0x0000) */
+ unsigned short fm2frq2; /* LFO2 pitch & freq (0x0000) */
+ unsigned char cutoff; /* initial cutoff (0xff) */
+ unsigned char filterQ; /* initial filter Q [0-15] (0x0) */
+ unsigned char chorus; /* chorus send (0x00) */
+ unsigned char reverb; /* reverb send (0x00) */
+ unsigned short reserved[4]; /* not used */
+} soundfont_voice_parm_t;
+
+
+/* wave table parameters: 92 bytes */
+typedef struct soundfont_voice_info_t {
+ unsigned short sf_id; /* file id (should be zero) */
+ unsigned short sample; /* sample id */
+ int start, end; /* sample offset correction */
+ int loopstart, loopend; /* loop offset correction */
+ short rate_offset; /* sample rate pitch offset */
+ unsigned short mode; /* sample mode */
+#define SNDRV_SFNT_MODE_ROMSOUND 0x8000
+#define SNDRV_SFNT_MODE_STEREO 1
+#define SNDRV_SFNT_MODE_LOOPING 2
+#define SNDRV_SFNT_MODE_NORELEASE 4 /* obsolete */
+#define SNDRV_SFNT_MODE_INIT_PARM 8
+
+ short root; /* midi root key */
+ short tune; /* pitch tuning (in cents) */
+ unsigned char low, high; /* key note range */
+ unsigned char vellow, velhigh; /* velocity range */
+ signed char fixkey, fixvel; /* fixed key, velocity */
+ signed char pan, fixpan; /* panning, fixed panning */
+ short exclusiveClass; /* exclusive class (0 = none) */
+ unsigned char amplitude; /* sample volume (127 max) */
+ unsigned char attenuation; /* attenuation (0.375dB) */
+ short scaleTuning; /* pitch scale tuning(%), normally 100 */
+ soundfont_voice_parm_t parm; /* voice envelope parameters */
+ unsigned short sample_mode; /* sample mode_flag (set by driver) */
+} soundfont_voice_info_t;
+
+
+/* instrument info header: 4 bytes */
+typedef struct soundfont_voice_rec_hdr_t {
+ unsigned char bank; /* midi bank number */
+ unsigned char instr; /* midi preset number */
+ char nvoices; /* number of voices */
+ char write_mode; /* write mode; normally 0 */
+#define SNDRV_SFNT_WR_APPEND 0 /* append anyway */
+#define SNDRV_SFNT_WR_EXCLUSIVE 1 /* skip if already exists */
+#define SNDRV_SFNT_WR_REPLACE 2 /* replace if already exists */
+} soundfont_voice_rec_hdr_t;
+
+
+/*
+ * sample wave information
+ */
+
+/* wave table sample header: 32 bytes */
+typedef struct soundfont_sample_info_t {
+ unsigned short sf_id; /* file id (should be zero) */
+ unsigned short sample; /* sample id */
+ int start, end; /* start & end offset */
+ int loopstart, loopend; /* loop start & end offset */
+ int size; /* size (0 = ROM) */
+ short dummy; /* not used */
+ unsigned short mode_flags; /* mode flags */
+#define SNDRV_SFNT_SAMPLE_8BITS 1 /* wave data is 8bits */
+#define SNDRV_SFNT_SAMPLE_UNSIGNED 2 /* wave data is unsigned */
+#define SNDRV_SFNT_SAMPLE_NO_BLANK 4 /* no blank loop is attached */
+#define SNDRV_SFNT_SAMPLE_SINGLESHOT 8 /* single-shot w/o loop */
+#define SNDRV_SFNT_SAMPLE_BIDIR_LOOP 16 /* bidirectional looping */
+#define SNDRV_SFNT_SAMPLE_STEREO_LEFT 32 /* stereo left sound */
+#define SNDRV_SFNT_SAMPLE_STEREO_RIGHT 64 /* stereo right sound */
+#define SNDRV_SFNT_SAMPLE_REVERSE_LOOP 128 /* reverse looping */
+ unsigned int truesize; /* used memory size (set by driver) */
+} soundfont_sample_info_t;
+
+
+/*
+ * voice preset mapping (aliasing)
+ */
+
+typedef struct soundfont_voice_map_t {
+ int map_bank, map_instr, map_key; /* key = -1 means all keys */
+ int src_bank, src_instr, src_key;
+} soundfont_voice_map_t;
+
+
+/*
+ * ioctls for hwdep
+ */
+
+#define SNDRV_EMUX_HWDEP_NAME "Emux WaveTable"
+
+#define SNDRV_EMUX_VERSION ((1 << 16) | (0 << 8) | 0) /* 1.0.0 */
+
+struct sndrv_emux_misc_mode {
+ int port; /* -1 = all */
+ int mode;
+ int value;
+ int value2; /* reserved */
+};
+
+enum {
+ SNDRV_EMUX_IOCTL_VERSION = _IOR('H', 0x80, unsigned int),
+ SNDRV_EMUX_IOCTL_LOAD_PATCH = _IOWR('H', 0x81, soundfont_patch_info_t),
+ SNDRV_EMUX_IOCTL_RESET_SAMPLES = _IO('H', 0x82),
+ SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES = _IO('H', 0x83),
+ SNDRV_EMUX_IOCTL_MEM_AVAIL = _IOW('H', 0x84, int),
+ SNDRV_EMUX_IOCTL_MISC_MODE = _IOWR('H', 0x84, struct sndrv_emux_misc_mode),
+};
+
+#endif /* __SOUND_SFNT_INFO_H */
diff --git a/include/sound/snd_wavefront.h b/include/sound/snd_wavefront.h
new file mode 100644
index 0000000..4b0b2b9
--- /dev/null
+++ b/include/sound/snd_wavefront.h
@@ -0,0 +1,141 @@
+#ifndef __SOUND_SND_WAVEFRONT_H__
+#define __SOUND_SND_WAVEFRONT_H__
+
+#include "cs4231.h"
+#include "mpu401.h"
+#include "hwdep.h"
+#include "rawmidi.h"
+#include "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 */
+ snd_rawmidi_substream_t *substream_output[2];
+ snd_rawmidi_substream_t *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 snd_rawmidi_ops_t snd_wavefront_midi_output;
+extern snd_rawmidi_ops_t 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 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_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 (snd_hwdep_t *,
+ struct file *,
+ unsigned int cmd,
+ unsigned long arg);
+extern int snd_wavefront_synth_open (snd_hwdep_t *, struct file *);
+extern int snd_wavefront_synth_release (snd_hwdep_t *, 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 (snd_hwdep_t *,
+ struct file *,
+ unsigned int cmd,
+ unsigned long arg);
+extern int snd_wavefront_fx_open (snd_hwdep_t *, struct file *);
+extern int snd_wavefront_fx_release (snd_hwdep_t *, struct file *);
+
+/* prefix in all snd_printk() delivered messages */
+
+#define LOGNAME "WaveFront: "
+
+#endif /* __SOUND_SND_WAVEFRONT_H__ */
diff --git a/include/sound/soundfont.h b/include/sound/soundfont.h
new file mode 100644
index 0000000..c992958
--- /dev/null
+++ b/include/sound/soundfont.h
@@ -0,0 +1,130 @@
+#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 "sfnt_info.h"
+#include "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)
+
+typedef 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 */
+
+ soundfont_voice_info_t 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 */
+} snd_sf_zone_t;
+
+typedef struct snd_sf_sample {
+ soundfont_sample_info_t v;
+ int counter;
+ snd_util_memblk_t *block; /* allocated data block */
+ struct snd_sf_sample *next;
+} snd_sf_sample_t;
+
+/*
+ * This represents all the information relating to a soundfont.
+ */
+typedef 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 */
+ snd_sf_zone_t *zones; /* Font information */
+ snd_sf_sample_t *samples; /* The sample headers */
+} snd_soundfont_t;
+
+/*
+ * Type of the sample access callback
+ */
+typedef int (*snd_sf_sample_new_t)(void *private_data, snd_sf_sample_t *sp,
+ snd_util_memhdr_t *hdr, const void __user *buf, long count);
+typedef int (*snd_sf_sample_free_t)(void *private_data, snd_sf_sample_t *sp,
+ snd_util_memhdr_t *hdr);
+typedef void (*snd_sf_sample_reset_t)(void *private);
+
+typedef struct snd_sf_callback {
+ void *private_data;
+ snd_sf_sample_new_t sample_new;
+ snd_sf_sample_free_t sample_free;
+ snd_sf_sample_reset_t sample_reset;
+} snd_sf_callback_t;
+
+/*
+ * List of soundfonts.
+ */
+typedef struct snd_sf_list {
+ snd_soundfont_t *currsf; /* The currently open soundfont */
+ int open_client; /* client pointer for lock */
+ int mem_used; /* used memory size */
+ snd_sf_zone_t *presets[SF_MAX_PRESETS];
+ snd_soundfont_t *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 */
+ snd_sf_callback_t callback; /* callback functions */
+ int presets_locked;
+ struct semaphore presets_mutex;
+ spinlock_t lock;
+ snd_util_memhdr_t *memhdr;
+} snd_sf_list_t;
+
+/* Prototypes for soundfont.c */
+int snd_soundfont_load(snd_sf_list_t *sflist, const void __user *data, long count, int client);
+int snd_soundfont_load_guspatch(snd_sf_list_t *sflist, const char __user *data,
+ long count, int client);
+int snd_soundfont_close_check(snd_sf_list_t *sflist, int client);
+
+snd_sf_list_t *snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr);
+void snd_sf_free(snd_sf_list_t *sflist);
+
+int snd_soundfont_remove_samples(snd_sf_list_t *sflist);
+int snd_soundfont_remove_unlocked(snd_sf_list_t *sflist);
+
+int snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
+ int preset, int bank,
+ int def_preset, int def_bank,
+ snd_sf_zone_t **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/sscape_ioctl.h b/include/sound/sscape_ioctl.h
new file mode 100644
index 0000000..0d88859
--- /dev/null
+++ b/include/sound/sscape_ioctl.h
@@ -0,0 +1,21 @@
+#ifndef SSCAPE_IOCTL_H
+#define SSCAPE_IOCTL_H
+
+
+struct sscape_bootblock
+{
+ unsigned char code[256];
+ unsigned version;
+};
+
+#define SSCAPE_MICROCODE_SIZE 65536
+
+struct sscape_microcode
+{
+ unsigned char __user *code;
+};
+
+#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
+#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode)
+
+#endif
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
new file mode 100644
index 0000000..ad3c3be3
--- /dev/null
+++ b/include/sound/tea575x-tuner.h
@@ -0,0 +1,53 @@
+#ifndef __SOUND_TEA575X_TUNER_H
+#define __SOUND_TEA575X_TUNER_H
+
+/*
+ * ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
+ *
+ * Copyright (c) 2004 Jaroslav Kysela <perex@suse.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/videodev.h>
+
+typedef struct snd_tea575x tea575x_t;
+
+struct snd_tea575x_ops {
+ void (*write)(tea575x_t *tea, unsigned int val);
+ unsigned int (*read)(tea575x_t *tea);
+};
+
+struct snd_tea575x {
+ snd_card_t *card;
+ struct video_device vd; /* video device */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
+ struct file_operations fops;
+#endif
+ int dev_nr; /* requested device number + 1 */
+ int vd_registered; /* video device is registered */
+ int tea5759; /* 5759 chip is present */
+ unsigned int freq_fixup; /* crystal onboard */
+ unsigned int val; /* hw value */
+ unsigned long freq; /* frequency */
+ struct snd_tea575x_ops *ops;
+ void *private_data;
+};
+
+void snd_tea575x_init(tea575x_t *tea);
+void snd_tea575x_exit(tea575x_t *tea);
+
+#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/include/sound/tea6330t.h b/include/sound/tea6330t.h
new file mode 100644
index 0000000..3896c0a
--- /dev/null
+++ b/include/sound/tea6330t.h
@@ -0,0 +1,42 @@
+#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 "control.h"
+#include "i2c.h" /* generic i2c support */
+
+typedef struct {
+ snd_i2c_device_t *device;
+ snd_i2c_bus_t *bus;
+ int equalizer;
+ int fader;
+ unsigned char regs[8];
+ unsigned char mleft, mright;
+ unsigned char bass, treble;
+ unsigned char max_bass, max_treble;
+} tea6330t_t;
+
+extern int snd_tea6330t_detect(snd_i2c_bus_t *bus, int equalizer);
+extern int snd_tea6330t_update_mixer(snd_card_t * card, snd_i2c_bus_t * 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..57fde99
--- /dev/null
+++ b/include/sound/timer.h
@@ -0,0 +1,157 @@
+#ifndef __SOUND_TIMER_H
+#define __SOUND_TIMER_H
+
+/*
+ * Timer abstract layer
+ * Copyright (c) by Jaroslav Kysela <perex@suse.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>
+
+typedef enum sndrv_timer_class snd_timer_class_t;
+typedef enum sndrv_timer_slave_class snd_timer_slave_class_t;
+typedef enum sndrv_timer_global snd_timer_global_t;
+typedef struct sndrv_timer_id snd_timer_id_t;
+typedef struct sndrv_timer_ginfo snd_timer_ginfo_t;
+typedef struct sndrv_timer_gparams snd_timer_gparams_t;
+typedef struct sndrv_timer_gstatus snd_timer_gstatus_t;
+typedef struct sndrv_timer_select snd_timer_select_t;
+typedef struct sndrv_timer_info snd_timer_info_t;
+typedef struct sndrv_timer_params snd_timer_params_t;
+typedef struct sndrv_timer_status snd_timer_status_t;
+typedef struct sndrv_timer_read snd_timer_read_t;
+typedef struct sndrv_timer_tread snd_timer_tread_t;
+
+#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 */
+
+typedef void (*snd_timer_callback_t) (snd_timer_instance_t * timeri, unsigned long ticks, unsigned long resolution);
+typedef void (*snd_timer_ccallback_t) (snd_timer_instance_t * timeri, enum sndrv_timer_event event,
+ struct timespec * tstamp, unsigned long resolution);
+
+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) (snd_timer_t * timer);
+ int (*close) (snd_timer_t * timer);
+ unsigned long (*c_resolution) (snd_timer_t * timer);
+ int (*start) (snd_timer_t * timer);
+ int (*stop) (snd_timer_t * timer);
+ int (*set_period) (snd_timer_t * timer, unsigned long period_num, unsigned long period_den);
+ int (*precise_resolution) (snd_timer_t * timer, unsigned long *num, unsigned long *den);
+};
+
+struct _snd_timer {
+ snd_timer_class_t tmr_class;
+ snd_card_t *card;
+ 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) (snd_timer_t *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 {
+ snd_timer_t * timer;
+ char *owner;
+ unsigned int flags;
+ void *private_data;
+ void (*private_free) (snd_timer_instance_t *ti);
+ snd_timer_callback_t callback;
+ snd_timer_ccallback_t ccallback;
+ 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 */
+ snd_timer_slave_class_t 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;
+ snd_timer_instance_t *master;
+};
+
+/*
+ * Registering
+ */
+
+extern int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer);
+extern void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp);
+extern int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer);
+extern int snd_timer_global_free(snd_timer_t *timer);
+extern int snd_timer_global_register(snd_timer_t *timer);
+extern int snd_timer_global_unregister(snd_timer_t *timer);
+
+extern int snd_timer_open(snd_timer_instance_t ** ti, char *owner, snd_timer_id_t *tid, unsigned int slave_id);
+extern int snd_timer_close(snd_timer_instance_t * timeri);
+extern unsigned long snd_timer_resolution(snd_timer_instance_t * timeri);
+extern int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks);
+extern int snd_timer_stop(snd_timer_instance_t * timeri);
+extern int snd_timer_continue(snd_timer_instance_t * timeri);
+extern int snd_timer_pause(snd_timer_instance_t * timeri);
+
+extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left);
+
+extern unsigned int snd_timer_system_resolution(void);
+
+#endif /* __SOUND_TIMER_H */
diff --git a/include/sound/trident.h b/include/sound/trident.h
new file mode 100644
index 0000000..f5254ec
--- /dev/null
+++ b/include/sound/trident.h
@@ -0,0 +1,479 @@
+#ifndef __SOUND_TRIDENT_H
+#define __SOUND_TRIDENT_H
+
+/*
+ * audio@tridentmicro.com
+ * Fri Feb 19 15:55:28 MST 1999
+ * Definitions for Trident 4DWave DX/NX 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 "pcm.h"
+#include "mpu401.h"
+#include "ac97_codec.h"
+#include "seq_midi_emul.h"
+#include "seq_device.h"
+#include "util_mem.h"
+//#include "ainstr_iw.h"
+//#include "ainstr_gf1.h"
+#include "ainstr_simple.h"
+
+#ifndef PCI_VENDOR_ID_TRIDENT
+#define PCI_VENDOR_ID_TRIDENT 0x1023
+#endif
+#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_DX
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
+#endif
+#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_NX
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
+#endif
+
+#ifndef PCI_VENDOR_ID_SI
+#define PCI_VENDOR_ID_SI 0x1039
+#endif
+#ifndef PCI_DEVICE_ID_SI_7018
+#define PCI_DEVICE_ID_SI_7018 0x7018
+#endif
+
+#define TRIDENT_DEVICE_ID_DX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_DX)
+#define TRIDENT_DEVICE_ID_NX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_NX)
+#define TRIDENT_DEVICE_ID_SI7018 ((PCI_VENDOR_ID_SI<<16)|PCI_DEVICE_ID_SI_7018)
+
+#define SNDRV_SEQ_DEV_ID_TRIDENT "trident-synth"
+
+#define SNDRV_TRIDENT_VOICE_TYPE_PCM 0
+#define SNDRV_TRIDENT_VOICE_TYPE_SYNTH 1
+#define SNDRV_TRIDENT_VOICE_TYPE_MIDI 2
+
+#define SNDRV_TRIDENT_VFLG_RUNNING (1<<0)
+
+/* TLB code constants */
+#define SNDRV_TRIDENT_PAGE_SIZE 4096
+#define SNDRV_TRIDENT_PAGE_SHIFT 12
+#define SNDRV_TRIDENT_PAGE_MASK ((1<<SNDRV_TRIDENT_PAGE_SHIFT)-1)
+#define SNDRV_TRIDENT_MAX_PAGES 4096
+
+/*
+ * Direct registers
+ */
+
+#define TRID_REG(trident, x) ((trident)->port + (x))
+
+#define ID_4DWAVE_DX 0x2000
+#define ID_4DWAVE_NX 0x2001
+
+/* Bank definitions */
+
+#define T4D_BANK_A 0
+#define T4D_BANK_B 1
+#define T4D_NUM_BANKS 2
+
+/* Register definitions */
+
+/* Global registers */
+
+enum global_control_bits {
+ CHANNEL_IDX = 0x0000003f,
+ OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
+ UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
+ ENDLP_IE = 0x00001000, /* interrupt enable: end of buffer */
+ MIDLP_IE = 0x00002000, /* interrupt enable: middle buffer */
+ ETOG_IE = 0x00004000, /* interrupt enable: envelope toggling */
+ EDROP_IE = 0x00008000, /* interrupt enable: envelope drop */
+ BANK_B_EN = 0x00010000, /* SiS: enable bank B (64 channels) */
+ PCMIN_B_MIX = 0x00020000, /* SiS: PCM IN B mixing enable */
+ I2S_OUT_ASSIGN = 0x00040000, /* SiS: I2S Out contains surround PCM */
+ SPDIF_OUT_ASSIGN= 0x00080000, /* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
+ MAIN_OUT_ASSIGN = 0x00100000, /* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
+};
+
+enum miscint_bits {
+ PB_UNDERRUN_IRQ = 0x00000001, REC_OVERRUN_IRQ = 0x00000002,
+ SB_IRQ = 0x00000004, MPU401_IRQ = 0x00000008,
+ OPL3_IRQ = 0x00000010, ADDRESS_IRQ = 0x00000020,
+ ENVELOPE_IRQ = 0x00000040, PB_UNDERRUN = 0x00000100,
+ REC_OVERRUN = 0x00000200, MIXER_UNDERFLOW = 0x00000400,
+ MIXER_OVERFLOW = 0x00000800, NX_SB_IRQ_DISABLE = 0x00001000,
+ ST_TARGET_REACHED = 0x00008000,
+ PB_24K_MODE = 0x00010000, ST_IRQ_EN = 0x00800000,
+ ACGPIO_IRQ = 0x01000000
+};
+
+/* T2 legacy dma control registers. */
+#define LEGACY_DMAR0 0x00 // ADR0
+#define LEGACY_DMAR4 0x04 // CNT0
+#define LEGACY_DMAR6 0x06 // CNT0 - High bits
+#define LEGACY_DMAR11 0x0b // MOD
+#define LEGACY_DMAR15 0x0f // MMR
+
+#define T4D_START_A 0x80
+#define T4D_STOP_A 0x84
+#define T4D_DLY_A 0x88
+#define T4D_SIGN_CSO_A 0x8c
+#define T4D_CSPF_A 0x90
+#define T4D_CSPF_B 0xbc
+#define T4D_CEBC_A 0x94
+#define T4D_AINT_A 0x98
+#define T4D_AINTEN_A 0x9c
+#define T4D_LFO_GC_CIR 0xa0
+#define T4D_MUSICVOL_WAVEVOL 0xa8
+#define T4D_SBDELTA_DELTA_R 0xac
+#define T4D_MISCINT 0xb0
+#define T4D_START_B 0xb4
+#define T4D_STOP_B 0xb8
+#define T4D_SBBL_SBCL 0xc0
+#define T4D_SBCTRL_SBE2R_SBDD 0xc4
+#define T4D_STIMER 0xc8
+#define T4D_AINT_B 0xd8
+#define T4D_AINTEN_B 0xdc
+#define T4D_RCI 0x70
+
+/* MPU-401 UART */
+#define T4D_MPU401_BASE 0x20
+#define T4D_MPUR0 0x20
+#define T4D_MPUR1 0x21
+#define T4D_MPUR2 0x22
+#define T4D_MPUR3 0x23
+
+/* S/PDIF Registers */
+#define NX_SPCTRL_SPCSO 0x24
+#define NX_SPLBA 0x28
+#define NX_SPESO 0x2c
+#define NX_SPCSTATUS 0x64
+
+/* Joystick */
+#define GAMEPORT_GCR 0x30
+#define GAMEPORT_MODE_ADC 0x80
+#define GAMEPORT_LEGACY 0x31
+#define GAMEPORT_AXES 0x34
+
+/* NX Specific Registers */
+#define NX_TLBC 0x6c
+
+/* Channel Registers */
+
+#define CH_START 0xe0
+
+#define CH_DX_CSO_ALPHA_FMS 0xe0
+#define CH_DX_ESO_DELTA 0xe8
+#define CH_DX_FMC_RVOL_CVOL 0xec
+
+#define CH_NX_DELTA_CSO 0xe0
+#define CH_NX_DELTA_ESO 0xe8
+#define CH_NX_ALPHA_FMS_FMC_RVOL_CVOL 0xec
+
+#define CH_LBA 0xe4
+#define CH_GVSEL_PAN_VOL_CTRL_EC 0xf0
+#define CH_EBUF1 0xf4
+#define CH_EBUF2 0xf8
+
+/* AC-97 Registers */
+
+#define DX_ACR0_AC97_W 0x40
+#define DX_ACR1_AC97_R 0x44
+#define DX_ACR2_AC97_COM_STAT 0x48
+
+#define NX_ACR0_AC97_COM_STAT 0x40
+#define NX_ACR1_AC97_W 0x44
+#define NX_ACR2_AC97_R_PRIMARY 0x48
+#define NX_ACR3_AC97_R_SECONDARY 0x4c
+
+#define SI_AC97_WRITE 0x40
+#define SI_AC97_READ 0x44
+#define SI_SERIAL_INTF_CTRL 0x48
+#define SI_AC97_GPIO 0x4c
+#define SI_ASR0 0x50
+#define SI_SPDIF_CS 0x70
+#define SI_GPIO 0x7c
+
+enum trident_nx_ac97_bits {
+ /* ACR1-3 */
+ NX_AC97_BUSY_WRITE = 0x0800,
+ NX_AC97_BUSY_READ = 0x0800,
+ NX_AC97_BUSY_DATA = 0x0400,
+ NX_AC97_WRITE_SECONDARY = 0x0100,
+ /* ACR0 */
+ NX_AC97_SECONDARY_READY = 0x0040,
+ NX_AC97_SECONDARY_RECORD = 0x0020,
+ NX_AC97_SURROUND_OUTPUT = 0x0010,
+ NX_AC97_PRIMARY_READY = 0x0008,
+ NX_AC97_PRIMARY_RECORD = 0x0004,
+ NX_AC97_PCM_OUTPUT = 0x0002,
+ NX_AC97_WARM_RESET = 0x0001
+};
+
+enum trident_dx_ac97_bits {
+ DX_AC97_BUSY_WRITE = 0x8000,
+ DX_AC97_BUSY_READ = 0x8000,
+ DX_AC97_READY = 0x0010,
+ DX_AC97_RECORD = 0x0008,
+ DX_AC97_PLAYBACK = 0x0002
+};
+
+enum sis7018_ac97_bits {
+ SI_AC97_BUSY_WRITE = 0x00008000,
+ SI_AC97_AUDIO_BUSY = 0x00004000,
+ SI_AC97_MODEM_BUSY = 0x00002000,
+ SI_AC97_BUSY_READ = 0x00008000,
+ SI_AC97_SECONDARY = 0x00000080,
+};
+
+enum serial_intf_ctrl_bits {
+ WARM_RESET = 0x00000001,
+ COLD_RESET = 0x00000002,
+ I2S_CLOCK = 0x00000004,
+ PCM_SEC_AC97 = 0x00000008,
+ AC97_DBL_RATE = 0x00000010,
+ SPDIF_EN = 0x00000020,
+ I2S_OUTPUT_EN = 0x00000040,
+ I2S_INPUT_EN = 0x00000080,
+ PCMIN = 0x00000100,
+ LINE1IN = 0x00000200,
+ MICIN = 0x00000400,
+ LINE2IN = 0x00000800,
+ HEAD_SET_IN = 0x00001000,
+ GPIOIN = 0x00002000,
+ /* 7018 spec says id = 01 but the demo board routed to 10
+ SECONDARY_ID= 0x00004000, */
+ SECONDARY_ID = 0x00004000,
+ PCMOUT = 0x00010000,
+ SURROUT = 0x00020000,
+ CENTEROUT = 0x00040000,
+ LFEOUT = 0x00080000,
+ LINE1OUT = 0x00100000,
+ LINE2OUT = 0x00200000,
+ GPIOOUT = 0x00400000,
+ SI_AC97_PRIMARY_READY = 0x01000000,
+ SI_AC97_SECONDARY_READY = 0x02000000,
+ SI_AC97_POWERDOWN = 0x04000000,
+};
+
+/* PCM defaults */
+
+#define T4D_DEFAULT_PCM_VOL 10 /* 0 - 255 */
+#define T4D_DEFAULT_PCM_PAN 0 /* 0 - 127 */
+#define T4D_DEFAULT_PCM_RVOL 127 /* 0 - 127 */
+#define T4D_DEFAULT_PCM_CVOL 127 /* 0 - 127 */
+
+typedef struct _snd_trident trident_t;
+typedef struct _snd_trident_voice snd_trident_voice_t;
+typedef struct _snd_trident_pcm_mixer snd_trident_pcm_mixer_t;
+
+typedef struct {
+ void (*sample_start)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_position_t position);
+ void (*sample_stop)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_stop_mode_t mode);
+ void (*sample_freq)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_frequency_t freq);
+ void (*sample_volume)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_ev_volume_t *volume);
+ void (*sample_loop)(trident_t *card, snd_trident_voice_t *voice, snd_seq_ev_loop_t *loop);
+ void (*sample_pos)(trident_t *card, snd_trident_voice_t *voice, snd_seq_position_t position);
+ void (*sample_private1)(trident_t *card, snd_trident_voice_t *voice, unsigned char *data);
+} snd_trident_sample_ops_t;
+
+typedef struct {
+ snd_midi_channel_set_t * chset;
+ trident_t * trident;
+ int mode; /* operation mode */
+ int client; /* sequencer client number */
+ int port; /* sequencer port number */
+ unsigned int midi_has_voices: 1;
+} snd_trident_port_t;
+
+typedef struct snd_trident_memblk_arg {
+ short first_page, last_page;
+} snd_trident_memblk_arg_t;
+
+typedef struct {
+ unsigned int * entries; /* 16k-aligned TLB table */
+ dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */
+ unsigned long * shadow_entries; /* shadow entries with virtual addresses */
+ struct snd_dma_buffer buffer;
+ snd_util_memhdr_t * memhdr; /* page allocation list */
+ struct snd_dma_buffer silent_page;
+} snd_trident_tlb_t;
+
+struct _snd_trident_voice {
+ unsigned int number;
+ unsigned int use: 1,
+ pcm: 1,
+ synth:1,
+ midi: 1;
+ unsigned int flags;
+ unsigned char client;
+ unsigned char port;
+ unsigned char index;
+
+ snd_seq_instr_t instr;
+ snd_trident_sample_ops_t *sample_ops;
+
+ /* channel parameters */
+ unsigned int CSO; /* 24 bits (16 on DX) */
+ unsigned int ESO; /* 24 bits (16 on DX) */
+ unsigned int LBA; /* 30 bits */
+ unsigned short EC; /* 12 bits */
+ unsigned short Alpha; /* 12 bits */
+ unsigned short Delta; /* 16 bits */
+ unsigned short Attribute; /* 16 bits - SiS 7018 */
+ unsigned short Vol; /* 12 bits (6.6) */
+ unsigned char Pan; /* 7 bits (1.4.2) */
+ unsigned char GVSel; /* 1 bit */
+ unsigned char RVol; /* 7 bits (5.2) */
+ unsigned char CVol; /* 7 bits (5.2) */
+ unsigned char FMC; /* 2 bits */
+ unsigned char CTRL; /* 4 bits */
+ unsigned char FMS; /* 4 bits */
+ unsigned char LFO; /* 8 bits */
+
+ unsigned int negCSO; /* nonzero - use negative CSO */
+
+ snd_util_memblk_t *memblk; /* memory block if TLB enabled */
+
+ /* PCM data */
+
+ trident_t *trident;
+ snd_pcm_substream_t *substream;
+ snd_trident_voice_t *extra; /* extra PCM voice (acts as interrupt generator) */
+ unsigned int running: 1,
+ capture: 1,
+ spdif: 1,
+ foldback: 1,
+ isync: 1,
+ isync2: 1,
+ isync3: 1;
+ int foldback_chan; /* foldback subdevice number */
+ unsigned int stimer; /* global sample timer (to detect spurious interrupts) */
+ unsigned int spurious_threshold; /* spurious threshold */
+ unsigned int isync_mark;
+ unsigned int isync_max;
+ unsigned int isync_ESO;
+
+ /* --- */
+
+ void *private_data;
+ void (*private_free)(snd_trident_voice_t *voice);
+};
+
+struct _snd_4dwave {
+ int seq_client;
+
+ snd_trident_port_t seq_ports[4];
+ snd_simple_ops_t simple_ops;
+ snd_seq_kinstr_list_t *ilist;
+
+ snd_trident_voice_t voices[64];
+
+ int ChanSynthCount; /* number of allocated synth channels */
+ int max_size; /* maximum synth memory size in bytes */
+ int current_size; /* current allocated synth mem in bytes */
+};
+
+struct _snd_trident_pcm_mixer {
+ snd_trident_voice_t *voice; /* active voice */
+ unsigned short vol; /* front volume */
+ unsigned char pan; /* pan control */
+ unsigned char rvol; /* rear volume */
+ unsigned char cvol; /* center volume */
+ unsigned char pad;
+};
+
+struct _snd_trident {
+ int irq;
+
+ unsigned int device; /* device ID */
+
+ unsigned char bDMAStart;
+
+ unsigned long port;
+ unsigned long midi_port;
+
+ unsigned int spurious_irq_count;
+ unsigned int spurious_irq_max_delta;
+
+ snd_trident_tlb_t tlb; /* TLB entries for NX cards */
+
+ unsigned char spdif_ctrl;
+ unsigned char spdif_pcm_ctrl;
+ unsigned int spdif_bits;
+ unsigned int spdif_pcm_bits;
+ snd_kcontrol_t *spdif_pcm_ctl; /* S/PDIF settings */
+ unsigned int ac97_ctrl;
+
+ unsigned int ChanMap[2]; /* allocation map for hardware channels */
+
+ int ChanPCM; /* max number of PCM channels */
+ int ChanPCMcnt; /* actual number of PCM channels */
+
+ unsigned int ac97_detect: 1; /* 1 = AC97 in detection phase */
+ unsigned int in_suspend: 1; /* 1 during suspend/resume */
+
+ struct _snd_4dwave synth; /* synth specific variables */
+
+ spinlock_t event_lock;
+ spinlock_t voice_alloc;
+
+ struct snd_dma_device dma_dev;
+
+ struct pci_dev *pci;
+ snd_card_t *card;
+ snd_pcm_t *pcm; /* ADC/DAC PCM */
+ snd_pcm_t *foldback; /* Foldback PCM */
+ snd_pcm_t *spdif; /* SPDIF PCM */
+ snd_rawmidi_t *rmidi;
+ snd_seq_device_t *seq_dev;
+
+ ac97_bus_t *ac97_bus;
+ ac97_t *ac97;
+ ac97_t *ac97_sec;
+
+ unsigned int musicvol_wavevol;
+ snd_trident_pcm_mixer_t pcm_mixer[32];
+ snd_kcontrol_t *ctl_vol; /* front volume */
+ snd_kcontrol_t *ctl_pan; /* pan */
+ snd_kcontrol_t *ctl_rvol; /* rear volume */
+ snd_kcontrol_t *ctl_cvol; /* center volume */
+
+ spinlock_t reg_lock;
+
+ struct gameport *gameport;
+};
+
+int snd_trident_create(snd_card_t * card,
+ struct pci_dev *pci,
+ int pcm_streams,
+ int pcm_spdif_device,
+ int max_wavetable_size,
+ trident_t ** rtrident);
+int snd_trident_create_gameport(trident_t *trident);
+
+int snd_trident_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
+int snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
+int snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
+int snd_trident_attach_synthesizer(trident_t * trident);
+snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port);
+void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice);
+void snd_trident_start_voice(trident_t * trident, unsigned int voice);
+void snd_trident_stop_voice(trident_t * trident, unsigned int voice);
+void snd_trident_write_voice_regs(trident_t * trident, snd_trident_voice_t *voice);
+
+/* TLB memory allocation */
+snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream);
+int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk);
+snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size);
+int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk);
+int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
+
+#endif /* __SOUND_TRIDENT_H */
diff --git a/include/sound/uda1341.h b/include/sound/uda1341.h
new file mode 100644
index 0000000..61ff65a
--- /dev/null
+++ b/include/sound/uda1341.h
@@ -0,0 +1,233 @@
+/*
+ * linux/include/linux/l3/uda1341.h
+ *
+ * Philips UDA1341 mixer device driver for ALSA
+ *
+ * Copyright (c) 2002 Tomas Kasparek <tomas.kasparek@seznam.cz>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * History:
+ *
+ * 2002-03-13 Tomas Kasparek Initial release - based on uda1341.h from OSS
+ * 2002-03-30 Tomas Kasparek Proc filesystem support, complete mixer and DSP
+ * features support
+ */
+
+/* $Id: uda1341.h,v 1.6 2004/05/03 17:36:50 tiwai Exp $ */
+
+#define UDA1341_ALSA_NAME "snd-uda1341"
+
+/*
+ * Default rate set after inicialization
+ */
+#define AUDIO_RATE_DEFAULT 44100
+
+/*
+ * UDA1341 L3 address and command types
+ */
+#define UDA1341_L3ADDR 5
+#define UDA1341_DATA0 (UDA1341_L3ADDR << 2 | 0)
+#define UDA1341_DATA1 (UDA1341_L3ADDR << 2 | 1)
+#define UDA1341_STATUS (UDA1341_L3ADDR << 2 | 2)
+
+enum uda1341_onoff {
+ OFF=0,
+ ON,
+};
+
+const char *onoff_names[] = {
+ "Off",
+ "On",
+};
+
+enum uda1341_format {
+ I2S=0,
+ LSB16,
+ LSB18,
+ LSB20,
+ MSB,
+ LSB16MSB,
+ LSB18MSB,
+ LSB20MSB,
+};
+
+const char *format_names[] = {
+ "I2S-bus",
+ "LSB 16bits",
+ "LSB 18bits",
+ "LSB 20bits",
+ "MSB",
+ "in LSB 16bits/out MSB",
+ "in LSB 18bits/out MSB",
+ "in LSB 20bits/out MSB",
+};
+
+enum uda1341_fs {
+ F512=0,
+ F384,
+ F256,
+ Funused,
+};
+
+const char *fs_names[] = {
+ "512*fs",
+ "384*fs",
+ "256*fs",
+ "Unused - bad value!",
+};
+
+enum uda1341_peak {
+ BEFORE=0,
+ AFTER,
+};
+
+const char *peak_names[] = {
+ "before",
+ "after",
+};
+
+enum uda1341_filter {
+ FLAT=0,
+ MIN,
+ MIN2,
+ MAX,
+};
+
+const char *filter_names[] = {
+ "flat",
+ "min",
+ "min",
+ "max",
+};
+
+const char*bass_values[][16] = {
+ {"0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB",
+ "0 dB", "0 dB", "0 dB", "0 dB", "undefined", }, //flat
+ {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB",
+ "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min
+ {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB",
+ "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min
+ {"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "20 dB",
+ "22 dB", "24 dB", "24 dB", "24 dB", "undefined",}, // max
+};
+
+enum uda1341_mixer {
+ DOUBLE,
+ LINE,
+ MIC,
+ MIXER,
+};
+
+const char *mixer_names[] = {
+ "double differential",
+ "input channel 1 (line in)",
+ "input channel 2 (microphone)",
+ "digital mixer",
+};
+
+enum uda1341_deemp {
+ NONE,
+ D32,
+ D44,
+ D48,
+};
+
+const char *deemp_names[] = {
+ "none",
+ "32 kHz",
+ "44.1 kHz",
+ "48 kHz",
+};
+
+const char *mic_sens_value[] = {
+ "-3 dB", "0 dB", "3 dB", "9 dB", "15 dB", "21 dB", "27 dB", "not used",
+};
+
+const unsigned short AGC_atime[] = {
+ 11, 16, 11, 16, 21, 11, 16, 21,
+};
+
+const unsigned short AGC_dtime[] = {
+ 100, 100, 200, 200, 200, 400, 400, 400,
+};
+
+const char *AGC_level[] = {
+ "-9.0", "-11.5", "-15.0", "-17.5",
+};
+
+const char *ig_small_value[] = {
+ "-3.0", "-2.5", "-2.0", "-1.5", "-1.0", "-0.5",
+};
+
+/*
+ * this was computed as peak_value[i] = pow((63-i)*1.42,1.013)
+ *
+ * UDA1341 datasheet on page 21: Peak value (dB) = (Peak level - 63.5)*5*log2
+ * There is an table with these values [level]=value: [3]=-90.31, [7]=-84.29
+ * [61]=-2.78, [62] = -1.48, [63] = 0.0
+ * I tried to compute it, but using but even using logarithm with base either 10 or 2
+ * i was'n able to get values in the table from the formula. So I constructed another
+ * formula (see above) to interpolate the values as good as possible. If there is some
+ * mistake, please contact me on tomas.kasparek@seznam.cz. Thanks.
+ * UDA1341TS datasheet is available at:
+ * http://www-us9.semiconductors.com/acrobat/datasheets/UDA1341TS_3.pdf
+ */
+const char *peak_value[] = {
+ "-INF dB", "N.A.", "N.A", "90.31 dB", "N.A.", "N.A.", "N.A.", "-84.29 dB",
+ "-82.65 dB", "-81.13 dB", "-79.61 dB", "-78.09 dB", "-76.57 dB", "-75.05 dB", "-73.53 dB",
+ "-72.01 dB", "-70.49 dB", "-68.97 dB", "-67.45 dB", "-65.93 dB", "-64.41 dB", "-62.90 dB",
+ "-61.38 dB", "-59.86 dB", "-58.35 dB", "-56.83 dB", "-55.32 dB", "-53.80 dB", "-52.29 dB",
+ "-50.78 dB", "-49.26 dB", "-47.75 dB", "-46.24 dB", "-44.73 dB", "-43.22 dB", "-41.71 dB",
+ "-40.20 dB", "-38.69 dB", "-37.19 dB", "-35.68 dB", "-34.17 dB", "-32.67 dB", "-31.17 dB",
+ "-29.66 dB", "-28.16 dB", "-26.66 dB", "-25.16 dB", "-23.66 dB", "-22.16 dB", "-20.67 dB",
+ "-19.17 dB", "-17.68 dB", "-16.19 dB", "-14.70 dB", "-13.21 dB", "-11.72 dB", "-10.24 dB",
+ "-8.76 dB", "-7.28 dB", "-5.81 dB", "-4.34 dB", "-2.88 dB", "-1.43 dB", "0.00 dB",
+};
+
+enum uda1341_config {
+ CMD_READ_REG = 0,
+ CMD_RESET,
+ CMD_FS,
+ CMD_FORMAT,
+ CMD_OGAIN,
+ CMD_IGAIN,
+ CMD_DAC,
+ CMD_ADC,
+ CMD_VOLUME,
+ CMD_BASS,
+ CMD_TREBBLE,
+ CMD_PEAK,
+ CMD_DEEMP,
+ CMD_MUTE,
+ CMD_FILTER,
+ CMD_CH1,
+ CMD_CH2,
+ CMD_MIC,
+ CMD_MIXER,
+ CMD_AGC,
+ CMD_IG,
+ CMD_AGC_TIME,
+ CMD_AGC_LEVEL,
+#ifdef CONFIG_PM
+ CMD_SUSPEND,
+ CMD_RESUME,
+#endif
+ CMD_LAST,
+};
+
+enum write_through {
+ //used in update_bits (write_cfg) to avoid l3_write - just update local copy of regs.
+ REGS_ONLY=0,
+ //update local regs and write value to uda1341 - do l3_write
+ FLUSH,
+};
+
+int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt);
+
+/*
+ * Local variables:
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/include/sound/util_mem.h b/include/sound/util_mem.h
new file mode 100644
index 0000000..9d2cdfa
--- /dev/null
+++ b/include/sound/util_mem.h
@@ -0,0 +1,64 @@
+#ifndef __SOUND_UTIL_MEM_H
+#define __SOUND_UTIL_MEM_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
+ */
+
+typedef struct snd_util_memblk snd_util_memblk_t;
+typedef struct snd_util_memhdr snd_util_memhdr_t;
+typedef unsigned int snd_util_unit_t;
+
+/*
+ * memory block
+ */
+struct snd_util_memblk {
+ snd_util_unit_t size; /* size of this block */
+ snd_util_unit_t offset; /* zero-offset of this block */
+ struct list_head list; /* link */
+};
+
+#define snd_util_memblk_argptr(blk) (void*)((char*)(blk) + sizeof(snd_util_memblk_t))
+
+/*
+ * memory management information
+ */
+struct snd_util_memhdr {
+ snd_util_unit_t size; /* size of whole data */
+ struct list_head block; /* block linked-list header */
+ int nblocks; /* # of allocated blocks */
+ snd_util_unit_t used; /* used memory size */
+ int block_extra_size; /* extra data size of chunk */
+ struct semaphore block_mutex; /* lock */
+};
+
+/*
+ * prototypes
+ */
+snd_util_memhdr_t *snd_util_memhdr_new(int memsize);
+void snd_util_memhdr_free(snd_util_memhdr_t *hdr);
+snd_util_memblk_t *snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size);
+int snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk);
+int snd_util_mem_avail(snd_util_memhdr_t *hdr);
+
+/* functions without mutex */
+snd_util_memblk_t *__snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size);
+void __snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk);
+snd_util_memblk_t *__snd_util_memblk_new(snd_util_memhdr_t *hdr, snd_util_unit_t units, struct list_head *prev);
+
+#endif /* __SOUND_UTIL_MEM_H */
diff --git a/include/sound/version.h b/include/sound/version.h
new file mode 100644
index 0000000..98b4230
--- /dev/null
+++ b/include/sound/version.h
@@ -0,0 +1,3 @@
+/* include/version.h. Generated by configure. */
+#define CONFIG_SND_VERSION "1.0.9rc2"
+#define CONFIG_SND_DATE " (Thu Mar 24 10:33:39 2005 UTC)"
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h
new file mode 100644
index 0000000..a7e2993
--- /dev/null
+++ b/include/sound/vx_core.h
@@ -0,0 +1,562 @@
+/*
+ * 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>
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+#if !defined(CONFIG_USE_VXLOADER) && !defined(CONFIG_SND_VX_LIB) /* built-in kernel */
+#define SND_VX_FW_LOADER /* use the standard firmware loader */
+#endif
+#endif
+
+struct firmware;
+struct device;
+
+typedef struct snd_vx_core vx_core_t;
+typedef struct vx_pipe vx_pipe_t;
+
+#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;
+ snd_pcm_substream_t *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 */
+ vx_pipe_t *monitoring_pipe; /* pointer to the monitoring pipe (capture pipe only)*/
+
+ struct tasklet_struct start_tq;
+};
+
+struct snd_vx_ops {
+ /* low-level i/o */
+ unsigned char (*in8)(vx_core_t *chip, int reg);
+ unsigned int (*in32)(vx_core_t *chip, int reg);
+ void (*out8)(vx_core_t *chip, int reg, unsigned char val);
+ void (*out32)(vx_core_t *chip, int reg, unsigned int val);
+ /* irq */
+ int (*test_and_ack)(vx_core_t *chip);
+ void (*validate_irq)(vx_core_t *chip, int enable);
+ /* codec */
+ void (*write_codec)(vx_core_t *chip, int codec, unsigned int data);
+ void (*akm_write)(vx_core_t *chip, int reg, unsigned int data);
+ void (*reset_codec)(vx_core_t *chip);
+ void (*change_audio_source)(vx_core_t *chip, int src);
+ void (*set_clock_source)(vx_core_t *chp, int src);
+ /* chip init */
+ int (*load_dsp)(vx_core_t *chip, int idx, const struct firmware *fw);
+ void (*reset_dsp)(vx_core_t *chip);
+ void (*reset_board)(vx_core_t *chip, int cold_reset);
+ int (*add_controls)(vx_core_t *chip);
+ /* pcm */
+ void (*dma_write)(vx_core_t *chip, snd_pcm_runtime_t *runtime,
+ vx_pipe_t *pipe, int count);
+ void (*dma_read)(vx_core_t *chip, snd_pcm_runtime_t *runtime,
+ vx_pipe_t *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;
+};
+
+/* 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 snd_vx_core {
+ /* ALSA stuff */
+ snd_card_t *card;
+ snd_pcm_t *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;
+
+ spinlock_t lock;
+ spinlock_t irq_lock;
+ struct tasklet_struct tq;
+
+ unsigned int chip_status;
+ unsigned int pcm_running;
+
+ struct device *dev;
+ snd_hwdep_t *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 semaphore mixer_mutex;
+
+ const struct firmware *firmware[4]; /* loaded firmware data */
+};
+
+
+/*
+ * constructor
+ */
+vx_core_t *snd_vx_create(snd_card_t *card, struct snd_vx_hardware *hw,
+ struct snd_vx_ops *ops, int extra_size);
+int snd_vx_setup_firmware(vx_core_t *chip);
+int snd_vx_load_boot_image(vx_core_t *chip, const struct firmware *dsp);
+int snd_vx_dsp_boot(vx_core_t *chip, const struct firmware *dsp);
+int snd_vx_dsp_load(vx_core_t *chip, const struct firmware *dsp);
+
+void snd_vx_free_firmware(vx_core_t *chip);
+
+/*
+ * interrupt handler; exported for pcmcia
+ */
+irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs);
+
+/*
+ * lowlevel functions
+ */
+inline static int vx_test_and_ack(vx_core_t *chip)
+{
+ snd_assert(chip->ops->test_and_ack, return -ENXIO);
+ return chip->ops->test_and_ack(chip);
+}
+
+inline static void vx_validate_irq(vx_core_t *chip, int enable)
+{
+ snd_assert(chip->ops->validate_irq, return);
+ chip->ops->validate_irq(chip, enable);
+}
+
+inline static unsigned char snd_vx_inb(vx_core_t *chip, int reg)
+{
+ snd_assert(chip->ops->in8, return 0);
+ return chip->ops->in8(chip, reg);
+}
+
+inline static unsigned int snd_vx_inl(vx_core_t *chip, int reg)
+{
+ snd_assert(chip->ops->in32, return 0);
+ return chip->ops->in32(chip, reg);
+}
+
+inline static void snd_vx_outb(vx_core_t *chip, int reg, unsigned char val)
+{
+ snd_assert(chip->ops->out8, return);
+ chip->ops->out8(chip, reg, val);
+}
+
+inline static void snd_vx_outl(vx_core_t *chip, int reg, unsigned int val)
+{
+ snd_assert(chip->ops->out32, return);
+ 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)
+
+void snd_vx_delay(vx_core_t *chip, int msec);
+
+static inline void vx_reset_dsp(vx_core_t *chip)
+{
+ snd_assert(chip->ops->reset_dsp, return);
+ chip->ops->reset_dsp(chip);
+}
+
+int vx_send_msg(vx_core_t *chip, struct vx_rmh *rmh);
+int vx_send_msg_nolock(vx_core_t *chip, struct vx_rmh *rmh);
+int vx_send_rih(vx_core_t *chip, int cmd);
+int vx_send_rih_nolock(vx_core_t *chip, int cmd);
+
+void vx_reset_codec(vx_core_t *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(vx_core_t *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
+ */
+inline static void vx_pseudo_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
+ vx_pipe_t *pipe, int count)
+{
+ snd_assert(chip->ops->dma_write, return);
+ chip->ops->dma_write(chip, runtime, pipe, count);
+}
+
+inline static void vx_pseudo_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
+ vx_pipe_t *pipe, int count)
+{
+ snd_assert(chip->ops->dma_read, return);
+ 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(vx_core_t *chip);
+void vx_pcm_update_intr(vx_core_t *chip, unsigned int events);
+
+/*
+ * mixer stuff
+ */
+int snd_vx_mixer_new(vx_core_t *chip);
+void vx_toggle_dac_mute(vx_core_t *chip, int mute);
+int vx_sync_audio_source(vx_core_t *chip);
+int vx_set_monitor_level(vx_core_t *chip, int audio, int level, int active);
+
+/*
+ * IEC958 & clock stuff
+ */
+void vx_set_iec958_status(vx_core_t *chip, unsigned int bits);
+int vx_set_clock(vx_core_t *chip, unsigned int freq);
+void vx_set_internal_clock(vx_core_t *chip, unsigned int freq);
+int vx_change_frequency(vx_core_t *chip);
+
+
+/*
+ * 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..9e572ae
--- /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 __attribute__ ((packed));
+
+ struct wf_sample_offset sampleStartOffset __attribute__ ((packed));
+ struct wf_sample_offset loopStartOffset __attribute__ ((packed));
+ struct wf_sample_offset sampleEndOffset __attribute__ ((packed));
+ struct wf_sample_offset loopEndOffset __attribute__ ((packed));
+
+ s16 FrequencyBias __attribute__ ((packed));
+
+ u8 SampleResolution:2 __attribute__ ((packed));
+ u8 Unused1:1 __attribute__ ((packed));
+ u8 Loop:1 __attribute__ ((packed));
+ u8 Bidirectional:1 __attribute__ ((packed));
+ u8 Unused2:1 __attribute__ ((packed));
+ u8 Reverse:1 __attribute__ ((packed));
+ u8 Unused3:1 __attribute__ ((packed));
+
+ /* 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/wavefront_fx.h b/include/sound/wavefront_fx.h
new file mode 100644
index 0000000..cec92b1
--- /dev/null
+++ b/include/sound/wavefront_fx.h
@@ -0,0 +1,9 @@
+#ifndef __SOUND_WAVEFRONT_FX_H
+#define __SOUND_WAVEFRONT_FX_H
+
+extern int snd_wavefront_fx_detect (snd_wavefront_t *);
+extern void snd_wavefront_fx_ioctl (snd_synth_t *sdev,
+ unsigned int cmd,
+ unsigned long arg);
+
+#endif __SOUND_WAVEFRONT_FX_H
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
new file mode 100644
index 0000000..4b57068
--- /dev/null
+++ b/include/sound/ymfpci.h
@@ -0,0 +1,396 @@
+#ifndef __SOUND_YMFPCI_H
+#define __SOUND_YMFPCI_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Definitions for Yahama YMF724/740/744/754 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 "pcm.h"
+#include "rawmidi.h"
+#include "ac97_codec.h"
+#include "timer.h"
+#include <linux/gameport.h>
+
+#ifndef PCI_VENDOR_ID_YAMAHA
+#define PCI_VENDOR_ID_YAMAHA 0x1073
+#endif
+#ifndef PCI_DEVICE_ID_YAMAHA_724
+#define PCI_DEVICE_ID_YAMAHA_724 0x0004
+#endif
+#ifndef PCI_DEVICE_ID_YAMAHA_724F
+#define PCI_DEVICE_ID_YAMAHA_724F 0x000d
+#endif
+#ifndef PCI_DEVICE_ID_YAMAHA_740
+#define PCI_DEVICE_ID_YAMAHA_740 0x000a
+#endif
+#ifndef PCI_DEVICE_ID_YAMAHA_740C
+#define PCI_DEVICE_ID_YAMAHA_740C 0x000c
+#endif
+#ifndef PCI_DEVICE_ID_YAMAHA_744
+#define PCI_DEVICE_ID_YAMAHA_744 0x0010
+#endif
+#ifndef PCI_DEVICE_ID_YAMAHA_754
+#define PCI_DEVICE_ID_YAMAHA_754 0x0012
+#endif
+
+/*
+ * Direct registers
+ */
+
+#define YMFREG(chip, reg) (chip->port + YDSXGR_##reg)
+
+#define YDSXGR_INTFLAG 0x0004
+#define YDSXGR_ACTIVITY 0x0006
+#define YDSXGR_GLOBALCTRL 0x0008
+#define YDSXGR_ZVCTRL 0x000A
+#define YDSXGR_TIMERCTRL 0x0010
+#define YDSXGR_TIMERCOUNT 0x0012
+#define YDSXGR_SPDIFOUTCTRL 0x0018
+#define YDSXGR_SPDIFOUTSTATUS 0x001C
+#define YDSXGR_EEPROMCTRL 0x0020
+#define YDSXGR_SPDIFINCTRL 0x0034
+#define YDSXGR_SPDIFINSTATUS 0x0038
+#define YDSXGR_DSPPROGRAMDL 0x0048
+#define YDSXGR_DLCNTRL 0x004C
+#define YDSXGR_GPIOININTFLAG 0x0050
+#define YDSXGR_GPIOININTENABLE 0x0052
+#define YDSXGR_GPIOINSTATUS 0x0054
+#define YDSXGR_GPIOOUTCTRL 0x0056
+#define YDSXGR_GPIOFUNCENABLE 0x0058
+#define YDSXGR_GPIOTYPECONFIG 0x005A
+#define YDSXGR_AC97CMDDATA 0x0060
+#define YDSXGR_AC97CMDADR 0x0062
+#define YDSXGR_PRISTATUSDATA 0x0064
+#define YDSXGR_PRISTATUSADR 0x0066
+#define YDSXGR_SECSTATUSDATA 0x0068
+#define YDSXGR_SECSTATUSADR 0x006A
+#define YDSXGR_SECCONFIG 0x0070
+#define YDSXGR_LEGACYOUTVOL 0x0080
+#define YDSXGR_LEGACYOUTVOLL 0x0080
+#define YDSXGR_LEGACYOUTVOLR 0x0082
+#define YDSXGR_NATIVEDACOUTVOL 0x0084
+#define YDSXGR_NATIVEDACOUTVOLL 0x0084
+#define YDSXGR_NATIVEDACOUTVOLR 0x0086
+#define YDSXGR_ZVOUTVOL 0x0088
+#define YDSXGR_ZVOUTVOLL 0x0088
+#define YDSXGR_ZVOUTVOLR 0x008A
+#define YDSXGR_SECADCOUTVOL 0x008C
+#define YDSXGR_SECADCOUTVOLL 0x008C
+#define YDSXGR_SECADCOUTVOLR 0x008E
+#define YDSXGR_PRIADCOUTVOL 0x0090
+#define YDSXGR_PRIADCOUTVOLL 0x0090
+#define YDSXGR_PRIADCOUTVOLR 0x0092
+#define YDSXGR_LEGACYLOOPVOL 0x0094
+#define YDSXGR_LEGACYLOOPVOLL 0x0094
+#define YDSXGR_LEGACYLOOPVOLR 0x0096
+#define YDSXGR_NATIVEDACLOOPVOL 0x0098
+#define YDSXGR_NATIVEDACLOOPVOLL 0x0098
+#define YDSXGR_NATIVEDACLOOPVOLR 0x009A
+#define YDSXGR_ZVLOOPVOL 0x009C
+#define YDSXGR_ZVLOOPVOLL 0x009E
+#define YDSXGR_ZVLOOPVOLR 0x009E
+#define YDSXGR_SECADCLOOPVOL 0x00A0
+#define YDSXGR_SECADCLOOPVOLL 0x00A0
+#define YDSXGR_SECADCLOOPVOLR 0x00A2
+#define YDSXGR_PRIADCLOOPVOL 0x00A4
+#define YDSXGR_PRIADCLOOPVOLL 0x00A4
+#define YDSXGR_PRIADCLOOPVOLR 0x00A6
+#define YDSXGR_NATIVEADCINVOL 0x00A8
+#define YDSXGR_NATIVEADCINVOLL 0x00A8
+#define YDSXGR_NATIVEADCINVOLR 0x00AA
+#define YDSXGR_NATIVEDACINVOL 0x00AC
+#define YDSXGR_NATIVEDACINVOLL 0x00AC
+#define YDSXGR_NATIVEDACINVOLR 0x00AE
+#define YDSXGR_BUF441OUTVOL 0x00B0
+#define YDSXGR_BUF441OUTVOLL 0x00B0
+#define YDSXGR_BUF441OUTVOLR 0x00B2
+#define YDSXGR_BUF441LOOPVOL 0x00B4
+#define YDSXGR_BUF441LOOPVOLL 0x00B4
+#define YDSXGR_BUF441LOOPVOLR 0x00B6
+#define YDSXGR_SPDIFOUTVOL 0x00B8
+#define YDSXGR_SPDIFOUTVOLL 0x00B8
+#define YDSXGR_SPDIFOUTVOLR 0x00BA
+#define YDSXGR_SPDIFLOOPVOL 0x00BC
+#define YDSXGR_SPDIFLOOPVOLL 0x00BC
+#define YDSXGR_SPDIFLOOPVOLR 0x00BE
+#define YDSXGR_ADCSLOTSR 0x00C0
+#define YDSXGR_RECSLOTSR 0x00C4
+#define YDSXGR_ADCFORMAT 0x00C8
+#define YDSXGR_RECFORMAT 0x00CC
+#define YDSXGR_P44SLOTSR 0x00D0
+#define YDSXGR_STATUS 0x0100
+#define YDSXGR_CTRLSELECT 0x0104
+#define YDSXGR_MODE 0x0108
+#define YDSXGR_SAMPLECOUNT 0x010C
+#define YDSXGR_NUMOFSAMPLES 0x0110
+#define YDSXGR_CONFIG 0x0114
+#define YDSXGR_PLAYCTRLSIZE 0x0140
+#define YDSXGR_RECCTRLSIZE 0x0144
+#define YDSXGR_EFFCTRLSIZE 0x0148
+#define YDSXGR_WORKSIZE 0x014C
+#define YDSXGR_MAPOFREC 0x0150
+#define YDSXGR_MAPOFEFFECT 0x0154
+#define YDSXGR_PLAYCTRLBASE 0x0158
+#define YDSXGR_RECCTRLBASE 0x015C
+#define YDSXGR_EFFCTRLBASE 0x0160
+#define YDSXGR_WORKBASE 0x0164
+#define YDSXGR_DSPINSTRAM 0x1000
+#define YDSXGR_CTRLINSTRAM 0x4000
+
+#define YDSXG_AC97READCMD 0x8000
+#define YDSXG_AC97WRITECMD 0x0000
+
+#define PCIR_DSXG_LEGACY 0x40
+#define PCIR_DSXG_ELEGACY 0x42
+#define PCIR_DSXG_CTRL 0x48
+#define PCIR_DSXG_PWRCTRL1 0x4a
+#define PCIR_DSXG_PWRCTRL2 0x4e
+#define PCIR_DSXG_FMBASE 0x60
+#define PCIR_DSXG_SBBASE 0x62
+#define PCIR_DSXG_MPU401BASE 0x64
+#define PCIR_DSXG_JOYBASE 0x66
+
+#define YDSXG_DSPLENGTH 0x0080
+#define YDSXG_CTRLLENGTH 0x3000
+
+#define YDSXG_DEFAULT_WORK_SIZE 0x0400
+
+#define YDSXG_PLAYBACK_VOICES 64
+#define YDSXG_CAPTURE_VOICES 2
+#define YDSXG_EFFECT_VOICES 5
+
+#define YMFPCI_LEGACY_SBEN (1 << 0) /* soundblaster enable */
+#define YMFPCI_LEGACY_FMEN (1 << 1) /* OPL3 enable */
+#define YMFPCI_LEGACY_JPEN (1 << 2) /* joystick enable */
+#define YMFPCI_LEGACY_MEN (1 << 3) /* MPU401 enable */
+#define YMFPCI_LEGACY_MIEN (1 << 4) /* MPU RX irq enable */
+#define YMFPCI_LEGACY_IOBITS (1 << 5) /* i/o bits range, 0 = 16bit, 1 =10bit */
+#define YMFPCI_LEGACY_SDMA (3 << 6) /* SB DMA select */
+#define YMFPCI_LEGACY_SBIRQ (7 << 8) /* SB IRQ select */
+#define YMFPCI_LEGACY_MPUIRQ (7 << 11) /* MPU IRQ select */
+#define YMFPCI_LEGACY_SIEN (1 << 14) /* serialized IRQ */
+#define YMFPCI_LEGACY_LAD (1 << 15) /* legacy audio disable */
+
+#define YMFPCI_LEGACY2_FMIO (3 << 0) /* OPL3 i/o address (724/740) */
+#define YMFPCI_LEGACY2_SBIO (3 << 2) /* SB i/o address (724/740) */
+#define YMFPCI_LEGACY2_MPUIO (3 << 4) /* MPU401 i/o address (724/740) */
+#define YMFPCI_LEGACY2_JSIO (3 << 6) /* joystick i/o address (724/740) */
+#define YMFPCI_LEGACY2_MAIM (1 << 8) /* MPU401 ack intr mask */
+#define YMFPCI_LEGACY2_SMOD (3 << 11) /* SB DMA mode */
+#define YMFPCI_LEGACY2_SBVER (3 << 13) /* SB version select */
+#define YMFPCI_LEGACY2_IMOD (1 << 15) /* legacy IRQ mode */
+/* SIEN:IMOD 0:0 = legacy irq, 0:1 = INTA, 1:0 = serialized IRQ */
+
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK
+#endif
+
+/*
+ *
+ */
+
+typedef struct _snd_ymfpci_playback_bank {
+ u32 format;
+ u32 loop_default;
+ u32 base; /* 32-bit address */
+ u32 loop_start; /* 32-bit offset */
+ u32 loop_end; /* 32-bit offset */
+ u32 loop_frac; /* 8-bit fraction - loop_start */
+ u32 delta_end; /* pitch delta end */
+ u32 lpfK_end;
+ u32 eg_gain_end;
+ u32 left_gain_end;
+ u32 right_gain_end;
+ u32 eff1_gain_end;
+ u32 eff2_gain_end;
+ u32 eff3_gain_end;
+ u32 lpfQ;
+ u32 status;
+ u32 num_of_frames;
+ u32 loop_count;
+ u32 start;
+ u32 start_frac;
+ u32 delta;
+ u32 lpfK;
+ u32 eg_gain;
+ u32 left_gain;
+ u32 right_gain;
+ u32 eff1_gain;
+ u32 eff2_gain;
+ u32 eff3_gain;
+ u32 lpfD1;
+ u32 lpfD2;
+} snd_ymfpci_playback_bank_t;
+
+typedef struct _snd_ymfpci_capture_bank {
+ u32 base; /* 32-bit address */
+ u32 loop_end; /* 32-bit offset */
+ u32 start; /* 32-bit offset */
+ u32 num_of_loops; /* counter */
+} snd_ymfpci_capture_bank_t;
+
+typedef struct _snd_ymfpci_effect_bank {
+ u32 base; /* 32-bit address */
+ u32 loop_end; /* 32-bit offset */
+ u32 start; /* 32-bit offset */
+ u32 temp;
+} snd_ymfpci_effect_bank_t;
+
+typedef struct _snd_ymfpci_voice ymfpci_voice_t;
+typedef struct _snd_ymfpci_pcm ymfpci_pcm_t;
+typedef struct _snd_ymfpci ymfpci_t;
+
+typedef enum {
+ YMFPCI_PCM,
+ YMFPCI_SYNTH,
+ YMFPCI_MIDI
+} ymfpci_voice_type_t;
+
+struct _snd_ymfpci_voice {
+ ymfpci_t *chip;
+ int number;
+ unsigned int use: 1,
+ pcm: 1,
+ synth: 1,
+ midi: 1;
+ snd_ymfpci_playback_bank_t *bank;
+ dma_addr_t bank_addr;
+ void (*interrupt)(ymfpci_t *chip, ymfpci_voice_t *voice);
+ ymfpci_pcm_t *ypcm;
+};
+
+typedef enum {
+ PLAYBACK_VOICE,
+ CAPTURE_REC,
+ CAPTURE_AC97,
+ EFFECT_DRY_LEFT,
+ EFFECT_DRY_RIGHT,
+ EFFECT_EFF1,
+ EFFECT_EFF2,
+ EFFECT_EFF3
+} snd_ymfpci_pcm_type_t;
+
+struct _snd_ymfpci_pcm {
+ ymfpci_t *chip;
+ snd_ymfpci_pcm_type_t type;
+ snd_pcm_substream_t *substream;
+ ymfpci_voice_t *voices[2]; /* playback only */
+ unsigned int running: 1;
+ unsigned int output_front: 1;
+ unsigned int output_rear: 1;
+ u32 period_size; /* cached from runtime->period_size */
+ u32 buffer_size; /* cached from runtime->buffer_size */
+ u32 period_pos;
+ u32 last_pos;
+ u32 capture_bank_number;
+ u32 shift;
+};
+
+struct _snd_ymfpci {
+ int irq;
+
+ unsigned int device_id; /* PCI device ID */
+ unsigned int rev; /* PCI revision */
+ unsigned long reg_area_phys;
+ void __iomem *reg_area_virt;
+ struct resource *res_reg_area;
+ struct resource *fm_res;
+ struct resource *mpu_res;
+
+ unsigned short old_legacy_ctrl;
+#ifdef SUPPORT_JOYSTICK
+ struct gameport *gameport;
+#endif
+
+ struct snd_dma_buffer work_ptr;
+
+ unsigned int bank_size_playback;
+ unsigned int bank_size_capture;
+ unsigned int bank_size_effect;
+ unsigned int work_size;
+
+ void *bank_base_playback;
+ void *bank_base_capture;
+ void *bank_base_effect;
+ void *work_base;
+ dma_addr_t bank_base_playback_addr;
+ dma_addr_t bank_base_capture_addr;
+ dma_addr_t bank_base_effect_addr;
+ dma_addr_t work_base_addr;
+ struct snd_dma_buffer ac3_tmp_base;
+
+ u32 *ctrl_playback;
+ snd_ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2];
+ snd_ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2];
+ snd_ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
+
+ int start_count;
+
+ u32 active_bank;
+ ymfpci_voice_t voices[64];
+
+ ac97_bus_t *ac97_bus;
+ ac97_t *ac97;
+ snd_rawmidi_t *rawmidi;
+ snd_timer_t *timer;
+
+ struct pci_dev *pci;
+ snd_card_t *card;
+ snd_pcm_t *pcm;
+ snd_pcm_t *pcm2;
+ snd_pcm_t *pcm_spdif;
+ snd_pcm_t *pcm_4ch;
+ snd_pcm_substream_t *capture_substream[YDSXG_CAPTURE_VOICES];
+ snd_pcm_substream_t *effect_substream[YDSXG_EFFECT_VOICES];
+ snd_kcontrol_t *ctl_vol_recsrc;
+ snd_kcontrol_t *ctl_vol_adcrec;
+ snd_kcontrol_t *ctl_vol_spdifrec;
+ unsigned short spdif_bits, spdif_pcm_bits;
+ snd_kcontrol_t *spdif_pcm_ctl;
+ int mode_dup4ch;
+ int rear_opened;
+ int spdif_opened;
+
+ spinlock_t reg_lock;
+ spinlock_t voice_lock;
+ wait_queue_head_t interrupt_sleep;
+ atomic_t interrupt_sleep_count;
+ snd_info_entry_t *proc_entry;
+
+#ifdef CONFIG_PM
+ u32 *saved_regs;
+ u32 saved_ydsxgr_mode;
+#endif
+};
+
+int snd_ymfpci_create(snd_card_t * card,
+ struct pci_dev *pci,
+ unsigned short old_legacy_ctrl,
+ ymfpci_t ** rcodec);
+void snd_ymfpci_free_gameport(ymfpci_t *chip);
+
+int snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
+int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
+int snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
+int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
+int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch);
+int snd_ymfpci_timer(ymfpci_t *chip, int device);
+
+#endif /* __SOUND_YMFPCI_H */
OpenPOWER on IntegriCloud