aboutsummaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 841475cc13b6..393a3043a46e 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4795,6 +4795,59 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
+/**
+ * snd_hda_get_default_vref - Get the default (mic) VREF pin bits
+ *
+ * Guess the suitable VREF pin bits to be set as the pin-control value.
+ * Note: the function doesn't set the AC_PINCTL_IN_EN bit.
+ */
+unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
+{
+ unsigned int pincap;
+ unsigned int oldval;
+ oldval = snd_hda_codec_read(codec, pin, 0,
+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+ pincap = snd_hda_query_pin_caps(codec, pin);
+ pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+ /* Exception: if the default pin setup is vref50, we give it priority */
+ if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
+ return AC_PINCTL_VREF_80;
+ else if (pincap & AC_PINCAP_VREF_50)
+ return AC_PINCTL_VREF_50;
+ else if (pincap & AC_PINCAP_VREF_100)
+ return AC_PINCTL_VREF_100;
+ else if (pincap & AC_PINCAP_VREF_GRD)
+ return AC_PINCTL_VREF_GRD;
+ return AC_PINCTL_VREF_HIZ;
+}
+EXPORT_SYMBOL_HDA(snd_hda_get_default_vref);
+
+int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
+ unsigned int val, bool cached)
+{
+ if (val) {
+ unsigned int cap = snd_hda_query_pin_caps(codec, pin);
+ if (cap && (val & AC_PINCTL_OUT_EN)) {
+ if (!(cap & AC_PINCAP_OUT))
+ val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
+ else if ((val & AC_PINCTL_HP_EN) &&
+ !(cap & AC_PINCAP_HP_DRV))
+ val &= ~AC_PINCTL_HP_EN;
+ }
+ if (cap && (val & AC_PINCTL_IN_EN)) {
+ if (!(cap & AC_PINCAP_IN))
+ val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
+ }
+ }
+ if (cached)
+ return snd_hda_codec_update_cache(codec, pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+ else
+ return snd_hda_codec_write(codec, pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+}
+EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl);
+
/*
* Helper for automatic pin configuration
*/