Commit db987421 authored by Oswald Buddenhagen's avatar Oswald Buddenhagen Committed by Takashi Iwai

ALSA: emu10k1: vastly improve usefulness of info in /proc

- Include the FX bus map, without which the already present send routing
  info would require looking up the documentation.
- Include the physical I/O channels as known to the driver
- Make the multi-channel capture map actually name the mapped input
  channels rather than "FXBUS" (Audigy) or even "???" (SbLive)
- The latter two are omitted for E-MU cards, as their physical I/O is
  routed through the FPGA
- While at it, make the "Card" field somewhat more useful

This includes de-duplicating the label tables between emuproc and emufx,
updating/improving the FX bus label table, and making the SB Live! 5.1
multi-track capture channel mapping hack data-driven.
Tested-by: default avatarJonathan Dowland <jon@dow.land>
Signed-off-by: default avatarOswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230526101659.437969-7-oswald.buddenhagen@gmx.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 6ab13291
...@@ -1440,6 +1440,16 @@ SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM ...@@ -1440,6 +1440,16 @@ SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM
/* 0x600 and 0x700 no used */ /* 0x600 and 0x700 no used */
/* ------------------- CONSTANTS -------------------- */
extern const char * const snd_emu10k1_fxbus[32];
extern const char * const snd_emu10k1_sblive_ins[16];
extern const char * const snd_emu10k1_audigy_ins[16];
extern const char * const snd_emu10k1_sblive_outs[32];
extern const char * const snd_emu10k1_audigy_outs[32];
extern const s8 snd_emu10k1_sblive51_fxbus2_map[16];
/* ------------------- STRUCTURES -------------------- */ /* ------------------- STRUCTURES -------------------- */
enum { enum {
......
...@@ -46,26 +46,45 @@ MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range."); ...@@ -46,26 +46,45 @@ MODULE_PARM_DESC(high_res_gpr_volume, "GPR mixer controls use 31-bit range.");
* Tables * Tables
*/ */
static const char * const fxbuses[16] = { // Playback channel labels; corresponds with the public FXBUS_* defines.
// Unlike the tables below, this is not determined by the hardware.
const char * const snd_emu10k1_fxbus[32] = {
/* 0x00 */ "PCM Left", /* 0x00 */ "PCM Left",
/* 0x01 */ "PCM Right", /* 0x01 */ "PCM Right",
/* 0x02 */ "PCM Surround Left", /* 0x02 */ "PCM Rear Left",
/* 0x03 */ "PCM Surround Right", /* 0x03 */ "PCM Rear Right",
/* 0x04 */ "MIDI Left", /* 0x04 */ "MIDI Left",
/* 0x05 */ "MIDI Right", /* 0x05 */ "MIDI Right",
/* 0x06 */ "Center", /* 0x06 */ "PCM Center",
/* 0x07 */ "LFE", /* 0x07 */ "PCM LFE",
/* 0x08 */ NULL, /* 0x08 */ "PCM Front Left",
/* 0x09 */ NULL, /* 0x09 */ "PCM Front Right",
/* 0x0a */ NULL, /* 0x0a */ NULL,
/* 0x0b */ NULL, /* 0x0b */ NULL,
/* 0x0c */ "MIDI Reverb", /* 0x0c */ "MIDI Reverb",
/* 0x0d */ "MIDI Chorus", /* 0x0d */ "MIDI Chorus",
/* 0x0e */ NULL, /* 0x0e */ "PCM Side Left",
/* 0x0f */ NULL /* 0x0f */ "PCM Side Right",
/* 0x10 */ NULL,
/* 0x11 */ NULL,
/* 0x12 */ NULL,
/* 0x13 */ NULL,
/* 0x14 */ "Passthrough Left",
/* 0x15 */ "Passthrough Right",
/* 0x16 */ NULL,
/* 0x17 */ NULL,
/* 0x18 */ NULL,
/* 0x19 */ NULL,
/* 0x1a */ NULL,
/* 0x1b */ NULL,
/* 0x1c */ NULL,
/* 0x1d */ NULL,
/* 0x1e */ NULL,
/* 0x1f */ NULL
}; };
static const char * const creative_ins[16] = { // Physical inputs; corresponds with the public EXTIN_* defines.
const char * const snd_emu10k1_sblive_ins[16] = {
/* 0x00 */ "AC97 Left", /* 0x00 */ "AC97 Left",
/* 0x01 */ "AC97 Right", /* 0x01 */ "AC97 Right",
/* 0x02 */ "TTL IEC958 Left", /* 0x02 */ "TTL IEC958 Left",
...@@ -84,7 +103,8 @@ static const char * const creative_ins[16] = { ...@@ -84,7 +103,8 @@ static const char * const creative_ins[16] = {
/* 0x0f */ NULL /* 0x0f */ NULL
}; };
static const char * const audigy_ins[16] = { // Physical inputs; corresponds with the public A_EXTIN_* defines.
const char * const snd_emu10k1_audigy_ins[16] = {
/* 0x00 */ "AC97 Left", /* 0x00 */ "AC97 Left",
/* 0x01 */ "AC97 Right", /* 0x01 */ "AC97 Right",
/* 0x02 */ "Audigy CD Left", /* 0x02 */ "Audigy CD Left",
...@@ -103,7 +123,8 @@ static const char * const audigy_ins[16] = { ...@@ -103,7 +123,8 @@ static const char * const audigy_ins[16] = {
/* 0x0f */ NULL /* 0x0f */ NULL
}; };
static const char * const creative_outs[32] = { // Physical outputs; corresponds with the public EXTOUT_* defines.
const char * const snd_emu10k1_sblive_outs[32] = {
/* 0x00 */ "AC97 Left", /* 0x00 */ "AC97 Left",
/* 0x01 */ "AC97 Right", /* 0x01 */ "AC97 Right",
/* 0x02 */ "Optical IEC958 Left", /* 0x02 */ "Optical IEC958 Left",
...@@ -120,6 +141,7 @@ static const char * const creative_outs[32] = { ...@@ -120,6 +141,7 @@ static const char * const creative_outs[32] = {
/* 0x0d */ "AC97 Surround Left", /* 0x0d */ "AC97 Surround Left",
/* 0x0e */ "AC97 Surround Right", /* 0x0e */ "AC97 Surround Right",
/* 0x0f */ NULL, /* 0x0f */ NULL,
// This is actually the FXBUS2 range; SB Live! 5.1 only.
/* 0x10 */ NULL, /* 0x10 */ NULL,
/* 0x11 */ "Analog Center", /* 0x11 */ "Analog Center",
/* 0x12 */ "Analog LFE", /* 0x12 */ "Analog LFE",
...@@ -138,7 +160,8 @@ static const char * const creative_outs[32] = { ...@@ -138,7 +160,8 @@ static const char * const creative_outs[32] = {
/* 0x1f */ NULL, /* 0x1f */ NULL,
}; };
static const char * const audigy_outs[32] = { // Physical outputs; corresponds with the public A_EXTOUT_* defines.
const char * const snd_emu10k1_audigy_outs[32] = {
/* 0x00 */ "Digital Front Left", /* 0x00 */ "Digital Front Left",
/* 0x01 */ "Digital Front Right", /* 0x01 */ "Digital Front Right",
/* 0x02 */ "Digital Center", /* 0x02 */ "Digital Center",
...@@ -173,6 +196,18 @@ static const char * const audigy_outs[32] = { ...@@ -173,6 +196,18 @@ static const char * const audigy_outs[32] = {
/* 0x1f */ NULL, /* 0x1f */ NULL,
}; };
// On the SB Live! 5.1, FXBUS2[1] and FXBUS2[2] are occupied by EXTOUT_ACENTER
// and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
//
// Since only 14 of the 16 EXTINs are used, this is not a big problem.
// We route AC97 to FX capture 14 and 15, SPDIF_CD to FX capture 0 and 3,
// and the rest of the EXTINs to the corresponding FX capture channel.
// Multitrack recorders will still see the center/LFE output signal
// on the second and third "input" channel.
const s8 snd_emu10k1_sblive51_fxbus2_map[16] = {
2, -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1
};
static const u32 bass_table[41][5] = { static const u32 bass_table[41][5] = {
{ 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 }, { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
{ 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d }, { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
...@@ -2290,21 +2325,11 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) ...@@ -2290,21 +2325,11 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
/* EFX capture - capture the 16 EXTINS */ /* EFX capture - capture the 16 EXTINS */
if (emu->card_capabilities->sblive51) { if (emu->card_capabilities->sblive51) {
/* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER for (z = 0; z < 16; z++) {
* and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording. s8 c = snd_emu10k1_sblive51_fxbus2_map[z];
* if (c != -1)
* Since only 14 of the 16 EXTINs are used, this is not a big problem. OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(c));
* We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture }
* 0 and 3, then the rest of the EXTINs to the corresponding FX capture
* channel. Multitrack recorders will still see the center/lfe output signal
* on the second and third channels.
*/
OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
for (z = 4; z < 14; z++)
OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
} else { } else {
for (z = 0; z < 16; z++) for (z = 0; z < 16; z++)
OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
...@@ -2448,9 +2473,9 @@ static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, ...@@ -2448,9 +2473,9 @@ static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
info->internal_tram_size = emu->fx8010.itram_size; info->internal_tram_size = emu->fx8010.itram_size;
info->external_tram_size = emu->fx8010.etram_pages.bytes / 2; info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
fxbus = fxbuses; fxbus = snd_emu10k1_fxbus;
extin = emu->audigy ? audigy_ins : creative_ins; extin = emu->audigy ? snd_emu10k1_audigy_ins : snd_emu10k1_sblive_ins;
extout = emu->audigy ? audigy_outs : creative_outs; extout = emu->audigy ? snd_emu10k1_audigy_outs : snd_emu10k1_sblive_outs;
extin_mask = emu->audigy ? ~0 : emu->fx8010.extin_mask; extin_mask = emu->audigy ? ~0 : emu->fx8010.extin_mask;
extout_mask = emu->audigy ? ~0 : emu->fx8010.extout_mask; extout_mask = emu->audigy ? ~0 : emu->fx8010.extout_mask;
for (res = 0; res < 16; res++, fxbus++, extin++, extout++) { for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
......
...@@ -66,118 +66,22 @@ static void snd_emu10k1_proc_spdif_status(struct snd_emu10k1 * emu, ...@@ -66,118 +66,22 @@ static void snd_emu10k1_proc_spdif_status(struct snd_emu10k1 * emu,
static void snd_emu10k1_proc_read(struct snd_info_entry *entry, static void snd_emu10k1_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer) struct snd_info_buffer *buffer)
{ {
/* FIXME - output names are in emufx.c too */
static const char * const creative_outs[32] = {
/* 00 */ "AC97 Left",
/* 01 */ "AC97 Right",
/* 02 */ "Optical IEC958 Left",
/* 03 */ "Optical IEC958 Right",
/* 04 */ "Center",
/* 05 */ "LFE",
/* 06 */ "Headphone Left",
/* 07 */ "Headphone Right",
/* 08 */ "Surround Left",
/* 09 */ "Surround Right",
/* 10 */ "PCM Capture Left",
/* 11 */ "PCM Capture Right",
/* 12 */ "MIC Capture",
/* 13 */ "AC97 Surround Left",
/* 14 */ "AC97 Surround Right",
/* 15 */ "???",
/* 16 */ "???",
/* 17 */ "Analog Center",
/* 18 */ "Analog LFE",
/* 19 */ "???",
/* 20 */ "???",
/* 21 */ "???",
/* 22 */ "???",
/* 23 */ "???",
/* 24 */ "???",
/* 25 */ "???",
/* 26 */ "???",
/* 27 */ "???",
/* 28 */ "???",
/* 29 */ "???",
/* 30 */ "???",
/* 31 */ "???"
};
static const char * const audigy_outs[64] = {
/* 00 */ "Digital Front Left",
/* 01 */ "Digital Front Right",
/* 02 */ "Digital Center",
/* 03 */ "Digital LEF",
/* 04 */ "Headphone Left",
/* 05 */ "Headphone Right",
/* 06 */ "Digital Rear Left",
/* 07 */ "Digital Rear Right",
/* 08 */ "Front Left",
/* 09 */ "Front Right",
/* 10 */ "Center",
/* 11 */ "LFE",
/* 12 */ "???",
/* 13 */ "???",
/* 14 */ "Rear Left",
/* 15 */ "Rear Right",
/* 16 */ "AC97 Front Left",
/* 17 */ "AC97 Front Right",
/* 18 */ "ADC Capture Left",
/* 19 */ "ADC Capture Right",
/* 20 */ "???",
/* 21 */ "???",
/* 22 */ "???",
/* 23 */ "???",
/* 24 */ "???",
/* 25 */ "???",
/* 26 */ "???",
/* 27 */ "???",
/* 28 */ "???",
/* 29 */ "???",
/* 30 */ "???",
/* 31 */ "???",
/* 32 */ "FXBUS2_0",
/* 33 */ "FXBUS2_1",
/* 34 */ "FXBUS2_2",
/* 35 */ "FXBUS2_3",
/* 36 */ "FXBUS2_4",
/* 37 */ "FXBUS2_5",
/* 38 */ "FXBUS2_6",
/* 39 */ "FXBUS2_7",
/* 40 */ "FXBUS2_8",
/* 41 */ "FXBUS2_9",
/* 42 */ "FXBUS2_10",
/* 43 */ "FXBUS2_11",
/* 44 */ "FXBUS2_12",
/* 45 */ "FXBUS2_13",
/* 46 */ "FXBUS2_14",
/* 47 */ "FXBUS2_15",
/* 48 */ "FXBUS2_16",
/* 49 */ "FXBUS2_17",
/* 50 */ "FXBUS2_18",
/* 51 */ "FXBUS2_19",
/* 52 */ "FXBUS2_20",
/* 53 */ "FXBUS2_21",
/* 54 */ "FXBUS2_22",
/* 55 */ "FXBUS2_23",
/* 56 */ "FXBUS2_24",
/* 57 */ "FXBUS2_25",
/* 58 */ "FXBUS2_26",
/* 59 */ "FXBUS2_27",
/* 60 */ "FXBUS2_28",
/* 61 */ "FXBUS2_29",
/* 62 */ "FXBUS2_30",
/* 63 */ "FXBUS2_31"
};
struct snd_emu10k1 *emu = entry->private_data; struct snd_emu10k1 *emu = entry->private_data;
const char * const *inputs = emu->audigy ?
snd_emu10k1_audigy_ins : snd_emu10k1_sblive_ins;
const char * const *outputs = emu->audigy ?
snd_emu10k1_audigy_outs : snd_emu10k1_sblive_outs;
unsigned short extin_mask = emu->audigy ? ~0 : emu->fx8010.extin_mask;
unsigned short extout_mask = emu->audigy ? ~0 : emu->fx8010.extout_mask;
unsigned int val, val1, ptrx, psst, dsl, snda; unsigned int val, val1, ptrx, psst, dsl, snda;
int nefx = emu->audigy ? 64 : 32; int nefx = emu->audigy ? 32 : 16;
const char * const *outputs = emu->audigy ? audigy_outs : creative_outs;
int idx; int idx;
snd_iprintf(buffer, "EMU10K1\n\n"); snd_iprintf(buffer, "EMU10K1\n\n");
snd_iprintf(buffer, "Card : %s\n", snd_iprintf(buffer, "Card : %s\n",
emu->audigy ? "Audigy" : (emu->card_capabilities->ecard ? "EMU APS" : "Creative")); emu->card_capabilities->emu_model ? "E-MU D.A.S." :
emu->card_capabilities->ecard ? "E-MU A.P.S." :
emu->audigy ? "SB Audigy" : "SB Live!");
snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size); snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2); snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2);
...@@ -211,14 +115,51 @@ static void snd_emu10k1_proc_read(struct snd_info_entry *entry, ...@@ -211,14 +115,51 @@ static void snd_emu10k1_proc_read(struct snd_info_entry *entry,
(val >> 28) & 0x0f, REG_VAL_GET(DSL_FXSENDAMOUNT_D, dsl)); (val >> 28) & 0x0f, REG_VAL_GET(DSL_FXSENDAMOUNT_D, dsl));
} }
} }
snd_iprintf(buffer, "\nCaptured FX Outputs :\n"); snd_iprintf(buffer, "\nEffect Send Targets:\n");
for (idx = 0; idx < nefx; idx++) { // Audigy actually has 64, but we don't use them all.
if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) for (idx = 0; idx < 32; idx++) {
snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); const char *c = snd_emu10k1_fxbus[idx];
if (c)
snd_iprintf(buffer, " Channel %02i [%s]\n", idx, c);
}
if (!emu->card_capabilities->emu_model) {
snd_iprintf(buffer, "\nOutput Channels:\n");
for (idx = 0; idx < 32; idx++)
if (outputs[idx] && (extout_mask & (1 << idx)))
snd_iprintf(buffer, " Channel %02i [%s]\n", idx, outputs[idx]);
snd_iprintf(buffer, "\nInput Channels:\n");
for (idx = 0; idx < 16; idx++)
if (inputs[idx] && (extin_mask & (1 << idx)))
snd_iprintf(buffer, " Channel %02i [%s]\n", idx, inputs[idx]);
snd_iprintf(buffer, "\nMultichannel Capture Sources:\n");
for (idx = 0; idx < nefx; idx++)
if (emu->efx_voices_mask[0] & (1 << idx))
snd_iprintf(buffer, " Channel %02i [Output: %s]\n",
idx, outputs[idx] ? outputs[idx] : "???");
if (emu->audigy) {
for (idx = 0; idx < 32; idx++)
if (emu->efx_voices_mask[1] & (1 << idx))
snd_iprintf(buffer, " Channel %02i [Input: %s]\n",
idx + 32, inputs[idx] ? inputs[idx] : "???");
} else {
for (idx = 0; idx < 16; idx++) {
if (emu->efx_voices_mask[0] & ((1 << 16) << idx)) {
if (emu->card_capabilities->sblive51) {
s8 c = snd_emu10k1_sblive51_fxbus2_map[idx];
if (c == -1)
snd_iprintf(buffer, " Channel %02i [Output: %s]\n",
idx + 16, outputs[idx + 16]);
else
snd_iprintf(buffer, " Channel %02i [Input: %s]\n",
idx + 16, inputs[c]);
} else {
snd_iprintf(buffer, " Channel %02i [Input: %s]\n",
idx + 16, inputs[idx] ? inputs[idx] : "???");
}
}
}
}
} }
snd_iprintf(buffer, "\nAll FX Outputs :\n");
for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++)
snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
} }
static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry, static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment