summaryrefslogtreecommitdiff
path: root/sys/dev/pci/azalia.c
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2009-05-01 02:45:31 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2009-05-01 02:45:31 +0000
commit16ddb2df214a31dcae5a99afc5e5c45534c38ffa (patch)
tree0df4128d32e79beb0a0bf9b8d2889ad5271b6a56 /sys/dev/pci/azalia.c
parent5af8a0e32273145069655b482eca0a81d7fce40a (diff)
try to get built-in speakers connected to a DAC no other output pin
connects to be default. if that's not possible, try to make it so that the speaker and the first output pin do not connect to the same DAC by default. allows more configuration freedom.
Diffstat (limited to 'sys/dev/pci/azalia.c')
-rw-r--r--sys/dev/pci/azalia.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c
index 56f0bf6682b..1398a69ecc9 100644
--- a/sys/dev/pci/azalia.c
+++ b/sys/dev/pci/azalia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.c,v 1.127 2009/05/01 02:04:20 jakemsr Exp $ */
+/* $OpenBSD: azalia.c,v 1.128 2009/05/01 02:45:30 jakemsr Exp $ */
/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
/*-
@@ -212,6 +212,7 @@ int azalia_codec_find_defadc_sub(codec_t *, nid_t, int, int);
int azalia_codec_init_volgroups(codec_t *);
int azalia_codec_sort_pins(codec_t *);
int azalia_codec_select_micadc(codec_t *);
+int azalia_codec_select_spkrdac(codec_t *);
int azalia_widget_init(widget_t *, const codec_t *, int);
int azalia_widget_label_widgets(codec_t *);
@@ -1357,6 +1358,10 @@ azalia_codec_init(codec_t *this)
if (err)
return err;
+ err = azalia_codec_select_spkrdac(this);
+ if (err)
+ return err;
+
err = this->init_dacgroup(this);
if (err)
return err;
@@ -1635,6 +1640,84 @@ azalia_codec_sort_pins(codec_t *this)
#undef MAX_PINS
}
+/* Connect the speaker to a DAC that no other output pin is connected
+ * to by default. If that is not possible, connect to a DAC other
+ * than the one the first output pin is connected to.
+ */
+int
+azalia_codec_select_spkrdac(codec_t *this)
+{
+ widget_t *w;
+ nid_t convs[HDA_MAX_CHANNELS];
+ int nconv, conv;
+ int i, j, err, fspkr, conn;
+
+ nconv = fspkr = 0;
+ for (i = 0; i < this->nopins; i++) {
+ conv = this->opins[i].conv;
+ for (j = 0; j < nconv; j++) {
+ if (conv == convs[j])
+ break;
+ }
+ if (j == nconv) {
+ if (conv == this->spkr_dac)
+ fspkr = 1;
+ convs[nconv++] = conv;
+ if (nconv == this->na_dacs)
+ break;
+ }
+ }
+
+ if (fspkr) {
+ conn = conv = -1;
+ w = &this->w[this->speaker];
+ for (i = 0; i < w->nconnections; i++) {
+ conv = azalia_codec_find_defdac(this,
+ w->connections[i], 1);
+ for (j = 0; j < nconv; j++)
+ if (conv == convs[j])
+ break;
+ if (j == nconv)
+ break;
+ }
+ if (i < w->nconnections) {
+ conn = i;
+ } else {
+ /* Couldn't get a unique DAC. Try to get a diferent
+ * DAC than the first pin's DAC.
+ */
+ if (this->spkr_dac == this->opins[0].conv) {
+ /* If the speaker connection can't be changed,
+ * change the first pin's connection.
+ */
+ if (w->nconnections == 1)
+ w = &this->w[this->opins[0].nid];
+ for (j = 0; j < w->nconnections; j++) {
+ conv = azalia_codec_find_defdac(this,
+ w->connections[j], 1);
+ if (conv != this->opins[0].conv) {
+ conn = j;
+ break;
+ }
+ }
+ }
+ }
+ if (conn != -1) {
+ err = this->comresp(this, w->nid,
+ CORB_SET_CONNECTION_SELECT_CONTROL, conn, 0);
+ if (err)
+ return(err);
+ w->selected = conn;
+ if (w->nid == this->speaker)
+ this->spkr_dac = conv;
+ else
+ this->opins[0].conv = conv;
+ }
+ }
+
+ return(0);
+}
+
int
azalia_codec_find_defdac(codec_t *this, int index, int depth)
{