linux/include/sound/emu10k1.h

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *  Copyright (c) by Jaroslav Kysela <[email protected]>,
 *		     Creative Labs, Inc.
 *  Definitions for EMU10K1 (SB Live!) chips
 */
#ifndef __SOUND_EMU10K1_H
#define __SOUND_EMU10K1_H


#include <sound/pcm.h>
#include <sound/rawmidi.h>
#include <sound/hwdep.h>
#include <sound/ac97_codec.h>
#include <sound/util_mem.h>
#include <sound/pcm-indirect.h>
#include <sound/timer.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/firmware.h>
#include <linux/io.h>

#include <uapi/sound/emu10k1.h>

/* ------------------- DEFINES -------------------- */

#define EMUPAGESIZE
#define MAXPAGES0
#define MAXPAGES1
#define NUM_G
#define NUM_EFX_PLAYBACK

/* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
#define EMU10K1_DMA_MASK
#define AUDIGY_DMA_MASK

#define TMEMSIZE

#define IP_TO_CP(ip)

// This is used to define hardware bit-fields (sub-registers) by combining
// the bit shift and count with the actual register address. The passed
// mask must represent a single run of adjacent bits.
// The non-concatenating (_NC) variant should be used directly only for
// sub-registers that do not follow the <register>_<field> naming pattern.
#define SUB_REG_NC(reg, field, mask)
#define SUB_REG(reg, field, mask)

// Macros for manipulating values of bit-fields declared using the above macros.
// Best used with constant register addresses, as otherwise quite some code is
// generated. The actual register read/write functions handle combined addresses
// automatically, so use of these macros conveys no advantage when accessing a
// single sub-register at a time.
#define REG_SHIFT(r)
#define REG_SIZE(r)
#define REG_MASK0(r)
#define REG_MASK(r)
#define REG_VAL_GET(r, v)
#define REG_VAL_PUT(r, v)

// List terminator for snd_emu10k1_ptr_write_multiple()
#define REGLIST_END

// Audigy specify registers are prefixed with 'A_'

/************************************************************************************************/
/* PCI function 0 registers, address = <val> + PCIBASE0						*/
/************************************************************************************************/

#define PTR
						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
						/* be modified independently of each other.	*/
#define PTR_CHANNELNUM_MASK
						/* channel number of the register to be		*/
						/* accessed.  For non per-channel registers the	*/
						/* value should be set to zero.			*/
#define PTR_ADDRESS_MASK
#define A_PTR_ADDRESS_MASK

#define DATA

#define IPR
						/* Clear pending interrupts by writing a 1 to	*/
						/* the relevant bits and zero to the other bits	*/
#define IPR_P16V
#define IPR_WATERMARK_REACHED
#define IPR_A_GPIO

/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
#define IPR_A_MIDITRANSBUFEMPTY2
#define IPR_A_MIDIRECVBUFEMPTY2

#define IPR_SPDIFBUFFULL
#define IPR_SPDIFBUFHALFFULL

#define IPR_SAMPLERATETRACKER
#define IPR_FXDSP
#define IPR_FORCEINT
#define IPR_PCIERROR
#define IPR_VOLINCR
#define IPR_VOLDECR
#define IPR_MUTE
#define IPR_MICBUFFULL
#define IPR_MICBUFHALFFULL
#define IPR_ADCBUFFULL
#define IPR_ADCBUFHALFFULL
#define IPR_EFXBUFFULL
#define IPR_EFXBUFHALFFULL
#define IPR_GPSPDIFSTATUSCHANGE
#define IPR_CDROMSTATUSCHANGE
#define IPR_INTERVALTIMER
#define IPR_MIDITRANSBUFEMPTY
#define IPR_MIDIRECVBUFEMPTY
#define IPR_CHANNELLOOP
						/* The interrupt is triggered shortly after	*/
						/* CCR_READADDRESS has crossed the boundary;	*/
						/* due to the cache, this runs ahead of the	*/
						/* actual playback position.			*/
#define IPR_CHANNELNUMBERMASK
						/* highest set channel in CLIPL, CLIPH, HLIPL,  */
						/* or HLIPH.  When IPR is written with CL set,	*/
						/* the bit in H/CLIPL or H/CLIPH corresponding	*/
						/* to the CN value written will be cleared.	*/

#define INTE
#define INTE_VIRTUALSB_MASK
#define INTE_VIRTUALSB_220
#define INTE_VIRTUALSB_240
#define INTE_VIRTUALSB_260
#define INTE_VIRTUALSB_280
#define INTE_VIRTUALMPU_MASK
#define INTE_VIRTUALMPU_300
#define INTE_VIRTUALMPU_310
#define INTE_VIRTUALMPU_320
#define INTE_VIRTUALMPU_330
#define INTE_MASTERDMAENABLE
#define INTE_SLAVEDMAENABLE
#define INTE_MASTERPICENABLE
#define INTE_SLAVEPICENABLE
#define INTE_VSBENABLE
#define INTE_ADLIBENABLE
#define INTE_MPUENABLE
#define INTE_FORCEINT

#define INTE_MRHANDENABLE
						/* 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.				*/

#define INTE_A_GPIOENABLE

/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)			*/
#define INTE_A_MIDITXENABLE2
#define INTE_A_MIDIRXENABLE2

#define INTE_A_SPDIF_BUFFULL_ENABLE
#define INTE_A_SPDIF_HALFBUFFULL_ENABLE

#define INTE_SAMPLERATETRACKER
						/* NOTE: This bit must always be enabled       	*/
#define INTE_FXDSPENABLE
#define INTE_PCIERRORENABLE
#define INTE_VOLINCRENABLE
#define INTE_VOLDECRENABLE
#define INTE_MUTEENABLE
#define INTE_MICBUFENABLE
#define INTE_ADCBUFENABLE
#define INTE_EFXBUFENABLE
#define INTE_GPSPDIFENABLE
#define INTE_CDSPDIFENABLE
#define INTE_INTERVALTIMERENB
#define INTE_MIDITXENABLE
#define INTE_MIDIRXENABLE

#define WC
SUB_REG()	/* Sample periods elapsed since reset		*/
SUB_REG()	/* Channel [0..63] currently being serviced	*/
						/* NOTE: Each channel takes 1/64th of a sample	*/
						/* period to be serviced.			*/

#define HCFG
						/* 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
#define HCFG_LEGACYFUNC_MPU
#define HCFG_LEGACYFUNC_SB
#define HCFG_LEGACYFUNC_AD
#define HCFG_LEGACYFUNC_MPIC
#define HCFG_LEGACYFUNC_MDMA
#define HCFG_LEGACYFUNC_SPCI
#define HCFG_LEGACYFUNC_SDMA
#define HCFG_IOCAPTUREADDR
#define HCFG_LEGACYWRITE
#define HCFG_LEGACYWORD
#define HCFG_LEGACYINT
						/* NOTE: The rest of the bits in this register	*/
						/* _are_ relevant under Linux.			*/
#define HCFG_PUSH_BUTTON_ENABLE
#define HCFG_BAUD_RATE
#define HCFG_EXPANDED_MEM
#define HCFG_CODECFORMAT_MASK

/* Specific to Alice2, CA0102 */

#define HCFG_CODECFORMAT_AC97_1
#define HCFG_CODECFORMAT_AC97_2
#define HCFG_AUTOMUTE_ASYNC
						/* will automatically mute their output when	*/
						/* they are not rate-locked to the external	*/
						/* async audio source  				*/
#define HCFG_AUTOMUTE_SPDIF
						/* will automatically mute their output when	*/
						/* the SPDIF V-bit indicates invalid audio	*/
#define HCFG_EMU32_SLAVE
#define HCFG_SLOW_RAMP
/* 0x00000800 not used on Alice2 */
#define HCFG_PHASE_TRACK_MASK
						/* phase track the previous input.		*/
						/* I2S0 can phase track the last S/PDIF input	*/
#define HCFG_I2S_ASRC_ENABLE
						/* conversion for the corresponding		*/
 						/* I2S format input				*/
/* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc.  */

/* Older chips */

