This is a discussion on Creative SB Audigy support for emu(4) within the lucky.openbsd.tech forums, part of the OpenBSD category; --> A call out to emu(4) users... that means SB Live! and now Audigy/Audigy 2/Audigy 4. The patch below adds ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| A call out to emu(4) users... that means SB Live! and now Audigy/Audigy 2/Audigy 4. The patch below adds initial support for SB Audigy cards. If you have any of the above listed cards can you please try this out? I'd like to make sure there are no regressions with known working SB Live! cards and that hopefully the Audigy stuff just works on at least a few different cards. I do not have any hardware supported by this driver, so I haven't tested this other than making sure it compiles, YMMV. Patch based on a diff from jakemsr@ which came from NetBSD. Two additional commits from NetBSD were merged for big endian support and typos. I added the use of pci_matchbyid(). Index: emuxki.c ================================================== ================= RCS file: /cvs/src/sys/dev/pci/emuxki.c,v retrieving revision 1.21 diff -u -p -r1.21 emuxki.c --- emuxki.c 21 Nov 2005 18:16:41 -0000 1.21 +++ emuxki.c 27 Nov 2005 12:20:50 -0000 @@ -44,7 +44,7 @@ * - inversed stereo at ac97 codec level * (XXX jdolecek - don't see the problem? maybe because auvia(4) has * it swapped too?) - * - bass disapear when you plug rear jack-in on Cambridge FPS2000 speakers + * - bass disappear when you plug rear jack-in on Cambridge FPS2000 speakers * (and presumably all speakers that support front and rear jack-in) * * TODO: @@ -52,7 +52,7 @@ * - (midi/mpu),joystick support * - Multiple voices play (problem with /dev/audio architecture) * - Multiple sources recording (Pb with audio(4)) - * - Independant modification of each channel's parameters (via mixer ?) + * - Independent modification of each channel's parameters (via mixer ?) * - DSP FX patches (to make fx like chipmunk) */ @@ -123,7 +123,7 @@ void emuxki_voice_dataloc_destroy(struct void emuxki_voice_commit_parms(struct emuxki_voice *); void emuxki_voice_recsrc_release(struct emuxki_softc *sc, emuxki_recsrc_t source); int emuxki_recsrc_reserve(struct emuxki_voice *voice, emuxki_recsrc_t source); -int emuxki_recsrc_rate_to_index(int srate); +int emuxki_voice_adc_rate(struct emuxki_voice *); u_int32_t emuxki_voice_curaddr(struct emuxki_voice *); int emuxki_set_vparms(struct emuxki_voice *voice, struct audio_params *p); int emuxki_voice_set_srate(struct emuxki_voice *voice, u_int32_t srate); @@ -136,6 +136,7 @@ struct emuxki_channel *emuxki_channel_ne void emuxki_channel_delete(struct emuxki_channel *chan); void emuxki_channel_start(struct emuxki_channel *chan); void emuxki_channel_stop(struct emuxki_channel *chan); +void emuxki_channel_commit_fx(struct emuxki_channel *chan); void emuxki_channel_commit_parms(struct emuxki_channel *chan); void emuxki_channel_set_bufparms(struct emuxki_channel *chan, u_int32_t start, u_int32_t end); void emuxki_channel_set_srate(struct emuxki_channel *chan, u_int32_t srate); @@ -204,6 +205,13 @@ int emuxki_ac97_read(void *, u_int8_t, int emuxki_ac97_write(void *, u_int8_t, u_int16_t); void emuxki_ac97_reset(void *); +const struct pci_matchid emuxki_devices[] = { + { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_SBLIVE }, + { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_SBLIVE2 }, + { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY }, + { PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY2 }, +}; + /* * Autoconfig goo. */ @@ -248,16 +256,12 @@ struct audio_hw_if emuxki_hw_if = { emuxki_trigger_input, }; -static const int emuxki_recsrc_adcrates[] = - { 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000, -1 }; #if 0 static const int emuxki_recsrc_intrmasks[EMU_NUMRECSRCS] = { EMU_INTE_MICBUFENABLE, EMU_INTE_ADCBUFENABLE, EMU_INTE_EFXBUFENABLE }; #endif static const u_int32_t emuxki_recsrc_bufaddrreg[EMU_NUMRECSRCS] = { EMU_MICBA, EMU_ADCBA, EMU_FXBA }; -static const u_int32_t emuxki_recsrc_idxreg[EMU_NUMRECSRCS] = - { EMU_RECIDX(EMU_MICIDX), EMU_RECIDX(EMU_ADCIDX), EMU_RECIDX(EMU_FXIDX) }; static const u_int32_t emuxki_recsrc_szreg[EMU_NUMRECSRCS] = { EMU_MICBS, EMU_ADCBS, EMU_FXBS }; static const int emuxki_recbuf_sz[] = { @@ -375,14 +379,29 @@ emuxki_scinit(struct emuxki_softc *sc) if ((err = emuxki_init(sc))) return (err); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG, - EMU_HCFG_AUDIOENABLE | - EMU_HCFG_LOCKTANKCACHE_MASK | EMU_HCFG_AUTOMUTE); + if (sc->sc_type & EMUXKI_AUDIGY2) { + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG, + EMU_HCFG_AUDIOENABLE | EMU_HCFG_AC3ENABLE_CDSPDIF | + EMU_HCFG_AC3ENABLE_GPSPDIF | EMU_HCFG_AUTOMUTE); + } else if (sc->sc_type & EMUXKI_AUDIGY) { + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG, + EMU_HCFG_AUDIOENABLE | EMU_HCFG_AUTOMUTE); + } else { + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG, + EMU_HCFG_AUDIOENABLE | + EMU_HCFG_LOCKTANKCACHE_MASK | EMU_HCFG_AUTOMUTE); + } bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_INTE, bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_INTE) | EMU_INTE_VOLINCRENABLE | EMU_INTE_VOLDECRENABLE | EMU_INTE_MUTEENABLE); + if (sc->sc_type & EMUXKI_AUDIGY2) { + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG, + EMU_A_IOCFG_GPOUT0 | + bus_space_read_4(sc->sc_iot, sc->sc_ioh, EMU_A_IOCFG)); + } + /* No multiple voice support for now */ sc->pvoice = sc->rvoice = NULL; @@ -404,14 +423,8 @@ emuxki_ac97_init(struct emuxki_softc *sc int emuxki_match(struct device *parent, void *match, void *aux) { - struct pci_attach_args *pa = aux; - - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CREATIVELABS && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_SBLIVE || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_SBLIVE2)) - return (1); - - return (0); + return (pci_matchbyid((struct pci_attach_args *)aux, emuxki_devices, + sizeof(emuxki_devices)/sizeof(emuxki_devices[0]))); } void @@ -450,10 +463,15 @@ emuxki_attach(struct device *parent, str } printf(": %s\n", intrstr); - /* XXX it's unknown wheather APS is made from Audigy as well */ + /* XXX it's unknown whether APS is made from Audigy as well */ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_AUDIGY) { sc->sc_type = EMUXKI_AUDIGY; - strlcpy(sc->sc_audv.name, "Audigy", sizeof sc->sc_audv.name); + if (PCI_REVISION(pa->pa_class) == 0x04) { + sc->sc_type |= EMUXKI_AUDIGY2; + strlcpy(sc->sc_audv.name, "Audigy2", sizeof sc->sc_audv.name); + } else { + strlcpy(sc->sc_audv.name, "Audigy", sizeof sc->sc_audv.name); + } } else if (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG) == EMU_SUBSYS_APS) { sc->sc_type = EMUXKI_APS; @@ -569,7 +587,9 @@ emuxki_read(struct emuxki_softc *sc, u_i u_int8_t size, offset = 0; int s; - ptr = ((((u_int32_t) reg) << 16) & EMU_PTR_ADDR_MASK) | + ptr = ((((u_int32_t) reg) << 16) & + (sc->sc_type & EMUXKI_AUDIGY ? + EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) | (chano & EMU_PTR_CHNO_MASK); if (reg & 0xff000000) { size = (reg >> 24) & 0x3f; @@ -594,7 +614,9 @@ emuxki_write(struct emuxki_softc *sc, u_ u_int8_t size, offset; int s; - ptr = ((((u_int32_t) reg) << 16) & EMU_PTR_ADDR_MASK) | + ptr = ((((u_int32_t) reg) << 16) & + (sc->sc_type & EMUXKI_AUDIGY ? + EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK)) | (chano & EMU_PTR_CHNO_MASK); /* BE CAREFUL WITH THAT AXE, EUGENE */ @@ -620,20 +642,33 @@ emuxki_write(struct emuxki_softc *sc, u_ void emuxki_write_micro(struct emuxki_softc *sc, u_int32_t pc, u_int32_t data) { - emuxki_write(sc, 0, EMU_MICROCODEBASE + pc, data); + emuxki_write(sc, 0, + (sc->sc_type & EMUXKI_AUDIGY ? + EMU_A_MICROCODEBASE : EMU_MICROCODEBASE) + pc, + data); } void emuxki_dsp_addop(struct emuxki_softc *sc, u_int16_t *pc, u_int8_t op, u_int16_t r, u_int16_t a, u_int16_t x, u_int16_t y) { - emuxki_write_micro(sc, *pc << 1, - ((x << 10) & EMU_DSP_LOWORD_OPX_MASK) | - (y & EMU_DSP_LOWORD_OPY_MASK)); - emuxki_write_micro(sc, (*pc << 1) + 1, - ((op << 20) & EMU_DSP_HIWORD_OPCODE_MASK) | - ((r << 10) & EMU_DSP_HIWORD_RESULT_MASK) | - (a & EMU_DSP_HIWORD_OPA_MASK)); + if (sc->sc_type & EMUXKI_AUDIGY) { + emuxki_write_micro(sc, *pc << 1, + ((x << 12) & EMU_A_DSP_LOWORD_OPX_MASK) | + (y & EMU_A_DSP_LOWORD_OPY_MASK)); + emuxki_write_micro(sc, (*pc << 1) + 1, + ((op << 24) & EMU_A_DSP_HIWORD_OPCODE_MASK) | + ((r << 12) & EMU_A_DSP_HIWORD_RESULT_MASK) | + (a & EMU_A_DSP_HIWORD_OPA_MASK)); + } else { + emuxki_write_micro(sc, *pc << 1, + ((x << 10) & EMU_DSP_LOWORD_OPX_MASK) | + (y & EMU_DSP_LOWORD_OPY_MASK)); + emuxki_write_micro(sc, (*pc << 1) + 1, + ((op << 20) & EMU_DSP_HIWORD_OPCODE_MASK) | + ((r << 10) & EMU_DSP_HIWORD_RESULT_MASK) | + (a & EMU_DSP_HIWORD_OPA_MASK)); + } (*pc)++; } @@ -652,43 +687,86 @@ emuxki_initfx(struct emuxki_softc *sc) emuxki_write(sc, 0, EMU_TANKMEMADDRREGBASE + pc, 0); } pc = 0; - /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */ - emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, - EMU_DSP_OUTL(EMU_DSP_OUT_AC97), - EMU_DSP_CST(0), - EMU_DSP_FX(0), EMU_DSP_CST(4)); - emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, - EMU_DSP_OUTR(EMU_DSP_OUT_AC97), - EMU_DSP_CST(0), - EMU_DSP_FX(1), EMU_DSP_CST(4)); - /* Rear channel OUT (l/r) = FX[2/3] * 4 */ + if (sc->sc_type & EMUXKI_AUDIGY) { + /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */ + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_FRONT), + EMU_A_DSP_CST(0), + EMU_DSP_FX(0), EMU_A_DSP_CST(4)); + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_FRONT), + EMU_A_DSP_CST(0), + EMU_DSP_FX(1), EMU_A_DSP_CST(4)); + + /* Rear channel OUT (l/r) = FX[2/3] * 4 */ +#if 0 + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_REAR), + EMU_A_DSP_OUTL(EMU_A_DSP_OUT_A_FRONT), + EMU_DSP_FX(0), EMU_A_DSP_CST(4)); + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_REAR), + EMU_A_DSP_OUTR(EMU_A_DSP_OUT_A_FRONT), + EMU_DSP_FX(1), EMU_A_DSP_CST(4)); +#endif + /* ADC recording (l/r) = AC97 In (l/r) */ + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, + EMU_A_DSP_OUTL(EMU_A_DSP_OUT_ADC), + EMU_A_DSP_INL(EMU_DSP_IN_AC97), + EMU_A_DSP_CST(0), EMU_A_DSP_CST(0)); + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, + EMU_A_DSP_OUTR(EMU_A_DSP_OUT_ADC), + EMU_A_DSP_INR(EMU_DSP_IN_AC97), + EMU_A_DSP_CST(0), EMU_A_DSP_CST(0)); + + /* zero out the rest of the microcode */ + while (pc < 512) + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, + EMU_A_DSP_CST(0), EMU_A_DSP_CST(0), + EMU_A_DSP_CST(0), EMU_A_DSP_CST(0)); + + emuxki_write(sc, 0, EMU_A_DBG, 0); /* Is it really necessary ? */ + } else { + /* AC97 Out (l/r) = AC97 In (l/r) + FX[0/1] * 4 */ + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_DSP_OUTL(EMU_DSP_OUT_A_FRONT), + EMU_DSP_CST(0), + EMU_DSP_FX(0), EMU_DSP_CST(4)); + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_DSP_OUTR(EMU_DSP_OUT_A_FRONT), + EMU_DSP_CST(0), + EMU_DSP_FX(1), EMU_DSP_CST(4)); + + /* Rear channel OUT (l/r) = FX[2/3] * 4 */ #if 0 - emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, - EMU_DSP_OUTL(EMU_DSP_OUT_RCHAN), - EMU_DSP_OUTL(EMU_DSP_OUT_AC97), - EMU_DSP_FX(0), EMU_DSP_CST(4)); - emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, - EMU_DSP_OUTR(EMU_DSP_OUT_RCHAN), - EMU_DSP_OUTR(EMU_DSP_OUT_AC97), - EMU_DSP_FX(1), EMU_DSP_CST(4)); + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_DSP_OUTL(EMU_DSP_OUT_AD_REAR), + EMU_DSP_OUTL(EMU_DSP_OUT_A_FRONT), + EMU_DSP_FX(0), EMU_DSP_CST(4)); + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_MACINTS, + EMU_DSP_OUTR(EMU_DSP_OUT_AD_REAR), + EMU_DSP_OUTR(EMU_DSP_OUT_A_FRONT), + EMU_DSP_FX(1), EMU_DSP_CST(4)); #endif - /* ADC recording (l/r) = AC97 In (l/r) */ - emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, - EMU_DSP_OUTL(EMU_DSP_OUT_ADC), - EMU_DSP_INL(EMU_DSP_IN_AC97), - EMU_DSP_CST(0), EMU_DSP_CST(0)); - emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, - EMU_DSP_OUTR(EMU_DSP_OUT_ADC), - EMU_DSP_INR(EMU_DSP_IN_AC97), - EMU_DSP_CST(0), EMU_DSP_CST(0)); - /* zero out the rest of the microcode */ - while (pc < 512) + /* ADC recording (l/r) = AC97 In (l/r) */ + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, + EMU_DSP_OUTL(EMU_DSP_OUT_ADC), + EMU_DSP_INL(EMU_DSP_IN_AC97), + EMU_DSP_CST(0), EMU_DSP_CST(0)); emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, - EMU_DSP_CST(0), EMU_DSP_CST(0), + EMU_DSP_OUTR(EMU_DSP_OUT_ADC), + EMU_DSP_INR(EMU_DSP_IN_AC97), EMU_DSP_CST(0), EMU_DSP_CST(0)); - emuxki_write(sc, 0, EMU_DBG, 0); /* Is it really necessary ? */ + /* zero out the rest of the microcode */ + while (pc < 512) + emuxki_dsp_addop(sc, &pc, EMU_DSP_OP_ACC3, + EMU_DSP_CST(0), EMU_DSP_CST(0), + EMU_DSP_CST(0), EMU_DSP_CST(0)); + + emuxki_write(sc, 0, EMU_DBG, 0); /* Is it really necessary ? */ + } } int @@ -712,6 +790,11 @@ emuxki_init(struct emuxki_softc *sc) emuxki_write(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE); emuxki_write(sc, 0, EMU_ADCBA, 0); + if(sc->sc_type & EMUXKI_AUDIGY) { + emuxki_write(sc, 0, EMU_SPBYPASS, EMU_SPBYPASS_24_BITS); + emuxki_write(sc, 0, EMU_AC97SLOT, EMU_AC97SLOT_CENTER | EMU_AC97SLOT_LFE); + } + /* Initialize all channels to stopped and no effects */ for (i = 0; i < EMU_NUMCHAN; i++) { emuxki_write(sc, i, EMU_CHAN_DCYSUSV, 0); @@ -754,6 +837,18 @@ emuxki_init(struct emuxki_softc *sc) emuxki_write(sc, 0, EMU_SPCS1, spcs); emuxki_write(sc, 0, EMU_SPCS2, spcs); + if(sc->sc_type & EMUXKI_AUDIGY2) { + emuxki_write(sc, 0, EMU_A2_SPDIF_SAMPLERATE, EMU_A2_SPDIF_UNKNOWN); + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCSEL); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, + EMU_A2_SRCSEL_ENABLE_SPDIF | EMU_A2_SRCSEL_ENABLE_SRCMULTI); + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_PTR, EMU_A2_SRCMULTI); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_A2_DATA, EMU_A2_SRCMULTI_ENABLE_INPUT); + } + + /* Let's play with sound processor */ emuxki_initfx(sc); @@ -783,7 +878,7 @@ emuxki_init(struct emuxki_softc *sc) silentpage = DMAADDR(sc->silentpage) << 1; ptb = KERNADDR(sc->ptb); for (i = 0; i < EMU_MAXPTE; i++) - ptb[i] = silentpage | i; + ptb[i] = htole32(silentpage | i); /* Write PTB address and set TCB to none */ emuxki_write(sc, 0, EMU_PTB, DMAADDR(sc->ptb)); @@ -844,7 +939,12 @@ emuxki_shutdown(struct emuxki_softc *sc) emuxki_write(sc, 0, EMU_MICBA, 0); emuxki_write(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE); emuxki_write(sc, 0, EMU_FXBA, 0); - emuxki_write(sc, 0, EMU_FXWC, 0); + if(sc->sc_type & EMUXKI_AUDIGY) { + emuxki_write(sc, 0, EMU_A_FXWC1, 0); + emuxki_write(sc, 0, EMU_A_FXWC2, 0); + } else { + emuxki_write(sc, 0, EMU_FXWC, 0); + } emuxki_write(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE); emuxki_write(sc, 0, EMU_ADCBA, 0); @@ -903,11 +1003,12 @@ emuxki_pmem_alloc(struct emuxki_softc *s numblocks++; for (i = 0; i < EMU_MAXPTE; i++) - if ((ptb[i] & EMU_CHAN_MAP_PTE_MASK) == silentpage) { + if ((letoh32(ptb[i]) & EMU_CHAN_MAP_PTE_MASK) == silentpage) { /* We look for a free PTE */ s = splaudio(); for (j = 0; j < numblocks; j++) - if ((ptb[i + j] & EMU_CHAN_MAP_PTE_MASK) + if ((letoh32(ptb[i + j]) + & EMU_CHAN_MAP_PTE_MASK) != silentpage) break; if (j == numblocks) { @@ -918,9 +1019,8 @@ emuxki_pmem_alloc(struct emuxki_softc *s } for (j = 0; j < numblocks; j++) ptb[i + j] = - (((DMAADDR(mem->dmamem) + - j * EMU_PTESIZE)) << 1) - | (i + j); + htole32((((DMAADDR(mem->dmamem) + + j * EMU_PTESIZE)) << 1) | (i + j)); LIST_INSERT_HEAD(&(sc->mem), mem, next); splx(s); return (KERNADDR(mem->dmamem)); @@ -961,11 +1061,22 @@ void emuxki_chanparms_set_defaults(struct emuxki_channel *chan) { chan->fxsend.a.level = chan->fxsend.b.level = - chan->fxsend.c.level = chan->fxsend.d.level = 0xc0; /* not max */ + chan->fxsend.c.level = chan->fxsend.d.level = + /* for audigy */ + chan->fxsend.e.level = chan->fxsend.f.level = + chan->fxsend.g.level = chan->fxsend.h.level = + chan->voice->sc->sc_type & EMUXKI_AUDIGY ? + 0xc0 : 0xff; /* not max */ + chan->fxsend.a.dest = 0x0; chan->fxsend.b.dest = 0x1; chan->fxsend.c.dest = 0x2; chan->fxsend.d.dest = 0x3; + /* for audigy */ + chan->fxsend.e.dest = 0x4; + chan->fxsend.f.dest = 0x5; + chan->fxsend.g.dest = 0x6; + chan->fxsend.h.dest = 0x7; chan->pitch.initial = 0x0000; /* shouldn't it be 0xE000 ? */ chan->pitch.current = 0x0000; /* should it be 0x0400 */ @@ -1046,6 +1157,16 @@ emuxki_channel_set_fxsend(struct emuxki_ chan->fxsend.b.dest = fxsend->b.dest; chan->fxsend.c.dest = fxsend->c.dest; chan->fxsend.d.dest = fxsend->d.dest; + + /* for audigy */ + chan->fxsend.e.level = fxsend->e.level; + chan->fxsend.f.level = fxsend->f.level; + chan->fxsend.g.level = fxsend->g.level; + chan->fxsend.h.level = fxsend->h.level; + chan->fxsend.e.dest = fxsend->e.dest; + chan->fxsend.f.dest = fxsend->f.dest; + chan->fxsend.g.dest = fxsend->g.dest; + chan->fxsend.h.dest = fxsend->h.dest; } void @@ -1070,6 +1191,44 @@ emuxki_channel_set_bufparms(struct emuxk } void +emuxki_channel_commit_fx(struct emuxki_channel *chan) +{ + struct emuxki_softc *sc = chan->voice->sc; + u_int8_t chano = chan->num; + + if(sc->sc_type & EMUXKI_AUDIGY) { + emuxki_write(sc, chano, EMU_A_CHAN_FXRT1, + (chan->fxsend.d.dest << 24) | + (chan->fxsend.c.dest << 16) | + (chan->fxsend.b.dest << 8) | + (chan->fxsend.a.dest)); + emuxki_write(sc, chano, EMU_A_CHAN_FXRT2, + (chan->fxsend.h.dest << 24) | + (chan->fxsend.g.dest << 16) | + (chan->fxsend.f.dest << 8) | + (chan->fxsend.e.dest)); + emuxki_write(sc, chano, EMU_A_CHAN_SENDAMOUNTS, + (chan->fxsend.e.level << 24) | + (chan->fxsend.f.level << 16) | + (chan->fxsend.g.level << 8) | + (chan->fxsend.h.level)); + } else { + emuxki_write(sc, chano, EMU_CHAN_FXRT, + (chan->fxsend.d.dest << 28) | + (chan->fxsend.c.dest << 24) | + (chan->fxsend.b.dest << 20) | + (chan->fxsend.a.dest << 16)); + } + + emuxki_write(sc, chano, 0x10000000 | EMU_CHAN_PTRX, + (chan->fxsend.a.level << 8) | chan->fxsend.b.level); + emuxki_write(sc, chano, EMU_CHAN_DSL, + (chan->fxsend.d.level << 24) | chan->loop.end); + emuxki_write(sc, chano, EMU_CHAN_PSST, + (chan->fxsend.c.level << 24) | chan->loop.start); +} + +void emuxki_channel_commit_parms(struct emuxki_channel *chan) { struct emuxki_voice *voice = chan->voice; @@ -1084,15 +1243,9 @@ emuxki_channel_commit_parms(struct emuxk s = splaudio(); emuxki_write(sc, chano, EMU_CHAN_CPF_STEREO, voice->stereo); - emuxki_write(sc, chano, EMU_CHAN_FXRT, - (chan->fxsend.d.dest << 28) | (chan->fxsend.c.dest << 24) | - (chan->fxsend.b.dest << 20) | (chan->fxsend.a.dest << 16)); - emuxki_write(sc, chano, 0x10000000 | EMU_CHAN_PTRX, - (chan->fxsend.a.level << 8) | chan->fxsend.b.level); - emuxki_write(sc, chano, EMU_CHAN_DSL, - (chan->fxsend.d.level << 24) | chan->loop.end); - emuxki_write(sc, chano, EMU_CHAN_PSST, - (chan->fxsend.c.level << 24) | chan->loop.start); + + emuxki_channel_commit_fx(chan); + emuxki_write(sc, chano, EMU_CHAN_CCCA, (chan->filter.lowpass_resonance_height << 28) | (chan->filter.interpolation_ROM << 25) | @@ -1202,7 +1355,7 @@ emuxki_channel_stop(struct emuxki_channe /* * Voices management - * emuxki_voice_dataloc : use(play or rec) independant dataloc union helpers + * emuxki_voice_dataloc : use(play or rec) independent dataloc union helpers * emuxki_voice_channel_* : play part of dataloc union helpers * emuxki_voice_recsrc_* : rec part of dataloc union helpers */ @@ -1262,7 +1415,7 @@ emuxki_recsrc_reserve(struct emuxki_voic { if (source < 0 || source >= EMU_NUMRECSRCS) { #ifdef EMUXKI_DEBUG - printf("Tryed to reserve invalid source: %d\n", source); + printf("Tried to reserve invalid source: %d\n", source); #endif return (EINVAL); } @@ -1274,20 +1427,6 @@ emuxki_recsrc_reserve(struct emuxki_voic return (0); } -int -emuxki_recsrc_rate_to_index(int srate) -{ - int index; - - for (index = 0; ; index++) { - if (emuxki_recsrc_adcrates[index] == srate) - return (index); - - if (emuxki_recsrc_adcrates[index] < 0) - return (-1); - } -} - /* When calling this function we assume the voice is stopped */ void emuxki_voice_recsrc_release(struct emuxki_softc *sc, emuxki_recsrc_t source) @@ -1412,13 +1551,22 @@ emuxki_voice_set_stereo(struct emuxki_vo fxsend.b.dest = 0x1; fxsend.c.dest = 0x2; fxsend.d.dest = 0x3; + /* for audigy */ + fxsend.e.dest = 0x4; + fxsend.f.dest = 0x5; + fxsend.g.dest = 0x6; + fxsend.h.dest = 0x7; if (voice->stereo) { fxsend.a.level = fxsend.c.level = 0xc0; fxsend.b.level = fxsend.d.level = 0x00; + fxsend.e.level = fxsend.g.level = 0xc0; + fxsend.f.level = fxsend.h.level = 0x00; emuxki_channel_set_fxsend(voice->dataloc.chan[0], &fxsend); fxsend.a.level = fxsend.c.level = 0x00; fxsend.b.level = fxsend.d.level = 0xc0; + fxsend.e.level = fxsend.g.level = 0x00; + fxsend.f.level = fxsend.h.level = 0xc0; emuxki_channel_set_fxsend(voice->dataloc.chan[1], &fxsend); } /* No else : default is good for mono */ @@ -1438,9 +1586,13 @@ emuxki_voice_set_srate(struct emuxki_voi emuxki_channel_set_srate(voice->dataloc.chan[1], srate); } else { - if (emuxki_recsrc_rate_to_index(srate) < 0) + if ((srate < 8000) || (srate > 48000)) return (EINVAL); voice->sample_rate = srate; + if (emuxki_voice_adc_rate(voice) < 0) { + voice->sample_rate = 0; + return (EINVAL); + } } return (0); } @@ -1571,20 +1723,38 @@ emuxki_voice_commit_parms(struct emuxki_ u_int32_t emuxki_voice_curaddr(struct emuxki_voice *voice) { + int idxreg = 0; /* XXX different semantics in these cases */ - if (voice->use & EMU_VOICE_USE_PLAY) + if (voice->use & EMU_VOICE_USE_PLAY) { /* returns number of samples (an l/r pair counts 1) */ return (emuxki_read(voice->sc, voice->dataloc.chan[0]->num, EMU_CHAN_CCCA_CURRADDR) - voice->dataloc.chan[0]->loop.start); - else + } else { /* returns number of bytes */ - return (emuxki_read(voice->sc, 0, - emuxki_recsrc_idxreg[voice->dataloc.source]) & - EMU_RECIDX_MASK); - + switch (voice->dataloc.source) { + case EMU_RECSRC_MIC: + idxreg = (voice->sc->sc_type & EMUXKI_AUDIGY) ? + EMU_A_MICIDX : EMU_MICIDX; + break; + case EMU_RECSRC_ADC: + idxreg = (voice->sc->sc_type & EMUXKI_AUDIGY) ? + EMU_A_ADCIDX : EMU_ADCIDX; + break; + case EMU_RECSRC_FX: + idxreg = EMU_FXIDX; + break; + default: +#ifdef EMUXKI_DEBUG + printf("emu: bad recording source!\n"); +#endif + break; + } + return (emuxki_read(voice->sc, 0, EMU_RECIDX(idxreg)) + & EMU_RECIDX_MASK); + } return (0); } @@ -1622,6 +1792,59 @@ emuxki_resched_timer(struct emuxki_softc splx(s); } +int +emuxki_voice_adc_rate(struct emuxki_voice *voice) +{ + switch(voice->sample_rate) { + case 48000: + return EMU_ADCCR_SAMPLERATE_48; + break; + case 44100: + return EMU_ADCCR_SAMPLERATE_44; + break; + case 32000: + return EMU_ADCCR_SAMPLERATE_32; + break; + case 24000: + return EMU_ADCCR_SAMPLERATE_24; + break; + case 22050: + return EMU_ADCCR_SAMPLERATE_22; + break; + case 16000: + return EMU_ADCCR_SAMPLERATE_16; + break; + case 12000: + if(voice->sc->sc_type & EMUXKI_AUDIGY) + return EMU_A_ADCCR_SAMPLERATE_12; + else { +#ifdef EMUXKI_DEBUG + printf("recording sample_rate not supported : %u\n", voice->sample_rate); +#endif + return (-1); + } + break; + case 11000: + if(voice->sc->sc_type & EMUXKI_AUDIGY) + return EMU_A_ADCCR_SAMPLERATE_11; + else + return EMU_ADCCR_SAMPLERATE_11; + break; + case 8000: + if(voice->sc->sc_type & EMUXKI_AUDIGY) + return EMU_A_ADCCR_SAMPLERATE_8; + else + return EMU_ADCCR_SAMPLERATE_8; + break; + default: +#ifdef EMUXKI_DEBUG + printf("recording sample_rate not supported : %u\n", voice->sample_rate); +#endif + return (-1); + } + return (-1); /* shouldn't get here */ +} + void emuxki_voice_start(struct emuxki_voice *voice, void (*inth) (void *), void *inthparam) @@ -1637,29 +1860,38 @@ emuxki_voice_start(struct emuxki_voice * emuxki_channel_start(voice->dataloc.chan[1]); } else { voice->trigblk = 1; - switch ((int)voice->dataloc.source) { + switch (voice->dataloc.source) { case EMU_RECSRC_ADC: - val = EMU_ADCCR_LCHANENABLE; /* XXX need to program DSP to output L+R * XXX in monaural case? */ - if (voice->stereo) - val |= EMU_ADCCR_RCHANENABLE; - val |= emuxki_recsrc_rate_to_index(voice->sample_rate); - emuxki_write(voice->sc, 0, EMU_ADCCR, 0); - emuxki_write(voice->sc, 0, EMU_ADCCR, val); + if (voice->sc->sc_type & EMUXKI_AUDIGY) { + val = EMU_A_ADCCR_LCHANENABLE; + if (voice->stereo) + val |= EMU_A_ADCCR_RCHANENABLE; + } else { + val = EMU_ADCCR_LCHANENABLE; + if (voice->stereo) + val |= EMU_ADCCR_RCHANENABLE; + } + val |= emuxki_voice_adc_rate(voice); + emuxki_write(voice->sc, 0, EMU_ADCCR, 0); + emuxki_write(voice->sc, 0, EMU_ADCCR, val); break; case EMU_RECSRC_MIC: case EMU_RECSRC_FX: printf("unimplemented\n"); break; + case EMU_RECSRC_NOTSET: + default: + break; } #if 0 /* DMA completion interrupt is useless; use timer */ int s; s = splaudio(); - val = emu_rd(sc, INTE, 4); + val = emu_rd(sc, INTE, 4); val |= emuxki_recsrc_intrmasks[voice->dataloc.source]; - emu_wr(sc, INTE, val, 4); + emu_wr(sc, INTE, val, 4); splx(s); #endif } @@ -1677,7 +1909,7 @@ emuxki_voice_halt(struct emuxki_voice *v } else { switch (voice->dataloc.source) { case EMU_RECSRC_ADC: - emuxki_write(voice->sc, 0, EMU_ADCCR, 0); + emuxki_write(voice->sc, 0, EMU_ADCCR, 0); break; case EMU_RECSRC_FX: case EMU_RECSRC_MIC: @@ -1693,9 +1925,9 @@ emuxki_voice_halt(struct emuxki_voice *v #if 0 int s; s = splaudio(); - val = emu_rd(sc, INTE, 4); + val = emu_rd(sc, INTE, 4); val &= ~emuxki_recsrc_intrmasks[voice->dataloc.source]; - emu_wr(sc, INTE, val, 4); + emu_wr(sc, INTE, val, 4); splx(s); #endif } @@ -1881,7 +2113,7 @@ emuxki_query_encoding(void *addr, struct int emuxki_set_vparms(struct emuxki_voice *voice, struct audio_params *p) { - u_int8_t b16, mode; + u_int8_t b16, mode; mode = (voice->use & EMU_VOICE_USE_PLAY) ? AUMODE_PLAY : AUMODE_RECORD; @@ -1973,7 +2205,7 @@ emuxki_set_params(void *addr, int setmod struct audio_params *play, struct audio_params *rec) { struct emuxki_softc *sc = addr; - int mode, error; + int mode, error; struct audio_params *p; for (mode = AUMODE_RECORD; mode != -1; @@ -2068,9 +2300,9 @@ void emuxki_freem(void *addr, void *ptr, int type) { struct emuxki_softc *sc = addr; - int i, s; + int i, s; struct emuxki_mem *mem; - size_t numblocks; + size_t numblocks; u_int32_t *ptb, silentpage; ptb = KERNADDR(sc->ptb); @@ -2086,7 +2318,7 @@ emuxki_freem(void *addr, void *ptr, int numblocks++; for (i = 0; i < numblocks; i++) ptb[mem->ptbidx + i] = - silentpage | (mem->ptbidx + i); + htole32(silentpage | (mem->ptbidx + i)); } LIST_REMOVE(mem, next); splx(s); @@ -2175,7 +2407,7 @@ emuxki_trigger_output(void *addr, void * struct emuxki_softc *sc = addr; /* No multiple voice support for now */ struct emuxki_voice *voice = sc->pvoice; - int error; + int error; if (voice == NULL) return (ENXIO); @@ -2198,7 +2430,7 @@ emuxki_trigger_input(void *addr, void *s struct emuxki_softc *sc = addr; /* No multiple voice support for now */ struct emuxki_voice *voice = sc->rvoice; - int error; + int error; if (voice == NULL) return (ENXIO); Index: emuxkireg.h ================================================== ================= RCS file: /cvs/src/sys/dev/pci/emuxkireg.h,v retrieving revision 1.3 diff -u -p -r1.3 emuxkireg.h --- emuxkireg.h 3 Jun 2002 21:13:20 -0000 1.3 +++ emuxkireg.h 27 Nov 2005 10:50:51 -0000 @@ -47,13 +47,18 @@ * including comments is available in Linux 2.4.* kernel as file * drivers/sound/emu10k1/8010.h */ - + +/* + * Audigy specific registers contain an '_A_' + * Audigy2 specific registers contain an '_A2_' + */ #define EMU_MKSUBREG(sz, idx, reg) (((sz) << 24) | ((idx) << 16) | (reg)) #define EMU_PTR 0x00 #define EMU_PTR_CHNO_MASK 0x0000003f #define EMU_PTR_ADDR_MASK 0x07ff0000 +#define EMU_A_PTR_ADDR_MASK 0x0fff0000 #define EMU_DATA 0x04 @@ -76,6 +81,8 @@ #define EMU_IPR_INTERVALTIMER 0x00000200 #define EMU_IPR_MIDITRANSBUFE 0x00000100 #define EMU_IPR_MIDIRECVBUFE 0x00000080 +#define EMU_IPR_A_MIDITRANSBUFE2 0x10000000 +#define EMU_IPR_A_MIDIRECBUFE2 0x08000000 #define EMU_IPR_CHANNELLOOP 0x00000040 #define EMU_IPR_CHNOMASK 0x0000003f @@ -115,6 +122,8 @@ #define EMU_INTE_INTERTIMERENB 0x00000004 #define EMU_INTE_MIDITXENABLE 0x00000002 #define EMU_INTE_MIDIRXENABLE 0x00000001 +#define EMU_INTE_A_MIDITXENABLE2 0x00020000 +#define EMU_INTE_A_MIDIRXENABLE2 0x00010000 #define EMU_WC 0x10 @@ -167,6 +176,12 @@ #define EMU_MUSTAT_IRDYN 0x80 #define EMU_MUSTAT_ORDYN 0x40 +#define EMU_A_IOCFG 0x18 +#define EMU_A_GPINPUT_MASK 0xff00 +#define EMU_A_GPOUTPUT_MASK 0x00ff +#define EMU_A_IOCFG_GPOUT0 0x0040 +#define EMU_A_IOCFG_GPOUT1 0x0004 + #define EMU_TIMER 0x1a #define EMU_TIMER_RATE_MASK 0x000003ff #define EMU_TIMER_RATE EMU_MKSUBREG(10, 0, EMU_TIMER) @@ -176,6 +191,14 @@ #define EMU_AC97ADDR_RDY 0x80 #define EMU_AC97ADDR_ADDR 0x7f +#define EMU_A2_PTR 0x20 +#define EMU_A2_DATA 0x24 + +#define EMU_A2_SRCSEL 0x600000 +#define EMU_A2_SRCSEL_ENABLE_SPDIF 0x00000004 +#define EMU_A2_SRCSEL_ENABLE_SRCMULTI 0x00000010 +#define EMU_A2_SRCMULTI 0x6e0000 +#define EMU_A2_SRCMULTI_ENABLE_INPUT 0xff00ff00 #define EMU_CHAN_CPF 0x00 @@ -391,19 +414,25 @@ #define EMU_TCB 0x41 #define EMU_TCB_MASK 0xfffff000 -#define EMU_ADCCR 0x42 +#define EMU_ADCCR 0x42 #define EMU_ADCCR_RCHANENABLE 0x00000010 +#define EMU_A_ADCCR_RCHANENABLE 0x00000020 #define EMU_ADCCR_LCHANENABLE 0x00000008 +#define EMU_A_ADCCR_LCHANENABLE 0x00000010 #define EMU_ADCCR_SAMPLERATE_MASK 0x00000007 +#define EMU_A_ADCCR_SAMPLERATE_MASK 0x0000000f #define EMU_ADCCR_SAMPLERATE_48 0x00000000 #define EMU_ADCCR_SAMPLERATE_44 0x00000001 #define EMU_ADCCR_SAMPLERATE_32 0x00000002 #define EMU_ADCCR_SAMPLERATE_24 0x00000003 #define EMU_ADCCR_SAMPLERATE_22 0x00000004 #define EMU_ADCCR_SAMPLERATE_16 0x00000005 +#define EMU_A_ADCCR_SAMPLERATE_12 0x00000006 #define EMU_ADCCR_SAMPLERATE_11 0x00000006 +#define EMU_A_ADCCR_SAMPLERATE_11 0x00000007 #define EMU_ADCCR_SAMPLERATE_8 0x00000007 +#define EMU_A_ADCCR_SAMPLERATE_8 0x00000008 #define EMU_FXWC 0x43 #define EMU_TCBS 0x44 @@ -473,8 +502,13 @@ #define EMU_DBG_STEP 0x00004000 #define EMU_DBG_CONDITION_CODE 0x00003e00 #define EMU_DBG_SINGLE_STEP_ADDR 0x000001ff -#define EMU_REG53 0x53 +#define EMU_A_DBG 0x53 +#define EMU_A_DBG_SINGLE_STEP 0x00020000 +#define EMU_A_DBG_ZC 0x40000000 +#define EMU_A_DBG_STEP_ADDR 0x000003ff +#define EMU_A_DBG_SATURATION_OCCRD 0x20000000 +#define EMU_A_DBG_SATURATION_ADDR 0x0ffc0000 #define EMU_SPCS0 0x54 #define EMU_SPCS1 0x55 @@ -519,9 +553,13 @@ #define EMU_SOLEL 0x5c #define EMU_SOLEH 0x5d -#define EMU_SPBYPASS 0x5e -#define EMU_SPBYPASS_ENABLE 0x00000001 - +#define EMU_SPBYPASS 0x5e +#define EMU_SPBYPASS_ENABLE 0x00000001 +#define EMU_SPBYPASS_24_BITS 0x00000f00 + +#define EMU_AC97SLOT 0x5f +#define EMU_AC97SLOT_CENTER 0x00000010 +#define EMU_AC97SLOT_LFE 0x00000020 #define EMU_CDSRCS 0x60 #define EMU_GPSRCS 0x61 @@ -532,7 +570,9 @@ #define EMU_MICIDX 0x63 +#define EMU_A_MICIDX 0x64 #define EMU_ADCIDX 0x64 +#define EMU_A_ADCIDX 0x63 #define EMU_FXIDX 0x65 #define EMU_RECIDX_MASK 0x0000ffff #define EMU_RECIDX(idxreg) (0x10000000|(idxreg)) @@ -542,7 +582,40 @@ #define EMU_FXIDX_IDX 0x10000065 */ +#define EMU_A_MUDATA1 0x70 +#define EMU_A_MUCMD1 0x71 +#define EMU_A_MUSTAT1 EMU_A_MUCMD1 +#define EMU_A_MUDATA2 0x72 +#define EMU_A_MUCMD2 0x73 +#define EMU_A_MUSTAT2 EMU_A_MUCMD2 +#define EMU_A_FXWC1 0x74 +#define EMU_A_FXWC2 0x75 +#define EMU_A_SPDIF_SAMPLERATE 0x76 +#define EMU_A_SPDIF_48000 0x00000080 +#define EMU_A_SPDIF_44100 0x00000000 +#define EMU_A_SPDIF_96000 0x00000040 +#define EMU_A2_SPDIF_SAMPLERATE EMU_MKSUBREG(3, 9, EMU_A_SPDIF_SAMPLERATE) +#define EMU_A2_SPDIF_MASK 0x00000e00 +#define EMU_A2_SPDIF_UNKNOWN 0x2 + +#define EMU_A_CHAN_FXRT2 0x7c +#define EMU_A_CHAN_FXRT_CHANNELE 0x0000003f +#define EMU_A_CHAN_FXRT_CHANNELF 0x00003f00 +#define EMU_A_CHAN_FXRT_CHANNELG 0x003f0000 +#define EMU_A_CHAN_FXRT_CHANNELH 0x3f000000 +#define EMU_A_CHAN_SENDAMOUNTS 0x7d +#define EMU_A_CHAN_FXSENDAMOUNTS_E_MASK 0xff000000 +#define EMU_A_CHAN_FXSENDAMOUNTS_F_MASK 0x00ff0000 +#define EMU_A_CHAN_FXSENDAMOUNTS_G_MASK 0x0000ff00 +#define EMU_A_CHAN_FXSENDAMOUNTS_H_MASK 0x000000ff +#define EMU_A_CHAN_FXRT1 0x7e +#define EMU_A_CHAN_FXRT_CHANNELA 0x0000003f +#define EMU_A_CHAN_FXRT_CHANNELB 0x00003f00 +#define EMU_A_CHAN_FXRT_CHANNELC 0x003f0000 +#define EMU_A_CHAN_FXRT_CHANNELD 0x3f000000 + #define EMU_FXGPREGBASE 0x100 +#define EMU_A_FXGPREGBASE 0x400 #define EMU_TANKMEMDATAREGBASE 0x200 #define EMU_TANKMEMDATAREG_MASK 0x000fffff @@ -555,12 +628,18 @@ #define EMU_MICROCODEBASE 0x400 +#define EMU_A_MICROCODEBASE 0x600 #define EMU_DSP_LOWORD_OPX_MASK 0x000ffc00 #define EMU_DSP_LOWORD_OPY_MASK 0x000003ff #define EMU_DSP_HIWORD_OPCODE_MASK 0x00f00000 #define EMU_DSP_HIWORD_RESULT_MASK 0x000ffc00 #define EMU_DSP_HIWORD_OPA_MASK 0x000003ff +#define EMU_A_DSP_LOWORD_OPX_MASK 0x007ff000 +#define EMU_A_DSP_LOWORD_OPY_MASK 0x000007ff +#define EMU_A_DSP_HIWORD_OPCODE_MASK 0x0f000000 +#define EMU_A_DSP_HIWORD_RESULT_MASK 0x007ff000 +#define EMU_A_DSP_HIWORD_OPA_MASK 0x000007ff #define EMU_DSP_OP_MACS 0x0 @@ -590,6 +669,9 @@ #define EMU_DSP_INL_BASE 0x010 #define EMU_DSP_INL(num) (EMU_DSP_IOL(EMU_DSP_INL_BASE, num)) #define EMU_DSP_INR(num) (EMU_DSP_IOR(EMU_DSP_INL_BASE, num)) +#define EMU_A_DSP_INL_BASE 0x040 +#define EMU_A_DSP_INL(num) (EMU_DSP_IOL(EMU_A_DSP_INL_BASE, num)) +#define EMU_A_DSP_INR(num) (EMU_DSP_IOR(EMU_A_DSP_INL_BASE, num)) #define EMU_DSP_IN_AC97 0 #define EMU_DSP_IN_CDSPDIF 1 #define EMU_DSP_IN_ZOOM 2 @@ -602,17 +684,31 @@ #define EMU_DSP_OUTL_BASE 0x020 #define EMU_DSP_OUTL(num) (EMU_DSP_IOL(EMU_DSP_OUTL_BASE, num)) #define EMU_DSP_OUTR(num) (EMU_DSP_IOR(EMU_DSP_OUTL_BASE, num)) -#define EMU_DSP_OUT_AC97 0 -#define EMU_DSP_OUT_TOSOPT 1 -#define EMU_DSP_OUT_UNKNOWN 2 -#define EMU_DSP_OUT_HEAD 3 -#define EMU_DSP_OUT_RCHAN 4 -#define EMU_DSP_OUT_ADC 5 -#define EMU_DSP_OUTL_MIC 6 +#define EMU_DSP_OUT_A_FRONT 0 +#define EMU_DSP_OUT_D_FRONT 1 +#define EMU_DSP_OUT_D_CENTER 2 +#define EMU_DSP_OUT_DRIVE_HP 3 +#define EMU_DSP_OUT_AD_REAR 4 +#define EMU_DSP_OUT_ADC 5 +#define EMU_DSP_OUTL_MIC 6 + +#define EMU_A_DSP_OUTL_BASE 0x060 +#define EMU_A_DSP_OUTL(num) (EMU_DSP_IOL(EMU_A_DSP_OUTL_BASE, num)) +#define EMU_A_DSP_OUTR(num) (EMU_DSP_IOR(EMU_A_DSP_OUTL_BASE, num)) +#define EMU_A_DSP_OUT_D_FRONT 0 +#define EMU_A_DSP_OUT_D_CENTER 1 +#define EMU_A_DSP_OUT_DRIVE_HP 2 +#define EMU_A_DSP_OUT_DREAR 3 +#define EMU_A_DSP_OUT_A_FRONT 4 +#define EMU_A_DSP_OUT_A_CENTER 5 +#define EMU_A_DSP_OUT_A_REAR 7 +#define EMU_A_DSP_OUT_ADC 11 #define EMU_DSP_CST_BASE 0x40 +#define EMU_A_DSP_CST_BASE 0xc0 #define EMU_DSP_CST(num) (EMU_DSP_CST_BASE + num) +#define EMU_A_DSP_CST(num) (EMU_A_DSP_CST_BASE + num) /* 00 = 0x00000000 01 = 0x00000001 @@ -651,5 +747,6 @@ #define EMU_DSP_HWR_DBAC 0x05B #define EMU_DSP_GPR(num) (EMU_FXGPREGBASE + num) +#define EMU_A_DSP_GPR(num) (EMU_A_FXGPREGBASE + num) #endif /* _DEV_PCI_EMUXKIREG_H_ */ Index: emuxkivar.h ================================================== ================= RCS file: /cvs/src/sys/dev/pci/emuxkivar.h,v retrieving revision 1.6 diff -u -p -r1.6 emuxkivar.h --- emuxkivar.h 26 Apr 2003 08:01:42 -0000 1.6 +++ emuxkivar.h 27 Nov 2005 10:50:51 -0000 @@ -95,7 +95,7 @@ struct emuxki_mem { struct emuxki_chanparms_fxsend { struct { u_int8_t level, dest; - } a, b, c, d; + } a, b, c, d, e, f, g, h; }; struct emuxki_chanparms_pitch { @@ -228,7 +228,8 @@ struct emuxki_softc { struct device sc_dev; struct audio_device sc_audv; enum { - EMUXKI_SBLIVE, EMUXKI_APS, EMUXKI_AUDIGY + EMUXKI_SBLIVE = 0x00, EMUXKI_AUDIGY = 0x01, EMUXKI_AUDIGY2 = 0x02, + EMUXKI_LIVE_5_1 = 0x04, EMUXKI_APS = 0x08 } sc_type; /* Autoconfig parameters */ |
| Thread Tools | |
| Display Modes | |
|
|