/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) 2004 James Courtier-Dutton <[email protected]> * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit * Version: 0.0.22 * * FEATURES currently supported: * See ca0106_main.c for features. * * Changelog: * Support interrupts per period. * Removed noise from Center/LFE channel when in Analog mode. * Rename and remove mixer controls. * 0.0.6 * Use separate card based DMA buffer for periods table list. * 0.0.7 * Change remove and rename ctrls into lists. * 0.0.8 * Try to fix capture sources. * 0.0.9 * Fix AC3 output. * Enable S32_LE format support. * 0.0.10 * Enable playback 48000 and 96000 rates. (Rates other that these do not work, even with "plug:front".) * 0.0.11 * Add Model name recognition. * 0.0.12 * Correct interrupt timing. interrupt at end of period, instead of in the middle of a playback period. * Remove redundent "voice" handling. * 0.0.13 * Single trigger call for multi channels. * 0.0.14 * Set limits based on what the sound card hardware can do. * playback periods_min=2, periods_max=8 * capture hw constraints require period_size = n * 64 bytes. * playback hw constraints require period_size = n * 64 bytes. * 0.0.15 * Separated ca0106.c into separate functional .c files. * 0.0.16 * Implement 192000 sample rate. * 0.0.17 * Add support for SB0410 and SB0413. * 0.0.18 * Modified Copyright message. * 0.0.19 * Added I2C and SPI registers. Filled in interrupt enable. * 0.0.20 * Added GPIO info for SB Live 24bit. * 0.0.21 * Implement support for Line-in capture on SB Live 24bit. * 0.0.22 * Add support for mute control on SB Live 24bit (cards w/ SPI DAC) * * This code was initially based on code from ALSA's emu10k1x.c which is: * Copyright (c) by Francisco Moraes <[email protected]> */ /************************************************************************************************/ /* PCI function 0 registers, address = <val> + PCIBASE0 */ /************************************************************************************************/ #define CA0106_PTR … /* NOTE: The CHANNELNUM and ADDRESS words can */ /* be modified independently of each other. */ /* CNL[1:0], ADDR[27:16] */ #define CA0106_DATA … /* DATA[31:0] */ #define CA0106_IPR … /* Clear pending interrupts by writing a 1 to */ /* the relevant bits and zero to the other bits */ #define IPR_MIDI_RX_B … #define IPR_MIDI_TX_B … #define IPR_SPDIF_IN_USER … #define IPR_SPDIF_OUT_USER … #define IPR_SPDIF_OUT_FRAME … #define IPR_SPI … #define IPR_I2C_EEPROM … #define IPR_I2C_DAC … #define IPR_AI … #define IPR_GPI … #define IPR_SRC_LOCKED … #define IPR_SPDIF_STATUS … #define IPR_TIMER2 … #define IPR_TIMER1 … #define IPR_MIDI_RX_A … #define IPR_MIDI_TX_A … #define IPR_PCI … #define CA0106_INTE … #define INTE_MIDI_RX_B … #define INTE_MIDI_TX_B … #define INTE_SPDIF_IN_USER … #define INTE_SPDIF_OUT_USER … #define INTE_SPDIF_OUT_FRAME … #define INTE_SPI … #define INTE_I2C_EEPROM … #define INTE_I2C_DAC … #define INTE_AI … #define INTE_GPI … #define INTE_SRC_LOCKED … #define INTE_SPDIF_STATUS … #define INTE_TIMER2 … #define INTE_TIMER1 … #define INTE_MIDI_RX_A … #define INTE_MIDI_TX_A … #define INTE_PCI … #define CA0106_UNKNOWN10 … #define CA0106_HCFG … /* 0x1000 causes AC3 to fails. It adds a dither bit. */ #define HCFG_STAC … #define HCFG_CAPTURE_I2S_BYPASS … #define HCFG_CAPTURE_SPDIF_BYPASS … #define HCFG_PLAYBACK_I2S_BYPASS … #define HCFG_FORCE_LOCK … #define HCFG_PLAYBACK_ATTENUATION … #define HCFG_PLAYBACK_DITHER … #define HCFG_PLAYBACK_S32_LE … #define HCFG_CAPTURE_S32_LE … #define HCFG_8_CHANNEL_PLAY … #define HCFG_8_CHANNEL_CAPTURE … #define HCFG_MONO … #define HCFG_I2S_OUTPUT … #define HCFG_AC97 … #define HCFG_LOCK_PLAYBACK_CACHE … /* NOTE: This should generally never be used. */ #define HCFG_LOCK_CAPTURE_CACHE … /* NOTE: This should generally never be used. */ #define HCFG_AUDIOENABLE … /* Should be set to 1 when the EMU10K1 is */ /* completely initialized. */ #define CA0106_GPIO … /* Here pins 0,1,2,3,4,,6 are output. 5,7 are input */ /* For the Audigy LS, pin 0 (or bit 8) controls the SPDIF/Analog jack. */ /* SB Live 24bit: * bit 8 0 = SPDIF in and out / 1 = Analog (Mic or Line)-in. * bit 9 0 = Mute / 1 = Analog out. * bit 10 0 = Line-in / 1 = Mic-in. * bit 11 0 = ? / 1 = ? * bit 12 0 = 48 Khz / 1 = 96 Khz Analog out on SB Live 24bit. * bit 13 0 = ? / 1 = ? * bit 14 0 = Mute / 1 = Analog out * bit 15 0 = ? / 1 = ? * Both bit 9 and bit 14 have to be set for analog sound to work on the SB Live 24bit. */ /* 8 general purpose programmable In/Out pins. * GPI [8:0] Read only. Default 0. * GPO [15:8] Default 0x9. (Default to SPDIF jack enabled for SPDIF) * GPO Enable [23:16] Default 0x0f. Setting a bit to 1, causes the pin to be an output pin. */ #define CA0106_AC97DATA … #define CA0106_AC97ADDRESS … /********************************************************************************************************/ /* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */ /********************************************************************************************************/ /* Initially all registers from 0x00 to 0x3f have zero contents. */ #define PLAYBACK_LIST_ADDR … /* One list entry: 4 bytes for DMA address, * 4 bytes for period_size << 16. * One list entry is 8 bytes long. * One list entry for each period in the buffer. */ /* ADDR[31:0], Default: 0x0 */ #define PLAYBACK_LIST_SIZE … /* SIZE[21:16], Default: 0x8 */ #define PLAYBACK_LIST_PTR … /* PTR[5:0], Default: 0x0 */ #define PLAYBACK_UNKNOWN3 … #define PLAYBACK_DMA_ADDR … /* DMA[31:0], Default: 0x0 */ #define PLAYBACK_PERIOD_SIZE … /* SIZE[31:16], Default: 0x0 */ #define PLAYBACK_POINTER … /* POINTER[15:0], Default: 0x0 */ #define PLAYBACK_PERIOD_END_ADDR … /* END_ADDR[15:0], FLAG[16] 0 = don't stop, 1 = stop */ #define PLAYBACK_FIFO_OFFSET_ADDRESS … /* Cache size valid [5:0] */ #define PLAYBACK_UNKNOWN9 … #define CAPTURE_DMA_ADDR … /* DMA[31:0], Default: 0x0 */ #define CAPTURE_BUFFER_SIZE … /* SIZE[31:16], Default: 0x0 */ #define CAPTURE_POINTER … /* POINTER[15:0], Default: 0x0 */ #define CAPTURE_FIFO_OFFSET_ADDRESS … /* Cache size valid [5:0] */ #define PLAYBACK_LAST_SAMPLE … /* 0x21 - 0x3f unused */ #define BASIC_INTERRUPT … /* Playback (0x1<<channel_id) */ /* Capture (0x100<<channel_id) */ /* Playback sample rate 96000 = 0x20000 */ /* Start Playback [3:0] (one bit per channel) * Start Capture [11:8] (one bit per channel) * Playback rate [23:16] (2 bits per channel) (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz) * Playback mixer in enable [27:24] (one bit per channel) * Playback mixer out enable [31:28] (one bit per channel) */ /* The Digital out jack is shared with the Center/LFE Analogue output. * The jack has 4 poles. I will call 1 - Tip, 2 - Next to 1, 3 - Next to 2, 4 - Next to 3 * For Analogue: 1 -> Center Speaker, 2 -> Sub Woofer, 3 -> Ground, 4 -> Ground * For Digital: 1 -> Front SPDIF, 2 -> Rear SPDIF, 3 -> Center/Subwoofer SPDIF, 4 -> Ground. * Standard 4 pole Video A/V cable with RCA outputs: 1 -> White, 2 -> Yellow, 3 -> Shield on all three, 4 -> Red. * So, from this you can see that you cannot use a Standard 4 pole Video A/V cable with the SB Audigy LS card. */ /* The Front SPDIF PCM gets mixed with samples from the AC97 codec, so can only work for Stereo PCM and not AC3/DTS * The Rear SPDIF can be used for Stereo PCM and also AC3/DTS * The Center/LFE SPDIF cannot be used for AC3/DTS, but can be used for Stereo PCM. * Summary: For ALSA we use the Rear channel for SPDIF Digital AC3/DTS output */ /* A standard 2 pole mono mini-jack to RCA plug can be used for SPDIF Stereo PCM output from the Front channel. * A standard 3 pole stereo mini-jack to 2 RCA plugs can be used for SPDIF AC3/DTS and Stereo PCM output utilising the Rear channel and just one of the RCA plugs. */ #define SPCS0 … #define SPCS1 … #define SPCS2 … #define SPCS3 … /* When Channel set to 0: */ #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 … /* When Channel set to 1: */ #define SPCS_WORD_LENGTH_MASK … #define SPCS_WORD_LENGTH_16 … #define SPCS_WORD_LENGTH_17 … #define SPCS_WORD_LENGTH_18 … #define SPCS_WORD_LENGTH_19 … #define SPCS_WORD_LENGTH_20A … #define SPCS_WORD_LENGTH_20 … #define SPCS_WORD_LENGTH_21 … #define SPCS_WORD_LENGTH_22 … #define SPCS_WORD_LENGTH_23 … #define SPCS_WORD_LENGTH_24 … #define SPCS_ORIGINAL_SAMPLE_RATE_MASK … #define SPCS_ORIGINAL_SAMPLE_RATE_NONE … #define SPCS_ORIGINAL_SAMPLE_RATE_16000 … #define SPCS_ORIGINAL_SAMPLE_RATE_RES1 … #define SPCS_ORIGINAL_SAMPLE_RATE_32000 … #define SPCS_ORIGINAL_SAMPLE_RATE_12000 … #define SPCS_ORIGINAL_SAMPLE_RATE_11025 … #define SPCS_ORIGINAL_SAMPLE_RATE_8000 … #define SPCS_ORIGINAL_SAMPLE_RATE_RES2 … #define SPCS_ORIGINAL_SAMPLE_RATE_192000 … #define SPCS_ORIGINAL_SAMPLE_RATE_24000 … #define SPCS_ORIGINAL_SAMPLE_RATE_96000 … #define SPCS_ORIGINAL_SAMPLE_RATE_48000 … #define SPCS_ORIGINAL_SAMPLE_RATE_176400 … #define SPCS_ORIGINAL_SAMPLE_RATE_22050 … #define SPCS_ORIGINAL_SAMPLE_RATE_88200 … #define SPCS_ORIGINAL_SAMPLE_RATE_44100 … #define SPDIF_SELECT1 … /* 0x100 - Front, 0x800 - Rear, 0x200 - Center/LFE. * But as the jack is shared, use 0xf00. * The Windows2000 driver uses 0x0000000f for both digital and analog. * 0xf00 introduces interesting noises onto the Center/LFE. * If you turn the volume up, you hear computer noise, * e.g. mouse moving, changing between app windows etc. * So, I am going to set this to 0x0000000f all the time now, * same as the windows driver does. * Use register SPDIF_SELECT2(0x72) to switch between SPDIF and Analog. */ /* When Channel = 0: * Wide SPDIF format [3:0] (one bit for each channel) (0=20bit, 1=24bit) * Tristate SPDIF Output [11:8] (one bit for each channel) (0=Not tristate, 1=Tristate) * SPDIF Bypass enable [19:16] (one bit for each channel) (0=Not bypass, 1=Bypass) */ /* When Channel = 1: * SPDIF 0 User data [7:0] * SPDIF 1 User data [15:8] * SPDIF 0 User data [23:16] * SPDIF 0 User data [31:24] * User data can be sent by using the SPDIF output frame pending and SPDIF output user bit interrupts. */ #define WATERMARK … #define SPDIF_INPUT_STATUS … #define CAPTURE_CACHE_DATA … #define CAPTURE_SOURCE … #define CAPTURE_SOURCE_CHANNEL0 … #define CAPTURE_SOURCE_CHANNEL1 … #define CAPTURE_SOURCE_CHANNEL2 … #define CAPTURE_SOURCE_CHANNEL3 … #define CAPTURE_SOURCE_RECORD_MAP … /* Record Map [7:0] (2 bits per channel) 0=mapped to channel 0, 1=mapped to channel 1, 2=mapped to channel2, 3=mapped to channel3 * Record source select for channel 0 [18:16] * Record source select for channel 1 [22:20] * Record source select for channel 2 [26:24] * Record source select for channel 3 [30:28] * 0 - SPDIF mixer output. * 1 - i2s mixer output. * 2 - SPDIF input. * 3 - i2s input. * 4 - AC97 capture. * 5 - SRC output. */ #define CAPTURE_VOLUME1 … #define CAPTURE_VOLUME2 … #define PLAYBACK_ROUTING1 … #define ROUTING1_REAR … #define ROUTING1_NULL … #define ROUTING1_CENTER_LFE … #define ROUTING1_FRONT … /* Channel_id's handle stereo channels. Channel X is a single mono channel */ /* Host is input from the PCI bus. */ /* Host channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7. * Host channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7. * Host channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7. * Host channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7. * Host channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7. * Host channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7. * Host channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7. * Host channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7. */ #define PLAYBACK_ROUTING2 … /* SRC is input from the capture inputs. */ /* SRC channel 0 [2:0] -> SPDIF Mixer/Router channel 0-7. * SRC channel 1 [6:4] -> SPDIF Mixer/Router channel 0-7. * SRC channel 2 [10:8] -> SPDIF Mixer/Router channel 0-7. * SRC channel 3 [14:12] -> SPDIF Mixer/Router channel 0-7. * SRC channel 4 [18:16] -> SPDIF Mixer/Router channel 0-7. * SRC channel 5 [22:20] -> SPDIF Mixer/Router channel 0-7. * SRC channel 6 [26:24] -> SPDIF Mixer/Router channel 0-7. * SRC channel 7 [30:28] -> SPDIF Mixer/Router channel 0-7. */ #define PLAYBACK_MUTE … /* SPDIF Mixer input control: * Invert SRC to SPDIF Mixer [7-0] (One bit per channel) * Invert Host to SPDIF Mixer [15:8] (One bit per channel) * SRC to SPDIF Mixer disable [23:16] (One bit per channel) * Host to SPDIF Mixer disable [31:24] (One bit per channel) */ #define PLAYBACK_VOLUME1 … /* PLAYBACK_VOLUME1 must be set to 30303030 for SPDIF AC3 Playback */ /* SPDIF mixer input volume. 0=12dB, 0x30=0dB, 0xFE=-51.5dB, 0xff=Mute */ /* One register for each of the 4 stereo streams. */ /* SRC Right volume [7:0] * SRC Left volume [15:8] * Host Right volume [23:16] * Host Left volume [31:24] */ #define CAPTURE_ROUTING1 … /* Similar to register 0x63, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */ #define CAPTURE_ROUTING2 … /* Similar to register 0x64, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */ #define CAPTURE_MUTE … /* Similar to register 0x65, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */ #define PLAYBACK_VOLUME2 … /* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */ #define UNKNOWN6b … #define MIDI_UART_A_DATA … #define MIDI_UART_A_CMD … #define MIDI_UART_B_DATA … #define MIDI_UART_B_CMD … /* unique channel identifier for midi->channel */ #define CA0106_MIDI_CHAN_A … #define CA0106_MIDI_CHAN_B … /* from mpu401 */ #define CA0106_MIDI_INPUT_AVAIL … #define CA0106_MIDI_OUTPUT_READY … #define CA0106_MPU401_RESET … #define CA0106_MPU401_ENTER_UART … #define CA0106_MPU401_ACK … #define SAMPLE_RATE_TRACKER_STATUS … /* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0 * Rate Locked [20] * SPDIF Locked [21] For SPDIF channel only. * Valid Audio [22] For SPDIF channel only. */ #define CAPTURE_CONTROL … /* Channel_id 0: 0x40c81000 must be changed to 0x40c80000 for SPDIF AC3 input or output. */ /* Channel_id 1: 0xffffffff(mute) 0x30303030(max) controls CAPTURE feedback into PLAYBACK. */ /* Sample rate output control register Channel=0 * Sample output rate [1:0] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz) * Sample input rate [3:2] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz) * SRC input source select [4] 0=Audio from digital mixer, 1=Audio from analog source. * Record rate [9:8] (0=48kHz, 1=Not available, 2=96kHz, 3=192Khz) * Record mixer output enable [12:10] * I2S input rate master mode [15:14] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz) * I2S output rate [17:16] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz) * I2S output source select [18] (0=Audio from host, 1=Audio from SRC) * Record mixer I2S enable [20:19] (enable/disable i2sin1 and i2sin0) * I2S output master clock select [21] (0=256*I2S output rate, 1=512*I2S output rate.) * I2S input master clock select [22] (0=256*I2S input rate, 1=512*I2S input rate.) * I2S input mode [23] (0=Slave, 1=Master) * SPDIF output rate [25:24] (0=48kHz, 1=44.1kHz, 2=96kHz, 3=192Khz) * SPDIF output source select [26] (0=host, 1=SRC) * Not used [27] * Record Source 0 input [29:28] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM) * Record Source 1 input [31:30] (0=SPDIF in, 1=I2S in, 2=AC97 Mic, 3=AC97 PCM) */ /* Sample rate output control register Channel=1 * I2S Input 0 volume Right [7:0] * I2S Input 0 volume Left [15:8] * I2S Input 1 volume Right [23:16] * I2S Input 1 volume Left [31:24] */ /* Sample rate output control register Channel=2 * SPDIF Input volume Right [23:16] * SPDIF Input volume Left [31:24] */ /* Sample rate output control register Channel=3 * No used */ #define SPDIF_SELECT2 … #define ROUTING2_FRONT_MASK … #define ROUTING2_CENTER_LFE_MASK … #define ROUTING2_REAR_MASK … /* Audio output control * AC97 output enable [5:0] * I2S output enable [19:16] * SPDIF output enable [27:24] */ #define UNKNOWN73 … #define CHIP_VERSION … #define EXTENDED_INT_MASK … /* Sets which Interrupts are enabled. */ /* 0x00000001 = Half period. Playback. * 0x00000010 = Full period. Playback. * 0x00000100 = Half buffer. Playback. * 0x00001000 = Full buffer. Playback. * 0x00010000 = Half buffer. Capture. * 0x00100000 = Full buffer. Capture. * Capture can only do 2 periods. * 0x01000000 = End audio. Playback. * 0x40000000 = Half buffer Playback,Caputre xrun. * 0x80000000 = Full buffer Playback,Caputre xrun. */ #define EXTENDED_INT … /* Shows which interrupts are active at the moment. */ /* Same bit layout as EXTENDED_INT_MASK */ #define COUNTER77 … #define COUNTER78 … #define EXTENDED_INT_TIMER … /* Causes interrupts based on timer intervals. */ #define SPI … #define I2C_A … #define I2C_D0 … #define I2C_D1 … //I2C values #define I2C_A_ADC_ADD_MASK … #define I2C_A_ADC_RW_MASK … #define I2C_A_ADC_TRANS_MASK … #define I2C_A_ADC_ABORT_MASK … #define I2C_A_ADC_LAST_MASK … #define I2C_A_ADC_BYTE_MASK … #define I2C_A_ADC_ADD … #define I2C_A_ADC_READ … #define I2C_A_ADC_START … #define I2C_A_ADC_ABORT … #define I2C_A_ADC_LAST … #define I2C_A_ADC_BYTE … #define I2C_D_ADC_REG_MASK … #define I2C_D_ADC_DAT_MASK … #define ADC_TIMEOUT … #define ADC_IFC_CTRL … #define ADC_MASTER … #define ADC_POWER … #define ADC_ATTEN_ADCL … #define ADC_ATTEN_ADCR … #define ADC_ALC_CTRL1 … #define ADC_ALC_CTRL2 … #define ADC_ALC_CTRL3 … #define ADC_NOISE_CTRL … #define ADC_LIMIT_CTRL … #define ADC_MUX … #if 0 /* FIXME: Not tested yet. */ #define ADC_GAIN_MASK … #define ADC_ZERODB … #define ADC_MUTE_MASK … #define ADC_MUTE … #define ADC_OSR … #define ADC_TIMEOUT_DISABLE … #define ADC_HPF_DISABLE … #define ADC_TRANWIN_MASK … #endif #define ADC_MUX_MASK … #define ADC_MUX_PHONE … #define ADC_MUX_MIC … #define ADC_MUX_LINEIN … #define ADC_MUX_AUX … #define SET_CHANNEL … #define PCM_FRONT_CHANNEL … #define PCM_REAR_CHANNEL … #define PCM_CENTER_LFE_CHANNEL … #define PCM_UNKNOWN_CHANNEL … #define CONTROL_FRONT_CHANNEL … #define CONTROL_REAR_CHANNEL … #define CONTROL_CENTER_LFE_CHANNEL … #define CONTROL_UNKNOWN_CHANNEL … /* Based on WM8768 Datasheet Rev 4.2 page 32 */ #define SPI_REG_MASK … #define SPI_REG_SHIFT … #define SPI_LDA1_REG … #define SPI_RDA1_REG … #define SPI_LDA2_REG … #define SPI_RDA2_REG … #define SPI_LDA3_REG … #define SPI_RDA3_REG … #define SPI_LDA4_REG … #define SPI_RDA4_REG … #define SPI_MASTDA_REG … #define SPI_DA_BIT_UPDATE … #define SPI_DA_BIT_0dB … #define SPI_DA_BIT_infdB … #define SPI_PL_REG … #define SPI_PL_BIT_L_M … #define SPI_PL_BIT_L_L … #define SPI_PL_BIT_L_R … #define SPI_PL_BIT_L_C … #define SPI_PL_BIT_R_M … #define SPI_PL_BIT_R_L … #define SPI_PL_BIT_R_R … #define SPI_PL_BIT_R_C … #define SPI_IZD_REG … #define SPI_IZD_BIT … #define SPI_FMT_REG … #define SPI_FMT_BIT_RJ … #define SPI_FMT_BIT_LJ … #define SPI_FMT_BIT_I2S … #define SPI_FMT_BIT_DSP … #define SPI_LRP_REG … #define SPI_LRP_BIT … #define SPI_BCP_REG … #define SPI_BCP_BIT … #define SPI_IWL_REG … #define SPI_IWL_BIT_16 … #define SPI_IWL_BIT_20 … #define SPI_IWL_BIT_24 … #define SPI_IWL_BIT_32 … #define SPI_MS_REG … #define SPI_MS_BIT … #define SPI_RATE_REG … #define SPI_RATE_BIT_128 … #define SPI_RATE_BIT_192 … #define SPI_RATE_BIT_256 … #define SPI_RATE_BIT_384 … #define SPI_RATE_BIT_512 … #define SPI_RATE_BIT_768 … /* They really do label the bit for the 4th channel "4" and not "3" */ #define SPI_DMUTE0_REG … #define SPI_DMUTE1_REG … #define SPI_DMUTE2_REG … #define SPI_DMUTE4_REG … #define SPI_DMUTE0_BIT … #define SPI_DMUTE1_BIT … #define SPI_DMUTE2_BIT … #define SPI_DMUTE4_BIT … #define SPI_PHASE0_REG … #define SPI_PHASE1_REG … #define SPI_PHASE2_REG … #define SPI_PHASE4_REG … #define SPI_PHASE0_BIT … #define SPI_PHASE1_BIT … #define SPI_PHASE2_BIT … #define SPI_PHASE4_BIT … #define SPI_PDWN_REG … #define SPI_PDWN_BIT … #define SPI_DACD0_REG … #define SPI_DACD1_REG … #define SPI_DACD2_REG … #define SPI_DACD4_REG … #define SPI_DACD0_BIT … #define SPI_DACD1_BIT … #define SPI_DACD2_BIT … #define SPI_DACD4_BIT … #define SPI_PWRDNALL_REG … #define SPI_PWRDNALL_BIT … #include "ca_midi.h" struct snd_ca0106; struct snd_ca0106_channel { … }; struct snd_ca0106_pcm { … }; struct snd_ca0106_details { … }; // definition of the chip-specific record struct snd_ca0106 { … }; int snd_ca0106_mixer(struct snd_ca0106 *emu); int snd_ca0106_proc_init(struct snd_ca0106 * emu); unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu, unsigned int reg, unsigned int chn); void snd_ca0106_ptr_write(struct snd_ca0106 *emu, unsigned int reg, unsigned int chn, unsigned int data); int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value); int snd_ca0106_spi_write(struct snd_ca0106 * emu, unsigned int data); #ifdef CONFIG_PM_SLEEP void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip); void snd_ca0106_mixer_resume(struct snd_ca0106 *chip); #else #define snd_ca0106_mixer_suspend … #define snd_ca0106_mixer_resume … #endif