#define HCFG_CODECFORMAT_AC97
#define HCFG_CODECFORMAT_I2S
#define HCFG_GPINPUT0
#define HCFG_GPINPUT1
#define HCFG_GPOUTPUT_MASK
#define HCFG_GPOUT0
#define HCFG_GPOUT1
#define HCFG_GPOUT2
#define HCFG_JOYENABLE
#define HCFG_PHASETRACKENABLE
						/* 1 = Force all 3 async digital inputs to use	*/
						/* the same async sample rate tracker (ZVIDEO)	*/
#define HCFG_AC3ENABLE_MASK
#define HCFG_AC3ENABLE_ZVIDEO
#define HCFG_AC3ENABLE_CDSPDIF
#define HCFG_AC3ENABLE_GPSPDIF
#define HCFG_AUTOMUTE
						/* will automatically mute their output when	*/
						/* they are not rate-locked to the external	*/
						/* async audio source  				*/
#define HCFG_LOCKSOUNDCACHE
						/* NOTE: This should generally never be used.  	*/
SUB_REG()	/* 1 = Cancel bustmaster accesses to tankcache	*/
						/* NOTE: This should generally never be used.  	*/
#define HCFG_MUTEBUTTONENABLE
						/* 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
						/* Should be set to 1 when the EMU10K1 is	*/
						/* completely initialized.			*/

// On Audigy, the MPU port moved to the 0x70-0x74 ptr registers

#define MUDATA

#define MUCMD
#define MUCMD_RESET
#define MUCMD_ENTERUARTMODE
						/* NOTE: All other commands are ignored		*/

#define MUSTAT
#define MUSTAT_IRDYN
#define MUSTAT_ORDYN

#define A_GPIO
#define A_GPINPUT_MASK
#define A3_GPINPUT_MASK
#define A_GPOUTPUT_MASK

// The GPIO port is used for I/O config on Sound Blasters;
// card-specific info can be found in the emu_chip_details table.
// On E-MU cards the port is used as the interface to the FPGA.

// Audigy output/GPIO stuff taken from the kX drivers
#define A_IOCFG
#define A_IOCFG_GPOUT0
#define A_IOCFG_DISABLE_ANALOG
#define A_IOCFG_ENABLE_DIGITAL
#define A_IOCFG_ENABLE_DIGITAL_AUDIGY4
#define A_IOCFG_UNKNOWN_20
#define A_IOCFG_DISABLE_AC97_FRONT
#define A_IOCFG_GPOUT1
#define A_IOCFG_GPOUT2
#define A_IOCFG_MULTIPURPOSE_JACK
                                                /* + digital for generic 10k2			*/
#define A_IOCFG_DIGITAL_JACK
#define A_IOCFG_FRONT_JACK
#define A_IOCFG_REAR_JACK
#define A_IOCFG_PHONES_JACK

#define TIMER
						/* 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
						/* 0 == 1024 periods, [1..4] are not useful	*/

#define AC97DATA

#define AC97ADDRESS
#define AC97ADDRESS_READY
#define AC97ADDRESS_ADDRESS

/* Available on the Audigy 2 and Audigy 4 only. This is the P16V chip. */
#define PTR2
#define DATA2
#define IPR2
#define IPR2_PLAYBACK_CH_0_LOOP
#define IPR2_PLAYBACK_CH_0_HALF_LOOP
#define IPR2_CAPTURE_CH_0_LOOP
#define IPR2_CAPTURE_CH_0_HALF_LOOP
						/* 0x00000100 Playback. Only in once per period.
						 * 0x00110000 Capture. Int on half buffer.
						 */
#define INTE2
#define INTE2_PLAYBACK_CH_0_LOOP
#define INTE2_PLAYBACK_CH_0_HALF_LOOP
#define INTE2_PLAYBACK_CH_1_LOOP
#define INTE2_PLAYBACK_CH_1_HALF_LOOP
#define INTE2_PLAYBACK_CH_2_LOOP
#define INTE2_PLAYBACK_CH_2_HALF_LOOP
#define INTE2_PLAYBACK_CH_3_LOOP
#define INTE2_PLAYBACK_CH_3_HALF_LOOP
#define INTE2_CAPTURE_CH_0_LOOP
#define INTE2_CAPTURE_CH_0_HALF_LOOP
#define HCFG2
						/* 0x00000000 2-channel output. */
						/* 0x00000200 8-channel output. */
						/* 0x00000004 pauses stream/irq fail. */
						/* Rest of bits do 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
#define INTE3

/************************************************************************************************/
/* PCI function 1 registers, address = <val> + PCIBASE1						*/
/************************************************************************************************/

#define JOYSTICK1
#define JOYSTICK2
#define JOYSTICK3
#define JOYSTICK4
#define JOYSTICK5
#define JOYSTICK6
#define JOYSTICK7
#define JOYSTICK8

/* When writing, any write causes JOYSTICK_COMPARATOR output enable to be pulsed on write.	*/
/* When reading, use these bitfields: */
#define JOYSTICK_BUTTONS
#define JOYSTICK_COMPARATOR

/********************************************************************************************************/
/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
/********************************************************************************************************/

// No official documentation was released for EMU10K1, but some info
// about playback can be extrapolated from the EMU8K documents:
// "AWE32/EMU8000 Programmer’s Guide" (emu8kpgm.pdf) - registers
// "AWE32 Developer's Information Pack" (adip301.pdf) - high-level view

// The short version:
// - The engine has 64 playback channels, also called voices. The channels
//   operate independently, except when paired for stereo (see below).
// - PCM samples are fetched into the cache; see description of CD0 below.
// - Samples are consumed at the rate CPF_CURRENTPITCH.
// - 8-bit samples are transformed upon use: cooked = (raw ^ 0x80) << 8
// - 8 samples are read at CCR_READADDRESS:CPF_FRACADDRESS and interpolated
//   according to CCCA_INTERPROM_*. With CCCA_INTERPROM_0 selected and a zero
//   CPF_FRACADDRESS, this results in CCR_READADDRESS[3] being used verbatim.
// - The value is multiplied by CVCF_CURRENTVOL.
// - The value goes through a filter with cutoff CVCF_CURRENTFILTER;
//   delay stages Z1 and Z2.
// - The value is added by so-called `sends` to 4 (EMU10K1) / 8 (EMU10K2)
//   of the 16 (EMU10K1) / 64 (EMU10K2) FX bus accumulators via FXRT*,
//   multiplied by a per-send amount (*_FXSENDAMOUNT_*).
//   The scaling of the send amounts is exponential-ish.
// - The DSP has a go at FXBUS* and outputs the values to EXTOUT* or EMU32OUT*.
// - The pitch, volume, and filter cutoff can be modulated by two envelope
//   engines and two low frequency oscillators.
// - To avoid abrupt changes to the parameters (which may cause audible
//   distortion), the modulation engine sets the target registers, towards
//   which the current registers "swerve" gradually.

// For the odd channel in a stereo pair, these registers are meaningless:
//   CPF_STEREO, CPF_CURRENTPITCH, PTRX_PITCHTARGET, CCR_CACHEINVALIDSIZE,
//   PSST_LOOPSTARTADDR, DSL_LOOPENDADDR, CCCA_CURRADDR
// The somewhat non-obviously still meaningful ones are:
//   CPF_STOP, CPF_FRACADDRESS, CCR_READADDRESS (!),
//   CCCA_INTERPROM, CCCA_8BITSELECT (!)
// (The envelope engine is ignored here, as stereo matters only for verbatim playback.)

#define CPF
SUB_REG()	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
#define CPF_STEREO_MASK
SUB_REG()	/* 1 = Current pitch forced to 0			*/
						/* Can be set only while matching bit in SOLEx is 1	*/
#define CPF_FRACADDRESS_MASK

#define PTRX
SUB_REG()	/* Pitch target of specified channel			*/
SUB_REG()	/* Linear level of channel output sent to FX send bus A	*/
SUB_REG()	/* Linear level of channel output sent to FX send bus B	*/

// Note: the volumes are raw multpliers, so real 100% is impossible.
#define CVCF
SUB_REG()	/* Current linear volume of specified channel		*/
SUB_REG()	/* Current filter cutoff frequency of specified channel	*/

#define VTFT
SUB_REG()	/* Volume target of specified channel			*/
SUB_REG()	/* Filter cutoff target of specified channel		*/

