Index: gnu/dev/sound/pci/emu10k1.h =================================================================== RCS file: /home/ncvs/src/sys/gnu/dev/sound/pci/emu10k1.h,v retrieving revision 1.5 diff -u -p -r1.5 emu10k1.h --- gnu/dev/sound/pci/emu10k1.h 24 May 2001 18:19:00 -0000 1.5 +++ gnu/dev/sound/pci/emu10k1.h 1 Apr 2003 14:54:29 -0000 @@ -66,6 +66,7 @@ /* accessed. For non per-channel registers the */ /* value should be set to zero. */ #define PTR_ADDRESS_MASK 0x07ff0000 /* Register index */ +#define A_PTR_ADDRESS_MASK 0x0fff0000 #define DATA 0x04 /* Indexed register set data register */ @@ -671,4 +672,87 @@ #define ENV_ON 0x80 #define ENV_OFF 0x00 + +/* Inputs */ +#define EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */ +#define EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */ +#define EXTIN_SPDIF_CD_L 0x02 /* internal S/PDIF CD - onboard - left */ +#define EXTIN_SPDIF_CD_R 0x03 /* internal S/PDIF CD - onboard - right */ +#define EXTIN_ZOOM_L 0x04 /* Zoom Video I2S - left */ +#define EXTIN_ZOOM_R 0x05 /* Zoom Video I2S - right */ +#define EXTIN_TOSLINK_L 0x06 /* LiveDrive - TOSLink Optical - left */ +#define EXTIN_TOSLINK_R 0x07 /* LiveDrive - TOSLink Optical - right */ +#define EXTIN_LINE1_L 0x08 /* LiveDrive - Line/Mic 1 - left */ +#define EXTIN_LINE1_R 0x09 /* LiveDrive - Line/Mic 1 - right */ +#define EXTIN_COAX_SPDIF_L 0x0a /* LiveDrive - Coaxial S/PDIF - left */ +#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */ +#define EXTIN_LINE2_L 0x0c /* LiveDrive - Line/Mic 2 - left */ +#define EXTIN_LINE2_R 0x0d /* LiveDrive - Line/Mic 2 - right */ + +/* Outputs */ +#define EXTOUT_AC97_L 0x00 /* AC'97 playback channel - left */ +#define EXTOUT_AC97_R 0x01 /* AC'97 playback channel - right */ +#define EXTOUT_TOSLINK_L 0x02 /* LiveDrive - TOSLink Optical - left */ +#define EXTOUT_TOSLINK_R 0x03 /* LiveDrive - TOSLink Optical - right */ +#define EXTOUT_CENTER 0x04 /* SB Live 5.1 - center */ +#define EXTOUT_LFE 0x05 /* SB Live 5.1 - LFE */ +#define EXTOUT_HEADPHONE_L 0x06 /* LiveDrive - Headphone - left */ +#define EXTOUT_HEADPHONE_R 0x07 /* LiveDrive - Headphone - right */ +#define EXTOUT_REAR_L 0x08 /* Rear channel - left */ +#define EXTOUT_REAR_R 0x09 /* Rear channel - right */ +#define EXTOUT_ADC_CAP_L 0x0a /* ADC Capture buffer - left */ +#define EXTOUT_ADC_CAP_R 0x0b /* ADC Capture buffer - right */ +#define EXTOUT_MIC_CAP 0x0c /* MIC Capture buffer */ +#define EXTOUT_ACENTER 0x11 /* Analog Center */ +#define EXTOUT_ALFE 0x12 /* Analog LFE */ + +/* Audigy Inputs */ +#define A_EXTIN_AC97_L 0x00 /* AC'97 capture channel - left */ +#define A_EXTIN_AC97_R 0x01 /* AC'97 capture channel - right */ +#define A_EXTIN_SPDIF_CD_L 0x02 /* digital CD left */ +#define A_EXTIN_SPDIF_CD_R 0x03 /* digital CD left */ +#define A_EXTIN_OPT_SPDIF_L 0x04 /* audigy drive Optical SPDIF - left */ +#define A_EXTIN_OPT_SPDIF_R 0x05 /* right */ + +#define A_EXTIN_LINE2_L 0x08 /* audigy drive line2/mic2 - left */ +#define A_EXTIN_LINE2_R 0x09 /* right */ +#define A_EXTIN_RCA_SPDIF_L 0x0a /* audigy drive RCA SPDIF - left */ +#define A_EXTIN_RCA_SPDIF_R 0x0b /* right */ +#define A_EXTIN_AUX2_L 0x0c /* audigy drive aux2 - left */ +#define A_EXTIN_AUX2_R 0x0d /* - right */ + +/* Audigy Outputs */ +#define A_EXTOUT_FRONT_L 0x00 /* digital front left */ +#define A_EXTOUT_FRONT_R 0x01 /* right */ +#define A_EXTOUT_CENTER 0x02 /* digital front center */ +#define A_EXTOUT_LFE 0x03 /* digital front lfe */ +#define A_EXTOUT_HEADPHONE_L 0x04 /* headphone audigy drive left */ +#define A_EXTOUT_HEADPHONE_R 0x05 /* right */ +#define A_EXTOUT_REAR_L 0x06 /* digital rear left */ +#define A_EXTOUT_REAR_R 0x07 /* right */ +#define A_EXTOUT_AFRONT_L 0x08 /* analog front left */ +#define A_EXTOUT_AFRONT_R 0x09 /* right */ +#define A_EXTOUT_ACENTER 0x0a /* analog center */ +#define A_EXTOUT_ALFE 0x0b /* analog LFE */ +/* 0x0c ?? */ +/* 0x0d ?? */ +#define A_EXTOUT_AREAR_L 0x0e /* analog rear left */ +#define A_EXTOUT_AREAR_R 0x0f /* right */ +#define A_EXTOUT_AC97_L 0x10 /* AC97 left (front) */ +#define A_EXTOUT_AC97_R 0x11 /* right */ +#define A_EXTOUT_ADC_CAP_L 0x16 /* ADC capture buffer left */ +#define A_EXTOUT_ADC_CAP_R 0x17 /* right */ + +/* Audigy bits */ +#define A_FXRT1 0x7e +#define A_FXRT2 0x7c +#define A_SENDAMOUNTS 0x7d +#define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */ +#define A_DBG 0x53 +#define A_FXGPREGBASE 0x400 /* Audigy GPRs, 0x400 to 0x5ff */ +#define A_ADCCR_RCHANENABLE 0x00000020 +#define A_ADCCR_LCHANENABLE 0x00000010 + +#define A_ADCIDX 0x63 +#define A_MICROCODEBASE 0x600 #endif /* EMU10K1_H */ Index: dev/sound/pci/emu10k1.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pci/emu10k1.c,v retrieving revision 1.33 diff -u -p -r1.33 emu10k1.c --- dev/sound/pci/emu10k1.c 26 Feb 2003 16:11:18 -0000 1.33 +++ dev/sound/pci/emu10k1.c 1 Apr 2003 14:54:39 -0000 @@ -104,6 +104,7 @@ struct sc_info { unsigned int bufsz; int timer, timerinterval; int pnum, rnum; + int audigy; struct emu_mem mem; struct emu_voice voice[64]; struct sc_pchinfo pch[EMU_CHANS]; @@ -205,7 +206,8 @@ emu_rdptr(struct sc_info *sc, int chn, i { u_int32_t ptr, val, mask, size, offset; - ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK); + ptr = ((reg << 16) & (sc->audigy ? A_PTR_ADDRESS_MASK : + PTR_ADDRESS_MASK)) | (chn & PTR_CHANNELNUM_MASK); emu_wr(sc, PTR, ptr, 4); val = emu_rd(sc, DATA, 4); if (reg & 0xff000000) { @@ -223,7 +225,8 @@ emu_wrptr(struct sc_info *sc, int chn, i { u_int32_t ptr, mask, size, offset; - ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK); + ptr = ((reg << 16) & (sc->audigy ? A_PTR_ADDRESS_MASK : + PTR_ADDRESS_MASK)) | (chn & PTR_CHANNELNUM_MASK); emu_wr(sc, PTR, ptr, 4); if (reg & 0xff000000) { size = (reg >> 24) & 0x3f; @@ -239,7 +242,8 @@ emu_wrptr(struct sc_info *sc, int chn, i static void emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data) { - emu_wrptr(sc, 0, MICROCODEBASE + pc, data); + emu_wrptr(sc, 0, (sc->audigy ? A_MICROCODEBASE : MICROCODEBASE) + pc, + data); } /* -------------------------------------------------------------------- */ @@ -775,7 +779,7 @@ emurchan_init(kobj_t obj, void *devinfo, ch->num = sc->rnum; switch(sc->rnum) { case 0: - ch->idxreg = ADCIDX; + ch->idxreg = sc->audigy ? A_ADCIDX : ADCIDX; ch->basereg = ADCBA; ch->sizereg = ADCBS; ch->setupreg = ADCCR; @@ -889,9 +893,11 @@ emurchan_trigger(kobj_t obj, void *data, ch->run = 1; emu_wrptr(sc, 0, ch->sizereg, sz); if (ch->num == 0) { - val = ADCCR_LCHANENABLE; + val = sc->audigy ? + A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE; if (ch->fmt & AFMT_STEREO) - val |= ADCCR_RCHANENABLE; + val |= sc->audigy ? + A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE; val |= emu_recval(ch->spd); emu_wrptr(sc, 0, ch->setupreg, 0); emu_wrptr(sc, 0, ch->setupreg, val); @@ -1147,8 +1153,9 @@ emu_memstart(struct sc_info *sc, void *b static void emu_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y, u_int32_t *pc) { - emu_wrefx(sc, (*pc) * 2, (x << 10) | y); - emu_wrefx(sc, (*pc) * 2 + 1, (op << 20) | (z << 10) | w); + emu_wrefx(sc, (*pc) * 2, (x << sc->audigy ? 12 : 10) | y); + emu_wrefx(sc, (*pc) * 2 + 1, (op << sc->audigy ? 24 : 20) | + (z << sc->audigy ? 12 : 10) | w); (*pc)++; } @@ -1157,6 +1164,10 @@ emu_initefx(struct sc_info *sc) { int i; u_int32_t pc = 16; + u_int32_t gpr = sc->audigy ? A_FXGPREGBASE : FXGPREGBASE; + u_int32_t extin = sc->audigy ? 0x40 : 0x10; + u_int32_t extout = sc->audigy ? 0x60 : 0x20; + u_int8_t is_audigy = sc->audigy; for (i = 0; i < 512; i++) { emu_wrefx(sc, i * 2, 0x10040); @@ -1164,7 +1175,7 @@ emu_initefx(struct sc_info *sc) } for (i = 0; i < 256; i++) - emu_wrptr(sc, 0, FXGPREGBASE + i, 0); + emu_wrptr(sc, 0, gpr + i, 0); /* FX-8010 DSP Registers: FX Bus @@ -1208,32 +1219,46 @@ emu_initefx(struct sc_info *sc) /* Routing - this will be configurable in later version */ /* GPR[0/1] = FX * 4 + SPDIF-in */ - emu_addefxop(sc, 4, 0x100, 0x12, 0, 0x44, &pc); - emu_addefxop(sc, 4, 0x101, 0x13, 1, 0x44, &pc); + emu_addefxop(sc, 4, gpr, extin + is_audigy ? + A_EXTIN_SPDIF_CD_L : EXTIN_SPDIF_CD_L, 0, 0x44, &pc); + emu_addefxop(sc, 4, gpr + 1, extin + is_audigy ? + A_EXTIN_SPDIF_CD_R : EXTIN_SPDIF_CD_R, 1, 0x44, &pc); /* GPR[0/1] += APS-input */ - emu_addefxop(sc, 6, 0x100, 0x100, 0x40, sc->APS ? 0x16 : 0x40, &pc); - emu_addefxop(sc, 6, 0x101, 0x101, 0x40, sc->APS ? 0x17 : 0x40, &pc); + emu_addefxop(sc, 6, gpr, gpr, 0x40, sc->APS ? 0x16 : 0x40, &pc); + emu_addefxop(sc, 6, gpr + 1, gpr + 1, 0x40, sc->APS ? 0x17 : 0x40, &pc); /* FrontOut (AC97) = GPR[0/1] */ - emu_addefxop(sc, 6, 0x20, 0x40, 0x40, 0x100, &pc); - emu_addefxop(sc, 6, 0x21, 0x40, 0x41, 0x101, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_AC97_L : EXTOUT_AC97_L, 0x40, 0x40, gpr, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_AC97_R : EXTOUT_AC97_L, 0x40, 0x41, gpr + 1, &pc); /* RearOut = (GPR[0/1] * RearVolume) >> 31 */ /* RearVolume = GRP[0x10/0x11] */ - emu_addefxop(sc, 0, 0x28, 0x40, 0x110, 0x100, &pc); - emu_addefxop(sc, 0, 0x29, 0x40, 0x111, 0x101, &pc); + emu_addefxop(sc, 0, extout + is_audigy ? + A_EXTOUT_REAR_L : EXTOUT_REAR_L, 0x40, gpr + 10, gpr, &pc); + emu_addefxop(sc, 0, extout + is_audigy ? + A_EXTOUT_REAR_R : EXTOUT_REAR_R, 0x40, gpr + 11, gpr + 1, &pc); /* TOS out = GPR[0/1] */ - emu_addefxop(sc, 6, 0x22, 0x40, 0x40, 0x100, &pc); - emu_addefxop(sc, 6, 0x23, 0x40, 0x40, 0x101, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_FRONT_L : EXTOUT_TOSLINK_L, 0x40, 0x40, gpr, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_FRONT_R : EXTOUT_TOSLINK_R, 0x40, 0x40, gpr + 1, &pc); /* Mute Out2 */ - emu_addefxop(sc, 6, 0x24, 0x40, 0x40, 0x40, &pc); - emu_addefxop(sc, 6, 0x25, 0x40, 0x40, 0x40, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_CENTER : EXTOUT_CENTER, 0x40, 0x40, 0x40, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_LFE : EXTOUT_LFE, 0x40, 0x40, 0x40, &pc); /* Mute Out3 */ - emu_addefxop(sc, 6, 0x26, 0x40, 0x40, 0x40, &pc); - emu_addefxop(sc, 6, 0x27, 0x40, 0x40, 0x40, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_HEADPHONE_L : EXTOUT_HEADPHONE_L, 0x40, 0x40, 0x40, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_HEADPHONE_R : EXTOUT_HEADPHONE_R, 0x40, 0x40, 0x40, &pc); /* Input0 (AC97) -> Record */ - emu_addefxop(sc, 6, 0x2a, 0x40, 0x40, 0x10, &pc); - emu_addefxop(sc, 6, 0x2b, 0x40, 0x40, 0x11, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_ADC_CAP_L : EXTOUT_ADC_CAP_L, 0x40, 0x40, 0x10, &pc); + emu_addefxop(sc, 6, extout + is_audigy ? + A_EXTOUT_ADC_CAP_R : EXTOUT_ADC_CAP_R, 0x40, 0x40, 0x11, &pc); - emu_wrptr(sc, 0, DBG, 0); + emu_wrptr(sc, 0, sc->audigy ? A_DBG : DBG, 0); } /* Probe and attach the card */ @@ -1260,6 +1285,12 @@ emu_init(struct sc_info *sc) emu_wrptr(sc, 0, SOLEL, 0); emu_wrptr(sc, 0, SOLEH, 0); + if (sc->audigy) { + emu_wrptr(sc, 0, 0x5e, 0xf00); /* ?? */ + emu_wrptr(sc, 0, 0x5f, 0x3); /* ?? */ + } + + /* init envelope engine */ for (ch = 0; ch < NUM_G; ch++) { emu_wrptr(sc, ch, DCYSUSV, ENV_OFF); @@ -1275,7 +1306,7 @@ emu_init(struct sc_info *sc) emu_wrptr(sc, ch, CCCA, 0); emu_wrptr(sc, ch, Z1, 0); emu_wrptr(sc, ch, Z2, 0); - emu_wrptr(sc, ch, FXRT, 0xd01c0000); + emu_wrptr(sc, ch, sc->audigy ? A_FXRT1 : FXRT, 0xd01c0000); emu_wrptr(sc, ch, ATKHLDM, 0); emu_wrptr(sc, ch, DCYSUSM, 0); @@ -1293,6 +1324,16 @@ emu_init(struct sc_info *sc) emu_wrptr(sc, ch, ENVVOL, 0); emu_wrptr(sc, ch, ENVVAL, 0); + if (sc->audigy) { + emu_wrptr(sc, ch, 0x4c, 0); /* ?? */ + emu_wrptr(sc, ch, 0x4d, 0); /* ?? */ + emu_wrptr(sc, ch, 0x4e, 0); /* ?? */ + emu_wrptr(sc, ch, 0x4f, 0); /* ?? */ + emu_wrptr(sc, ch, A_FXRT1, 0x03020100); + emu_wrptr(sc, ch, A_FXRT2, 0x3f3f3f3f); + emu_wrptr(sc, ch, A_SENDAMOUNTS, 0); + } + sc->voice[ch].vnum = ch; sc->voice[ch].slave = NULL; sc->voice[ch].busy = 0; @@ -1365,10 +1406,16 @@ emu_init(struct sc_info *sc) * Lock Sound Memory = 0 * Auto Mute = 1 */ - tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE | HCFG_AUTOMUTE; + if (sc->audigy) + tmp = HCFG_AUDIOENABLE | HCFG_AUTOMUTE | HCFG_JOYENABLE; + else + tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE | HCFG_AUTOMUTE; if (sc->rev >= 6) tmp |= HCFG_JOYENABLE; emu_wr(sc, HCFG, tmp, 4); + if (sc->audigy) + emu_wr(sc, A_IOCFG, emu_rd(sc, A_IOCFG, 4) & ~0x44, 4); + /* TOSLink detection */ sc->tos_link = 0; @@ -1434,16 +1481,21 @@ static int emu_pci_probe(device_t dev) { char *s = NULL; + struct sc_info *sc; switch (pci_get_devid(dev)) { case EMU10K1_PCI_ID: + sc = device_get_softc(dev); + sc->audigy = 0; s = "Creative EMU10K1"; break; -/* + case EMU10K2_PCI_ID: + sc = device_get_softc(dev); + sc->audigy = 1; s = "Creative EMU10K2"; break; -*/ + default: return ENXIO; }