📄 ac97.c
字号:
case REC_VIDEO: return AUD_REC_VIDEO; case REC_AUX: return AUD_REC_AUX; case REC_LINE_IN: return AUD_REC_LINE_IN; case REC_PHONE: return AUD_REC_PHONE; default: dolog ("Unknown record source %d, using MIC\n", i); return AUD_REC_MIC; }}static uint8_t aud_to_ac97_record_source (audrecsource_t rs){ switch (rs) { case AUD_REC_MIC: return REC_MIC; case AUD_REC_CD: return REC_CD; case AUD_REC_VIDEO: return REC_VIDEO; case AUD_REC_AUX: return REC_AUX; case AUD_REC_LINE_IN: return REC_LINE_IN; case AUD_REC_PHONE: return REC_PHONE; default: dolog ("Unknown audio recording source %d using MIC\n", rs); return REC_MIC; }}static void record_select (AC97LinkState *s, uint32_t val){ uint8_t rs = val & REC_MASK; uint8_t ls = (val >> 8) & REC_MASK; audrecsource_t ars = ac97_to_aud_record_source (rs); audrecsource_t als = ac97_to_aud_record_source (ls); AUD_set_record_source (&als, &ars); rs = aud_to_ac97_record_source (ars); ls = aud_to_ac97_record_source (als); mixer_store (s, AC97_Record_Select, rs | (ls << 8));}#endifstatic void mixer_reset (AC97LinkState *s){ uint8_t active[LAST_INDEX]; dolog ("mixer_reset\n"); memset (s->mixer_data, 0, sizeof (s->mixer_data)); memset (active, 0, sizeof (active)); mixer_store (s, AC97_Reset , 0x0000); /* 6940 */ mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x8000); mixer_store (s, AC97_PC_BEEP_Volume_Mute , 0x0000); mixer_store (s, AC97_Phone_Volume_Mute , 0x8008); mixer_store (s, AC97_Mic_Volume_Mute , 0x8008); mixer_store (s, AC97_CD_Volume_Mute , 0x8808); mixer_store (s, AC97_Aux_Volume_Mute , 0x8808); mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x8000); mixer_store (s, AC97_General_Purpose , 0x0000); mixer_store (s, AC97_3D_Control , 0x0000); mixer_store (s, AC97_Powerdown_Ctrl_Stat , 0x000f); /* * Sigmatel 9700 (STAC9700) */ mixer_store (s, AC97_Vendor_ID1 , 0x8384); mixer_store (s, AC97_Vendor_ID2 , 0x7600); /* 7608 */ mixer_store (s, AC97_Extended_Audio_ID , 0x0809); mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, 0x0009); mixer_store (s, AC97_PCM_Front_DAC_Rate , 0xbb80); mixer_store (s, AC97_PCM_Surround_DAC_Rate , 0xbb80); mixer_store (s, AC97_PCM_LFE_DAC_Rate , 0xbb80); mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80); mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80);#ifdef USE_MIXER record_select (s, 0); set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME , 0x8000); set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM , 0x8808); set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);#endif reset_voices (s, active);}/** * Native audio mixer * I/O Reads */static uint32_t nam_readb (void *opaque, uint32_t addr){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; dolog ("U nam readb %#x\n", addr); s->cas = 0; return ~0U;}static uint32_t nam_readw (void *opaque, uint32_t addr){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; uint32_t val = ~0U; uint32_t index = addr - s->base[0]; s->cas = 0; val = mixer_load (s, index); return val;}static uint32_t nam_readl (void *opaque, uint32_t addr){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; dolog ("U nam readl %#x\n", addr); s->cas = 0; return ~0U;}/** * Native audio mixer * I/O Writes */static void nam_writeb (void *opaque, uint32_t addr, uint32_t val){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; dolog ("U nam writeb %#x <- %#x\n", addr, val); s->cas = 0;}static void nam_writew (void *opaque, uint32_t addr, uint32_t val){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; uint32_t index = addr - s->base[0]; s->cas = 0; switch (index) { case AC97_Reset: mixer_reset (s); break; case AC97_Powerdown_Ctrl_Stat: val &= ~0xf; val |= mixer_load (s, index) & 0xf; mixer_store (s, index, val); break;#ifdef USE_MIXER case AC97_Master_Volume_Mute: set_volume (s, index, AUD_MIXER_VOLUME, val); break; case AC97_PCM_Out_Volume_Mute: set_volume (s, index, AUD_MIXER_PCM, val); break; case AC97_Line_In_Volume_Mute: set_volume (s, index, AUD_MIXER_LINE_IN, val); break; case AC97_Record_Select: record_select (s, val); break;#endif case AC97_Vendor_ID1: case AC97_Vendor_ID2: dolog ("Attempt to write vendor ID to %#x\n", val); break; case AC97_Extended_Audio_ID: dolog ("Attempt to write extended audio ID to %#x\n", val); break; case AC97_Extended_Audio_Ctrl_Stat: if (!(val & EACS_VRA)) { mixer_store (s, AC97_PCM_Front_DAC_Rate, 0xbb80); mixer_store (s, AC97_PCM_LR_ADC_Rate, 0xbb80); open_voice (s, PI_INDEX, 48000); open_voice (s, PO_INDEX, 48000); } if (!(val & EACS_VRM)) { mixer_store (s, AC97_MIC_ADC_Rate, 0xbb80); open_voice (s, MC_INDEX, 48000); } dolog ("Setting extended audio control to %#x\n", val); mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, val); break; case AC97_PCM_Front_DAC_Rate: if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) { mixer_store (s, index, val); dolog ("Set front DAC rate to %d\n", val); open_voice (s, PO_INDEX, val); } else { dolog ("Attempt to set front DAC rate to %d, " "but VRA is not set\n", val); } break; case AC97_MIC_ADC_Rate: if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM) { mixer_store (s, index, val); dolog ("Set MIC ADC rate to %d\n", val); open_voice (s, MC_INDEX, val); } else { dolog ("Attempt to set MIC ADC rate to %d, " "but VRM is not set\n", val); } break; case AC97_PCM_LR_ADC_Rate: if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) { mixer_store (s, index, val); dolog ("Set front LR ADC rate to %d\n", val); open_voice (s, PI_INDEX, val); } else { dolog ("Attempt to set LR ADC rate to %d, but VRA is not set\n", val); } break; default: dolog ("U nam writew %#x <- %#x\n", addr, val); mixer_store (s, index, val); break; }}static void nam_writel (void *opaque, uint32_t addr, uint32_t val){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; dolog ("U nam writel %#x <- %#x\n", addr, val); s->cas = 0;}/** * Native audio bus master * I/O Reads */static uint32_t nabm_readb (void *opaque, uint32_t addr){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; AC97BusMasterRegs *r = NULL; uint32_t index = addr - s->base[1]; uint32_t val = ~0U; switch (index) { case CAS: dolog ("CAS %d\n", s->cas); val = s->cas; s->cas = 1; break; case PI_CIV: case PO_CIV: case MC_CIV: r = &s->bm_regs[GET_BM (index)]; val = r->civ; dolog ("CIV[%d] -> %#x\n", GET_BM (index), val); break; case PI_LVI: case PO_LVI: case MC_LVI: r = &s->bm_regs[GET_BM (index)]; val = r->lvi; dolog ("LVI[%d] -> %#x\n", GET_BM (index), val); break; case PI_PIV: case PO_PIV: case MC_PIV: r = &s->bm_regs[GET_BM (index)]; val = r->piv; dolog ("PIV[%d] -> %#x\n", GET_BM (index), val); break; case PI_CR: case PO_CR: case MC_CR: r = &s->bm_regs[GET_BM (index)]; val = r->cr; dolog ("CR[%d] -> %#x\n", GET_BM (index), val); break; case PI_SR: case PO_SR: case MC_SR: r = &s->bm_regs[GET_BM (index)]; val = r->sr & 0xff; dolog ("SRb[%d] -> %#x\n", GET_BM (index), val); break; default: dolog ("U nabm readb %#x -> %#x\n", addr, val); break; } return val;}static uint32_t nabm_readw (void *opaque, uint32_t addr){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; AC97BusMasterRegs *r = NULL; uint32_t index = addr - s->base[1]; uint32_t val = ~0U; switch (index) { case PI_SR: case PO_SR: case MC_SR: r = &s->bm_regs[GET_BM (index)]; val = r->sr; dolog ("SR[%d] -> %#x\n", GET_BM (index), val); break; case PI_PICB: case PO_PICB: case MC_PICB: r = &s->bm_regs[GET_BM (index)]; val = r->picb; dolog ("PICB[%d] -> %#x\n", GET_BM (index), val); break; default: dolog ("U nabm readw %#x -> %#x\n", addr, val); break; } return val;}static uint32_t nabm_readl (void *opaque, uint32_t addr){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; AC97BusMasterRegs *r = NULL; uint32_t index = addr - s->base[1]; uint32_t val = ~0U; switch (index) { case PI_BDBAR: case PO_BDBAR: case MC_BDBAR: r = &s->bm_regs[GET_BM (index)]; val = r->bdbar; dolog ("BMADDR[%d] -> %#x\n", GET_BM (index), val); break; case PI_CIV: case PO_CIV: case MC_CIV: r = &s->bm_regs[GET_BM (index)]; val = r->civ | (r->lvi << 8) | (r->sr << 16); dolog ("CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM (index), r->civ, r->lvi, r->sr); break; case PI_PICB: case PO_PICB: case MC_PICB: r = &s->bm_regs[GET_BM (index)]; val = r->picb | (r->piv << 16) | (r->cr << 24); dolog ("PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM (index), val, r->picb, r->piv, r->cr); break; case GLOB_CNT: val = s->glob_cnt; dolog ("glob_cnt -> %#x\n", val); break; case GLOB_STA: val = s->glob_sta | GS_S0CR; dolog ("glob_sta -> %#x\n", val); break; default: dolog ("U nabm readl %#x -> %#x\n", addr, val); break; } return val;}/** * Native audio bus master * I/O Writes */static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; AC97BusMasterRegs *r = NULL; uint32_t index = addr - s->base[1]; switch (index) { case PI_LVI: case PO_LVI: case MC_LVI: r = &s->bm_regs[GET_BM (index)]; if ((r->cr & CR_RPBM) && (r->sr & SR_DCH)) { r->sr &= ~(SR_DCH | SR_CELV); r->civ = r->piv; r->piv = (r->piv + 1) % 32; fetch_bd (s, r); } r->lvi = val % 32; dolog ("LVI[%d] <- %#x\n", GET_BM (index), val); break; case PI_CR: case PO_CR: case MC_CR: r = &s->bm_regs[GET_BM (index)]; if (val & CR_RR) { reset_bm_regs (s, r); } else { r->cr = val & CR_VALID_MASK; if (!(r->cr & CR_RPBM)) { voice_set_active (s, r - s->bm_regs, 0); r->sr |= SR_DCH; } else { r->civ = r->piv; r->piv = (r->piv + 1) % 32; fetch_bd (s, r); r->sr &= ~SR_DCH; voice_set_active (s, r - s->bm_regs, 1); } } dolog ("CR[%d] <- %#x (cr %#x)\n", GET_BM (index), val, r->cr); break; case PI_SR: case PO_SR: case MC_SR: r = &s->bm_regs[GET_BM (index)]; r->sr |= val & ~(SR_RO_MASK | SR_WCLEAR_MASK); update_sr (s, r, r->sr & ~(val & SR_WCLEAR_MASK)); dolog ("SR[%d] <- %#x (sr %#x)\n", GET_BM (index), val, r->sr); break; default: dolog ("U nabm writeb %#x <- %#x\n", addr, val); break; }}static void nabm_writew (void *opaque, uint32_t addr, uint32_t val){ PCIAC97LinkState *d = opaque; AC97LinkState *s = &d->ac97; AC97BusMasterRegs *r = NULL; uint32_t index = addr - s->base[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -