On Sat, Jun 07, 2003 at 01:19:42PM -0400, John Wilson wrote:
> I've been using the OSS drivers for my Audigy "Gamer" sound card for quite
> some time now, and would like to switch away from OSS.  I vaguely
> remember, after searching Google, that someone had gotten this to work
> after a recent cvsup.  Unfortunately, I cannot seem to get this to work
> natively.

Here is what I use.  I tried to make it as non-distruptive of pre-Audigy
cards as possible, but it won't work with them for some reason.  Thus why
this patch hasn't been committed yet.


Index: dev/sound/pci/emu10k1.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/sound/pci/emu10k1.c,v
retrieving revision 1.37
diff -u -r1.37 emu10k1.c
--- dev/sound/pci/emu10k1.c     20 Apr 2003 09:07:14 -0000      1.37
+++ dev/sound/pci/emu10k1.c     7 Jun 2003 21:19:50 -0000
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2003 Orlando Bassotto <[EMAIL PROTECTED]>
  * Copyright (c) 1999 Cameron Grant <[EMAIL PROTECTED]>
  * All rights reserved.
  *
@@ -27,6 +28,9 @@
 #include <dev/sound/pcm/sound.h>
 #include <dev/sound/pcm/ac97.h>
 #include <gnu/dev/sound/pci/emu10k1.h>
+#include <gnu/dev/sound/pci/emu10k1-ac97.h>
+#include <gnu/dev/sound/pci/emu10k1-alsa.h>
+#include <dev/sound/pci/emu10k1.h>
 
 #include <pci/pcireg.h>
 #include <pci/pcivar.h>
@@ -39,9 +43,25 @@
 #define        EMU10K1_PCI_ID  0x00021102
 #define        EMU10K2_PCI_ID  0x00041102
 #define        EMU_DEFAULT_BUFSZ       4096
-#define        EMU_CHANS       4
+#define EMU_MAX_CHANS  8
 #undef EMUDEBUG
 
+#define        EMUPAGESIZE     4096    /* don't change */
+#define        MAXREQVOICES    8
+#define        MAXPAGES        (32768 * 64 / EMUPAGESIZE)      /* WAVEOUT_MAXBUFSIZE 
* NUM_G / EMUPAGESIZE */
+#define        RESERVED        0
+#define        NUM_MIDI        16
+#define        NUM_G           64              /* use all channels */
+#define        NUM_FXSENDS     4
+
+#define        TMEMSIZE        256*1024
+#define        TMEMSIZEREG     4
+
+#define        ENABLE          0xffffffff
+#define        DISABLE         0x00000000
+#define        ENV_ON          0x80
+#define        ENV_OFF         0x00
+
 struct emu_memblk {
        SLIST_ENTRY(emu_memblk) link;
        void *buf;
@@ -63,6 +83,8 @@
        int b16:1, stereo:1, busy:1, running:1, ismaster:1;
        int speed;
        int start, end, vol;
+       int fxrt1;      /* FX routing */
+       int fxrt2;      /* FX routing (only for audigy) */
        u_int32_t buf;
        struct emu_voice *slave;
        struct pcm_channel *channel;
@@ -91,7 +113,8 @@
 struct sc_info {
        device_t        dev;
        u_int32_t       type, rev;
-       u_int32_t       tos_link:1, APS:1;
+       u_int32_t       tos_link:1, APS:1, audigy:1, audigy2:1;
+       u_int32_t       addrmask;       /* wider if audigy */
 
        bus_space_tag_t st;
        bus_space_handle_t sh;
@@ -104,9 +127,10 @@
        unsigned int bufsz;
        int timer, timerinterval;
        int pnum, rnum;
+       int nchans;
        struct emu_mem mem;
        struct emu_voice voice[64];
-       struct sc_pchinfo pch[EMU_CHANS];
+       struct sc_pchinfo pch[EMU_MAX_CHANS];
        struct sc_rchinfo rch[3];
 };
 
@@ -166,6 +190,8 @@
 static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
 
 static int adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
+/* audigy supports 12kHz. */
+static int audigy_adcspeed[9] = {48000, 44100, 32000, 24000, 22050, 16000, 12000, 
11025, 8000};
 
 /* -------------------------------------------------------------------- */
 /* Hardware */
@@ -205,7 +231,7 @@
 {
        u_int32_t ptr, val, mask, size, offset;
 
-       ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK);
+       ptr = ((reg << 16) & sc->addrmask) | (chn & PTR_CHANNELNUM_MASK);
        emu_wr(sc, PTR, ptr, 4);
        val = emu_rd(sc, DATA, 4);
        if (reg & 0xff000000) {
@@ -223,7 +249,7 @@
 {
        u_int32_t ptr, mask, size, offset;
 
-       ptr = ((reg << 16) & PTR_ADDRESS_MASK) | (chn & PTR_CHANNELNUM_MASK);
+       ptr = ((reg << 16) & sc->addrmask) | (chn & PTR_CHANNELNUM_MASK);
        emu_wr(sc, PTR, ptr, 4);
        if (reg & 0xff000000) {
                size = (reg >> 24) & 0x3f;
@@ -239,7 +265,8 @@
 static void
 emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data)
 {
-       emu_wrptr(sc, 0, MICROCODEBASE + pc, data);
+       pc += sc->audigy ? AUDIGY_CODEBASE : MICROCODEBASE;
+       emu_wrptr(sc, 0, pc, data);
 }
 
 /* -------------------------------------------------------------------- */
@@ -282,7 +309,7 @@
        int i, tmp, rate;
 
        rate = 0;
-       for (i = 0; i < EMU_CHANS; i++) {
+       for (i = 0; i < sc->nchans; i++) {
                pch = &sc->pch[i];
                if (pch->buffer) {
                        tmp = (pch->spd * sndbuf_getbps(pch->buffer)) / pch->blksz;
@@ -345,6 +372,16 @@
        return val;
 }
 
+static int
+audigy_recval(int speed) {
+       int val;
+
+       val = 0;
+       while (val < 8 && speed < audigy_adcspeed[val])
+               val++;
+       return val;
+}
+
 static u_int32_t
 emu_rate_to_pitch(u_int32_t rate)
 {
@@ -447,6 +484,16 @@
        m->vol = 0xff;
        m->buf = tmp_addr;
        m->slave = s;
+       if (sc->audigy) {
+               m->fxrt1 = FXBUS_MIDI_CHORUS | FXBUS_PCM_LEFT << 8 |
+                   FXBUS_PCM_RIGHT << 16 | FXBUS_MIDI_REVERB << 24;
+               m->fxrt2 = 0x3f3f3f3f;  /* No effects on second route */
+       } else {
+               m->fxrt1 = FXBUS_MIDI_CHORUS | FXBUS_PCM_LEFT << 4 |
+                   FXBUS_PCM_RIGHT << 8 | FXBUS_MIDI_REVERB << 12;
+               m->fxrt2 = 0;
+       }
+
        if (s != NULL) {
                s->start = m->start;
                s->end = m->end;
@@ -458,6 +505,8 @@
                s->ismaster = 0;
                s->vol = m->vol;
                s->buf = m->buf;
+               s->fxrt1 = m->fxrt1;
+               s->fxrt2 = m->fxrt2;
                s->slave = NULL;
        }
        return 0;
@@ -506,7 +555,13 @@
        val *= v->b16 ? 1 : 2;
        start = sa + val;
 
-       emu_wrptr(sc, v->vnum, FXRT, 0xd01c0000);
+       if (sc->audigy) {
+               emu_wrptr(sc, v->vnum, A_FXRT1, v->fxrt1);
+               emu_wrptr(sc, v->vnum, A_FXRT2, v->fxrt2);
+               emu_wrptr(sc, v->vnum, A_SENDAMOUNTS, 0);
+       }
+       else
+               emu_wrptr(sc, v->vnum, FXRT, v->fxrt1 << 16);
 
        emu_wrptr(sc, v->vnum, PTRX, (x << 8) | r);
        emu_wrptr(sc, v->vnum, DSL, ea | (y << 24));
@@ -607,6 +662,12 @@
                "ip", "ifatn", "pefe", "fmmod", "tremfrq", "fmfrq2",
                "tempenv"
        };
+       char *regname2[] = {
+               "mudata1", "mustat1", "mudata2", "mustat2",
+               "fxwc1", "fxwc2", "spdrate", NULL, NULL,
+               NULL, NULL, NULL, "fxrt2", "sndamnt", "fxrt1",
+               NULL, NULL
+       };
        int i, x;
 
        printf("voice number %d\n", v->vnum);
@@ -619,6 +680,19 @@
                if (x > 2)
                        x = 0;
        }
+
+       /* Print out audigy extra registers */
+       if (sc->audigy) {
+               for (i = 0; i <= 0xe; i++) {
+                       if (regname2[i] == NULL)
+                               continue;
+                       printf("%s\t[%08x]", regname2[i], emu_rdptr(sc, v->vnum, i + 
0x70));
+                       printf("%s", (x == 2)? "\n" : "\t");
+                       x++;
+                       if (x > 2)
+                               x = 0;
+               }
+       }
        printf("\n\n");
 }
 #endif
@@ -777,7 +851,7 @@
        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;
@@ -826,8 +900,12 @@
 {
        struct sc_rchinfo *ch = data;
 
-       if (ch->num == 0)
-               speed = adcspeed[emu_recval(speed)];
+       if (ch->num == 0) {
+               if (ch->parent->audigy)
+                       speed = audigy_adcspeed[audigy_recval(speed)];
+               else
+                       speed = adcspeed[emu_recval(speed)];
+       }
        if (ch->num == 1)
                speed = 48000;
        if (ch->num == 2)
@@ -891,10 +969,18 @@
                ch->run = 1;
                emu_wrptr(sc, 0, ch->sizereg, sz);
                if (ch->num == 0) {
-                       val = ADCCR_LCHANENABLE;
-                       if (ch->fmt & AFMT_STEREO)
-                               val |= ADCCR_RCHANENABLE;
-                       val |= emu_recval(ch->spd);
+                       if (sc->audigy) {
+                               val = A_ADCCR_LCHANENABLE;
+                               if (ch->fmt & AFMT_STEREO)
+                                       val |= A_ADCCR_RCHANENABLE;
+                               val |= audigy_recval(ch->spd);
+                       } else {
+                               val = ADCCR_LCHANENABLE;
+                               if (ch->fmt & AFMT_STEREO)
+                                       val |= ADCCR_RCHANENABLE;
+                               val |= emu_recval(ch->spd);
+                       }
+
                        emu_wrptr(sc, 0, ch->setupreg, 0);
                        emu_wrptr(sc, 0, ch->setupreg, val);
                }
@@ -976,7 +1062,7 @@
                if (stat & IPR_INTERVALTIMER) {
                        ack |= IPR_INTERVALTIMER;
                        x = 0;
-                       for (i = 0; i < EMU_CHANS; i++) {
+                       for (i = 0; i < sc->nchans; i++) {
                                if (sc->pch[i].run) {
                                        x = 1;
                                        chn_intr(sc->pch[i].channel);
@@ -1155,11 +1241,174 @@
 }
 
 static void
+audigy_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 << 12) | y);
+       emu_wrefx(sc, (*pc) * 2 + 1, (op << 24) | (z << 12) | w);
+       (*pc)++;
+}
+
+static void
+audigy_initefx(struct sc_info *sc)
+{
+       int i;
+       u_int32_t pc = 0;
+
+       /* skip 0, 0, -1, 0 - NOPs */
+       for (i = 0; i < 512; i++)
+               audigy_addefxop(sc, 0x0f, 0x0c0, 0x0c0, 0x0cf, 0x0c0, &pc);
+
+       for (i = 0; i < 512; i++)
+               emu_wrptr(sc, 0, A_FXGPREGBASE + i, 0x0);
+
+       pc = 16;
+
+       /* stop fx processor */
+       emu_wrptr(sc, 0, A_DBG, A_DBG_SINGLE_STEP);
+
+       /* Audigy 2 (EMU10K2) DSP Registers:
+          FX Bus
+               0x000-0x00f : 16 registers (???)
+          Input
+               0x040/0x041 : AC97 Codec (l/r)
+               0x042/0x043 : ADC, S/PDIF (l/r)
+               0x044/0x045 : Optical S/PDIF in (l/r)
+               0x046/0x047 : ???
+               0x048/0x049 : Line/Mic 2 (l/r)
+               0x04a/0x04b : RCA S/PDIF (l/r)
+               0x04c/0x04d : Aux 2 (l/r)
+          Output
+               0x060/0x061 : Digital Front (l/r)
+               0x062/0x063 : Digital Center/LFE
+               0x064/0x065 : AudigyDrive Heaphone (l/r)
+               0x066/0x067 : Digital Rear (l/r)
+               0x068/0x069 : Analog Front (l/r)
+               0x06a/0x06b : Analog Center/LFE
+               0x06c/0x06d : ???
+               0x06e/0x06f : Analog Rear (l/r)
+               0x070/0x071 : AC97 Output (l/r)
+               0x072/0x073 : ???
+               0x074/0x075 : ???
+               0x076/0x077 : ADC Recording Buffer (l/r)
+          Constants
+               0x0c0 - 0x0c4 = 0 - 4
+               0x0c5 = 0x8, 0x0c6 = 0x10, 0x0c7 = 0x20
+               0x0c8 = 0x100, 0x0c9 = 0x10000, 0x0ca = 0x80000
+               0x0cb = 0x10000000, 0x0cc = 0x20000000, 0x0cd = 0x40000000
+               0x0ce = 0x80000000, 0x0cf = 0x7fffffff, 0x0d0 = 0xffffffff
+               0x0d1 = 0xfffffffe, 0x0d2 = 0xc0000000, 0x0d3 = 0x41fbbcdc
+               0x0d4 = 0x5a7ef9db, 0x0d5 = 0x00100000, 0x0dc = 0x00000001 (???)
+          Temporary Values
+               0x0d6 : Accumulator (???)
+               0x0d7 : Condition Register
+               0x0d8 : Noise source
+               0x0d9 : Noise source
+          Tank Memory Data Registers
+               0x200 - 0x2ff
+          Tank Memory Address Registers
+               0x300 - 0x3ff
+          General Purpose Registers
+               0x400 - 0x5ff
+        */
+
+       /* AC97Output[l/r] = FXBus PCM[l/r] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AC97_L), A_C_00000000,
+                       A_C_00000000, A_FXBUS(FXBUS_PCM_LEFT), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AC97_R), A_C_00000000,
+                       A_C_00000000, A_FXBUS(FXBUS_PCM_RIGHT), &pc);
+
+       /* GPR[0/1] = RCA S/PDIF[l/r] -- Master volume */
+       audigy_addefxop(sc, iACC3, A_GPR(0), A_C_00000000,
+                       A_C_00000000, A_EXTIN(A_EXTIN_RCA_SPDIF_L), &pc);
+       audigy_addefxop(sc, iACC3, A_GPR(1), A_C_00000000,
+                       A_C_00000000, A_EXTIN(A_EXTIN_RCA_SPDIF_R), &pc);
+
+       /* GPR[2] = GPR[0] (Left) / 2 + GPR[1] (Right) / 2 -- Central volume */
+       audigy_addefxop(sc, iINTERP, A_GPR(2), A_GPR(1),
+                       A_C_40000000, A_GPR(0), &pc);
+
+       /* Headphones[l/r] = GPR[0/1] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_HEADPHONE_L),
+                       A_C_00000000, A_C_00000000, A_GPR(0), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_HEADPHONE_R),
+                       A_C_00000000, A_C_00000000, A_GPR(1), &pc);
+
+       /* Analog Front[l/r] = GPR[0/1] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AFRONT_L), A_C_00000000,
+                       A_C_00000000, A_GPR(0), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AFRONT_R), A_C_00000000,
+                       A_C_00000000, A_GPR(1), &pc);
+
+       /* Digital Front[l/r] = GPR[0/1] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L), A_C_00000000,
+                       A_C_00000000, A_GPR(0), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_FRONT_R), A_C_00000000,
+                       A_C_00000000, A_GPR(1), &pc);
+
+       /* Center and Subwoofer configuration */
+       /* Analog Center = GPR[0] + GPR[2] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ACENTER), A_C_00000000,
+                       A_GPR(0), A_GPR(2), &pc);
+       /* Analog Sub = GPR[1] + GPR[2] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ALFE), A_C_00000000,
+                       A_GPR(1), A_GPR(2), &pc);
+
+       /* Digital Center = GPR[0] + GPR[2] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_CENTER), A_C_00000000,
+                       A_GPR(0), A_GPR(2), &pc);
+       /* Digital Sub = GPR[1] + GPR[2] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_LFE), A_C_00000000,
+                       A_GPR(1), A_GPR(2), &pc);
+
+#if 0
+       /* Analog Rear[l/r] = (GPR[0/1] * RearVolume[l/r]) >> 31 */
+       /*   RearVolume = GPR[0x10/0x11] (Will this ever be implemented?) */
+       audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_AREAR_L), A_C_00000000,
+                       A_GPR(16), A_GPR(0), &pc);
+       audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_AREAR_R), A_C_00000000,
+                       A_GPR(17), A_GPR(1), &pc);
+
+       /* Digital Rear[l/r] = (GPR[0/1] * RearVolume[l/r]) >> 31 */
+       /*   RearVolume = GPR[0x10/0x11] (Will this ever be implemented?) */
+       audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_REAR_L), A_C_00000000,
+                       A_GPR(16), A_GPR(0), &pc);
+       audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_REAR_R), A_C_00000000,
+                       A_GPR(17), A_GPR(1), &pc);
+#else
+       /* XXX This is just a copy to the channel, since we do not have
+        *     a patch manager, it is useful for have another output enabled.
+        */
+
+       /* Analog Rear[l/r] = GPR[0/1] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AREAR_L), A_C_00000000,
+                       A_C_00000000, A_GPR(0), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AREAR_R), A_C_00000000,
+                       A_C_00000000, A_GPR(1), &pc);
+
+       /* Digital Rear[l/r] = GPR[0/1] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_REAR_L), A_C_00000000,
+                       A_C_00000000, A_GPR(0), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_REAR_R), A_C_00000000,
+                       A_C_00000000, A_GPR(1), &pc);
+#endif
+
+       /* ADC Recording buffer[l/r] = AC97Input[l/r] */
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ADC_CAP_L), A_C_00000000,
+                       A_C_00000000, A_EXTIN(A_EXTIN_AC97_L), &pc);
+       audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ADC_CAP_R), A_C_00000000,
+                       A_C_00000000, A_EXTIN(A_EXTIN_AC97_R), &pc);
+
+       /* resume normal operations */
+       emu_wrptr(sc, 0, A_DBG, 0);
+}
+
+static void
 emu_initefx(struct sc_info *sc)
 {
        int i;
        u_int32_t pc = 16;
 
+       /* acc3 0,0,0,0 - NOPs */
        for (i = 0; i < 512; i++) {
                emu_wrefx(sc, i * 2, 0x10040);
                emu_wrefx(sc, i * 2 + 1, 0x610040);
@@ -1175,24 +1424,34 @@
             0x010/0x011 : AC97 Codec (l/r)
             0x012/0x013 : ADC, S/PDIF (l/r)
             0x014/0x015 : Mic(left), Zoom (l/r)
-            0x016/0x017 : APS S/PDIF?? (l/r)
+            0x016/0x017 : TOS link in (l/r)
+            0x018/0x019 : Line/Mic 1 (l/r)
+            0x01a/0x01b : COAX S/PDIF (l/r)
+            0x01c/0x01d : Line/Mic 2 (l/r)
           Output
             0x020/0x021 : AC97 Output (l/r)
             0x022/0x023 : TOS link out (l/r)
-            0x024/0x025 : ??? (l/r)
+            0x024/0x025 : Center/LFE
             0x026/0x027 : LiveDrive Headphone (l/r)
             0x028/0x029 : Rear Channel (l/r)
             0x02a/0x02b : ADC Recording Buffer (l/r)
+            0x02c       : Mic Recording Buffer
+            0x031/0x032 : Analog Center/LFE
           Constants
             0x040 - 0x044 = 0 - 4
             0x045 = 0x8, 0x046 = 0x10, 0x047 = 0x20
             0x048 = 0x100, 0x049 = 0x10000, 0x04a = 0x80000
             0x04b = 0x10000000, 0x04c = 0x20000000, 0x04d = 0x40000000
-            0x04e = 0x80000000, 0x04f = 0x7fffffff
+            0x04e = 0x80000000, 0x04f = 0x7fffffff, 0x050 = 0xffffffff
+            0x051 = 0xfffffffe, 0x052 = 0xc0000000, 0x053 = 0x41fbbcdc
+            0x054 = 0x5a7ef9db, 0x055 = 0x00100000
           Temporary Values
             0x056 : Accumulator
-            0x058 : Noise source?
-            0x059 : Noise source?
+            0x057 : Condition Register
+            0x058 : Noise source
+            0x059 : Noise source
+            0x05a : IRQ Register
+            0x05b : TRAM Delay Base Address Count
           General Purpose Registers
             0x100 - 0x1ff
           Tank Memory Data Registers
@@ -1201,40 +1460,81 @@
             0x300 - 0x3ff
             */
 
-       /* Operators:
-          0 : z := w + (x * y >> 31)
-          4 : z := w + x * y
-          6 : z := w + x + y
-          */
-
        /* 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, iMACINT0, GPR(0), EXTIN(EXTIN_SPDIF_CD_L),
+                       FXBUS(FXBUS_PCM_LEFT), C_00000004, &pc);
+       emu_addefxop(sc, iMACINT0, GPR(1), EXTIN(EXTIN_SPDIF_CD_R),
+                       FXBUS(FXBUS_PCM_RIGHT), C_00000004, &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, iACC3, GPR(0), GPR(0), C_00000000,
+                       sc->APS ? EXTIN(EXTIN_TOSLINK_L) : C_00000000, &pc);
+       emu_addefxop(sc, iACC3, GPR(1), GPR(1), C_00000000,
+                       sc->APS ? EXTIN(EXTIN_TOSLINK_R) : C_00000000, &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, iACC3, EXTOUT(EXTOUT_AC97_L), C_00000000,
+                       C_00000000, GPR(0), &pc);
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_AC97_R), C_00000000,
+                       C_00000001, GPR(1), &pc);
+
+       /* GPR[2] = GPR[0] (Left) / 2 + GPR[1] (Right) / 2 -- Central volume */
+       emu_addefxop(sc, iINTERP, GPR(2), GPR(1), C_40000000, GPR(0), &pc);
+
+#if 0
        /* 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);
-       /* TOS out = GPR[0/1] */
-       emu_addefxop(sc, 6, 0x22, 0x40, 0x40, 0x100, &pc);
-       emu_addefxop(sc, 6, 0x23, 0x40, 0x40, 0x101, &pc);
-       /* Mute Out2 */
-       emu_addefxop(sc, 6, 0x24, 0x40, 0x40, 0x40, &pc);
-       emu_addefxop(sc, 6, 0x25, 0x40, 0x40, 0x40, &pc);
-       /* Mute Out3 */
-       emu_addefxop(sc, 6, 0x26, 0x40, 0x40, 0x40, &pc);
-       emu_addefxop(sc, 6, 0x27, 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);
+       /*   RearVolume = GPR[0x10/0x11] */
+       emu_addefxop(sc, iMAC0, EXTOUT(EXTOUT_REAR_L), C_00000000,
+                       GPR(16), GPR(0), &pc);
+       emu_addefxop(sc, iMAC0, EXTOUT(EXTOUT_REAR_R), C_00000000,
+                       GPR(17), GPR(1), &pc);
+#else
+       /* XXX This is just a copy to the channel, since we do not have
+        *     a patch manager, it is useful for have another output enabled.
+        */
+
+       /* Rear[l/r] = GPR[0/1] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_REAR_L), C_00000000,
+                       C_00000000, GPR(0), &pc);
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_REAR_R), C_00000000,
+                       C_00000000, GPR(1), &pc);
+#endif
 
+       /* TOS out[l/r] = GPR[0/1] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_TOSLINK_L), C_00000000,
+                       C_00000000, GPR(0), &pc);
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_TOSLINK_R), C_00000000,
+                       C_00000000, GPR(1), &pc);
+
+       /* Center and Subwoofer configuration */
+       /* Analog Center = GPR[0] + GPR[2] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ACENTER), C_00000000,
+                       GPR(0), GPR(2), &pc);
+       /* Analog Sub = GPR[1] + GPR[2] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ALFE), C_00000000,
+                       GPR(1), GPR(2), &pc);
+       /* Digital Center = GPR[0] + GPR[2] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_CENTER), C_00000000,
+                       GPR(0), GPR(2), &pc);
+       /* Digital Sub = GPR[1] + GPR[2] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_LFE), C_00000000,
+                       GPR(1), GPR(2), &pc);
+
+       /* Headphones[l/r] = GPR[0/1] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_HEADPHONE_L), C_00000000,
+                       C_00000000, GPR(0), &pc);
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_HEADPHONE_R), C_00000000,
+                       C_00000000, GPR(1), &pc);
+
+       /* ADC Recording buffer[l/r] = AC97Input[l/r] */
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ADC_CAP_L), C_00000000,
+                       C_00000000, EXTIN(EXTIN_AC97_L), &pc);
+       emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ADC_CAP_R), C_00000000,
+                       C_00000000, EXTIN(EXTIN_AC97_R), &pc);
+
+       /* resume normal operations */
        emu_wrptr(sc, 0, DBG, 0);
 }
 
@@ -1244,6 +1544,9 @@
 {
        u_int32_t spcs, ch, tmp, i;
 
+       /* enable additional AC97 slots */
+       emu_wrptr(sc, 0, AC97SLOT, AC97SLOT_CNTR | AC97SLOT_LFE);
+
        /* disable audio and lock cache */
        emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | 
HCFG_MUTEBUTTONENABLE, 4);
 
@@ -1262,6 +1565,12 @@
        emu_wrptr(sc, 0, SOLEL, 0);
        emu_wrptr(sc, 0, SOLEH, 0);
 
+       /* wonder what these do... */
+       if (sc->audigy) {
+               emu_wrptr(sc, 0, SPBYPASS, 0xf00);
+               emu_wrptr(sc, 0, AC97SLOT, 0x3);
+       }
+
        /* init envelope engine */
        for (ch = 0; ch < NUM_G; ch++) {
                emu_wrptr(sc, ch, DCYSUSV, ENV_OFF);
@@ -1295,6 +1604,18 @@
                emu_wrptr(sc, ch, ENVVOL, 0);
                emu_wrptr(sc, ch, ENVVAL, 0);
 
+               if (sc->audigy) {
+                       /* audigy cards need this to initialize correctly */
+                       emu_wrptr(sc, ch, 0x4c, 0);
+                       emu_wrptr(sc, ch, 0x4d, 0);
+                       emu_wrptr(sc, ch, 0x4e, 0);
+                       emu_wrptr(sc, ch, 0x4f, 0);
+                       /* set default routing */
+                       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;
@@ -1331,7 +1652,26 @@
        emu_wrptr(sc, 0, SPCS1, spcs);
        emu_wrptr(sc, 0, SPCS2, spcs);
 
-       emu_initefx(sc);
+       if (!sc->audigy)
+               emu_initefx(sc);
+       else if (sc->audigy2) { /* Audigy 2 */
+               /* from ALSA initialization code: */
+
+               /* Hack for Alice3 to work independent of haP16V driver */
+               u_int32_t tmp;
+
+               /* Setup SRCMulti_I2S SamplingRate */
+               tmp = emu_rdptr(sc, 0, A_SPDIF_SAMPLERATE) & 0xfffff1ff;
+               emu_wrptr(sc, 0, A_SPDIF_SAMPLERATE, tmp | 0x400);
+
+               /* Setup SRCSel (Enable SPDIF, I2S SRCMulti) */
+               emu_wr(sc, 0x20, 0x00600000, 4);
+               emu_wr(sc, 0x24, 0x00000014, 4);
+
+               /* Setup SRCMulti Input Audio Enable */
+               emu_wr(sc, 0x20, 0x006e0000, 4);
+               emu_wr(sc, 0x24, 0xff00ff00, 4);
+       }
 
        SLIST_INIT(&sc->mem.blocks);
        sc->mem.ptb_pages = emu_malloc(sc, MAXPAGES * sizeof(u_int32_t), 
&sc->mem.ptb_pages_addr);
@@ -1361,26 +1701,69 @@
        /* emu_memalloc(sc, EMUPAGESIZE); */
        /*
         *  Hokay, now enable the AUD bit
+        *
+        *  Audigy
+        *   Enable Audio = 0 (enabled after fx processor initialization)
+        *   Mute Disable Audio = 0
+        *   Joystick = 1
+        *
+        *  Audigy 2
+        *   Enable Audio = 1
+        *   Mute Disable Audio = 0
+        *   Joystick = 1
+        *   GP S/PDIF AC3 Enable = 1
+        *   CD S/PDIF AC3 Enable = 1
+        *
+        *  EMU10K1
         *   Enable Audio = 1
         *   Mute Disable Audio = 0
         *   Lock Tank Memory = 1
         *   Lock Sound Memory = 0
         *   Auto Mute = 1
         */
-       tmp = HCFG_AUDIOENABLE | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE;
-       if (sc->rev >= 6)
-               tmp |= HCFG_JOYENABLE;
-       emu_wr(sc, HCFG, tmp, 4);
-
-       /* TOSLink detection */
-       sc->tos_link = 0;
-       tmp = emu_rd(sc, HCFG, 4);
-       if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
-               emu_wr(sc, HCFG, tmp | 0x800, 4);
-               DELAY(50);
-               if (tmp != (emu_rd(sc, HCFG, 4) & ~0x800)) {
-                       sc->tos_link = 1;
-                       emu_wr(sc, HCFG, tmp, 4);
+
+       if (sc->audigy) {
+               tmp = HCFG_AUTOMUTE | HCFG_JOYENABLE;
+               if (sc->audigy2)        /* Audigy 2 */
+                       tmp = HCFG_AUDIOENABLE | HCFG_AC3ENABLE_CDSPDIF |
+                           HCFG_AC3ENABLE_GPSPDIF;
+               emu_wr(sc, HCFG, tmp, 4);
+
+               audigy_initefx(sc);
+
+               /* from ALSA initialization code: */
+
+               /* enable audio and disable both audio/digital outputs */
+               emu_wr(sc, HCFG, emu_rd(sc, HCFG, 4) | HCFG_AUDIOENABLE, 4);
+               emu_wr(sc, A_IOCFG, emu_rd(sc, A_IOCFG, 4) & ~A_IOCFG_GPOUT_AD,
+                   4);
+               if (sc->audigy2) {      /* Audigy 2 */
+                       /* Unmute Analog.
+                        * Set GPO6 to 1 for Apollo. This has to be done after
+                        * init Alice3 I2SOut beyond 48kHz.
+                        * So, sequence is important.
+                        */
+                       emu_wr(sc, A_IOCFG,
+                           emu_rd(sc, A_IOCFG, 4) | A_IOCFG_GPOUT_A, 4);
+               }
+       } else {
+               /* EMU10K1 initialization code */
+               tmp = HCFG_AUDIOENABLE | HCFG_AUTOMUTE | HCFG_LOCKTANKCACHE;
+               if (sc->rev >= 6)
+                       tmp |= HCFG_JOYENABLE;
+
+               emu_wr(sc, HCFG, tmp, 4);
+
+               /* TOSLink detection */
+               sc->tos_link = 0;
+               tmp = emu_rd(sc, HCFG, 4);
+               if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
+                       emu_wr(sc, HCFG, tmp | HCFG_GPOUT1, 4);
+                       DELAY(50);
+                       if (tmp != (emu_rd(sc, HCFG, 4) & ~HCFG_GPOUT1)) {
+                               sc->tos_link = 1;
+                               emu_wr(sc, HCFG, tmp, 4);
+                       }
                }
        }
 
@@ -1402,6 +1785,10 @@
                emu_wrptr(sc, ch, CPF, 0);
        }
 
+       if (sc->audigy) {       /* stop fx processor */
+               emu_wrptr(sc, 0, A_DBG, A_DBG_SINGLE_STEP);
+       }
+
        /* disable audio and lock cache */
        emu_wr(sc, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | 
HCFG_MUTEBUTTONENABLE, 4);
 
@@ -1441,11 +1828,14 @@
        case EMU10K1_PCI_ID:
                s = "Creative EMU10K1";
                break;
-/*
+
        case EMU10K2_PCI_ID:
-               s = "Creative EMU10K2";
+               if (pci_get_revid(dev) == 0x04)
+                       s = "Creative Audigy 2 (EMU10K2)";
+               else
+                       s = "Creative Audigy (EMU10K2)";
                break;
-*/
+
        default:
                return ENXIO;
        }
