summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2009-04-24 15:31:19 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2009-04-24 15:31:19 +0000
commit4eaed026c1723f98a6af45ad5003e165cf161893 (patch)
treeb88999d5871c2ac239ce6d82bd6a94faa9ade480 /sys/dev/pci
parentf878e6be882338da696fb52540a7644782f92fd4 (diff)
after all widgets have been initialized, loop through all widgets
and do some further initialization and information gathering: - disable mixer and selector widgets that don't have any enabled connections - create lists of analog and digital input and output converters - find the internal/fixed connection microphone and speaker, and which converters they are connected to by default - create a list of jack sensing capable pins some of this was already being done in other places, but moved here for simplification/better organization
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/azalia.c169
-rw-r--r--sys/dev/pci/azalia.h21
2 files changed, 82 insertions, 108 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c
index 1569cb11161..8332f42b3ff 100644
--- a/sys/dev/pci/azalia.c
+++ b/sys/dev/pci/azalia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.c,v 1.118 2009/04/24 15:07:57 jakemsr Exp $ */
+/* $OpenBSD: azalia.c,v 1.119 2009/04/24 15:31:18 jakemsr Exp $ */
/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
/*-
@@ -206,7 +206,6 @@ int azalia_codec_connect_stream(codec_t *, int, uint16_t, int);
int azalia_codec_disconnect_stream(codec_t *, int);
void azalia_codec_print_audiofunc(const codec_t *);
void azalia_codec_print_groups(const codec_t *);
-int azalia_codec_init_hp_spkr(codec_t *);
int azalia_codec_find_defdac(codec_t *, int, int);
int azalia_codec_init_volgroups(codec_t *);
@@ -1258,9 +1257,6 @@ azalia_codec_init(codec_t *this)
strlcpy(this->w[this->audiofunc].name, "hdaudio",
sizeof(this->w[this->audiofunc].name));
- this->speaker = -1;
- this->mic = -1;
- this->nsense_pins = 0;
FOR_EACH_WIDGET(this, i) {
err = azalia_widget_init(&this->w[i], this, i);
if (err)
@@ -1274,17 +1270,75 @@ azalia_codec_init(codec_t *this)
if (this->init_widget != NULL)
this->init_widget(this, &this->w[i], this->w[i].nid);
}
- /* Find widgets without any enabled inputs and disable them.
- * Must be done after all widgets are initialized and
- * their connections created.
- */
+
+ this->na_dacs = this->na_dacs_d = 0;
+ this->na_adcs = this->na_adcs_d = 0;
+ this->speaker = this->spkr_dac = this->mic = -1;
+ this->nsense_pins = 0;
FOR_EACH_WIDGET(this, i) {
- if (this->w[i].type == COP_AWTYPE_AUDIO_MIXER ||
- this->w[i].type == COP_AWTYPE_AUDIO_SELECTOR) {
+ if (!this->w[i].enable)
+ continue;
+
+ switch (this->w[i].type) {
+
+ case COP_AWTYPE_AUDIO_MIXER:
+ case COP_AWTYPE_AUDIO_SELECTOR:
if (!azalia_widget_check_conn(this, i, 0))
this->w[i].enable = 0;
+ break;
+
+ case COP_AWTYPE_AUDIO_OUTPUT:
+ if ((this->w[i].widgetcap & COP_AWCAP_DIGITAL) == 0) {
+ if (this->na_dacs < HDA_MAX_CHANNELS)
+ this->a_dacs[this->na_dacs++] = i;
+ } else {
+ if (this->na_dacs_d < HDA_MAX_CHANNELS)
+ this->a_dacs_d[this->na_dacs_d++] = i;
+ }
+ break;
+
+ case COP_AWTYPE_AUDIO_INPUT:
+ if ((this->w[i].widgetcap & COP_AWCAP_DIGITAL) == 0) {
+ if (this->na_adcs < HDA_MAX_CHANNELS)
+ this->a_adcs[this->na_adcs++] = i;
+ } else {
+ if (this->na_adcs_d < HDA_MAX_CHANNELS)
+ this->a_adcs_d[this->na_adcs_d++] = i;
+ }
+ break;
+
+ case COP_AWTYPE_PIN_COMPLEX:
+ switch (CORB_CD_PORT(this->w[i].d.pin.config)) {
+ case CORB_CD_FIXED:
+ switch (this->w[i].d.pin.device) {
+ case CORB_CD_SPEAKER:
+ this->speaker = i;
+ this->spkr_dac = azalia_codec_find_defdac(this, i, 0);
+ break;
+ case CORB_CD_MICIN:
+ this->mic = i;
+ this->mic_adc = -1; /* XXX */
+ break;
+ }
+ break;
+ case CORB_CD_JACK:
+ if (this->nsense_pins >= HDA_MAX_SENSE_PINS ||
+ !(this->w[i].d.pin.cap & COP_PINCAP_PRESENCE))
+ break;
+ /* check override bit */
+ err = this->comresp(this, i,
+ CORB_GET_CONFIGURATION_DEFAULT, 0, &result);
+ if (err)
+ break;
+ if (!(CORB_CD_MISC(result) & CORB_CD_PRESENCEOV)) {
+ this->sense_pins[this->nsense_pins++] = i;
+ }
+ break;
+ }
+ break;
}
}
+
err = this->init_dacgroup(this);
if (err)
return err;
@@ -1299,10 +1353,6 @@ azalia_codec_init(codec_t *this)
if (err)
return err;
- err = azalia_codec_init_hp_spkr(this);
- if (err)
- return err;
-
err = azalia_codec_init_volgroups(this);
if (err)
return err;
@@ -1319,37 +1369,6 @@ azalia_codec_init(codec_t *this)
}
int
-azalia_codec_init_hp_spkr(codec_t *this)
-{
- int i;
-
- this->hp_dac = -1;
- this->spkr_dac = -1;
-
- if (this->speaker != -1)
- this->spkr_dac = azalia_codec_find_defdac(this,
- this->speaker, 0);
-
- if (this->headphones == -1) {
- FOR_EACH_WIDGET(this, i) {
- if (this->w[i].type != COP_AWTYPE_PIN_COMPLEX)
- continue;
- if (this->w[i].d.pin.device == CORB_CD_LINEOUT &&
- (this->w[i].d.pin.cap & COP_PINCAP_HEADPHONE)) {
- this->headphones = i;
- break;
- }
- }
- }
-
- if (this->headphones != -1)
- this->hp_dac = azalia_codec_find_defdac(this,
- this->headphones, 0);
-
- return 0;
-}
-
-int
azalia_codec_find_defdac(codec_t *this, int index, int depth)
{
const widget_t *w;
@@ -1438,7 +1457,7 @@ azalia_codec_init_volgroups(codec_t *this)
if (dac == -1)
continue;
if (dac != this->dacs.groups[this->dacs.cur].conv[0] &&
- dac != this->hp_dac && dac != this->spkr_dac)
+ dac != this->spkr_dac)
continue;
if ((cap & COP_AMPCAP_MUTE) && COP_AMPCAP_NUMSTEPS(cap)) {
if (w->type == COP_AWTYPE_BEEP_GENERATOR) {
@@ -1463,7 +1482,7 @@ azalia_codec_init_volgroups(codec_t *this)
if (dac == -1)
continue;
if (dac != this->dacs.groups[this->dacs.cur].conv[0] &&
- dac != this->hp_dac && dac != this->spkr_dac)
+ dac != this->spkr_dac)
continue;
if (w->type == COP_AWTYPE_BEEP_GENERATOR)
continue;
@@ -1811,8 +1830,7 @@ azalia_codec_connect_stream(codec_t *this, int dir, uint16_t fmt, int number)
stream_chan = (number << 4);
if (curchan < nchan) {
stream_chan |= curchan;
- } else if (w->nid == this->spkr_dac ||
- w->nid == this->hp_dac) {
+ } else if (w->nid == this->spkr_dac) {
stream_chan |= 0; /* first channel(s) */
} else
stream_chan = 0; /* idle stream */
@@ -2190,7 +2208,6 @@ azalia_widget_init_audio(widget_t *this, const codec_t *codec)
int
azalia_widget_init_pin(widget_t *this, const codec_t *codec)
{
- codec_t *wcodec;
uint32_t result, dir;
int err;
@@ -2251,56 +2268,8 @@ azalia_widget_init_pin(widget_t *this, const codec_t *codec)
}
/* Disable unconnected pins */
- if (CORB_CD_PORT(this->d.pin.config) == CORB_CD_NONE) {
+ if (CORB_CD_PORT(this->d.pin.config) == CORB_CD_NONE)
this->enable = 0;
- return 0;
- }
-
- /* need a non const codec pointer */
- wcodec = &codec->az->codecs[codec->az->codecno];
-
- if (codec->nsense_pins < HDA_MAX_SENSE_PINS &&
- this->d.pin.cap & COP_PINCAP_PRESENCE &&
- CORB_CD_PORT(this->d.pin.config) == CORB_CD_JACK) {
- /* check override bit */
- err = codec->comresp(codec, this->nid,
- CORB_GET_CONFIGURATION_DEFAULT, 0, &result);
- if (err)
- return err;
- if (!(CORB_CD_MISC(result) & CORB_CD_PRESENCEOV)) {
- wcodec->sense_pins[wcodec->nsense_pins++] = this->nid;
- }
- }
-
- if (this->d.pin.device == CORB_CD_HEADPHONE &&
- (this->d.pin.cap & COP_PINCAP_OUTPUT) &&
- (CORB_CD_PORT(this->d.pin.config) == CORB_CD_JACK ||
- CORB_CD_PORT(this->d.pin.config) == CORB_CD_BOTH)) {
- if (codec->headphones == -1 ||
- (this->d.pin.association <
- codec->w[codec->headphones].d.pin.association))
- wcodec->headphones = this->nid;
- }
-
- if (this->d.pin.device == CORB_CD_SPEAKER &&
- (this->d.pin.cap & COP_PINCAP_OUTPUT) &&
- (CORB_CD_PORT(this->d.pin.config) == CORB_CD_FIXED ||
- CORB_CD_PORT(this->d.pin.config) == CORB_CD_BOTH)) {
- if (codec->speaker == -1 ||
- (this->d.pin.association <
- codec->w[codec->speaker].d.pin.association))
- wcodec->speaker = this->nid;
- }
-
- if (this->d.pin.device == CORB_CD_MICIN &&
- (this->d.pin.cap & COP_PINCAP_INPUT) &&
- (CORB_CD_PORT(this->d.pin.config) == CORB_CD_FIXED ||
- CORB_CD_PORT(this->d.pin.config) == CORB_CD_BOTH)) {
- if (codec->mic == -1 ||
- (this->d.pin.association <
- codec->w[codec->mic].d.pin.association))
- wcodec->mic = this->nid;
- }
return 0;
}
diff --git a/sys/dev/pci/azalia.h b/sys/dev/pci/azalia.h
index 44b797d0b6c..5abbbcaea34 100644
--- a/sys/dev/pci/azalia.h
+++ b/sys/dev/pci/azalia.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.h,v 1.40 2009/01/05 09:46:26 jakemsr Exp $ */
+/* $OpenBSD: azalia.h,v 1.41 2009/04/24 15:31:18 jakemsr Exp $ */
/* $NetBSD: azalia.h,v 1.6 2006/01/16 14:15:26 kent Exp $ */
/*-
@@ -639,17 +639,22 @@ typedef struct codec_t {
int nmixers, maxmixers;
mixer_item_t *mixers;
- struct audio_format* formats;
+ struct audio_format *formats;
int nformats;
- struct audio_encoding* encs;
+ struct audio_encoding *encs;
int nencs;
- int headphones;
- int hp_dac;
- int speaker;
- int spkr_dac;
+ nid_t a_dacs[HDA_MAX_CHANNELS], a_dacs_d[HDA_MAX_CHANNELS];
+ int na_dacs, na_dacs_d;
+ nid_t a_adcs[HDA_MAX_CHANNELS], a_adcs_d[HDA_MAX_CHANNELS];
+ int na_adcs, na_adcs_d;
+
+ nid_t mic; /* fixed (internal) mic */
+ nid_t mic_adc;
+ nid_t speaker; /* fixed (internal) speaker */
+ nid_t spkr_dac;
+
int spkr_muters;
- int mic;
volgroup_t playvols;
volgroup_t recvols;