All of lore.kernel.org
 help / color / mirror / Atom feed
* Unifying sound/pci/hda/patch_*hdmi.c
@ 2010-09-15 14:48 Takashi Iwai
  2010-09-15 14:51 ` Wu Fengguang
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Takashi Iwai @ 2010-09-15 14:48 UTC (permalink / raw)
  To: Stephen Warren; +Cc: alsa-devel, Wu Fengguang, wni

[-- Attachment #1: Type: text/plain, Size: 475 bytes --]

Hi,

the below is a patch for unifying three patch_*hdmi.c into a single
file.  I'd like to push this to 2.6.37, so please review, especially
whether it can break Nvidia hardware (since I have no h/w available).

In future, we can reduce ATI- and Nvidia-specific codes gradually
after confirming the generic parser works.

The patch is found in sound-unstable git tree, too.  The corresponding
alsa-driver-unstable tarball can be used for external builds.


thanks,

Takashi

[-- Attachment #2: 0001-ALSA-hda-Merge-all-HDMI-modules-into-the-unified-mod.patch --]
[-- Type: application/octet-stream, Size: 59602 bytes --]

>From fd74a0170e730d397b796dc34eb5212358e764ea Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 7 Sep 2010 12:27:25 +0200
Subject: [PATCH] ALSA: hda - Merge all HDMI modules into the unified module

This patch merges all three patch_*hdmi variants to the single HDMI
parser.  There is only one snd-hda-codec-hdmi module now.

In this patch, the behavior of each parser isn't changed much.
The old ATI parser still doesn't use the dynamic parser yet.
In later patches, they'll be cleaned up.

Also, this patch gets rid of the individual snd-hda-eld module and
builds into snd-hda-codec-hdmi, since this is referred only from the
HDMI parser.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/Kconfig           |   39 +--
 sound/pci/hda/Makefile          |   15 +-
 sound/pci/hda/hda_eld.c         |    7 -
 sound/pci/hda/patch_atihdmi.c   |  224 -------------
 sound/pci/hda/patch_hdmi.c      |  685 ++++++++++++++++++++++++++++++++++++++-
 sound/pci/hda/patch_intelhdmi.c |  220 -------------
 sound/pci/hda/patch_nvhdmi.c    |  608 ----------------------------------
 7 files changed, 691 insertions(+), 1107 deletions(-)
 delete mode 100644 sound/pci/hda/patch_atihdmi.c
 delete mode 100644 sound/pci/hda/patch_intelhdmi.c
 delete mode 100644 sound/pci/hda/patch_nvhdmi.c

diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 9194c3c..329e116 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -119,47 +119,20 @@ config SND_HDA_CODEC_VIA
 	  snd-hda-codec-via.
 	  This module is automatically loaded at probing.
 
-config SND_HDA_CODEC_ATIHDMI
-	bool "Build ATI HDMI HD-audio codec support"
-	default y
-	help
-	  Say Y here to include ATI HDMI HD-audio codec support in
-	  snd-hda-intel driver, such as ATI RS600 HDMI.
-
-	  When the HD-audio driver is built as a module, the codec
-	  support code is also built as another module,
-	  snd-hda-codec-atihdmi.
-	  This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_NVHDMI
-	bool "Build NVIDIA HDMI HD-audio codec support"
-	default y
-	help
-	  Say Y here to include NVIDIA HDMI HD-audio codec support in
-	  snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
-
-	  When the HD-audio driver is built as a module, the codec
-	  support code is also built as another module,
-	  snd-hda-codec-nvhdmi.
-	  This module is automatically loaded at probing.
-
-config SND_HDA_CODEC_INTELHDMI
-	bool "Build INTEL HDMI HD-audio codec support"
+config SND_HDA_CODEC_HDMI
+	bool "Build HDMI HD-audio codec support"
 	select SND_DYNAMIC_MINORS
 	default y
 	help
-	  Say Y here to include INTEL HDMI HD-audio codec support in
-	  snd-hda-intel driver, such as Eaglelake integrated HDMI.
+	  Say Y here to include HDMI HD-audio codec support in
+	  snd-hda-intel driver.  This includes all AMD/ATI, Intel and
+	  Nvidia HDMI codecs.
 
 	  When the HD-audio driver is built as a module, the codec
 	  support code is also built as another module,
-	  snd-hda-codec-intelhdmi.
+	  snd-hda-codec-hdmi.
 	  This module is automatically loaded at probing.
 
-config SND_HDA_ELD
-	def_bool y
-	depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
-
 config SND_HDA_CODEC_CIRRUS
 	bool "Build Cirrus Logic codec support"
 	depends on SND_HDA_INTEL
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 24bc195..17ef365 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o
 snd-hda-codec-y := hda_codec.o
 snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
 snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
-snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
 snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
 snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
 
@@ -12,13 +11,11 @@ snd-hda-codec-cmedia-objs :=	patch_cmedia.o
 snd-hda-codec-analog-objs :=	patch_analog.o
 snd-hda-codec-idt-objs :=	patch_sigmatel.o
 snd-hda-codec-si3054-objs :=	patch_si3054.o
-snd-hda-codec-atihdmi-objs :=	patch_atihdmi.o
 snd-hda-codec-cirrus-objs :=	patch_cirrus.o
 snd-hda-codec-ca0110-objs :=	patch_ca0110.o
 snd-hda-codec-conexant-objs :=	patch_conexant.o
 snd-hda-codec-via-objs :=	patch_via.o
-snd-hda-codec-nvhdmi-objs :=	patch_nvhdmi.o
-snd-hda-codec-intelhdmi-objs :=	patch_intelhdmi.o
+snd-hda-codec-hdmi-objs :=	patch_hdmi.o hda_eld.o
 
 # common driver
 obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
@@ -39,9 +36,6 @@ endif
 ifdef CONFIG_SND_HDA_CODEC_SI3054
 obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
 endif
-ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
-endif
 ifdef CONFIG_SND_HDA_CODEC_CIRRUS
 obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
 endif
@@ -54,11 +48,8 @@ endif
 ifdef CONFIG_SND_HDA_CODEC_VIA
 obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
 endif
-ifdef CONFIG_SND_HDA_CODEC_NVHDMI
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-nvhdmi.o
-endif
-ifdef CONFIG_SND_HDA_CODEC_INTELHDMI
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-intelhdmi.o
+ifdef CONFIG_SND_HDA_CODEC_HDMI
+obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-hdmi.o
 endif
 
 # this must be the last entry after codec drivers;
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 26c3ade..cb0c23a 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -332,7 +332,6 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
 	return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
 						 AC_DIPSIZE_ELD_BUF);
 }
-EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
 
 int snd_hdmi_get_eld(struct hdmi_eld *eld,
 		     struct hda_codec *codec, hda_nid_t nid)
@@ -368,7 +367,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
 	kfree(buf);
 	return ret;
 }
-EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
 
 static void hdmi_show_short_audio_desc(struct cea_sad *a)
 {
@@ -407,7 +405,6 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
 	}
 	buf[j] = '\0';	/* necessary when j == 0 */
 }
-EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
 
 void snd_hdmi_show_eld(struct hdmi_eld *e)
 {
@@ -426,7 +423,6 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
 	for (i = 0; i < e->sad_count; i++)
 		hdmi_show_short_audio_desc(e->sad + i);
 }
-EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
 
 #ifdef CONFIG_PROC_FS
 
@@ -585,7 +581,6 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
 
 	return 0;
 }
-EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
 
 void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
 {
@@ -594,7 +589,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
 		eld->proc_entry = NULL;
 	}
 }
-EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
 
 #endif /* CONFIG_PROC_FS */
 
@@ -645,4 +639,3 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
 	pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
 	pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
 }
-EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info);
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
deleted file mode 100644
index fb684f0..0000000
--- a/sound/pci/hda/patch_atihdmi.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for ATI HDMI codecs
- *
- * Copyright (c) 2006 ATI Technologies Inc.
- *
- *
- *  This driver is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This driver is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-struct atihdmi_spec {
-	struct hda_multi_out multiout;
-
-	struct hda_pcm pcm_rec;
-};
-
-#define CVT_NID		0x02	/* audio converter */
-#define PIN_NID		0x03	/* HDMI output pin */
-
-static struct hda_verb atihdmi_basic_init[] = {
-	/* enable digital output on pin widget */
-	{ 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-	{} /* terminator */
-};
-
-/*
- * Controls
- */
-static int atihdmi_build_controls(struct hda_codec *codec)
-{
-	struct atihdmi_spec *spec = codec->spec;
-	int err;
-
-	err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
-	if (err < 0)
-		return err;
-
-	return 0;
-}
-
-static int atihdmi_init(struct hda_codec *codec)
-{
-	snd_hda_sequence_write(codec, atihdmi_basic_init);
-	/* SI codec requires to unmute the pin */
-	if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
-		snd_hda_codec_write(codec, PIN_NID, 0,
-				    AC_VERB_SET_AMP_GAIN_MUTE,
-				    AMP_OUT_UNMUTE);
-	return 0;
-}
-
-/*
- * Digital out
- */
-static int atihdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
-				     struct hda_codec *codec,
-				     struct snd_pcm_substream *substream)
-{
-	struct atihdmi_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
-				      struct hda_codec *codec,
-				      struct snd_pcm_substream *substream)
-{
-	struct atihdmi_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
-					    struct hda_codec *codec,
-					    unsigned int stream_tag,
-					    unsigned int format,
-					    struct snd_pcm_substream *substream)
-{
-	struct atihdmi_spec *spec = codec->spec;
-	int chans = substream->runtime->channels;
-	int i, err;
-
-	err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
-					    format, substream);
-	if (err < 0)
-		return err;
-	snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT,
-			    chans - 1);
-	/* FIXME: XXX */
-	for (i = 0; i < chans; i++) {
-		snd_hda_codec_write(codec, CVT_NID, 0,
-				    AC_VERB_SET_HDMI_CHAN_SLOT,
-				    (i << 4) | i);
-	}
-	return 0;
-}
-
-static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 2,
-	.nid = CVT_NID, /* NID to query formats and rates and setup streams */
-	.ops = {
-		.open = atihdmi_dig_playback_pcm_open,
-		.close = atihdmi_dig_playback_pcm_close,
-		.prepare = atihdmi_dig_playback_pcm_prepare
-	},
-};
-
-static int atihdmi_build_pcms(struct hda_codec *codec)
-{
-	struct atihdmi_spec *spec = codec->spec;
-	struct hda_pcm *info = &spec->pcm_rec;
-	unsigned int chans;
-
-	codec->num_pcms = 1;
-	codec->pcm_info = info;
-
-	info->name = "ATI HDMI";
-	info->pcm_type = HDA_PCM_TYPE_HDMI;
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
-
-	/* FIXME: we must check ELD and change the PCM parameters dynamically
-	 */
-	chans = get_wcaps(codec, CVT_NID);
-	chans = get_wcaps_channels(chans);
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
-
-	return 0;
-}
-
-static void atihdmi_free(struct hda_codec *codec)
-{
-	kfree(codec->spec);
-}
-
-static struct hda_codec_ops atihdmi_patch_ops = {
-	.build_controls = atihdmi_build_controls,
-	.build_pcms = atihdmi_build_pcms,
-	.init = atihdmi_init,
-	.free = atihdmi_free,
-};
-
-static int patch_atihdmi(struct hda_codec *codec)
-{
-	struct atihdmi_spec *spec;
-
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
-
-	spec->multiout.num_dacs = 0;	  /* no analog */
-	spec->multiout.max_channels = 2;
-	/* NID for copying analog to digital,
-	 * seems to be unused in pure-digital
-	 * case.
-	 */
-	spec->multiout.dig_out_nid = CVT_NID;
-
-	codec->patch_ops = atihdmi_patch_ops;
-
-	return 0;
-}
-
-/*
- * patch entries
- */
-static struct hda_codec_preset snd_hda_preset_atihdmi[] = {
-	{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
-	{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
-	{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
-	{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
-	{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
-	{ .id = 0x17e80047, .name = "Chrontel HDMI",  .patch = patch_atihdmi },
-	{} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:1002793c");
-MODULE_ALIAS("snd-hda-codec-id:10027919");
-MODULE_ALIAS("snd-hda-codec-id:1002791a");
-MODULE_ALIAS("snd-hda-codec-id:1002aa01");
-MODULE_ALIAS("snd-hda-codec-id:10951390");
-MODULE_ALIAS("snd-hda-codec-id:17e80047");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ATI HDMI HD-audio codec");
-
-static struct hda_codec_preset_list atihdmi_list = {
-	.preset = snd_hda_preset_atihdmi,
-	.owner = THIS_MODULE,
-};
-
-static int __init patch_atihdmi_init(void)
-{
-	return snd_hda_add_codec_preset(&atihdmi_list);
-}
-
-static void __exit patch_atihdmi_exit(void)
-{
-	snd_hda_delete_codec_preset(&atihdmi_list);
-}
-
-module_init(patch_atihdmi_init)
-module_exit(patch_atihdmi_exit)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index afd6022..a18f40b 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -3,6 +3,9 @@
  *  patch_hdmi.c - routines for HDMI/DisplayPort codecs
  *
  *  Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
+ *  Copyright (c) 2006 ATI Technologies Inc.
+ *  Copyright (c) 2008 NVIDIA Corp.  All rights reserved.
+ *  Copyright (c) 2008 Wei Ni <wni@nvidia.com>
  *
  *  Authors:
  *			Wu Fengguang <wfg@linux.intel.com>
@@ -25,6 +28,22 @@
  *  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+/*
+ * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
+ * could support two independent pipes, each of them can be connected to one or
+ * more ports (DVI, HDMI or DisplayPort).
+ *
+ * The HDA correspondence of pipes/ports are converter/pin nodes.
+ */
+#define MAX_HDMI_CVTS	3
+#define MAX_HDMI_PINS	3
 
 struct hdmi_spec {
 	int num_cvts;
@@ -49,10 +68,10 @@ struct hdmi_spec {
 	struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
 
 	/*
-	 * nvhdmi specific
+	 * ati/nvhdmi specific
 	 */
 	struct hda_multi_out multiout;
-	unsigned int codec_type;
+	struct hda_pcm_stream *pcm_playback;
 
 	/* misc flags */
 	/* PD bit indicates only the update, not the current state */
@@ -791,7 +810,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
 /*
  * HDA/HDMI auto parsing
  */
-
 static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
 {
 	struct hdmi_spec *spec = codec->spec;
@@ -922,3 +940,664 @@ static int hdmi_parse_codec(struct hda_codec *codec)
 	return 0;
 }
 
+/*
+ */
+static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = {
+	"HDMI 0",
+	"HDMI 1",
+	"HDMI 2",
+};
+
+/*
+ * HDMI callbacks
+ */
+
+static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					   struct hda_codec *codec,
+					   unsigned int stream_tag,
+					   unsigned int format,
+					   struct snd_pcm_substream *substream)
+{
+	hdmi_set_channel_count(codec, hinfo->nid,
+			       substream->runtime->channels);
+
+	hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
+
+	return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
+}
+
+static struct hda_pcm_stream generic_hdmi_pcm_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.ops = {
+		.open = hdmi_pcm_open,
+		.prepare = generic_hdmi_playback_pcm_prepare,
+	},
+};
+
+static int generic_hdmi_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];
+		if (spec->pcm_playback)
+			*pstr = *spec->pcm_playback;
+		else
+			*pstr = generic_hdmi_pcm_playback;
+		pstr->nid = spec->cvt[i];
+		if (pstr->channels_max <= 2 && chans && chans <= 16)
+			pstr->channels_max = chans;
+	}
+
+	return 0;
+}
+
+static int generic_hdmi_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]);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int generic_hdmi_init(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; spec->pin[i]; i++) {
+		hdmi_enable_output(codec, spec->pin[i]);
+		snd_hda_codec_write(codec, spec->pin[i], 0,
+				    AC_VERB_SET_UNSOLICITED_ENABLE,
+				    AC_USRSP_EN | spec->pin[i]);
+	}
+	return 0;
+}
+
+static void generic_hdmi_free(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->num_pins; i++)
+		snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
+
+	kfree(spec);
+}
+
+static struct hda_codec_ops generic_hdmi_patch_ops = {
+	.init			= generic_hdmi_init,
+	.free			= generic_hdmi_free,
+	.build_pcms		= generic_hdmi_build_pcms,
+	.build_controls 	= generic_hdmi_build_controls,
+	.unsol_event		= hdmi_unsol_event,
+};
+
+static int patch_generic_hdmi(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+	int i;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+	if (hdmi_parse_codec(codec) < 0) {
+		codec->spec = NULL;
+		kfree(spec);
+		return -EINVAL;
+	}
+	codec->patch_ops = generic_hdmi_patch_ops;
+
+	for (i = 0; i < spec->num_pins; i++)
+		snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
+
+	init_channel_allocations();
+
+	return 0;
+}
+
+/*
+ * Nvidia specific implmenetations
+ */
+
+#define Nv_VERB_SET_Channel_Allocation          0xF79
+#define Nv_VERB_SET_Info_Frame_Checksum         0xF7A
+#define Nv_VERB_SET_Audio_Protection_On         0xF98
+#define Nv_VERB_SET_Audio_Protection_Off        0xF99
+
+#define nvhdmi_master_con_nid_7x	0x04
+#define nvhdmi_master_pin_nid_7x	0x05
+
+static hda_nid_t nvhdmi_con_nids_7x[4] = {
+	/*front, rear, clfe, rear_surr */
+	0x6, 0x8, 0xa, 0xc,
+};
+
+static struct hda_verb nvhdmi_basic_init_7x[] = {
+	/* set audio protect on */
+	{ 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
+	/* enable digital output on pin widget */
+	{ 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
+	{ 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
+	{ 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
+	{ 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
+	{ 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
+	{} /* terminator */
+};
+
+#ifdef LIMITED_RATE_FMT_SUPPORT
+/* support only the safe format and rate */
+#define SUPPORTED_RATES		SNDRV_PCM_RATE_48000
+#define SUPPORTED_MAXBPS	16
+#define SUPPORTED_FORMATS	SNDRV_PCM_FMTBIT_S16_LE
+#else
+/* support all rates and formats */
+#define SUPPORTED_RATES \
+	(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+	SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
+	 SNDRV_PCM_RATE_192000)
+#define SUPPORTED_MAXBPS	24
+#define SUPPORTED_FORMATS \
+	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
+#endif
+
+static int nvhdmi_7x_init(struct hda_codec *codec)
+{
+	snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
+	return 0;
+}
+
+static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				    struct hda_codec *codec,
+				    struct snd_pcm_substream *substream)
+{
+	struct hdmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int simple_playback_pcm_close(struct hda_pcm_stream *hinfo,
+				     struct hda_codec *codec,
+				     struct snd_pcm_substream *substream)
+{
+	struct hdmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       unsigned int stream_tag,
+				       unsigned int format,
+				       struct snd_pcm_substream *substream)
+{
+	struct hdmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+					     stream_tag, format, substream);
+}
+
+static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo,
+				   struct hda_codec *codec,
+				   struct snd_pcm_substream *substream)
+{
+	struct hdmi_spec *spec = codec->spec;
+	int i;
+
+	snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
+			0, AC_VERB_SET_CHANNEL_STREAMID, 0);
+	for (i = 0; i < 4; i++) {
+		/* set the stream id */
+		snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
+				AC_VERB_SET_CHANNEL_STREAMID, 0);
+		/* set the stream format */
+		snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
+				AC_VERB_SET_STREAM_FORMAT, 0);
+	}
+
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
+				     struct hda_codec *codec,
+				     unsigned int stream_tag,
+				     unsigned int format,
+				     struct snd_pcm_substream *substream)
+{
+	int chs;
+	unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id;
+	int i;
+
+	mutex_lock(&codec->spdif_mutex);
+
+	chs = substream->runtime->channels;
+	chan = chs ? (chs - 1) : 1;
+
+	switch (chs) {
+	default:
+	case 0:
+	case 2:
+		chanmask = 0x00;
+		break;
+	case 4:
+		chanmask = 0x08;
+		break;
+	case 6:
+		chanmask = 0x0b;
+		break;
+	case 8:
+		chanmask = 0x13;
+		break;
+	}
+	dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
+	dataDCC2 = 0x2;
+
+	/* set the Audio InforFrame Channel Allocation */
+	snd_hda_codec_write(codec, 0x1, 0,
+			Nv_VERB_SET_Channel_Allocation, chanmask);
+
+	/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
+	if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
+		snd_hda_codec_write(codec,
+				nvhdmi_master_con_nid_7x,
+				0,
+				AC_VERB_SET_DIGI_CONVERT_1,
+				codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+
+	/* set the stream id */
+	snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
+			AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
+
+	/* set the stream format */
+	snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
+			AC_VERB_SET_STREAM_FORMAT, format);
+
+	/* turn on again (if needed) */
+	/* enable and set the channel status audio/data flag */
+	if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
+		snd_hda_codec_write(codec,
+				nvhdmi_master_con_nid_7x,
+				0,
+				AC_VERB_SET_DIGI_CONVERT_1,
+				codec->spdif_ctls & 0xff);
+		snd_hda_codec_write(codec,
+				nvhdmi_master_con_nid_7x,
+				0,
+				AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (chs == 2)
+			channel_id = 0;
+		else
+			channel_id = i * 2;
+
+		/* turn off SPDIF once;
+		 *otherwise the IEC958 bits won't be updated
+		 */
+		if (codec->spdif_status_reset &&
+		(codec->spdif_ctls & AC_DIG1_ENABLE))
+			snd_hda_codec_write(codec,
+				nvhdmi_con_nids_7x[i],
+				0,
+				AC_VERB_SET_DIGI_CONVERT_1,
+				codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+		/* set the stream id */
+		snd_hda_codec_write(codec,
+				nvhdmi_con_nids_7x[i],
+				0,
+				AC_VERB_SET_CHANNEL_STREAMID,
+				(stream_tag << 4) | channel_id);
+		/* set the stream format */
+		snd_hda_codec_write(codec,
+				nvhdmi_con_nids_7x[i],
+				0,
+				AC_VERB_SET_STREAM_FORMAT,
+				format);
+		/* turn on again (if needed) */
+		/* enable and set the channel status audio/data flag */
+		if (codec->spdif_status_reset &&
+		(codec->spdif_ctls & AC_DIG1_ENABLE)) {
+			snd_hda_codec_write(codec,
+					nvhdmi_con_nids_7x[i],
+					0,
+					AC_VERB_SET_DIGI_CONVERT_1,
+					codec->spdif_ctls & 0xff);
+			snd_hda_codec_write(codec,
+					nvhdmi_con_nids_7x[i],
+					0,
+					AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
+		}
+	}
+
+	/* set the Audio Info Frame Checksum */
+	snd_hda_codec_write(codec, 0x1, 0,
+			Nv_VERB_SET_Info_Frame_Checksum,
+			(0x71 - chan - chanmask));
+
+	mutex_unlock(&codec->spdif_mutex);
+	return 0;
+}
+
+static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 8,
+	.nid = nvhdmi_master_con_nid_7x,
+	.rates = SUPPORTED_RATES,
+	.maxbps = SUPPORTED_MAXBPS,
+	.formats = SUPPORTED_FORMATS,
+	.ops = {
+		.open = simple_playback_pcm_open,
+		.close = nvhdmi_8ch_7x_pcm_close,
+		.prepare = nvhdmi_8ch_7x_pcm_prepare
+	},
+};
+
+static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = nvhdmi_master_con_nid_7x,
+	.rates = SUPPORTED_RATES,
+	.maxbps = SUPPORTED_MAXBPS,
+	.formats = SUPPORTED_FORMATS,
+	.ops = {
+		.open = simple_playback_pcm_open,
+		.close = simple_playback_pcm_close,
+		.prepare = simple_playback_pcm_prepare
+	},
+};
+
+static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
+	.build_controls = generic_hdmi_build_controls,
+	.build_pcms = generic_hdmi_build_pcms,
+	.init = nvhdmi_7x_init,
+	.free = generic_hdmi_free,
+};
+
+static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
+	.build_controls = generic_hdmi_build_controls,
+	.build_pcms = generic_hdmi_build_pcms,
+	.init = nvhdmi_7x_init,
+	.free = generic_hdmi_free,
+};
+
+static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+	int err = patch_generic_hdmi(codec);
+
+	if (err < 0)
+		return err;
+	spec = codec->spec;
+	spec->old_pin_detect = 1;
+	spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
+	return 0;
+}
+
+static int patch_nvhdmi_2ch(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+
+	spec->multiout.num_dacs = 0;  /* no analog */
+	spec->multiout.max_channels = 2;
+	spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
+	spec->old_pin_detect = 1;
+	spec->num_cvts = 1;
+	spec->cvt[0] = nvhdmi_master_con_nid_7x;
+	spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
+
+	codec->patch_ops = nvhdmi_patch_ops_2ch;
+
+	return 0;
+}
+
+static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+	int err = patch_generic_hdmi(codec);
+
+	if (err < 0)
+		return err;
+	spec = codec->spec;
+	spec->multiout.max_channels = 8;
+	codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
+	return 0;
+}
+
+/*
+ * ATI-specific implementations
+ *
+ * FIXME: we may omit the whole this and use the generic code once after
+ * it's confirmed to work.
+ */
+
+#define ATIHDMI_CVT_NID		0x02	/* audio converter */
+#define ATIHDMI_PIN_NID		0x03	/* HDMI output pin */
+
+static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					unsigned int stream_tag,
+					unsigned int format,
+					struct snd_pcm_substream *substream)
+{
+	struct hdmi_spec *spec = codec->spec;
+	int chans = substream->runtime->channels;
+	int i, err;
+
+	err = simple_playback_pcm_prepare(hinfo, codec, stream_tag, format,
+					  substream);
+	if (err < 0)
+		return err;
+	snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT,
+			    chans - 1);
+	/* FIXME: XXX */
+	for (i = 0; i < chans; i++) {
+		snd_hda_codec_write(codec, spec->cvt[0], 0,
+				    AC_VERB_SET_HDMI_CHAN_SLOT,
+				    (i << 4) | i);
+	}
+	return 0;
+}
+
+static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = ATIHDMI_CVT_NID,
+	.ops = {
+		.open = simple_playback_pcm_open,
+		.close = simple_playback_pcm_close,
+		.prepare = atihdmi_playback_pcm_prepare
+	},
+};
+
+static struct hda_verb atihdmi_basic_init[] = {
+	/* enable digital output on pin widget */
+	{ 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{} /* terminator */
+};
+
+static int atihdmi_init(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+
+	snd_hda_sequence_write(codec, atihdmi_basic_init);
+	/* SI codec requires to unmute the pin */
+	if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP)
+		snd_hda_codec_write(codec, spec->pin[0], 0,
+				    AC_VERB_SET_AMP_GAIN_MUTE,
+				    AMP_OUT_UNMUTE);
+	return 0;
+}
+
+static struct hda_codec_ops atihdmi_patch_ops = {
+	.build_controls = generic_hdmi_build_controls,
+	.build_pcms = generic_hdmi_build_pcms,
+	.init = atihdmi_init,
+	.free = generic_hdmi_free,
+};
+
+
+static int patch_atihdmi(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+
+	spec->multiout.num_dacs = 0;	  /* no analog */
+	spec->multiout.max_channels = 2;
+	spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
+	spec->num_cvts = 1;
+	spec->cvt[0] = ATIHDMI_CVT_NID;
+	spec->pin[0] = ATIHDMI_PIN_NID;
+	spec->pcm_playback = &atihdmi_pcm_digital_playback;
+
+	codec->patch_ops = atihdmi_patch_ops;
+
+	return 0;
+}
+
+
+/*
+ * patch entries
+ */
+static struct hda_codec_preset snd_hda_preset_hdmi[] = {
+{ .id = 0x1002793c, .name = "RS600 HDMI",	.patch = patch_atihdmi },
+{ .id = 0x10027919, .name = "RS600 HDMI",	.patch = patch_atihdmi },
+{ .id = 0x1002791a, .name = "RS690/780 HDMI",	.patch = patch_atihdmi },
+{ .id = 0x1002aa01, .name = "R6xx HDMI",	.patch = patch_atihdmi },
+{ .id = 0x10951390, .name = "SiI1390 HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x10951392, .name = "SiI1392 HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x17e80047, .name = "Chrontel HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x10de0002, .name = "MCP77/78 HDMI",	.patch = patch_nvhdmi_8ch_7x },
+{ .id = 0x10de0003, .name = "MCP77/78 HDMI",	.patch = patch_nvhdmi_8ch_7x },
+{ .id = 0x10de0005, .name = "MCP77/78 HDMI",	.patch = patch_nvhdmi_8ch_7x },
+{ .id = 0x10de0006, .name = "MCP77/78 HDMI",	.patch = patch_nvhdmi_8ch_7x },
+{ .id = 0x10de0007, .name = "MCP79/7A HDMI",	.patch = patch_nvhdmi_8ch_7x },
+{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de000c, .name = "MCP89 HDMI",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP",	.patch = patch_nvhdmi_8ch_89 },
+{ .id = 0x10de0067, .name = "MCP67 HDMI",	.patch = patch_nvhdmi_2ch },
+{ .id = 0x10de8001, .name = "MCP73 HDMI",	.patch = patch_nvhdmi_2ch },
+{ .id = 0x80860054, .name = "IbexPeak HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x80862801, .name = "Bearlake HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x80862802, .name = "Cantiga HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x80862803, .name = "Eaglelake HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x80862804, .name = "IbexPeak HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x80862805, .name = "CougarPoint HDMI",	.patch = patch_generic_hdmi },
+{ .id = 0x808629fb, .name = "Crestline HDMI",	.patch = patch_generic_hdmi },
+{} /* terminator */
+};
+
+MODULE_ALIAS("snd-hda-codec-id:1002793c");
+MODULE_ALIAS("snd-hda-codec-id:10027919");
+MODULE_ALIAS("snd-hda-codec-id:1002791a");
+MODULE_ALIAS("snd-hda-codec-id:1002aa01");
+MODULE_ALIAS("snd-hda-codec-id:10951390");
+MODULE_ALIAS("snd-hda-codec-id:10951392");
+MODULE_ALIAS("snd-hda-codec-id:10de0002");
+MODULE_ALIAS("snd-hda-codec-id:10de0003");
+MODULE_ALIAS("snd-hda-codec-id:10de0005");
+MODULE_ALIAS("snd-hda-codec-id:10de0006");
+MODULE_ALIAS("snd-hda-codec-id:10de0007");
+MODULE_ALIAS("snd-hda-codec-id:10de000a");
+MODULE_ALIAS("snd-hda-codec-id:10de000b");
+MODULE_ALIAS("snd-hda-codec-id:10de000c");
+MODULE_ALIAS("snd-hda-codec-id:10de000d");
+MODULE_ALIAS("snd-hda-codec-id:10de0010");
+MODULE_ALIAS("snd-hda-codec-id:10de0011");
+MODULE_ALIAS("snd-hda-codec-id:10de0012");
+MODULE_ALIAS("snd-hda-codec-id:10de0013");
+MODULE_ALIAS("snd-hda-codec-id:10de0014");
+MODULE_ALIAS("snd-hda-codec-id:10de0018");
+MODULE_ALIAS("snd-hda-codec-id:10de0019");
+MODULE_ALIAS("snd-hda-codec-id:10de001a");
+MODULE_ALIAS("snd-hda-codec-id:10de001b");
+MODULE_ALIAS("snd-hda-codec-id:10de001c");
+MODULE_ALIAS("snd-hda-codec-id:10de0040");
+MODULE_ALIAS("snd-hda-codec-id:10de0041");
+MODULE_ALIAS("snd-hda-codec-id:10de0042");
+MODULE_ALIAS("snd-hda-codec-id:10de0043");
+MODULE_ALIAS("snd-hda-codec-id:10de0044");
+MODULE_ALIAS("snd-hda-codec-id:10de0067");
+MODULE_ALIAS("snd-hda-codec-id:10de8001");
+MODULE_ALIAS("snd-hda-codec-id:17e80047");
+MODULE_ALIAS("snd-hda-codec-id:80860054");
+MODULE_ALIAS("snd-hda-codec-id:80862801");
+MODULE_ALIAS("snd-hda-codec-id:80862802");
+MODULE_ALIAS("snd-hda-codec-id:80862803");
+MODULE_ALIAS("snd-hda-codec-id:80862804");
+MODULE_ALIAS("snd-hda-codec-id:80862805");
+MODULE_ALIAS("snd-hda-codec-id:808629fb");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("HDMI HD-audio codec");
+MODULE_ALIAS("snd-hda-codec-intelhdmi");
+MODULE_ALIAS("snd-hda-codec-nvhdmi");
+MODULE_ALIAS("snd-hda-codec-atihdmi");
+
+static struct hda_codec_preset_list intel_list = {
+	.preset = snd_hda_preset_hdmi,
+	.owner = THIS_MODULE,
+};
+
+static int __init patch_hdmi_init(void)
+{
+	return snd_hda_add_codec_preset(&intel_list);
+}
+
+static void __exit patch_hdmi_exit(void)
+{
+	snd_hda_delete_codec_preset(&intel_list);
+}
+
+module_init(patch_hdmi_init)
+module_exit(patch_hdmi_exit)
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
deleted file mode 100644
index 36a9b83..0000000
--- a/sound/pci/hda/patch_intelhdmi.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- *
- *  patch_intelhdmi.c - Patch for Intel HDMI codecs
- *
- *  Copyright(c) 2008 Intel Corporation. All rights reserved.
- *
- *  Authors:
- *  			Jiang Zhe <zhe.jiang@intel.com>
- *  			Wu Fengguang <wfg@linux.intel.com>
- *
- *  Maintained by:
- *  			Wu Fengguang <wfg@linux.intel.com>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either version 2 of the License, or (at your option)
- *  any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software Foundation,
- *  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-/*
- * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
- * could support two independent pipes, each of them can be connected to one or
- * more ports (DVI, HDMI or DisplayPort).
- *
- * The HDA correspondence of pipes/ports are converter/pin nodes.
- */
-#define MAX_HDMI_CVTS	3
-#define MAX_HDMI_PINS	3
-
-#include "patch_hdmi.c"
-
-static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
-	"INTEL HDMI 0",
-	"INTEL HDMI 1",
-	"INTEL HDMI 2",
-};
-
-/*
- * HDMI callbacks
- */
-
-static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
-					   struct hda_codec *codec,
-					   unsigned int stream_tag,
-					   unsigned int format,
-					   struct snd_pcm_substream *substream)
-{
-	hdmi_set_channel_count(codec, hinfo->nid,
-			       substream->runtime->channels);
-
-	hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
-
-	return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
-}
-
-static struct hda_pcm_stream intel_hdmi_pcm_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.ops = {
-		.open = hdmi_pcm_open,
-		.prepare = intel_hdmi_playback_pcm_prepare,
-	},
-};
-
-static int intel_hdmi_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;
-
-		chans = get_wcaps(codec, spec->cvt[i]);
-		chans = get_wcaps_channels(chans);
-
-		info->name = intel_hdmi_pcm_names[i];
-		info->pcm_type = HDA_PCM_TYPE_HDMI;
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
-							intel_hdmi_pcm_playback;
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
-	}
-
-	return 0;
-}
-
-static int intel_hdmi_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]);
-		if (err < 0)
-			return err;
-	}
-
-	return 0;
-}
-
-static int intel_hdmi_init(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	int i;
-
-	for (i = 0; spec->pin[i]; i++) {
-		hdmi_enable_output(codec, spec->pin[i]);
-		snd_hda_codec_write(codec, spec->pin[i], 0,
-				    AC_VERB_SET_UNSOLICITED_ENABLE,
-				    AC_USRSP_EN | spec->pin[i]);
-	}
-	return 0;
-}
-
-static void intel_hdmi_free(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	int i;
-
-	for (i = 0; i < spec->num_pins; i++)
-		snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
-
-	kfree(spec);
-}
-
-static struct hda_codec_ops intel_hdmi_patch_ops = {
-	.init			= intel_hdmi_init,
-	.free			= intel_hdmi_free,
-	.build_pcms		= intel_hdmi_build_pcms,
-	.build_controls 	= intel_hdmi_build_controls,
-	.unsol_event		= hdmi_unsol_event,
-};
-
-static int patch_intel_hdmi(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec;
-	int i;
-
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
-	if (hdmi_parse_codec(codec) < 0) {
-		codec->spec = NULL;
-		kfree(spec);
-		return -EINVAL;
-	}
-	codec->patch_ops = intel_hdmi_patch_ops;
-
-	for (i = 0; i < spec->num_pins; i++)
-		snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
-
-	init_channel_allocations();
-
-	return 0;
-}
-
-static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
-{ .id = 0x808629fb, .name = "Crestline HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x80862801, .name = "Bearlake HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x80862802, .name = "Cantiga HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x80862803, .name = "Eaglelake HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x80862804, .name = "IbexPeak HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x80860054, .name = "IbexPeak HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x80862805, .name = "CougarPoint HDMI",	.patch = patch_intel_hdmi },
-{ .id = 0x10951392, .name = "SiI1392 HDMI",	.patch = patch_intel_hdmi },
-{} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:808629fb");
-MODULE_ALIAS("snd-hda-codec-id:80862801");
-MODULE_ALIAS("snd-hda-codec-id:80862802");
-MODULE_ALIAS("snd-hda-codec-id:80862803");
-MODULE_ALIAS("snd-hda-codec-id:80862804");
-MODULE_ALIAS("snd-hda-codec-id:80862805");
-MODULE_ALIAS("snd-hda-codec-id:80860054");
-MODULE_ALIAS("snd-hda-codec-id:10951392");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
-
-static struct hda_codec_preset_list intel_list = {
-	.preset = snd_hda_preset_intelhdmi,
-	.owner = THIS_MODULE,
-};
-
-static int __init patch_intelhdmi_init(void)
-{
-	return snd_hda_add_codec_preset(&intel_list);
-}
-
-static void __exit patch_intelhdmi_exit(void)
-{
-	snd_hda_delete_codec_preset(&intel_list);
-}
-
-module_init(patch_intelhdmi_init)
-module_exit(patch_intelhdmi_exit)
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
deleted file mode 100644
index baa108b..0000000
--- a/sound/pci/hda/patch_nvhdmi.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Universal Interface for Intel High Definition Audio Codec
- *
- * HD audio interface patch for NVIDIA HDMI codecs
- *
- * Copyright (c) 2008 NVIDIA Corp.  All rights reserved.
- * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
- *
- *
- *  This driver is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This driver is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include "hda_codec.h"
-#include "hda_local.h"
-
-#define MAX_HDMI_CVTS	1
-#define MAX_HDMI_PINS	1
-
-#include "patch_hdmi.c"
-
-static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
-	"NVIDIA HDMI",
-};
-
-/* define below to restrict the supported rates and formats */
-/* #define LIMITED_RATE_FMT_SUPPORT */
-
-enum HDACodec {
-	HDA_CODEC_NVIDIA_MCP7X,
-	HDA_CODEC_NVIDIA_MCP89,
-	HDA_CODEC_NVIDIA_GT21X,
-	HDA_CODEC_INVALID
-};
-
-#define Nv_VERB_SET_Channel_Allocation          0xF79
-#define Nv_VERB_SET_Info_Frame_Checksum         0xF7A
-#define Nv_VERB_SET_Audio_Protection_On         0xF98
-#define Nv_VERB_SET_Audio_Protection_Off        0xF99
-
-#define nvhdmi_master_con_nid_7x	0x04
-#define nvhdmi_master_pin_nid_7x	0x05
-
-#define nvhdmi_master_con_nid_89	0x04
-#define nvhdmi_master_pin_nid_89	0x05
-
-static hda_nid_t nvhdmi_con_nids_7x[4] = {
-	/*front, rear, clfe, rear_surr */
-	0x6, 0x8, 0xa, 0xc,
-};
-
-static struct hda_verb nvhdmi_basic_init_7x[] = {
-	/* set audio protect on */
-	{ 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
-	/* enable digital output on pin widget */
-	{ 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
-	{ 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
-	{ 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
-	{ 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
-	{ 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
-	{} /* terminator */
-};
-
-#ifdef LIMITED_RATE_FMT_SUPPORT
-/* support only the safe format and rate */
-#define SUPPORTED_RATES		SNDRV_PCM_RATE_48000
-#define SUPPORTED_MAXBPS	16
-#define SUPPORTED_FORMATS	SNDRV_PCM_FMTBIT_S16_LE
-#else
-/* support all rates and formats */
-#define SUPPORTED_RATES \
-	(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
-	SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
-	 SNDRV_PCM_RATE_192000)
-#define SUPPORTED_MAXBPS	24
-#define SUPPORTED_FORMATS \
-	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
-#endif
-
-/*
- * Controls
- */
-static int nvhdmi_build_controls(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	int err;
-	int i;
-
-	if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
-	|| (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
-		for (i = 0; i < codec->num_pcms; i++) {
-			err = snd_hda_create_spdif_out_ctls(codec,
-							    spec->cvt[i]);
-			if (err < 0)
-				return err;
-		}
-	} else {
-		err = snd_hda_create_spdif_out_ctls(codec,
-						    spec->multiout.dig_out_nid);
-		if (err < 0)
-			return err;
-	}
-
-	return 0;
-}
-
-static int nvhdmi_init(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	int i;
-	if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
-	|| (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
-		for (i = 0; spec->pin[i]; i++) {
-			hdmi_enable_output(codec, spec->pin[i]);
-			snd_hda_codec_write(codec, spec->pin[i], 0,
-					    AC_VERB_SET_UNSOLICITED_ENABLE,
-					    AC_USRSP_EN | spec->pin[i]);
-		}
-	} else {
-		snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
-	}
-	return 0;
-}
-
-static void nvhdmi_free(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	int i;
-
-	if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
-	|| (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
-		for (i = 0; i < spec->num_pins; i++)
-			snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
-	}
-
-	kfree(spec);
-}
-
-/*
- * Digital out
- */
-static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					struct snd_pcm_substream *substream)
-{
-	struct hdmi_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
-
-static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					struct snd_pcm_substream *substream)
-{
-	struct hdmi_spec *spec = codec->spec;
-	int i;
-
-	snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
-			0, AC_VERB_SET_CHANNEL_STREAMID, 0);
-	for (i = 0; i < 4; i++) {
-		/* set the stream id */
-		snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
-				AC_VERB_SET_CHANNEL_STREAMID, 0);
-		/* set the stream format */
-		snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
-				AC_VERB_SET_STREAM_FORMAT, 0);
-	}
-
-	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					struct snd_pcm_substream *substream)
-{
-	struct hdmi_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
-}
-
-static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					unsigned int stream_tag,
-					unsigned int format,
-					struct snd_pcm_substream *substream)
-{
-	hdmi_set_channel_count(codec, hinfo->nid,
-			       substream->runtime->channels);
-
-	hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
-
-	return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
-}
-
-static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					unsigned int stream_tag,
-					unsigned int format,
-					struct snd_pcm_substream *substream)
-{
-	int chs;
-	unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id;
-	int i;
-
-	mutex_lock(&codec->spdif_mutex);
-
-	chs = substream->runtime->channels;
-	chan = chs ? (chs - 1) : 1;
-
-	switch (chs) {
-	default:
-	case 0:
-	case 2:
-		chanmask = 0x00;
-		break;
-	case 4:
-		chanmask = 0x08;
-		break;
-	case 6:
-		chanmask = 0x0b;
-		break;
-	case 8:
-		chanmask = 0x13;
-		break;
-	}
-	dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT;
-	dataDCC2 = 0x2;
-
-	/* set the Audio InforFrame Channel Allocation */
-	snd_hda_codec_write(codec, 0x1, 0,
-			Nv_VERB_SET_Channel_Allocation, chanmask);
-
-	/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
-	if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
-		snd_hda_codec_write(codec,
-				nvhdmi_master_con_nid_7x,
-				0,
-				AC_VERB_SET_DIGI_CONVERT_1,
-				codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
-
-	/* set the stream id */
-	snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
-			AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
-
-	/* set the stream format */
-	snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
-			AC_VERB_SET_STREAM_FORMAT, format);
-
-	/* turn on again (if needed) */
-	/* enable and set the channel status audio/data flag */
-	if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
-		snd_hda_codec_write(codec,
-				nvhdmi_master_con_nid_7x,
-				0,
-				AC_VERB_SET_DIGI_CONVERT_1,
-				codec->spdif_ctls & 0xff);
-		snd_hda_codec_write(codec,
-				nvhdmi_master_con_nid_7x,
-				0,
-				AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
-	}
-
-	for (i = 0; i < 4; i++) {
-		if (chs == 2)
-			channel_id = 0;
-		else
-			channel_id = i * 2;
-
-		/* turn off SPDIF once;
-		 *otherwise the IEC958 bits won't be updated
-		 */
-		if (codec->spdif_status_reset &&
-		(codec->spdif_ctls & AC_DIG1_ENABLE))
-			snd_hda_codec_write(codec,
-				nvhdmi_con_nids_7x[i],
-				0,
-				AC_VERB_SET_DIGI_CONVERT_1,
-				codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
-		/* set the stream id */
-		snd_hda_codec_write(codec,
-				nvhdmi_con_nids_7x[i],
-				0,
-				AC_VERB_SET_CHANNEL_STREAMID,
-				(stream_tag << 4) | channel_id);
-		/* set the stream format */
-		snd_hda_codec_write(codec,
-				nvhdmi_con_nids_7x[i],
-				0,
-				AC_VERB_SET_STREAM_FORMAT,
-				format);
-		/* turn on again (if needed) */
-		/* enable and set the channel status audio/data flag */
-		if (codec->spdif_status_reset &&
-		(codec->spdif_ctls & AC_DIG1_ENABLE)) {
-			snd_hda_codec_write(codec,
-					nvhdmi_con_nids_7x[i],
-					0,
-					AC_VERB_SET_DIGI_CONVERT_1,
-					codec->spdif_ctls & 0xff);
-			snd_hda_codec_write(codec,
-					nvhdmi_con_nids_7x[i],
-					0,
-					AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
-		}
-	}
-
-	/* set the Audio Info Frame Checksum */
-	snd_hda_codec_write(codec, 0x1, 0,
-			Nv_VERB_SET_Info_Frame_Checksum,
-			(0x71 - chan - chanmask));
-
-	mutex_unlock(&codec->spdif_mutex);
-	return 0;
-}
-
-static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					unsigned int stream_tag,
-					unsigned int format,
-					struct snd_pcm_substream *substream)
-{
-	struct hdmi_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
-					format, substream);
-}
-
-static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
-	.substreams = 1,
-	.channels_min = 2,
-	.ops = {
-		.open = hdmi_pcm_open,
-		.prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
-	},
-};
-
-static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 8,
-	.nid = nvhdmi_master_con_nid_7x,
-	.rates = SUPPORTED_RATES,
-	.maxbps = SUPPORTED_MAXBPS,
-	.formats = SUPPORTED_FORMATS,
-	.ops = {
-		.open = nvhdmi_dig_playback_pcm_open,
-		.close = nvhdmi_dig_playback_pcm_close_8ch_7x,
-		.prepare = nvhdmi_dig_playback_pcm_prepare_8ch
-	},
-};
-
-static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 2,
-	.nid = nvhdmi_master_con_nid_7x,
-	.rates = SUPPORTED_RATES,
-	.maxbps = SUPPORTED_MAXBPS,
-	.formats = SUPPORTED_FORMATS,
-	.ops = {
-		.open = nvhdmi_dig_playback_pcm_open,
-		.close = nvhdmi_dig_playback_pcm_close_2ch,
-		.prepare = nvhdmi_dig_playback_pcm_prepare_2ch
-	},
-};
-
-static int nvhdmi_build_pcms_8ch_89(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;
-
-		chans = get_wcaps(codec, spec->cvt[i]);
-		chans = get_wcaps_channels(chans);
-
-		info->name = nvhdmi_pcm_names[i];
-		info->pcm_type = HDA_PCM_TYPE_HDMI;
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK]
-					= nvhdmi_pcm_digital_playback_8ch_89;
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
-		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
-	}
-
-	return 0;
-}
-
-static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	struct hda_pcm *info = spec->pcm_rec;
-
-	codec->num_pcms = 1;
-	codec->pcm_info = info;
-
-	info->name = "NVIDIA HDMI";
-	info->pcm_type = HDA_PCM_TYPE_HDMI;
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK]
-					= nvhdmi_pcm_digital_playback_8ch_7x;
-
-	return 0;
-}
-
-static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec = codec->spec;
-	struct hda_pcm *info = spec->pcm_rec;
-
-	codec->num_pcms = 1;
-	codec->pcm_info = info;
-
-	info->name = "NVIDIA HDMI";
-	info->pcm_type = HDA_PCM_TYPE_HDMI;
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK]
-					= nvhdmi_pcm_digital_playback_2ch;
-
-	return 0;
-}
-
-static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
-	.build_controls = nvhdmi_build_controls,
-	.build_pcms = nvhdmi_build_pcms_8ch_89,
-	.init = nvhdmi_init,
-	.free = nvhdmi_free,
-	.unsol_event = hdmi_unsol_event,
-};
-
-static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
-	.build_controls = nvhdmi_build_controls,
-	.build_pcms = nvhdmi_build_pcms_8ch_7x,
-	.init = nvhdmi_init,
-	.free = nvhdmi_free,
-};
-
-static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
-	.build_controls = nvhdmi_build_controls,
-	.build_pcms = nvhdmi_build_pcms_2ch,
-	.init = nvhdmi_init,
-	.free = nvhdmi_free,
-};
-
-static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec;
-	int i;
-
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
-	spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
-	spec->old_pin_detect = 1;
-
-	if (hdmi_parse_codec(codec) < 0) {
-		codec->spec = NULL;
-		kfree(spec);
-		return -EINVAL;
-	}
-	codec->patch_ops = nvhdmi_patch_ops_8ch_89;
-
-	for (i = 0; i < spec->num_pins; i++)
-		snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
-
-	init_channel_allocations();
-
-	return 0;
-}
-
-static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec;
-
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
-
-	spec->multiout.num_dacs = 0;  /* no analog */
-	spec->multiout.max_channels = 8;
-	spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
-	spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
-	spec->old_pin_detect = 1;
-
-	codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
-
-	return 0;
-}
-
-static int patch_nvhdmi_2ch(struct hda_codec *codec)
-{
-	struct hdmi_spec *spec;
-
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
-
-	spec->multiout.num_dacs = 0;  /* no analog */
-	spec->multiout.max_channels = 2;
-	spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
-	spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
-	spec->old_pin_detect = 1;
-
-	codec->patch_ops = nvhdmi_patch_ops_2ch;
-
-	return 0;
-}
-
-/*
- * patch entries
- */
-static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
-	{ .id = 0x10de0002, .name = "MCP77/78 HDMI",  .patch = patch_nvhdmi_8ch_7x },
-	{ .id = 0x10de0003, .name = "MCP77/78 HDMI",  .patch = patch_nvhdmi_8ch_7x },
-	{ .id = 0x10de0005, .name = "MCP77/78 HDMI",  .patch = patch_nvhdmi_8ch_7x },
-	{ .id = 0x10de0006, .name = "MCP77/78 HDMI",  .patch = patch_nvhdmi_8ch_7x },
-	{ .id = 0x10de0007, .name = "MCP79/7A HDMI",  .patch = patch_nvhdmi_8ch_7x },
-	{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de000c, .name = "MCP89 HDMI",     .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
-	{ .id = 0x10de0067, .name = "MCP67 HDMI",     .patch = patch_nvhdmi_2ch },
-	{ .id = 0x10de8001, .name = "MCP73 HDMI",     .patch = patch_nvhdmi_2ch },
-	{} /* terminator */
-};
-
-MODULE_ALIAS("snd-hda-codec-id:10de0002");
-MODULE_ALIAS("snd-hda-codec-id:10de0003");
-MODULE_ALIAS("snd-hda-codec-id:10de0005");
-MODULE_ALIAS("snd-hda-codec-id:10de0006");
-MODULE_ALIAS("snd-hda-codec-id:10de0007");
-MODULE_ALIAS("snd-hda-codec-id:10de000a");
-MODULE_ALIAS("snd-hda-codec-id:10de000b");
-MODULE_ALIAS("snd-hda-codec-id:10de000c");
-MODULE_ALIAS("snd-hda-codec-id:10de000d");
-MODULE_ALIAS("snd-hda-codec-id:10de0010");
-MODULE_ALIAS("snd-hda-codec-id:10de0011");
-MODULE_ALIAS("snd-hda-codec-id:10de0012");
-MODULE_ALIAS("snd-hda-codec-id:10de0013");
-MODULE_ALIAS("snd-hda-codec-id:10de0014");
-MODULE_ALIAS("snd-hda-codec-id:10de0018");
-MODULE_ALIAS("snd-hda-codec-id:10de0019");
-MODULE_ALIAS("snd-hda-codec-id:10de001a");
-MODULE_ALIAS("snd-hda-codec-id:10de001b");
-MODULE_ALIAS("snd-hda-codec-id:10de001c");
-MODULE_ALIAS("snd-hda-codec-id:10de0040");
-MODULE_ALIAS("snd-hda-codec-id:10de0041");
-MODULE_ALIAS("snd-hda-codec-id:10de0042");
-MODULE_ALIAS("snd-hda-codec-id:10de0043");
-MODULE_ALIAS("snd-hda-codec-id:10de0044");
-MODULE_ALIAS("snd-hda-codec-id:10de0067");
-MODULE_ALIAS("snd-hda-codec-id:10de8001");
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
-
-static struct hda_codec_preset_list nvhdmi_list = {
-	.preset = snd_hda_preset_nvhdmi,
-	.owner = THIS_MODULE,
-};
-
-static int __init patch_nvhdmi_init(void)
-{
-	return snd_hda_add_codec_preset(&nvhdmi_list);
-}
-
-static void __exit patch_nvhdmi_exit(void)
-{
-	snd_hda_delete_codec_preset(&nvhdmi_list);
-}
-
-module_init(patch_nvhdmi_init)
-module_exit(patch_nvhdmi_exit)
-- 
1.7.2.1


[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-15 14:48 Unifying sound/pci/hda/patch_*hdmi.c Takashi Iwai
@ 2010-09-15 14:51 ` Wu Fengguang
  2010-09-15 15:01 ` Wu Fengguang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Wu Fengguang @ 2010-09-15 14:51 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Stephen Warren, wni

Thanks. I'll test it on Intel hardware tomorrow :)

On Wed, Sep 15, 2010 at 04:48:55PM +0200, Takashi Iwai wrote:
> Hi,
> 
> the below is a patch for unifying three patch_*hdmi.c into a single
> file.  I'd like to push this to 2.6.37, so please review, especially
> whether it can break Nvidia hardware (since I have no h/w available).
> 
> In future, we can reduce ATI- and Nvidia-specific codes gradually
> after confirming the generic parser works.
> 
> The patch is found in sound-unstable git tree, too.  The corresponding
> alsa-driver-unstable tarball can be used for external builds.
> 
> 
> thanks,
> 
> Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-15 14:48 Unifying sound/pci/hda/patch_*hdmi.c Takashi Iwai
  2010-09-15 14:51 ` Wu Fengguang
@ 2010-09-15 15:01 ` Wu Fengguang
  2010-09-15 15:03 ` Wu Fengguang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Wu Fengguang @ 2010-09-15 15:01 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Stephen Warren, wni

Takashi,

Since the driver will also be supporting DisplayPort audio,
would you add "DisplayPort" too in the following chunk?

        +config SND_HDA_CODEC_HDMI
==>     +       bool "Build HDMI HD-audio codec support"
                select SND_DYNAMIC_MINORS
                default y
                help
        -         Say Y here to include INTEL HDMI HD-audio codec support in
        -         snd-hda-intel driver, such as Eaglelake integrated HDMI.
==>     +         Say Y here to include HDMI HD-audio codec support in
        +         snd-hda-intel driver.  This includes all AMD/ATI, Intel and
==>     +         Nvidia HDMI codecs.
                 

Thanks,
Fengguang

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-15 14:48 Unifying sound/pci/hda/patch_*hdmi.c Takashi Iwai
  2010-09-15 14:51 ` Wu Fengguang
  2010-09-15 15:01 ` Wu Fengguang
@ 2010-09-15 15:03 ` Wu Fengguang
  2010-09-15 15:08   ` Takashi Iwai
  2010-09-16 18:10 ` Stephen Warren
  2010-09-19  7:29 ` Wu Fengguang
  4 siblings, 1 reply; 8+ messages in thread
From: Wu Fengguang @ 2010-09-15 15:03 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Stephen Warren, wni


+ * Nvidia specific implmenetations

s/implmenetations/implementations/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-15 15:03 ` Wu Fengguang
@ 2010-09-15 15:08   ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2010-09-15 15:08 UTC (permalink / raw)
  To: Wu Fengguang; +Cc: alsa-devel, Stephen Warren, wni

At Wed, 15 Sep 2010 23:03:27 +0800,
Wu Fengguang wrote:
> 
> 
> + * Nvidia specific implmenetations
> 
> s/implmenetations/implementations/

Thanks, fixed both now.


Takashi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-15 14:48 Unifying sound/pci/hda/patch_*hdmi.c Takashi Iwai
                   ` (2 preceding siblings ...)
  2010-09-15 15:03 ` Wu Fengguang
@ 2010-09-16 18:10 ` Stephen Warren
  2010-09-16 20:41   ` Takashi Iwai
  2010-09-19  7:29 ` Wu Fengguang
  4 siblings, 1 reply; 8+ messages in thread
From: Stephen Warren @ 2010-09-16 18:10 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang, Wei Ni

Takashi Iwai wrote:
> the below is a patch for unifying three patch_*hdmi.c into a single
> file.  I'd like to push this to 2.6.37, so please review, especially
> whether it can break Nvidia hardware (since I have no h/w available).

