Merge branch 'test/hda-vol-ofs' into next/hda
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 64eb110..75914bc 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -352,5 +352,4 @@
 
 STAC9872
 ========
-  vaio		Setup for VAIO FE550G/SZ110
-  vaio-ar Setup for VAIO AR
+  N/A
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0cf2424..a259b3e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2642,7 +2642,7 @@
 		int dev;
 
 		if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
-			return 0; /* no substreams assigned */
+			continue; /* no substreams assigned */
 
 		if (!cpcm->pcm) {
 			dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
@@ -3419,10 +3419,20 @@
 			cfg->input_pins[AUTO_PIN_AUX] = nid;
 			break;
 		case AC_JACK_SPDIF_OUT:
+		case AC_JACK_DIG_OTHER_OUT:
 			cfg->dig_out_pin = nid;
+			if (loc == AC_JACK_LOC_HDMI)
+				cfg->dig_out_type = HDA_PCM_TYPE_HDMI;
+			else
+				cfg->dig_out_type = HDA_PCM_TYPE_SPDIF;
 			break;
 		case AC_JACK_SPDIF_IN:
+		case AC_JACK_DIG_OTHER_IN:
 			cfg->dig_in_pin = nid;
+			if (loc == AC_JACK_LOC_HDMI)
+				cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
+			else
+				cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
 			break;
 		}
 	}
@@ -3528,6 +3538,8 @@
 		   cfg->hp_pins[1], cfg->hp_pins[2],
 		   cfg->hp_pins[3], cfg->hp_pins[4]);
 	snd_printd("   mono: mono_out=0x%x\n", cfg->mono_out_pin);
+	if (cfg->dig_out_pin)
+		snd_printd("   dig-out=0x%x\n", cfg->dig_out_pin);
 	snd_printd("   inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
 		   " cd=0x%x, aux=0x%x\n",
 		   cfg->input_pins[AUTO_PIN_MIC],
@@ -3536,6 +3548,8 @@
 		   cfg->input_pins[AUTO_PIN_FRONT_LINE],
 		   cfg->input_pins[AUTO_PIN_CD],
 		   cfg->input_pins[AUTO_PIN_AUX]);
+	if (cfg->dig_out_pin)
+		snd_printd("   dig-in=0x%x\n", cfg->dig_in_pin);
 
 	return 0;
 }
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index d53ce1f..ec687b2 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -357,6 +357,8 @@
 	hda_nid_t dig_out_pin;
 	hda_nid_t dig_in_pin;
 	hda_nid_t mono_out_pin;
+	int dig_out_type; /* HDA_PCM_TYPE_XXX */
+	int dig_in_type; /* HDA_PCM_TYPE_XXX */
 };
 
 #define get_defcfg_connect(cfg) \
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 5d249a5..4cfa78c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -269,6 +269,7 @@
 					 * dig_out_nid and hp_nid are optional
 					 */
 	hda_nid_t alt_dac_nid;
+	int dig_out_type;
 
 	/* capture */
 	unsigned int num_adc_nids;
@@ -305,6 +306,9 @@
 	unsigned int jack_present: 1;
 	unsigned int master_sw: 1;
 
+	/* other flags */
+	unsigned int no_analog :1; /* digital I/O only */
+
 	/* for virtual master */
 	hda_nid_t vmaster_nid;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -2018,11 +2022,13 @@
 						    spec->multiout.dig_out_nid);
 		if (err < 0)
 			return err;
-		err = snd_hda_create_spdif_share_sw(codec,
-						    &spec->multiout);
-		if (err < 0)
-			return err;
-		spec->multiout.share_spdif = 1;
+		if (!spec->no_analog) {
+			err = snd_hda_create_spdif_share_sw(codec,
+							    &spec->multiout);
+			if (err < 0)
+				return err;
+			spec->multiout.share_spdif = 1;
+		}
 	}
 	if (spec->dig_in_nid) {
 		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -2031,7 +2037,8 @@
 	}
 
 	/* if we have no master control, let's create it */
-	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
+	if (!spec->no_analog &&
+	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
 		unsigned int vmaster_tlv[4];
 		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
 					HDA_OUTPUT, vmaster_tlv);
@@ -2040,7 +2047,8 @@
 		if (err < 0)
 			return err;
 	}
-	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
+	if (!spec->no_analog &&
+	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
 					  NULL, alc_slave_sws);
 		if (err < 0)
@@ -3059,6 +3067,9 @@
 	codec->num_pcms = 1;
 	codec->pcm_info = info;
 
+	if (spec->no_analog)
+		goto skip_analog;
+
 	info->name = spec->stream_name_analog;
 	if (spec->stream_analog_playback) {
 		if (snd_BUG_ON(!spec->multiout.dac_nids))
@@ -3082,12 +3093,16 @@
 		}
 	}
 
+ skip_analog:
 	/* SPDIF for stream index #1 */
 	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
 		codec->num_pcms = 2;
 		info = spec->pcm_rec + 1;
 		info->name = spec->stream_name_digital;
-		info->pcm_type = HDA_PCM_TYPE_SPDIF;
+		if (spec->dig_out_type)
+			info->pcm_type = spec->dig_out_type;
+		else
+			info->pcm_type = HDA_PCM_TYPE_SPDIF;
 		if (spec->multiout.dig_out_nid &&
 		    spec->stream_digital_playback) {
 			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
@@ -3102,6 +3117,9 @@
 		codec->spdif_status_reset = 1;
 	}
 
+	if (spec->no_analog)
+		return 0;
+
 	/* If the use of more than one ADC is requested for the current
 	 * model, configure a second analog capture-only PCM.
 	 */
@@ -10464,8 +10482,14 @@
 					   alc262_ignore);
 	if (err < 0)
 		return err;
-	if (!spec->autocfg.line_outs)
+	if (!spec->autocfg.line_outs) {
+		if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
+			spec->multiout.max_channels = 2;
+			spec->no_analog = 1;
+			goto dig_only;
+		}
 		return 0; /* can't find valid BIOS pin config */
+	}
 	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
 	if (err < 0)
 		return err;
@@ -10475,8 +10499,11 @@
 
 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
 
-	if (spec->autocfg.dig_out_pin)
+ dig_only:
+	if (spec->autocfg.dig_out_pin) {
 		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
+		spec->dig_out_type = spec->autocfg.dig_out_type;
+	}
 	if (spec->autocfg.dig_in_pin)
 		spec->dig_in_nid = ALC262_DIGIN_NID;
 
@@ -10871,7 +10898,7 @@
 			spec->capsrc_nids = alc262_capsrc_nids;
 		}
 	}
