summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2008-12-31 11:54:56 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2008-12-31 11:54:56 +0000
commit1509944c1b6be222482afb1c9fe49e89df83a48f (patch)
tree64b4c8df11ce06333ae334b1fea48b476f69719c
parent85904198d6a4eb901b13e8671d37da50dd95ca3b (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.
-rw-r--r--sys/dev/pci/azalia.c84
-rw-r--r--sys/dev/pci/azalia.h8
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;