diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-11-10 06:41:37 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-11-10 06:41:37 -0500 |
commit | da691064d1cc28053375c442992611dcac979d8c (patch) | |
tree | ae99178853bb49052133c8babb600517842e34b1 /sound/pci/hda | |
parent | 68ef0561efe494143516df38c03a16b837b8e79c (diff) | |
parent | 2f451d2a2a44b66586b803763068195088f9ccd4 (diff) |
Merge branch 'fix/hda' into topic/hda
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 64 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 16 |
3 files changed, 53 insertions, 28 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 916a1863af73..e44b107fdc75 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2331 | return 0; | 2331 | return 0; |
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | ||
2335 | |||
2336 | /* apply the function to all matching slave ctls in the mixer list */ | ||
2337 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, | ||
2338 | map_slave_func_t func, void *data) | ||
2339 | { | ||
2340 | struct hda_nid_item *items; | ||
2341 | const char * const *s; | ||
2342 | int i, err; | ||
2343 | |||
2344 | items = codec->mixers.list; | ||
2345 | for (i = 0; i < codec->mixers.used; i++) { | ||
2346 | struct snd_kcontrol *sctl = items[i].kctl; | ||
2347 | if (!sctl || !sctl->id.name || | ||
2348 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) | ||
2349 | continue; | ||
2350 | for (s = slaves; *s; s++) { | ||
2351 | if (!strcmp(sctl->id.name, *s)) { | ||
2352 | err = func(data, sctl); | ||
2353 | if (err) | ||
2354 | return err; | ||
2355 | break; | ||
2356 | } | ||
2357 | } | ||
2358 | } | ||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | static int check_slave_present(void *data, struct snd_kcontrol *sctl) | ||
2363 | { | ||
2364 | return 1; | ||
2365 | } | ||
2366 | |||
2334 | /** | 2367 | /** |
2335 | * snd_hda_add_vmaster - create a virtual master control and add slaves | 2368 | * snd_hda_add_vmaster - create a virtual master control and add slaves |
2336 | * @codec: HD-audio codec | 2369 | * @codec: HD-audio codec |
@@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2351 | unsigned int *tlv, const char * const *slaves) | 2384 | unsigned int *tlv, const char * const *slaves) |
2352 | { | 2385 | { |
2353 | struct snd_kcontrol *kctl; | 2386 | struct snd_kcontrol *kctl; |
2354 | const char * const *s; | ||
2355 | int err; | 2387 | int err; |
2356 | 2388 | ||
2357 | for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) | 2389 | err = map_slaves(codec, slaves, check_slave_present, NULL); |
2358 | ; | 2390 | if (err != 1) { |
2359 | if (!*s) { | ||
2360 | snd_printdd("No slave found for %s\n", name); | 2391 | snd_printdd("No slave found for %s\n", name); |
2361 | return 0; | 2392 | return 0; |
2362 | } | 2393 | } |
@@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2367 | if (err < 0) | 2398 | if (err < 0) |
2368 | return err; | 2399 | return err; |
2369 | 2400 | ||
2370 | for (s = slaves; *s; s++) { | 2401 | err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, |
2371 | struct snd_kcontrol *sctl; | 2402 | kctl); |
2372 | int i = 0; | 2403 | if (err < 0) |
2373 | for (;;) { | 2404 | return err; |
2374 | sctl = _snd_hda_find_mixer_ctl(codec, *s, i); | ||
2375 | if (!sctl) { | ||
2376 | if (!i) | ||
2377 | snd_printdd("Cannot find slave %s, " | ||
2378 | "skipped\n", *s); | ||
2379 | break; | ||
2380 | } | ||
2381 | err = snd_ctl_add_slave(kctl, sctl); | ||
2382 | if (err < 0) | ||
2383 | return err; | ||
2384 | i++; | ||
2385 | } | ||
2386 | } | ||
2387 | return 0; | 2405 | return 0; |
2388 | } | 2406 | } |
2389 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); | 2407 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); |
@@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
4752 | memset(sequences_hp, 0, sizeof(sequences_hp)); | 4770 | memset(sequences_hp, 0, sizeof(sequences_hp)); |
4753 | assoc_line_out = 0; | 4771 | assoc_line_out = 0; |
4754 | 4772 | ||
4773 | codec->ignore_misc_bit = true; | ||
4755 | end_nid = codec->start_nid + codec->num_nodes; | 4774 | end_nid = codec->start_nid + codec->num_nodes; |
4756 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 4775 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
4757 | unsigned int wid_caps = get_wcaps(codec, nid); | 4776 | unsigned int wid_caps = get_wcaps(codec, nid); |
@@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
4767 | continue; | 4786 | continue; |
4768 | 4787 | ||
4769 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4788 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
4789 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
4790 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
4791 | codec->ignore_misc_bit = false; | ||
4770 | conn = get_defcfg_connect(def_conf); | 4792 | conn = get_defcfg_connect(def_conf); |
4771 | if (conn == AC_JACK_PORT_NONE) | 4793 | if (conn == AC_JACK_PORT_NONE) |
4772 | continue; | 4794 | continue; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 755f2b0f9d8e..564471169cae 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -854,6 +854,7 @@ struct hda_codec { | |||
854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ | 854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ |
855 | unsigned int pins_shutup:1; /* pins are shut up */ | 855 | unsigned int pins_shutup:1; /* pins are shut up */ |
856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
857 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | ||
857 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 858 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
858 | unsigned int power_on :1; /* current (global) power-state */ | 859 | unsigned int power_on :1; /* current (global) power-state */ |
859 | unsigned int power_transition :1; /* power-state in transition */ | 860 | unsigned int power_transition :1; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index dcbea0da0fa2..6579e0f2bb57 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | |||
510 | 510 | ||
511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
512 | { | 512 | { |
513 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && | 513 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) |
514 | /* disable MISC_NO_PRESENCE check because it may break too | 514 | return false; |
515 | * many devices | 515 | if (!codec->ignore_misc_bit && |
516 | */ | 516 | (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & |
517 | /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & | 517 | AC_DEFCFG_MISC_NO_PRESENCE)) |
518 | AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ | 518 | return false; |
519 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); | 519 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) |
520 | return false; | ||
521 | return true; | ||
520 | } | 522 | } |
521 | 523 | ||
522 | /* flags for hda_nid_item */ | 524 | /* flags for hda_nid_item */ |