--- /dev/null
+From 2eda344546caaf9168e778a4007f4609e95106e0 Mon Sep 17 00:00:00 2001
+From: Mauro Carvalho Chehab <mchehab@infradead.org>
+Date: Mon, 11 Aug 2008 10:18:39 +0200
+Subject: ALSA: hda - Add a new function to seek for a codec ID
+Patch-mainline: 2.6.29-rc1
+References: bnc#460478
+
+Gateway notebooks have their ID inside codec vendor ID, not at PCI ID. Due to
+that, model auto-detection were not possible with the standard seek method.
+
+This is what is found at lspci -vnn:
+
+00:14.2 Audio device [0403]: ATI Technologies Inc SB450 HDA Audio [1002:437b] (rev 01)
+ Subsystem: ATI Technologies Inc SB450 HDA Audio [1002:437b]
+
+Yet, autodetection is possible, since the codec properly reflects the vendor at
+the Subsystem ID:
+
+$ cat /proc/asound/card0/codec#0 |head -4
+
+Codec: SigmaTel STAC9250
+Address: 0
+Vendor Id: 0x83847634
+Subsystem Id: 0x107b0367
+
+This patch adds a new autodetection function that seeks for codec subsystem ID.
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/pci/hda/hda_codec.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
+ sound/pci/hda/hda_local.h | 3 ++
+ 2 files changed, 63 insertions(+), 0 deletions(-)
+
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 0043448..9c1af01 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -2364,6 +2364,66 @@ int snd_hda_check_board_config(struct hd
+ }
+
+ /**
++ * snd_hda_check_board_codec_sid_config - compare the current codec
++ subsystem ID with the
++ config table
++
++ This is important for Gateway notebooks with SB450 HDA Audio
++ where the vendor ID of the PCI device is:
++ ATI Technologies Inc SB450 HDA Audio [1002:437b]
++ and the vendor/subvendor are found only at the codec.
++
++ * @codec: the HDA codec
++ * @num_configs: number of config enums
++ * @models: array of model name strings
++ * @tbl: configuration table, terminated by null entries
++ *
++ * Compares the modelname or PCI subsystem id of the current codec with the
++ * given configuration table. If a matching entry is found, returns its
++ * config value (supposed to be 0 or positive).
++ *
++ * If no entries are matching, the function returns a negative value.
++ */
++int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
++ int num_configs, const char **models,
++ const struct snd_pci_quirk *tbl)
++{
++ const struct snd_pci_quirk *q;
++
++ /* Search for codec ID */
++ for (q = tbl; q->subvendor; q++) {
++ unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
++
++ if (vendorid == codec->subsystem_id)
++ break;
++ }
++
++ if (!q->subvendor)
++ return -1;
++
++ tbl = q;
++
++ if (tbl->value >= 0 && tbl->value < num_configs) {
++#ifdef CONFIG_SND_DEBUG_DETECT
++ char tmp[10];
++ const char *model = NULL;
++ if (models)
++ model = models[tbl->value];
++ if (!model) {
++ sprintf(tmp, "#%d", tbl->value);
++ model = tmp;
++ }
++ snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
++ "for config %x:%x (%s)\n",
++ model, tbl->subvendor, tbl->subdevice,
++ (tbl->name ? tbl->name : "Unknown device"));
++#endif
++ return tbl->value;
++ }
++ return -1;
++}
++
++/**
+ * snd_hda_add_new_ctls - create controls from the array
+ * @codec: the HDA codec
+ * @knew: the array of struct snd_kcontrol_new
+diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
+index 6f2fe0f..1dd8716 100644
+--- a/sound/pci/hda/hda_local.h
++++ b/sound/pci/hda/hda_local.h
+@@ -288,6 +288,9 @@ static inline int snd_hda_codec_proc_new
+ int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
+ const char **modelnames,
+ const struct snd_pci_quirk *pci_list);
++int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
++ int num_configs, const char **models,
++ const struct snd_pci_quirk *tbl);
+ int snd_hda_add_new_ctls(struct hda_codec *codec,
+ struct snd_kcontrol_new *knew);
+
+--
+1.6.1
+