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 | ||
