From cb053a8265954518d4c9e865d8a0d682405825d2 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Mon, 27 Jun 2011 11:32:07 +0200
Subject: [PATCH] ALSA: hda - Call proper DAC-filler function for Realtek auto-parser
Git-commit: cb053a8265954518d4c9e865d8a0d682405825d2
Patch-mainline: 3.1-rc2
Refernces: FATE#314106,FATE#314311,FATE#313695

In alc_auto_add_multi_channel_mode(), when the primary HP workaround
is enabled, it re-initializes the DAC list but calls alc662's function
in a fixed way.  This isn't pretty suitable for other codecs, of course.

Now we call it with fill_dac function pointer so that the proper
function can be called at that point.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/pci/hda/patch_realtek.c |   42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5353,9 +5353,10 @@ static int add_control_with_pfx(struct a
 #define ALC880_PIN_CD_NID		0x1c
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
-				     const struct auto_pin_cfg *cfg)
+static int alc880_auto_fill_dac_nids(struct hda_codec *codec)
 {
+	struct alc_spec *spec = codec->spec;
+	const struct auto_pin_cfg *cfg = &spec->autocfg;
 	hda_nid_t nid;
 	int assigned[4];
 	int i, j;
@@ -5729,7 +5730,8 @@ static void alc880_auto_init_input_src(s
 	}
 }
 
-static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
+static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
+					   int (*fill_dac)(struct hda_codec *));
 
 /* parse the BIOS configuration and set up the alc_spec */
 /* return 1 if successful, 0 if the proper config is not found,
@@ -5748,10 +5750,10 @@ static int alc880_parse_auto_config(stru
 	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+	err = alc880_auto_fill_dac_nids(codec);
 	if (err < 0)
 		return err;
-	err = alc_auto_add_multi_channel_mode(codec);
+	err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
 	if (err < 0)
 		return err;
 	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
@@ -11188,10 +11190,10 @@ static int alc882_parse_auto_config(stru
 	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+	err = alc880_auto_fill_dac_nids(codec);
 	if (err < 0)
 		return err;
-	err = alc_auto_add_multi_channel_mode(codec);
+	err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
 	if (err < 0)
 		return err;
 	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
@@ -15882,10 +15884,10 @@ static hda_nid_t alc861_look_for_dac(str
 }
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
-				     const struct auto_pin_cfg *cfg)
+static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
+	const struct auto_pin_cfg *cfg = &spec->autocfg;
 	int i;
 	hda_nid_t nid, dac;
 
@@ -16050,10 +16052,10 @@ static int alc861_parse_auto_config(stru
 	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
+	err = alc861_auto_fill_dac_nids(codec);
 	if (err < 0)
 		return err;
-	err = alc_auto_add_multi_channel_mode(codec);
+	err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
 	if (err < 0)
 		return err;
 	err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
@@ -17125,10 +17127,10 @@ static int alc861vd_parse_auto_config(st
 	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+	err = alc880_auto_fill_dac_nids(codec);
 	if (err < 0)
 		return err;
-	err = alc_auto_add_multi_channel_mode(codec);
+	err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
 	if (err < 0)
 		return err;
 	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
@@ -18798,10 +18800,10 @@ static hda_nid_t alc_auto_look_for_dac(s
 }
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
-				     const struct auto_pin_cfg *cfg)
+static int alc662_auto_fill_dac_nids(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
+	const struct auto_pin_cfg *cfg = &spec->autocfg;
 	int i;
 	hda_nid_t dac;
 
@@ -19107,7 +19109,8 @@ static const struct snd_kcontrol_new alc
 	.put = alc_auto_ch_mode_put,
 };
 
-static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
+static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
+					   int (*fill_dac)(struct hda_codec *))
 {
 	struct alc_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -19124,7 +19127,8 @@ static int alc_auto_add_multi_channel_mo
 		cfg->hp_outs = 0;
 		memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
 		cfg->line_out_type = AUTO_PIN_HP_OUT;
-		alc662_auto_fill_dac_nids(codec, cfg);
+		if (fill_dac)
+			fill_dac(codec);
 	}
 	if (cfg->line_outs != 1 ||
 	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
@@ -19165,10 +19169,10 @@ static int alc662_parse_auto_config(stru
 	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
+	err = alc662_auto_fill_dac_nids(codec);
 	if (err < 0)
 		return err;
-	err = alc_auto_add_multi_channel_mode(codec);
+	err = alc_auto_add_multi_channel_mode(codec, alc662_auto_fill_dac_nids);
 	if (err < 0)
 		return err;
 	err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
