162306a36Sopenharmony_ci/**************************************************************************** 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci Copyright Echo Digital Audio Corporation (c) 1998 - 2004 462306a36Sopenharmony_ci All rights reserved 562306a36Sopenharmony_ci www.echoaudio.com 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci This file is part of Echo Digital Audio's generic driver library. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci Echo Digital Audio's generic driver library is free software; 1062306a36Sopenharmony_ci you can redistribute it and/or modify it under the terms of 1162306a36Sopenharmony_ci the GNU General Public License as published by the Free Software 1262306a36Sopenharmony_ci Foundation. 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci This program is distributed in the hope that it will be useful, 1562306a36Sopenharmony_ci but WITHOUT ANY WARRANTY; without even the implied warranty of 1662306a36Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1762306a36Sopenharmony_ci GNU General Public License for more details. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci You should have received a copy of the GNU General Public License 2062306a36Sopenharmony_ci along with this program; if not, write to the Free Software 2162306a36Sopenharmony_ci Foundation, Inc., 59 Temple Place - Suite 330, Boston, 2262306a36Sopenharmony_ci MA 02111-1307, USA. 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci **************************************************************************** 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci Translation from C++ and adaptation for use in ALSA-Driver 2762306a36Sopenharmony_ci were made by Giuliano Pochini <pochini@shiny.it> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci **************************************************************************** 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci Here's a block diagram of how most of the cards work: 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci +-----------+ 3562306a36Sopenharmony_ci record | |<-------------------- Inputs 3662306a36Sopenharmony_ci <-------| | | 3762306a36Sopenharmony_ci PCI | Transport | | 3862306a36Sopenharmony_ci bus | engine | \|/ 3962306a36Sopenharmony_ci ------->| | +-------+ 4062306a36Sopenharmony_ci play | |--->|monitor|-------> Outputs 4162306a36Sopenharmony_ci +-----------+ | mixer | 4262306a36Sopenharmony_ci +-------+ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci The lines going to and from the PCI bus represent "pipes". A pipe performs 4562306a36Sopenharmony_ci audio transport - moving audio data to and from buffers on the host via 4662306a36Sopenharmony_ci bus mastering. 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci The inputs and outputs on the right represent input and output "busses." 4962306a36Sopenharmony_ci A bus is a physical, real connection to the outside world. An example 5062306a36Sopenharmony_ci of a bus would be the 1/4" analog connectors on the back of Layla or 5162306a36Sopenharmony_ci an RCA S/PDIF connector. 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci For most cards, there is a one-to-one correspondence between outputs 5462306a36Sopenharmony_ci and busses; that is, each individual pipe is hard-wired to a single bus. 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24, 5762306a36Sopenharmony_ci Layla24, Mona, and Indigo. 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci Mia has a feature called "virtual outputs." 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci +-----------+ 6462306a36Sopenharmony_ci record | |<----------------------------- Inputs 6562306a36Sopenharmony_ci <-------| | | 6662306a36Sopenharmony_ci PCI | Transport | | 6762306a36Sopenharmony_ci bus | engine | \|/ 6862306a36Sopenharmony_ci ------->| | +------+ +-------+ 6962306a36Sopenharmony_ci play | |-->|vmixer|-->|monitor|-------> Outputs 7062306a36Sopenharmony_ci +-----------+ +------+ | mixer | 7162306a36Sopenharmony_ci +-------+ 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci Obviously, the difference here is the box labeled "vmixer." Vmixer is 7562306a36Sopenharmony_ci short for "virtual output mixer." For Mia, pipes are *not* hard-wired 7662306a36Sopenharmony_ci to a single bus; the vmixer lets you mix any pipe to any bus in any 7762306a36Sopenharmony_ci combination. 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci Note, however, that the left-hand side of the diagram is unchanged. 8062306a36Sopenharmony_ci Transport works exactly the same way - the difference is in the mixer stage. 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci Pipes and busses are numbered starting at zero. 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci Pipe index 8862306a36Sopenharmony_ci ========== 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci A number of calls in CEchoGals refer to a "pipe index". A pipe index is 9162306a36Sopenharmony_ci a unique number for a pipe that unambiguously refers to a playback or record 9262306a36Sopenharmony_ci pipe. Pipe indices are numbered starting with analog outputs, followed by 9362306a36Sopenharmony_ci digital outputs, then analog inputs, then digital inputs. 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci Take Gina24 as an example: 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci Pipe index 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci 0-7 Analog outputs (0 .. FirstDigitalBusOut-1) 10062306a36Sopenharmony_ci 8-15 Digital outputs (FirstDigitalBusOut .. NumBussesOut-1) 10162306a36Sopenharmony_ci 16-17 Analog inputs 10262306a36Sopenharmony_ci 18-25 Digital inputs 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci You get the pipe index by calling CEchoGals::OpenAudio; the other transport 10662306a36Sopenharmony_ci functions take the pipe index as a parameter. If you need a pipe index for 10762306a36Sopenharmony_ci some other reason, use the handy Makepipe_index method. 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci Some calls take a CChannelMask parameter; CChannelMask is a handy way to 11162306a36Sopenharmony_ci group pipe indices. 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci Digital mode switch 11662306a36Sopenharmony_ci =================== 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch 11962306a36Sopenharmony_ci or DMS. Cards with a DMS can be set to one of three mutually exclusive 12062306a36Sopenharmony_ci digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical. 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci This may create some confusion since ADAT optical is 8 channels wide and 12362306a36Sopenharmony_ci S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this 12462306a36Sopenharmony_ci by acting as if they always have 8 digital outs and ins. If you are in 12562306a36Sopenharmony_ci either S/PDIF mode, the last 6 channels don't do anything - data sent 12662306a36Sopenharmony_ci out these channels is thrown away and you will always record zeros. 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are 12962306a36Sopenharmony_ci only available if you have the card configured for S/PDIF optical or S/PDIF 13062306a36Sopenharmony_ci RCA. 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci Double speed mode 13562306a36Sopenharmony_ci ================= 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24, 13862306a36Sopenharmony_ci Layla24, Mona, Mia, and Indigo). For these cards, the driver sometimes has 13962306a36Sopenharmony_ci to worry about "double speed mode"; double speed mode applies whenever the 14062306a36Sopenharmony_ci sampling rate is above 50 kHz. 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci For instance, Mona and Layla24 support word clock sync. However, they 14362306a36Sopenharmony_ci actually support two different word clock modes - single speed (below 14462306a36Sopenharmony_ci 50 kHz) and double speed (above 50 kHz). The hardware detects if a single 14562306a36Sopenharmony_ci or double speed word clock signal is present; the generic code uses that 14662306a36Sopenharmony_ci information to determine which mode to use. 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci The generic code takes care of all this for you. 14962306a36Sopenharmony_ci*/ 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci#ifndef _ECHOAUDIO_H_ 15362306a36Sopenharmony_ci#define _ECHOAUDIO_H_ 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci#include "echoaudio_dsp.h" 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci/*********************************************************************** 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci PCI configuration space 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci***********************************************************************/ 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci/* 16762306a36Sopenharmony_ci * PCI vendor ID and device IDs for the hardware 16862306a36Sopenharmony_ci */ 16962306a36Sopenharmony_ci#define VENDOR_ID 0x1057 17062306a36Sopenharmony_ci#define DEVICE_ID_56301 0x1801 17162306a36Sopenharmony_ci#define DEVICE_ID_56361 0x3410 17262306a36Sopenharmony_ci#define SUBVENDOR_ID 0xECC0 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/* 17662306a36Sopenharmony_ci * Valid Echo PCI subsystem card IDs 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_ci#define DARLA20 0x0010 17962306a36Sopenharmony_ci#define GINA20 0x0020 18062306a36Sopenharmony_ci#define LAYLA20 0x0030 18162306a36Sopenharmony_ci#define DARLA24 0x0040 18262306a36Sopenharmony_ci#define GINA24 0x0050 18362306a36Sopenharmony_ci#define LAYLA24 0x0060 18462306a36Sopenharmony_ci#define MONA 0x0070 18562306a36Sopenharmony_ci#define MIA 0x0080 18662306a36Sopenharmony_ci#define INDIGO 0x0090 18762306a36Sopenharmony_ci#define INDIGO_IO 0x00a0 18862306a36Sopenharmony_ci#define INDIGO_DJ 0x00b0 18962306a36Sopenharmony_ci#define DC8 0x00c0 19062306a36Sopenharmony_ci#define INDIGO_IOX 0x00d0 19162306a36Sopenharmony_ci#define INDIGO_DJX 0x00e0 19262306a36Sopenharmony_ci#define ECHO3G 0x0100 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci/************************************************************************ 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci Array sizes and so forth 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci***********************************************************************/ 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci/* 20262306a36Sopenharmony_ci * Sizes 20362306a36Sopenharmony_ci */ 20462306a36Sopenharmony_ci#define ECHO_MAXAUDIOINPUTS 32 /* Max audio input channels */ 20562306a36Sopenharmony_ci#define ECHO_MAXAUDIOOUTPUTS 32 /* Max audio output channels */ 20662306a36Sopenharmony_ci#define ECHO_MAXAUDIOPIPES 32 /* Max number of input and output 20762306a36Sopenharmony_ci * pipes */ 20862306a36Sopenharmony_ci#define E3G_MAX_OUTPUTS 16 20962306a36Sopenharmony_ci#define ECHO_MAXMIDIJACKS 1 /* Max MIDI ports */ 21062306a36Sopenharmony_ci#define ECHO_MIDI_QUEUE_SZ 512 /* Max MIDI input queue entries */ 21162306a36Sopenharmony_ci#define ECHO_MTC_QUEUE_SZ 32 /* Max MIDI time code input queue 21262306a36Sopenharmony_ci * entries */ 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* 21562306a36Sopenharmony_ci * MIDI activity indicator timeout 21662306a36Sopenharmony_ci */ 21762306a36Sopenharmony_ci#define MIDI_ACTIVITY_TIMEOUT_USEC 200000 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/**************************************************************************** 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci Clocks 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci*****************************************************************************/ 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci/* 22762306a36Sopenharmony_ci * Clock numbers 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_ci#define ECHO_CLOCK_INTERNAL 0 23062306a36Sopenharmony_ci#define ECHO_CLOCK_WORD 1 23162306a36Sopenharmony_ci#define ECHO_CLOCK_SUPER 2 23262306a36Sopenharmony_ci#define ECHO_CLOCK_SPDIF 3 23362306a36Sopenharmony_ci#define ECHO_CLOCK_ADAT 4 23462306a36Sopenharmony_ci#define ECHO_CLOCK_ESYNC 5 23562306a36Sopenharmony_ci#define ECHO_CLOCK_ESYNC96 6 23662306a36Sopenharmony_ci#define ECHO_CLOCK_MTC 7 23762306a36Sopenharmony_ci#define ECHO_CLOCK_NUMBER 8 23862306a36Sopenharmony_ci#define ECHO_CLOCKS 0xffff 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* 24162306a36Sopenharmony_ci * Clock bit numbers - used to report capabilities and whatever clocks 24262306a36Sopenharmony_ci * are being detected dynamically. 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_INTERNAL (1 << ECHO_CLOCK_INTERNAL) 24562306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_WORD (1 << ECHO_CLOCK_WORD) 24662306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_SUPER (1 << ECHO_CLOCK_SUPER) 24762306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_SPDIF (1 << ECHO_CLOCK_SPDIF) 24862306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_ADAT (1 << ECHO_CLOCK_ADAT) 24962306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_ESYNC (1 << ECHO_CLOCK_ESYNC) 25062306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_ESYNC96 (1 << ECHO_CLOCK_ESYNC96) 25162306a36Sopenharmony_ci#define ECHO_CLOCK_BIT_MTC (1<<ECHO_CLOCK_MTC) 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci/*************************************************************************** 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci Digital modes 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci****************************************************************************/ 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci/* 26162306a36Sopenharmony_ci * Digital modes for Mona, Layla24, and Gina24 26262306a36Sopenharmony_ci */ 26362306a36Sopenharmony_ci#define DIGITAL_MODE_NONE 0xFF 26462306a36Sopenharmony_ci#define DIGITAL_MODE_SPDIF_RCA 0 26562306a36Sopenharmony_ci#define DIGITAL_MODE_SPDIF_OPTICAL 1 26662306a36Sopenharmony_ci#define DIGITAL_MODE_ADAT 2 26762306a36Sopenharmony_ci#define DIGITAL_MODE_SPDIF_CDROM 3 26862306a36Sopenharmony_ci#define DIGITAL_MODES 4 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci/* 27162306a36Sopenharmony_ci * Digital mode capability masks 27262306a36Sopenharmony_ci */ 27362306a36Sopenharmony_ci#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA (1 << DIGITAL_MODE_SPDIF_RCA) 27462306a36Sopenharmony_ci#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL (1 << DIGITAL_MODE_SPDIF_OPTICAL) 27562306a36Sopenharmony_ci#define ECHOCAPS_HAS_DIGITAL_MODE_ADAT (1 << DIGITAL_MODE_ADAT) 27662306a36Sopenharmony_ci#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM (1 << DIGITAL_MODE_SPDIF_CDROM) 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci#define EXT_3GBOX_NC 0x01 /* 3G box not connected */ 28062306a36Sopenharmony_ci#define EXT_3GBOX_NOT_SET 0x02 /* 3G box not detected yet */ 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci#define ECHOGAIN_MUTED (-128) /* Minimum possible gain */ 28462306a36Sopenharmony_ci#define ECHOGAIN_MINOUT (-128) /* Min output gain (dB) */ 28562306a36Sopenharmony_ci#define ECHOGAIN_MAXOUT (6) /* Max output gain (dB) */ 28662306a36Sopenharmony_ci#define ECHOGAIN_MININP (-50) /* Min input gain (0.5 dB) */ 28762306a36Sopenharmony_ci#define ECHOGAIN_MAXINP (50) /* Max input gain (0.5 dB) */ 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci#define PIPE_STATE_STOPPED 0 /* Pipe has been reset */ 29062306a36Sopenharmony_ci#define PIPE_STATE_PAUSED 1 /* Pipe has been stopped */ 29162306a36Sopenharmony_ci#define PIPE_STATE_STARTED 2 /* Pipe has been started */ 29262306a36Sopenharmony_ci#define PIPE_STATE_PENDING 3 /* Pipe has pending start */ 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistruct audiopipe { 29762306a36Sopenharmony_ci volatile __le32 *dma_counter; /* Commpage register that contains 29862306a36Sopenharmony_ci * the current dma position 29962306a36Sopenharmony_ci * (lower 32 bits only) 30062306a36Sopenharmony_ci */ 30162306a36Sopenharmony_ci u32 last_period; /* Counter position last time a 30262306a36Sopenharmony_ci * period elapsed 30362306a36Sopenharmony_ci */ 30462306a36Sopenharmony_ci u32 last_counter; /* Used exclusively by pcm_pointer 30562306a36Sopenharmony_ci * under PCM core locks. 30662306a36Sopenharmony_ci * The last position, which is used 30762306a36Sopenharmony_ci * to compute... 30862306a36Sopenharmony_ci */ 30962306a36Sopenharmony_ci u32 position; /* ...the number of bytes tranferred 31062306a36Sopenharmony_ci * by the DMA engine, modulo the 31162306a36Sopenharmony_ci * buffer size 31262306a36Sopenharmony_ci */ 31362306a36Sopenharmony_ci short index; /* Index of the first channel or <0 31462306a36Sopenharmony_ci * if hw is not configured yet 31562306a36Sopenharmony_ci */ 31662306a36Sopenharmony_ci short interleave; 31762306a36Sopenharmony_ci struct snd_dma_buffer sgpage; /* Room for the scatter-gather list */ 31862306a36Sopenharmony_ci struct snd_pcm_hardware hw; 31962306a36Sopenharmony_ci struct snd_pcm_hw_constraint_list constr; 32062306a36Sopenharmony_ci short sglist_head; 32162306a36Sopenharmony_ci char state; /* pipe state */ 32262306a36Sopenharmony_ci}; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistruct audioformat { 32662306a36Sopenharmony_ci u8 interleave; /* How the data is arranged in memory: 32762306a36Sopenharmony_ci * mono = 1, stereo = 2, ... 32862306a36Sopenharmony_ci */ 32962306a36Sopenharmony_ci u8 bits_per_sample; /* 8, 16, 24, 32 (24 bits left aligned) */ 33062306a36Sopenharmony_ci char mono_to_stereo; /* Only used if interleave is 1 and 33162306a36Sopenharmony_ci * if this is an output pipe. 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ci char data_are_bigendian; /* 1 = big endian, 0 = little endian */ 33462306a36Sopenharmony_ci}; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cistruct echoaudio { 33862306a36Sopenharmony_ci spinlock_t lock; 33962306a36Sopenharmony_ci struct snd_pcm_substream *substream[DSP_MAXPIPES]; 34062306a36Sopenharmony_ci struct mutex mode_mutex; 34162306a36Sopenharmony_ci u16 num_digital_modes, digital_mode_list[6]; 34262306a36Sopenharmony_ci u16 num_clock_sources, clock_source_list[10]; 34362306a36Sopenharmony_ci unsigned int opencount; /* protected by mode_mutex */ 34462306a36Sopenharmony_ci struct snd_kcontrol *clock_src_ctl; 34562306a36Sopenharmony_ci struct snd_pcm *analog_pcm, *digital_pcm; 34662306a36Sopenharmony_ci struct snd_card *card; 34762306a36Sopenharmony_ci const char *card_name; 34862306a36Sopenharmony_ci struct pci_dev *pci; 34962306a36Sopenharmony_ci unsigned long dsp_registers_phys; 35062306a36Sopenharmony_ci struct resource *iores; 35162306a36Sopenharmony_ci struct snd_dma_buffer *commpage_dma_buf; 35262306a36Sopenharmony_ci int irq; 35362306a36Sopenharmony_ci#ifdef ECHOCARD_HAS_MIDI 35462306a36Sopenharmony_ci struct snd_rawmidi *rmidi; 35562306a36Sopenharmony_ci struct snd_rawmidi_substream *midi_in, *midi_out; 35662306a36Sopenharmony_ci#endif 35762306a36Sopenharmony_ci struct timer_list timer; 35862306a36Sopenharmony_ci char tinuse; /* Timer in use */ 35962306a36Sopenharmony_ci char midi_full; /* MIDI output buffer is full */ 36062306a36Sopenharmony_ci char can_set_rate; /* protected by mode_mutex */ 36162306a36Sopenharmony_ci char rate_set; /* protected by mode_mutex */ 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci /* This stuff is used mainly by the lowlevel code */ 36462306a36Sopenharmony_ci struct comm_page *comm_page; /* Virtual address of the memory 36562306a36Sopenharmony_ci * seen by DSP 36662306a36Sopenharmony_ci */ 36762306a36Sopenharmony_ci u32 pipe_alloc_mask; /* Bitmask of allocated pipes */ 36862306a36Sopenharmony_ci u32 pipe_cyclic_mask; /* Bitmask of pipes with cyclic 36962306a36Sopenharmony_ci * buffers 37062306a36Sopenharmony_ci */ 37162306a36Sopenharmony_ci u32 sample_rate; /* Card sample rate in Hz */ 37262306a36Sopenharmony_ci u8 digital_mode; /* Current digital mode 37362306a36Sopenharmony_ci * (see DIGITAL_MODE_*) 37462306a36Sopenharmony_ci */ 37562306a36Sopenharmony_ci u8 spdif_status; /* Gina20, Darla20, Darla24 - only */ 37662306a36Sopenharmony_ci u8 clock_state; /* Gina20, Darla20, Darla24 - only */ 37762306a36Sopenharmony_ci u8 input_clock; /* Currently selected sample clock 37862306a36Sopenharmony_ci * source 37962306a36Sopenharmony_ci */ 38062306a36Sopenharmony_ci u8 output_clock; /* Layla20 only */ 38162306a36Sopenharmony_ci char meters_enabled; /* VU-meters status */ 38262306a36Sopenharmony_ci char asic_loaded; /* Set true when ASIC loaded */ 38362306a36Sopenharmony_ci char bad_board; /* Set true if DSP won't load */ 38462306a36Sopenharmony_ci char professional_spdif; /* 0 = consumer; 1 = professional */ 38562306a36Sopenharmony_ci char non_audio_spdif; /* 3G - only */ 38662306a36Sopenharmony_ci char digital_in_automute; /* Gina24, Layla24, Mona - only */ 38762306a36Sopenharmony_ci char has_phantom_power; 38862306a36Sopenharmony_ci char hasnt_input_nominal_level; /* Gina3G */ 38962306a36Sopenharmony_ci char phantom_power; /* Gina3G - only */ 39062306a36Sopenharmony_ci char has_midi; 39162306a36Sopenharmony_ci char midi_input_enabled; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci#ifdef ECHOCARD_ECHO3G 39462306a36Sopenharmony_ci /* External module -dependent pipe and bus indexes */ 39562306a36Sopenharmony_ci char px_digital_out, px_analog_in, px_digital_in, px_num; 39662306a36Sopenharmony_ci char bx_digital_out, bx_analog_in, bx_digital_in, bx_num; 39762306a36Sopenharmony_ci#endif 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci char nominal_level[ECHO_MAXAUDIOPIPES]; /* True == -10dBV 40062306a36Sopenharmony_ci * False == +4dBu */ 40162306a36Sopenharmony_ci s8 input_gain[ECHO_MAXAUDIOINPUTS]; /* Input level -50..+50 40262306a36Sopenharmony_ci * unit is 0.5dB */ 40362306a36Sopenharmony_ci s8 output_gain[ECHO_MAXAUDIOOUTPUTS]; /* Output level -128..+6 dB 40462306a36Sopenharmony_ci * (-128=muted) */ 40562306a36Sopenharmony_ci s8 monitor_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOINPUTS]; 40662306a36Sopenharmony_ci /* -128..+6 dB */ 40762306a36Sopenharmony_ci s8 vmixer_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS]; 40862306a36Sopenharmony_ci /* -128..+6 dB */ 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci u16 digital_modes; /* Bitmask of supported modes 41162306a36Sopenharmony_ci * (see ECHOCAPS_HAS_DIGITAL_MODE_*) */ 41262306a36Sopenharmony_ci u16 input_clock_types; /* Suppoted input clock types */ 41362306a36Sopenharmony_ci u16 output_clock_types; /* Suppoted output clock types - 41462306a36Sopenharmony_ci * Layla20 only */ 41562306a36Sopenharmony_ci u16 device_id, subdevice_id; 41662306a36Sopenharmony_ci u16 *dsp_code; /* Current DSP code loaded, 41762306a36Sopenharmony_ci * NULL if nothing loaded */ 41862306a36Sopenharmony_ci short dsp_code_to_load; /* DSP code to load */ 41962306a36Sopenharmony_ci short asic_code; /* Current ASIC code */ 42062306a36Sopenharmony_ci u32 comm_page_phys; /* Physical address of the 42162306a36Sopenharmony_ci * memory seen by DSP */ 42262306a36Sopenharmony_ci u32 __iomem *dsp_registers; /* DSP's register base */ 42362306a36Sopenharmony_ci u32 active_mask; /* Chs. active mask or 42462306a36Sopenharmony_ci * punks out */ 42562306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 42662306a36Sopenharmony_ci const struct firmware *fw_cache[8]; /* Cached firmwares */ 42762306a36Sopenharmony_ci#endif 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci#ifdef ECHOCARD_HAS_MIDI 43062306a36Sopenharmony_ci u16 mtc_state; /* State for MIDI input parsing state machine */ 43162306a36Sopenharmony_ci u8 midi_buffer[MIDI_IN_BUFFER_SIZE]; 43262306a36Sopenharmony_ci#endif 43362306a36Sopenharmony_ci}; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_cistatic int init_dsp_comm_page(struct echoaudio *chip); 43762306a36Sopenharmony_cistatic int init_line_levels(struct echoaudio *chip); 43862306a36Sopenharmony_cistatic int free_pipes(struct echoaudio *chip, struct audiopipe *pipe); 43962306a36Sopenharmony_cistatic int load_firmware(struct echoaudio *chip); 44062306a36Sopenharmony_cistatic int wait_handshake(struct echoaudio *chip); 44162306a36Sopenharmony_cistatic int send_vector(struct echoaudio *chip, u32 command); 44262306a36Sopenharmony_cistatic int get_firmware(const struct firmware **fw_entry, 44362306a36Sopenharmony_ci struct echoaudio *chip, const short fw_index); 44462306a36Sopenharmony_cistatic void free_firmware(const struct firmware *fw_entry, 44562306a36Sopenharmony_ci struct echoaudio *chip); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci#ifdef ECHOCARD_HAS_MIDI 44862306a36Sopenharmony_cistatic int enable_midi_input(struct echoaudio *chip, char enable); 44962306a36Sopenharmony_cistatic void snd_echo_midi_output_trigger( 45062306a36Sopenharmony_ci struct snd_rawmidi_substream *substream, int up); 45162306a36Sopenharmony_cistatic int midi_service_irq(struct echoaudio *chip); 45262306a36Sopenharmony_cistatic int snd_echo_midi_create(struct snd_card *card, 45362306a36Sopenharmony_ci struct echoaudio *chip); 45462306a36Sopenharmony_ci#endif 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_cistatic inline void clear_handshake(struct echoaudio *chip) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci chip->comm_page->handshake = 0; 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic inline u32 get_dsp_register(struct echoaudio *chip, u32 index) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci return readl(&chip->dsp_registers[index]); 46562306a36Sopenharmony_ci} 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_cistatic inline void set_dsp_register(struct echoaudio *chip, u32 index, 46862306a36Sopenharmony_ci u32 value) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci writel(value, &chip->dsp_registers[index]); 47162306a36Sopenharmony_ci} 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci/* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_* 47562306a36Sopenharmony_cifor 3G cards because they depend on the external box. They are integer 47662306a36Sopenharmony_ciconstants for all other cards. 47762306a36Sopenharmony_ciNever use those defines directly, use the following functions instead. */ 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_cistatic inline int px_digital_out(const struct echoaudio *chip) 48062306a36Sopenharmony_ci{ 48162306a36Sopenharmony_ci return PX_DIGITAL_OUT; 48262306a36Sopenharmony_ci} 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_cistatic inline int px_analog_in(const struct echoaudio *chip) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci return PX_ANALOG_IN; 48762306a36Sopenharmony_ci} 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_cistatic inline int px_digital_in(const struct echoaudio *chip) 49062306a36Sopenharmony_ci{ 49162306a36Sopenharmony_ci return PX_DIGITAL_IN; 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cistatic inline int px_num(const struct echoaudio *chip) 49562306a36Sopenharmony_ci{ 49662306a36Sopenharmony_ci return PX_NUM; 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_cistatic inline int bx_digital_out(const struct echoaudio *chip) 50062306a36Sopenharmony_ci{ 50162306a36Sopenharmony_ci return BX_DIGITAL_OUT; 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic inline int bx_analog_in(const struct echoaudio *chip) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci return BX_ANALOG_IN; 50762306a36Sopenharmony_ci} 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistatic inline int bx_digital_in(const struct echoaudio *chip) 51062306a36Sopenharmony_ci{ 51162306a36Sopenharmony_ci return BX_DIGITAL_IN; 51262306a36Sopenharmony_ci} 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_cistatic inline int bx_num(const struct echoaudio *chip) 51562306a36Sopenharmony_ci{ 51662306a36Sopenharmony_ci return BX_NUM; 51762306a36Sopenharmony_ci} 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_cistatic inline int num_pipes_out(const struct echoaudio *chip) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci return px_analog_in(chip); 52262306a36Sopenharmony_ci} 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_cistatic inline int num_pipes_in(const struct echoaudio *chip) 52562306a36Sopenharmony_ci{ 52662306a36Sopenharmony_ci return px_num(chip) - px_analog_in(chip); 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistatic inline int num_busses_out(const struct echoaudio *chip) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci return bx_analog_in(chip); 53262306a36Sopenharmony_ci} 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_cistatic inline int num_busses_in(const struct echoaudio *chip) 53562306a36Sopenharmony_ci{ 53662306a36Sopenharmony_ci return bx_num(chip) - bx_analog_in(chip); 53762306a36Sopenharmony_ci} 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_cistatic inline int num_analog_busses_out(const struct echoaudio *chip) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci return bx_digital_out(chip); 54262306a36Sopenharmony_ci} 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_cistatic inline int num_analog_busses_in(const struct echoaudio *chip) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci return bx_digital_in(chip) - bx_analog_in(chip); 54762306a36Sopenharmony_ci} 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_cistatic inline int num_digital_busses_out(const struct echoaudio *chip) 55062306a36Sopenharmony_ci{ 55162306a36Sopenharmony_ci return num_busses_out(chip) - num_analog_busses_out(chip); 55262306a36Sopenharmony_ci} 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_cistatic inline int num_digital_busses_in(const struct echoaudio *chip) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci return num_busses_in(chip) - num_analog_busses_in(chip); 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci/* The monitor array is a one-dimensional array; compute the offset 56062306a36Sopenharmony_ci * into the array */ 56162306a36Sopenharmony_cistatic inline int monitor_index(const struct echoaudio *chip, int out, int in) 56262306a36Sopenharmony_ci{ 56362306a36Sopenharmony_ci return out * num_busses_in(chip) + in; 56462306a36Sopenharmony_ci} 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci#endif /* _ECHOAUDIO_H_ */ 567