-	if (!spec->cap_mixer)
+	if (!spec->cap_mixer && !spec->no_analog)
 		set_capture_mixer(spec);
 
 	spec->vmaster_nid = 0x0c;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c2d4abe..0fa6c59 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -844,10 +844,6 @@
 };
 
 static struct hda_verb stac92hd83xxx_core_init[] = {
-	/* start of config #1 */
-	{ 0xe, AC_VERB_SET_CONNECT_SEL, 0x3},
-
-	/* start of config #2 */
 	{ 0xa, AC_VERB_SET_CONNECT_SEL, 0x0},
 	{ 0xb, AC_VERB_SET_CONNECT_SEL, 0x0},
 	{ 0xd, AC_VERB_SET_CONNECT_SEL, 0x1},
@@ -2558,7 +2554,7 @@
 		codec->num_pcms++;
 		info++;
 		info->name = "STAC92xx Digital";
-		info->pcm_type = HDA_PCM_TYPE_SPDIF;
+		info->pcm_type = spec->autocfg.dig_out_type;
 		if (spec->multiout.dig_out_nid) {
 			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
 			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
@@ -4779,7 +4775,9 @@
 static int patch_stac92hd83xxx(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec;
+	hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
 	int err;
+	int num_dacs;
 
 	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -4798,13 +4796,21 @@
 	spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
 	spec->multiout.dac_nids = spec->dac_nids;
 
+
+	/* set port 0xe to select the last DAC
+	 */
+	num_dacs = snd_hda_get_connections(codec, 0x0e,
+		conn, STAC92HD83_DAC_COUNT + 1) - 1;
+
+	snd_hda_codec_write_cache(codec, 0xe, 0,
+		AC_VERB_SET_CONNECT_SEL, num_dacs);
+
 	spec->init = stac92hd83xxx_core_init;
 	switch (codec->vendor_id) {
 	case 0x111d7605:
 		break;
 	default:
 		spec->num_pwrs--;
-		spec->init++; /* switch to config #2 */
 	}
 
 	spec->mixer = stac92hd83xxx_mixer;
@@ -5370,223 +5376,65 @@
  * STAC9872 hack
  */
 
-/* static config for Sony VAIO FE550G and Sony VAIO AR */
-static hda_nid_t vaio_dacs[] = { 0x2 };
-#define VAIO_HP_DAC	0x5
-static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
-static hda_nid_t vaio_mux_nids[] = { 0x15 };
-
-static struct hda_input_mux vaio_mux = {
-	.num_items = 3,
-	.items = {
-		/* { "HP", 0x0 }, */
-		{ "Mic Jack", 0x1 },
-		{ "Internal Mic", 0x2 },
-		{ "PCM", 0x3 },
-	}
-};
-
-static struct hda_verb vaio_init[] = {
-	{0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
-	{0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
-	{0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
-	{0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
+static struct hda_verb stac9872_core_init[] = {
 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
-	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
 	{}
 };
 
-static struct hda_verb vaio_ar_init[] = {
-	{0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
-	{0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
-	{0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
-/*	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */
-	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */
-/*	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */
-	{}
-};
-
-static struct snd_kcontrol_new vaio_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
-	/* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
+static struct snd_kcontrol_new stac9872_mixer[] = {
 	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Source",
-		.count = 1,
-		.info = stac92xx_mux_enum_info,
-		.get = stac92xx_mux_enum_get,
-		.put = stac92xx_mux_enum_put,
-	},
-	{}
+	STAC_INPUT_SOURCE(1),
+	{ } /* end */
 };
 
-static struct snd_kcontrol_new vaio_ar_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
-	/* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
-	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
-	/*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Source",
-		.count = 1,
-		.info = stac92xx_mux_enum_info,
-		.get = stac92xx_mux_enum_get,
-		.put = stac92xx_mux_enum_put,
-	},
-	{}
+static hda_nid_t stac9872_pin_nids[] = {
+	0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+	0x11, 0x13, 0x14,
 };
 
-static struct hda_codec_ops stac9872_patch_ops = {
-	.build_controls = stac92xx_build_controls,
-	.build_pcms = stac92xx_build_pcms,
-	.init = stac92xx_init,
-	.free = stac92xx_free,
-#ifdef SND_HDA_NEEDS_RESUME
-	.resume = stac92xx_resume,
-#endif
+static hda_nid_t stac9872_adc_nids[] = {
+	0x8 /*,0x6*/
 };
 
-static int stac9872_vaio_init(struct hda_codec *codec)
-{
-	int err;
-
-	err = stac92xx_init(codec);
-	if (err < 0)
-		return err;
-	if (codec->patch_ops.unsol_event)
-		codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
-	return 0;
-}
-
-static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
-{
-	if (get_pin_presence(codec, 0x0a)) {
-		stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
-		stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
-	} else {
-		stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
-		stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
-	}
-} 
-
-static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	switch (res >> 26) {
-	case STAC_HP_EVENT:
-		stac9872_vaio_hp_detect(codec, res);
-		break;
-	}
-}
-
-static struct hda_codec_ops stac9872_vaio_patch_ops = {
-	.build_controls = stac92xx_build_controls,
-	.build_pcms = stac92xx_build_pcms,
-	.init = stac9872_vaio_init,
-	.free = stac92xx_free,
-	.unsol_event = stac9872_vaio_unsol_event,
-#ifdef CONFIG_PM
-	.resume = stac92xx_resume,
-#endif
-};
-
-enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
-       CXD9872RD_VAIO,
-       /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */
-       STAC9872AK_VAIO, 
-       /* Unknown. id=0x83847661 and subsys=0x104D1200. */
-       STAC9872K_VAIO,
-       /* AR Series. id=0x83847664 and subsys=104D1300 */
-       CXD9872AKD_VAIO,
-       STAC_9872_MODELS,
-};
-
-static const char *stac9872_models[STAC_9872_MODELS] = {
-	[CXD9872RD_VAIO]	= "vaio",
-	[CXD9872AKD_VAIO]	= "vaio-ar",
-};
-
-static struct snd_pci_quirk stac9872_cfg_tbl[] = {
-	SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
-	SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
-	SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
-	SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
-	{}
+static hda_nid_t stac9872_mux_nids[] = {
+	0x15
 };
 
 static int patch_stac9872(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec;
-	int board_config;
+	int err;
 
-	board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
-						  stac9872_models,
-						  stac9872_cfg_tbl);
-	if (board_config < 0)
-		/* unknown config, let generic-parser do its job... */
-		return snd_hda_parse_generic_codec(codec);
-	
 	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
-
 	codec->spec = spec;
-	switch (board_config) {
-	case CXD9872RD_VAIO:
-	case STAC9872AK_VAIO:
-	case STAC9872K_VAIO:
-		spec->mixer = vaio_mixer;
-		spec->init = vaio_init;
-		spec->multiout.max_channels = 2;
-		spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
-		spec->multiout.dac_nids = vaio_dacs;
-		spec->multiout.hp_nid = VAIO_HP_DAC;
-		spec->num_adcs = ARRAY_SIZE(vaio_adcs);
-		spec->adc_nids = vaio_adcs;
-		spec->num_pwrs = 0;
-		spec->input_mux = &vaio_mux;
-		spec->mux_nids = vaio_mux_nids;
-		codec->patch_ops = stac9872_vaio_patch_ops;
-		break;
-	
-	case CXD9872AKD_VAIO:
-		spec->mixer = vaio_ar_mixer;
-		spec->init = vaio_ar_init;
-		spec->multiout.max_channels = 2;
-		spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs);
-		spec->multiout.dac_nids = vaio_dacs;
-		spec->multiout.hp_nid = VAIO_HP_DAC;
-		spec->num_adcs = ARRAY_SIZE(vaio_adcs);
-		spec->num_pwrs = 0;
-		spec->adc_nids = vaio_adcs;
-		spec->input_mux = &vaio_mux;
-		spec->mux_nids = vaio_mux_nids;
-		codec->patch_ops = stac9872_patch_ops;
-		break;
-	}
 
+#if 0 /* no model right now */
+	spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
+							stac9872_models,
+							stac9872_cfg_tbl);
+#endif
+
+	spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
+	spec->pin_nids = stac9872_pin_nids;
+	spec->multiout.dac_nids = spec->dac_nids;
+	spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids);
+	spec->adc_nids = stac9872_adc_nids;
+	spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
+	spec->mux_nids = stac9872_mux_nids;
+	spec->mixer = stac9872_mixer;
+	spec->init = stac9872_core_init;
+
+	err = stac92xx_parse_auto_config(codec, 0x10, 0x12);
+	if (err < 0) {
+		stac92xx_free(codec);
+		return -EINVAL;
+	}
+	spec->input_mux = &spec->private_imux;
+	codec->patch_ops = stac92xx_patch_ops;
 	return 0;
 }