Patchwork [12.04] ALSA: HDA: Realtek: Take vmaster dac from multiout dac list

login
register
mail settings
Submitter David Henningsson
Date April 5, 2012, 11:56 a.m.
Message ID <1333626988-11129-1-git-send-email-david.henningsson@canonical.com>
Download mbox | patch
Permalink /patch/150941/
State New
Headers show

Comments

David Henningsson - April 5, 2012, 11:56 a.m.
With the auto-parser we can choose the dac nid for vmaster from
the DACs we already know, instead of hard-coding it. This is more
future-proof and was actually wrong on one machine.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
(backported from commit fde48a1f808e2bb6aaad5709d2470d814a157c86
Conflicts:
	sound/pci/hda/patch_realtek.c)

BugLink: https://bugs.launchpad.net/bugs/974090
---

After a quick chat with apw, I hope this patch can be committed. Feel free to
grab me on IRC if you have more questions - I know I'm late, sorry for that.
I wrote the patch a while back, but it did not make it into 3.2 (it is 
in 3.3).

It fixes a volume slider problem for a machine we want to certify.
It has been tested on the actual hardware, and I've done a regression test
on one Realtek machine I have here.
Should you wish to do more regression tests, there is a ready-made DKMS package
here:
http://people.canonical.com/~diwic/temp/alsa-hda-dkms-vmaster-realtek_0.1_all.deb

 sound/pci/hda/patch_realtek.c |   42 ++++++++++++++++++----------------------
 1 files changed, 19 insertions(+), 23 deletions(-)
Leann Ogasawara - April 5, 2012, 1:32 p.m.
On Thu, 2012-04-05 at 13:56 +0200, David Henningsson wrote:
> With the auto-parser we can choose the dac nid for vmaster from
> the DACs we already know, instead of hard-coding it. This is more
> future-proof and was actually wrong on one machine.
> 
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> (backported from commit fde48a1f808e2bb6aaad5709d2470d814a157c86
> Conflicts:
> 	sound/pci/hda/patch_realtek.c)
> 
> BugLink: https://bugs.launchpad.net/bugs/974090

Patch is upstream and tested.

Acked-by: Leann Ogasawara <leann.ogasawara@canonical.com>

