diff options
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r-- | sound/pci/hda/hda_generic.c | 126 |
1 files changed, 104 insertions, 22 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 3067ed4fe3b2..c7f6d1cab606 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -474,6 +474,20 @@ static void invalidate_nid_path(struct hda_codec *codec, int idx) | |||
474 | memset(path, 0, sizeof(*path)); | 474 | memset(path, 0, sizeof(*path)); |
475 | } | 475 | } |
476 | 476 | ||
477 | /* return a DAC if paired to the given pin by codec driver */ | ||
478 | static hda_nid_t get_preferred_dac(struct hda_codec *codec, hda_nid_t pin) | ||
479 | { | ||
480 | struct hda_gen_spec *spec = codec->spec; | ||
481 | const hda_nid_t *list = spec->preferred_dacs; | ||
482 | |||
483 | if (!list) | ||
484 | return 0; | ||
485 | for (; *list; list += 2) | ||
486 | if (*list == pin) | ||
487 | return list[1]; | ||
488 | return 0; | ||
489 | } | ||
490 | |||
477 | /* look for an empty DAC slot */ | 491 | /* look for an empty DAC slot */ |
478 | static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin, | 492 | static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin, |
479 | bool is_digital) | 493 | bool is_digital) |
@@ -1192,7 +1206,14 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs, | |||
1192 | continue; | 1206 | continue; |
1193 | } | 1207 | } |
1194 | 1208 | ||
1195 | dacs[i] = look_for_dac(codec, pin, false); | 1209 | dacs[i] = get_preferred_dac(codec, pin); |
1210 | if (dacs[i]) { | ||
1211 | if (is_dac_already_used(codec, dacs[i])) | ||
1212 | badness += bad->shared_primary; | ||
1213 | } | ||
1214 | |||
1215 | if (!dacs[i]) | ||
1216 | dacs[i] = look_for_dac(codec, pin, false); | ||
1196 | if (!dacs[i] && !i) { | 1217 | if (!dacs[i] && !i) { |
1197 | /* try to steal the DAC of surrounds for the front */ | 1218 | /* try to steal the DAC of surrounds for the front */ |
1198 | for (j = 1; j < num_outs; j++) { | 1219 | for (j = 1; j < num_outs; j++) { |
@@ -2506,12 +2527,8 @@ static int create_out_jack_modes(struct hda_codec *codec, int num_pins, | |||
2506 | 2527 | ||
2507 | for (i = 0; i < num_pins; i++) { | 2528 | for (i = 0; i < num_pins; i++) { |
2508 | hda_nid_t pin = pins[i]; | 2529 | hda_nid_t pin = pins[i]; |
2509 | if (pin == spec->hp_mic_pin) { | 2530 | if (pin == spec->hp_mic_pin) |
2510 | int ret = create_hp_mic_jack_mode(codec, pin); | ||
2511 | if (ret < 0) | ||
2512 | return ret; | ||
2513 | continue; | 2531 | continue; |
2514 | } | ||
2515 | if (get_out_jack_num_items(codec, pin) > 1) { | 2532 | if (get_out_jack_num_items(codec, pin) > 1) { |
2516 | struct snd_kcontrol_new *knew; | 2533 | struct snd_kcontrol_new *knew; |
2517 | char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; | 2534 | char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; |
@@ -2764,7 +2781,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, | |||
2764 | val &= ~(AC_PINCTL_VREFEN | PIN_HP); | 2781 | val &= ~(AC_PINCTL_VREFEN | PIN_HP); |
2765 | val |= get_vref_idx(vref_caps, idx) | PIN_IN; | 2782 | val |= get_vref_idx(vref_caps, idx) | PIN_IN; |
2766 | } else | 2783 | } else |
2767 | val = snd_hda_get_default_vref(codec, nid); | 2784 | val = snd_hda_get_default_vref(codec, nid) | PIN_IN; |
2768 | } | 2785 | } |
2769 | snd_hda_set_pin_ctl_cache(codec, nid, val); | 2786 | snd_hda_set_pin_ctl_cache(codec, nid, val); |
2770 | call_hp_automute(codec, NULL); | 2787 | call_hp_automute(codec, NULL); |
@@ -2784,9 +2801,6 @@ static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin) | |||
2784 | struct hda_gen_spec *spec = codec->spec; | 2801 | struct hda_gen_spec *spec = codec->spec; |
2785 | struct snd_kcontrol_new *knew; | 2802 | struct snd_kcontrol_new *knew; |
2786 | 2803 | ||
2787 | if (get_out_jack_num_items(codec, pin) <= 1 && | ||
2788 | get_in_jack_num_items(codec, pin) <= 1) | ||
2789 | return 0; /* no need */ | ||
2790 | knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode", | 2804 | knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode", |
2791 | &hp_mic_jack_mode_enum); | 2805 | &hp_mic_jack_mode_enum); |
2792 | if (!knew) | 2806 | if (!knew) |
@@ -2815,6 +2829,42 @@ static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx) | |||
2815 | return 0; | 2829 | return 0; |
2816 | } | 2830 | } |
2817 | 2831 | ||
2832 | /* return true if either a volume or a mute amp is found for the given | ||
2833 | * aamix path; the amp has to be either in the mixer node or its direct leaf | ||
2834 | */ | ||
2835 | static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid, | ||
2836 | hda_nid_t pin, unsigned int *mix_val, | ||
2837 | unsigned int *mute_val) | ||
2838 | { | ||
2839 | int idx, num_conns; | ||
2840 | const hda_nid_t *list; | ||
2841 | hda_nid_t nid; | ||
2842 | |||
2843 | idx = snd_hda_get_conn_index(codec, mix_nid, pin, true); | ||
2844 | if (idx < 0) | ||
2845 | return false; | ||
2846 | |||
2847 | *mix_val = *mute_val = 0; | ||
2848 | if (nid_has_volume(codec, mix_nid, HDA_INPUT)) | ||
2849 | *mix_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); | ||
2850 | if (nid_has_mute(codec, mix_nid, HDA_INPUT)) | ||
2851 | *mute_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); | ||
2852 | if (*mix_val && *mute_val) | ||
2853 | return true; | ||
2854 | |||
2855 | /* check leaf node */ | ||
2856 | num_conns = snd_hda_get_conn_list(codec, mix_nid, &list); | ||
2857 | if (num_conns < idx) | ||
2858 | return false; | ||
2859 | nid = list[idx]; | ||
2860 | if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT)) | ||
2861 | *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
2862 | if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT)) | ||
2863 | *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
2864 | |||
2865 | return *mix_val || *mute_val; | ||
2866 | } | ||
2867 | |||
2818 | /* create input playback/capture controls for the given pin */ | 2868 | /* create input playback/capture controls for the given pin */ |
2819 | static int new_analog_input(struct hda_codec *codec, int input_idx, | 2869 | static int new_analog_input(struct hda_codec *codec, int input_idx, |
2820 | hda_nid_t pin, const char *ctlname, int ctlidx, | 2870 | hda_nid_t pin, const char *ctlname, int ctlidx, |
@@ -2822,12 +2872,11 @@ static int new_analog_input(struct hda_codec *codec, int input_idx, | |||
2822 | { | 2872 | { |
2823 | struct hda_gen_spec *spec = codec->spec; | 2873 | struct hda_gen_spec *spec = codec->spec; |
2824 | struct nid_path *path; | 2874 | struct nid_path *path; |
2825 | unsigned int val; | 2875 | unsigned int mix_val, mute_val; |
2826 | int err, idx; | 2876 | int err, idx; |
2827 | 2877 | ||
2828 | if (!nid_has_volume(codec, mix_nid, HDA_INPUT) && | 2878 | if (!look_for_mix_leaf_ctls(codec, mix_nid, pin, &mix_val, &mute_val)) |
2829 | !nid_has_mute(codec, mix_nid, HDA_INPUT)) | 2879 | return 0; |
2830 | return 0; /* no need for analog loopback */ | ||
2831 | 2880 | ||
2832 | path = snd_hda_add_new_path(codec, pin, mix_nid, 0); | 2881 | path = snd_hda_add_new_path(codec, pin, mix_nid, 0); |
2833 | if (!path) | 2882 | if (!path) |
@@ -2836,20 +2885,18 @@ static int new_analog_input(struct hda_codec *codec, int input_idx, | |||
2836 | spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path); | 2885 | spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path); |
2837 | 2886 | ||
2838 | idx = path->idx[path->depth - 1]; | 2887 | idx = path->idx[path->depth - 1]; |
2839 | if (nid_has_volume(codec, mix_nid, HDA_INPUT)) { | 2888 | if (mix_val) { |
2840 | val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); | 2889 | err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, mix_val); |
2841 | err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val); | ||
2842 | if (err < 0) | 2890 | if (err < 0) |
2843 | return err; | 2891 | return err; |
2844 | path->ctls[NID_PATH_VOL_CTL] = val; | 2892 | path->ctls[NID_PATH_VOL_CTL] = mix_val; |
2845 | } | 2893 | } |
2846 | 2894 | ||
2847 | if (nid_has_mute(codec, mix_nid, HDA_INPUT)) { | 2895 | if (mute_val) { |
2848 | val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); | 2896 | err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, mute_val); |
2849 | err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val); | ||
2850 | if (err < 0) | 2897 | if (err < 0) |
2851 | return err; | 2898 | return err; |
2852 | path->ctls[NID_PATH_MUTE_CTL] = val; | 2899 | path->ctls[NID_PATH_MUTE_CTL] = mute_val; |
2853 | } | 2900 | } |
2854 | 2901 | ||
2855 | path->active = true; | 2902 | path->active = true; |
@@ -4271,6 +4318,26 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | |||
4271 | return AC_PWRST_D3; | 4318 | return AC_PWRST_D3; |
4272 | } | 4319 | } |
4273 | 4320 | ||
4321 | /* mute all aamix inputs initially; parse up to the first leaves */ | ||
4322 | static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) | ||
4323 | { | ||
4324 | int i, nums; | ||
4325 | const hda_nid_t *conn; | ||
4326 | bool has_amp; | ||
4327 | |||
4328 | nums = snd_hda_get_conn_list(codec, mix, &conn); | ||
4329 | has_amp = nid_has_mute(codec, mix, HDA_INPUT); | ||
4330 | for (i = 0; i < nums; i++) { | ||
4331 | if (has_amp) | ||
4332 | snd_hda_codec_amp_stereo(codec, mix, | ||
4333 | HDA_INPUT, i, | ||
4334 | 0xff, HDA_AMP_MUTE); | ||
4335 | else if (nid_has_volume(codec, conn[i], HDA_OUTPUT)) | ||
4336 | snd_hda_codec_amp_stereo(codec, conn[i], | ||
4337 | HDA_OUTPUT, 0, | ||
4338 | 0xff, HDA_AMP_MUTE); | ||
4339 | } | ||
4340 | } | ||
4274 | 4341 | ||
4275 | /* | 4342 | /* |
4276 | * Parse the given BIOS configuration and set up the hda_gen_spec | 4343 | * Parse the given BIOS configuration and set up the hda_gen_spec |
@@ -4383,6 +4450,17 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
4383 | if (err < 0) | 4450 | if (err < 0) |
4384 | return err; | 4451 | return err; |
4385 | 4452 | ||
4453 | /* create "Headphone Mic Jack Mode" if no input selection is | ||
4454 | * available (or user specifies add_jack_modes hint) | ||
4455 | */ | ||
4456 | if (spec->hp_mic_pin && | ||
4457 | (spec->auto_mic || spec->input_mux.num_items == 1 || | ||
4458 | spec->add_jack_modes)) { | ||
4459 | err = create_hp_mic_jack_mode(codec, spec->hp_mic_pin); | ||
4460 | if (err < 0) | ||
4461 | return err; | ||
4462 | } | ||
4463 | |||
4386 | if (spec->add_jack_modes) { | 4464 | if (spec->add_jack_modes) { |
4387 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 4465 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
4388 | err = create_out_jack_modes(codec, cfg->line_outs, | 4466 | err = create_out_jack_modes(codec, cfg->line_outs, |
@@ -4398,6 +4476,10 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
4398 | } | 4476 | } |
4399 | } | 4477 | } |
4400 | 4478 | ||
4479 | /* mute all aamix input initially */ | ||
4480 | if (spec->mixer_nid) | ||
4481 | mute_all_mixer_nid(codec, spec->mixer_nid); | ||
4482 | |||
4401 | dig_only: | 4483 | dig_only: |
4402 | parse_digital(codec); | 4484 | parse_digital(codec); |
4403 | 4485 | ||