diff options
author | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2008-12-31 11:54:56 +0000 |
---|---|---|
committer | Jacob Meuser <jakemsr@cvs.openbsd.org> | 2008-12-31 11:54:56 +0000 |
commit | 1509944c1b6be222482afb1c9fe49e89df83a48f (patch) | |
tree | 64b4c8df11ce06333ae334b1fea48b476f69719c /sys/dev | |
parent | 85904198d6a4eb901b13e8671d37da50dd95ca3b (diff) |
builtin speakers and headphone jacks have an interesting relationship.
keep track of some information about them, such as the DAC they are
connected to by default. this will be used soon.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/azalia.c | 84 | ||||
-rw-r--r-- | sys/dev/pci/azalia.h | 8 |
2 files changed, 87 insertions, 5 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c index 194fd903e8e..9460f2de206 100644 --- a/sys/dev/pci/azalia.c +++ b/sys/dev/pci/azalia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.c,v 1.100 2008/12/31 11:25:36 jakemsr Exp $ */ +/* $OpenBSD: azalia.c,v 1.101 2008/12/31 11:54:55 jakemsr Exp $ */ /* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ /*- @@ -238,6 +238,8 @@ 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_widget_init(widget_t *, const codec_t *, int); int azalia_widget_label_widgets(codec_t *); @@ -1286,6 +1288,8 @@ azalia_codec_init(codec_t *this) sizeof(this->w[CORB_NID_ROOT].name)); strlcpy(this->w[this->audiofunc].name, "hdaudio", sizeof(this->w[this->audiofunc].name)); + + this->speaker = -1; FOR_EACH_WIDGET(this, i) { err = azalia_widget_init(&this->w[i], this, i); if (err) @@ -1313,17 +1317,89 @@ azalia_codec_init(codec_t *this) err = this->init_dacgroup(this); if (err) return err; + + azalia_codec_print_groups(this); + err = azalia_widget_label_widgets(this); if (err) return err; - azalia_codec_print_groups(this); - err = azalia_codec_construct_format(this, 0, 0); if (err) return err; - return this->mixer_init(this); + err = this->mixer_init(this); + if (err) + return err; + + err = azalia_codec_init_hp_spkr(this); + if (err) + return err; + + return 0; +} + +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; + int ret; + + w = &this->w[index]; + if (w->enable == 0) + return -1; + + if (w->type == COP_AWTYPE_AUDIO_OUTPUT) + return index; + + if (depth > 0 && + (w->type == COP_AWTYPE_PIN_COMPLEX || + w->type == COP_AWTYPE_AUDIO_INPUT)) + return -1; + if (++depth >= 10) + return -1; + + if (w->nconnections > 0) { + index = w->connections[w->selected]; + if (VALID_WIDGET_NID(index, this)) { + ret = azalia_codec_find_defdac(this, index, depth); + if (ret >= 0) + return ret; + } + } + + return -1; } int diff --git a/sys/dev/pci/azalia.h b/sys/dev/pci/azalia.h index 7179acf5037..7c005f98bbb 100644 --- a/sys/dev/pci/azalia.h +++ b/sys/dev/pci/azalia.h @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.h,v 1.29 2008/12/23 04:12:19 jakemsr Exp $ */ +/* $OpenBSD: azalia.h,v 1.30 2008/12/31 11:54:55 jakemsr Exp $ */ /* $NetBSD: azalia.h,v 1.6 2006/01/16 14:15:26 kent Exp $ */ /*- @@ -626,6 +626,12 @@ typedef struct codec_t { struct audio_encoding* encs; int nencs; + int headphones; + int speaker; + int hp_dac; + int spkr_dac; + int spkr_muters; + nid_t sense_pins[HDA_MAX_SENSE_PINS]; int nsense_pins; |