diff options
author | James Courtier-Dutton <James@superbug.co.uk> | 2006-10-01 05:48:04 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 02:59:59 -0500 |
commit | 9f4bd5dde81b5cb94e4f52f2f05825aa0422f1ff (patch) | |
tree | 884d0016c361a555ab1bc95287e64a6c109a0609 /sound/pci/emu10k1/emufx.c | |
parent | 5986a2ec35836a878350c54af4bd91b1de6abc59 (diff) |
[ALSA] snd-emu10k1: Added support for emu1010, including E-Mu 1212m and E-Mu 1820m
Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/emu10k1/emufx.c')
-rw-r--r-- | sound/pci/emu10k1/emufx.c | 102 |
1 files changed, 90 insertions, 12 deletions
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 13cd6ce89811..d8e8db89535f 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * Creative Labs, Inc. | 3 | * Creative Labs, Inc. |
4 | * Routines for effect processor FX8010 | 4 | * Routines for effect processor FX8010 |
5 | * | 5 | * |
6 | * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk> | ||
7 | * Added EMU 1010 support. | ||
8 | * | ||
6 | * BUGS: | 9 | * BUGS: |
7 | * -- | 10 | * -- |
8 | * | 11 | * |
@@ -1069,6 +1072,21 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl | |||
1069 | ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; | 1072 | ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; |
1070 | } | 1073 | } |
1071 | 1074 | ||
1075 | static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( | ||
1076 | struct snd_emu10k1_fx8010_code *icode, | ||
1077 | u32 *ptr, int tmp, int bit_shifter16, | ||
1078 | int reg_in, int reg_out) | ||
1079 | { | ||
1080 | A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000); | ||
1081 | A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000); | ||
1082 | A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2)); | ||
1083 | A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000); | ||
1084 | A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000); | ||
1085 | A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000); | ||
1086 | A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2)); | ||
1087 | A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000); | ||
1088 | return 1; | ||
1089 | } | ||
1072 | 1090 | ||
1073 | /* | 1091 | /* |
1074 | * initial DSP configuration for Audigy | 1092 | * initial DSP configuration for Audigy |
@@ -1077,6 +1095,7 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl | |||
1077 | static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | 1095 | static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) |
1078 | { | 1096 | { |
1079 | int err, i, z, gpr, nctl; | 1097 | int err, i, z, gpr, nctl; |
1098 | int bit_shifter16; | ||
1080 | const int playback = 10; | 1099 | const int playback = 10; |
1081 | const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ | 1100 | const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ |
1082 | const int stereo_mix = capture + 2; | 1101 | const int stereo_mix = capture + 2; |
@@ -1114,17 +1133,14 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1114 | ptr = 0; | 1133 | ptr = 0; |
1115 | nctl = 0; | 1134 | nctl = 0; |
1116 | gpr = stereo_mix + 10; | 1135 | gpr = stereo_mix + 10; |
1136 | gpr_map[gpr++] = 0x00007fff; | ||
1137 | gpr_map[gpr++] = 0x00008000; | ||
1138 | gpr_map[gpr++] = 0x0000ffff; | ||
1139 | bit_shifter16 = gpr; | ||
1117 | 1140 | ||
1118 | /* stop FX processor */ | 1141 | /* stop FX processor */ |
1119 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); | 1142 | snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); |
1120 | 1143 | ||
1121 | #if 0 | ||
1122 | /* FIX: jcd test */ | ||
1123 | for (z = 0; z < 80; z=z+2) { | ||
1124 | A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */ | ||
1125 | A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */ | ||
1126 | } | ||
1127 | #endif /* jcd test */ | ||
1128 | #if 1 | 1144 | #if 1 |
1129 | /* PCM front Playback Volume (independent from stereo mix) */ | 1145 | /* PCM front Playback Volume (independent from stereo mix) */ |
1130 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); | 1146 | A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); |
@@ -1182,13 +1198,20 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | |||
1182 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); | 1198 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); |
1183 | snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); | 1199 | snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); |
1184 | gpr += 2; | 1200 | gpr += 2; |
1185 | 1201 | ||
1186 | /* | 1202 | /* |
1187 | * inputs | 1203 | * inputs |
1188 | */ | 1204 | */ |
1189 | #define A_ADD_VOLUME_IN(var,vol,input) \ | 1205 | #define A_ADD_VOLUME_IN(var,vol,input) \ |
1190 | A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | 1206 | A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) |
1191 | 1207 | ||
1208 | /* emu1212 DSP 0 and DSP 1 Capture */ | ||
1209 | if (emu->card_capabilities->emu1010) { | ||
1210 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0)); | ||
1211 | A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1)); | ||
1212 | snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0); | ||
1213 | gpr += 2; | ||
1214 | } | ||
1192 | /* AC'97 Playback Volume - used only for mic (renamed later) */ | 1215 | /* AC'97 Playback Volume - used only for mic (renamed later) */ |
1193 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L); | 1216 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L); |
1194 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R); | 1217 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R); |
@@ -1429,6 +1452,13 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1429 | 1452 | ||
1430 | /* digital outputs */ | 1453 | /* digital outputs */ |
1431 | /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */ | 1454 | /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */ |
1455 | if (emu->card_capabilities->emu1010) { | ||
1456 | /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */ | ||
1457 | snd_printk("EMU outputs on\n"); | ||
1458 | for (z = 0; z < 8; z++) { | ||
1459 | A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000); | ||
1460 | } | ||
1461 | } | ||
1432 | 1462 | ||
1433 | /* IEC958 Optical Raw Playback Switch */ | 1463 | /* IEC958 Optical Raw Playback Switch */ |
1434 | gpr_map[gpr++] = 0; | 1464 | gpr_map[gpr++] = 0; |
@@ -1466,9 +1496,57 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
1466 | A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1); | 1496 | A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1); |
1467 | #endif | 1497 | #endif |
1468 | 1498 | ||
1469 | /* EFX capture - capture the 16 EXTINs */ | 1499 | if (emu->card_capabilities->emu1010) { |
1470 | for (z = 0; z < 16; z++) { | 1500 | snd_printk("EMU inputs on\n"); |
1471 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); | 1501 | /* Capture 8 channels of S32_LE sound */ |
1502 | |||
1503 | /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ | ||
1504 | /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ | ||
1505 | /* A_P16VIN(0) is delayed by one sample, | ||
1506 | * so all other A_P16VIN channels will need to also be delayed | ||
1507 | */ | ||
1508 | /* Left ADC in. 1 of 2 */ | ||
1509 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); | ||
1510 | /* Right ADC in 1 of 2 */ | ||
1511 | gpr_map[gpr++] = 0x00000000; | ||
1512 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); | ||
1513 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); | ||
1514 | gpr_map[gpr++] = 0x00000000; | ||
1515 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) ); | ||
1516 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000); | ||
1517 | gpr_map[gpr++] = 0x00000000; | ||
1518 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) ); | ||
1519 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000); | ||
1520 | /* For 96kHz mode */ | ||
1521 | /* Left ADC in. 2 of 2 */ | ||
1522 | gpr_map[gpr++] = 0x00000000; | ||
1523 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) ); | ||
1524 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000); | ||
1525 | /* Right ADC in 2 of 2 */ | ||
1526 | gpr_map[gpr++] = 0x00000000; | ||
1527 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) ); | ||
1528 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000); | ||
1529 | gpr_map[gpr++] = 0x00000000; | ||
1530 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) ); | ||
1531 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000); | ||
1532 | gpr_map[gpr++] = 0x00000000; | ||
1533 | snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); | ||
1534 | A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); | ||
1535 | |||
1536 | #if 0 | ||
1537 | for (z = 4; z < 8; z++) { | ||
1538 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000); | ||
1539 | } | ||
1540 | for (z = 0xc; z < 0x10; z++) { | ||
1541 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000); | ||
1542 | } | ||
1543 | #endif | ||
1544 | } else { | ||
1545 | /* EFX capture - capture the 16 EXTINs */ | ||
1546 | /* Capture 16 channels of S16_LE sound */ | ||
1547 | for (z = 0; z < 16; z++) { | ||
1548 | A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); | ||
1549 | } | ||
1472 | } | 1550 | } |
1473 | 1551 | ||
1474 | #endif /* JCD test */ | 1552 | #endif /* JCD test */ |
@@ -2138,7 +2216,7 @@ void snd_emu10k1_free_efx(struct snd_emu10k1 *emu) | |||
2138 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP); | 2216 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP); |
2139 | } | 2217 | } |
2140 | 2218 | ||
2141 | #if 0 // FIXME: who use them? | 2219 | #if 0 /* FIXME: who use them? */ |
2142 | int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) | 2220 | int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) |
2143 | { | 2221 | { |
2144 | if (output < 0 || output >= 6) | 2222 | if (output < 0 || output >= 6) |