[ALSA] emu10k1 - 1616(M) cardbus improvements

This patch improves E-Mu 1616(M) cardbus support. It adds definitions of the
new Microdock and 1010 cardbus registers (thanks again for descriptions
James) and improves mixer for this card. Now you can use S/PDIF and ADAT on
Mirodock and also use headpohone output on host cardbus card as another
independent output.

Signed-off-by: Ctirad Fertr <c.fertr@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Ctirad Fertr 2007-12-13 16:27:13 +01:00 committed by Mercurial server
parent 190d2c46e5
commit 1c02e36681
3 changed files with 382 additions and 100 deletions

View file

@ -1299,6 +1299,23 @@
#define EMU_DST_ALICE_I2S2_LEFT 0x0700 /* Alice2 I2S2 Left */
#define EMU_DST_ALICE_I2S2_RIGHT 0x0701 /* Alice2 I2S2 Right */
/* Additional destinations for 1616(M)/Microdock */
/* Microdock S/PDIF OUT Left, 1st or 48kHz only */
#define EMU_DST_MDOCK_SPDIF_LEFT1 0x0112
/* Microdock S/PDIF OUT Left, 2nd or 96kHz */
#define EMU_DST_MDOCK_SPDIF_LEFT2 0x0113
/* Microdock S/PDIF OUT Right, 1st or 48kHz only */
#define EMU_DST_MDOCK_SPDIF_RIGHT1 0x0116
/* Microdock S/PDIF OUT Right, 2nd or 96kHz */
#define EMU_DST_MDOCK_SPDIF_RIGHT2 0x0117
/* Microdock S/PDIF ADAT 8 channel out +8 to +f */
#define EMU_DST_MDOCK_ADAT 0x0118
/* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
#define EMU_DST_MANA_DAC_LEFT 0x0300
/* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
#define EMU_DST_MANA_DAC_RIGHT 0x0301
/************************************************************************************************/
/* EMU1010m HANA Sources */
/************************************************************************************************/
@ -1452,6 +1469,19 @@
#define EMU_SRC_HANA_SPDIF_LEFT2 0x0502 /* Hana SPDIF Left, 2nd or 96kHz */
#define EMU_SRC_HANA_SPDIF_RIGHT1 0x0501 /* Hana SPDIF Right, 1st or 48kHz only */
#define EMU_SRC_HANA_SPDIF_RIGHT2 0x0503 /* Hana SPDIF Right, 2nd or 96kHz */
/* Additional inputs for 1616(M)/Microdock */
/* Microdock S/PDIF Left, 1st or 48kHz only */
#define EMU_SRC_MDOCK_SPDIF_LEFT1 0x0112
/* Microdock S/PDIF Left, 2nd or 96kHz */
#define EMU_SRC_MDOCK_SPDIF_LEFT2 0x0113
/* Microdock S/PDIF Right, 1st or 48kHz only */
#define EMU_SRC_MDOCK_SPDIF_RIGHT1 0x0116
/* Microdock S/PDIF Right, 2nd or 96kHz */
#define EMU_SRC_MDOCK_SPDIF_RIGHT2 0x0117
/* Microdock ADAT 8 channel in +8 to +f */
#define EMU_SRC_MDOCK_ADAT 0x0118
/* 0x600 and 0x700 no used */
/* ------------------- STRUCTURES -------------------- */

View file

