Subject: kern/25731: Lack of Audigy support with the emuxki driver.
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <adamk@voicenet.com>
List: netbsd-bugs
Date: 05/27/2004 18:37:00
>Number:         25731
>Category:       kern
>Synopsis:       Lack of Audigy support with the emuxki driver.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu May 27 18:38:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Adam K Kirchhoff
>Release:        2.0F
>Organization:
>Environment:
NetBSD sorrow.ashke.com 2.0F NetBSD 2.0F (GENERIC) #0: Thu May 27 13:29:12 EDT 2004  root@sorrow.ashke.com:/usr/obj/sys/arch/i386/compile/GENERIC i386
>Description:

NetBSD supports the SB Live (PCM playback and recording) with the emxuxk driver, but not the newer Audigy, which are relatively common these days.
>How-To-Repeat:

Boot into any recent NetBSD release (or even -CURRENT) and notice that your Audigy isn't being detected at all.
>Fix:

This diff (also available at 
http://go.visualtech.com/emuxki-netbsd.diff) adds Audigy support (possibly Audigy2, but I'm not sure).  It was written by Jacob Meuser, primarily for OpenBSD, but he ported it to NetBSD as well.  The mixer is still broken (input volumes can be controlled, but PCM and Master don't actually affect the volume), but he hasn't had much time to continue working on it since March of this year.  I figure patching the current emuxki driver is the first step to getting fully functional support for the Audigy into NetBSD.  

This is a diff between my source tree (-CURRENT from May 27th with Jacob's patch applied, and the rejects manually fixed) and what's in -CURRENT.

Index: emuxki.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/emuxki.c,v
retrieving revision 1.34
diff -r1.34 emuxki.c
116a117
> static int emuxki_voice_adc_rate(struct emuxki_voice *);
213,214d213
< static const int emuxki_recsrc_adcrates[] =
<     { 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000, -1 };
221,222d219
< static const u_int32_t emuxki_recsrc_idxreg[EMU_NUMRECSRCS] =
<     { EMU_RECIDX(EMU_MICIDX), EMU_RECIDX(EMU_ADCIDX), EMU_RECIDX(EMU_FXIDX) };
338,340c335,346
< 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, EMU_HCFG,
< 		EMU_HCFG_AUDIOENABLE | EMU_HCFG_JOYENABLE |
< 		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);
> 	}
344a351,355
> 	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));
> 	}
371c382,383
< 	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_SBLIVE2))
---
> 	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_SBLIVE2 ||
> 	     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_AUDIGY ))
424c436,456
< 	aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
---
> 
>  /* XXX it's unknown wheather APS is made from Audigy as well */
>         if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CREATIVELABS_AUDIGY) {
>                 sc->sc_type = EMUXKI_AUDIGY;
>                 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;
>                 strlcpy(sc->sc_audv.name, "E-mu APS", sizeof sc->sc_audv.name);
>         } else {
>                 sc->sc_type = EMUXKI_SBLIVE;
>                 strlcpy(sc->sc_audv.name, "SB Live!", sizeof sc->sc_audv.name);
>         }
>         snprintf(sc->sc_audv.version, sizeof sc->sc_audv.version, "0x%02x",
>                  PCI_REVISION(pa->pa_class));
>         strlcpy(sc->sc_audv.config, "emuxki", sizeof sc->sc_audv.config);
430a463
> 	aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
533c566,568
< 	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)) |
558c593,595
< 	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)) |
579c616,619
< 	emuxki_write(sc, 0, EMU_MICROCODEBASE + pc, data);
---
> 	emuxki_write(sc, 0,
> 		(sc->sc_type & EMUXKI_AUDIGY ?
> 			EMU_A_MICROCODEBASE : EMU_MICROCODEBASE) + pc,
> 		 data);
586,593c626,643
< 	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)++;
---
> 	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)++;
611,619d660
< 	/* 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));
621c662,673
< 	/* 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 */
623,642c675,688
< 	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));
< #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)
---
> 		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));
644c690,726
< 				  EMU_DSP_CST(0), EMU_DSP_CST(0),
---
> 				  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_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),
645a728,737
> 		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)
> 			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));
647c739,740
< 	emuxki_write(sc, 0, EMU_DBG, 0);	/* Is it really necessary ? */
---
> 		emuxki_write(sc, 0, EMU_DBG, 0);	/* Is it really necessary ? */
> 	}
670a764,768
>         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);
>         }
> 
712a811,822
>         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);
>         }
> 
> 
803c913,918
< 	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);
>         }
921c1036,1042
< 	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 */
> 
925a1047,1051
> 	/* for audigy */
> 	chan->fxsend.e.dest = 0x4;
> 	chan->fxsend.f.dest = 0x5;
> 	chan->fxsend.g.dest = 0x6;
> 	chan->fxsend.h.dest = 0x7;
1005a1132,1141
> 
> 	/* 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;
1029a1166,1203
> 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);
> }
> 
> static void
1044,1052c1218,1220
< 	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);
> 
1234,1247d1401
< static 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);
< 	}
< }
< 
1371a1526,1530
> 		/* for audigy */
> 		fxsend.e.dest = 0x4;
> 		fxsend.f.dest = 0x5;
> 		fxsend.g.dest = 0x6;
> 		fxsend.h.dest = 0x7;
1374a1534,1535
> 			fxsend.e.level = fxsend.g.level = 0xc0;
> 			fxsend.f.level = fxsend.h.level = 0x00;
1378a1540,1541
> 			fxsend.e.level = fxsend.g.level = 0x00;
> 			fxsend.f.level = fxsend.h.level = 0xc0;
1398c1561
< 		if (emuxki_recsrc_rate_to_index(srate) < 0)
---
> 		if ((srate < 8000) || (srate > 48000))
1400a1564,1567
> 		if (emuxki_voice_adc_rate(voice) < 0) {
> 			voice->sample_rate = 0;
> 			return (EINVAL);
> 		}
1517a1685
> 	int idxreg = 0;
1520c1688
< 	if (voice->use & EMU_VOICE_USE_PLAY)
---
> 	if (voice->use & EMU_VOICE_USE_PLAY) {
1526c1694
< 	else
---
> 	} else {
1528,1531c1696,1716
< 		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);
> 	}
1568a1754,1807
> static 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 */
> }
> 
> 
1584c1823
< 		switch ((int)voice->dataloc.source) {
---
> 		switch (voice->dataloc.source) {
1586d1824
< 			val = EMU_ADCCR_LCHANENABLE;
1589,1593c1827,1838
< 			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);
1598a1844,1846
> 		case EMU_RECSRC_NOTSET:
> 		default:
> 		        break;
1604c1852
<                 val = emu_rd(sc, INTE, 4);
---
> 		val = emu_rd(sc, INTE, 4);
1606c1854
<                 emu_wr(sc, INTE, val, 4);
---
> 		emu_wr(sc, INTE, val, 4);
1624c1872
<                         emuxki_write(voice->sc, 0, EMU_ADCCR, 0);
---
> 			emuxki_write(voice->sc, 0, EMU_ADCCR, 0);
1640c1888
<                 val = emu_rd(sc, INTE, 4);
---
> 		val = emu_rd(sc, INTE, 4);
1642c1890
<                 emu_wr(sc, INTE, val, 4);
---
> 		emu_wr(sc, INTE, val, 4);
1834c2082
< 	u_int8_t        b16, mode;
---
> 	u_int8_t	b16, mode;
1926c2174
< 	int             mode, error;
---
> 	int	     mode, error;
1987,1989c2235,2236
< 	strncpy(dev->name, "Creative EMU10k1", sizeof(dev->name));
< 	strcpy(dev->version, "");
< 	strncpy(dev->config, "emuxki", sizeof(dev->config));
---
> 	struct emuxki_softc *sc = addr;
> 	*dev = sc->sc_audv;
2034c2281
< 	int             i, s;
---
> 	int	     i, s;
2036c2283
< 	size_t          numblocks;
---
> 	size_t	  numblocks;
2158c2405
< 	int             error;
---
> 	int	     error;
2181c2428
< 	int             error;
---
> 	int	error;
Index: emuxkireg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/emuxkireg.h,v
retrieving revision 1.4
diff -r1.4 emuxkireg.h
49c49,53
<  
---
> 
> /*
>  * Audigy specific registers contain an '_A_'
>  * Audigy2 specific registers contain an '_A2_'
>  */
55a60
> #define  EMU_A_PTR_ADDR_MASK	0x0fff0000
77a83,84
> #define  EMU_IPR_A_MIDITRANSBUFE2 0x10000000
> #define  EMU_IPR_A_MIDIRECBUFE2	0x08000000
116a124,125
> #define  EMU_INTE_A_MIDITXENABLE2 0x00020000
> #define  EMU_INTE_A_MIDIRXENABLE2 0x00010000
164a174,179
> #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
> 
173a189,197
> #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
> 
356a381
> #define  EMU_A_ADCCR_RCHANENABLE	0x00000020
357a383
> #define  EMU_A_ADCCR_LCHANENABLE	0x00000010
358a385
> #define  EMU_A_ADCCR_SAMPLERATE_MASK    0x0000000f
364a392
> #define   EMU_A_ADCCR_SAMPLERATE_12	0x00000006
365a394
> #define   EMU_A_ADCCR_SAMPLERATE_11	0x00000007
366a396
> #define   EMU_A_ADCCR_SAMPLERATE_8	0x00000008
432c462,468
< #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
468,469c504,510
< #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
478a520
> #define EMU_A_MICIDX	0x64
479a522
> #define EMU_A_ADCIDX	0x63
488a532,563
> #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
> 
489a565
> #define EMU_A_FXGPREGBASE	0x400
501a578
> #define  EMU_A_MICROCODEBASE		0x600
506a584,588
> #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
533a616,618
> #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))
546,552c631,649
< #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
554a652
> #define	EMU_A_DSP_CST_BASE	0xc0
555a654
> #define	EMU_A_DSP_CST(num)	(EMU_A_DSP_CST_BASE + num)
593a693
> #define EMU_A_DSP_GPR(num)	(EMU_A_FXGPREGBASE + num)
Index: emuxkivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/emuxkivar.h,v
retrieving revision 1.6
diff -r1.6 emuxkivar.h
42a43
> #define EMU_SUBSYS_APS		0x40011102
96c97
< 	} a, b, c, d;
---
> 	} a, b, c, d, e, f, g, h;
226a228,233
> 	audio_device_t sc_audv;
>   	enum {
> 		EMUXKI_SBLIVE = 0x00, EMUXKI_AUDIGY = 0x01,
> 		EMUXKI_AUDIGY2 = 0x02, EMUXKI_LIVE_5_1 = 0x04,
> 		EMUXKI_APS = 0x08
>   	} sc_type;
Index: pcidevs
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pcidevs,v
retrieving revision 1.626
diff -r1.626 pcidevs
1234a1235
> product CREATIVELABS AUDIGY	0x0004	SB Audigy EMU 10000
Index: pcidevs.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pcidevs.h,v
retrieving revision 1.626
diff -r1.626 pcidevs.h
1241a1242
> #define	PCI_PRODUCT_CREATIVELABS_AUDIGY	0x0004		/* SB Audigy EMU 10000 */
Index: pcidevs_data.h
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pcidevs_data.h,v
retrieving revision 1.624
diff -r1.624 pcidevs_data.h
3012a3013,3018
> 	    PCI_VENDOR_CREATIVELABS, PCI_PRODUCT_CREATIVELABS_AUDIGY,
> 	    0,
> 	    "Creative Labs",
> 	    "SB Audigy EMU 10000",
> 	},
> 	{

>Release-Note:
>Audit-Trail:
>Unformatted: