aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_generic.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 3a3abfa6150c..7975031312cb 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -2747,6 +2747,42 @@ static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx)
2747 return 0; 2747 return 0;
2748} 2748}
2749 2749
2750/* return true if either a volume or a mute amp is found for the given
2751 * aamix path; the amp has to be either in the mixer node or its direct leaf
2752 */
2753static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid,
2754 hda_nid_t pin, unsigned int *mix_val,
2755 unsigned int *mute_val)
2756{
2757 int idx, num_conns;
2758 const hda_nid_t *list;
2759 hda_nid_t nid;
2760
2761 idx = snd_hda_get_conn_index(codec, mix_nid, pin, true);
2762 if (idx < 0)
2763 return false;
2764
2765 *mix_val = *mute_val = 0;
2766 if (nid_has_volume(codec, mix_nid, HDA_INPUT))
2767 *mix_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
2768 if (nid_has_mute(codec, mix_nid, HDA_INPUT))
2769 *mute_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
2770 if (*mix_val && *mute_val)
2771 return true;
2772
2773 /* check leaf node */
2774 num_conns = snd_hda_get_conn_list(codec, mix_nid, &list);
2775 if (num_conns < idx)
2776 return false;
2777 nid = list[idx];
2778 if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT))
2779 *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
2780 if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT))
2781 *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
2782
2783 return *mix_val || *mute_val;
2784}
2785
2750/* create input playback/capture controls for the given pin */ 2786/* create input playback/capture controls for the given pin */
2751static int new_analog_input(struct hda_codec *codec, int input_idx, 2787static int new_analog_input(struct hda_codec *codec, int input_idx,
2752 hda_nid_t pin, const char *ctlname, int ctlidx, 2788 hda_nid_t pin, const char *ctlname, int ctlidx,
@@ -2754,12 +2790,11 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
2754{ 2790{
2755 struct hda_gen_spec *spec = codec->spec; 2791 struct hda_gen_spec *spec = codec->spec;
2756 struct nid_path *path; 2792 struct nid_path *path;
2757 unsigned int val; 2793 unsigned int mix_val, mute_val;
2758 int err, idx; 2794 int err, idx;
2759 2795
2760 if (!nid_has_volume(codec, mix_nid, HDA_INPUT) && 2796 if (!look_for_mix_leaf_ctls(codec, mix_nid, pin, &mix_val, &mute_val))
2761 !nid_has_mute(codec, mix_nid, HDA_INPUT)) 2797 return 0;
2762 return 0; /* no need for analog loopback */
2763 2798
2764 path = snd_hda_add_new_path(codec, pin, mix_nid, 0); 2799 path = snd_hda_add_new_path(codec, pin, mix_nid, 0);
2765 if (!path) 2800 if (!path)
@@ -2768,20 +2803,18 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,
2768 spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path); 2803 spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path);
2769 2804
2770 idx = path->idx[path->depth - 1]; 2805 idx = path->idx[path->depth - 1];
2771 if (nid_has_volume(codec, mix_nid, HDA_INPUT)) { 2806 if (mix_val) {
2772 val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); 2807 err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, mix_val);
2773 err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val);
2774 if (err < 0) 2808 if (err < 0)
2775 return err; 2809 return err;
2776 path->ctls[NID_PATH_VOL_CTL] = val; 2810 path->ctls[NID_PATH_VOL_CTL] = mix_val;
2777 } 2811 }
2778 2812
2779 if (nid_has_mute(codec, mix_nid, HDA_INPUT)) { 2813 if (mute_val) {
2780 val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); 2814 err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, mute_val);
2781 err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val);
2782 if (err < 0) 2815 if (err < 0)
2783 return err; 2816 return err;
2784 path->ctls[NID_PATH_MUTE_CTL] = val; 2817 path->ctls[NID_PATH_MUTE_CTL] = mute_val;
2785 } 2818 }
2786 2819
2787 path->active = true; 2820 path->active = true;