> ---
> 
> After a quick chat with apw, I hope this patch can be committed. Feel free to
> grab me on IRC if you have more questions - I know I'm late, sorry for that.
> I wrote the patch a while back, but it did not make it into 3.2 (it is 
> in 3.3).
> 
> It fixes a volume slider problem for a machine we want to certify.
> It has been tested on the actual hardware, and I've done a regression test
> on one Realtek machine I have here.
> Should you wish to do more regression tests, there is a ready-made DKMS package
> here:
> http://people.canonical.com/~diwic/temp/alsa-hda-dkms-vmaster-realtek_0.1_all.deb
> 
>  sound/pci/hda/patch_realtek.c |   42 ++++++++++++++++++----------------------
>  1 files changed, 19 insertions(+), 23 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 13fa5f2..91e767a 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -2937,6 +2937,8 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
>  
>  static int alc_auto_fill_multi_ios(struct hda_codec *codec,
>  				   unsigned int location);
> +static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
> +					  hda_nid_t pin, hda_nid_t dac);
>  
>  /* fill in the dac_nids table from the parsed pin configuration */
>  static int alc_auto_fill_dac_nids(struct hda_codec *codec)
> @@ -3037,6 +3039,11 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
>  		}
>  	}
>  
> +	if (cfg->line_out_pins[0])
> +		spec->vmaster_nid =
> +			alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
> +						 spec->multiout.dac_nids[0]);
> +
>  	return 0;
>  }
>  
> @@ -4000,8 +4007,10 @@ static int patch_alc880(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
> +		spec->vmaster_nid = 0x0c;
>  		setup_preset(codec, &alc880_presets[board_config]);
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4019,8 +4028,6 @@ static int patch_alc880(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4129,8 +4136,10 @@ static int patch_alc260(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc260_presets[board_config]);
> +		spec->vmaster_nid = 0x08;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4150,8 +4159,6 @@ static int patch_alc260(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x08;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4354,8 +4361,10 @@ static int patch_alc882(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc882_presets[board_config]);
> +		spec->vmaster_nid = 0x0c;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4375,8 +4384,6 @@ static int patch_alc882(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4509,8 +4516,10 @@ static int patch_alc262(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc262_presets[board_config]);
> +		spec->vmaster_nid = 0x0c;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4530,8 +4539,6 @@ static int patch_alc262(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4643,8 +4650,6 @@ static int patch_alc268(struct hda_codec *codec)
>  	if (!spec->no_analog && !spec->cap_mixer)
>  		set_capture_mixer(codec);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	spec->init_hook = alc_auto_init_std;
>  	spec->shutup = alc_eapd_shutup;
> @@ -5200,8 +5205,6 @@ static int patch_alc269(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  #ifdef CONFIG_PM
>  	codec->patch_ops.resume = alc269_resume;
> @@ -5331,8 +5334,6 @@ static int patch_alc861(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x03;
> -
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
>  	codec->patch_ops = alc_patch_ops;
> @@ -5457,8 +5458,6 @@ static int patch_alc861vd(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
>  	codec->patch_ops = alc_patch_ops;
> @@ -5841,7 +5840,6 @@ static int patch_alc662(struct hda_codec *codec)
>  			break;
>  		}
>  	}
> -	spec->vmaster_nid = 0x02;
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> @@ -5895,8 +5893,6 @@ static int patch_alc680(struct hda_codec *codec)
>  	if (!spec->no_analog && !spec->cap_mixer)
>  		set_capture_mixer(codec);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	spec->init_hook = alc_auto_init_std;
>  
> -- 
> 1.7.9.1
> 
>
Seth Forshee - April 5, 2012, 1:45 p.m.
On Thu, Apr 05, 2012 at 01:56:28PM +0200, David Henningsson wrote:
> With the auto-parser we can choose the dac nid for vmaster from
> the DACs we already know, instead of hard-coding it. This is more
> future-proof and was actually wrong on one machine.
> 
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> (backported from commit fde48a1f808e2bb6aaad5709d2470d814a157c86
> Conflicts:
> 	sound/pci/hda/patch_realtek.c)
> 
> BugLink: https://bugs.launchpad.net/bugs/974090
> ---
> 
> After a quick chat with apw, I hope this patch can be committed. Feel free to
> grab me on IRC if you have more questions - I know I'm late, sorry for that.
> I wrote the patch a while back, but it did not make it into 3.2 (it is 
> in 3.3).
> 
> It fixes a volume slider problem for a machine we want to certify.
> It has been tested on the actual hardware, and I've done a regression test
> on one Realtek machine I have here.
> Should you wish to do more regression tests, there is a ready-made DKMS package
> here:
> http://people.canonical.com/~diwic/temp/alsa-hda-dkms-vmaster-realtek_0.1_all.deb
> 
>  sound/pci/hda/patch_realtek.c |   42 ++++++++++++++++++----------------------
>  1 files changed, 19 insertions(+), 23 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 13fa5f2..91e767a 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -2937,6 +2937,8 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
>  
>  static int alc_auto_fill_multi_ios(struct hda_codec *codec,
>  				   unsigned int location);
> +static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
> +					  hda_nid_t pin, hda_nid_t dac);
>  
>  /* fill in the dac_nids table from the parsed pin configuration */
>  static int alc_auto_fill_dac_nids(struct hda_codec *codec)
> @@ -3037,6 +3039,11 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
>  		}
>  	}
>  
> +	if (cfg->line_out_pins[0])
> +		spec->vmaster_nid =
> +			alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
> +						 spec->multiout.dac_nids[0]);
> +
>  	return 0;
>  }
>  
> @@ -4000,8 +4007,10 @@ static int patch_alc880(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
> +		spec->vmaster_nid = 0x0c;
>  		setup_preset(codec, &alc880_presets[board_config]);
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4019,8 +4028,6 @@ static int patch_alc880(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4129,8 +4136,10 @@ static int patch_alc260(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc260_presets[board_config]);
> +		spec->vmaster_nid = 0x08;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4150,8 +4159,6 @@ static int patch_alc260(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x08;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4354,8 +4361,10 @@ static int patch_alc882(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc882_presets[board_config]);
> +		spec->vmaster_nid = 0x0c;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4375,8 +4384,6 @@ static int patch_alc882(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4509,8 +4516,10 @@ static int patch_alc262(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc262_presets[board_config]);
> +		spec->vmaster_nid = 0x0c;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4530,8 +4539,6 @@ static int patch_alc262(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4643,8 +4650,6 @@ static int patch_alc268(struct hda_codec *codec)
>  	if (!spec->no_analog && !spec->cap_mixer)
>  		set_capture_mixer(codec);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	spec->init_hook = alc_auto_init_std;
>  	spec->shutup = alc_eapd_shutup;
> @@ -5200,8 +5205,6 @@ static int patch_alc269(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  #ifdef CONFIG_PM
>  	codec->patch_ops.resume = alc269_resume;
> @@ -5331,8 +5334,6 @@ static int patch_alc861(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x03;
> -
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
>  	codec->patch_ops = alc_patch_ops;
> @@ -5457,8 +5458,6 @@ static int patch_alc861vd(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
>  	codec->patch_ops = alc_patch_ops;
> @@ -5841,7 +5840,6 @@ static int patch_alc662(struct hda_codec *codec)
>  			break;
>  		}
>  	}
> -	spec->vmaster_nid = 0x02;
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> @@ -5895,8 +5893,6 @@ static int patch_alc680(struct hda_codec *codec)
>  	if (!spec->no_analog && !spec->cap_mixer)
>  		set_capture_mixer(codec);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	spec->init_hook = alc_auto_init_std;
>  
> -- 
> 1.7.9.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Leann Ogasawara - April 5, 2012, 3:05 p.m.
Applied to Precise master-next.

Thanks,
Leann

On Thu, 2012-04-05 at 13:56 +0200, David Henningsson wrote:
> With the auto-parser we can choose the dac nid for vmaster from
> the DACs we already know, instead of hard-coding it. This is more
> future-proof and was actually wrong on one machine.
> 
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> (backported from commit fde48a1f808e2bb6aaad5709d2470d814a157c86
> Conflicts:
> 	sound/pci/hda/patch_realtek.c)
> 
> BugLink: https://bugs.launchpad.net/bugs/974090
> ---
> 
> After a quick chat with apw, I hope this patch can be committed. Feel free to
> grab me on IRC if you have more questions - I know I'm late, sorry for that.
> I wrote the patch a while back, but it did not make it into 3.2 (it is 
> in 3.3).
> 
> It fixes a volume slider problem for a machine we want to certify.
> It has been tested on the actual hardware, and I've done a regression test
> on one Realtek machine I have here.
> Should you wish to do more regression tests, there is a ready-made DKMS package
> here:
> http://people.canonical.com/~diwic/temp/alsa-hda-dkms-vmaster-realtek_0.1_all.deb
> 
>  sound/pci/hda/patch_realtek.c |   42 ++++++++++++++++++----------------------
>  1 files changed, 19 insertions(+), 23 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 13fa5f2..91e767a 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -2937,6 +2937,8 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
>  
>  static int alc_auto_fill_multi_ios(struct hda_codec *codec,
>  				   unsigned int location);
> +static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
> +					  hda_nid_t pin, hda_nid_t dac);
>  
>  /* fill in the dac_nids table from the parsed pin configuration */
>  static int alc_auto_fill_dac_nids(struct hda_codec *codec)
> @@ -3037,6 +3039,11 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
>  		}
>  	}
>  
> +	if (cfg->line_out_pins[0])
> +		spec->vmaster_nid =
> +			alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
> +						 spec->multiout.dac_nids[0]);
> +
>  	return 0;
>  }
>  
> @@ -4000,8 +4007,10 @@ static int patch_alc880(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
> +		spec->vmaster_nid = 0x0c;
>  		setup_preset(codec, &alc880_presets[board_config]);
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4019,8 +4028,6 @@ static int patch_alc880(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4129,8 +4136,10 @@ static int patch_alc260(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc260_presets[board_config]);
> +		spec->vmaster_nid = 0x08;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4150,8 +4159,6 @@ static int patch_alc260(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x08;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4354,8 +4361,10 @@ static int patch_alc882(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc882_presets[board_config]);
> +		spec->vmaster_nid = 0x0c;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4375,8 +4384,6 @@ static int patch_alc882(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4509,8 +4516,10 @@ static int patch_alc262(struct hda_codec *codec)
>  #endif
>  	}
>  
> -	if (board_config != ALC_MODEL_AUTO)
> +	if (board_config != ALC_MODEL_AUTO) {
>  		setup_preset(codec, &alc262_presets[board_config]);
> +		spec->vmaster_nid = 0x0c;
> +	}
>  
>  	if (!spec->no_analog && !spec->adc_nids) {
>  		alc_auto_fill_adc_caps(codec);
> @@ -4530,8 +4539,6 @@ static int patch_alc262(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x0c;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	if (board_config == ALC_MODEL_AUTO)
>  		spec->init_hook = alc_auto_init_std;
> @@ -4643,8 +4650,6 @@ static int patch_alc268(struct hda_codec *codec)
>  	if (!spec->no_analog && !spec->cap_mixer)
>  		set_capture_mixer(codec);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	spec->init_hook = alc_auto_init_std;
>  	spec->shutup = alc_eapd_shutup;
> @@ -5200,8 +5205,6 @@ static int patch_alc269(struct hda_codec *codec)
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  #ifdef CONFIG_PM
>  	codec->patch_ops.resume = alc269_resume;
> @@ -5331,8 +5334,6 @@ static int patch_alc861(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x03;
> -
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
>  	codec->patch_ops = alc_patch_ops;
> @@ -5457,8 +5458,6 @@ static int patch_alc861vd(struct hda_codec *codec)
>  		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
>  	}
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
>  	codec->patch_ops = alc_patch_ops;
> @@ -5841,7 +5840,6 @@ static int patch_alc662(struct hda_codec *codec)
>  			break;
>  		}
>  	}
> -	spec->vmaster_nid = 0x02;
>  
>  	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
>  
> @@ -5895,8 +5893,6 @@ static int patch_alc680(struct hda_codec *codec)
>  	if (!spec->no_analog && !spec->cap_mixer)
>  		set_capture_mixer(codec);
>  
> -	spec->vmaster_nid = 0x02;
> -
>  	codec->patch_ops = alc_patch_ops;
>  	spec->init_hook = alc_auto_init_std;
>  
> -- 
> 1.7.9.1
> 
>

Patch

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 13fa5f2..91e767a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2937,6 +2937,8 @@  static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
 
 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
 				   unsigned int location);
+static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
+					  hda_nid_t pin, hda_nid_t dac);
 
 /* fill in the dac_nids table from the parsed pin configuration */
 static int alc_auto_fill_dac_nids(struct hda_codec *codec)
@@ -3037,6 +3039,11 @@  static int alc_auto_fill_dac_nids(struct hda_codec *codec)
 		}
 	}
 
+	if (cfg->line_out_pins[0])
+		spec->vmaster_nid =
+			alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
+						 spec->multiout.dac_nids[0]);
+
 	return 0;
 }
 
