aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_auto_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_auto_parser.c')
-rw-r--r--sound/pci/hda/hda_auto_parser.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 90d2fda6c8f9..3cf913772e9b 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -839,6 +839,44 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action)
839} 839}
840EXPORT_SYMBOL_GPL(snd_hda_apply_fixup); 840EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
841 841
842static bool pin_config_match(struct hda_codec *codec,
843 const struct hda_pintbl *pins)
844{
845 for (; pins->nid; pins++) {
846 u32 def_conf = snd_hda_codec_get_pincfg(codec, pins->nid);
847 u32 mask = 0xffffff00;
848 if ((pins->val & mask) != (def_conf & mask))
849 return false;
850 }
851 return true;
852}
853
854void snd_hda_pick_pin_fixup(struct hda_codec *codec,
855 const struct snd_hda_pin_quirk *pin_quirk,
856 const struct hda_fixup *fixlist)
857{
858 const struct snd_hda_pin_quirk *pq;
859
860 if (codec->fixup_forced)
861 return;
862
863 for (pq = pin_quirk; pq->subvendor; pq++) {
864 if ((codec->subsystem_id & 0xffff0000) != (pq->subvendor << 16))
865 continue;
866 if (codec->vendor_id != pq->codec)
867 continue;
868 if (pin_config_match(codec, pq->pins)) {
869 codec->fixup_id = pq->value;
870#ifdef CONFIG_SND_DEBUG_VERBOSE
871 codec->fixup_name = pq->name;
872#endif
873 codec->fixup_list = fixlist;
874 return;
875 }
876 }
877}
878EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup);
879
842void snd_hda_pick_fixup(struct hda_codec *codec, 880void snd_hda_pick_fixup(struct hda_codec *codec,
843 const struct hda_model_fixup *models, 881 const struct hda_model_fixup *models,
844 const struct snd_pci_quirk *quirk, 882 const struct snd_pci_quirk *quirk,
@@ -852,15 +890,17 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
852 if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { 890 if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
853 codec->fixup_list = NULL; 891 codec->fixup_list = NULL;
854 codec->fixup_id = -1; 892 codec->fixup_id = -1;
893 codec->fixup_forced = 1;
855 return; 894 return;
856 } 895 }
857 896
858 if (codec->modelname && models) { 897 if (codec->modelname && models) {
859 while (models->name) { 898 while (models->name) {
860 if (!strcmp(codec->modelname, models->name)) { 899 if (!strcmp(codec->modelname, models->name)) {
861 id = models->id; 900 codec->fixup_id = models->id;
862 name = models->name; 901 codec->fixup_name = models->name;
863 break; 902 codec->fixup_forced = 1;
903 return;
864 } 904 }
865 models++; 905 models++;
866 } 906 }
@@ -889,6 +929,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
889 } 929 }
890 } 930 }
891 931
932 codec->fixup_forced = 0;
892 codec->fixup_id = id; 933 codec->fixup_id = id;
893 if (id >= 0) { 934 if (id >= 0) {
894 codec->fixup_list = fixlist; 935 codec->fixup_list = fixlist;