#define Z1

#define Z2

#define PSST
SUB_REG()	/* Linear level of channel output sent to FX send bus C	*/
SUB_REG()	/* Loop start address of the specified channel		*/

#define DSL
SUB_REG()	/* Linear level of channel output sent to FX send bus D	*/
SUB_REG()	/* Loop end address of the specified channel		*/

#define CCCA
SUB_REG()	/* Lowpass filter resonance (Q) height			*/
#define CCCA_INTERPROM_MASK
						/* 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
#define CCCA_INTERPROM_1
#define CCCA_INTERPROM_2
#define CCCA_INTERPROM_3
#define CCCA_INTERPROM_4
#define CCCA_INTERPROM_5
#define CCCA_INTERPROM_6
#define CCCA_INTERPROM_7
#define CCCA_8BITSELECT
						/* 8-bit samples are unsigned, 16-bit ones signed	*/
SUB_REG()	/* Current address of the selected channel		*/

#define CCR
SUB_REG()	/* Number of invalid samples before the read address	*/
#define CCR_CACHELOOPFLAG
#define CCR_INTERLEAVEDSAMPLES
						/* Auto-set from CPF_STEREO_MASK			*/
#define CCR_WORDSIZEDSAMPLES
						/* Auto-set from CCCA_8BITSELECT			*/
SUB_REG()	/* Next cached sample to play				*/
SUB_REG()	/* Number of invalid samples in cache prior to loop	*/
						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
#define CCR_LOOPFLAG
SUB_REG()	/* CLP_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/

#define CLP
						/* NOTE: This register is normally not used		*/
SUB_REG()	/* Cache loop address low word				*/

#define FXRT
						/* NOTE: It is illegal to assign the same routing to	*/
						/* two effects sends.					*/
#define FXRT_CHANNELA
#define FXRT_CHANNELB
#define FXRT_CHANNELC
#define FXRT_CHANNELD

#define MAPA
#define MAPB

#define MAP_PTE_MASK0
#define MAP_PTI_MASK0

#define MAP_PTE_MASK1
#define MAP_PTI_MASK1

/* 0x0e, 0x0f: Internal state, at least on Audigy */

#define ENVVOL
#define ENVVOL_MASK  
						/* 0x8000-n == 666*n usec delay	       			*/

#define ATKHLDV
#define ATKHLDV_PHASE0_MASK
#define ATKHLDV_HOLDTIME_MASK
#define ATKHLDV_ATTACKTIME_MASK
						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/

#define DCYSUSV
#define DCYSUSV_PHASE1_MASK
#define DCYSUSV_SUSTAINLEVEL_MASK
#define DCYSUSV_CHANNELENABLE_MASK
						/* this channel and from writing to pitch, filter and	*/
						/* volume targets.					*/
#define DCYSUSV_DECAYTIME_MASK
						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/

#define LFOVAL1
#define LFOVAL_MASK
						/* 0x8000-n == 666*n usec delay				*/

#define ENVVAL
#define ENVVAL_MASK
						/* 0x8000-n == 666*n usec delay				*/

#define ATKHLDM
#define ATKHLDM_PHASE0_MASK
#define ATKHLDM_HOLDTIME
#define ATKHLDM_ATTACKTIME
						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/

#define DCYSUSM
#define DCYSUSM_PHASE1_MASK
#define DCYSUSM_SUSTAINLEVEL_MASK
#define DCYSUSM_DECAYTIME_MASK
						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/

#define LFOVAL2
#define LFOVAL2_MASK
						/* 0x8000-n == 666*n usec delay				*/

#define IP
#define IP_MASK
						/* 4 bits of octave, 12 bits of fractional octave	*/
#define IP_UNITY

#define IFATN
SUB_REG()	/* Initial filter cutoff frequency in exponential units	*/
						/* 6 most significant bits are semitones		*/
						/* 2 least significant bits are fractions		*/
SUB_REG()	/* Initial attenuation in 0.375dB steps			*/

#define PEFE
SUB_REG()	/* Pitch envlope amount					*/
						/* Signed 2's complement, +/- one octave peak extremes	*/
SUB_REG()	/* Filter envlope amount				*/
						/* Signed 2's complement, +/- six octaves peak extremes */


#define FMMOD
#define FMMOD_MODVIBRATO
						/* Signed 2's complement, +/- one octave extremes	*/
#define FMMOD_MOFILTER
						/* Signed 2's complement, +/- three octave extremes	*/

#define TREMFRQ
#define TREMFRQ_DEPTH
						/* Signed 2's complement, with +/- 12dB extremes	*/
#define TREMFRQ_FREQUENCY
						/* ??Hz steps, maximum of ?? Hz.			*/

#define FM2FRQ2
#define FM2FRQ2_DEPTH
						/* Signed 2's complement, +/- one octave extremes	*/
#define FM2FRQ2_FREQUENCY
						/* 0.039Hz steps, maximum of 9.85 Hz.			*/

#define TEMPENV
#define TEMPENV_MASK
						/* NOTE: All channels contain internal variables; do	*/
						/* not write to these locations.			*/

/* 0x1f: not used */

// 32 cache registers (== 128 bytes) per channel follow.
// In stereo mode, the two channels' caches are concatenated into one,
// and hold the interleaved frames.
// The cache holds 64 frames, so the upper half is not used in 8-bit mode.
// All registers mentioned below count in frames. Shortcuts:
//   CA = CCCA_CURRADDR, CRA = CCR_READADDRESS,
//   CLA = CCR_CACHELOOPADDRHI:CLP_CACHELOOPADDR,
//   CIS = CCR_CACHEINVALIDSIZE, LIS = CCR_LOOPINVALSIZE,
//   CLF = CCR_CACHELOOPFLAG, LF = CCR_LOOPFLAG
// The cache is a ring buffer; CRA operates modulo 64.
// The cache is filled from (CA - CIS) into (CRA - CIS).
// The engine has a fetch threshold of 32 bytes, so it tries to keep
// CIS below 8 (16-bit stereo), 16 (16-bit mono, 8-bit stereo), or
// 32 (8-bit mono). The actual transfers are pretty unpredictable,
// especially if several voices are running.
// Frames are consumed at CRA, which is incremented afterwards,
// along with CA and CIS. This implies that the actual playback
// position always lags CA by exactly 64 frames.
// When CA reaches DSL_LOOPENDADDR, LF is set for one frame's time.
// LF's rising edge causes the current values of CA and CIS to be
// copied into CLA and LIS, resp., and CLF to be set.
// If CLF is set, the first LIS of the CIS frames are instead
// filled from (CLA - LIS), and CLF is subsequently reset.
#define CD0

#define PTB
#define PTB_MASK

#define TCB
#define TCB_MASK

#define ADCCR
#define ADCCR_RCHANENABLE
#define ADCCR_LCHANENABLE
						/* NOTE: To guarantee phase coherency, both channels	*/
						/* must be disabled prior to enabling both channels.	*/
#define A_ADCCR_RCHANENABLE
#define A_ADCCR_LCHANENABLE

#define A_ADCCR_SAMPLERATE_MASK
#define ADCCR_SAMPLERATE_MASK
#define ADCCR_SAMPLERATE_48
#define ADCCR_SAMPLERATE_44
#define ADCCR_SAMPLERATE_32
#define ADCCR_SAMPLERATE_24
#define ADCCR_SAMPLERATE_22
#define ADCCR_SAMPLERATE_16
#define ADCCR_SAMPLERATE_11
#define ADCCR_SAMPLERATE_8
#define A_ADCCR_SAMPLERATE_12
#define A_ADCCR_SAMPLERATE_11
#define A_ADCCR_SAMPLERATE_8

