mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
ALSA: emu10k1: apply channel delay hack to all E-MU cards
Evidently, the channel delay bug exists in all E-MU cards; it's in the Hana FPGA program, and was never fixed. Note that the implementation is somewhat lazy - to localize the code paths, we actually waste a GPR and a DSP instruction by keeping two delay registers for the same physical source. Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Link: https://lore.kernel.org/r/20230510173917.3073107-6-oswald.buddenhagen@gmx.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
4c7bfbcf75
commit
f549466b8b
@ -1192,6 +1192,7 @@
|
||||
* emumixer.c - snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[]
|
||||
*/
|
||||
#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
/* This channel is delayed by one sample. */
|
||||
#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
#define EMU_DST_ALICE2_EMU32_3 0x0002 /* 16 EMU32 channels to Alice2 +0 to +0xf */
|
||||
|
@ -1326,13 +1326,20 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
||||
if (emu->card_capabilities->ca0108_chip) {
|
||||
// For unclear reasons, the EMU32IN cannot be the Y operand!
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A3_EMU32IN(0x0), A_GPR(gpr));
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A3_EMU32IN(0x1), A_GPR(gpr+1));
|
||||
// A3_EMU32IN(0) is delayed by one sample, so all other A3_EMU32IN channels
|
||||
// need to be delayed as well; we use an auxiliary register for that.
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+2), A_GPR(gpr+1));
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr+2), A3_EMU32IN(0x1), A_C_00000000, A_C_00000000);
|
||||
} 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));
|
||||
// A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels
|
||||
// need to be delayed as well; we use an auxiliary register for that.
|
||||
A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_GPR(gpr+2));
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr+2), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
|
||||
}
|
||||
snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
|
||||
gpr += 2;
|
||||
gpr_map[gpr + 2] = 0x00000000;
|
||||
gpr += 3;
|
||||
}
|
||||
/* AC'97 Playback Volume - used only for mic (renamed later) */
|
||||
A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
|
||||
@ -1624,11 +1631,17 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
|
||||
dev_info(emu->card->dev, "EMU2 inputs on\n");
|
||||
/* Note that the Tina[2] DSPs have 16 more EMU32 inputs which we don't use. */
|
||||
|
||||
for (z = 0; z < 0x10; z++) {
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16(
|
||||
icode, &ptr, tmp, bit_shifter16, A3_EMU32IN(0), A_FXBUS2(0));
|
||||
// A3_EMU32IN(0) is delayed by one sample, so all other A3_EMU32IN channels
|
||||
// need to be delayed as well; we use an auxiliary register for that.
|
||||
for (z = 1; z < 0x10; z++) {
|
||||
snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
|
||||
bit_shifter16,
|
||||
A3_EMU32IN(z),
|
||||
A_GPR(gpr),
|
||||
A_FXBUS2(z*2) );
|
||||
A_OP(icode, &ptr, iACC3, A_GPR(gpr), A3_EMU32IN(z), A_C_00000000, A_C_00000000);
|
||||
gpr_map[gpr++] = 0x00000000;
|
||||
}
|
||||
} else {
|
||||
dev_info(emu->card->dev, "EMU inputs on\n");
|
||||
|
Loading…
Reference in New Issue
Block a user