diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-03-21 15:02:32 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2010-03-21 15:02:32 +0000 |
commit | b74f5ec5b5c2cb5fff825294cb3ab7fee928af78 (patch) | |
tree | cdccfab4afdb879ef9d0942c2cf90b3502a16068 /sys/dev | |
parent | 566af0529b8d2b4dce7c97bd8fe0ff07a63bf0ea (diff) |
deal with the possibility of two internal speaker pins, like on
macbooks that have a "normal" pair of stereo speakers as well
as subwoofer(s). problem reported and fix tested by Ted Roby.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/azalia.c | 49 | ||||
-rw-r--r-- | sys/dev/pci/azalia.h | 5 | ||||
-rw-r--r-- | sys/dev/pci/azalia_codec.c | 27 |
3 files changed, 65 insertions, 16 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c index e7672a42bdf..f59f9043550 100644 --- a/sys/dev/pci/azalia.c +++ b/sys/dev/pci/azalia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.c,v 1.167 2010/03/16 08:28:22 jakemsr Exp $ */ +/* $OpenBSD: azalia.c,v 1.168 2010/03/21 15:02:31 jakemsr Exp $ */ /* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ /*- @@ -1660,7 +1660,8 @@ azalia_codec_init(codec_t *this) this->na_dacs = this->na_dacs_d = 0; this->na_adcs = this->na_adcs_d = 0; - this->speaker = this->spkr_dac = this->fhp = this->fhp_dac = + this->speaker = this->speaker2 = this->spkr_dac = + this->fhp = this->fhp_dac = this->mic = this->mic_adc = -1; this->nsense_pins = 0; this->nout_jacks = 0; @@ -1704,13 +1705,22 @@ azalia_codec_init(codec_t *this) case CORB_CD_FIXED: switch (w->d.pin.device) { case CORB_CD_SPEAKER: - if ((this->speaker == -1) || - (w->d.pin.association < - this->w[this->speaker].d.pin.association)) { + if (this->speaker == -1) { this->speaker = i; + } else if (w->d.pin.association < + this->w[this->speaker].d.pin.association || + (w->d.pin.association == + this->w[this->speaker].d.pin.association && + w->d.pin.sequence < + this->w[this->speaker].d.pin.sequence)) { + this->speaker2 = this->speaker; + this->speaker = i; + } else { + this->speaker2 = i; + } + if (this->speaker == i) this->spkr_dac = azalia_codec_find_defdac(this, i, 0); - } break; case CORB_CD_MICIN: this->mic = i; @@ -1938,7 +1948,8 @@ azalia_codec_sort_pins(codec_t *this) switch(w->d.pin.device) { /* primary - output by default */ case CORB_CD_SPEAKER: - if (w->nid == this->speaker) + if (w->nid == this->speaker || + w->nid == this->speaker2) break; /* FALLTHROUGH */ case CORB_CD_HEADPHONE: @@ -1991,7 +2002,8 @@ azalia_codec_sort_pins(codec_t *this) break; /* secondary - output by default */ case CORB_CD_SPEAKER: - if (w->nid == this->speaker) + if (w->nid == this->speaker || + w->nid == this->speaker2) break; /* FALLTHROUGH */ case CORB_CD_HEADPHONE: @@ -2267,6 +2279,27 @@ azalia_codec_select_spkrdac(codec_t *this) } } + /* If there is a speaker2, try to connect it to spkr_dac. */ + if (this->speaker2 != -1) { + conn = conv = -1; + w = &this->w[this->speaker2]; + for (i = 0; i < w->nconnections; i++) { + conv = azalia_codec_find_defdac(this, + w->connections[i], 1); + if (conv == this->spkr_dac) { + conn = i; + break; + } + } + if (conn != -1) { + err = azalia_comresp(this, w->nid, + CORB_SET_CONNECTION_SELECT_CONTROL, conn, 0); + if (err) + return(err); + w->selected = conn; + } + } + return(0); } diff --git a/sys/dev/pci/azalia.h b/sys/dev/pci/azalia.h index f7df5eb68d3..c8f4edfb901 100644 --- a/sys/dev/pci/azalia.h +++ b/sys/dev/pci/azalia.h @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.h,v 1.58 2009/12/22 08:48:14 jakemsr Exp $ */ +/* $OpenBSD: azalia.h,v 1.59 2010/03/21 15:02:31 jakemsr Exp $ */ /* $NetBSD: azalia.h,v 1.6 2006/01/16 14:15:26 kent Exp $ */ /*- @@ -691,7 +691,8 @@ typedef struct codec_t { nid_t mic; /* fixed (internal) mic */ nid_t mic_adc; nid_t speaker; /* fixed (internal) speaker */ - nid_t spkr_dac; + nid_t speaker2; /* 2nd fixed (internal) speaker */ + nid_t spkr_dac; /* default DAC for speaker and speaker2 */ nid_t input_mixer; nid_t fhp; /* front headphone jack */ nid_t fhp_dac; diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c index 18a2cc3faef..0ae6907122c 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.141 2010/02/11 21:33:39 jakemsr Exp $ */ +/* $OpenBSD: azalia_codec.c,v 1.142 2010/03/21 15:02:31 jakemsr Exp $ */ /* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */ /*- @@ -547,11 +547,21 @@ azalia_unsol_event(codec_t *this, int tag) mc.un.ord = vol; err = azalia_mixer_set(this, this->speaker, MI_TARGET_OUTAMP, &mc); + if (!err && this->speaker2 != -1 && + (this->w[this->speaker2].widgetcap & COP_AWCAP_OUTAMP) && + (this->w[this->speaker2].outamp_cap & COP_AMPCAP_MUTE)) + err = azalia_mixer_set(this, this->speaker2, + MI_TARGET_OUTAMP, &mc); break; case AZ_SPKR_MUTE_SPKR_DIR: mc.un.ord = vol ? 0 : 1; err = azalia_mixer_set(this, this->speaker, MI_TARGET_PINDIR, &mc); + if (!err && this->speaker2 != -1 && + (this->w[this->speaker2].d.pin.cap & COP_PINCAP_OUTPUT) && + (this->w[this->speaker2].d.pin.cap & COP_PINCAP_INPUT)) + err = azalia_mixer_set(this, this->speaker2, + MI_TARGET_PINDIR, &mc); break; case AZ_SPKR_MUTE_DAC_MUTE: mc.un.ord = vol; @@ -763,7 +773,8 @@ azalia_mixer_init(codec_t *this) /* input mute */ if (w->widgetcap & COP_AWCAP_INAMP && w->inamp_cap & COP_AMPCAP_MUTE && - w->nid != this->speaker) { + w->nid != this->speaker && + w->nid != this->speaker2) { if (w->type != COP_AWTYPE_AUDIO_MIXER) { MIXER_REG_PROLOG; snprintf(d->label.name, sizeof(d->label.name), @@ -790,7 +801,8 @@ azalia_mixer_init(codec_t *this) if (!azalia_widget_enabled(this, w->connections[j])) continue; - if (w->connections[j] == this->speaker) + if (w->connections[j] == this->speaker || + w->connections[j] == this->speaker2) continue; d->un.s.member[k].mask = 1 << j; strlcpy(d->un.s.member[k].label.name, @@ -807,7 +819,8 @@ azalia_mixer_init(codec_t *this) /* input gain */ if (w->widgetcap & COP_AWCAP_INAMP && COP_AMPCAP_NUMSTEPS(w->inamp_cap) && - w->nid != this->speaker) { + w->nid != this->speaker && + w->nid != this->speaker2) { if (w->type != COP_AWTYPE_AUDIO_SELECTOR && w->type != COP_AWTYPE_AUDIO_MIXER) { MIXER_REG_PROLOG; @@ -829,7 +842,8 @@ azalia_mixer_init(codec_t *this) if (!azalia_widget_enabled(this, w->connections[j])) continue; - if (w->connections[j] == this->speaker) + if (w->connections[j] == this->speaker || + w->connections[j] == this->speaker2) continue; MIXER_REG_PROLOG; snprintf(d->label.name, @@ -868,7 +882,8 @@ azalia_mixer_init(codec_t *this) if (!azalia_widget_enabled(this, w->connections[j])) continue; - if (w->connections[j] == this->speaker) + if (w->connections[j] == this->speaker || + w->connections[j] == this->speaker2) continue; d->un.s.member[k].mask = 1 << j; strlcpy(d->un.s.member[k].label.name, |