#define FXWC
						/* 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 A_TBLSZ

#define TCBS
#define TCBS_MASK
#define TCBS_BUFFSIZE_16K
#define TCBS_BUFFSIZE_32K
#define TCBS_BUFFSIZE_64K
#define TCBS_BUFFSIZE_128K
#define TCBS_BUFFSIZE_256K
#define TCBS_BUFFSIZE_512K
#define TCBS_BUFFSIZE_1024K
#define TCBS_BUFFSIZE_2048K

#define MICBA
#define MICBA_MASK

#define ADCBA
#define ADCBA_MASK

#define FXBA
#define FXBA_MASK

#define A_HWM

#define MICBS

#define ADCBS

#define FXBS

/* The following mask values define the size of the ADC, MIC and FX buffers in bytes */
#define ADCBS_BUFSIZE_NONE
#define ADCBS_BUFSIZE_384
#define ADCBS_BUFSIZE_448
#define ADCBS_BUFSIZE_512
#define ADCBS_BUFSIZE_640
#define ADCBS_BUFSIZE_768
#define ADCBS_BUFSIZE_896
#define ADCBS_BUFSIZE_1024
#define ADCBS_BUFSIZE_1280
#define ADCBS_BUFSIZE_1536
#define ADCBS_BUFSIZE_1792
#define ADCBS_BUFSIZE_2048
#define ADCBS_BUFSIZE_2560
#define ADCBS_BUFSIZE_3072
#define ADCBS_BUFSIZE_3584
#define ADCBS_BUFSIZE_4096
#define ADCBS_BUFSIZE_5120
#define ADCBS_BUFSIZE_6144
#define ADCBS_BUFSIZE_7168
#define ADCBS_BUFSIZE_8192
#define ADCBS_BUFSIZE_10240
#define ADCBS_BUFSIZE_12288
#define ADCBS_BUFSIZE_14366
#define ADCBS_BUFSIZE_16384
#define ADCBS_BUFSIZE_20480
#define ADCBS_BUFSIZE_24576
#define ADCBS_BUFSIZE_28672
#define ADCBS_BUFSIZE_32768
#define ADCBS_BUFSIZE_40960
#define ADCBS_BUFSIZE_49152
#define ADCBS_BUFSIZE_57344
#define ADCBS_BUFSIZE_65536

// On Audigy, the FX send amounts are not applied instantly, but determine
// targets towards which the following registers swerve gradually.
#define A_CSBA
#define A_CSDC
#define A_CSFE
#define A_CSHG

// NOTE: 0x50,51,52: 64-bit (split over voices 0 & 1)
#define CDCS

#define GPSCS

// Corresponding EMU10K1_DBG_* constants are in the public header
#define DBG

#define A_SPSC

#define REG53

// Corresponding A_DBG_* constants are in the public header
#define A_DBG

// NOTE: 0x54,55,56: 64-bit (split over voices 0 & 1)
#define SPCS0

#define SPCS1

#define SPCS2

#define SPCS_CLKACCYMASK
#define SPCS_CLKACCY_1000PPM
#define SPCS_CLKACCY_50PPM
#define SPCS_CLKACCY_VARIABLE
#define SPCS_SAMPLERATEMASK
#define SPCS_SAMPLERATE_44
#define SPCS_SAMPLERATE_48
#define SPCS_SAMPLERATE_32
#define SPCS_CHANNELNUMMASK
#define SPCS_CHANNELNUM_UNSPEC
#define SPCS_CHANNELNUM_LEFT
#define SPCS_CHANNELNUM_RIGHT
#define SPCS_SOURCENUMMASK
#define SPCS_SOURCENUM_UNSPEC
#define SPCS_GENERATIONSTATUS
#define SPCS_CATEGORYCODEMASK
#define SPCS_MODEMASK
#define SPCS_EMPHASISMASK
#define SPCS_EMPHASIS_NONE
#define SPCS_EMPHASIS_50_15
#define SPCS_COPYRIGHT
#define SPCS_NOTAUDIODATA
#define SPCS_PROFESSIONAL

/* 0x57: Not used */

/* The 32-bit CLIx and SOLEx registers all have one bit per channel control/status      	*/
#define CLIEL
#define CLIEH

#define CLIPL
#define CLIPH

// These cause CPF_STOP_MASK to be set shortly after CCCA_CURRADDR passes DSL_LOOPENDADDR.
// Subsequent changes to the address registers don't resume; clearing the bit here or in CPF does.
// The registers are NOT synchronized; the next serviced channel picks up immediately.
#define SOLEL
#define SOLEH

#define SPBYPASS
#define SPBYPASS_SPDIF0_MASK
#define SPBYPASS_SPDIF1_MASK
/* bypass mode: 0 - DSP; 1 - SPDIF A, 2 - SPDIF B, 3 - SPDIF C					*/
#define SPBYPASS_FORMAT

#define AC97SLOT
#define AC97SLOT_REAR_RIGHT
#define AC97SLOT_REAR_LEFT
#define AC97SLOT_CNTR
#define AC97SLOT_LFE

#define A_PCB

// NOTE: 0x60,61,62: 64-bit
#define CDSRCS

#define GPSRCS

#define ZVSRCS
						/* NOTE: This one has no SPDIFLOCKED field	*/
						/* Assumes sample lock				*/

/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
#define SRCS_SPDIFVALID
#define SRCS_SPDIFLOCKED
#define SRCS_RATELOCKED
#define SRCS_ESTSAMPLERATE

/* Note that these values can vary +/- by a small amount                                        */
#define SRCS_SPDIFRATE_44
#define SRCS_SPDIFRATE_48
#define SRCS_SPDIFRATE_96

#define MICIDX
SUB_REG()

#define ADCIDX
SUB_REG()

#define A_ADCIDX
SUB_REG()

#define A_MICIDX
SUB_REG()

#define FXIDX
SUB_REG()

/* The 32-bit HLIEx and HLIPx registers all have one bit per channel control/status      		*/
#define HLIEL
#define HLIEH

#define HLIPL
#define HLIPH

#define A_SPRI
#define A_SPRA
#define A_SPRC

#define A_DICE

#define A_TTB
#define A_TDOF

/* This is the MPU port on the card (via the game port)						*/
#define A_MUDATA1
#define A_MUCMD1
#define A_MUSTAT1

/* This is the MPU port on the Audigy Drive 							*/
#define A_MUDATA2
#define A_MUCMD2
#define A_MUSTAT2	

/* The next two are the Audigy equivalent of FXWC						*/
/* the Audigy can record any output (16bit, 48kHz, up to 64 channels simultaneously) 		*/
/* Each bit selects a channel for recording */
#define A_FXWC1
#define A_FXWC2

#define A_EHC

#define A_SPDIF_SAMPLERATE
#define A_SPDIF_RATE_MASK
#define A_SPDIF_48000
#define A_SPDIF_192000
#define A_SPDIF_96000
#define A_SPDIF_44100
#define A_SPDIF_MUTED

SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00)  /* This sets the capture PCM rate, but it is  */
						   /* unclear if this sets the ADC rate as well. */
#define A_I2S_CAPTURE_48000
#define A_I2S_CAPTURE_192000
#define A_I2S_CAPTURE_96000
#define A_I2S_CAPTURE_44100

#define A_EHC_SRC48_MASK
#define A_EHC_SRC48_BYPASS
#define A_EHC_SRC48_192
#define A_EHC_SRC48_96
#define A_EHC_SRC48_44
#define A_EHC_SRC48_MUTED

#define A_EHC_P17V_TVM
#define A_EHC_P17V_SEL0_MASK
#define A_EHC_P17V_SEL1_MASK
#define A_EHC_P17V_SEL2_MASK
#define A_EHC_P17V_SEL3_MASK

#define A_EHC_ASYNC_BYPASS

#define A_SRT3
#define A_SRT4
#define A_SRT5
/* - default to 0x01080000 on my audigy 2 ZS --rlrevell	*/

#define A_SRT_ESTSAMPLERATE
#define A_SRT_RATELOCKED

#define A_TTDA
#define A_TTDD

// In A_FXRT1 & A_FXRT2, the 0x80 bit of each byte completely disables the
// filter (CVCF_CURRENTFILTER) for the corresponding channel. There is no
// effect on the volume (CVCF_CURRENTVOLUME) or the interpolator's filter
// (CCCA_INTERPROM_MASK).

#define A_FXRT2
#define A_FXRT_CHANNELE
#define A_FXRT_CHANNELF
#define A_FXRT_CHANNELG
#define A_FXRT_CHANNELH

