aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/ad1848.h32
-rw-r--r--sound/isa/ad1848/ad1848_lib.c123
-rw-r--r--sound/isa/cmi8330.c82
-rw-r--r--sound/isa/sgalaxy.c12
4 files changed, 114 insertions, 135 deletions
diff --git a/include/sound/ad1848.h b/include/sound/ad1848.h
index a881d5173c64..1271e0dada90 100644
--- a/include/sound/ad1848.h
+++ b/include/sound/ad1848.h
@@ -126,36 +126,4 @@ int snd_ad1848_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
126const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction); 126const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction);
127int snd_ad1848_mixer(struct snd_wss *chip); 127int snd_ad1848_mixer(struct snd_wss *chip);
128 128
129/* exported mixer stuffs */
130enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
131
132#define AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) \
133 ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
134#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \
135 ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22))
136
137/* for ease of use */
138struct ad1848_mix_elem {
139 const char *name;
140 int index;
141 int type;
142 unsigned long private_value;
143 const unsigned int *tlv;
144};
145
146#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
147{ .name = xname, \
148 .index = xindex, \
149 .type = AD1848_MIX_SINGLE, \
150 .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) }
151
152#define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
153{ .name = xname, \
154 .index = xindex, \
155 .type = AD1848_MIX_DOUBLE, \
156 .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) }
157
158int snd_ad1848_add_ctl_elem(struct snd_wss *chip,
159 const struct ad1848_mix_elem *c);
160
161#endif /* __SOUND_AD1848_H */ 129#endif /* __SOUND_AD1848_H */
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 5aa8f6dae75b..4f7aaf4e0989 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -1163,88 +1163,64 @@ static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1163 return change; 1163 return change;
1164} 1164}
1165 1165
1166/*
1167 */
1168int snd_ad1848_add_ctl_elem(struct snd_wss *chip,
1169 const struct ad1848_mix_elem *c)
1170{
1171 static struct snd_kcontrol_new newctls[] = {
1172 [AD1848_MIX_SINGLE] = {
1173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1174 .info = snd_ad1848_info_single,
1175 .get = snd_ad1848_get_single,
1176 .put = snd_ad1848_put_single,
1177 },
1178 [AD1848_MIX_DOUBLE] = {
1179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1180 .info = snd_ad1848_info_double,
1181 .get = snd_ad1848_get_double,
1182 .put = snd_ad1848_put_double,
1183 },
1184 [AD1848_MIX_CAPTURE] = {
1185 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1186 .info = snd_ad1848_info_mux,
1187 .get = snd_ad1848_get_mux,
1188 .put = snd_ad1848_put_mux,
1189 },
1190 };
1191 struct snd_kcontrol *ctl;
1192 int err;
1193
1194 ctl = snd_ctl_new1(&newctls[c->type], chip);
1195 if (! ctl)
1196 return -ENOMEM;
1197 strlcpy(ctl->id.name, c->name, sizeof(ctl->id.name));
1198 ctl->id.index = c->index;
1199 ctl->private_value = c->private_value;
1200 if (c->tlv) {
1201 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1202 ctl->tlv.p = c->tlv;
1203 }
1204 if ((err = snd_ctl_add(chip->card, ctl)) < 0)
1205 return err;
1206 return 0;
1207}
1208
1209EXPORT_SYMBOL(snd_ad1848_add_ctl_elem);
1210
1211static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); 1166static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
1212static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); 1167static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
1213static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); 1168static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
1214 1169
1215#define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \ 1170#define AD1848_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
1216{ .name = xname, \ 1171{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1172 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
1173 .name = xname, \
1217 .index = xindex, \ 1174 .index = xindex, \
1218 .type = AD1848_MIX_SINGLE, \ 1175 .info = snd_ad1848_info_single, \
1219 .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert), \ 1176 .get = snd_ad1848_get_single, \
1220 .tlv = xtlv } 1177 .put = snd_ad1848_put_single, \
1178 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
1179 .tlv = { .p = (xtlv) } }
1221 1180
1222#define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \ 1181#define AD1848_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert, xtlv) \
1223{ .name = xname, \ 1182{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1183 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
1184 .name = xname, \
1224 .index = xindex, \ 1185 .index = xindex, \
1225 .type = AD1848_MIX_DOUBLE, \ 1186 .info = snd_ad1848_info_double, \
1226 .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert), \ 1187 .get = snd_ad1848_get_double, \
1227 .tlv = xtlv } 1188 .put = snd_ad1848_put_double, \
1228 1189 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
1229static struct ad1848_mix_elem snd_ad1848_controls[] = { 1190 (shift_right << 19) | (mask << 24) | (invert << 22), \
1230AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), 1191 .tlv = { .p = (xtlv) } }
1231AD1848_DOUBLE_TLV("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1, 1192
1232 db_scale_6bit), 1193static struct snd_kcontrol_new snd_ad1848_controls[] = {
1233AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 1194WSS_DOUBLE("PCM Playback Switch", 0,
1234AD1848_DOUBLE_TLV("Aux Playback Volume", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1, 1195 AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
1235 db_scale_5bit_12db_max), 1196AD1848_DOUBLE_TLV("PCM Playback Volume", 0,
1236AD1848_DOUBLE("Aux Playback Switch", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 1197 AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1,
1237AD1848_DOUBLE_TLV("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1, 1198 db_scale_6bit),
1238 db_scale_5bit_12db_max), 1199WSS_DOUBLE("Aux Playback Switch", 0,
1239AD1848_DOUBLE_TLV("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0, 1200 AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
1240 db_scale_rec_gain), 1201AD1848_DOUBLE_TLV("Aux Playback Volume", 0,
1202 AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
1203 db_scale_5bit_12db_max),
1204WSS_DOUBLE("Aux Playback Switch", 1,
1205 AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
1206AD1848_DOUBLE_TLV("Aux Playback Volume", 1,
1207 AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
1208 db_scale_5bit_12db_max),
1209AD1848_DOUBLE_TLV("Capture Volume", 0,
1210 AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0,
1211 db_scale_rec_gain),
1241{ 1212{
1242 .name = "Capture Source", 1213 .name = "Capture Source",
1243 .type = AD1848_MIX_CAPTURE, 1214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1215 .info = snd_ad1848_info_mux,
1216 .get = snd_ad1848_get_mux,
1217 .put = snd_ad1848_put_mux,
1244}, 1218},
1245AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0), 1219WSS_SINGLE("Loopback Capture Switch", 0,
1246AD1848_SINGLE_TLV("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0, 1220 AD1848_LOOPBACK, 0, 1, 0),
1247 db_scale_6bit), 1221AD1848_SINGLE_TLV("Loopback Capture Volume", 0,
1222 AD1848_LOOPBACK, 1, 63, 0,
1223 db_scale_6bit),
1248}; 1224};
1249 1225
1250int snd_ad1848_mixer(struct snd_wss *chip) 1226int snd_ad1848_mixer(struct snd_wss *chip)
@@ -1261,9 +1237,12 @@ int snd_ad1848_mixer(struct snd_wss *chip)
1261 1237
1262 strcpy(card->mixername, pcm->name); 1238 strcpy(card->mixername, pcm->name);
1263 1239
1264 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) 1240 for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) {
1265 if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0) 1241 err = snd_ctl_add(card,
1242 snd_ctl_new1(&snd_ad1848_controls[idx], chip));
1243 if (err < 0)
1266 return err; 1244 return err;
1245 }
1267 1246
1268 return 0; 1247 return 0;
1269} 1248}
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index af6ba129910e..ca6f602f15c2 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -174,32 +174,57 @@ MODULE_DEVICE_TABLE(pnp_card, snd_cmi8330_pnpids);
174#endif 174#endif
175 175
176 176
177static struct ad1848_mix_elem snd_cmi8330_controls[] __devinitdata = { 177static struct snd_kcontrol_new snd_cmi8330_controls[] __devinitdata = {
178AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), 178WSS_DOUBLE("Master Playback Volume", 0,
179AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), 179 CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
180AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), 180WSS_SINGLE("Loud Playback Switch", 0,
181AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), 181 CMI8330_MUTEMUX, 6, 1, 1),
182AD1848_DOUBLE("Line Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0), 182WSS_DOUBLE("PCM Playback Switch", 0,
183AD1848_DOUBLE("Line Playback Volume", 0, CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0), 183 AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1),
184AD1848_DOUBLE("Line Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0), 184WSS_DOUBLE("PCM Playback Volume", 0,
185AD1848_DOUBLE("Line Capture Volume", 0, CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0), 185 AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1),
186AD1848_DOUBLE("CD Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0), 186WSS_DOUBLE("Line Playback Switch", 0,
187AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0), 187 CMI8330_MUTEMUX, CMI8330_MUTEMUX, 4, 3, 1, 0),
188AD1848_DOUBLE("CD Playback Volume", 0, CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0), 188WSS_DOUBLE("Line Playback Volume", 0,
189AD1848_DOUBLE("CD Capture Volume", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0), 189 CMI8330_LINVOL, CMI8330_LINVOL, 4, 0, 15, 0),
190AD1848_SINGLE("Mic Playback Switch", 0, CMI8330_MUTEMUX, 0, 1, 0), 190WSS_DOUBLE("Line Capture Switch", 0,
191AD1848_SINGLE("Mic Playback Volume", 0, CMI8330_OUTPUTVOL, 0, 7, 0), 191 CMI8330_RMUX3D, CMI8330_RMUX3D, 2, 1, 1, 0),
192AD1848_SINGLE("Mic Capture Switch", 0, CMI8330_RMUX3D, 0, 1, 0), 192WSS_DOUBLE("Line Capture Volume", 0,
193AD1848_SINGLE("Mic Capture Volume", 0, CMI8330_OUTPUTVOL, 5, 7, 0), 193 CMI8330_LINGAIN, CMI8330_LINGAIN, 4, 0, 15, 0),
194AD1848_DOUBLE("Wavetable Playback Switch", 0, CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0), 194WSS_DOUBLE("CD Playback Switch", 0,
195AD1848_DOUBLE("Wavetable Playback Volume", 0, CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0), 195 CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0),
196AD1848_DOUBLE("Wavetable Capture Switch", 0, CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0), 196WSS_DOUBLE("CD Capture Switch", 0,
197AD1848_DOUBLE("Wavetable Capture Volume", 0, CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0), 197 CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0),
198AD1848_SINGLE("3D Control - Switch", 0, CMI8330_RMUX3D, 5, 1, 1), 198WSS_DOUBLE("CD Playback Volume", 0,
199AD1848_SINGLE("PC Speaker Playback Volume", 0, CMI8330_OUTPUTVOL, 3, 3, 0), 199 CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0),
200AD1848_SINGLE("FM Playback Switch", 0, CMI8330_RECMUX, 3, 1, 1), 200WSS_DOUBLE("CD Capture Volume", 0,
201AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",CAPTURE,SWITCH), 0, CMI8330_RMUX3D, 7, 1, 1), 201 CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0),
202AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",PLAYBACK,SWITCH), 0, CMI8330_MUTEMUX, 7, 1, 1), 202WSS_SINGLE("Mic Playback Switch", 0,
203 CMI8330_MUTEMUX, 0, 1, 0),
204WSS_SINGLE("Mic Playback Volume", 0,
205 CMI8330_OUTPUTVOL, 0, 7, 0),
206WSS_SINGLE("Mic Capture Switch", 0,
207 CMI8330_RMUX3D, 0, 1, 0),
208WSS_SINGLE("Mic Capture Volume", 0,
209 CMI8330_OUTPUTVOL, 5, 7, 0),
210WSS_DOUBLE("Wavetable Playback Switch", 0,
211 CMI8330_RECMUX, CMI8330_RECMUX, 1, 0, 1, 0),
212WSS_DOUBLE("Wavetable Playback Volume", 0,
213 CMI8330_WAVVOL, CMI8330_WAVVOL, 4, 0, 15, 0),
214WSS_DOUBLE("Wavetable Capture Switch", 0,
215 CMI8330_RECMUX, CMI8330_RECMUX, 5, 4, 1, 0),
216WSS_DOUBLE("Wavetable Capture Volume", 0,
217 CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4, 0, 15, 0),
218WSS_SINGLE("3D Control - Switch", 0,
219 CMI8330_RMUX3D, 5, 1, 1),
220WSS_SINGLE("PC Speaker Playback Volume", 0,
221 CMI8330_OUTPUTVOL, 3, 3, 0),
222WSS_SINGLE("FM Playback Switch", 0,
223 CMI8330_RECMUX, 3, 1, 1),
224WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0,
225 CMI8330_RMUX3D, 7, 1, 1),
226WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0,
227 CMI8330_MUTEMUX, 7, 1, 1),
203}; 228};
204 229
205#ifdef ENABLE_SB_MIXER 230#ifdef ENABLE_SB_MIXER
@@ -268,7 +293,10 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330
268 strcpy(card->mixername, "CMI8330/C3D"); 293 strcpy(card->mixername, "CMI8330/C3D");
269 294
270 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { 295 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
271 if ((err = snd_ad1848_add_ctl_elem(acard->wss, &snd_cmi8330_controls[idx])) < 0) 296 err = snd_ctl_add(card,
297 snd_ctl_new1(&snd_cmi8330_controls[idx],
298 acard->wss));
299 if (err < 0)
272 return err; 300 return err;
273 } 301 }
274 302
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index 9a5a7cc0e607..5894b2d4db64 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -175,9 +175,11 @@ static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
175 return snd_sgalaxy_setup_wss(wssport[dev], irq, dma); 175 return snd_sgalaxy_setup_wss(wssport[dev], irq, dma);
176} 176}
177 177
178static struct ad1848_mix_elem snd_sgalaxy_controls[] = { 178static struct snd_kcontrol_new snd_sgalaxy_controls[] = {
179AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1), 179WSS_DOUBLE("Aux Playback Switch", 0,
180AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) 180 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1),
181WSS_DOUBLE("Aux Playback Volume", 0,
182 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
181}; 183};
182 184
183static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip) 185static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip)
@@ -210,7 +212,9 @@ static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip)
210 return err; 212 return err;
211 /* build AUX2 input */ 213 /* build AUX2 input */
212 for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) { 214 for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) {
213 if ((err = snd_ad1848_add_ctl_elem(chip, &snd_sgalaxy_controls[idx])) < 0) 215 err = snd_ctl_add(card,
216 snd_ctl_new1(&snd_sgalaxy_controls[idx], chip));
217 if (err < 0)
214 return err; 218 return err;
215 } 219 }
216 return 0; 220 return 0;