aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_auto_parser.c37
-rw-r--r--sound/pci/hda/hda_local.h14
2 files changed, 51 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 36961ab3b81d..a14275326234 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -839,6 +839,43 @@ 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 if (pins->val != def_conf)
848 return false;
849 }
850 return true;
851}
852
853void snd_hda_pick_pin_fixup(struct hda_codec *codec,
854 const struct snd_hda_pin_quirk *pin_quirk,
855 const struct hda_fixup *fixlist)
856{
857 const struct snd_hda_pin_quirk *pq;
858
859 if (codec->fixup_forced)
860 return;
861
862 for (pq = pin_quirk; pq->subvendor; pq++) {
863 if (codec->bus->pci->subsystem_vendor != pq->subvendor)
864 continue;
865 if (codec->vendor_id != pq->codec)
866 continue;
867 if (pin_config_match(codec, pq->pins)) {
868 codec->fixup_id = pq->value;
869#ifdef CONFIG_SND_DEBUG_VERBOSE
870 codec->fixup_name = pq->name;
871#endif
872 codec->fixup_list = fixlist;
873 return;
874 }
875 }
876}
877EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup);
878
842void snd_hda_pick_fixup(struct hda_codec *codec, 879void snd_hda_pick_fixup(struct hda_codec *codec,
843 const struct hda_model_fixup *models, 880 const struct hda_model_fixup *models,
844 const struct snd_pci_quirk *quirk, 881 const struct snd_pci_quirk *quirk,
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index e51d15529215..ebd1fa6f015c 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -407,6 +407,16 @@ struct hda_fixup {
407 } v; 407 } v;
408}; 408};
409 409
410struct snd_hda_pin_quirk {
411 unsigned int codec; /* Codec vendor/device ID */
412 unsigned short subvendor; /* PCI subvendor ID */
413 const struct hda_pintbl *pins; /* list of matching pins */
414#ifdef CONFIG_SND_DEBUG_VERBOSE
415 const char *name;
416#endif
417 int value; /* quirk value */
418};
419
410/* fixup types */ 420/* fixup types */
411enum { 421enum {
412 HDA_FIXUP_INVALID, 422 HDA_FIXUP_INVALID,
@@ -434,6 +444,10 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
434 const struct hda_model_fixup *models, 444 const struct hda_model_fixup *models,
435 const struct snd_pci_quirk *quirk, 445 const struct snd_pci_quirk *quirk,
436 const struct hda_fixup *fixlist); 446 const struct hda_fixup *fixlist);
447void snd_hda_pick_pin_fixup(struct hda_codec *codec,
448 const struct snd_hda_pin_quirk *pin_quirk,
449 const struct hda_fixup *fixlist);
450
437 451
438/* 452/*
439 * unsolicited event handler 453 * unsolicited event handler