@@ -4000,8 +4007,10 @@  static int patch_alc880(struct hda_codec *codec)
 #endif
 	}
 
-	if (board_config != ALC_MODEL_AUTO)
+	if (board_config != ALC_MODEL_AUTO) {
+		spec->vmaster_nid = 0x0c;
 		setup_preset(codec, &alc880_presets[board_config]);
+	}
 
 	if (!spec->no_analog && !spec->adc_nids) {
 		alc_auto_fill_adc_caps(codec);
@@ -4019,8 +4028,6 @@  static int patch_alc880(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 	}
 
-	spec->vmaster_nid = 0x0c;
-
 	codec->patch_ops = alc_patch_ops;
 	if (board_config == ALC_MODEL_AUTO)
 		spec->init_hook = alc_auto_init_std;
@@ -4129,8 +4136,10 @@  static int patch_alc260(struct hda_codec *codec)
 #endif
 	}
 
-	if (board_config != ALC_MODEL_AUTO)
+	if (board_config != ALC_MODEL_AUTO) {
 		setup_preset(codec, &alc260_presets[board_config]);
+		spec->vmaster_nid = 0x08;
+	}
 
 	if (!spec->no_analog && !spec->adc_nids) {
 		alc_auto_fill_adc_caps(codec);
@@ -4150,8 +4159,6 @@  static int patch_alc260(struct hda_codec *codec)
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
-	spec->vmaster_nid = 0x08;
-
 	codec->patch_ops = alc_patch_ops;
 	if (board_config == ALC_MODEL_AUTO)
 		spec->init_hook = alc_auto_init_std;
@@ -4354,8 +4361,10 @@  static int patch_alc882(struct hda_codec *codec)
 #endif
 	}
 