@ -1103,79 +1103,114 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */
#endif
/* Default outputs */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
emu->emu1010.output_source[0] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[1] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
emu->emu1010.output_source[2] = 23;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
emu->emu1010.output_source[3] = 24;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
emu->emu1010.output_source[4] = 25;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
emu->emu1010.output_source[5] = 26;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6);
emu->emu1010.output_source[6] = 27;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7);
emu->emu1010.output_source[7] = 28;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
emu->emu1010.output_source[8] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[9] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
emu->emu1010.output_source[10] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[11] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
emu->emu1010.output_source[12] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[13] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
emu->emu1010.output_source[14] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[15] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
emu->emu1010.output_source[16] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[17] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2);
emu->emu1010.output_source[18] = 23;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3);
emu->emu1010.output_source[19] = 24;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4);
emu->emu1010.output_source[20] = 25;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5);
emu->emu1010.output_source[21] = 26;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6);
emu->emu1010.output_source[22] = 27;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
emu->emu1010.output_source[23] = 28;
if (emu->card_capabilities->emu_model == 3) {
/* 1616(M) cardbus default outputs */
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[0] = 17;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[1] = 18;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
emu->emu1010.output_source[2] = 19;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
emu->emu1010.output_source[3] = 20;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
emu->emu1010.output_source[4] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
emu->emu1010.output_source[5] = 22;
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_MANA_DAC_LEFT, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[16] = 17;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_MANA_DAC_RIGHT, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[17] = 18;
} else {
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[0] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[1] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
emu->emu1010.output_source[2] = 23;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
emu->emu1010.output_source[3] = 24;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
emu->emu1010.output_source[4] = 25;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
emu->emu1010.output_source[5] = 26;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6);
emu->emu1010.output_source[6] = 27;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7);
emu->emu1010.output_source[7] = 28;
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[8] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[9] = 22;
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[10] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[11] = 22;
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[12] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[13] = 22;
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[14] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[15] = 22;
/* ALICE2 bus 0xa0 */
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0);
emu->emu1010.output_source[16] = 21;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1);
emu->emu1010.output_source[17] = 22;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2);
emu->emu1010.output_source[18] = 23;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3);
emu->emu1010.output_source[19] = 24;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4);
emu->emu1010.output_source[20] = 25;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5);
emu->emu1010.output_source[21] = 26;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6);
emu->emu1010.output_source[22] = 27;
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
emu->emu1010.output_source[23] = 28;
}
/* TEMP: Select SPDIF in/out */
//snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */

View file

