aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2014-05-26 04:22:41 -0400
committerTakashi Iwai <tiwai@suse.de>2014-05-26 05:03:53 -0400
commit20531415adf30877296ea89fb0e534ac87f6cc71 (patch)
tree78b27b039a771fd5671008cb692961092579ce0b
parentc21c8cf77f47e234b5724d24dd133dc034351327 (diff)
ALSA: hda - Add a new quirk match based on default pin configuration
Normally, we match on pci ssid only. This works but needs new code for every machine. To catch more machines in the same quirk, let's add a new type of quirk, where we match on 1) PCI Subvendor ID (i e, not device, just vendor) 2) Codec ID 3) Pin configuration default If all these three match, we could be reasonably certain that the quirk should apply to the machine even though it might not be the exact same device. Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-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