From: Ctirad Fertr Date: Thu, 13 Dec 2007 15:27:13 +0000 (+0100) Subject: [ALSA] emu10k1 - 1616(M) cardbus improvements X-Git-Tag: v2.6.25-rc1~1127^2~7 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c02e36681ae20a796204e8d629d13fa9d5e20b5;p=linux-2.6 [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 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 8a0c3c1ef8..4474b4e15f 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h @@ -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 -------------------- */ diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index da66067668..54b978e74f 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -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 */ diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 83acfa6e93..9b5883b795 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c @@ -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_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)); + 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)); + 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)); + 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; }