diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2008-12-25 22:15:06 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2008-12-25 22:15:06 +0000 |
commit | ebe426e94d0d89c3e2cad9e759dacbb252b2fc2a (patch) | |
tree | 3a6535d37b682f6c080cdaef45ad769dbdec4a3b /sys/dev | |
parent | 16ca401b45ea601c777ce0386822772d93ed6135 (diff) |
currently azalia only supports one codec. instead of using simply the
first codec with an audio function group, use the first codec with
an audio function group that can do analog I/O, if there is one.
codecs that just do digital I/O aren't quite as useful, yet.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/azalia.c | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c index acbf4ccd9ba..8d49e985864 100644 --- a/sys/dev/pci/azalia.c +++ b/sys/dev/pci/azalia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.c,v 1.95 2008/12/25 00:58:15 jakemsr Exp $ */ +/* $OpenBSD: azalia.c,v 1.96 2008/12/25 22:15:05 jakemsr Exp $ */ /* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ /*- @@ -665,7 +665,8 @@ void azalia_attach_intr(struct device *self) { azalia_t *az; - int err, i, c; + codec_t *codec; + int err, i, j, c; az = (azalia_t*)self; @@ -685,18 +686,43 @@ azalia_attach_intr(struct device *self) AZ_WRITE_4(az, INTCTL, AZ_READ_4(az, INTCTL) | HDA_INTCTL_CIE | HDA_INTCTL_GIE); - c = -1; + c = 0; for (i = 0; i < az->ncodecs; i++) { err = azalia_codec_init(&az->codecs[i]); - if (!err && c < 0) - c = i; + if (!err) + c++; } - if (c < 0) { + if (c == 0) { printf("%s: No codecs found\n", XNAME(az)); goto err_exit; } - /* Use the first audio codec */ + + /* Use the first codec capable of analog I/O. If there are none, + * use the first codec capable of digital I/O. + */ + c = -1; + for (i = 0; i < az->ncodecs; i++) { + if (az->codecs[i].audiofunc < 0) + continue; + codec = &az->codecs[i]; + FOR_EACH_WIDGET(codec, j) { + if (codec->w[j].type == COP_AWTYPE_AUDIO_OUTPUT || + codec->w[j].type == COP_AWTYPE_AUDIO_INPUT) { + if (codec->w[j].widgetcap & COP_AWCAP_DIGITAL) { + if (c < 0) + c = i; + } else { + c = i; + break; + } + } + } + } az->codecno = c; + if (az->codecno < 0) { + DPRINTF(("%s: chosen codec has no converters.\n", XNAME(az))); + goto err_exit; + } printf("%s: codecs: ", XNAME(az)); for (i = 0; i < az->ncodecs; i++) { @@ -710,6 +736,19 @@ azalia_attach_intr(struct device *self) } printf("\n"); + /* All codecs with audio are enabled, but only one will be used. */ + for (i = 0; i < az->ncodecs; i++) { + codec = &az->codecs[i]; + if (i != az->codecno) { + if (codec->audiofunc < 0) + continue; + codec->comresp(codec, codec->audiofunc, + CORB_SET_POWER_STATE, CORB_PS_D3, NULL); + DELAY(100); + azalia_codec_delete(codec); + } + } + /* Use stream#1 and #2. Don't use stream#0. */ if (azalia_stream_init(&az->pstream, az, az->nistreams + 0, 1, AUMODE_PLAY)) @@ -1298,12 +1337,18 @@ azalia_codec_delete(codec_t *this) this->formats = NULL; } this->nformats = 0; + if (this->encs != NULL) { free(this->encs, M_DEVBUF); this->encs = NULL; } this->nencs = 0; + if (this->w != NULL) { + free(this->w, M_DEVBUF); + this->w = NULL; + } + return 0; } |