From 3aaf898025b1f75f30457e00e890c9f7c43567ab Mon Sep 17 00:00:00 2001
From: Stephen Warren <swarren@nvidia.com>
Date: Wed, 1 Jun 2011 11:14:19 -0600
Subject: [PATCH] ALSA: hda: Separate generic and non-generic implementations
Git-commit: 3aaf898025b1f75f30457e00e890c9f7c43567ab
Patch-mainline: 3.1-rc2
Refernces: FATE#314106,FATE#314311,FATE#313695

A future change will significantly rework the generic implementation
in order to support codecs with a different number of pins and
converters. Isolate the more custom codec variants from this change by
duplicating the small portions of generic code they share. This
simplifies the later rework of that previously shared code, since we
don't have to consider the more custom codecs, and also prevents
support for those codecs from regressing.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/pci/hda/patch_hdmi.c |   75 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 9 deletions(-)

--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1164,6 +1164,63 @@ static int patch_generic_hdmi(struct hda
 }
 
 /*
+ * Shared non-generic implementations
+ */
+
+static int simple_playback_build_pcms(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+	int i;
+
+	codec->num_pcms = spec->num_cvts;
+	codec->pcm_info = info;
+
+	for (i = 0; i < codec->num_pcms; i++, info++) {
+		unsigned int chans;
+		struct hda_pcm_stream *pstr;
+
+		chans = get_wcaps(codec, spec->cvt[i]);
+		chans = get_wcaps_channels(chans);
+
+		info->name = generic_hdmi_pcm_names[i];
+		info->pcm_type = HDA_PCM_TYPE_HDMI;
+		pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
+		snd_BUG_ON(!spec->pcm_playback);
+		*pstr = *spec->pcm_playback;
+		pstr->nid = spec->cvt[i];
+		if (pstr->channels_max <= 2 && chans && chans <= 16)
+			pstr->channels_max = chans;
+	}
+
+	return 0;
+}
+
+static int simple_playback_build_controls(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+	int err;
+	int i;
+
+	for (i = 0; i < codec->num_pcms; i++) {
+		err = snd_hda_create_spdif_out_ctls(codec,
+						    spec->cvt[i],
+						    spec->cvt[i]);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static void simple_playback_free(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+
+	kfree(spec);
+}
+
+/*
  * Nvidia specific implementations
  */
 
@@ -1475,17 +1532,17 @@ static const struct hda_pcm_stream nvhdm
 };
 
 static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
-	.build_controls = generic_hdmi_build_controls,
-	.build_pcms = generic_hdmi_build_pcms,
+	.build_controls = simple_playback_build_controls,
+	.build_pcms = simple_playback_build_pcms,
 	.init = nvhdmi_7x_init,
-	.free = generic_hdmi_free,
+	.free = simple_playback_free,
 };
 
 static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
-	.build_controls = generic_hdmi_build_controls,
-	.build_pcms = generic_hdmi_build_pcms,
+	.build_controls = simple_playback_build_controls,
+	.build_pcms = simple_playback_build_pcms,
 	.init = nvhdmi_7x_init,
-	.free = generic_hdmi_free,
+	.free = simple_playback_free,
 };
 
 static int patch_nvhdmi_2ch(struct hda_codec *codec)
@@ -1596,10 +1653,10 @@ static int atihdmi_init(struct hda_codec
 }
 
 static const struct hda_codec_ops atihdmi_patch_ops = {
-	.build_controls = generic_hdmi_build_controls,
-	.build_pcms = generic_hdmi_build_pcms,
+	.build_controls = simple_playback_build_controls,
+	.build_pcms = simple_playback_build_pcms,
 	.init = atihdmi_init,
-	.free = generic_hdmi_free,
+	.free = simple_playback_free,
 };
 
 
