summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2007-02-25 06:17:56 +0000
committerariff <ariff@FreeBSD.org>2007-02-25 06:17:56 +0000
commiteb8824b9ca7736992c941a965af390f675f50597 (patch)
treeb214201b6bdd8ab73270958b10a82a1ffafd9c55 /sys
parent573a964db6deb3f61961bfe0f4586caa6b8cbb9e (diff)
downloadFreeBSD-src-eb8824b9ca7736992c941a965af390f675f50597.zip
FreeBSD-src-eb8824b9ca7736992c941a965af390f675f50597.tar.gz
Fix ALC883 microphone / recording issues. Setting high(er) VRef on
(external) microphone pin tend to screw it. Internal microphone (found on several laptops) still need high VRef. Tested by: Pietro Cerutti <pietro.cerutti@gmail.com> lenix <irc.freenode.net>
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sound/pci/hda/hdac.c99
1 files changed, 95 insertions, 4 deletions
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 5b7c163..ccc3b9b 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -80,7 +80,7 @@
#include "mixer_if.h"
-#define HDA_DRV_TEST_REV "20070128_0039"
+#define HDA_DRV_TEST_REV "20070225_0040"
#define HDA_WIDGET_PARSER_REV 1
SND_DECLARE_FILE("$FreeBSD$");
@@ -1690,7 +1690,7 @@ static uint32_t
hdac_widget_pin_getconfig(struct hdac_widget *w)
{
struct hdac_softc *sc;
- uint32_t config, id;
+ uint32_t config, orig, id;
nid_t cad, nid;
sc = w->devinfo->codec->sc;
@@ -1701,6 +1701,8 @@ hdac_widget_pin_getconfig(struct hdac_widget *w)
config = hdac_command(sc,
HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid),
cad);
+ orig = config;
+
/*
* XXX REWRITE!!!! Don't argue!
*/
@@ -1757,11 +1759,72 @@ hdac_widget_pin_getconfig(struct hdac_widget *w)
default:
break;
}
+ } else if (id == HDA_CODEC_ALC883 &&
+ HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, sc->pci_subvendor)) {
+ switch (nid) {
+ case 25:
+ config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+ config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+ break;
+ default:
+ break;
+ }
+ } else if (id == HDA_CODEC_CXVENICE && sc->pci_subvendor ==
+ HP_V3000_SUBVENDOR) {
+ switch (nid) {
+ case 18:
+ config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
+ config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
+ break;
+ case 20:
+ config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
+ config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
+ break;
+ default:
+ break;
+ }
}
+ HDA_BOOTVERBOSE(
+ if (config != orig)
+ device_printf(sc->dev,
+ "HDA_DEBUG: Pin config nid=%u 0x%08x -> 0x%08x\n",
+ nid, orig, config);
+ );
+
return (config);
}
+static uint32_t
+hdac_widget_pin_getcaps(struct hdac_widget *w)
+{
+ struct hdac_softc *sc;
+ uint32_t caps, orig, id;
+ nid_t cad, nid;
+
+ sc = w->devinfo->codec->sc;
+ cad = w->devinfo->codec->cad;
+ nid = w->nid;
+ id = hdac_codec_id(w->devinfo);
+
+ caps = hdac_command(sc,
+ HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_PIN_CAP), cad);
+ orig = caps;
+
+ HDA_BOOTVERBOSE(
+ if (caps != orig)
+ device_printf(sc->dev,
+ "HDA_DEBUG: Pin caps nid=%u 0x%08x -> 0x%08x\n",
+ nid, orig, caps);
+ );
+
+ return (caps);
+}
+
static void
hdac_widget_pin_parse(struct hdac_widget *w)
{
@@ -1774,8 +1837,7 @@ hdac_widget_pin_parse(struct hdac_widget *w)
config = hdac_widget_pin_getconfig(w);
w->wclass.pin.config = config;
- pincap = hdac_command(sc,
- HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_PIN_CAP), cad);
+ pincap = hdac_widget_pin_getcaps(w);
w->wclass.pin.cap = pincap;
w->wclass.pin.ctrl = hdac_command(sc,
@@ -3653,6 +3715,35 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo)
}
}
break;
+ case HDA_CODEC_ALC883:
+ /*
+ * nid: 24/25 = External (jack) or Internal (fixed) Mic.
+ * Clear vref cap for jack connectivity.
+ */
+ w = hdac_widget_get(devinfo, 24);
+ if (w != NULL && w->enable != 0 && w->type ==
+ HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+ (w->wclass.pin.config &
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) ==
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK)
+ w->wclass.pin.cap &= ~(
+ HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK |
+ HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK |
+ HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK);
+ w = hdac_widget_get(devinfo, 25);
+ if (w != NULL && w->enable != 0 && w->type ==
+ HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
+ (w->wclass.pin.config &
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) ==
+ HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK)
+ w->wclass.pin.cap &= ~(
+ HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK |
+ HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK |
+ HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK);
+ /*
+ * nid: 26 = Line-in, leave it alone.
+ */
+ break;
case HDA_CODEC_AD1981HD:
w = hdac_widget_get(devinfo, 11);
if (w != NULL && w->enable != 0 && w->nconns > 3)
OpenPOWER on IntegriCloud