/*
* Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
* Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.20
+ * Version: 0.0.21
*
* FEATURES currently supported:
* See ca0106_main.c for features.
* 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.
*
*
* This code was initally based on code from ALSA's emu10k1x.c which is:
* bit 9 0 = Mute / 1 = Analog out.
* bit 10 0 = Line-in / 1 = Mic-in.
* bit 11 0 = ? / 1 = ?
- * bit 12 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 = ?
#define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */
/* 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 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
-#define UART_A_DATA 0x6c /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_A_CMD 0x6d /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_B_DATA 0x6e /* Uart, Unknown. */
-#define UART_B_CMD 0x6f /* Uart, Unknown. */
+#define MIDI_UART_A_DATA 0x6c /* Midi Uart A Data */
+#define MIDI_UART_A_CMD 0x6d /* Midi Uart A Command/Status */
+#define MIDI_UART_B_DATA 0x6e /* Midi Uart B Data (currently unused) */
+#define MIDI_UART_B_CMD 0x6f /* Midi Uart B Command/Status (currently unused) */
+
+/* unique channel identifier for midi->channel */
+
+#define CA0106_MIDI_CHAN_A 0x1
+#define CA0106_MIDI_CHAN_B 0x2
+
+/* from mpu401 */
+
+#define CA0106_MIDI_INPUT_AVAIL 0x80
+#define CA0106_MIDI_OUTPUT_READY 0x40
+#define CA0106_MPU401_RESET 0xff
+#define CA0106_MPU401_ENTER_UART 0x3f
+#define CA0106_MPU401_ACK 0xfe
+
#define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */
/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0
* Rate Locked [20]
/* Causes interrupts based on timer intervals. */
#define SPI 0x7a /* SPI: Serial Interface Register */
#define I2C_A 0x7b /* I2C Address. 32 bit */
-#define I2C_0 0x7c /* I2C Data Port 0. 32 bit */
-#define I2C_1 0x7d /* I2C Data Port 1. 32 bit */
+#define I2C_D0 0x7c /* I2C Data Port 0. 32 bit */
+#define I2C_D1 0x7d /* I2C Data Port 1. 32 bit */
+//I2C values
+#define I2C_A_ADC_ADD_MASK 0x000000fe //The address is a 7 bit address
+#define I2C_A_ADC_RW_MASK 0x00000001 //bit mask for R/W
+#define I2C_A_ADC_TRANS_MASK 0x00000010 //Bit mask for I2c address DAC value
+#define I2C_A_ADC_ABORT_MASK 0x00000020 //Bit mask for I2C transaction abort flag
+#define I2C_A_ADC_LAST_MASK 0x00000040 //Bit mask for Last word transaction
+#define I2C_A_ADC_BYTE_MASK 0x00000080 //Bit mask for Byte Mode
+
+#define I2C_A_ADC_ADD 0x00000034 //This is the Device address for ADC
+#define I2C_A_ADC_READ 0x00000001 //To perform a read operation
+#define I2C_A_ADC_START 0x00000100 //Start I2C transaction
+#define I2C_A_ADC_ABORT 0x00000200 //I2C transaction abort
+#define I2C_A_ADC_LAST 0x00000400 //I2C last transaction
+#define I2C_A_ADC_BYTE 0x00000800 //I2C one byte mode
+
+#define I2C_D_ADC_REG_MASK 0xfe000000 //ADC address register
+#define I2C_D_ADC_DAT_MASK 0x01ff0000 //ADC data register
+
+#define ADC_TIMEOUT 0x00000007 //ADC Timeout Clock Disable
+#define ADC_IFC_CTRL 0x0000000b //ADC Interface Control
+#define ADC_MASTER 0x0000000c //ADC Master Mode Control
+#define ADC_POWER 0x0000000d //ADC PowerDown Control
+#define ADC_ATTEN_ADCL 0x0000000e //ADC Attenuation ADCL
+#define ADC_ATTEN_ADCR 0x0000000f //ADC Attenuation ADCR
+#define ADC_ALC_CTRL1 0x00000010 //ADC ALC Control 1
+#define ADC_ALC_CTRL2 0x00000011 //ADC ALC Control 2
+#define ADC_ALC_CTRL3 0x00000012 //ADC ALC Control 3
+#define ADC_NOISE_CTRL 0x00000013 //ADC Noise Gate Control
+#define ADC_LIMIT_CTRL 0x00000014 //ADC Limiter Control
+#define ADC_MUX 0x00000015 //ADC Mux offset
+#if 0
+/* FIXME: Not tested yet. */
+#define ADC_GAIN_MASK 0x000000ff //Mask for ADC Gain
+#define ADC_ZERODB 0x000000cf //Value to set ADC to 0dB
+#define ADC_MUTE_MASK 0x000000c0 //Mask for ADC mute
+#define ADC_MUTE 0x000000c0 //Value to mute ADC
+#define ADC_OSR 0x00000008 //Mask for ADC oversample rate select
+#define ADC_TIMEOUT_DISABLE 0x00000008 //Value and mask to disable Timeout clock
+#define ADC_HPF_DISABLE 0x00000100 //Value and mask to disable High pass filter
+#define ADC_TRANWIN_MASK 0x00000070 //Mask for Length of Transient Window
+#endif
+
+#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux
+#define ADC_MUX_MIC 0x00000002 //Value to select Mic at ADC Mux
+#define ADC_MUX_LINEIN 0x00000004 //Value to select LineIn at ADC Mux
+#define ADC_MUX_PHONE 0x00000001 //Value to select TAD at ADC Mux (Not used)
+#define ADC_MUX_AUX 0x00000008 //Value to select Aux at ADC Mux
#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
#define PCM_FRONT_CHANNEL 0
#define CONTROL_CENTER_LFE_CHANNEL 1
#define CONTROL_UNKNOWN_CHANNEL 2
-typedef struct snd_ca0106_channel ca0106_channel_t;
-typedef struct snd_ca0106 ca0106_t;
-typedef struct snd_ca0106_pcm ca0106_pcm_t;
+#include "ca_midi.h"
+
+struct snd_ca0106;
struct snd_ca0106_channel {
- ca0106_t *emu;
+ struct snd_ca0106 *emu;
int number;
int use;
- void (*interrupt)(ca0106_t *emu, ca0106_channel_t *channel);
- ca0106_pcm_t *epcm;
+ void (*interrupt)(struct snd_ca0106 *emu, struct snd_ca0106_channel *channel);
+ struct snd_ca0106_pcm *epcm;
};
struct snd_ca0106_pcm {
- ca0106_t *emu;
- snd_pcm_substream_t *substream;
+ struct snd_ca0106 *emu;
+ struct snd_pcm_substream *substream;
int channel_id;
unsigned short running;
};
+struct snd_ca0106_details {
+ u32 serial;
+ char * name;
+ int ac97;
+ int gpio_type;
+ int i2c_adc;
+ int spi_dac;
+};
+
// definition of the chip-specific record
struct snd_ca0106 {
- snd_card_t *card;
+ struct snd_card *card;
+ struct snd_ca0106_details *details;
struct pci_dev *pci;
unsigned long port;
spinlock_t emu_lock;
- ac97_t *ac97;
- snd_pcm_t *pcm;
+ struct snd_ac97 *ac97;
+ struct snd_pcm *pcm;
- ca0106_channel_t playback_channels[4];
- ca0106_channel_t capture_channels[4];
+ struct snd_ca0106_channel playback_channels[4];
+ struct snd_ca0106_channel capture_channels[4];
u32 spdif_bits[4]; /* s/pdif out setup */
int spdif_enable;
int capture_source;
+ int capture_mic_line_in;
struct snd_dma_buffer buffer;
+
+ struct snd_ca_midi midi;
+ struct snd_ca_midi midi2;
};
-int __devinit snd_ca0106_mixer(ca0106_t *emu);
-int __devinit snd_ca0106_proc_init(ca0106_t * emu);
+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);
-unsigned int snd_ca0106_ptr_read(ca0106_t * emu,
- unsigned int reg,
- unsigned int chn);
+int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
-void snd_ca0106_ptr_write(ca0106_t *emu,
- unsigned int reg,
- unsigned int chn,
- unsigned int data);