@@ -1472,6 +1862,10 @@
        sc->dev = dev;
        sc->type = pci_get_devid(dev);
        sc->rev = pci_get_revid(dev);
+       sc->audigy = (sc->type == EMU10K2_PCI_ID);
+       sc->audigy2 = (sc->audigy && sc->rev == 0x04);
+       sc->nchans = sc->audigy ? 8 : 4;
+       sc->addrmask = sc->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
 
        data = pci_read_config(dev, PCIR_COMMAND, 2);
        data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN);
@@ -1518,8 +1912,8 @@
 
        snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", 
rman_get_start(sc->reg), rman_get_start(sc->irq));
 
-       if (pcm_register(dev, sc, EMU_CHANS, gotmic ? 3 : 2)) goto bad;
-       for (i = 0; i < EMU_CHANS; i++)
+       if (pcm_register(dev, sc, sc->nchans, gotmic ? 3 : 2)) goto bad;
+       for (i = 0; i < sc->nchans; i++)
                pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
        for (i = 0; i < (gotmic ? 3 : 2); i++)
                pcm_addchan(dev, PCMDIR_REC, &emurchan_class, sc);
Index: gnu/dev/sound/pci/emu10k1-ac97.h
===================================================================
RCS file: /home/ncvs/src/sys/gnu/dev/sound/pci/emu10k1-ac97.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 emu10k1-ac97.h
--- gnu/dev/sound/pci/emu10k1-ac97.h    21 Apr 2003 02:27:52 -0000      1.1.1.1
+++ gnu/dev/sound/pci/emu10k1-ac97.h    7 Jun 2003 19:32:38 -0000
@@ -1,8 +1,15 @@
-#ifndef _AC97_CODEC_H_
-#define _AC97_CODEC_H_
+#ifndef _EMU10K1_AC97_H_
+#define _EMU10K1_AC97_H_
+
+/*********************************************/
+/* emu10k1-ac97.h, derived from ac97_codec.h */
+/*********************************************/
+
+/********************************************************************************************************/
+/* AC97 pointer-offset register set, accessed through the AC97ADDRESS and AC97DATA 
registers           */
+/********************************************************************************************************/
+
 