First off, in general, I think working towards unifying all the HDMI
code is a great goal.

However, this patch worries me a bit because it significantly changes
the way some parts of the code work at the same time as performing the
refactoring...

In particular, after a brief skim, I see the following issues:

+static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+	int err = patch_generic_hdmi(codec);
+
+	if (err < 0)
+		return err;
+	spec = codec->spec;
+	spec->old_pin_detect = 1;
+	spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;

That last line is definitely wrong as far as I can tell. Just delete
it?

+	return 0;
+}

+static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec;
+	int err = patch_generic_hdmi(codec);

The old nvhdmi_8ch_7x code was custom like nvhdmi_2ch. Unfortunately, I'm
not familiar with the old HW nor why it used custom code instead of the
generic parser. This seems like a risky change without testing.

One behavioral change I see is that patch_generic_hdmi will call
snd_hda_eld_proc_new, which wasn't previously called for this codec type.
Yet, nvhdmi_patch_ops_8ch_7x doesn't point unsol_event at hdmi_unsol_event,
so the ELD stuff won't work. I don't know if the unsolicited event logic in
the HW works on this chip or not, given the Linux driver hasn't used it
before. I suppose it has to work, but who knows...

Related,

+static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
+	.build_controls = generic_hdmi_build_controls,
+	.build_pcms = generic_hdmi_build_pcms,
+	.init = nvhdmi_7x_init,
+	.free = generic_hdmi_free,
+};