#define A_SENDAMOUNTS
#define A_FXSENDAMOUNT_E_MASK
#define A_FXSENDAMOUNT_F_MASK
#define A_FXSENDAMOUNT_G_MASK
#define A_FXSENDAMOUNT_H_MASK

/* The send amounts for this one are the same as used with the emu10k1 */
#define A_FXRT1
#define A_FXRT_CHANNELA
#define A_FXRT_CHANNELB
#define A_FXRT_CHANNELC
#define A_FXRT_CHANNELD

/* 0x7f: Not used */

/* The public header defines the GPR and TRAM base addresses that
 * are valid for _both_ CPU and DSP addressing. */

/* 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 MICROCODEBASE
#define A_MICROCODEBASE


/************************************************************************************************/
/* E-MU Digital Audio System overview								*/
/************************************************************************************************/

// - These cards use a regular PCI-attached Audigy chip (Alice2/Tina/Tina2);
//   the PCIe variants simply put the Audigy chip behind a PCI bridge.
// - All physical PCM I/O is routed through an additional FPGA; the regular
//   EXTIN/EXTOUT ports are unconnected.
// - The FPGA has a signal routing matrix, to connect each destination (output
//   socket or capture channel) to a source (input socket or playback channel).
// - The FPGA is controlled via Audigy's GPIO port, while sample data is
//   transmitted via proprietary EMU32 serial links. On first-generation
//   E-MU 1010 cards, Audigy's I2S inputs are also used for sample data.
// - The Audio/Micro Dock is attached to Hana via EDI, a "network" link.
// - The Audigy chip operates in slave mode; the clock is supplied by the FPGA.
//   Gen1 E-MU 1010 cards have two crystals (for 44.1 kHz and 48 kHz multiples),
//   while the later cards use a single crystal and a PLL chip.
// - The whole card is switched to 2x/4x mode to achieve 88.2/96/176.4/192 kHz
//   sample rates. Alice2/Tina keeps running at 44.1/48 kHz, but multiple channels
//   are bundled.
// - The number of available EMU32/EDI channels is hit in 2x/4x mode, so the total
//   number of usable inputs/outputs is limited, esp. with ADAT in use.
// - S/PDIF is unavailable in 4x mode (only over TOSLINK on newer 1010 cards) due
//   to being unspecified at 176.4/192 kHz. Therefore, the Dock's S/PDIF channels
//   can overlap with the Dock's ADC/DAC's high channels.
// - The code names are mentioned below and in the emu_chip_details table.

/************************************************************************************************/
/* EMU1010 FPGA registers									*/
/************************************************************************************************/

#define EMU_HANA_DESTHI
#define EMU_HANA_DESTLO

#define EMU_HANA_SRCHI
#define EMU_HANA_SRCLO

#define EMU_HANA_DOCK_PWR
#define EMU_HANA_DOCK_PWR_ON

#define EMU_HANA_WCLOCK
					/* Must be written after power on to reset DLL */
					/* One is unable to detect the Audio dock without this */
#define EMU_HANA_WCLOCK_SRC_MASK
#define EMU_HANA_WCLOCK_INT_48K
#define EMU_HANA_WCLOCK_INT_44_1K
#define EMU_HANA_WCLOCK_HANA_SPDIF_IN
#define EMU_HANA_WCLOCK_HANA_ADAT_IN
#define EMU_HANA_WCLOCK_SYNC_BNC
#define EMU_HANA_WCLOCK_2ND_HANA
#define EMU_HANA_WCLOCK_SRC_RESERVED
#define EMU_HANA_WCLOCK_OFF
#define EMU_HANA_WCLOCK_MULT_MASK
#define EMU_HANA_WCLOCK_1X
#define EMU_HANA_WCLOCK_2X
#define EMU_HANA_WCLOCK_4X
#define EMU_HANA_WCLOCK_MULT_RESERVED

// If the selected external clock source is/becomes invalid or incompatible
// with the clock multiplier, the clock source is reset to this value, and
// a WCLK_CHANGED interrupt is raised.
#define EMU_HANA_DEFCLOCK
#define EMU_HANA_DEFCLOCK_48K
#define EMU_HANA_DEFCLOCK_44_1K

#define EMU_HANA_UNMUTE
#define EMU_MUTE
#define EMU_UNMUTE

#define EMU_HANA_FPGA_CONFIG
#define EMU_HANA_FPGA_CONFIG_AUDIODOCK
#define EMU_HANA_FPGA_CONFIG_HANA

#define EMU_HANA_IRQ_ENABLE
#define EMU_HANA_IRQ_WCLK_CHANGED
#define EMU_HANA_IRQ_ADAT
#define EMU_HANA_IRQ_DOCK
#define EMU_HANA_IRQ_DOCK_LOST

#define EMU_HANA_SPDIF_MODE
#define EMU_HANA_SPDIF_MODE_TX_CONSUMER
#define EMU_HANA_SPDIF_MODE_TX_PRO
#define EMU_HANA_SPDIF_MODE_TX_NOCOPY
#define EMU_HANA_SPDIF_MODE_RX_CONSUMER
#define EMU_HANA_SPDIF_MODE_RX_PRO
#define EMU_HANA_SPDIF_MODE_RX_NOCOPY
#define EMU_HANA_SPDIF_MODE_RX_INVALID

#define EMU_HANA_OPTICAL_TYPE
#define EMU_HANA_OPTICAL_IN_SPDIF
#define EMU_HANA_OPTICAL_IN_ADAT
#define EMU_HANA_OPTICAL_OUT_SPDIF
#define EMU_HANA_OPTICAL_OUT_ADAT

#define EMU_HANA_MIDI_IN
#define EMU_HANA_MIDI_INA_FROM_HAMOA
#define EMU_HANA_MIDI_INA_FROM_DOCK1
#define EMU_HANA_MIDI_INA_FROM_DOCK2
#define EMU_HANA_MIDI_INB_FROM_HAMOA
#define EMU_HANA_MIDI_INB_FROM_DOCK1
#define EMU_HANA_MIDI_INB_FROM_DOCK2

#define EMU_HANA_DOCK_LEDS_1
#define EMU_HANA_DOCK_LEDS_1_MIDI1
#define EMU_HANA_DOCK_LEDS_1_MIDI2
#define EMU_HANA_DOCK_LEDS_1_SMPTE_IN
#define EMU_HANA_DOCK_LEDS_1_SMPTE_OUT

#define EMU_HANA_DOCK_LEDS_2
#define EMU_HANA_DOCK_LEDS_2_44K
#define EMU_HANA_DOCK_LEDS_2_48K
#define EMU_HANA_DOCK_LEDS_2_96K
#define EMU_HANA_DOCK_LEDS_2_192K
#define EMU_HANA_DOCK_LEDS_2_LOCK
#define EMU_HANA_DOCK_LEDS_2_EXT

#define EMU_HANA_DOCK_LEDS_3
#define EMU_HANA_DOCK_LEDS_3_CLIP_A
#define EMU_HANA_DOCK_LEDS_3_CLIP_B
#define EMU_HANA_DOCK_LEDS_3_SIGNAL_A
#define EMU_HANA_DOCK_LEDS_3_SIGNAL_B
#define EMU_HANA_DOCK_LEDS_3_MANUAL_CLIP
#define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL

#define EMU_HANA_ADC_PADS
#define EMU_HANA_DOCK_ADC_PAD1
#define EMU_HANA_DOCK_ADC_PAD2
#define EMU_HANA_DOCK_ADC_PAD3
#define EMU_HANA_0202_ADC_PAD1

#define EMU_HANA_DOCK_MISC
#define EMU_HANA_DOCK_DAC1_MUTE
#define EMU_HANA_DOCK_DAC2_MUTE
#define EMU_HANA_DOCK_DAC3_MUTE
#define EMU_HANA_DOCK_DAC4_MUTE
#define EMU_HANA_DOCK_PHONES_192_DAC1
#define EMU_HANA_DOCK_PHONES_192_DAC2
#define EMU_HANA_DOCK_PHONES_192_DAC3
#define EMU_HANA_DOCK_PHONES_192_DAC4

