aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa')
-rw-r--r--sound/isa/es18xx.c99
1 files changed, 90 insertions, 9 deletions
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index bde9860327fe..0488eba051e9 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -939,37 +939,118 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
939 * MIXER part 939 * MIXER part
940 */ 940 */
941 941
942/* Record source mux routines:
943 * Depending on the chipset this mux switches between 4, 5, or 8 possible inputs.
944 * bit table for the 4/5 source mux:
945 * reg 1C:
946 * b2 b1 b0 muxSource
947 * x 0 x microphone
948 * 0 1 x CD
949 * 1 1 0 line
950 * 1 1 1 mixer
951 * if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines
952 * either the play mixer or the capture mixer.
953 *
954 * "map4Source" translates from source number to reg bit pattern
955 * "invMap4Source" translates from reg bit pattern to source number
956 */
957
942static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 958static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
943{ 959{
944 static char *texts[8] = { 960 static char *texts4Source[4] = {
961 "Mic", "CD", "Line", "Master"
962 };
963 static char *texts5Source[5] = {
964 "Mic", "CD", "Line", "Master", "Mix"
965 };
966 static char *texts8Source[8] = {
945 "Mic", "Mic Master", "CD", "AOUT", 967 "Mic", "Mic Master", "CD", "AOUT",
946 "Mic1", "Mix", "Line", "Master" 968 "Mic1", "Mix", "Line", "Master"
947 }; 969 };
970 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
948 971
949 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 972 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
950 uinfo->count = 1; 973 uinfo->count = 1;
951 uinfo->value.enumerated.items = 8; 974 switch (chip->version) {
952 if (uinfo->value.enumerated.item > 7) 975 case 0x1868:
953 uinfo->value.enumerated.item = 7; 976 case 0x1878:
954 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 977 uinfo->value.enumerated.items = 4;
978 if (uinfo->value.enumerated.item > 3)
979 uinfo->value.enumerated.item = 3;
980 strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]);
981 break;
982 case 0x1887:
983 case 0x1888:
984 uinfo->value.enumerated.items = 5;
985 if (uinfo->value.enumerated.item > 4)
986 uinfo->value.enumerated.item = 4;
987 strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]);
988 break;
989 case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */
990 case 0x1879:
991 uinfo->value.enumerated.items = 8;
992 if (uinfo->value.enumerated.item > 7)
993 uinfo->value.enumerated.item = 7;
994 strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]);
995 break;
996 default:
997 return -EINVAL;
998 }
955 return 0; 999 return 0;
956} 1000}
957 1001
958static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1002static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
959{ 1003{
1004 static unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3};
960 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); 1005 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
961 ucontrol->value.enumerated.item[0] = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; 1006 int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
1007 if (!(chip->version == 0x1869 || chip->version == 0x1879)) {
1008 muxSource = invMap4Source[muxSource];
1009 if (muxSource==3 &&
1010 (chip->version == 0x1887 || chip->version == 0x1888) &&
1011 (snd_es18xx_mixer_read(chip, 0x7a) & 0x08)
1012 )
1013 muxSource = 4;
1014 }
1015 ucontrol->value.enumerated.item[0] = muxSource;
962 return 0; 1016 return 0;
963} 1017}
964 1018
965static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1019static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
966{ 1020{
1021 static unsigned char map4Source[4] = {0, 2, 6, 7};
967 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); 1022 struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
968 unsigned char val = ucontrol->value.enumerated.item[0]; 1023 unsigned char val = ucontrol->value.enumerated.item[0];
969 1024 unsigned char retVal = 0;
970 if (val > 7) 1025
1026 switch (chip->version) {
1027 /* 5 source chips */
1028 case 0x1887:
1029 case 0x1888:
1030 if (val > 4)
1031 return -EINVAL;
1032 if (val == 4) {
1033 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08;
1034 val = 3;
1035 } else
1036 retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00;
1037 /* 4 source chips */
1038 case 0x1868:
1039 case 0x1878:
1040 if (val > 3)
1041 return -EINVAL;
1042 val = map4Source[val];
1043 break;
1044 /* 8 source chips */
1045 case 0x1869:
1046 case 0x1879:
1047 if (val > 7)
1048 return -EINVAL;
1049 break;
1050 default:
971 return -EINVAL; 1051 return -EINVAL;
972 return snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val; 1052 }
1053 return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal;
973} 1054}
974 1055
975static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1056static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)