| #ifndef __SOUND_AC97_CODEC_H |
| #define __SOUND_AC97_CODEC_H |
| |
| /* |
| * Copyright (c) by Jaroslav Kysela <perex@suse.cz> |
| * Universal interface for Audio Codec '97 |
| * |
| * For more details look to AC '97 component specification revision 2.1 |
| * by Intel Corporation (http://developer.intel.com). |
| * |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| * |
| */ |
| |
| #include "control.h" |
| #include "info.h" |
| |
| /* |
| * AC'97 codec registers |
| */ |
| |
| #define AC97_RESET 0x00 /* Reset */ |
| #define AC97_MASTER 0x02 /* Master Volume */ |
| #define AC97_HEADPHONE 0x04 /* Headphone Volume (optional) */ |
| #define AC97_MASTER_MONO 0x06 /* Master Volume Mono (optional) */ |
| #define AC97_MASTER_TONE 0x08 /* Master Tone (Bass & Treble) (optional) */ |
| #define AC97_PC_BEEP 0x0a /* PC Beep Volume (optinal) */ |
| #define AC97_PHONE 0x0c /* Phone Volume (optional) */ |
| #define AC97_MIC 0x0e /* MIC Volume */ |
| #define AC97_LINE 0x10 /* Line In Volume */ |
| #define AC97_CD 0x12 /* CD Volume */ |
| #define AC97_VIDEO 0x14 /* Video Volume (optional) */ |
| #define AC97_AUX 0x16 /* AUX Volume (optional) */ |
| #define AC97_PCM 0x18 /* PCM Volume */ |
| #define AC97_REC_SEL 0x1a /* Record Select */ |
| #define AC97_REC_GAIN 0x1c /* Record Gain */ |
| #define AC97_REC_GAIN_MIC 0x1e /* Record Gain MIC (optional) */ |
| #define AC97_GENERAL_PURPOSE 0x20 /* General Purpose (optional) */ |
| #define AC97_3D_CONTROL 0x22 /* 3D Control (optional) */ |
| #define AC97_RESERVED 0x24 /* Reserved */ |
| #define AC97_POWERDOWN 0x26 /* Powerdown control / status */ |
| /* range 0x28-0x3a - AUDIO AC'97 2.0 extensions */ |
| #define AC97_EXTENDED_ID 0x28 /* Extended Audio ID */ |
| #define AC97_EXTENDED_STATUS 0x2a /* Extended Audio Status */ |
| #define AC97_PCM_FRONT_DAC_RATE 0x2c /* PCM Front DAC Rate */ |
| #define AC97_PCM_SURR_DAC_RATE 0x2e /* PCM Surround DAC Rate */ |
| #define AC97_PCM_LFE_DAC_RATE 0x30 /* PCM LFE DAC Rate */ |
| #define AC97_PCM_LR_ADC_RATE 0x32 /* PCM LR DAC Rate */ |
| #define AC97_PCM_MIC_ADC_RATE 0x34 /* PCM MIC ADC Rate */ |
| #define AC97_CENTER_LFE_MASTER 0x36 /* Center + LFE Master Volume */ |
| #define AC97_SURROUND_MASTER 0x38 /* Surround (Rear) Master Volume */ |
| #define AC97_SPDIF 0x3a /* S/PDIF control */ |
| /* range 0x3c-0x58 - MODEM */ |
| /* range 0x5a-0x7b - Vendor Specific */ |
| #define AC97_VENDOR_ID1 0x7c /* Vendor ID1 */ |
| #define AC97_VENDOR_ID2 0x7e /* Vendor ID2 / revision */ |
| |
| /* extended audio status and control bit defines */ |
| #define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */ |
| #define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */ |
| #define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */ |
| #define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */ |
| #define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */ |
| #define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */ |
| #define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */ |
| #define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */ |
| #define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */ |
| #define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */ |
| #define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */ |
| #define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */ |
| #define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */ |
| #define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */ |
| #define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */ |
| #define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */ |
| #define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */ |
| #define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */ |
| |
| /* S/PDIF control bit defines */ |
| #define AC97_SC_PRO 0x0001 /* Professional status */ |
| #define AC97_SC_NAUDIO 0x0002 /* Non audio stream */ |
| #define AC97_SC_COPY 0x0004 /* Copyright status */ |
| #define AC97_SC_PRE 0x0008 /* Preemphasis status */ |
| #define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */ |
| #define AC97_SC_L 0x0800 /* Generation Level status */ |
| #define AC97_SC_SPSR_MASK 0xcfff /* S/PDIF Sample Rate bits */ |
| #define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */ |
| #define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */ |
| #define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */ |
| #define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */ |
| #define AC97_SC_V 0x8000 /* Validity status */ |
| |
| /* specific - SigmaTel */ |
| #define AC97_SIGMATEL_ANALOG 0x6c /* Analog Special */ |
| #define AC97_SIGMATEL_DAC2INVERT 0x6e |
| #define AC97_SIGMATEL_BIAS1 0x70 |
| #define AC97_SIGMATEL_BIAS2 0x72 |
| #define AC97_SIGMATEL_MULTICHN 0x74 /* Multi-Channel programming */ |
| #define AC97_SIGMATEL_CIC1 0x76 |
| #define AC97_SIGMATEL_CIC2 0x78 |
| |
| /* specific - Analog Devices */ |
| #define AC97_AD_TEST 0x5a /* test register */ |
| #define AC97_AD_CODEC_CFG 0x70 /* codec configuration */ |
| #define AC97_AD_JACK_SPDIF 0x72 /* Jack Sense & S/PDIF */ |
| #define AC97_AD_SERIAL_CFG 0x74 /* Serial Configuration */ |
| #define AC97_AD_MISC 0x76 /* Misc Control Bits */ |
| |
| /* ac97->scaps */ |
| #define AC97_SCAP_SURROUND_DAC (1<<0) /* surround L&R DACs are present */ |
| #define AC97_SCAP_CENTER_LFE_DAC (1<<1) /* center and LFE DACs are present */ |
| |
| /* ac97->flags */ |
| #define AC97_HAS_PC_BEEP (1<<0) |
| #define AC97_AD_MULTI (1<<1) /* Analog Devices - multi codecs */ |
| |
| /* |
| |
| */ |
| |
| typedef struct _snd_ac97 ac97_t; |
| |
| struct _snd_ac97 { |
| void (*write) (ac97_t *ac97, unsigned short reg, unsigned short val); |
| unsigned short (*read) (ac97_t *ac97, unsigned short reg); |
| void (*wait) (ac97_t *ac97); |
| void (*init) (ac97_t *ac97); |
| snd_info_entry_t *proc_entry; |
| snd_info_entry_t *proc_regs_entry; |
| void *private_data; |
| void (*private_free) (ac97_t *ac97); |
| /* --- */ |
| snd_card_t *card; |
| spinlock_t reg_lock; |
| unsigned short num; /* number of codec: 0 = primary, 1 = secondary */ |
| unsigned short addr; /* physical address of codec [0-3] */ |
| unsigned int id; /* identification of codec */ |
| unsigned short caps; /* capabilities (register 0) */ |
| unsigned short ext_id; /* extended feature identification (register 28) */ |
| unsigned int scaps; /* driver capabilities */ |
| unsigned int flags; /* specific code */ |
| unsigned int clock; /* AC'97 clock (usually 48000Hz) */ |
| unsigned int rates_front_dac; |
| unsigned int rates_surr_dac; |
| unsigned int rates_lfe_dac; |
| unsigned int rates_adc; |
| unsigned int rates_mic_adc; |
| unsigned int spdif_status; |
| unsigned short regs[0x80]; /* register cache */ |
| unsigned char reg_accessed[0x80 / 8]; /* bit flags */ |
| union { /* vendor specific code */ |
| struct { |
| unsigned short unchained[3]; // 0 = C34, 1 = C79, 2 = C69 |
| unsigned short chained[3]; // 0 = C34, 1 = C79, 2 = C69 |
| unsigned short id[3]; // codec IDs (lower 16-bit word) |
| unsigned short pcmreg[3]; // PCM registers |
| struct semaphore mutex; |
| } ad18xx; |
| } spec; |
| }; |
| |
| int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97); |
| |
| void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value); |
| unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg); |
| void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value); |
| int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value); |
| int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value); |
| int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate); |
| #ifdef CONFIG_PM |
| void snd_ac97_suspend(ac97_t *ac97); |
| void snd_ac97_resume(ac97_t *ac97); |
| #endif |
| |
| #endif /* __SOUND_AC97_CODEC_H */ |