summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c61
-rw-r--r--sound/pci/hda/hda_local.h3
2 files changed, 64 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 004344825e9..9c1af0101dd 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2705,6 +2705,67 @@ int snd_hda_check_board_config(struct hda_codec *codec,
EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
/**
+ * 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;
+}
+EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
+
+/**
* 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 6f2fe0f9fdd..1dd8716c387 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -296,6 +296,9 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen);
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);