diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 60 |
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 | ||
2190 | typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | ||
2191 | |||
2192 | /* apply the function to all matching slave ctls in the mixer list */ | ||
2193 | static 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 | |||
2218 | static 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 | } |
2245 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); | 2263 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); |