#define EMU_HANA_MIDI_OUT
#define EMU_HANA_MIDI_OUT_0202
#define EMU_HANA_MIDI_OUT_DOCK1
#define EMU_HANA_MIDI_OUT_DOCK2
#define EMU_HANA_MIDI_OUT_SYNC2
#define EMU_HANA_MIDI_OUT_LOOP

#define EMU_HANA_DAC_PADS
#define EMU_HANA_DOCK_DAC_PAD1
#define EMU_HANA_DOCK_DAC_PAD2
#define EMU_HANA_DOCK_DAC_PAD3
#define EMU_HANA_DOCK_DAC_PAD4
#define EMU_HANA_0202_DAC_PAD1

/* 0x14 - 0x1f Unused R/W registers */

#define EMU_HANA_IRQ_STATUS
					/* Same bits as for EMU_HANA_IRQ_ENABLE */
					/* Reading the register resets it. */

#define EMU_HANA_OPTION_CARDS
#define EMU_HANA_OPTION_HAMOA
#define EMU_HANA_OPTION_SYNC
#define EMU_HANA_OPTION_DOCK_ONLINE
#define EMU_HANA_OPTION_DOCK_OFFLINE

#define EMU_HANA_ID
					/* 0010101  5 bits ID byte & 0x1f = 0x15 with Tina/2 */

#define EMU_HANA_MAJOR_REV
#define EMU_HANA_MINOR_REV

#define EMU_DOCK_MAJOR_REV
#define EMU_DOCK_MINOR_REV

#define EMU_DOCK_BOARD_ID
#define EMU_DOCK_BOARD_ID0
#define EMU_DOCK_BOARD_ID1

// The actual code disagrees about the bit width of the registers -
// the formula used is freq = 0x1770000 / (((X_HI << 5) | X_LO) + 1)

#define EMU_HANA_WC_SPDIF_HI
#define EMU_HANA_WC_SPDIF_LO

#define EMU_HANA_WC_ADAT_HI
#define EMU_HANA_WC_ADAT_LO

#define EMU_HANA_WC_BNC_LO
#define EMU_HANA_WC_BNC_HI

#define EMU_HANA2_WC_SPDIF_HI
#define EMU_HANA2_WC_SPDIF_LO

/* 0x30 - 0x3f Unused Read only registers */

// The meaning of this is not clear; kX-project just calls it "lock" in some info-only code.
#define EMU_HANA_LOCK_STS_LO
#define EMU_HANA_LOCK_STS_HI

/************************************************************************************************/
/* EMU1010 Audio Destinations									*/
/************************************************************************************************/
/* Hana, original 1010,1212m,1820[m] using Alice2
 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
 * 0x01, 0x00-0x1f: 32 EDI channels to Audio Dock
 *       0x00: Dock DAC 1 Left
 *       0x04: Dock DAC 1 Right
 *       0x08: Dock DAC 2 Left
 *       0x0c: Dock DAC 2 Right
 *       0x10: Dock DAC 3 Left
 *       0x12: PHONES Left (n/a in 2x/4x mode; output mirrors DAC4 Left)
 *       0x14: Dock DAC 3 Right
 *       0x16: PHONES Right (n/a in 2x/4x mode; output mirrors DAC4 Right)
 *       0x18: Dock DAC 4 Left
 *       0x1a: S/PDIF Left
 *       0x1c: Dock DAC 4 Right
 *       0x1e: S/PDIF Right
 * 0x02, 0x00: Hana S/PDIF Left
 * 0x02, 0x01: Hana S/PDIF Right
 * 0x03, 0x00: Hamoa DAC Left
 * 0x03, 0x01: Hamoa DAC Right
 * 0x04, 0x00-0x07: Hana ADAT
 * 0x05, 0x00: I2S0 Left to Alice2
 * 0x05, 0x01: I2S0 Right to Alice2
 * 0x06, 0x00: I2S0 Left to Alice2
 * 0x06, 0x01: I2S0 Right to Alice2
 * 0x07, 0x00: I2S0 Left to Alice2
 * 0x07, 0x01: I2S0 Right to Alice2
 *
 * Hana2 never released, but used Tina
 * Not needed.
 *
 * Hana3, rev2 1010,1212m,1616[m] using Tina
 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina
 * 0x01, 0x00-0x1f: 32 EDI channels to Micro Dock
 *       0x00: Dock DAC 1 Left
 *       0x04: Dock DAC 1 Right
 *       0x08: Dock DAC 2 Left
 *       0x0c: Dock DAC 2 Right
 *       0x10: Dock DAC 3 Left
 *       0x12: Dock S/PDIF Left
 *       0x14: Dock DAC 3 Right
 *       0x16: Dock S/PDIF Right
 *       0x18-0x1f: Dock ADAT 0-7
 * 0x02, 0x00: Hana3 S/PDIF Left
 * 0x02, 0x01: Hana3 S/PDIF Right
 * 0x03, 0x00: Hamoa DAC Left
 * 0x03, 0x01: Hamoa DAC Right
 * 0x04, 0x00-0x07: Hana3 ADAT 0-7
 * 0x05, 0x00-0x0f: 16 EMU32B channels to Tina
 * 0x06-0x07: Not used
 *
 * HanaLite, rev1 0404 using Alice2
 * HanaLiteLite, rev2 0404 using Tina
 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2/Tina
 * 0x01: Not used
 * 0x02, 0x00: S/PDIF Left
 * 0x02, 0x01: S/PDIF Right
 * 0x03, 0x00: DAC Left
 * 0x03, 0x01: DAC Right
 * 0x04-0x07: Not used
 *
 * Mana, Cardbus 1616 using Tina2
 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina2
 * 0x01, 0x00-0x1f: 32 EDI channels to Micro Dock
 *       (same as rev2 1010)
 * 0x02: Not used
 * 0x03, 0x00: Mana DAC Left
 * 0x03, 0x01: Mana DAC Right
 * 0x04, 0x00-0x0f: 16 EMU32B channels to Tina2
 * 0x05-0x07: Not used
 */

/* 32-bit destinations of signal in the Hana FPGA. Destinations are either
 * physical outputs of Hana, or outputs going to Alice2/Tina for capture -
 * 16 x EMU_DST_ALICE2_EMU32_X (2x on rev2 boards). Which data is fed into
 * a channel depends on the mixer control setting for each destination - see
 * the register arrays in emumixer.c.
 */
#define EMU_DST_ALICE2_EMU32_0
					/* This channel is delayed by one sample. */
