aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 45b4a8d70e0..21958518467 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2187,6 +2187,39 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2187 return 0; 2187 return 0;
2188} 2188}
2189 2189
2190typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
2191
2192/* apply the function to all matching slave ctls in the mixer list */
2193static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2194 map_slave_func_t func, void *data)
2195{
2196 struct hda_nid_item *items;
2197 const char * const *s;
2198 int i, err;
2199
2200 items = codec->mixers.list;
2201 for (i = 0; i < codec->mixers.used; i++) {
2202 struct snd_kcontrol *sctl = items[i].kctl;
2203 if (!sctl || !sctl->id.name ||
2204 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
2205 continue;
2206 for (s = slaves; *s; s++) {
2207 if (!strcmp(sctl->id.name, *s)) {
2208 err = func(data, sctl);
2209 if (err)
2210 return err;
2211 break;
2212 }
2213 }
2214 }
2215 return 0;
2216}
2217
2218static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2219{
2220 return 1;
2221}
2222
2190/** 2223/**
2191 * snd_hda_add_vmaster - create a virtual master control and add slaves 2224 * snd_hda_add_vmaster - create a virtual master control and add slaves
2192 * @codec: HD-audio codec 2225 * @codec: HD-audio codec
@@ -2207,12 +2240,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2207 unsigned int *tlv, const char * const *slaves) 2240 unsigned int *tlv, const char * const *slaves)
2208{ 2241{
2209 struct snd_kcontrol *kctl; 2242 struct snd_kcontrol *kctl;
2210 const char * const *s;
2211 int err; 2243 int err;
2212 2244
2213 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) 2245 err = map_slaves(codec, slaves, check_slave_present, NULL);
2214 ; 2246 if (err != 1) {
2215 if (!*s) {
2216 snd_printdd("No slave found for %s\n", name); 2247 snd_printdd("No slave found for %s\n", name);
2217 return 0; 2248 return 0;
2218 } 2249 }
@@ -2223,23 +2254,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2223 if (err < 0) 2254 if (err < 0)
2224 return err; 2255 return err;
2225 2256
2226 for (s = slaves; *s; s++) { 2257 err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave,
2227 struct snd_kcontrol *sctl; 2258 kctl);
2228 int i = 0; 2259 if (err < 0)
2229 for (;;) { 2260 return err;
2230 sctl = _snd_hda_find_mixer_ctl(codec, *s, i);
2231 if (!sctl) {
2232 if (!i)
2233 snd_printdd("Cannot find slave %s, "
2234 "skipped\n", *s);
2235 break;
2236 }
2237 err = snd_ctl_add_slave(kctl, sctl);
2238 if (err < 0)
2239 return err;
2240 i++;
2241 }
2242 }
2243 return 0; 2261 return 0;
2244} 2262}
2245EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); 2263EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);