summaryrefslogtreecommitdiff
path: root/sys/dev/pci/azalia_codec.c
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2008-11-19 03:44:15 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2008-11-19 03:44:15 +0000
commit2e126ab14cf2f2a94f19eed4060eec69a2c9e000 (patch)
tree3659b1eb9da708eb2af3507d17e73c6a291d663c /sys/dev/pci/azalia_codec.c
parenta92bbc472ac73b5869592a795d91fd88e6cc0311 (diff)
the jack sense automatic muting code has many problems, including
being the cause of PR5982. unfortunately, there's no easy and clean solution to automatic muting. we can't always rely on the codec giving us the right information. people have different preferences as to what should be muted and what shouldn't. etc, etc. so instead, just make the sense state of jacks that support sensing available through the mixer interface. this allows for any possible user configuration and supports all pins that have sense capabilities, not just headpones. codecs that use the generic mixer configuration (which is the plan for all codecs) and have sensing capable pins will now get a few more read-only mixer items, such as: outputs.hp_sense=plugged outputs.mic_sense=unplugged outputs.line_sense=unplugged hopefully what they mean is self-explanatory. based on much discussion with ratchov@ and Alexey Suslikov
Diffstat (limited to 'sys/dev/pci/azalia_codec.c')
-rw-r--r--sys/dev/pci/azalia_codec.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c
index 860c54427e2..f1000e32314 100644
--- a/sys/dev/pci/azalia_codec.c
+++ b/sys/dev/pci/azalia_codec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia_codec.c,v 1.65 2008/11/17 00:42:53 jakemsr Exp $ */
+/* $OpenBSD: azalia_codec.c,v 1.66 2008/11/19 03:44:14 jakemsr Exp $ */
/* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */
/*-
@@ -881,6 +881,35 @@ azalia_generic_mixer_init(codec_t *this)
}
}
+ /* sense pins */
+ for (i = 0; i < this->nsense_pins; i++) {
+ FOR_EACH_WIDGET(this, j) {
+ if (this->w[j].nid == this->sense_pins[i])
+ break;
+ }
+ if (j == this->wend) {
+ DPRINTF(("%s: sense pin %2.2x not found\n",
+ __func__, this->sense_pins[i]));
+ continue;
+ }
+
+ MIXER_REG_PROLOG;
+ m->nid = this->w[j].nid;
+ snprintf(d->label.name, sizeof(d->label.name), "%s_sense",
+ this->w[j].name);
+ d->type = AUDIO_MIXER_ENUM;
+ d->mixer_class = AZ_CLASS_OUTPUT;
+ m->target = AZ_TARGET_PINSENSE;
+ d->un.e.num_mem = 2;
+ d->un.e.member[0].ord = 0;
+ strlcpy(d->un.e.member[0].label.name, "unplugged",
+ MAX_AUDIO_DEV_LEN);
+ d->un.e.member[1].ord = 1;
+ strlcpy(d->un.e.member[1].label.name, "plugged",
+ MAX_AUDIO_DEV_LEN);
+ this->nmixers++;
+ }
+
/* if the codec has multiple DAC groups, create "inputs.usingdac" */
if (this->dacs.ngroups > 1) {
MIXER_REG_PROLOG;
@@ -1367,6 +1396,15 @@ azalia_generic_mixer_get(const codec_t *this, nid_t nid, int target, mixer_ctrl_
mc->un.ord = result & CORB_EAPD_EAPD ? 1 : 0;
}
+ /* sense pin */
+ else if (target == AZ_TARGET_PINSENSE) {
+ err = this->comresp(this, nid, CORB_GET_PIN_SENSE,
+ 0, &result);
+ if (err)
+ return err;
+ mc->un.ord = result & CORB_PS_PRESENCE ? 1 : 0;
+ }
+
else {
printf("%s: internal error in %s: target=%x\n",
XNAME(this), __func__, target);
@@ -1648,6 +1686,10 @@ azalia_generic_mixer_set(codec_t *this, nid_t nid, int target, const mixer_ctrl_
return err;
}
+ else if (target == AZ_TARGET_PINSENSE) {
+ /* do nothing, control is read only */
+ }
+
else {
printf("%s: internal error in %s: target=%x\n",
XNAME(this), __func__, target);