diff options
Diffstat (limited to 'sound/pci/hda/hda_auto_parser.c')
-rw-r--r-- | sound/pci/hda/hda_auto_parser.c | 47 |
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 | } |
840 | EXPORT_SYMBOL_GPL(snd_hda_apply_fixup); | 840 | EXPORT_SYMBOL_GPL(snd_hda_apply_fixup); |
841 | 841 | ||
842 | static 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 | |||
854 | void 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 | } | ||
878 | EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup); | ||
879 | |||
842 | void snd_hda_pick_fixup(struct hda_codec *codec, | 880 | void 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; |