#define EMU_DST_ALICE2_EMU32_1
#define EMU_DST_ALICE2_EMU32_2
#define EMU_DST_ALICE2_EMU32_3
#define EMU_DST_ALICE2_EMU32_4
#define EMU_DST_ALICE2_EMU32_5
#define EMU_DST_ALICE2_EMU32_6
#define EMU_DST_ALICE2_EMU32_7
#define EMU_DST_ALICE2_EMU32_8
#define EMU_DST_ALICE2_EMU32_9
#define EMU_DST_ALICE2_EMU32_A
#define EMU_DST_ALICE2_EMU32_B
#define EMU_DST_ALICE2_EMU32_C
#define EMU_DST_ALICE2_EMU32_D
#define EMU_DST_ALICE2_EMU32_E
#define EMU_DST_ALICE2_EMU32_F
#define EMU_DST_DOCK_DAC1_LEFT1
#define EMU_DST_DOCK_DAC1_LEFT2
#define EMU_DST_DOCK_DAC1_LEFT3
#define EMU_DST_DOCK_DAC1_LEFT4
#define EMU_DST_DOCK_DAC1_RIGHT1
#define EMU_DST_DOCK_DAC1_RIGHT2
#define EMU_DST_DOCK_DAC1_RIGHT3
#define EMU_DST_DOCK_DAC1_RIGHT4
#define EMU_DST_DOCK_DAC2_LEFT1
#define EMU_DST_DOCK_DAC2_LEFT2
#define EMU_DST_DOCK_DAC2_LEFT3
#define EMU_DST_DOCK_DAC2_LEFT4
#define EMU_DST_DOCK_DAC2_RIGHT1
#define EMU_DST_DOCK_DAC2_RIGHT2
#define EMU_DST_DOCK_DAC2_RIGHT3
#define EMU_DST_DOCK_DAC2_RIGHT4
#define EMU_DST_DOCK_DAC3_LEFT1
#define EMU_DST_DOCK_DAC3_LEFT2
#define EMU_DST_DOCK_DAC3_LEFT3
#define EMU_DST_DOCK_DAC3_LEFT4
#define EMU_DST_DOCK_PHONES_LEFT1
#define EMU_DST_DOCK_PHONES_LEFT2
#define EMU_DST_DOCK_DAC3_RIGHT1
#define EMU_DST_DOCK_DAC3_RIGHT2
#define EMU_DST_DOCK_DAC3_RIGHT3
#define EMU_DST_DOCK_DAC3_RIGHT4
#define EMU_DST_DOCK_PHONES_RIGHT1
#define EMU_DST_DOCK_PHONES_RIGHT2
#define EMU_DST_DOCK_DAC4_LEFT1
#define EMU_DST_DOCK_DAC4_LEFT2
#define EMU_DST_DOCK_DAC4_LEFT3
#define EMU_DST_DOCK_DAC4_LEFT4
#define EMU_DST_DOCK_SPDIF_LEFT1
#define EMU_DST_DOCK_SPDIF_LEFT2
#define EMU_DST_DOCK_DAC4_RIGHT1
#define EMU_DST_DOCK_DAC4_RIGHT2
#define EMU_DST_DOCK_DAC4_RIGHT3
#define EMU_DST_DOCK_DAC4_RIGHT4
#define EMU_DST_DOCK_SPDIF_RIGHT1
#define EMU_DST_DOCK_SPDIF_RIGHT2
#define EMU_DST_HANA_SPDIF_LEFT1
#define EMU_DST_HANA_SPDIF_LEFT2
#define EMU_DST_HANA_SPDIF_LEFT3
#define EMU_DST_HANA_SPDIF_LEFT4
#define EMU_DST_HANA_SPDIF_RIGHT1
#define EMU_DST_HANA_SPDIF_RIGHT2
#define EMU_DST_HANA_SPDIF_RIGHT3
#define EMU_DST_HANA_SPDIF_RIGHT4
#define EMU_DST_HAMOA_DAC_LEFT1
#define EMU_DST_HAMOA_DAC_LEFT2
#define EMU_DST_HAMOA_DAC_LEFT3
#define EMU_DST_HAMOA_DAC_LEFT4
#define EMU_DST_HAMOA_DAC_RIGHT1
#define EMU_DST_HAMOA_DAC_RIGHT2
#define EMU_DST_HAMOA_DAC_RIGHT3
#define EMU_DST_HAMOA_DAC_RIGHT4
// In S/MUX mode, the samples of one channel are adjacent.
#define EMU_DST_HANA_ADAT
#define EMU_DST_ALICE_I2S0_LEFT
#define EMU_DST_ALICE_I2S0_RIGHT
#define EMU_DST_ALICE_I2S1_LEFT
#define EMU_DST_ALICE_I2S1_RIGHT
#define EMU_DST_ALICE_I2S2_LEFT
#define EMU_DST_ALICE_I2S2_RIGHT

/* Additional destinations for 1616(M)/Microdock */

#define EMU_DST_MDOCK_SPDIF_LEFT1
#define EMU_DST_MDOCK_SPDIF_LEFT2
#define EMU_DST_MDOCK_SPDIF_RIGHT1
#define EMU_DST_MDOCK_SPDIF_RIGHT2
#define EMU_DST_MDOCK_ADAT

#define EMU_DST_MANA_DAC_LEFT
#define EMU_DST_MANA_DAC_RIGHT

/************************************************************************************************/
/* EMU1010 Audio Sources									*/
/************************************************************************************************/
/* Hana, original 1010,1212m,1820[m] using Alice2
 * 0x00, 0x00-0x1f: Silence
 * 0x01, 0x00-0x1f: 32 EDI channels from Audio Dock
 *       0x00: Dock Mic A
 *       0x04: Dock Mic B
 *       0x08: Dock ADC 1 Left
 *       0x0c: Dock ADC 1 Right
 *       0x10: Dock ADC 2 Left
 *       0x14: Dock ADC 2 Right
 *       0x18: Dock ADC 3 Left
 *       0x1c: Dock ADC 3 Right
 * 0x02, 0x00: Hamoa ADC Left
 * 0x02, 0x01: Hamoa ADC Right
 * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
 * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
 * 0x04, 0x00-0x07: Hana ADAT
 * 0x05, 0x00: Hana S/PDIF Left
 * 0x05, 0x01: Hana S/PDIF Right
 * 0x06-0x07: Not used
 *
 * Hana2 never released, but used Tina
 * Not needed.
 *
 * Hana3, rev2 1010,1212m,1616[m] using Tina
 * 0x00, 0x00-0x1f: Silence
 * 0x01, 0x00-0x1f: 32 EDI channels from Micro Dock
 *       0x00: Dock Mic A
 *       0x04: Dock Mic B
 *       0x08: Dock ADC 1 Left
 *       0x0c: Dock ADC 1 Right
 *       0x10: Dock ADC 2 Left
 *       0x12: Dock S/PDIF Left
 *       0x14: Dock ADC 2 Right
 *       0x16: Dock S/PDIF Right
 *       0x18-0x1f: Dock ADAT 0-7
 * 0x02, 0x00: Hamoa ADC Left
 * 0x02, 0x01: Hamoa ADC Right
 * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output
 * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output
 * 0x04, 0x00-0x07: Hana3 ADAT
 * 0x05, 0x00: Hana3 S/PDIF Left
 * 0x05, 0x01: Hana3 S/PDIF Right
 * 0x06-0x07: Not used
 *
 * HanaLite, rev1 0404 using Alice2
 * HanaLiteLite, rev2 0404 using Tina
 * 0x00, 0x00-0x1f: Silence
 * 0x01: Not used
 * 0x02, 0x00: ADC Left
 * 0x02, 0x01: ADC Right
 * 0x03, 0x00-0x0f: 16 inputs from Alice2/Tina Emu32A output
 * 0x03, 0x10-0x1f: 16 inputs from Alice2/Tina Emu32B output
 * 0x04: Not used
 * 0x05, 0x00: S/PDIF Left
 * 0x05, 0x01: S/PDIF Right
 * 0x06-0x07: Not used
 *
 * Mana, Cardbus 1616 using Tina2
 * 0x00, 0x00-0x1f: Silence
 * 0x01, 0x00-0x1f: 32 EDI channels from Micro Dock
 *       (same as rev2 1010)
 * 0x02: Not used
 * 0x03, 0x00-0x0f: 16 inputs from Tina2 Emu32A output
 * 0x03, 0x10-0x1f: 16 inputs from Tina2 Emu32B output
 * 0x04-0x07: Not used
 */

/* 32-bit sources of signal in the Hana FPGA. The sources are routed to
 * destinations using a mixer control for each destination - see emumixer.c.
 * Sources are either physical inputs of Hana, or inputs from Alice2/Tina -
 * 16 x EMU_SRC_ALICE_EMU32A + 16 x EMU_SRC_ALICE_EMU32B.
 */