-#include <linux/types.h>
-#include <linux/soundcard.h>
 
 /* AC97 1.0 */
 #define  AC97_RESET               0x0000      //
@@ -180,66 +187,5 @@
                                     (FOO < SOUND_MIXER_NRDEVICES) && \
                                     (CODEC)->supported_mixers & (1<<FOO) )
 
-struct ac97_codec {
-       /* AC97 controller connected with */
-       void *private_data;
-
-       char *name;
-       int id;
-       int dev_mixer; 
-       int type;
-
-       struct ac97_ops *codec_ops;
-
-       /* controller specific lower leverl ac97 accessing routines */
-       u16  (*codec_read)  (struct ac97_codec *codec, u8 reg);
-       void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
-
-       /* Wait for codec-ready.  Ok to sleep here.  */
-       void  (*codec_wait)  (struct ac97_codec *codec);
-
-       /* OSS mixer masks */
-       int modcnt;
-       int supported_mixers;
-       int stereo_mixers;
-       int record_sources;
-
-       int bit_resolution;
-
-       /* OSS mixer interface */
-       int  (*read_mixer) (struct ac97_codec *codec, int oss_channel);
-       void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
-                           unsigned int left, unsigned int right);
-       int  (*recmask_io) (struct ac97_codec *codec, int rw, int mask);
-       int  (*mixer_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long 
arg);
-
-       /* saved OSS mixer states */
-       unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-
-       /* Software Modem interface */
-       int  (*modem_ioctl)(struct ac97_codec *codec, unsigned int cmd, unsigned long 
arg);
-};
-
-/*
- *     Operation structures for each known AC97 chip
- */
- 
-struct ac97_ops
-{
-       /* Initialise */
-       int (*init)(struct ac97_codec *c);
-       /* Amplifier control */
-       int (*amplifier)(struct ac97_codec *codec, int on);
-       /* Digital mode control */
-       int (*digital)(struct ac97_codec *codec, int format);
-};
-
-extern int ac97_read_proc (char *page_out, char **start, off_t off,
-                          int count, int *eof, void *data);
-extern int ac97_probe_codec(struct ac97_codec *);
-extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
-extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
-extern int ac97_save_state(struct ac97_codec *codec);
-extern int ac97_restore_state(struct ac97_codec *codec);
 
-#endif /* _AC97_CODEC_H_ */
+#endif /* _EMU10K_AC97_H_ */
Index: gnu/dev/sound/pci/emu10k1-alsa.h
===================================================================
RCS file: /home/ncvs/src/sys/gnu/dev/sound/pci/emu10k1-alsa.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 emu10k1-alsa.h
--- gnu/dev/sound/pci/emu10k1-alsa.h    7 Jun 2003 20:54:30 -0000       1.1.1.1
+++ gnu/dev/sound/pci/emu10k1-alsa.h    7 Jun 2003 21:24:48 -0000
@@ -71,9 +71,12 @@
                                                /* channel number of the register to 
be         */
                                                /* accessed.  For non per-channel 
registers the */
                                                /* value should be set to zero.        
         */
+#endif /* __KERNEL__ */
+
 #define PTR_ADDRESS_MASK       0x07ff0000      /* Register index                      
         */
-#define A_PTR_ADDRESS_MASK     0x0fff0000
+#define        A_PTR_ADDRESS_MASK      0x0fff0000      /* Audigy register index       
                 */ 
 
+#ifdef __KERNEL__
 #define DATA                   0x04            /* Indexed register set data register  
         */
 
 #define IPR                    0x08            /* Global interrupt pending register   
         */
@@ -1284,41 +1287,6 @@
 #define EMU10K1_GRP_TRANSLATION_BASS           2
 #define EMU10K1_GRP_TRANSLATION_TREBLE         3
 #define EMU10K1_GPR_TRANSLATION_ONOFF          4
