summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/emu10k1.h2
-rw-r--r--sound/pci/emu10k1/emupcm.c17
2 files changed, 19 insertions, 0 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 9c5de1f45566..583fabef0b99 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -709,6 +709,8 @@ SUB_REG(PEFE, FILTERAMOUNT, 0x000000ff) /* Filter envlope amount */
#define ADCBS_BUFSIZE_57344 0x0000001e
#define ADCBS_BUFSIZE_65536 0x0000001f
+// On Audigy, the FX send amounts are not applied instantly, but determine
+// targets towards which the following registers swerve gradually.
#define A_CSBA 0x4c /* FX send B & A current amounts */
#define A_CSDC 0x4d /* FX send D & C current amounts */
#define A_CSFE 0x4e /* FX send F & E current amounts */
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 0b23ff8d9c3b..903a68a4d396 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -236,6 +236,18 @@ static unsigned int emu10k1_select_interprom(unsigned int pitch_target)
return CCCA_INTERPROM_2;
}
+static u16 emu10k1_send_target_from_amount(u8 amount)
+{
+ static const u8 shifts[8] = { 4, 4, 5, 6, 7, 8, 9, 10 };
+ static const u16 offsets[8] = { 0, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000 };
+ u8 exp;
+
+ if (amount == 0xff)
+ return 0xffff;
+ exp = amount >> 5;
+ return ((amount & 0x1f) << shifts[exp]) + offsets[exp];
+}
+
static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
int master, int extra,
struct snd_emu10k1_voice *evoice,
@@ -301,6 +313,11 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
A_FXRT2, snd_emu10k1_compose_audigy_fxrt2(send_routing),
A_SENDAMOUNTS, snd_emu10k1_compose_audigy_sendamounts(send_amount),
REGLIST_END);
+ for (int i = 0; i < 4; i++) {
+ u32 aml = emu10k1_send_target_from_amount(send_amount[2 * i]);
+ u32 amh = emu10k1_send_target_from_amount(send_amount[2 * i + 1]);
+ snd_emu10k1_ptr_write(emu, A_CSBA + i, voice, (amh << 16) | aml);
+ }
} else {
snd_emu10k1_ptr_write(emu, FXRT, voice,
snd_emu10k1_compose_send_routing(send_routing));