summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2010-03-21 15:02:32 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2010-03-21 15:02:32 +0000
commitb74f5ec5b5c2cb5fff825294cb3ab7fee928af78 (patch)
treecdccfab4afdb879ef9d0942c2cf90b3502a16068 /sys/dev
parent566af0529b8d2b4dce7c97bd8fe0ff07a63bf0ea (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.c49
-rw-r--r--sys/dev/pci/azalia.h5
-rw-r--r--sys/dev/pci/azalia_codec.c27
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,