Преглед на файлове

ALSA: hda: Add modelname lookup and fixup for realtek codecs

Facilitate fixup for realtek codecs via modelname lookup of fixup
data.  Fallback to quirk based lookup in absence of model definition.

Signed-off-by: Todd Broch <tbroch@chromium.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Todd Broch преди 14 години
родител
ревизия
e1eb5f1006
променени са 1 файла, в които са добавени 49 реда и са изтрити 12 реда
  1. 49 12
      sound/pci/hda/patch_realtek.c

+ 49 - 12
sound/pci/hda/patch_realtek.c

@@ -1677,6 +1677,11 @@ struct alc_pincfg {
 	u32 val;
 	u32 val;
 };
 };
 
 
+struct alc_model_fixup {
+	const int id;
+	const char *name;
+};
+
 struct alc_fixup {
 struct alc_fixup {
 	unsigned int sku;
 	unsigned int sku;
 	const struct alc_pincfg *pins;
 	const struct alc_pincfg *pins;
@@ -1685,23 +1690,19 @@ struct alc_fixup {
 		     int pre_init);
 		     int pre_init);
 };
 };
 
 
-static void alc_pick_fixup(struct hda_codec *codec,
-			   const struct snd_pci_quirk *quirk,
-			   const struct alc_fixup *fix,
-			   int pre_init)
+static void __alc_pick_fixup(struct hda_codec *codec,
+			     const struct alc_fixup *fix,
+			     const char *modelname,
+			     int pre_init)
 {
 {
 	const struct alc_pincfg *cfg;
 	const struct alc_pincfg *cfg;
 	struct alc_spec *spec;
 	struct alc_spec *spec;
 
 
-	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
-	if (!quirk)
-		return;
-	fix += quirk->value;
 	cfg = fix->pins;
 	cfg = fix->pins;
 	if (pre_init && fix->sku) {
 	if (pre_init && fix->sku) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
-			    codec->chip_name, quirk->name);
+			    codec->chip_name, modelname);
 #endif
 #endif
 		spec = codec->spec;
 		spec = codec->spec;
 		spec->cdefine.sku_cfg = fix->sku;
 		spec->cdefine.sku_cfg = fix->sku;
@@ -1710,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec,
 	if (pre_init && cfg) {
 	if (pre_init && cfg) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
-			    codec->chip_name, quirk->name);
+			    codec->chip_name, modelname);
 #endif
 #endif
 		for (; cfg->nid; cfg++)
 		for (; cfg->nid; cfg++)
 			snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
 			snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
@@ -1718,19 +1719,55 @@ static void alc_pick_fixup(struct hda_codec *codec,
 	if (!pre_init && fix->verbs) {
 	if (!pre_init && fix->verbs) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
-			    codec->chip_name, quirk->name);
+			    codec->chip_name, modelname);
 #endif
 #endif
 		add_verb(codec->spec, fix->verbs);
 		add_verb(codec->spec, fix->verbs);
 	}
 	}
 	if (fix->func) {
 	if (fix->func) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
 		snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
-			    codec->chip_name, quirk->name);
+			    codec->chip_name, modelname);
 #endif
 #endif
 		fix->func(codec, fix, pre_init);
 		fix->func(codec, fix, pre_init);
 	}
 	}
 }
 }
 
 
+static void alc_pick_fixup(struct hda_codec *codec,
+				 const struct snd_pci_quirk *quirk,
+				 const struct alc_fixup *fix,
+				 int pre_init)
+{
+	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
+	if (quirk) {
+		fix += quirk->value;
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+		__alc_pick_fixup(codec, fix, quirk->name, pre_init);
+#else
+		__alc_pick_fixup(codec, fix, NULL, pre_init);
+#endif
+	}
+}
+
+static void alc_pick_fixup_model(struct hda_codec *codec,
+				 const struct alc_model_fixup *models,
+				 const struct snd_pci_quirk *quirk,
+				 const struct alc_fixup *fix,
+				 int pre_init)
+{
+	if (codec->modelname && models) {
+		while (models->name) {
+			if (!strcmp(codec->modelname, models->name)) {
+				fix += models->id;
+				break;
+			}
+			models++;
+		}
+		__alc_pick_fixup(codec, fix, codec->modelname, pre_init);
+	} else {
+		alc_pick_fixup(codec, quirk, fix, pre_init);
+	}
+}
+
 static int alc_read_coef_idx(struct hda_codec *codec,
 static int alc_read_coef_idx(struct hda_codec *codec,
 			unsigned int coef_idx)
 			unsigned int coef_idx)
 {
 {