summaryrefslogtreecommitdiff
path: root/sys/dev/pci/azalia.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.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.c')
-rw-r--r--sys/dev/pci/azalia.c115
1 files changed, 10 insertions, 105 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c
index 4d6921ed9ba..843f6940406 100644
--- a/sys/dev/pci/azalia.c
+++ b/sys/dev/pci/azalia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.c,v 1.72 2008/11/14 21:58:11 jakemsr Exp $ */
+/* $OpenBSD: azalia.c,v 1.73 2008/11/19 03:44:14 jakemsr Exp $ */
/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
/*-
@@ -43,7 +43,6 @@
#include <sys/param.h>
#include <sys/device.h>
-#include <sys/timeout.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#include <uvm/uvm_param.h>
@@ -171,7 +170,6 @@ typedef struct azalia_t {
codec_t codecs[15];
int ncodecs; /* number of codecs */
int codecno; /* index of the using codec */
- struct timeout timeo;
azalia_dma_t corb_dma;
int corb_size;
@@ -223,8 +221,6 @@ int azalia_free_dmamem(const azalia_t *, azalia_dma_t*);
int azalia_codec_init(codec_t *);
int azalia_codec_delete(codec_t *);
-void azalia_codec_jack_intr(void *);
-void azalia_codec_jack_handler(codec_t *);
void azalia_codec_add_bits(codec_t *, int, uint32_t, int);
void azalia_codec_add_format(codec_t *, int, int, int, uint32_t,
int32_t);
@@ -731,112 +727,12 @@ azalia_attach_intr(struct device *self)
az->audiodev = audio_attach_mi(&azalia_hw_if, az, &az->dev);
- /* Setup jack_intr if only there is no unsol_event handler. */
- if (az->codecs[az->codecno].unsol_event == NULL) {
- timeout_set(&az->timeo, azalia_codec_jack_intr, az);
- timeout_add_sec(&az->timeo, 2);
- }
-
return;
err_exit:
azalia_pci_detach(self, 0);
return;
}
-void
-azalia_codec_jack_intr(void *addr)
-{
- struct azalia_t *az = (struct azalia_t *)addr;
- int s;
-
- s = splaudio();
- azalia_codec_jack_handler(&az->codecs[az->codecno]);
- timeout_add_sec(&az->timeo, 2);
- splx(s);
-}
-
-void
-azalia_codec_jack_handler(codec_t *this)
-{
- int i, j, err, dev;
- uint32_t sense, ctl, val, dir;
-
- FOR_EACH_WIDGET(this, i) {
- const widget_t *w;
-
- dev = 0;
- w = &this->w[i];
-
- /* Find pin with conn=jack and presence capability. */
- if (w == NULL || w->type != COP_AWTYPE_PIN_COMPLEX ||
- (CORB_CD_PORT(w->d.pin.config)) != CORB_CD_JACK ||
- (!(w->d.pin.cap & COP_PINCAP_PRESENCE)))
- continue;
-
- /* Headphones. */
- if (w->d.pin.device == CORB_CD_HEADPHONE &&
- (w->d.pin.cap & COP_PINCAP_HEADPHONE)) {
- dev = CORB_CD_SPEAKER; /* (un)mute speakers */
- dir = CORB_PWC_OUTPUT;
- }
-
- if (!dev)
- continue;
-
- err = this->comresp(this, w->nid, CORB_GET_PIN_SENSE,
- 0, &sense);
- if (err)
- break;
-
- err = this->comresp(this, w->nid, CORB_GET_PIN_WIDGET_CONTROL,
- 0, &ctl);
- if (err)
- break;
-
- if (sense & CORB_PS_PRESENCE)
- val = ctl | dir;
- else
- val = ctl & ~dir;
-
- if (val != ctl) {
- ctl = val;
- err = this->comresp(this, w->nid,
- CORB_SET_PIN_WIDGET_CONTROL, ctl, NULL);
- if (err)
- break;
- }
-
- FOR_EACH_WIDGET(this, j) {
- const widget_t *w;
-
- w = &this->w[j];
-
- /* Find suitable and connected pin for (un)mute. */
- if (w == NULL || w->type != COP_AWTYPE_PIN_COMPLEX ||
- (CORB_CD_PORT(w->d.pin.config)) == CORB_CD_NONE ||
- j == i || w->d.pin.device != dev)
- continue;
-
- err = this->comresp(this, w->nid,
- CORB_GET_PIN_WIDGET_CONTROL, 0, &ctl);
- if (err)
- break;
-
- if (sense & CORB_PS_PRESENCE)
- val = ctl & ~dir;
- else
- val = ctl | dir;
-
- if (val != ctl) {
- ctl = val;
- err = this->comresp(this, w->nid,
- CORB_SET_PIN_WIDGET_CONTROL, ctl, NULL);
- if (err)
- break;
- }
- }
- }
-}
int
azalia_init_corb(azalia_t *az)
@@ -1897,6 +1793,7 @@ azalia_widget_print_audio(const widget_t *this, const char *lead)
int
azalia_widget_init_pin(widget_t *this, const codec_t *codec)
{
+ codec_t *wcodec;
uint32_t result;
int err;
@@ -1939,6 +1836,14 @@ azalia_widget_init_pin(widget_t *this, const codec_t *codec)
CORB_SET_PIN_WIDGET_CONTROL, result, NULL);
}
}
+ /* sense pin */
+ if (codec->nsense_pins < AZ_MAX_SENSE_PINS &&
+ this->d.pin.cap & COP_PINCAP_PRESENCE &&
+ CORB_CD_PORT(this->d.pin.config) == CORB_CD_JACK) {
+ wcodec = &codec->az->codecs[codec->az->codecno];
+ wcodec->sense_pins[codec->nsense_pins] = this->nid;
+ wcodec->nsense_pins++;
+ }
return 0;
}