#define EMU_SRC_SILENCE
#define EMU_SRC_DOCK_MIC_A1
#define EMU_SRC_DOCK_MIC_A2
#define EMU_SRC_DOCK_MIC_A3
#define EMU_SRC_DOCK_MIC_A4
#define EMU_SRC_DOCK_MIC_B1
#define EMU_SRC_DOCK_MIC_B2
#define EMU_SRC_DOCK_MIC_B3
#define EMU_SRC_DOCK_MIC_B4
#define EMU_SRC_DOCK_ADC1_LEFT1
#define EMU_SRC_DOCK_ADC1_LEFT2
#define EMU_SRC_DOCK_ADC1_LEFT3
#define EMU_SRC_DOCK_ADC1_LEFT4
#define EMU_SRC_DOCK_ADC1_RIGHT1
#define EMU_SRC_DOCK_ADC1_RIGHT2
#define EMU_SRC_DOCK_ADC1_RIGHT3
#define EMU_SRC_DOCK_ADC1_RIGHT4
#define EMU_SRC_DOCK_ADC2_LEFT1
#define EMU_SRC_DOCK_ADC2_LEFT2
#define EMU_SRC_DOCK_ADC2_LEFT3
#define EMU_SRC_DOCK_ADC2_LEFT4
#define EMU_SRC_DOCK_ADC2_RIGHT1
#define EMU_SRC_DOCK_ADC2_RIGHT2
#define EMU_SRC_DOCK_ADC2_RIGHT3
#define EMU_SRC_DOCK_ADC2_RIGHT4
#define EMU_SRC_DOCK_ADC3_LEFT1
#define EMU_SRC_DOCK_ADC3_LEFT2
#define EMU_SRC_DOCK_ADC3_LEFT3
#define EMU_SRC_DOCK_ADC3_LEFT4
#define EMU_SRC_DOCK_ADC3_RIGHT1
#define EMU_SRC_DOCK_ADC3_RIGHT2
#define EMU_SRC_DOCK_ADC3_RIGHT3
#define EMU_SRC_DOCK_ADC3_RIGHT4
#define EMU_SRC_HAMOA_ADC_LEFT1
#define EMU_SRC_HAMOA_ADC_LEFT2
#define EMU_SRC_HAMOA_ADC_LEFT3
#define EMU_SRC_HAMOA_ADC_LEFT4
#define EMU_SRC_HAMOA_ADC_RIGHT1
#define EMU_SRC_HAMOA_ADC_RIGHT2
#define EMU_SRC_HAMOA_ADC_RIGHT3
#define EMU_SRC_HAMOA_ADC_RIGHT4
#define EMU_SRC_ALICE_EMU32A
#define EMU_SRC_ALICE_EMU32B
// In S/MUX mode, the samples of one channel are adjacent.
#define EMU_SRC_HANA_ADAT
#define EMU_SRC_HANA_SPDIF_LEFT1
#define EMU_SRC_HANA_SPDIF_LEFT2
#define EMU_SRC_HANA_SPDIF_LEFT3
#define EMU_SRC_HANA_SPDIF_LEFT4
#define EMU_SRC_HANA_SPDIF_RIGHT1
#define EMU_SRC_HANA_SPDIF_RIGHT2
#define EMU_SRC_HANA_SPDIF_RIGHT3
#define EMU_SRC_HANA_SPDIF_RIGHT4

/* Additional inputs for 1616(M)/Microdock */

#define EMU_SRC_MDOCK_SPDIF_LEFT1
#define EMU_SRC_MDOCK_SPDIF_LEFT2
#define EMU_SRC_MDOCK_SPDIF_RIGHT1
#define EMU_SRC_MDOCK_SPDIF_RIGHT2
#define EMU_SRC_MDOCK_ADAT

/* 0x600 and 0x700 no used */


/* ------------------- CONSTANTS -------------------- */

extern const char * const snd_emu10k1_fxbus[32];
extern const char * const snd_emu10k1_sblive_ins[16];
extern const char * const snd_emu10k1_audigy_ins[16];
extern const char * const snd_emu10k1_sblive_outs[32];
extern const char * const snd_emu10k1_audigy_outs[32];
extern const s8 snd_emu10k1_sblive51_fxbus2_map[16];

/* ------------------- STRUCTURES -------------------- */

enum {};

struct snd_emu10k1;

struct snd_emu10k1_voice {};

enum {};

struct snd_emu10k1_pcm {};

struct snd_emu10k1_pcm_mixer {};

#define snd_emu10k1_compose_send_routing(route)

#define snd_emu10k1_compose_audigy_fxrt1(route)

#define snd_emu10k1_compose_audigy_fxrt2(route)

#define snd_emu10k1_compose_audigy_sendamounts(vol)

struct snd_emu10k1_memblk {};

#define snd_emu10k1_memblk_offset(blk)

#define EMU10K1_MAX_TRAM_BLOCKS_PER_CODE

struct snd_emu10k1_fx8010_ctl {};

snd_fx8010_irq_handler_t;

struct snd_emu10k1_fx8010_irq {};

struct snd_emu10k1_fx8010_pcm {};

struct snd_emu10k1_fx8010 {};

struct snd_emu10k1_midi {};

enum {};

// Chip-o-logy:
// - All SB Live! cards use EMU10K1 chips
// - All SB Audigy cards use CA* chips, termed "emu10k2" by the driver
// - Original Audigy uses CA0100 "Alice"
// - Audigy 2 uses CA0102/CA10200 "Alice2"
//   - Has an interface for CA0151 (P16V) "Alice3"
// - Audigy 2 Value uses CA0108/CA10300 "Tina"
//   - Approximately a CA0102 with an on-chip CA0151 (P17V)
// - Audigy 2 ZS NB uses CA0109 "Tina2"
//   - Cardbus version of CA0108
struct snd_emu_chip_details {};

#define NUM_OUTPUT_DESTS
#define NUM_INPUT_DESTS

struct snd_emu1010 {};

struct snd_emu10k1 {};

int snd_emu10k1_create(struct snd_card *card,
		       struct pci_dev *pci,
		       unsigned short extin_mask,
		       unsigned short extout_mask,
		       long max_cache_bytes,
		       int enable_ir,
		       uint subsystem);

int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device);
int snd_p16v_pcm(struct snd_emu10k1 *emu, int device);
int snd_p16v_mixer(struct snd_emu10k1 * emu);
int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_mixer(struct snd_emu10k1 * emu, int pcm_device, int multi_device);
int snd_emu10k1_timer(struct snd_emu10k1 * emu, int device);
int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device);

irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id);

void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int voice);
int snd_emu10k1_init_efx(struct snd_emu10k1 *emu);
void snd_emu10k1_free_efx(struct snd_emu10k1 *emu);
int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size);
int snd_emu10k1_done(struct snd_emu10k1 * emu);

/* I/O functions */
unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, ...);
unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
static inline void snd_emu1010_fpga_lock(struct snd_emu10k1 *emu) { mutex_lock(&emu->emu1010.lock); };
static inline void snd_emu1010_fpga_unlock(struct snd_emu10k1 *emu) { mutex_unlock(&emu->emu1010.lock); };
void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value);
void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value);
void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src);
u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst);
int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src);
void snd_emu1010_update_clock(struct snd_emu10k1 *emu);
void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock, const struct firmware *fw_entry);
unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
#if 0
void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
#endif
void snd_emu10k1_voice_set_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices);
void snd_emu10k1_voice_clear_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices);
int snd_emu10k1_voice_clear_loop_stop_multiple_atomic(struct snd_emu10k1 *emu, u64 voices);
void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait);
static inline unsigned int snd_emu10k1_wc(struct snd_emu10k1 *emu) {}
unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data);

#ifdef CONFIG_PM_SLEEP
void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu);
void snd_emu10k1_resume_init(struct snd_emu10k1 *emu);
void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu);
int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu);
void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu);
void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu);
void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu);
int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu);
void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu);
void snd_p16v_suspend(struct snd_emu10k1 *emu);
void snd_p16v_resume(struct snd_emu10k1 *emu);
#endif

/* memory allocation */
struct snd_util_memblk *snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream);
int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
int snd_emu10k1_alloc_pages_maybe_wider(struct snd_emu10k1 *emu, size_t size,
					struct snd_dma_buffer *dmab);
struct snd_util_memblk *snd_emu10k1_synth_alloc(struct snd_emu10k1 *emu, unsigned int size);
int snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
int snd_emu10k1_synth_memset(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, int size, u8 value);
int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, const char __user *data, int size, u32 xor);
int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk);

/* voice allocation */
int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int count, int channels,
			    struct snd_emu10k1_pcm *epcm, struct snd_emu10k1_voice **rvoice);
int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice);

/* MIDI uart */
int snd_emu10k1_midi(struct snd_emu10k1 * emu);
int snd_emu10k1_audigy_midi(struct snd_emu10k1 * emu);

/* proc interface */
int snd_emu10k1_proc_init(struct snd_emu10k1 * emu);

/* fx8010 irq handler */
int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
					    snd_fx8010_irq_handler_t *handler,
					    unsigned char gpr_running,
					    void *private_data,
					    struct snd_emu10k1_fx8010_irq *irq);
int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
					      struct snd_emu10k1_fx8010_irq *irq);

#endif	/* __SOUND_EMU10K1_H */