OSDN Git Service

ALSA: hda: Add modelname lookup and fixup for realtek codecs
authorTodd Broch <tbroch@chromium.org>
Mon, 6 Dec 2010 19:19:51 +0000 (11:19 -0800)
committerTakashi Iwai <tiwai@suse.de>
Thu, 9 Dec 2010 06:23:01 +0000 (07:23 +0100)
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>
sound/pci/hda/patch_realtek.c

index 0badeda..9ba4279 100644 (file)
@@ -1677,6 +1677,11 @@ struct alc_pincfg {
        u32 val;
 };
 
+struct alc_model_fixup {
+       const int id;
+       const char *name;
+};
+
 struct alc_fixup {
        unsigned int sku;
        const struct alc_pincfg *pins;
@@ -1685,23 +1690,19 @@ struct alc_fixup {
                     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;
        struct alc_spec *spec;
 
-       quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
-       if (!quirk)
-               return;
-       fix += quirk->value;
        cfg = fix->pins;
        if (pre_init && fix->sku) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
-                           codec->chip_name, quirk->name);
+                           codec->chip_name, modelname);
 #endif
                spec = codec->spec;
                spec->cdefine.sku_cfg = fix->sku;
@@ -1710,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec,
        if (pre_init && cfg) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
-                           codec->chip_name, quirk->name);
+                           codec->chip_name, modelname);
 #endif
                for (; cfg->nid; cfg++)
                        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) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
-                           codec->chip_name, quirk->name);
+                           codec->chip_name, modelname);
 #endif
                add_verb(codec->spec, fix->verbs);
        }
        if (fix->func) {
 #ifdef CONFIG_SND_DEBUG_VERBOSE
                snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
-                           codec->chip_name, quirk->name);
+                           codec->chip_name, modelname);
 #endif
                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,
                        unsigned int coef_idx)
 {