aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-12-06 12:06:23 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-10 04:34:27 -0500
commitba8111276f2cc10b9851613bc8300cabda3c7e0d (patch)
tree130a5f15b45d49fba35016303285212e55b16f67 /sound/pci/hda/patch_realtek.c
parent30dcd3b40409a4db272998b0cba1b9e80c15b1c8 (diff)
ALSA: hda/realtek - Manage mixer controls in out_path list
As we parse the output paths more precisely now, we can use this path list for parsing the widgets for volume and mute mixer controls. The spec->vol_ctls[] and sw_ctls[] bitmasks are replaced with the ctls[] in each output path instance. Interestingly, this move alone automagically fixes some bugs that the conflicting volume or mute NIDs weren't properly detected. Also, by parsing the whole path, there are more chances to get a free widget for volume/mute controls. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c230
1 files changed, 131 insertions, 99 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1f178d6da9d4..cacfbc05786a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -116,6 +116,8 @@ struct nid_path {
116 unsigned int ctls[2]; /* 0 = volume, 1 = mute */ 116 unsigned int ctls[2]; /* 0 = volume, 1 = mute */
117}; 117};
118 118
119enum { NID_PATH_VOL_CTL = 0, NID_PATH_MUTE_CTL = 1 };
120
119struct alc_spec { 121struct alc_spec {
120 struct hda_gen_spec gen; 122 struct hda_gen_spec gen;
121 123
@@ -150,8 +152,6 @@ struct alc_spec {
150 const hda_nid_t *capsrc_nids; 152 const hda_nid_t *capsrc_nids;
151 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 153 hda_nid_t dig_in_nid; /* digital-in NID; optional */
152 hda_nid_t mixer_nid; /* analog-mixer NID */ 154 hda_nid_t mixer_nid; /* analog-mixer NID */
153 DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
154 DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
155 155
156 /* capture setup for dynamic dual-adc switch */ 156 /* capture setup for dynamic dual-adc switch */
157 hda_nid_t cur_adc; 157 hda_nid_t cur_adc;
@@ -2886,22 +2886,6 @@ static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2886 return srcs[0]; 2886 return srcs[0];
2887} 2887}
2888 2888
2889/* get MIX nid connected to the given pin targeted to DAC */
2890static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2891 hda_nid_t dac)
2892{
2893 hda_nid_t mix[5];
2894 int i, num;
2895
2896 pin = alc_go_down_to_selector(codec, pin);
2897 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2898 for (i = 0; i < num; i++) {
2899 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2900 return mix[i];
2901 }
2902 return 0;
2903}
2904
2905/* select the connection from pin to DAC if needed */ 2889/* select the connection from pin to DAC if needed */
2906static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, 2890static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2907 hda_nid_t dac) 2891 hda_nid_t dac)
@@ -3049,29 +3033,28 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
3049 return nid_found; 3033 return nid_found;
3050} 3034}
3051 3035
3052/* mark up volume and mute control NIDs: used during badness parsing and 3036static bool is_ctl_used(struct hda_codec *codec, unsigned int val, int type)
3053 * at creating actual controls
3054 */
3055static inline unsigned int get_ctl_pos(unsigned int data)
3056{ 3037{
3057 hda_nid_t nid = get_amp_nid_(data); 3038 struct alc_spec *spec = codec->spec;
3058 unsigned int dir; 3039 int i;
3059 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3060 return 0;
3061 dir = get_amp_direction_(data);
3062 return (nid << 1) | dir;
3063}
3064 3040
3065#define is_ctl_used(bits, data) \ 3041 for (i = 0; i < spec->out_path.used; i++) {
3066 test_bit(get_ctl_pos(data), bits) 3042 struct nid_path *path = snd_array_elem(&spec->out_path, i);
3067#define mark_ctl_usage(bits, data) \ 3043 if (path->ctls[type] == val)
3068 set_bit(get_ctl_pos(data), bits) 3044 return true;
3045 }
3046 return false;
3047}
3069 3048
3070static void clear_vol_marks(struct hda_codec *codec) 3049static void clear_vol_marks(struct hda_codec *codec)
3071{ 3050{
3072 struct alc_spec *spec = codec->spec; 3051 struct alc_spec *spec = codec->spec;
3073 memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls)); 3052 int i;
3074 memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls)); 3053
3054 for (i = 0; i < spec->out_path.used; i++) {
3055 struct nid_path *path = snd_array_elem(&spec->out_path, i);
3056 path->ctls[0] = path->ctls[1] = 0;
3057 }
3075} 3058}
3076 3059
3077/* badness definition */ 3060/* badness definition */
@@ -3097,9 +3080,9 @@ enum {
3097}; 3080};
3098 3081
3099static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, 3082static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
3100 hda_nid_t pin, hda_nid_t dac); 3083 struct nid_path *path);
3101static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, 3084static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
3102 hda_nid_t pin, hda_nid_t dac); 3085 struct nid_path *path);
3103 3086
3104static bool add_new_out_path(struct hda_codec *codec, hda_nid_t pin, 3087static bool add_new_out_path(struct hda_codec *codec, hda_nid_t pin,
3105 hda_nid_t dac) 3088 hda_nid_t dac)
@@ -3118,34 +3101,56 @@ static bool add_new_out_path(struct hda_codec *codec, hda_nid_t pin,
3118 return false; 3101 return false;
3119} 3102}
3120 3103
3104/* get the path pointing from the given dac to pin;
3105 * passing 0 to either @pin or @dac behaves as a wildcard
3106 */
3107static struct nid_path *get_out_path(struct hda_codec *codec, hda_nid_t pin,
3108 hda_nid_t dac)
3109{
3110 struct alc_spec *spec = codec->spec;
3111 int i;
3112
3113 for (i = 0; i < spec->out_path.used; i++) {
3114 struct nid_path *path = snd_array_elem(&spec->out_path, i);
3115 if (path->depth <= 0)
3116 continue;
3117 if ((!dac || path->path[0] == dac) &&
3118 (!pin || path->path[path->depth - 1] == pin))
3119 return path;
3120 }
3121 return NULL;
3122}
3123
3121static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin, 3124static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
3122 hda_nid_t dac) 3125 hda_nid_t dac)
3123{ 3126{
3124 struct alc_spec *spec = codec->spec; 3127 struct nid_path *path = get_out_path(codec, pin, dac);
3125 hda_nid_t nid; 3128 hda_nid_t nid;
3126 unsigned int val; 3129 unsigned int val;
3127 int badness = 0; 3130 int badness = 0;
3128 3131
3129 nid = alc_look_for_out_vol_nid(codec, pin, dac); 3132 if (!path)
3133 return BAD_SHARED_VOL * 2;
3134 nid = alc_look_for_out_vol_nid(codec, path);
3130 if (nid) { 3135 if (nid) {
3131 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 3136 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3132 if (is_ctl_used(spec->vol_ctls, nid)) 3137 if (is_ctl_used(codec, val, NID_PATH_VOL_CTL))
3133 badness += BAD_SHARED_VOL; 3138 badness += BAD_SHARED_VOL;
3134 else 3139 else
3135 mark_ctl_usage(spec->vol_ctls, val); 3140 path->ctls[NID_PATH_VOL_CTL] = val;
3136 } else 3141 } else
3137 badness += BAD_SHARED_VOL; 3142 badness += BAD_SHARED_VOL;
3138 nid = alc_look_for_out_mute_nid(codec, pin, dac); 3143 nid = alc_look_for_out_mute_nid(codec, path);
3139 if (nid) { 3144 if (nid) {
3140 unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid)); 3145 unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
3141 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) 3146 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
3142 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 3147 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3143 else 3148 else
3144 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT); 3149 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
3145 if (is_ctl_used(spec->sw_ctls, val)) 3150 if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL))
3146 badness += BAD_SHARED_VOL; 3151 badness += BAD_SHARED_VOL;
3147 else 3152 else
3148 mark_ctl_usage(spec->sw_ctls, val); 3153 path->ctls[NID_PATH_MUTE_CTL] = val;
3149 } else 3154 } else
3150 badness += BAD_SHARED_VOL; 3155 badness += BAD_SHARED_VOL;
3151 return badness; 3156 return badness;
@@ -3279,7 +3284,6 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
3279 memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid)); 3284 memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
3280 spec->multi_ios = 0; 3285 spec->multi_ios = 0;
3281 snd_array_free(&spec->out_path); 3286 snd_array_free(&spec->out_path);
3282 clear_vol_marks(codec);
3283 badness = 0; 3287 badness = 0;
3284 3288
3285 /* fill hard-wired DACs first */ 3289 /* fill hard-wired DACs first */
@@ -3521,10 +3525,13 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3521 cfg->line_out_type, best_wired, best_mio); 3525 cfg->line_out_type, best_wired, best_mio);
3522 debug_show_configs(spec, cfg); 3526 debug_show_configs(spec, cfg);
3523 3527
3524 if (cfg->line_out_pins[0]) 3528 if (cfg->line_out_pins[0]) {
3525 spec->vmaster_nid = 3529 struct nid_path *path = get_out_path(codec,
3526 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], 3530 cfg->line_out_pins[0],
3527 spec->multiout.dac_nids[0]); 3531 spec->multiout.dac_nids[0]);
3532 if (path)
3533 spec->vmaster_nid = alc_look_for_out_vol_nid(codec, path);
3534 }
3528 3535
3529 /* clear the bitmap flags for creating controls */ 3536 /* clear the bitmap flags for creating controls */
3530 clear_vol_marks(codec); 3537 clear_vol_marks(codec);
@@ -3533,43 +3540,43 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3533} 3540}
3534 3541
3535static int alc_auto_add_vol_ctl(struct hda_codec *codec, 3542static int alc_auto_add_vol_ctl(struct hda_codec *codec,
3536 const char *pfx, int cidx, 3543 const char *pfx, int cidx,
3537 hda_nid_t nid, unsigned int chs) 3544 hda_nid_t nid, unsigned int chs,
3545 struct nid_path *path)
3538{ 3546{
3539 struct alc_spec *spec = codec->spec;
3540 unsigned int val; 3547 unsigned int val;
3541 if (!nid) 3548 if (!nid || !path)
3542 return 0; 3549 return 0;
3543 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); 3550 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
3544 if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */ 3551 if (is_ctl_used(codec, val, NID_PATH_VOL_CTL) && chs != 2) /* exclude LFE */
3545 return 0; 3552 return 0;
3546 mark_ctl_usage(spec->vol_ctls, val); 3553 path->ctls[NID_PATH_VOL_CTL] = val;
3547 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, 3554 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
3548 val); 3555 val);
3549} 3556}
3550 3557
3551static int alc_auto_add_stereo_vol(struct hda_codec *codec, 3558static int alc_auto_add_stereo_vol(struct hda_codec *codec,
3552 const char *pfx, int cidx, 3559 const char *pfx, int cidx,
3553 hda_nid_t nid) 3560 hda_nid_t nid, struct nid_path *path)
3554{ 3561{
3555 int chs = 1; 3562 int chs = 1;
3556 if (get_wcaps(codec, nid) & AC_WCAP_STEREO) 3563 if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
3557 chs = 3; 3564 chs = 3;
3558 return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs); 3565 return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs, path);
3559} 3566}
3560 3567
3561/* create a mute-switch for the given mixer widget; 3568/* create a mute-switch for the given mixer widget;
3562 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute 3569 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
3563 */ 3570 */
3564static int alc_auto_add_sw_ctl(struct hda_codec *codec, 3571static int alc_auto_add_sw_ctl(struct hda_codec *codec,
3565 const char *pfx, int cidx, 3572 const char *pfx, int cidx,
3566 hda_nid_t nid, unsigned int chs) 3573 hda_nid_t nid, unsigned int chs,
3574 struct nid_path *path)
3567{ 3575{
3568 struct alc_spec *spec = codec->spec;
3569 int wid_type; 3576 int wid_type;
3570 int type; 3577 int type;
3571 unsigned long val; 3578 unsigned long val;
3572 if (!nid) 3579 if (!nid || !path)
3573 return 0; 3580 return 0;
3574 wid_type = get_wcaps_type(get_wcaps(codec, nid)); 3581 wid_type = get_wcaps_type(get_wcaps(codec, nid));
3575 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) { 3582 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
@@ -3582,44 +3589,46 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
3582 type = ALC_CTL_BIND_MUTE; 3589 type = ALC_CTL_BIND_MUTE;
3583 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); 3590 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
3584 } 3591 }
3585 if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */ 3592 if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL) && chs != 2) /* exclude LFE */
3586 return 0; 3593 return 0;
3587 mark_ctl_usage(spec->sw_ctls, val); 3594 path->ctls[NID_PATH_MUTE_CTL] = val;
3588 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); 3595 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
3589} 3596}
3590 3597
3591static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx, 3598static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx,
3592 int cidx, hda_nid_t nid) 3599 int cidx, hda_nid_t nid,
3600 struct nid_path *path)
3593{ 3601{
3594 int chs = 1; 3602 int chs = 1;
3595 if (get_wcaps(codec, nid) & AC_WCAP_STEREO) 3603 if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
3596 chs = 3; 3604 chs = 3;
3597 return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs); 3605 return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs, path);
3598} 3606}
3599 3607
3600static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, 3608static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
3601 hda_nid_t pin, hda_nid_t dac) 3609 struct nid_path *path)
3602{ 3610{
3603 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac); 3611 int i;
3604 if (nid_has_mute(codec, pin, HDA_OUTPUT)) 3612
3605 return pin; 3613 for (i = path->depth - 1; i >= 0; i--) {
3606 else if (mix && nid_has_mute(codec, mix, HDA_INPUT)) 3614 if (nid_has_mute(codec, path->path[i], HDA_OUTPUT))
3607 return mix; 3615 return path->path[i];
3608 else if (nid_has_mute(codec, dac, HDA_OUTPUT)) 3616 if (i != path->depth - 1 && i != 0 &&
3609 return dac; 3617 nid_has_mute(codec, path->path[i], HDA_INPUT))
3618 return path->path[i];
3619 }
3610 return 0; 3620 return 0;
3611} 3621}
3612 3622
3613static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, 3623static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
3614 hda_nid_t pin, hda_nid_t dac) 3624 struct nid_path *path)
3615{ 3625{
3616 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac); 3626 int i;
3617 if (nid_has_volume(codec, dac, HDA_OUTPUT)) 3627
3618 return dac; 3628 for (i = path->depth - 1; i >= 0; i--) {
3619 else if (nid_has_volume(codec, mix, HDA_OUTPUT)) 3629 if (nid_has_volume(codec, path->path[i], HDA_OUTPUT))
3620 return mix; 3630 return path->path[i];
3621 else if (nid_has_volume(codec, pin, HDA_OUTPUT)) 3631 }
3622 return pin;
3623 return 0; 3632 return 0;
3624} 3633}
3625 3634
@@ -3639,6 +3648,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3639 int index; 3648 int index;
3640 hda_nid_t dac, pin; 3649 hda_nid_t dac, pin;
3641 hda_nid_t sw, vol; 3650 hda_nid_t sw, vol;
3651 struct nid_path *path;
3642 3652
3643 dac = spec->multiout.dac_nids[i]; 3653 dac = spec->multiout.dac_nids[i];
3644 if (!dac) 3654 if (!dac)
@@ -3652,27 +3662,36 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3652 name = alc_get_line_out_pfx(spec, i, true, &index); 3662 name = alc_get_line_out_pfx(spec, i, true, &index);
3653 } 3663 }
3654 3664
3655 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3665 path = get_out_path(codec, pin, dac);
3656 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3666 if (!path)
3667 continue;
3668 sw = alc_look_for_out_mute_nid(codec, path);
3669 vol = alc_look_for_out_vol_nid(codec, path);
3657 if (!name || !strcmp(name, "CLFE")) { 3670 if (!name || !strcmp(name, "CLFE")) {
3658 /* Center/LFE */ 3671 /* Center/LFE */
3659 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); 3672 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1,
3673 path);
3660 if (err < 0) 3674 if (err < 0)
3661 return err; 3675 return err;
3662 err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2); 3676 err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2,
3677 path);
3663 if (err < 0) 3678 if (err < 0)
3664 return err; 3679 return err;
3665 err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1); 3680 err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1,
3681 path);
3666 if (err < 0) 3682 if (err < 0)
3667 return err; 3683 return err;
3668 err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2); 3684 err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2,
3685 path);
3669 if (err < 0) 3686 if (err < 0)
3670 return err; 3687 return err;
3671 } else { 3688 } else {
3672 err = alc_auto_add_stereo_vol(codec, name, index, vol); 3689 err = alc_auto_add_stereo_vol(codec, name, index, vol,
3690 path);
3673 if (err < 0) 3691 if (err < 0)
3674 return err; 3692 return err;
3675 err = alc_auto_add_stereo_sw(codec, name, index, sw); 3693 err = alc_auto_add_stereo_sw(codec, name, index, sw,
3694 path);
3676 if (err < 0) 3695 if (err < 0)
3677 return err; 3696 return err;
3678 } 3697 }
@@ -3685,9 +3704,14 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3685 int cidx) 3704 int cidx)
3686{ 3705{
3687 struct alc_spec *spec = codec->spec; 3706 struct alc_spec *spec = codec->spec;
3707 struct nid_path *path;
3688 hda_nid_t sw, vol; 3708 hda_nid_t sw, vol;
3689 int err; 3709 int err;
3690 3710
3711 path = get_out_path(codec, pin, dac);
3712 if (!path)
3713 return 0;
3714
3691 if (!dac) { 3715 if (!dac) {
3692 unsigned int val; 3716 unsigned int val;
3693 /* the corresponding DAC is already occupied */ 3717 /* the corresponding DAC is already occupied */
@@ -3695,18 +3719,18 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3695 return 0; /* no way */ 3719 return 0; /* no way */
3696 /* create a switch only */ 3720 /* create a switch only */
3697 val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT); 3721 val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
3698 if (is_ctl_used(spec->sw_ctls, val)) 3722 if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL))
3699 return 0; /* already created */ 3723 return 0; /* already created */
3700 mark_ctl_usage(spec->sw_ctls, val); 3724 path->ctls[NID_PATH_MUTE_CTL] = val;
3701 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); 3725 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
3702 } 3726 }
3703 3727
3704 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3728 sw = alc_look_for_out_mute_nid(codec, path);
3705 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3729 vol = alc_look_for_out_vol_nid(codec, path);
3706 err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); 3730 err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol, path);
3707 if (err < 0) 3731 if (err < 0)
3708 return err; 3732 return err;
3709 err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); 3733 err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw, path);
3710 if (err < 0) 3734 if (err < 0)
3711 return err; 3735 return err;
3712 return 0; 3736 return 0;
@@ -3780,9 +3804,13 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3780 n = 0; 3804 n = 0;
3781 for (i = 0; i < num_pins; i++) { 3805 for (i = 0; i < num_pins; i++) {
3782 hda_nid_t vol; 3806 hda_nid_t vol;
3807 struct nid_path *path;
3783 if (!pins[i] || !dacs[i]) 3808 if (!pins[i] || !dacs[i])
3784 continue; 3809 continue;
3785 vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]); 3810 path = get_out_path(codec, pins[i], dacs[i]);
3811 if (!path)
3812 continue;
3813 vol = alc_look_for_out_vol_nid(codec, path);
3786 if (vol) 3814 if (vol)
3787 ctl->values[n++] = 3815 ctl->values[n++] =
3788 HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT); 3816 HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
@@ -3821,6 +3849,7 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
3821 int i, num; 3849 int i, num;
3822 hda_nid_t nid, mix = 0; 3850 hda_nid_t nid, mix = 0;
3823 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 3851 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
3852 struct nid_path *path;
3824 3853
3825 alc_set_pin_output(codec, pin, pin_type); 3854 alc_set_pin_output(codec, pin, pin_type);
3826 nid = alc_go_down_to_selector(codec, pin); 3855 nid = alc_go_down_to_selector(codec, pin);
@@ -3845,13 +3874,16 @@ static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
3845 AMP_IN_UNMUTE(1)); 3874 AMP_IN_UNMUTE(1));
3846 } 3875 }
3847 /* initialize volume */ 3876 /* initialize volume */
3848 nid = alc_look_for_out_vol_nid(codec, pin, dac); 3877 path = get_out_path(codec, pin, dac);
3878 if (!path)
3879 return;
3880 nid = alc_look_for_out_vol_nid(codec, path);
3849 if (nid) 3881 if (nid)
3850 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3882 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3851 AMP_OUT_ZERO); 3883 AMP_OUT_ZERO);
3852 3884
3853 /* unmute DAC if it's not assigned to a mixer */ 3885 /* unmute DAC if it's not assigned to a mixer */
3854 nid = alc_look_for_out_mute_nid(codec, pin, dac); 3886 nid = alc_look_for_out_mute_nid(codec, path);
3855 if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT)) 3887 if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT))
3856 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3888 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3857 AMP_OUT_ZERO); 3889 AMP_OUT_ZERO);