-	if (board_config != ALC_MODEL_AUTO)
+	if (board_config != ALC_MODEL_AUTO) {
 		setup_preset(codec, &alc882_presets[board_config]);
+		spec->vmaster_nid = 0x0c;
+	}
 
 	if (!spec->no_analog && !spec->adc_nids) {
 		alc_auto_fill_adc_caps(codec);
@@ -4375,8 +4384,6 @@  static int patch_alc882(struct hda_codec *codec)
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
-	spec->vmaster_nid = 0x0c;
-
 	codec->patch_ops = alc_patch_ops;
 	if (board_config == ALC_MODEL_AUTO)
 		spec->init_hook = alc_auto_init_std;
@@ -4509,8 +4516,10 @@  static int patch_alc262(struct hda_codec *codec)
 #endif
 	}
 
-	if (board_config != ALC_MODEL_AUTO)
+	if (board_config != ALC_MODEL_AUTO) {
 		setup_preset(codec, &alc262_presets[board_config]);
+		spec->vmaster_nid = 0x0c;
+	}
 
 	if (!spec->no_analog && !spec->adc_nids) {
 		alc_auto_fill_adc_caps(codec);
@@ -4530,8 +4539,6 @@  static int patch_alc262(struct hda_codec *codec)
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
-	spec->vmaster_nid = 0x0c;
-
 	codec->patch_ops = alc_patch_ops;
 	if (board_config == ALC_MODEL_AUTO)
 		spec->init_hook = alc_auto_init_std;
@@ -4643,8 +4650,6 @@  static int patch_alc268(struct hda_codec *codec)
 	if (!spec->no_analog && !spec->cap_mixer)
 		set_capture_mixer(codec);
 
-	spec->vmaster_nid = 0x02;
-
 	codec->patch_ops = alc_patch_ops;
 	spec->init_hook = alc_auto_init_std;
 	spec->shutup = alc_eapd_shutup;
@@ -5200,8 +5205,6 @@  static int patch_alc269(struct hda_codec *codec)
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
-	spec->vmaster_nid = 0x02;
-
 	codec->patch_ops = alc_patch_ops;
 #ifdef CONFIG_PM
 	codec->patch_ops.resume = alc269_resume;
@@ -5331,8 +5334,6 @@  static int patch_alc861(struct hda_codec *codec)
 		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
 	}
 
-	spec->vmaster_nid = 0x03;
-
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	codec->patch_ops = alc_patch_ops;
@@ -5457,8 +5458,6 @@  static int patch_alc861vd(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 	}
 
-	spec->vmaster_nid = 0x02;
-
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	codec->patch_ops = alc_patch_ops;
@@ -5841,7 +5840,6 @@  static int patch_alc662(struct hda_codec *codec)
 			break;
 		}
 	}
-	spec->vmaster_nid = 0x02;
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
@@ -5895,8 +5893,6 @@  static int patch_alc680(struct hda_codec *codec)
 	if (!spec->no_analog && !spec->cap_mixer)
 		set_capture_mixer(codec);
 
-	spec->vmaster_nid = 0x02;
-
 	codec->patch_ops = alc_patch_ops;
 	spec->init_hook = alc_auto_init_std;