diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2008-07-31 15:08:32 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-08-06 09:39:55 -0400 |
commit | 5664daa1c1fa250dd7f6b336278b0402638e8edc (patch) | |
tree | a128ca1e8ead396c43bb50827ef989cdd34f5ca9 /sound/isa/ad1848/ad1848_lib.c | |
parent | 811585e9d1769d6e282852fc0675735209547ca0 (diff) |
ALSA: wss_lib: use wss mixer code instead of ad1848 one
Use the wss mixer code and kill the ad1848 mixer code.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Reviewed-by: Rene Herman <rene.herman@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/isa/ad1848/ad1848_lib.c')
-rw-r--r-- | sound/isa/ad1848/ad1848_lib.c | 261 |
1 files changed, 0 insertions, 261 deletions
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 07756fa36947..5de046014337 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c | |||
@@ -995,267 +995,6 @@ const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction) | |||
995 | EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); | 995 | EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); |
996 | 996 | ||
997 | /* | 997 | /* |
998 | * MIXER part | ||
999 | */ | ||
1000 | |||
1001 | static int snd_ad1848_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
1002 | { | ||
1003 | static char *texts[4] = { | ||
1004 | "Line", "Aux", "Mic", "Mix" | ||
1005 | }; | ||
1006 | |||
1007 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1008 | uinfo->count = 2; | ||
1009 | uinfo->value.enumerated.items = 4; | ||
1010 | if (uinfo->value.enumerated.item > 3) | ||
1011 | uinfo->value.enumerated.item = 3; | ||
1012 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1017 | { | ||
1018 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | ||
1019 | unsigned long flags; | ||
1020 | |||
1021 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1022 | ucontrol->value.enumerated.item[0] = (chip->image[AD1848_LEFT_INPUT] & AD1848_MIXS_ALL) >> 6; | ||
1023 | ucontrol->value.enumerated.item[1] = (chip->image[AD1848_RIGHT_INPUT] & AD1848_MIXS_ALL) >> 6; | ||
1024 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1025 | return 0; | ||
1026 | } | ||
1027 | |||
1028 | static int snd_ad1848_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1029 | { | ||
1030 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | ||
1031 | unsigned long flags; | ||
1032 | unsigned short left, right; | ||
1033 | int change; | ||
1034 | |||
1035 | if (ucontrol->value.enumerated.item[0] > 3 || | ||
1036 | ucontrol->value.enumerated.item[1] > 3) | ||
1037 | return -EINVAL; | ||
1038 | left = ucontrol->value.enumerated.item[0] << 6; | ||
1039 | right = ucontrol->value.enumerated.item[1] << 6; | ||
1040 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1041 | left = (chip->image[AD1848_LEFT_INPUT] & ~AD1848_MIXS_ALL) | left; | ||
1042 | right = (chip->image[AD1848_RIGHT_INPUT] & ~AD1848_MIXS_ALL) | right; | ||
1043 | change = left != chip->image[AD1848_LEFT_INPUT] || | ||
1044 | right != chip->image[AD1848_RIGHT_INPUT]; | ||
1045 | snd_ad1848_out(chip, AD1848_LEFT_INPUT, left); | ||
1046 | snd_ad1848_out(chip, AD1848_RIGHT_INPUT, right); | ||
1047 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1048 | return change; | ||
1049 | } | ||
1050 | |||
1051 | static int snd_ad1848_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
1052 | { | ||
1053 | int mask = (kcontrol->private_value >> 16) & 0xff; | ||
1054 | |||
1055 | uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1056 | uinfo->count = 1; | ||
1057 | uinfo->value.integer.min = 0; | ||
1058 | uinfo->value.integer.max = mask; | ||
1059 | return 0; | ||
1060 | } | ||
1061 | |||
1062 | static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1063 | { | ||
1064 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | ||
1065 | unsigned long flags; | ||
1066 | int reg = kcontrol->private_value & 0xff; | ||
1067 | int shift = (kcontrol->private_value >> 8) & 0xff; | ||
1068 | int mask = (kcontrol->private_value >> 16) & 0xff; | ||
1069 | int invert = (kcontrol->private_value >> 24) & 0xff; | ||
1070 | |||
1071 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1072 | ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask; | ||
1073 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1074 | if (invert) | ||
1075 | ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static int snd_ad1848_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1080 | { | ||
1081 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | ||
1082 | unsigned long flags; | ||
1083 | int reg = kcontrol->private_value & 0xff; | ||
1084 | int shift = (kcontrol->private_value >> 8) & 0xff; | ||
1085 | int mask = (kcontrol->private_value >> 16) & 0xff; | ||
1086 | int invert = (kcontrol->private_value >> 24) & 0xff; | ||
1087 | int change; | ||
1088 | unsigned short val; | ||
1089 | |||
1090 | val = (ucontrol->value.integer.value[0] & mask); | ||
1091 | if (invert) | ||
1092 | val = mask - val; | ||
1093 | val <<= shift; | ||
1094 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1095 | val = (chip->image[reg] & ~(mask << shift)) | val; | ||
1096 | change = val != chip->image[reg]; | ||
1097 | snd_ad1848_out(chip, reg, val); | ||
1098 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1099 | return change; | ||
1100 | } | ||
1101 | |||
1102 | static int snd_ad1848_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
1103 | { | ||
1104 | int mask = (kcontrol->private_value >> 24) & 0xff; | ||
1105 | |||
1106 | uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
1107 | uinfo->count = 2; | ||
1108 | uinfo->value.integer.min = 0; | ||
1109 | uinfo->value.integer.max = mask; | ||
1110 | return 0; | ||
1111 | } | ||
1112 | |||
1113 | static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1114 | { | ||
1115 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | ||
1116 | unsigned long flags; | ||
1117 | int left_reg = kcontrol->private_value & 0xff; | ||
1118 | int right_reg = (kcontrol->private_value >> 8) & 0xff; | ||
1119 | int shift_left = (kcontrol->private_value >> 16) & 0x07; | ||
1120 | int shift_right = (kcontrol->private_value >> 19) & 0x07; | ||
1121 | int mask = (kcontrol->private_value >> 24) & 0xff; | ||
1122 | int invert = (kcontrol->private_value >> 22) & 1; | ||
1123 | |||
1124 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1125 | ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask; | ||
1126 | ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask; | ||
1127 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1128 | if (invert) { | ||
1129 | ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; | ||
1130 | ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; | ||
1131 | } | ||
1132 | return 0; | ||
1133 | } | ||
1134 | |||
1135 | static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
1136 | { | ||
1137 | struct snd_wss *chip = snd_kcontrol_chip(kcontrol); | ||
1138 | unsigned long flags; | ||
1139 | int left_reg = kcontrol->private_value & 0xff; | ||
1140 | int right_reg = (kcontrol->private_value >> 8) & 0xff; | ||
1141 | int shift_left = (kcontrol->private_value >> 16) & 0x07; | ||
1142 | int shift_right = (kcontrol->private_value >> 19) & 0x07; | ||
1143 | int mask = (kcontrol->private_value >> 24) & 0xff; | ||
1144 | int invert = (kcontrol->private_value >> 22) & 1; | ||
1145 | int change; | ||
1146 | unsigned short val1, val2; | ||
1147 | |||
1148 | val1 = ucontrol->value.integer.value[0] & mask; | ||
1149 | val2 = ucontrol->value.integer.value[1] & mask; | ||
1150 | if (invert) { | ||
1151 | val1 = mask - val1; | ||
1152 | val2 = mask - val2; | ||
1153 | } | ||
1154 | val1 <<= shift_left; | ||
1155 | val2 <<= shift_right; | ||
1156 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1157 | if (left_reg != right_reg) { | ||
1158 | val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; | ||
1159 | val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; | ||
1160 | change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; | ||
1161 | snd_ad1848_out(chip, left_reg, val1); | ||
1162 | snd_ad1848_out(chip, right_reg, val2); | ||
1163 | } else { | ||
1164 | val1 = (chip->image[left_reg] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2; | ||
1165 | change = val1 != chip->image[left_reg]; | ||
1166 | snd_ad1848_out(chip, left_reg, val1); | ||
1167 | } | ||
1168 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1169 | return change; | ||
1170 | } | ||
1171 | |||
1172 | static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); | ||
1173 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); | ||
1174 | static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); | ||
1175 | |||
1176 | #define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ | ||
1177 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1178 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ | ||
1179 | .name = xname, \ | ||
1180 | .index = xindex, \ | ||
1181 | .info = snd_ad1848_info_single, \ | ||
1182 | .get = snd_ad1848_get_single, \ | ||
1183 | .put = snd_ad1848_put_single, \ | ||
1184 | .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \ | ||
1185 | .tlv = { .p = (xtlv) } } | ||
1186 | |||
1187 | #define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ | ||
1188 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1189 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ | ||
1190 | .name = xname, \ | ||
1191 | .index = xindex, \ | ||
1192 | .info = snd_ad1848_info_double, \ | ||
1193 | .get = snd_ad1848_get_double, \ | ||
1194 | .put = snd_ad1848_put_double, \ | ||
1195 | .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \ | ||
1196 | (shift_right << 19) | (mask << 24) | (invert << 22), \ | ||
1197 | .tlv = { .p = (xtlv) } } | ||
1198 | |||
1199 | static struct snd_kcontrol_new snd_ad1848_controls[] = { | ||
1200 | WSS_DOUBLE("PCM Playback Switch", 0, | ||
1201 | AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), | ||
1202 | AD1848_DOUBLE_TLV("PCM Playback Volume", 0, | ||
1203 | AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, | ||
1204 | db_scale_6bit), | ||
1205 | WSS_DOUBLE("Aux Playback Switch", 0, | ||
1206 | AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), | ||
1207 | AD1848_DOUBLE_TLV("Aux Playback Volume", 0, | ||
1208 | AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1, | ||
1209 | db_scale_5bit_12db_max), | ||
1210 | WSS_DOUBLE("Aux Playback Switch", 1, | ||
1211 | AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), | ||
1212 | AD1848_DOUBLE_TLV("Aux Playback Volume", 1, | ||
1213 | AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1, | ||
1214 | db_scale_5bit_12db_max), | ||
1215 | AD1848_DOUBLE_TLV("Capture Volume", 0, | ||
1216 | AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0, | ||
1217 | db_scale_rec_gain), | ||
1218 | { | ||
1219 | .name = "Capture Source", | ||
1220 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1221 | .info = snd_ad1848_info_mux, | ||
1222 | .get = snd_ad1848_get_mux, | ||
1223 | .put = snd_ad1848_put_mux, | ||
1224 | }, | ||
1225 | WSS_SINGLE("Loopback Capture Switch", 0, | ||
1226 | AD1848_LOOPBACK, 0, 1, 0), | ||
1227 | AD1848_SINGLE_TLV("Loopback Capture Volume", 0, | ||
1228 | AD1848_LOOPBACK, 1, 63, 0, | ||
1229 | db_scale_6bit), | ||
1230 | }; | ||
1231 | |||
1232 | int snd_ad1848_mixer(struct snd_wss *chip) | ||
1233 | { | ||
1234 | struct snd_card *card; | ||
1235 | struct snd_pcm *pcm; | ||
1236 | unsigned int idx; | ||
1237 | int err; | ||
1238 | |||
1239 | snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); | ||
1240 | |||
1241 | pcm = chip->pcm; | ||
1242 | card = chip->card; | ||
1243 | |||
1244 | strcpy(card->mixername, pcm->name); | ||
1245 | |||
1246 | for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) { | ||
1247 | err = snd_ctl_add(card, | ||
1248 | snd_ctl_new1(&snd_ad1848_controls[idx], chip)); | ||
1249 | if (err < 0) | ||
1250 | return err; | ||
1251 | } | ||
1252 | |||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | EXPORT_SYMBOL(snd_ad1848_mixer); | ||
1257 | |||
1258 | /* | ||
1259 | * INIT part | 998 | * INIT part |
1260 | */ | 999 | */ |
1261 | 1000 | ||