[ALSA] snd-emu10k1: Add support for E-Mu 1616 PCI, 1616M PCI, 0404 PCI, E-Mu
authorJames Courtier-Dutton <James@superbug.co.uk>
Mon, 23 Jul 2007 13:01:46 +0000 (14:01 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 16 Oct 2007 13:57:43 +0000 (15:57 +0200)
Notebook.
Description: The .device=0x0008 chips have new, but different EMU32 in/out
channels. Driver updated to make use of these EMU32 channels.

Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
include/sound/emu10k1.h
sound/pci/emu10k1/emufx.c
sound/pci/emu10k1/emuproc.c

index 529d0a5..868f3bd 100644 (file)
@@ -1746,6 +1746,8 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
 #define A_FXBUS2(x)    (0x80 + (x))    /* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
 #define A_EMU32OUTH(x) (0xa0 + (x))    /* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" - ??? */
 #define A_EMU32OUTL(x) (0xb0 + (x))    /* x = 0x00 - 0x0f "EMU32_OUT_1 - _F" - ??? */
+#define A3_EMU32IN(x)  (0x160 + (x))   /* x = 0x00 - 0x3f "EMU32_IN_00 - _3F" - Only when .device = 0x0008 */
+#define A3_EMU32OUT(x) (0x1E0 + (x))   /* x = 0x00 - 0x0f "EMU32_OUT_00 - _3F" - Only when .device = 0x0008 */
 #define A_GPR(x)       (A_FXGPREGBASE + (x))
 
 /* cc_reg constants */
index 7206c0f..febdd13 100644 (file)
@@ -1207,7 +1207,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
        A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
        snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
        gpr += 2;
-       
+
        /* PCM Surround Playback (independent from stereo mix) */
        A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
        A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
@@ -1267,8 +1267,16 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
 
        /* emu1212 DSP 0 and DSP 1 Capture */
        if (emu->card_capabilities->emu1010) {
-               A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
-               A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
+               if (emu->card_capabilities->ca0108_chip) {
+                       /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
+                       A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
+                       A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
+                       A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
+                       A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
+               } else {
+                       A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
+                       A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
+               }
                snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
                gpr += 2;
        }
@@ -1516,7 +1524,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
                /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
                snd_printk("EMU outputs on\n");
                for (z = 0; z < 8; z++) {
-                       A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
+                       if (emu->card_capabilities->ca0108_chip) {
+                               A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
+                       } else {
+                               A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
+                       }
                }
        }
 
@@ -1557,106 +1569,116 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
 #endif
 
        if (emu->card_capabilities->emu1010) {
-               snd_printk("EMU inputs on\n");
-               /* Capture 16 (originally 8) channels of S32_LE sound */
-               
-               /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
-               /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
-               /* A_P16VIN(0) is delayed by one sample,
-                * so all other A_P16VIN channels will need to also be delayed
-                */
-               /* Left ADC in. 1 of 2 */
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
-               /* Right ADC in 1 of 2 */
-               gpr_map[gpr++] = 0x00000000;
-               /* Delaying by one sample: instead of copying the input
-                * value A_P16VIN to output A_FXBUS2 as in the first channel,
-                * we use an auxiliary register, delaying the value by one
-                * sample
-                */
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
-               /* For 96kHz mode */
-               /* Left ADC in. 2 of 2 */
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
-               /* Right ADC in 2 of 2 */
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
-               /* Pavel Hofman - we still have voices, A_FXBUS2s, and
-                * A_P16VINs available -
-                * let's add 8 more capture channels - total of 16
-                */
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x10));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x12));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x14));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x16));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x18));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x1a));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x1c));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
-                    A_C_00000000, A_C_00000000);
-               gpr_map[gpr++] = 0x00000000;
-               snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
-                                                         bit_shifter16,
-                                                         A_GPR(gpr - 1),
-                                                         A_FXBUS2(0x1e));
-               A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
-                    A_C_00000000, A_C_00000000);
+               if (emu->card_capabilities->ca0108_chip) {
+                       snd_printk("EMU2 inputs on\n");
+                       for (z = 0; z < 0x10; z++) {
+                               snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, 
+                                                                       bit_shifter16,
+                                                                       A3_EMU32IN(z),
+                                                                       A_FXBUS2(z*2) );
+                       }
+               } else {
+                       snd_printk("EMU inputs on\n");
+                       /* Capture 16 (originally 8) channels of S32_LE sound */
+
+                       /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
+                       /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
+                       /* A_P16VIN(0) is delayed by one sample,
+                        * so all other A_P16VIN channels will need to also be delayed
+                        */
+                       /* Left ADC in. 1 of 2 */
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
+                       /* Right ADC in 1 of 2 */
+                       gpr_map[gpr++] = 0x00000000;
+                       /* Delaying by one sample: instead of copying the input
+                        * value A_P16VIN to output A_FXBUS2 as in the first channel,
+                        * we use an auxiliary register, delaying the value by one
+                        * sample
+                        */
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
+                       /* For 96kHz mode */
+                       /* Left ADC in. 2 of 2 */
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
+                       /* Right ADC in 2 of 2 */
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
+                       /* Pavel Hofman - we still have voices, A_FXBUS2s, and
+                        * A_P16VINs available -
+                        * let's add 8 more capture channels - total of 16
+                        */
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x10));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x12));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x14));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x16));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x18));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x1a));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x1c));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
+                            A_C_00000000, A_C_00000000);
+                       gpr_map[gpr++] = 0x00000000;
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+                                                                 bit_shifter16,
+                                                                 A_GPR(gpr - 1),
+                                                                 A_FXBUS2(0x1e));
+                       A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
+                            A_C_00000000, A_C_00000000);
+               }
 
 #if 0
                for (z = 4; z < 8; z++) {
index 2c15859..a0dae0d 100644 (file)
@@ -385,7 +385,7 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
        int i;
        snd_iprintf(buffer, "EMU1010 Registers:\n\n");
 
-       for(i = 0; i < 0x30; i+=1) {
+       for(i = 0; i < 0x40; i+=1) {
                spin_lock_irqsave(&emu->emu_lock, flags);
                regs=i+0x40; /* 0x40 upwards are registers. */
                outl(regs, emu->port + A_IOCFG);
@@ -555,9 +555,9 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
 {
        struct snd_info_entry *entry;
 #ifdef CONFIG_SND_DEBUG
-       if ((emu->card_capabilities->emu1010) &&
-            snd_card_proc_new(emu->card, "emu1010_regs", &entry)) {
-               snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
+       if (emu->card_capabilities->emu1010) {
+               if (! snd_card_proc_new(emu->card, "emu1010_regs", &entry)) 
+                       snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
        }
        if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
                snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);