-
-typedef struct {
-       snd_ctl_elem_id_t id;           /* full control ID definition */
-       unsigned int vcount;            /* visible count */
-       unsigned int count;             /* count of GPR (1..16) */
-       unsigned char gpr[32];          /* GPR number(s) */
-       unsigned int value[32];         /* initial values */
-       unsigned int min;               /* minimum range */
-       unsigned int max;               /* maximum range */
-       unsigned int translation;       /* translation type (EMU10K1_GRP_TRANSLATION*) 
*/
-} emu10k1_fx8010_control_gpr_t;
-
-typedef struct {
-       char name[128];
-
-       unsigned long gpr_valid[0x100/(sizeof(unsigned long)*8)]; /* bitmask of valid 
initializers */
-       unsigned int gpr_map[0x100];      /* initializers */
-
-       unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
-       emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace 
*/
-
-       unsigned int gpr_del_control_count; /* count of GPR controls to remove */
-       snd_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */
-
-       unsigned int gpr_list_control_count; /* count of GPR controls to list */
-       unsigned int gpr_list_control_total; /* total count of GPR controls */
-       emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */
-
-       unsigned long tram_valid[0xa0/(sizeof(unsigned long)*8)]; /* bitmask of valid 
initializers */
-       unsigned int tram_data_map[0xa0]; /* data initializers */
-       unsigned int tram_addr_map[0xa0]; /* map initializers */
-
-       unsigned long code_valid[512/(sizeof(unsigned long)*8)];  /* bitmask of valid 
instructions */
-       unsigned int code[512][2];        /* one instruction - 64 bits */
-} emu10k1_fx8010_code_t;
 
 typedef struct {
        unsigned int address;           /* 31.bit == 1 -> external TRAM */
Index: gnu/dev/sound/pci/emu10k1.h
===================================================================
RCS file: /home/ncvs/src/sys/gnu/dev/sound/pci/emu10k1.h,v
retrieving revision 1.6
diff -u -r1.6 emu10k1.h
--- gnu/dev/sound/pci/emu10k1.h 18 Apr 2003 04:13:38 -0000      1.6
+++ gnu/dev/sound/pci/emu10k1.h 7 Jun 2003 20:14:00 -0000
@@ -1,7 +1,7 @@
 /*
  **********************************************************************
  *     emu10k1.h, derived from 8010.h
- *     Copyright 1999, 2000 Creative Labs, Inc.
+ *     Copyright 1999-2001 Creative Labs, Inc.
  *
  **********************************************************************
  *
@@ -11,6 +11,8 @@
  *     November 2, 1999     Alan Cox       Cleaned of 8bit chars, DOS
  *                                         line endings
  *     December 8, 1999     Jon Taylor     Added lots of new register info
+ *     May 16, 2001         Daniel Bertrand Added unofficial DBG register info
+ *     Oct-Nov 2001         D.B.            Added unofficial Audigy registers 
  *
  **********************************************************************
  *
@@ -38,21 +40,13 @@
 #ifndef EMU10K1_H
 #define EMU10K1_H
 
-/* ------------------- DEFINES -------------------- */
+// Driver version:
+#define MAJOR_VER 0
+#define MINOR_VER 20
+#define DRIVER_VERSION "0.20a"
 
-#define EMUPAGESIZE    4096    /* don't change */
-#define MAXREQVOICES   8
-#define MAXPAGES       (32768 * 64 / EMUPAGESIZE)      /* WAVEOUT_MAXBUFSIZE * NUM_G 
/ EMUPAGESIZE */
-#define RESERVED       0
-#define NUM_MIDI       16
-#define NUM_G          64              /* use all channels */
-#define NUM_FXSENDS    4
 
-
-#define TMEMSIZE       256*1024
-#define TMEMSIZEREG    4
-
-#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip 
>> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
+// Audigy specify registers are prefixed with 'A_'
 
 
/************************************************************************************************/
 /* PCI function 0 registers, address = <val> + PCIBASE0                               
                 */
@@ -72,6 +66,11 @@
 #define IPR                    0x08            /* Global interrupt pending register   
         */
                                                /* Clear pending interrupts by writing 
a 1 to   */
                                                /* the relevant bits and zero to the 
other bits */
+
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)         
         */
+#define A_IPR_MIDITRANSBUFEMPTY2       0x10000000      /* MIDI UART transmit buffer 
empty              */
+#define A_IPR_MIDIRECVBUFEMPTY2        0x08000000      /* MIDI UART receive buffer 
empty               */
+
 #define IPR_SAMPLERATETRACKER  0x01000000      /* Sample rate tracker lock status 
change       */
 #define IPR_FXDSP              0x00800000      /* Enable FX DSP interrupts            
         */
 #define IPR_FORCEINT           0x00400000      /* Force Sound Blaster interrupt       
         */
@@ -96,6 +95,10 @@
                                                /* IP is written with CL set, the bit 
in CLIPL  */
                                                /* or CLIPH corresponding to the CIN 
value      */
                                                /* written will be cleared.            
         */
+#define A_IPR_MIDITRANSBUFEMPTY1       IPR_MIDITRANSBUFEMPTY   /* MIDI UART transmit 
buffer empty              */
+#define A_IPR_MIDIRECVBUFEMPTY1        IPR_MIDIRECVBUFEMPTY    /* MIDI UART receive 
buffer empty               */
+
+
 
 #define INTE                   0x0c            /* Interrupt enable register           
         */
 #define INTE_VIRTUALSB_MASK    0xc0000000      /* Virtual Soundblaster I/O port 
capture        */
@@ -123,6 +126,11 @@
                                                /* behavior and possibly random 
segfaults and   */
                                                /* lockups if enabled.                 
         */
 
+/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1)         
         */
+#define A_INTE_MIDITXENABLE2   0x00020000      /* Enable MIDI transmit-buffer-empty 
interrupts */
+#define A_INTE_MIDIRXENABLE2   0x00010000      /* Enable MIDI receive-buffer-empty 
interrupts  */
+
+
 #define INTE_SAMPLERATETRACKER 0x00002000      /* Enable sample rate tracker 
interrupts        */
                                                /* NOTE: This bit must always be 
enabled        */
 #define INTE_FXDSPENABLE       0x00001000      /* Enable FX DSP interrupts            
         */
@@ -139,6 +147,10 @@
 #define INTE_MIDITXENABLE      0x00000002      /* Enable MIDI transmit-buffer-empty 
interrupts */
 #define INTE_MIDIRXENABLE      0x00000001      /* Enable MIDI receive-buffer-empty 
interrupts  */
 
+/* The next two interrupts are for the midi port on the Audigy (A_MPU2)        */
+#define A_INTE_MIDITXENABLE1   INTE_MIDITXENABLE
+#define A_INTE_MIDIRXENABLE1   INTE_MIDIRXENABLE
+
 #define WC                     0x10            /* Wall Clock register                 
         */
 #define WC_SAMPLECOUNTER_MASK  0x03FFFFC0      /* Sample periods elapsed since reset  
         */
 #define WC_SAMPLECOUNTER       0x14060010
@@ -170,7 +182,12 @@
 #define HCFG_CODECFORMAT_I2S   0x00010000      /* I2S CODEC format -- Secondary 
(Rear) Output  */
 #define HCFG_GPINPUT0          0x00004000      /* External pin112                     
         */
 #define HCFG_GPINPUT1          0x00002000      /* External pin110                     
         */
+
 #define HCFG_GPOUTPUT_MASK     0x00001c00      /* External pins which may be 
controlled        */
+#define HCFG_GPOUT0            0x00001000      /* set to enable digital out on 5.1 
cards       */
+#define HCFG_GPOUT1            0x00000800      /* External pin? (IR)                  
         */
+#define HCFG_GPOUT2            0x00000400      /* External pin? (IR)                  
         */
+
 #define HCFG_JOYENABLE         0x00000200      /* Internal joystick enable            
         */
 #define HCFG_PHASETRACKENABLE  0x00000100      /* Phase tracking enable               
         */
                                                /* 1 = Force all 3 async digital 
inputs to use  */
@@ -178,6 +195,7 @@
 #define HCFG_AC3ENABLE_MASK    0x0x0000e0      /* AC3 async input control - Not 