Generic_hdmi_free calls snd_hda_eld_proc_free. Since nvhdmi_7x_init
doesn't call generic_hdmi_init, will that attempt to free ELD structures
that aren't allocated?

Once the above issues are thought through, I can try to find time to test
this on HW. Unfortunately, I definitely don't have any of the "2ch" HW
available to test at all. I do have a small subset of the "8ch_7x" and
"8ch_89" HW (although my only HDMI sink at work only supports 2-channel
audio). Also, my allotted time to work on the audio driver is very small
right now, plus I'll be away from the office next week and hence won't
have HW access to test anything anyway. Sorry I suck at being a tester!

> In future, we can reduce ATI- and Nvidia-specific codes gradually after
> confirming the generic parser works.
> 
> The patch is found in sound-unstable git tree, too.  The corresponding
> alsa-driver-unstable tarball can be used for external builds.
> 
> 
> thanks,
> 
> Takashi

-- 
nvpublic

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-16 18:10 ` Stephen Warren
@ 2010-09-16 20:41   ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2010-09-16 20:41 UTC (permalink / raw)
  To: Stephen Warren; +Cc: alsa-devel, Wu Fengguang, Wei Ni

At Thu, 16 Sep 2010 11:10:13 -0700,
Stephen Warren wrote:
> 
> Takashi Iwai wrote:
> > the below is a patch for unifying three patch_*hdmi.c into a single
> > file.  I'd like to push this to 2.6.37, so please review, especially
> > whether it can break Nvidia hardware (since I have no h/w available).
> 
> First off, in general, I think working towards unifying all the HDMI
> code is a great goal.
> 
> However, this patch worries me a bit because it significantly changes
> the way some parts of the code work at the same time as performing the
> refactoring...
> 
> In particular, after a brief skim, I see the following issues:
> 
> +static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
> +{
> +	struct hdmi_spec *spec;
> +	int err = patch_generic_hdmi(codec);
> +
> +	if (err < 0)
> +		return err;
> +	spec = codec->spec;
> +	spec->old_pin_detect = 1;
> +	spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
> 
> That last line is definitely wrong as far as I can tell. Just delete
> it?

Ah, crap, this has to be removed.


> +	return 0;
> +}
> 
> +static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
> +{
> +	struct hdmi_spec *spec;
> +	int err = patch_generic_hdmi(codec);
> 
> The old nvhdmi_8ch_7x code was custom like nvhdmi_2ch. Unfortunately, I'm
> not familiar with the old HW nor why it used custom code instead of the
> generic parser. This seems like a risky change without testing.

Looks like I did wrong copy&paste here and there.  It was intended to
call patch_nvhdmi_2ch() instead.  The additional fix patch is below.


> One behavioral change I see is that patch_generic_hdmi will call
> snd_hda_eld_proc_new, which wasn't previously called for this codec type.
> Yet, nvhdmi_patch_ops_8ch_7x doesn't point unsol_event at hdmi_unsol_event,
> so the ELD stuff won't work. I don't know if the unsolicited event logic in
> the HW works on this chip or not, given the Linux driver hasn't used it
> before. I suppose it has to work, but who knows...
> 
> Related,
> 
> +static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
> +	.build_controls = generic_hdmi_build_controls,
> +	.build_pcms = generic_hdmi_build_pcms,
> +	.init = nvhdmi_7x_init,
> +	.free = generic_hdmi_free,
> +};
> 
> Generic_hdmi_free calls snd_hda_eld_proc_free. Since nvhdmi_7x_init
> doesn't call generic_hdmi_init, will that attempt to free ELD structures
> that aren't allocated?

The call of snd_hda_eld_proc_free() is harmless, so I chose one
function to reduce rather than having two. 


> Once the above issues are thought through, I can try to find time to test
> this on HW. Unfortunately, I definitely don't have any of the "2ch" HW
> available to test at all. I do have a small subset of the "8ch_7x" and
> "8ch_89" HW (although my only HDMI sink at work only supports 2-channel
> audio). Also, my allotted time to work on the audio driver is very small
> right now, plus I'll be away from the office next week and hence won't
> have HW access to test anything anyway. Sorry I suck at being a tester!

OK, no problem.
Thanks for review, anyway.


Takashi

---
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index c6d183e..7d4ed7f 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1352,7 +1352,6 @@ static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
 		return err;
 	spec = codec->spec;
 	spec->old_pin_detect = 1;
-	spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
 	return 0;
 }
 
@@ -1382,12 +1381,13 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
 static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
 {
 	struct hdmi_spec *spec;
-	int err = patch_generic_hdmi(codec);
+	int err = patch_nvhdmi_2ch(codec);
 
 	if (err < 0)
 		return err;
 	spec = codec->spec;
 	spec->multiout.max_channels = 8;
+	spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x;
 	codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: Unifying sound/pci/hda/patch_*hdmi.c
  2010-09-15 14:48 Unifying sound/pci/hda/patch_*hdmi.c Takashi Iwai
                   ` (3 preceding siblings ...)
  2010-09-16 18:10 ` Stephen Warren
@ 2010-09-19  7:29 ` Wu Fengguang
  4 siblings, 0 replies; 8+ messages in thread
From: Wu Fengguang @ 2010-09-19  7:29 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Stephen Warren, wni

On Wed, Sep 15, 2010 at 04:48:55PM +0200, Takashi Iwai wrote:
> Hi,
> 
> the below is a patch for unifying three patch_*hdmi.c into a single
> file.  I'd like to push this to 2.6.37, so please review, especially
> whether it can break Nvidia hardware (since I have no h/w available).

It works on Eaglelake (G45) and CougarPoint. I cannot find a IbexPeak
box for test for now, however its codec file is almost the same as
CougarPoint, so there should be no big problem.

Thanks,
Fengguang

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-09-19  7:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-15 14:48 Unifying sound/pci/hda/patch_*hdmi.c Takashi Iwai
2010-09-15 14:51 ` Wu Fengguang
2010-09-15 15:01 ` Wu Fengguang
2010-09-15 15:03 ` Wu Fengguang
2010-09-15 15:08   ` Takashi Iwai
2010-09-16 18:10 ` Stephen Warren
2010-09-16 20:41   ` Takashi Iwai
2010-09-19  7:29 ` Wu Fengguang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.