Open Sound System |
Do you have problems with sound/audio application development? Don't panic! Click here for help! |
This file is part of Open Sound System.
Copyright (C) 4Front Technologies 1996-2008.
This this source file is released under GPL v2 license (no other versions). See the COPYING file included in the main directory of this source distribution for the license terms and conditions.
#include "oss_envy24ht_cfg.h" #define IN #define OUT #define UCHAR unsigned char #define PUCHAR UCHAR* #define BYTE unsigned char #define PBYTE BYTE* #define BOOLEAN unsigned char #define ULONG unsigned int #define PULONG ULONG* #define USHORT unsigned short #define PUSHORT USHORT* #define WORD USHORT #define PWORD PUSHORT
Default levels
#define WM_OUT_DEFAULT 0x7F #define WM_OUT_MAX 0x7F #define WM_INP_DEFAULT 0x0C /* for 0dB */ #define AC97_INP_DEFAULT 0x1f1f #define AC97_INP_MAX 0x1f #define REG_CCS 1 #define REG_MT 2 #define WM_MASTER_MODE_CNTRL 0 /* List of the WKN CCS Control Registers. */ #define WKN_CONTROL_REG 0x00 #define WKN_INT_MASK_REG 0x01 #define WKN_INT_STAT_REG 0x02 #define WKN_DMA_INT 0x10 #define WKN_UART_RECV 0x80 #define WKN_UART_TRAN 0x20 /* #define WKN_INDEX_REG 0x03 */ #define WKN_SYS_CONFIG 0x04 #define WKN_49MHZ 0x40 #define WKN_ACLINK_CONFIG 0x05 #define CODEC_AKM 0x80 #define WKN_I2S_CONFIG 0x06 #define WKN_SPDIF_CONFIG 0x07 #define SPDIF_ENABLE_MASK 0x00010000 /* #define WKN_AC97_INDEX 0x08 */ /* #define WKN_AC97_CMDSTAT 0x09 */ #define WKN_TX_QUE 0x0A #define WKN_RX_QUE 0x0B #define WKN_MIDI_PORT1_DATA_REG 0x0C #define WKN_MIDI_PORT1_CMD_REG 0x0D #define WKN_NMI_EXTSTAT_REG 0x0E #define WKN_I2C_DEVADDR 0x10 #define WKN_I2C_AKM 0x20 #define WKN_I2C_WRITE 0x01 #define WKN_I2C_READ 0x00 #define WKN_I2C_BYTEADDR 0x11 #define WKN_I2C_DATA 0x12 #define WKN_I2C_STATUS 0x13 #define WKN_I2C_BUSY 0x01 #define WKN_GPIO_DATA0 0x14 #define WKN_GPIO_DATA1 0x15 #define WKN_GPIO_DATA2 0x1E #define WKN_GPIO_WRT_MASK0 0x16 #define WKN_GPIO_WRT_MASK1 0x17 #define WKN_GPIO_WRT_MASK2 0x1F #define WKN_GPIO_DIR0 0x18 #define WKN_GPIO_DIR1 0x19 #define WKN_GPIO_DIR2 0x1A #define WKN_GPIO_DATA16 0x1E #define WKN_GPIO_WRT_MASK16 0x1F #define GPIO_DATA_ADR_MASK 0x000000FF #define GPIO_LD_DATA_H_MASK 0x00000100 #define GPIO_LD_DATA_L_MASK 0x00000200 #define GPIO_LD_ADR_MASK 0x00000400 #define GPIO_GO_MASK 0x00000800 #define GPIO_WM8770_CS_MASK 0x00001000 #define GPIO_INT_REST_MASK 0x00002000 #define GPIO_REMOTE_MASK 0x00004000 #define GPIO_HEADPHONE_MASK 0x00004000 #define GPIO_DIGITAL_SEL 0x00008000 #define GPIO_AC97_RESET_MASK 0x00010000 #define GPIO_SDA_TX_MASK 0x00020000 #define GPIO_SDA_MASK 0x00040000 #define GPIO_SCL_MASK 0x00080000 #define GPIO_WM8770_RS_MASK 0x00100000 #define GPIO_CS8415_CDTO_MASK 0x00200000 #define GPIO_CS8415_CS_MASK 0x00400000 #define WM_DAC1_VOL_CNTRL 0x00 #define WM_DAC2_VOL_CNTRL 0x02 #define WM_DAC3_VOL_CNTRL 0x04 #define WM_DAC4_VOL_CNTRL 0x06 #define WM_MASTER_VOL_CNTRL 0x08 #define WM_POWER_CNTRL 0x18 #define WM_ADC_GAIN_CNTRL 0x19 #define WM_ADC_INPUT_MX 0x1B #define WM_OUT12_SELECT 0x1C #define WM_OUT34_SELECT 0x1D #define CS_CONTROL_1 0x01 #define CS_CONTROL_2 0x02 #define CS_CLK_SRC_CNTRL 0x04 #define CS_SER_OUT_FORMAT 0x06 #define MT_SAMPLE_RATE_REG 0x01 #define MT_48KHZ 0x0 #define MT_24KHZ 0x01 #define MT_12KHZ 0x02 #define MT_9p6KHZ 0x03 #define MT_32KHZ 0x04 #define MT_16KHZ 0x05 #define MT_8KHZ 0x06 #define MT_96KHZ 0x07 #define MT_192KHZ 0x0E #define MT_64KHZ 0x0F #define MT_44p1KHZ 0x08 #define MT_22p05KHZ 0x09 #define MT_11p025KHZ 0x0A #define MT_88p2KHZ 0x0B #define MT_176p4KHZ 0x0C #define MT_DATA_FORMAT_REG 0x02 #define MT_128X 0x08 #define MT_INTR_MASK_REG 0x03 #define SRC_PDMA 0x00 #define SRC_PSDIN0_L 0x02 #define SRC_PSDIN0_R 0x03 #define SRC_SPDIN_L 0x06 #define SRC_SPDIN_R 0x07 #define SRC_MASK 0x07 static const UCHAR gWMRegister[] = { WM_DAC1_VOL_CNTRL, WM_DAC1_VOL_CNTRL + 1, WM_DAC2_VOL_CNTRL, WM_DAC2_VOL_CNTRL + 1, WM_DAC3_VOL_CNTRL, WM_DAC3_VOL_CNTRL + 1, WM_DAC4_VOL_CNTRL, WM_DAC4_VOL_CNTRL + 1, WM_MASTER_VOL_CNTRL, WM_MASTER_VOL_CNTRL + 1, WM_ADC_GAIN_CNTRL, WM_ADC_GAIN_CNTRL + 1 }; #define AC97_IDXREG_RESET 0x00 #define AC97_IDXREG_STEREO_OUT 0x02 #define AC97_IDXREG_MONO_OUT 0x06 #define AC97_IDXREG_PCBEEP 0x0A #define AC97_IDXREG_PHONE 0x0C #define AC97_IDXREG_MIC_IN 0x0E #define AC97_IDXREG_LINE_IN 0x10 #define AC97_IDXREG_CD_IN 0x12 #define AC97_IDXREG_VIDEO_IN 0x14 #define AC97_IDXREG_AUX_IN 0x16 #define AC97_IDXREG_PCM_OUT 0x18 #define AC97_IDXREG_RECORD_SELECT 0x1A #define AC97_IDXREG_RECORD_GAIN 0x1C #define AC97_IDXREG_GEN_PURPOSE 0x20 #define AC97_IDXREG_POWER_DOWN 0x26 #define AC97_IDXREG_TEST_CONTROL 0x5A #define AC97_IDXREG_VENDOR_RESV 0x7A #define AC97_IDXREG_VENDOR_ID1 0x7C #define AC97_IDXREG_VENDOR_ID2 0x7E /* AC97 register - AC97_IDXREG_RECORD_SELECT */ #define AC97_REC_SELECT_MIC 0x0000 #define AC97_REC_SELECT_LINEIN 0x0404 #define AC97_REC_SELECT_ST_MIX 0x0505
List of the Channel IDs
#define CH_MASTER_LEFT ((OUT_MASTER<<16)|CH_LEFT) #define CH_MASTER_RIGHT ((OUT_MASTER<<16)|CH_RIGHT) #define CH_MASTER_BOTH ((OUT_MASTER<<16)|CH_BOTH) #define CH_OUT12_LEFT ((OUT_12<<16)|CH_LEFT) #define CH_OUT12_RIGHT ((OUT_12<<16)|CH_RIGHT) #define CH_OUT12_BOTH ((OUT_12<<16)|CH_BOTH) #define CH_OUT34_LEFT ((OUT_34<<16)|CH_LEFT) #define CH_OUT34_RIGHT ((OUT_34<<16)|CH_RIGHT) #define CH_OUT34_BOTH ((OUT_34<<16)|CH_BOTH) #define CH_OUT56_LEFT ((OUT_56<<16)|CH_LEFT) #define CH_OUT56_RIGHT ((OUT_56<<16)|CH_RIGHT) #define CH_OUT56_BOTH ((OUT_56<<16)|CH_BOTH) #define CH_OUT78_LEFT ((OUT_78<<16)|CH_LEFT) #define CH_OUT78_RIGHT ((OUT_78<<16)|CH_RIGHT) #define CH_OUT78_BOTH ((OUT_78<<16)|CH_BOTH) #define CH_IN12_LEFT ((IN_12<<16)|CH_LEFT) #define CH_IN12_RIGHT ((IN_12<<16)|CH_RIGHT) #define CH_IN12_BOTH ((IN_12<<16)|CH_BOTH) #define CH_FRONT_BOTH CH_OUT12_BOTH #define CH_REAR_BOTH CH_OUT34_BOTH #define CH_CENTER CH_OUT56_LEFT #define CH_LFE CH_OUT56_RIGHT #define CH_BS_BOTH CH_OUT78_BOTH #define MAX_VOLUME 0x7F #define MIN_VOLUME 0x00 #define MAX_GAIN 0x1F #define MT_PLAY_REC_UNDOVR 0x01A #define MT_INTR_STATUS_REG 0x00 #define MT_INTR_MASK_REG 0x03 #define MT_SPDIF_REG 0x3C /* List of AC97 inputs */ #define AC97_CD 0 #define AC97_AUX 1 #define AC97_LINE 2 #define AC97_MIC 3 #define AC97_PHONO 4 #define AC97_LINE2 5 #define AC97_COUNT 6 /* Must match devc->m_AC97Volume definition in envy24ht.h */ /* Channel def */ #define CH_LEFT 0x00000001 #define CH_RIGHT 0x00000002 #define CH_BOTH (CH_LEFT|CH_RIGHT) #define CH_NOP 0xFFFFFFFF
List of inputs
#define ADC_CD 0 #define ADC_AUX 1 #define ADC_LINE 2 #define ADC_MIC 3 #define ADC_PHONO 4 #define ADC_WTL 5 #define ADC_LINE_REAR 6 #define ADC_STEREO_MIX 7 #define ADC_COUNT 8 /* Must match the size of m_ADCVolume */
List of Lines
#define LINE_OUT_1L 0x00000000 #define LINE_OUT_1R 0x00000001 #define LINE_OUT_2L 0x00000002 #define LINE_OUT_2R 0x00000003 #define LINE_OUT_3L 0x00000004 #define LINE_OUT_3R 0x00000005 #define LINE_OUT_4L 0x00000006 #define LINE_OUT_4R 0x00000007 #define LINE_MASTER 0x00000008 #define LINE_MASTER_ 0x00000009 #define LINE_GAIN_L 0x0000000a #define LINE_GAIN_R 0x0000000b #define LINE_S_NUM 0x0000000c /* 12 - Should match devc->m_fDACMute size */
List of Stereo Lines
#define OUT_12 0x00000000 #define OUT_34 0x00000001 #define OUT_56 0x00000002 #define OUT_78 0x00000003 #define OUT_MASTER 0x00000004 #define IN_12 0x00000005 #define NUM_LINES 0x00000006
SPDIF Out Source
enum { DIGOUT_DIG_IN = 0, DIGOUT_ANA_IN, DIGOUT_WAVE };
Digital IN Source
enum { DIGIN_OPTICAL = 0, DIGIN_COAX, DIGIN_CD_IN };
Out-0 Source
enum { SRC_DMA1 = 0, SRC_PSDIN0, SRC_SPDIN };
Line IN Source (Aureon 7.1 Universe only)
#define SRC_AUX 0 #define SRC_WTL 1 #define SRC_LINE_REAR 2 #define SRC_GROUND 3
Clock Source
enum { ICE_INTERNAL_CLOCK = 0, ICE_SPDIF_CLOCK };
Function of Frontjack
enum { FRONT_JACK_LINEIN = 0, FRONT_JACK_HEADPHONE }; enum MUX_TP_PIN { CD_IN_MUX_TP_PIN = 1, LINE_IN_MUX_TP_PIN, AUX_IN_MUX_TP_PIN, PHONO_IN_MUX_PIN, LINE2_IN_MUX_PIN, MIC_IN_MUX_TP_PIN, DIG_IN_MUX_TP_PIN, STEREO_MIX_MUX_TP_PIN }; #define AUREON_REMOTE_CNTRL 0x32 /* #define AUREON_REMOTE_ID 0x0016 */ #define AUREON_REMOTE_ID 0x6B86 #define AUREON_PCA_BASEBOARD 0x40 #define MT_LOOPBK_CONTROL 0x02C #define MT_LOOPBK_CONTROL_DAC_REG 0x030 #define MT_LOOPBK_CONTROL_SPDIF_OUT_REG 0x032 #define WIDTH_BYTE 1 #define WIDTH_WORD 2 #define WIDTH_DWORD 4 #define BITS_ON 0x10 #define BITS_OFF 0x00 #define TOGGLE_ON 0x20 #define CRITSEC_ON 0x00000001 #define WIDTH_MASK 0x0f #include "spdif.h" #include "envy24ht.h"
Function : WritePort ------------------------------------------------------------------------------- Description : Parameters : dwRegType -> : dwIndex -> : dwValue -> : dwWidth -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void WritePort (envy24ht_devc * devc, IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwValue, IN ULONG dwWidth) { oss_native_word pPort = devc->ccs_base; switch (dwRegType) { case REG_CCS: pPort = devc->ccs_base; break; case REG_MT: pPort = devc->mt_base; break; } /* registers are addressible in byte, word or dword */ switch (dwWidth) { case WIDTH_BYTE: OUTB (devc->osdev, dwValue, pPort + dwIndex); break; case WIDTH_WORD: OUTW (devc->osdev, dwValue, pPort + dwIndex); break; case WIDTH_DWORD: OUTL (devc->osdev, dwValue, pPort + dwIndex); break; } }
Function : ReadPort ------------------------------------------------------------------------------- Description : Returns : -> Parameters : IN ULONG dwWidth -> IN ULONG dwWidth ------------------------------------------------------------------------------- Notes : =============================================================================
static ULONG ReadPort (envy24ht_devc * devc, IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwWidth) { oss_native_word pPort = devc->ccs_base; ULONG dwData = 0; switch (dwRegType) { case REG_CCS: pPort = devc->ccs_base; break; case REG_MT: pPort = devc->mt_base; break; } /* all other registers are addressible in byte, word or dword */ switch (dwWidth) { case WIDTH_BYTE: dwData = INB (devc->osdev, pPort + dwIndex); break; case WIDTH_WORD: dwData = INW (devc->osdev, pPort + dwIndex); break; case WIDTH_DWORD: dwData = INL (devc->osdev, pPort + dwIndex); break; } return dwData; }
Function : ReadModifyWritePort ------------------------------------------------------------------------------- Description : Returns : VOID -> Parameters : wRegType -> : dwMask -> : dwControl -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void ReadModifyWritePort (envy24ht_devc * devc, IN ULONG dwRegType, IN ULONG dwIndex, IN ULONG dwMask, IN ULONG dwControl /* dwControl: */ /* bit[3:0] : data width, 1 => byte, 2 => word, 4 => dword */ /* bit[4] : 1 => turn on bit(s); 0 => turn off bit(s) */ /* bit[5] : 1 => toggle bit(s) */ /* bit[6] : 1 => turn on Hw access critical section */ ) { ULONG dwValue; ULONG dwWidth; oss_native_word flags; dwWidth = dwControl & WIDTH_MASK; if (dwControl & CRITSEC_ON) { MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags); } dwValue = ReadPort (devc, dwRegType, dwIndex, dwWidth); /* see whether we should turn on or off the bit(s) */ if (dwControl & BITS_ON) dwValue |= dwMask; else dwValue &= ~dwMask; WritePort (devc, dwRegType, dwIndex, dwValue, dwWidth); /* see if we need to toggle the bit(s) */ if (dwControl & TOGGLE_ON) { dwValue ^= dwMask; WritePort (devc, dwRegType, dwIndex, dwValue, dwWidth); } if (dwControl & CRITSEC_ON) { MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags); } }
Function : WriteGPIO ------------------------------------------------------------------------------- Description : Writes masked Data to GPIO Port Parameters : IN ULONG Data -> : IN ULONG Mask -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void WriteGPIO (envy24ht_devc * devc, IN ULONG Data, IN ULONG Mask) { USHORT MaskL; UCHAR MaskH; USHORT DataL; UCHAR DataH; /* Do the masking. */ MaskL = (USHORT) Mask; MaskH = (UCHAR) (Mask >> 16); DataL = (USHORT) Data; DataH = (UCHAR) (Data >> 16); devc->gpio_shadow_L &= ~MaskL; devc->gpio_shadow_H &= ~MaskH; devc->gpio_shadow_L |= (MaskL & DataL); devc->gpio_shadow_H |= (MaskH & DataH); /* Write Data */ WritePort (devc, REG_CCS, WKN_GPIO_DATA0, devc->gpio_shadow_L, WIDTH_WORD); WritePort (devc, REG_CCS, WKN_GPIO_DATA2, devc->gpio_shadow_H, WIDTH_BYTE); }
Function : SetSDADir ------------------------------------------------------------------------------- Description : Returns : void -> Parameters : IN BOOLEAN fOut -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetSDADir (envy24ht_devc * devc, IN BOOLEAN fOut) { if (fOut) { /* Set GPIO 18 direction to output */ WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDF, WIDTH_BYTE); /* Turn IIC logic to SDA write */ WriteGPIO (devc, GPIO_SDA_TX_MASK, GPIO_SDA_TX_MASK); } else { WriteGPIO (devc, 0, GPIO_SDA_TX_MASK); /* Direction "Read" for GPIO 18 (SDA) */ WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDB, WIDTH_BYTE); } }
Function : SetSDA ------------------------------------------------------------------------------- Description : Parameters : BOOLEAN fSet ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetSDA (envy24ht_devc * devc, BOOLEAN fSet) { /* Set GPIO 18 direction to output */ SetSDADir (devc, 1); /* Write SDA */ WriteGPIO (devc, fSet ? GPIO_SDA_MASK : 0, GPIO_SDA_MASK); }
Function : GetSDA ------------------------------------------------------------------------------- Description : Returns : UCHAR -> ------------------------------------------------------------------------------- Notes : =============================================================================
static UCHAR GetSDA (envy24ht_devc * devc) { UCHAR ulData; /* Turn IIC logic to SDA read */ SetSDADir (devc, 0); ulData = ((ReadPort (devc, REG_CCS, WKN_GPIO_DATA2, WIDTH_BYTE) & 0x04) == 0x04); return ulData; }
Function : SetIIC ------------------------------------------------------------------------------- Description : Parameters : IN BOOLEAN fSDA -> : IN BOOLEAN fCLK -> : IN ULONG ulSleep -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetIIC (envy24ht_devc * devc, IN BOOLEAN fSDA, IN BOOLEAN fCLK, IN ULONG ulSleep) { SetSDA (devc, fSDA); if (fCLK) WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK); else WriteGPIO (devc, 0, GPIO_SCL_MASK); if (ulSleep) oss_udelay (ulSleep); }
Function : IICStart ------------------------------------------------------------------------------- Description : Parameters : ULONG ulSleep -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void IICStart (envy24ht_devc * devc, ULONG ulSleep) { /* falling edge of SDA while SCL is HIGH */ SetIIC (devc, 1, 1, ulSleep); SetIIC (devc, 0, 1, ulSleep); }
Function : IICStop ------------------------------------------------------------------------------- Description : Parameters : ULONG ulSleep -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void IICStop (envy24ht_devc * devc, ULONG ulSleep) { /* rising edge of SDA while SCL is HIGH */ SetIIC (devc, 0, 1, ulSleep); SetIIC (devc, 1, 1, ulSleep); /* Reset Lines (No IIC requirement, but for prevent conflicts with SPI) */ /*SetIIC(0,0,ulSleep); */ }
Function : IICSendByte ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : CHAR bByte -> : ULONG ulSleep -> ------------------------------------------------------------------------------- Notes : =============================================================================
static UCHAR IICSendByte (envy24ht_devc * devc, IN UCHAR bByte, IN ULONG ulSleep) { UCHAR bDataBit, bAck; int i; for (i = 7; i >= 0; i--) /* send byte (MSB first) */ { bDataBit = (bByte >> i) & 0x01; SetIIC (devc, bDataBit, 0, ulSleep); SetIIC (devc, bDataBit, 1, ulSleep); SetIIC (devc, bDataBit, 0, ulSleep); } /* end for i */ SetIIC (devc, 1, 0, ulSleep); /* This is neccesary for PLC */ SetSDADir (devc, 0); /* Get acknowledge */ SetIIC (devc, 1, 1, ulSleep); bAck = GetSDA (devc); /*if (fAddress) */ /* SetIIC(devc, 1,0,ulSleep); */ /* else */ /* this is a start condition but never mind */ SetIIC (devc, 0, 0, ulSleep); return (!bAck); /* bAck = 0 --> success */ } #if 0
Function : IICReceiveByte ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : CHAR fLastByte -> : ULONG ulSleep -> ------------------------------------------------------------------------------- Notes : =============================================================================
static UCHAR IICReceiveByte (envy24ht_devc * devc, UCHAR fLastByte, ULONG ulSleep) { UCHAR bRead = 0; int i; for (i = 7; i >= 0; i--) { SetIIC (devc, 1, 0, ulSleep); SetIIC (devc, 1, 1, ulSleep); bRead <<= 1; bRead += GetSDA (devc); } /* -> no acknowledge for last received byte */ SetIIC (devc, fLastByte, 0, ulSleep); /* SDA = HIGH for last byte */ SetIIC (devc, fLastByte, 1, ulSleep); SetIIC (devc, fLastByte, 0, ulSleep); /* clock -> LOW */ return bRead; } #endif
Function : IICWriteBuffer ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : CHAR bIicAddress -> : PUCHAR pbByte -> : USHORT nNoBytes -> : ULONG ulSleep -> ------------------------------------------------------------------------------- Notes : =============================================================================
static UCHAR IICWriteBuffer (envy24ht_devc * devc, UCHAR bIicAddress, PUCHAR pbByte, USHORT nNoBytes, ULONG ulSleep) { IICStart (devc, ulSleep); /* send IIC address and data byte */ if (!IICSendByte (devc, bIicAddress, ulSleep)) goto FAILED; /* send buffer */ do { if (!IICSendByte (devc, *pbByte, ulSleep)) goto FAILED; /* got no acknowledge */ pbByte++; nNoBytes--; } while (nNoBytes); IICStop (devc, ulSleep); return 1; FAILED: IICStop (devc, ulSleep); return 0; }
Function : WriteCS8415 ------------------------------------------------------------------------------- Description : Parameters : IN UCHAR Register -> : IN UCHAR Value -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void WriteCS8415 (envy24ht_devc * devc, IN UCHAR Register, IN UCHAR Value) { ULONG i; BOOLEAN fData; ULONG ulCmd; ULONG ulCount; /* m_pAdapter->HwEnter(); *//* TODO */ /* Clock low to prevent IIC Startcondition */ WriteGPIO (devc, 0, GPIO_SCL_MASK); SetSDA (devc, 0); /* Chip select (CS low) */ WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK); /* format buffer */ ulCmd = 0x200000 + /* chip address + R/W */ (((ULONG) Register) << 8) + /* register address */ Value; /* Value */ ulCmd <<= 8; ulCount = 24; /* (AddressOnly) ? 16:24; */ for (i = 0; i < ulCount; i++) { fData = (ulCmd & 0x80000000) ? 1 : 0; /* CCLK -> low */ WriteGPIO (devc, 0, GPIO_SCL_MASK); oss_udelay (3); /* CDTI -> Set data */ SetSDA (devc, fData); oss_udelay (3); /* CCLK -> high */ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK); ulCmd <<= 1; } WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CCLK -> low */ /* Chip deselect (CS high) */ WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK); /* m_pAdapter->HwLeave(); *//* TODO */ } #if 0
Function : ReadCS8415 ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : IN UCHAR Register -> ------------------------------------------------------------------------------- Notes : =============================================================================
/*ARGSUSED*/ static UCHAR ReadCS8415 (envy24ht_devc * devc, IN UCHAR Register) { ULONG i; BOOLEAN fData; UCHAR cValue = 0; USHORT wCmd; /* m_pAdapter->HwEnter(); *//* TODO */ /* Clock low to prevent IIC Startcondition */ WriteGPIO (devc, 0, GPIO_SCL_MASK); SetSDA (devc, 0); /* Chip select (CS low) */ WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK); /* Set GPIO21 to read direction */ WritePort (devc, REG_CCS, WKN_GPIO_DIR2, 0xDF, WIDTH_BYTE); wCmd = 0x2100; /* + *//* chip address + R/W */ /*(((USHORT)Register) << 8); *//* register address */ for (i = 0; i < 16; i++) { fData = (wCmd & 0x8000) ? 1 : 0; /* CCLK -> low */ WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CDTI -> Set data */ SetSDA (devc, fData); oss_udelay (3); /* CCLK -> high */ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK); wCmd <<= 1; if (i > 7) { /* Read CDTO */ cValue <<= 1; cValue += ((ReadPort (devc, REG_CCS, WKN_GPIO_DATA2, WIDTH_BYTE) & 0x20) == 0x20); } } WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CCLK -> low */ /* Chip deselect (CS high) */ WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK); /* m_pAdapter->HwLeave(); *//* TODO */ return cValue; } #endif
Definition of PCA I/Os
typedef union tagPCA_CFG { unsigned char cReg; struct { unsigned char P00_SourceSel:2; /* LineIN Selector */ /* 00 -> Aux */ /* 01 -> Wavetable */ /* 11 -> LineIN Rear */ unsigned char P02_DigSel:1; /* DigitalIN Selector */ /* 0 -> Coax */ /* 1 -> Optical */ unsigned char P03_LineLED:1; /* LineLED */ /* 0 -> Off */ /* 1 -> On */ unsigned char P04_unused:4; /* unused */ } Bits; } PCA_CFG;
Function : WritePCA ------------------------------------------------------------------------------- Description : Returns : NTSTATUS -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void WritePCA (envy24ht_devc * devc) { PCA_CFG tCFG; BYTE bByte[2]; tCFG.cReg = 0; switch (devc->m_LineInSource) { case SRC_AUX: tCFG.Bits.P00_SourceSel = 0; break; case SRC_WTL: tCFG.Bits.P00_SourceSel = 1; break; case SRC_LINE_REAR: tCFG.Bits.P00_SourceSel = 2; break; case SRC_GROUND: tCFG.Bits.P00_SourceSel = 3; break; } /* Switch LineLED when Line is selected for record */ if (devc->m_ADCIndex == ADC_LINE) tCFG.Bits.P03_LineLED = 1; if (devc->m_DigInSource == DIGIN_OPTICAL) tCFG.Bits.P02_DigSel = 1; /* Set all I/Os to Output */ bByte[0] = 3; bByte[1] = 0; IICWriteBuffer (devc, AUREON_PCA_BASEBOARD, bByte, 2, 30); /* Write config */ bByte[0] = 0x01; bByte[1] = tCFG.cReg; IICWriteBuffer (devc, AUREON_PCA_BASEBOARD, bByte, 2, 30); }
Function : SetDigInSource ------------------------------------------------------------------------------- Description : Returns : void -> Parameters : IN ULONG Source -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetDigInSource (envy24ht_devc * devc, IN ULONG Source) { switch (Source) { case DIGIN_OPTICAL: case DIGIN_COAX: WriteCS8415 (devc, CS_CONTROL_2, 0x01); break; case DIGIN_CD_IN: WriteCS8415 (devc, CS_CONTROL_2, 0x00); break; } devc->m_DigInSource = Source; WritePCA (devc); }
Function : SetOUT0Source ------------------------------------------------------------------------------- Description : Returns : void -> Parameters : IN ULONG Source -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetOUT0Source (envy24ht_devc * devc, IN ULONG Source) { ULONG ulShiftL, ulShiftR; ULONG aulShiftL[] = { 0, 8, 11, 14, 17 }; ULONG aulShiftR[] = { 3, 20, 23, 26, 29 }; ULONG ulSourceL, ulSourceR; int i; /* No DigMonitor when Clock is internal */ if ((devc->m_ClockSource == ICE_INTERNAL_CLOCK) && (Source == SRC_SPDIN)) return; for (i = 0; i < 5; i++) { ulShiftL = aulShiftL[i]; ulShiftR = aulShiftR[i]; switch (Source) { case SRC_DMA1: ulSourceL = SRC_PDMA; ulSourceR = SRC_PDMA; break; case SRC_PSDIN0: ulSourceL = SRC_PSDIN0_L; ulSourceR = SRC_PSDIN0_R; break; case SRC_SPDIN: ulSourceL = SRC_SPDIN_L; ulSourceR = SRC_SPDIN_R; break; default: /* Do nothing */ return; } /* First reset all relevant bits */ ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL, SRC_MASK << ulShiftL, WIDTH_DWORD | BITS_OFF); ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL, SRC_MASK << ulShiftR, WIDTH_DWORD | BITS_OFF); /* ..and set routing mask */ ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL, ulSourceL << ulShiftL, WIDTH_DWORD | BITS_ON); ReadModifyWritePort (devc, REG_MT, MT_LOOPBK_CONTROL, ulSourceR << ulShiftR, WIDTH_DWORD | BITS_ON); } devc->m_Out0Source = Source; } static void SetADCMux (envy24ht_devc * devc, IN ULONG Value);
Function : SetLineSource ------------------------------------------------------------------------------- Description : Parameters : IN ULONG Source -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetLineSource (envy24ht_devc * devc, IN ULONG Source) { switch (Source) { case SRC_AUX: devc->m_AuxMux = 0x00; break; case SRC_WTL: devc->m_AuxMux = 0x44; break; case SRC_LINE_REAR: devc->m_AuxMux = 0x66; break; } /* Update ADCMux */ SetADCMux (devc, devc->m_ADCMux); devc->m_LineInSource = Source; WritePCA (devc); }
Function : SetClockSource ------------------------------------------------------------------------------- Description : Parameters : IN ULONG ClockSource -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetClockSource (envy24ht_devc * devc, IN ULONG ClockSource) { if (ClockSource == ICE_INTERNAL_CLOCK) { ReadModifyWritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, 0x10, WIDTH_BYTE | BITS_OFF); /* Disable DigMonitor to avoid noisy output */ if (devc->m_Out0Source == SRC_SPDIN) SetOUT0Source (devc, SRC_DMA1); } else { ReadModifyWritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, 0x10, WIDTH_BYTE | BITS_ON); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); } devc->m_ClockSource = ClockSource; }
Function : ResetGPIO ------------------------------------------------------------------------------- Description : Returns : void -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void ResetGPIO (envy24ht_devc * devc) { /* Enable all lower GPIOs */ WritePort (devc, REG_CCS, WKN_GPIO_WRT_MASK0, 0x0, WIDTH_WORD); /* Enable all upper GPIOs */ WritePort (devc, REG_CCS, WKN_GPIO_WRT_MASK2, 0x0, WIDTH_BYTE); /* Set GPIO direction */ if (devc->subvendor == SSID_AUREON_UNIVERSE) { /* -> all output except GPIO_CS8415_CDTO_MASK */ /* and GPIO_REMOTE_MASK */ WritePort (devc, REG_CCS, WKN_GPIO_DIR0, ~(GPIO_CS8415_CDTO_MASK | GPIO_REMOTE_MASK), WIDTH_DWORD); } else { /* All output except GPIO_CS8415_CDTO_MASK */ WritePort (devc, REG_CCS, WKN_GPIO_DIR0, ~GPIO_CS8415_CDTO_MASK, WIDTH_DWORD); } oss_udelay (100);
Reset AC97 Interface -----------------------------------------------------------------------------
WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK); oss_udelay (3); WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK); oss_udelay (3); WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK);
Enable Remote-Control Interrupts -----------------------------------------------------------------------------
WriteGPIO (devc, GPIO_INT_REST_MASK, GPIO_INT_REST_MASK); /* Select optical input */ /* WriteGPIO(devc, GPIO_DIGITAL_SEL, 0); */ }
Function : SetSPDIFConfig ------------------------------------------------------------------------------- Description : Returns : void -> Parameters : IN ULONG Config -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetSPDIFConfig (envy24ht_devc * devc, IN ULONG Config) { ReadModifyWritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x80, WIDTH_BYTE | BITS_OFF); if (Config & SPDIF_ENABLE_MASK) { devc->m_f1724SPDIF = 1; } else { devc->m_f1724SPDIF = 0; } /* Reset SPDIF Config */ ReadModifyWritePort (devc, REG_MT, MT_SPDIF_REG, 0x000F, WIDTH_WORD | BITS_OFF); /* Set new Config */ ReadModifyWritePort (devc, REG_MT, MT_SPDIF_REG, Config & 0xFFFF, WIDTH_WORD | BITS_ON); devc->m_SPDIFConfig = Config; if (devc->m_f1724SPDIF) ReadModifyWritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x80, WIDTH_BYTE | BITS_ON); /* Force saving of registers */ /* devc->m_pAdapter->SetDirty(); *//* TODO */ }
Function : SetFrontjack ------------------------------------------------------------------------------- Description : Parameters : IN ULONG Frontjack -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetFrontjack (envy24ht_devc * devc, IN ULONG Frontjack) { switch (Frontjack) { case FRONT_JACK_LINEIN: WriteGPIO (devc, 0, GPIO_HEADPHONE_MASK); break; case FRONT_JACK_HEADPHONE: WriteGPIO (devc, GPIO_HEADPHONE_MASK, GPIO_HEADPHONE_MASK); break; } devc->m_Frontjack = Frontjack; /* Force saving of registers */ /* devc->m_pAdapter->SetDirty(); *//* TODO */ }
Function : Init1724 ------------------------------------------------------------------------------- Description : Returns : void -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void Init1724 (envy24ht_devc * devc) { /* System Config: 4 DACs, one ADC & SPDIF, MPU enabled, 24,576Mhz crystal */ /* WritePort(REG_CCS, WKN_SYS_CONFIG, 0x2B, WIDTH_BYTE); */ /* CL_NOTE: New Setings */ /* System Config: 4 DACs, one ADC & SPDIF, MPU disabled, 24,576Mhz crystal */ WritePort (devc, REG_CCS, WKN_SYS_CONFIG, 0x0B, WIDTH_BYTE); /* Config I2S Interface */ WritePort (devc, REG_CCS, WKN_ACLINK_CONFIG, 0x80, WIDTH_BYTE); WritePort (devc, REG_CCS, WKN_I2S_CONFIG, 0xF9, WIDTH_BYTE); WritePort (devc, REG_CCS, WKN_SPDIF_CONFIG, 0x83, WIDTH_BYTE); /* Config Interrupt behaviour */ WritePort (devc, REG_MT, MT_PLAY_REC_UNDOVR, 0, WIDTH_BYTE); WritePort (devc, REG_MT, MT_INTR_STATUS_REG, 0, WIDTH_BYTE); WritePort (devc, REG_MT, MT_INTR_MASK_REG, 0xFF, WIDTH_BYTE); WritePort (devc, REG_CCS, WKN_INT_STAT_REG, 0, WIDTH_BYTE); WritePort (devc, REG_CCS, WKN_INT_MASK_REG, 0xFE, WIDTH_BYTE); SetSPDIFConfig (devc, 0); /* SetSDPIFSource(devc, DIGOUT_WAVE); */ SetDigInSource (devc, DIGIN_OPTICAL); SetFrontjack (devc, FRONT_JACK_LINEIN); }
Function : WriteWM8770 ------------------------------------------------------------------------------- Description : Parameters : IN UCHAR Register -> : IN UCHAR Value -> ------------------------------------------------------------------------------- Notes : =============================================================================
void WriteWM8770 (envy24ht_devc * devc, IN UCHAR Register, IN USHORT Value) { int i; BOOLEAN fData; USHORT wCmd; /* KIRQL OldIrql; */ /* m_pAdapter->HwEnter(); */ /* KeAcquireSpinLock (&m_SPILock,&OldIrql); */ /* Clock low to prevent IIC Startcondition */ WriteGPIO (devc, 0, GPIO_SCL_MASK); SetSDA (devc, 0); /* Chip select (CS low) */ WriteGPIO (devc, 0, GPIO_WM8770_CS_MASK); /* format buffer */ wCmd = (((USHORT) Register) << 9) + Value; for (i = 0; i < 16; i++) { fData = (wCmd & 0x8000) ? 1 : 0; /* CCLK -> low */ WriteGPIO (devc, 0, GPIO_SCL_MASK); oss_udelay (3); /* CDTI -> Set data */ SetSDA (devc, fData); oss_udelay (3); /* CCLK -> high */ WriteGPIO (devc, GPIO_SCL_MASK, GPIO_SCL_MASK); wCmd <<= 1; } WriteGPIO (devc, 0, GPIO_SCL_MASK); /* CCLK -> low */ /* Chip deselect */ WriteGPIO (devc, GPIO_WM8770_CS_MASK, GPIO_WM8770_CS_MASK); }
Function : SetVolReg ------------------------------------------------------------------------------- Description : Parameters : IN ULONG LineIdx -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetVolReg (envy24ht_devc * devc, IN ULONG LineIdx) { int iVol, ChnlVol; ChnlVol = devc->m_DACVolume[LineIdx]; /* See if we want to mute anything */ if (devc->m_fDACMute[LineIdx] || devc->m_fDACMute[LINE_MASTER]) { WriteWM8770 (devc, gWMRegister[LineIdx], 0x100); return; } /* Since master volume is virtualized, we add the attenuations for both */ /* master volume and channel volume to obtain the overall attenuation */ /* Get total attenuation */ iVol = ChnlVol + devc->m_DACVolume[LINE_MASTER] - MAX_VOLUME; /* Check against bounds */ iVol = (iVol < MAX_VOLUME) ? iVol : MAX_VOLUME; if (iVol < MIN_VOLUME) iVol = MIN_VOLUME; WriteWM8770 (devc, gWMRegister[LineIdx], iVol | 0x180); }
Function : SetMute ------------------------------------------------------------------------------- Description : Returns : VOID -> Parameters : IN ULONG ChannelID -> : IN BOOLEAN Mute -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetDACMute (envy24ht_devc * devc, IN ULONG ChannelID, IN BOOLEAN Mute) { ULONG LineIndex; /* Convert ChannelID to line index */ /* If it is for left channel, we will need to add one */ LineIndex = ChannelID >> 15; /* See if this is for master volume */ if (LineIndex == LINE_MASTER) { /* if current setting is not the same as previous setting */ if (devc->m_fDACMute[LINE_MASTER] != Mute) { int i; devc->m_fDACMute[LINE_MASTER] = Mute; /* Need to do it for every single line (excluding Master and Gain) */ for (i = 0; i <= LINE_OUT_4R; i++) { SetVolReg (devc, i); } return; } } /* See if this is for left channel */ if (ChannelID & CH_LEFT) { /* if current setting is not the same as previous setting */ if (devc->m_fDACMute[LineIndex] != Mute) { devc->m_fDACMute[LineIndex] = Mute; if (LineIndex == LINE_GAIN_L) { WriteWM8770 (devc, gWMRegister[LINE_GAIN_L], devc-> m_DACVolume[LINE_GAIN_L] | ((Mute) ? 0x20 : 0x00)); } else { SetVolReg (devc, LineIndex); } } } /* See if this is for right channel */ if (ChannelID & CH_RIGHT) { LineIndex++; /* if current setting is not the same as previous setting */ if (devc->m_fDACMute[LineIndex] != Mute) { devc->m_fDACMute[LineIndex] = Mute; if (LineIndex == LINE_GAIN_R) { WriteWM8770 (devc, gWMRegister[LINE_GAIN_R], devc-> m_DACVolume[LINE_GAIN_R] | ((Mute) ? 0x20 : 0x00)); } else { SetVolReg (devc, LineIndex); } } } /* m_pAdapter->SetDirty(); *//* TODO */ }
Function : SetVolume ------------------------------------------------------------------------------- Description : Returns : VOID -> Parameters : IN ICE_HW_PARAM* HwParm -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetDACVolume (envy24ht_devc * devc, IN ULONG ChannelID, IN UCHAR Volume) { ULONG LineIndex; WORD LeftRight; BOOLEAN VolChnged = 0; /* Convert ChannelID to line index */ LineIndex = ChannelID >> 15; /* Get the left/right side */ LeftRight = (WORD) (ChannelID & 0xffff); /* Check if left volume is changed */ if (LeftRight & CH_LEFT) { if (devc->m_DACVolume[LineIndex] != Volume) { devc->m_DACVolume[LineIndex] = Volume; VolChnged = 1; } } /* Check if right volume is changed */ if (LeftRight & CH_RIGHT) { if (devc->m_DACVolume[LineIndex + 1] != Volume) { devc->m_DACVolume[LineIndex + 1] = Volume; VolChnged = 1; } } /* If any volume is changed, need to touch hardware */ if (VolChnged) { /* check if this is for input gain */ if ((ChannelID >> 16) == IN_12) { USHORT WMValue = (USHORT) Volume; #ifdef NULL_DB WMValue = 0x0C; #endif if (LeftRight & CH_LEFT) WriteWM8770 (devc, gWMRegister[LineIndex], WMValue); if (LeftRight & CH_RIGHT) WriteWM8770 (devc, gWMRegister[LineIndex + 1], WMValue); } else /* Yap, now check if this is for master volume */ if ((ChannelID >> 16) == OUT_MASTER) { int i; /* Need to do it for every single line (excluding Master and Gain) */ for (i = 0; i <= LINE_OUT_4R; i++) { SetVolReg (devc, i); } } else { if (LeftRight & CH_LEFT) SetVolReg (devc, LineIndex); if (LeftRight & CH_RIGHT) SetVolReg (devc, LineIndex + 1); } } /* m_pAdapter->SetDirty(); TODO */ }
Function : GetVolume ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : IN ULONG ChannelID -> ------------------------------------------------------------------------------- Notes : =============================================================================
static UCHAR GetDACVolume (envy24ht_devc * devc, IN ULONG ChannelID) { UCHAR Value; USHORT LeftRight; ULONG LineIndex; /* Convert ChannelID to line index */ LineIndex = ChannelID >> 15; /* Get the left/right side */ LeftRight = (USHORT) (ChannelID & 0xffff); if (LeftRight == CH_LEFT) { Value = devc->m_DACVolume[LineIndex]; } else { Value = devc->m_DACVolume[LineIndex + 1]; } return Value; } #if 0
Function : GetMute ------------------------------------------------------------------------------- Description : Returns : BOOLEAN -> Parameters : IN ULONG ChannelID -> ------------------------------------------------------------------------------- Notes : =============================================================================
static BOOLEAN GetDACMute (envy24ht_devc * devc, IN ULONG ChannelID) { BOOLEAN Value; USHORT LeftRight; ULONG LineIndex; /* Convert ChannelID to line index */ LineIndex = ChannelID >> 15; /* Get the left/right side */ LeftRight = (USHORT) (ChannelID & 0xffff); if (LeftRight == CH_LEFT) { Value = devc->m_fDACMute[LineIndex]; } else { Value = devc->m_fDACMute[LineIndex + 1]; } return Value; } #endif
Function : SetADCGain ------------------------------------------------------------------------------- Description : Parameters : IN ULONG Index -> : IN ULONG Value -> : IN ULONG Channel -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetADCGain (envy24ht_devc * devc, IN ULONG Index, IN USHORT Value, IN ULONG Channel) { UCHAR WMReg = 0x19; USHORT WMValue; /* Set only selected Line */ if (Index != devc->m_ADCIndex) return; switch (Channel) { case CH_LEFT: devc->m_ADCVolume[Index] = (Value << 8) | (devc->m_ADCVolume[Index] & 0x00FF); break; case CH_BOTH: devc->m_ADCVolume[Index] = (Value << 8) | Value; break; case CH_NOP: /* Hold Value */ break; case CH_RIGHT: default: devc->m_ADCVolume[Index] = Value | (devc->m_ADCVolume[Index] & 0xFF00); } WMValue = ((devc->m_ADCVolume[Index] & 0x00FF) < 0x1F) ? (devc->m_ADCVolume[Index] & 0x00FF) : 0x1F; #ifdef NULL_DB WMValue = 0x0C; #endif WriteWM8770 (devc, WMReg, WMValue); WMValue = (((devc->m_ADCVolume[Index] >> 8) & 0x00FF) < 0x1F) ? ((devc->m_ADCVolume[Index] >> 8) & 0x00FF) : 0x1F; #ifdef NULL_DB WMValue = 0x0C; #endif WriteWM8770 (devc, WMReg + 1, WMValue); /* Force saving of registers */ /* devc->m_pAdapter->SetDirty(); TODO */ } #if 0
Function : GetADCGain ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : IN ULONG Index -> : IN ULONG Channel -> ------------------------------------------------------------------------------- Notes : =============================================================================
static UCHAR GetADCGain (envy24ht_devc * devc, IN ULONG Index, IN ULONG Channel) { UCHAR Value; if (Channel == CH_LEFT) { Value = (UCHAR) ((devc->m_ADCVolume[Index] >> 8) & 0xFF); } else { Value = (UCHAR) (devc->m_ADCVolume[Index] & 0xFF); } return Value; } #endif
Function : SetADCMux ------------------------------------------------------------------------------- Description : Parameters : IN Value -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetADCMux (envy24ht_devc * devc, IN ULONG Value) { UCHAR MuxVal = 0; BOOLEAN fAU; /* Store to shadow register */ devc->m_ADCMux = Value; devc->m_fSPDIFRecord = 0; fAU = (devc->subvendor == SSID_AUREON_UNIVERSE); switch (Value) { case CD_IN_MUX_TP_PIN: devc->m_ADCIndex = ADC_CD; MuxVal = (fAU) ? 0x11 : 0x00; break; case LINE_IN_MUX_TP_PIN: devc->m_ADCIndex = ADC_LINE; MuxVal = (fAU) ? 0x33 : 0x22; break; case AUX_IN_MUX_TP_PIN: devc->m_ADCIndex = ADC_AUX; MuxVal = (fAU) ? devc->m_AuxMux : 0x11; break; case MIC_IN_MUX_TP_PIN: devc->m_ADCIndex = ADC_MIC; MuxVal = (fAU) ? 0x55 : 0x33; break; case DIG_IN_MUX_TP_PIN: /* Use SPDIF DMA channel */ devc->m_fSPDIFRecord = 1; break; case PHONO_IN_MUX_PIN: devc->m_ADCIndex = ADC_PHONO; MuxVal = 0x22; break; case STEREO_MIX_MUX_TP_PIN: devc->m_ADCIndex = ADC_STEREO_MIX; MuxVal = (fAU) ? 0x77 : 0x44; break; default: devc->m_ADCIndex = ADC_LINE; MuxVal = 0x22; } WriteWM8770 (devc, WM_ADC_INPUT_MX, (UCHAR) MuxVal); /* Reset GAIN */ SetADCGain (devc, devc->m_ADCIndex, 0, CH_NOP); /* Update PCA config */ WritePCA (devc); /* Force saving of registers */ /*devc->m_pAdapter->SetDirty(); TODO */ }
Function : InitWM8770 ------------------------------------------------------------------------------- Description : ------------------------------------------------------------------------------- Notes : Call before Registry Read =============================================================================
static void InitWM8770 (envy24ht_devc * devc) {
Reset WM8770 -----------------------------------------------------------------------------
/* Set SPI Mode */ WriteGPIO (devc, 0, GPIO_WM8770_RS_MASK); oss_udelay (3); WriteGPIO (devc, GPIO_WM8770_CS_MASK, GPIO_WM8770_CS_MASK); oss_udelay (3); WriteGPIO (devc, GPIO_WM8770_RS_MASK, GPIO_WM8770_RS_MASK); oss_udelay (100);
Set defaults -----------------------------------------------------------------------------
/* Output defaults */ SetDACVolume (devc, CH_MASTER_BOTH, WM_OUT_DEFAULT); SetDACVolume (devc, CH_FRONT_BOTH, WM_OUT_DEFAULT); SetDACVolume (devc, CH_REAR_BOTH, WM_OUT_DEFAULT); SetDACVolume (devc, CH_CENTER, WM_OUT_DEFAULT); SetDACVolume (devc, CH_LFE, WM_OUT_DEFAULT); SetDACVolume (devc, CH_BS_BOTH, WM_OUT_DEFAULT); SetDACMute (devc, CH_MASTER_BOTH, 0); SetDACMute (devc, CH_FRONT_BOTH, 0); SetDACMute (devc, CH_REAR_BOTH, 0); SetDACMute (devc, CH_CENTER, 0); SetDACMute (devc, CH_LFE, 0); SetDACMute (devc, CH_BS_BOTH, 0); /* Input */ SetADCGain (devc, ADC_CD, WM_INP_DEFAULT, CH_BOTH); SetADCGain (devc, ADC_AUX, WM_INP_DEFAULT, CH_BOTH); SetADCGain (devc, ADC_LINE, WM_INP_DEFAULT, CH_BOTH); SetADCGain (devc, ADC_MIC, WM_INP_DEFAULT, CH_BOTH); /* Mux */ SetADCMux (devc, STEREO_MIX_MUX_TP_PIN); /* At least Power DAC & ADC */ WriteWM8770 (devc, WM_POWER_CNTRL, 0x0000); /* Power ADC Input Mux */ WriteWM8770 (devc, WM_ADC_INPUT_MX, 0x0000); /* Enable Aux-Output */ if (devc->subvendor == SSID_PHASE28) { WriteWM8770 (devc, WM_OUT12_SELECT, 0x0009); WriteWM8770 (devc, WM_OUT34_SELECT, 0x0009); } else { WriteWM8770 (devc, WM_OUT12_SELECT, 0x000b); WriteWM8770 (devc, WM_OUT34_SELECT, 0x0009); } /* Init Master Mode Register */ WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x0012); }
Function : InitCS8415 ------------------------------------------------------------------------------- Description : Returns : void -> ------------------------------------------------------------------------------- Notes : Has to be called after InitWM8770 since RST must be "high" =============================================================================
static void InitCS8415 (envy24ht_devc * devc) { /* Init Remote-Controller */ if (devc->subvendor == SSID_AUREON_UNIVERSE) { UCHAR bByte[2]; bByte[0] = (UCHAR) ((AUREON_REMOTE_ID >> 8) & 0xFF); bByte[1] = (UCHAR) AUREON_REMOTE_ID; IICWriteBuffer (devc, AUREON_REMOTE_CNTRL, bByte, 2, 200); }
Reset CS8415 -----------------------------------------------------------------------------
/* Set SPI Mode */ WriteGPIO (devc, GPIO_CS8415_CS_MASK, GPIO_CS8415_CS_MASK); oss_udelay (3); WriteGPIO (devc, 0, GPIO_CS8415_CS_MASK); oss_udelay (100); /* Set defaults */ WriteCS8415 (devc, CS_CONTROL_1, 0x80); /* SPDIF mux to RXP1 */ WriteCS8415 (devc, CS_CONTROL_2, 0x01); WriteCS8415 (devc, CS_CLK_SRC_CNTRL, 0x41); WriteCS8415 (devc, CS_SER_OUT_FORMAT, 0x05); /* all other register remain to their defaults */ } #define GPIO_WAIT 10
Function : WriteAC97Codec ------------------------------------------------------------------------------- Description : Writes to TT-AC97 Interface Parameters : IN ULONG Register -> : IN ULONG Data -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void WriteAC97Codec (envy24ht_devc * devc, IN ULONG Register, IN ULONG Data) { UCHAR TTData; #ifdef TTTT /* CL_TEST */ /* Reset AC97 */ WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK); oss_udelay (3); WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK); oss_udelay (3); WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK); oss_udelay (3); /* Unmute Master */ WriteAC97Codec (devc, 0x02, 0x00); #endif /* m_pAdapter->HwEnter(); TODO */ oss_udelay (GPIO_WAIT); /* Reset all LD Pins and GO Pin */ WriteGPIO (devc, 0, GPIO_LD_DATA_H_MASK | GPIO_LD_DATA_L_MASK | GPIO_LD_ADR_MASK | GPIO_GO_MASK); /* apply address to TT-AC97 Interface */ WriteGPIO (devc, Register, GPIO_DATA_ADR_MASK); /* Set "Load Address" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, GPIO_LD_ADR_MASK, GPIO_LD_ADR_MASK); /* Reset "Load Address" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, 0, GPIO_LD_ADR_MASK); /* apply data low to TT-AC97 Interface */ oss_udelay (GPIO_WAIT); TTData = (UCHAR) (Data & 0x000000FF); WriteGPIO (devc, TTData, GPIO_DATA_ADR_MASK); /* Set "Load Data low" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, GPIO_LD_DATA_L_MASK, GPIO_LD_DATA_L_MASK); /* Reset "Load Data low" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, 0, GPIO_LD_DATA_L_MASK); /* apply data high to TT-AC97 Interface */ oss_udelay (GPIO_WAIT); TTData = (UCHAR) ((Data >> 8) & 0x000000FF); WriteGPIO (devc, TTData, GPIO_DATA_ADR_MASK); /* Set "Load Data high" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, GPIO_LD_DATA_H_MASK, GPIO_LD_DATA_H_MASK); /* Reset "Load Data high" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, 0, GPIO_LD_DATA_H_MASK); /* Set and immediately reset "GO" Pin */ oss_udelay (GPIO_WAIT); WriteGPIO (devc, GPIO_GO_MASK, GPIO_GO_MASK); WriteGPIO (devc, 0, GPIO_GO_MASK); /* m_pAdapter->HwLeave(); *//* TODO */ }
Function : SetAC97Volume ------------------------------------------------------------------------------- Description : Parameters : IN ULONG Index -> : IN UHSORT Value -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetAC97Volume (envy24ht_devc * devc, IN ULONG Index, IN USHORT left, IN USHORT right) { int AC97Reg = 0, value; devc->m_AC97Volume[Index] = left | (right << 8); left = AC97_INP_MAX - left; right = AC97_INP_MAX - right; value = (left << 8) | right; switch (devc->subvendor) { case SSID_AUREON_SKY: case SSID_PRODIGY71: case SSID_AUREON_SPACE: switch (Index) { case AC97_MIC: AC97Reg = AC97_IDXREG_MIC_IN; break; case AC97_LINE: AC97Reg = AC97_IDXREG_LINE_IN; break; case AC97_CD: AC97Reg = AC97_IDXREG_CD_IN; break; case AC97_AUX: AC97Reg = AC97_IDXREG_AUX_IN; break; default: cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index); return; } break; case SSID_AUREON_UNIVERSE: switch (Index) { case AC97_MIC: AC97Reg = AC97_IDXREG_MIC_IN; break; case AC97_LINE: AC97Reg = AC97_IDXREG_LINE_IN; break; case AC97_CD: AC97Reg = AC97_IDXREG_AUX_IN; break; case AC97_PHONO: AC97Reg = AC97_IDXREG_CD_IN; break; case AC97_AUX: case AC97_LINE2: AC97Reg = AC97_IDXREG_VIDEO_IN; break; default: cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index); return; } break; } if (!devc->m_fAC97Mute[Index]) { WriteAC97Codec (devc, AC97Reg, value); } /* Force saving of registers */ /* m_pAdapter->SetDirty(); TODO */ }
Function : GetAC97Volume ------------------------------------------------------------------------------- Description : Returns : UCHAR -> Parameters : IN ULONG Index -> : IN ULONG Channel -> ------------------------------------------------------------------------------- Notes : =============================================================================
static USHORT GetAC97Volume (envy24ht_devc * devc, IN ULONG Index) { return devc->m_AC97Volume[Index]; }
Function : SetAC97Mute ------------------------------------------------------------------------------- Description : Returns : void -> Parameters : IN ULONG Index -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetAC97Mute (envy24ht_devc * devc, IN ULONG Index, BOOLEAN OnOff) { UCHAR AC97Reg = 0; devc->m_fAC97Mute[Index] = OnOff; switch (devc->subvendor) { case SSID_AUREON_SKY: case SSID_PRODIGY71: case SSID_AUREON_SPACE: switch (Index) { case AC97_MIC: AC97Reg = AC97_IDXREG_MIC_IN; break; case AC97_LINE: AC97Reg = AC97_IDXREG_LINE_IN; break; case AC97_CD: AC97Reg = AC97_IDXREG_CD_IN; break; case AC97_AUX: AC97Reg = AC97_IDXREG_AUX_IN; break; default: cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index); return; } break; case SSID_AUREON_UNIVERSE: switch (Index) { case AC97_MIC: AC97Reg = AC97_IDXREG_MIC_IN; break; case AC97_LINE: AC97Reg = AC97_IDXREG_LINE_IN; break; case AC97_CD: AC97Reg = AC97_IDXREG_AUX_IN; break; case AC97_PHONO: AC97Reg = AC97_IDXREG_CD_IN; break; case AC97_AUX: case AC97_LINE2: AC97Reg = AC97_IDXREG_VIDEO_IN; break; default: cmn_err (CE_CONT, "Aureon: Bad index %d\n", Index); return; } break; } #ifdef AC97_MUTE WriteAC97Codec (devc, AC97Reg, 0x8000); #else WriteAC97Codec (devc, AC97Reg, (OnOff) ? 0x8000 : devc->m_AC97Volume[Index]); #endif /* Force saving of registers */ /* m_pAdapter->SetDirty(); *//* TODO */ }
Function : InitAC97 ------------------------------------------------------------------------------- Description : Returns : void -> ------------------------------------------------------------------------------- Notes : Call before Registry Read =============================================================================
static void InitAC97 (envy24ht_devc * devc) { /* Reset AC97 */ oss_udelay (30); WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK); oss_udelay (3); WriteGPIO (devc, 0, GPIO_AC97_RESET_MASK); oss_udelay (3); WriteGPIO (devc, GPIO_AC97_RESET_MASK, GPIO_AC97_RESET_MASK); oss_udelay (3); /* Unmute Master */ WriteAC97Codec (devc, 0x02, 0x00);
Set defaults -----------------------------------------------------------------------------
/* Volume */ SetAC97Volume (devc, AC97_MIC, AC97_INP_DEFAULT, AC97_INP_DEFAULT); SetAC97Volume (devc, AC97_LINE, AC97_INP_DEFAULT, AC97_INP_DEFAULT); SetAC97Volume (devc, AC97_AUX, AC97_INP_DEFAULT, AC97_INP_DEFAULT); SetAC97Volume (devc, AC97_CD, AC97_INP_DEFAULT, AC97_INP_DEFAULT); /* Mute */ SetAC97Mute (devc, AC97_MIC, 0); SetAC97Mute (devc, AC97_LINE, 0); SetAC97Mute (devc, AC97_AUX, 0); SetAC97Mute (devc, AC97_CD, 0); }
Function : SetSampleRate ------------------------------------------------------------------------------- Description : Returns : NTSTATUS -> Parameters : IN ULONG SampleRate -> ------------------------------------------------------------------------------- Notes : =============================================================================
static void SetSampleRate (envy24ht_devc * devc, IN ULONG SampleRate) { WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x0012); switch (SampleRate) { case 48000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_48KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); /* WRITE_PORT_UCHAR(WKNMTBase + MT_DATA_FORMAT_REG,(~MT_128X)&READ_PORT_UCHAR(WKNMTBase + MT_DATA_FORMAT_REG)); */ break; case 24000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_24KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 12000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_12KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 9600: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_9p6KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 32000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_32KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 16000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_16KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 8000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_8KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 96000: WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A); WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_96KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 192000: WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A); WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_192KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_ON); break; case 64000: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_64KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 44100: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_44p1KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 22050: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_22p05KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 11025: WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_11p025KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 88200: WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A); WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_88p2KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; case 176400: WriteWM8770 (devc, WM_MASTER_MODE_CNTRL, 0x001A); WritePort (devc, REG_MT, MT_SAMPLE_RATE_REG, MT_176p4KHZ, WIDTH_BYTE); ReadModifyWritePort (devc, REG_MT, MT_DATA_FORMAT_REG, MT_128X, WIDTH_BYTE | BITS_OFF); break; default: break; } } static void aureon_card_init (envy24ht_devc * devc) { /* Do not change the order of the following lines */ Init1724 (devc); ResetGPIO (devc); if (devc->subvendor != SSID_PHASE28) InitAC97 (devc); InitWM8770 (devc); InitCS8415 (devc); /* Do not change the order of the above lines */ SetSPDIFConfig (devc, 0); /* SetSDPIFSource(devc, DIGOUT_WAVE); */ SetDigInSource (devc, DIGIN_COAX); SetFrontjack (devc, FRONT_JACK_HEADPHONE); SetLineSource (devc, SRC_LINE_REAR); SetClockSource (devc, ICE_INTERNAL_CLOCK); } static void aureon_set_rate (envy24ht_devc * devc) { SetSampleRate (devc, devc->speed); } static int aureon_set_ctl (int dev, int ctl, unsigned int cmd, int value) { envy24ht_devc *devc = mixer_devs[dev]->devc; if (cmd == SNDCTL_MIX_READ) { switch (ctl) { case 1: return devc->m_LineInSource; case 3: return devc->m_DigInSource; case 4: return devc->m_Frontjack; } } if (cmd == SNDCTL_MIX_WRITE) { switch (ctl) { case 1: SetLineSource (devc, value); return devc->m_LineInSource; case 3: SetDigInSource (devc, value); return devc->m_DigInSource; case 4: SetFrontjack (devc, value); return devc->m_Frontjack; } } return OSS_EINVAL; } static int aureon_set_vol (int dev, int ChannelID, unsigned int cmd, int value) { envy24ht_devc *devc = mixer_devs[dev]->devc; ULONG LineIndex; WORD LeftRight; int left, right; /* Convert ChannelID to line index */ LineIndex = ChannelID >> 15; /* Get the left/right side */ LeftRight = (WORD) (ChannelID & 0xffff); if (cmd == SNDCTL_MIX_READ) { left = right = 0; if (LeftRight & CH_LEFT) left = GetDACVolume (devc, (LineIndex << 15) | CH_LEFT); if (LeftRight & CH_RIGHT) right = GetDACVolume (devc, (LineIndex << 15) | CH_RIGHT); if (left == 0) left = right; else if (right == 0) right = left; return left | (right << 8); } if (cmd == SNDCTL_MIX_WRITE) { left = (value & 0xff); right = ((value >> 8) & 0xff); if (LeftRight != CH_BOTH) right = left; if (LeftRight & CH_LEFT) SetDACVolume (devc, (LineIndex << 15) | CH_LEFT, left); if (LeftRight & CH_RIGHT) SetDACVolume (devc, (LineIndex << 15) | CH_RIGHT, right); return left | (right << 8); } return OSS_EINVAL; } static int aureon_set_ac97 (int dev, int Index, unsigned int cmd, int value) { envy24ht_devc *devc = mixer_devs[dev]->devc; int left, right; if (cmd == SNDCTL_MIX_READ) { return GetAC97Volume (devc, Index); } if (cmd == SNDCTL_MIX_WRITE) { left = (value & 0xff); right = ((value >> 8) & 0xff); SetAC97Volume (devc, Index, left, right); return left | (right << 8); } return OSS_EINVAL; } /*ARGSUSED*/ static int aureon_mixer_init_common (envy24ht_devc * devc, int dev, int root) { int ctl, group; if ((group = mixer_ext_create_group (dev, root, "VOL")) < 0) return group; if ((ctl = mixer_ext_create_control (dev, group, CH_MASTER_BOTH, aureon_set_vol, MIXT_STEREOSLIDER, "MASTER", WM_OUT_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, CH_FRONT_BOTH, aureon_set_vol, MIXT_STEREOSLIDER, "FRONT", WM_OUT_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, CH_REAR_BOTH, aureon_set_vol, MIXT_STEREOSLIDER, "SURROUND", WM_OUT_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, CH_CENTER, aureon_set_vol, MIXT_MONOSLIDER, "CENTER", WM_OUT_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, CH_LFE, aureon_set_vol, MIXT_MONOSLIDER, "LFE", WM_OUT_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, CH_BS_BOTH, aureon_set_vol, MIXT_STEREOSLIDER, "REAR", WM_OUT_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((group = mixer_ext_create_group_flags (dev, root, "TERRATEC", MIXF_FLAT)) < 0) return group; if ((ctl = mixer_ext_create_control (dev, group, 1, aureon_set_ctl, MIXT_ENUM, "LINESRC", 4, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; mixer_ext_set_strings (dev, ctl, "AUX WTL REAR GROUND", 0); if ((ctl = mixer_ext_create_control (dev, group, 3, aureon_set_ctl, MIXT_ENUM, "DIGIN", 3, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; mixer_ext_set_strings (dev, ctl, "OPTICAL COAX CD", 0); return 0; } /*ARGSUSED*/ static int aureon_mixer_init_universe (envy24ht_devc * devc, int dev, int group) { int ctl; if ((group = mixer_ext_create_group (dev, group, "ENVY24_UNIVERSE")) < 0) return group; if ((ctl = mixer_ext_create_control (dev, group, 4, aureon_set_ctl, MIXT_ENUM, "FRONTJACK", 3, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; mixer_ext_set_strings (dev, ctl, "LINEIN HEADPH", 0); return 0; } /*ARGSUSED*/ static int aureon_mixer_init_ac97 (envy24ht_devc * devc, int dev, int group) { int ctl; if ((group = mixer_ext_create_group (dev, group, "ENVY24_AC97")) < 0) return group; if ((ctl = mixer_ext_create_control (dev, group, AC97_MIC, aureon_set_ac97, MIXT_STEREOSLIDER, "MIC", AC97_INP_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, AC97_LINE, aureon_set_ac97, MIXT_STEREOSLIDER, "LINE", AC97_INP_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, AC97_CD, aureon_set_ac97, MIXT_STEREOSLIDER, "CD", AC97_INP_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, AC97_PHONO, aureon_set_ac97, MIXT_STEREOSLIDER, "PHONO", AC97_INP_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; if ((ctl = mixer_ext_create_control (dev, group, AC97_AUX, aureon_set_ac97, MIXT_STEREOSLIDER, "AUX", AC97_INP_MAX, MIXF_READABLE | MIXF_WRITEABLE)) < 0) return ctl; return 0; } static int aureon_mixer_init (envy24ht_devc * devc, int dev, int root) { aureon_mixer_init_common (devc, dev, root); if (devc->subvendor == SSID_AUREON_UNIVERSE) aureon_mixer_init_universe (devc, dev, root); if (devc->subvendor != SSID_PHASE28) aureon_mixer_init_ac97 (devc, dev, root); return 0; } envy24ht_auxdrv_t envy24ht_aureon_auxdrv = { aureon_card_init, aureon_mixer_init, aureon_set_rate, NULL, NULL, NULL, /* aureon_private1 */ };