implemented    */
 #define HCFG_AC3ENABLE_ZVIDEO  0x00000080      /* Channels 0 and 1 replace ZVIDEO     
         */
 #define HCFG_AC3ENABLE_CDSPDIF 0x00000040      /* Channels 0 and 1 replace CDSPDIF    
         */
+#define HCFG_AC3ENABLE_GPSPDIF  0x00000020      /* Channels 0 and 1 replace GPSPDIF   
          */
 #define HCFG_AUTOMUTE          0x00000010      /* When set, the async sample rate 
convertors   */
                                                /* will automatically mute their 
output when    */
                                                /* they are not rate-locked to the 
external     */
@@ -186,6 +204,7 @@
                                                /* NOTE: This should generally never 
be used.   */
 #define HCFG_LOCKTANKCACHE_MASK        0x00000004      /* 1 = Cancel bustmaster 
accesses to tankcache  */
                                                /* NOTE: This should generally never 
be used.   */
+#define HCFG_LOCKTANKCACHE     0x01020014
 #define HCFG_MUTEBUTTONENABLE  0x00000002      /* 1 = Master mute button sets 
AUDIOENABLE = 0. */
                                                /* NOTE: This is a 'cheap' way to 
implement a   */
                                                /* master mute function on the mute 
button, and */
@@ -196,6 +215,8 @@
                                                /* Should be set to 1 when the EMU10K1 
is       */
                                                /* completely initialized.             
         */
 
+//For Audigy, MPU port move to 0x70-0x74 ptr register
+
 #define MUDATA                 0x18            /* MPU401 data register (8 bits)       
         */
 
 #define MUCMD                  0x19            /* MPU401 command register (8 bits)    
         */
@@ -207,11 +228,16 @@
 #define MUSTAT_IRDYN           0x80            /* 0 = MIDI data or command ACK        
         */
 #define MUSTAT_ORDYN           0x40            /* 0 = MUDATA can accept a command or 
data      */
 
-#define TIMER                  0x1a            /* Timer terminal count register       
         */
+#define A_IOCFG                        0x18            /* GPIO on Audigy card 
(16bits)                 */
+#define A_GPINPUT_MASK         0xff00
+#define A_GPOUTPUT_MASK                0x00ff
+#define A_IOCFG_GPOUT0         0x0044          /* ? */
+
+#define TIMER                  0x1a            /* Timer terminal count register 
(16-bit)       */
                                                /* NOTE: After the rate is changed, a 
maximum   */
                                                /* of 1024 sample periods should be 
allowed     */
                                                /* before the new rate is guaranteed 
accurate.  */
-#define TIMER_RATE_MASK                0x000003ff      /* Timer interrupt rate in 
sample periods       */
+#define TIMER_RATE_MASK                0x03ff          /* Timer interrupt rate in 
sample periods       */
                                                /* 0 == 1024 periods, [1..4] are not 
useful     */
 #define TIMER_RATE             0x0a00001a
 
@@ -221,54 +247,6 @@
 #define AC97ADDRESS_READY      0x80            /* Read-only bit, reflects CODEC READY 
signal   */
 #define AC97ADDRESS_ADDRESS    0x7f            /* Address of indexed AC97 register    
         */
 
-/************************************************************************************************/
-/* PCI function 1 registers, address = <val> + PCIBASE1                               
                 */
-/************************************************************************************************/
-
-#define JOYSTICK1              0x00            /* Analog joystick port register       
         */
-#define JOYSTICK2              0x01            /* Analog joystick port register       
         */
-#define JOYSTICK3              0x02            /* Analog joystick port register       
         */
-#define JOYSTICK4              0x03            /* Analog joystick port register       
         */
-#define JOYSTICK5              0x04            /* Analog joystick port register       
         */
-#define JOYSTICK6              0x05            /* Analog joystick port register       
         */
-#define JOYSTICK7              0x06            /* Analog joystick port register       
         */
-#define JOYSTICK8              0x07            /* Analog joystick port register       
         */
-
-/* When writing, any write causes JOYSTICK_COMPARATOR output enable to be pulsed on 
write.     */
-/* When reading, use these bitfields: */
-#define JOYSTICK_BUTTONS       0x0f            /* Joystick button data                
         */
-#define JOYSTICK_COMPARATOR    0xf0            /* Joystick comparator data            
         */
-
-
-/********************************************************************************************************/
-/* AC97 pointer-offset register set, accessed through the AC97ADDRESS and AC97DATA 
registers           */
-/********************************************************************************************************/
-
-#define AC97_RESET             0x00
-#define AC97_MASTERVOLUME      0x02            /* Master volume                       
                 */
-#define AC97_HEADPHONEVOLUME   0x04            /* Headphone volume                    
                 */
-#define AC97_MASTERVOLUMEMONO  0x06            /* Mast volume mono                    
                 */
-#define AC97_MASTERTONE                0x08
-#define AC97_PCBEEPVOLUME      0x0a            /* PC speaker system beep volume       
                 */
-#define AC97_PHONEVOLUME       0x0c
-#define AC97_MICVOLUME         0x0e
-#define AC97_LINEINVOLUME      0x10
-#define AC97_CDVOLUME          0x12
-#define AC97_VIDEOVOLUME       0x14
-#define AC97_AUXVOLUME         0x16
-#define AC97_PCMOUTVOLUME      0x18
-#define AC97_RECORDSELECT      0x1a
-#define AC97_RECORDGAIN                0x1c
-#define AC97_RECORDGAINMIC     0x1e
-#define AC97_GENERALPURPOSE    0x20
-#define AC97_3DCONTROL         0x22
-#define AC97_MODEMRATE         0x24
-#define AC97_POWERDOWN         0x26
-#define AC97_VENDORID1         0x7c
-#define AC97_VENDORID2         0x7e
-#define AC97_ZVIDEOVOLUME      0xec
-#define AC97_AC3VOLUME         0xed
-
 
/********************************************************************************************************/
 /* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers   
                 */
 
/********************************************************************************************************/
@@ -444,6 +422,8 @@
 #define TREMFRQ                0x1c            /* Tremolo amount and modulation LFO 
frequency register */
 #define TREMFRQ_DEPTH          0x0000ff00      /* Tremolo depth                       
                 */
                                                /* Signed 2's complement, with +/- 
12dB extremes        */
+#define TREMFRQ_FREQUENCY      0x000000ff      /* Tremolo LFO frequency               
                 */
+                                               /* ??Hz steps, maximum of ?? Hz.       
                 */
 
 #define FM2FRQ2                0x1d            /* Vibrato amount and vibrato LFO 
frequency register    */
 #define FM2FRQ2_DEPTH          0x0000ff00      /* Vibrato LFO vibrato depth           
                 */
@@ -484,7 +464,12 @@
 #define ADCCR_LCHANENABLE      0x00000008      /* Enables left channel for writing to 
the host         */
                                                /* NOTE: To guarantee phase coherency, 
both channels    */
                                                /* must be disabled prior to enabling 
both channels.    */
+#define A_ADCCR_RCHANENABLE    0x00000020
+#define A_ADCCR_LCHANENABLE    0x00000010
+
+#define A_ADCCR_SAMPLERATE_MASK 0x0000000F      /* Audigy sample rate convertor 
output rate            */
 #define ADCCR_SAMPLERATE_MASK  0x00000007      /* Sample rate convertor output rate   
                 */
+
 #define ADCCR_SAMPLERATE_48    0x00000000      /* 48kHz sample rate                   
                 */
 #define ADCCR_SAMPLERATE_44    0x00000001      /* 44.1kHz sample rate                 
                 */
 #define ADCCR_SAMPLERATE_32    0x00000002      /* 32kHz sample rate                   
                 */
@@ -494,10 +479,16 @@
 #define ADCCR_SAMPLERATE_11    0x00000006      /* 11.025kHz sample rate               
                 */
 #define ADCCR_SAMPLERATE_8     0x00000007      /* 8kHz sample rate                    
                 */
 
+#define A_ADCCR_SAMPLERATE_12  0x00000006      /* 12kHz sample rate                   
                 */
+#define A_ADCCR_SAMPLERATE_11  0x00000007      /* 11.025kHz sample rate               
                 */
+#define A_ADCCR_SAMPLERATE_8   0x00000008      /* 8kHz sample rate                    
                 */
+
 #define FXWC                   0x43            /* FX output write channels register   
                 */
                                                /* When set, each bit enables the 
writing of the        */
-                                               /* corresponding FX output channel 
into host memory     */
-
+                                               /* corresponding FX output channel 
(internal registers  */
+                                               /* 0x20-0x3f) into host memory. This 
mode of recording  */
+                                               /* is 16bit, 48KHz only. All 32 
channels can be enabled */
+                                               /* simultaneously.                     
                 */
 #define TCBS                   0x44            /* Tank cache buffer size register     
                 */
 #define TCBS_MASK              0x00000007      /* Tank cache buffer size field        
                 */
 #define TCBS_BUFFSIZE_16K      0x00000000
@@ -565,8 +556,25 @@
 
 #define DBG                    0x52            /* DO NOT PROGRAM THIS REGISTER!!! MAY 
DESTROY CHIP */
 
+/* definitions for debug register - taken from the alsa drivers */
+#define DBG_ZC                  0x80000000      /* zero tram counter */
+#define DBG_SATURATION_OCCURED  0x02000000      /* saturation control */
+#define DBG_SATURATION_ADDR     0x01ff0000      /* saturation address */
+#define DBG_SINGLE_STEP         0x00008000      /* single step mode */
+#define DBG_STEP                0x00004000      /* start single step */
+#define DBG_CONDITION_CODE      0x00003e00      /* condition code */
+#define DBG_SINGLE_STEP_ADDR    0x000001ff      /* single step address */
+
+
 #define REG53                  0x53            /* DO NOT PROGRAM THIS REGISTER!!! MAY 
DESTROY CHIP */
 
+#define A_DBG                   0x53
+#define A_DBG_SINGLE_STEP       0x00020000     /* Set to zero to start dsp */
+#define A_DBG_ZC                0x40000000     /* zero tram counter */
+#define A_DBG_STEP_ADDR                 0x000003ff
+#define A_DBG_SATURATION_OCCURED 0x20000000
+#define A_DBG_SATURATION_ADDR   0x0ffc0000
+
 #define SPCS0                  0x54            /* SPDIF output Channel Status 0 
register       */
 
 #define SPCS1                  0x55            /* SPDIF output Channel Status 1 
register       */
@@ -613,6 +621,10 @@
 #define SPBYPASS               0x5e            /* SPDIF BYPASS mode register          
         */
 #define SPBYPASS_ENABLE                0x00000001      /* Enable SPDIF bypass mode    
                 */
 
+#define AC97SLOT               0x5f            /* additional AC97 slots enable bits */
+#define AC97SLOT_CNTR          0x10            /* Center enable */
+#define AC97SLOT_LFE           0x20            /* LFE enable */
+
 #define CDSRCS                 0x60            /* CD-ROM Sample Rate Converter status 
register */
 
 #define GPSRCS                 0x61            /* General Purpose SPDIF sample rate 
cvt status */
@@ -626,10 +638,19 @@
 #define SRCS_RATELOCKED                0x01000000      /* Sample rate locked          
                 */
 #define SRCS_ESTSAMPLERATE     0x0007ffff      /* Do not modify this field.           
         */
 
+
+/* Note that these values can vary +/- by a small amount                              
          */
+#define SRCS_SPDIFRATE_44      0x0003acd9
+#define SRCS_SPDIFRATE_48      0x00040000
+#define SRCS_SPDIFRATE_96      0x00080000
+
 #define MICIDX                  0x63            /* Microphone recording buffer index 
register   */
 #define MICIDX_MASK             0x0000ffff      /* 16-bit value                       
          */
 #define MICIDX_IDX             0x10000063
 
+#define A_ADCIDX               0x63
+#define A_ADCIDX_IDX           0x10000063
+
 #define ADCIDX                 0x64            /* ADC recording buffer index register 
         */
 #define ADCIDX_MASK            0x0000ffff      /* 16 bit index field                  
         */
 #define ADCIDX_IDX             0x10000064
@@ -638,9 +659,50 @@
 #define FXIDX_MASK             0x0000ffff      /* 16-bit value                        
         */
 #define FXIDX_IDX              0x10000065
 
+/* This is the MPU port on the card (via the game port)                               
                 */
+#define A_MUDATA1              0x70
+#define A_MUCMD1               0x71
+#define A_MUSTAT1              A_MUCMD1
+
+/* This is the MPU port on the Audigy Drive                                           
         */
+#define A_MUDATA2              0x72
+#define A_MUCMD2               0x73
+#define A_MUSTAT2              A_MUCMD2        
+
+/* The next two are the Audigy equivalent of FXWC                                     
         */
+/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously)   
         */
+/* Each bit selects a channel for recording */
+#define A_FXWC1                        0x74            /* Selects 0x7f-0x60 for FX 
recording           */
+#define A_FXWC2                        0x75            /* Selects 0x9f-0x80 for FX 
recording           */
+
+#define A_SPDIF_SAMPLERATE     0x76            /* Set the sample rate of SPDIF output 
         */
+#define A_SPDIF_48000          0x00000080
+#define A_SPDIF_44100          0x00000000
+#define A_SPDIF_96000          0x00000040
+
+#define A_FXRT2                        0x7c
+#define A_FXRT_CHANNELE                0x0000003f      /* Effects send bus number for 
channel's effects send E */
+#define A_FXRT_CHANNELF                0x00003f00      /* Effects send bus number for 
channel's effects send F */
+#define A_FXRT_CHANNELG                0x003f0000      /* Effects send bus number for 
channel's effects send G */
+#define A_FXRT_CHANNELH                0x3f000000      /* Effects send bus number for 
channel's effects send H */
+
+#define A_SENDAMOUNTS          0x7d
+#define A_FXSENDAMOUNT_E_MASK  0xff000000
+#define A_FXSENDAMOUNT_F_MASK  0x00ff0000
+#define A_FXSENDAMOUNT_G_MASK  0x0000ff00
+#define A_FXSENDAMOUNT_H_MASK  0x000000ff
+
+/* The send amounts for this one are the same as used with the emu10k1 */
+#define A_FXRT1                        0x7e
+#define A_FXRT_CHANNELA                0x0000003f
+#define A_FXRT_CHANNELB                0x00003f00
+#define A_FXRT_CHANNELC                0x003f0000
+#define A_FXRT_CHANNELD                0x3f000000
+
+
 /* Each FX general purpose register is 32 bits in length, all bits are used           
         */
 #define FXGPREGBASE            0x100           /* FX general purpose registers base   
         */
-
+#define A_FXGPREGBASE          0x400           /* Audigy GPRs, 0x400 to 0x5ff         
         */
 /* Tank audio data is logarithmically compressed down to 16 bits before writing to 
TRAM and is */
 /* decompressed back to 20 bits on a read.  There are a total of 160 locations, the 
last 32    */
 /* locations are for external TRAM.                                                   
         */
@@ -665,10 +727,14 @@
 #define HIWORD_RESULT_MASK     0x000ffc00      /* Instruction result                  
         */
 #define HIWORD_OPA_MASK                0x000003ff      /* Instruction operand A       
                 */
 
-#define ENABLE                         0xffffffff
-#define DISABLE                0x00000000
 
-#define ENV_ON                 0x80
-#define ENV_OFF                        0x00
+/* Audigy Soundcard have a different instruction format */
+#define AUDIGY_CODEBASE                0x600
+#define A_LOWORD_OPY_MASK      0x000007ff              
+#define A_LOWORD_OPX_MASK      0x007ff000
+#define A_HIWORD_OPCODE_MASK   0x0f000000
+#define A_HIWORD_RESULT_MASK   0x007ff000
+#define A_HIWORD_OPA_MASK      0x000007ff
+
 
 #endif /* EMU10K1_H */
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to