@ -139,6 +139,61 @@ static char *emu1010_src_texts[] = {
"DSP 31",
};
/* 1616(m) cardbus */
static char *emu1616_src_texts[] = {
"Silence",
"Dock Mic A",
"Dock Mic B",
"Dock ADC1 Left",
"Dock ADC1 Right",
"Dock ADC2 Left",
"Dock ADC2 Right",
"Dock SPDIF Left",
"Dock SPDIF Right",
"ADAT 0",
"ADAT 1",
"ADAT 2",
"ADAT 3",
"ADAT 4",
"ADAT 5",
"ADAT 6",
"ADAT 7",
"DSP 0",
"DSP 1",
"DSP 2",
"DSP 3",
"DSP 4",
"DSP 5",
"DSP 6",
"DSP 7",
"DSP 8",
"DSP 9",
"DSP 10",
"DSP 11",
"DSP 12",
"DSP 13",
"DSP 14",
"DSP 15",
"DSP 16",
"DSP 17",
"DSP 18",
"DSP 19",
"DSP 20",
"DSP 21",
"DSP 22",
"DSP 23",
"DSP 24",
"DSP 25",
"DSP 26",
"DSP 27",
"DSP 28",
"DSP 29",
"DSP 30",
"DSP 31",
};
/*
* List of data sources available for each destination
*/
@ -198,6 +253,59 @@ static unsigned int emu1010_src_regs[] = {
EMU_SRC_ALICE_EMU32B+0xf, /* 52 */
};
/* 1616(m) cardbus */
static unsigned int emu1616_src_regs[] = {
EMU_SRC_SILENCE,
EMU_SRC_DOCK_MIC_A1,
EMU_SRC_DOCK_MIC_B1,
EMU_SRC_DOCK_ADC1_LEFT1,
EMU_SRC_DOCK_ADC1_RIGHT1,
EMU_SRC_DOCK_ADC2_LEFT1,
EMU_SRC_DOCK_ADC2_RIGHT1,
EMU_SRC_MDOCK_SPDIF_LEFT1,
EMU_SRC_MDOCK_SPDIF_RIGHT1,
EMU_SRC_MDOCK_ADAT,
EMU_SRC_MDOCK_ADAT+1,
EMU_SRC_MDOCK_ADAT+2,
EMU_SRC_MDOCK_ADAT+3,
EMU_SRC_MDOCK_ADAT+4,
EMU_SRC_MDOCK_ADAT+5,
EMU_SRC_MDOCK_ADAT+6,
EMU_SRC_MDOCK_ADAT+7,
EMU_SRC_ALICE_EMU32A,
EMU_SRC_ALICE_EMU32A+1,
EMU_SRC_ALICE_EMU32A+2,
EMU_SRC_ALICE_EMU32A+3,
EMU_SRC_ALICE_EMU32A+4,
EMU_SRC_ALICE_EMU32A+5,
EMU_SRC_ALICE_EMU32A+6,
EMU_SRC_ALICE_EMU32A+7,
EMU_SRC_ALICE_EMU32A+8,
EMU_SRC_ALICE_EMU32A+9,
EMU_SRC_ALICE_EMU32A+0xa,
EMU_SRC_ALICE_EMU32A+0xb,
EMU_SRC_ALICE_EMU32A+0xc,
EMU_SRC_ALICE_EMU32A+0xd,
EMU_SRC_ALICE_EMU32A+0xe,
EMU_SRC_ALICE_EMU32A+0xf,
EMU_SRC_ALICE_EMU32B,
EMU_SRC_ALICE_EMU32B+1,
EMU_SRC_ALICE_EMU32B+2,
EMU_SRC_ALICE_EMU32B+3,
EMU_SRC_ALICE_EMU32B+4,
EMU_SRC_ALICE_EMU32B+5,
EMU_SRC_ALICE_EMU32B+6,
EMU_SRC_ALICE_EMU32B+7,
EMU_SRC_ALICE_EMU32B+8,
EMU_SRC_ALICE_EMU32B+9,
EMU_SRC_ALICE_EMU32B+0xa,
EMU_SRC_ALICE_EMU32B+0xb,
EMU_SRC_ALICE_EMU32B+0xc,
EMU_SRC_ALICE_EMU32B+0xd,
EMU_SRC_ALICE_EMU32B+0xe,
EMU_SRC_ALICE_EMU32B+0xf,
};
/*
* Data destinations - physical EMU outputs.
* Each destination has an enum mixer control to choose a data source
@ -229,6 +337,28 @@ static unsigned int emu1010_output_dst[] = {
EMU_DST_HANA_ADAT+7, /* 23 */
};
/* 1616(m) cardbus */
static unsigned int emu1616_output_dst[] = {
EMU_DST_DOCK_DAC1_LEFT1,
EMU_DST_DOCK_DAC1_RIGHT1,
EMU_DST_DOCK_DAC2_LEFT1,
EMU_DST_DOCK_DAC2_RIGHT1,
EMU_DST_DOCK_DAC3_LEFT1,
EMU_DST_DOCK_DAC3_RIGHT1,
EMU_DST_MDOCK_SPDIF_LEFT1,
EMU_DST_MDOCK_SPDIF_RIGHT1,
EMU_DST_MDOCK_ADAT,
EMU_DST_MDOCK_ADAT+1,
EMU_DST_MDOCK_ADAT+2,
EMU_DST_MDOCK_ADAT+3,
EMU_DST_MDOCK_ADAT+4,
EMU_DST_MDOCK_ADAT+5,
EMU_DST_MDOCK_ADAT+6,
EMU_DST_MDOCK_ADAT+7,
EMU_DST_MANA_DAC_LEFT,
EMU_DST_MANA_DAC_RIGHT,
};
/*
* Data destinations - HANA outputs going to Alice2 (audigy) for
* capture (EMU32 + I2S links)
@ -259,14 +389,26 @@ static unsigned int emu1010_input_dst[] = {
EMU_DST_ALICE_I2S2_RIGHT,
};
static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
char **items;
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 53;
if (emu->card_capabilities->emu_model == 3) { /* 1616(m) cardbus */
uinfo->value.enumerated.items = 49;
items = emu1616_src_texts;
} else {
uinfo->value.enumerated.items = 53;
items = emu1010_src_texts;
}
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name, emu1010_src_texts[uinfo->value.enumerated.item]);
uinfo->value.enumerated.item =
uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name,
items[uinfo->value.enumerated.item]);
return 0;
}
@ -278,7 +420,8 @@ static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol,
channel = (kcontrol->private_value) & 0xff;
/* Limit: emu1010_output_dst, emu->emu1010.output_source */
if (channel >= 24)
if (channel >= 24 ||
(emu->card_capabilities->emu_model == 3 && channel >= 18))
return -EINVAL;
ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel];
return 0;
@ -288,24 +431,28 @@ static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int change = 0;
unsigned int val;
unsigned int channel;
val = ucontrol->value.enumerated.item[0];
if (val >= 53)
if (val >= 53 ||
(emu->card_capabilities->emu_model == 3 && val >= 49))
return -EINVAL;
channel = (kcontrol->private_value) & 0xff;
/* Limit: emu1010_output_dst, emu->emu1010.output_source */
if (channel >= 24)
if (channel >= 24 ||
(emu->card_capabilities->emu_model == 3 && channel >= 18))
return -EINVAL;
if (emu->emu1010.output_source[channel] != val) {
emu->emu1010.output_source[channel] = val;
change = 1;
if (emu->emu1010.output_source[channel] == val)
return 0;
emu->emu1010.output_source[channel] = val;
if (emu->card_capabilities->emu_model == 3) /* 1616(m) cardbus */
snd_emu1010_fpga_link_dst_src_write(emu,
emu1616_output_dst[channel], emu1616_src_regs[val]);
else
snd_emu1010_fpga_link_dst_src_write(emu,
emu1010_output_dst[channel], emu1010_src_regs[val]);
}
return change;
return 1;
}
static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol,
@ -326,24 +473,27 @@ static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
int change = 0;
unsigned int val;
unsigned int channel;
val = ucontrol->value.enumerated.item[0];
if (val >= 53)
if (val >= 53 ||
(emu->card_capabilities->emu_model == 3 && val >= 49))
return -EINVAL;
channel = (kcontrol->private_value) & 0xff;
/* Limit: emu1010_input_dst, emu->emu1010.input_source */
if (channel >= 22)
return -EINVAL;
if (emu->emu1010.input_source[channel] != val) {
emu->emu1010.input_source[channel] = val;
change = 1;
if (emu->emu1010.input_source[channel] == val)
return 0;
emu->emu1010.input_source[channel] = val;
if (emu->card_capabilities->emu_model == 3) /* 1616(m) cardbus */
snd_emu1010_fpga_link_dst_src_write(emu,
emu1010_input_dst[channel], emu1616_src_regs[val]);
else
snd_emu1010_fpga_link_dst_src_write(emu,
emu1010_input_dst[channel], emu1010_src_regs[val]);
}
return change;
return 1;
}
#define EMU1010_SOURCE_OUTPUT(xname,chid) \
@ -383,6 +533,30 @@ static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = {
EMU1010_SOURCE_OUTPUT("1010 ADAT 7 Playback Enum", 0x17),
};
/* 1616(m) cardbus */
static struct snd_kcontrol_new snd_emu1616_output_enum_ctls[] __devinitdata = {
EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3),
EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4),
EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5),
EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 6),
EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 7),
EMU1010_SOURCE_OUTPUT("Dock ADAT 0 Playback Enum", 8),
EMU1010_SOURCE_OUTPUT("Dock ADAT 1 Playback Enum", 9),
EMU1010_SOURCE_OUTPUT("Dock ADAT 2 Playback Enum", 0xa),
EMU1010_SOURCE_OUTPUT("Dock ADAT 3 Playback Enum", 0xb),
EMU1010_SOURCE_OUTPUT("Dock ADAT 4 Playback Enum", 0xc),
EMU1010_SOURCE_OUTPUT("Dock ADAT 5 Playback Enum", 0xd),
EMU1010_SOURCE_OUTPUT("Dock ADAT 6 Playback Enum", 0xe),
EMU1010_SOURCE_OUTPUT("Dock ADAT 7 Playback Enum", 0xf),
EMU1010_SOURCE_OUTPUT("Mana DAC Left Playback Enum", 0x10),
EMU1010_SOURCE_OUTPUT("Mana DAC Right Playback Enum", 0x11),
};
#define EMU1010_SOURCE_INPUT(xname,chid) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@ -1817,30 +1991,73 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
return err;
}
if (emu->card_capabilities->emu_model) {
if (emu->card_capabilities->emu_model == 3) {
/* 1616(m) cardbus */
int i;
for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_output_enum_ctls[i], emu));
for (i = 0; i < ARRAY_SIZE(snd_emu1616_output_enum_ctls); i++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1616_output_enum_ctls[i],
emu));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_input_enum_ctls[i], emu));
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_input_enum_ctls[i],
emu));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads) - 2; i++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads) - 2; i++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
if (err < 0)
return err;
}
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_internal_clock, emu));
if (err < 0)
return err;
} else {
/* all other e-mu cards for now */
int i;
for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_output_enum_ctls[i],
emu));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_input_enum_ctls[i],
emu));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads); i++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
if (err < 0)
return err;
}
for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads); i++) {
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
if (err < 0)
return err;
}
err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_internal_clock, emu));
err = snd_ctl_add(card,
snd_ctl_new1(&snd_emu1010_internal_clock, emu));
if (err < 0)
return err;
}