summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/azalia.c85
-rw-r--r--sys/dev/pci/azalia.h42
-rw-r--r--sys/dev/pci/azalia_codec.c41
3 files changed, 113 insertions, 55 deletions
diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c
index a487fe4242e..50a85e88530 100644
--- a/sys/dev/pci/azalia.c
+++ b/sys/dev/pci/azalia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.c,v 1.34 2007/09/10 22:37:08 deanna Exp $ */
+/* $OpenBSD: azalia.c,v 1.35 2007/10/10 03:39:21 deanna Exp $ */
/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
/*-
@@ -334,6 +334,18 @@ static const char *pin_devices[16] = {
"SPDIF-out", "digital-out", "modem-line", "modem-handset",
"line-in", AudioNaux, AudioNmicrophone, "telephony",
"SPDIF-in", "digital-in", "dev0e", "other"};
+static const char *pin_conn[4] = {
+ "jack", "none", "fixed", "combined"};
+static const char *pin_conntype[16] = {
+ "unknown", "1/8", "1/4", "atapi", "rca", "optical",
+ "digital", "analog", "din", "xlr", "rj-11", "combination",
+ "con0c", "con0d", "con0e", "other"};
+static const char *pin_geo[15] = {
+ "n/a", "rear", "front", "left",
+ "right", "top", "bottom", "spec0", "spec1", "spec2",
+ "loc0a", "loc0b", "loc0c", "loc0d", "loc0f"};
+static const char *pin_chass[4] = {
+ "external", "internal", "separate", "other"};
#endif
/* ================================================================
@@ -1162,6 +1174,12 @@ azalia_codec_init(codec_t *this)
DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
(result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result),
COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result)));
+ this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
+ COP_GPIO_COUNT, &result);
+ DPRINTF(("\tgpio: wake=%u unsol=%u gpis=%u gpos=%u gpios=%u\n",
+ (result & COP_GPIO_WAKE) != 0, (result & COP_GPIO_UNSOL) != 0,
+ COP_GPIO_GPIS(result), COP_GPIO_GPOS(result),
+ COP_GPIO_GPIOS(result)));
#endif
strlcpy(this->w[CORB_NID_ROOT].name, "root",
@@ -1544,11 +1562,13 @@ azalia_widget_init(widget_t *this, const codec_t *codec, nid_t nid)
COP_INPUT_AMPCAP, &this->inamp_cap);
else
this->inamp_cap = codec->w[codec->audiofunc].inamp_cap;
- DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n",
- (this->inamp_cap & COP_AMPCAP_MUTE) != 0,
- COP_AMPCAP_STEPSIZE(this->inamp_cap),
- COP_AMPCAP_NUMSTEPS(this->inamp_cap),
- COP_AMPCAP_OFFSET(this->inamp_cap)));
+ if ((this->widgetcap & COP_AWCAP_AMPOV) ||
+ (this->nid == codec->audiofunc))
+ DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n",
+ (this->inamp_cap & COP_AMPCAP_MUTE) != 0,
+ COP_AMPCAP_STEPSIZE(this->inamp_cap),
+ COP_AMPCAP_NUMSTEPS(this->inamp_cap),
+ COP_AMPCAP_OFFSET(this->inamp_cap)));
}
if (this->widgetcap & COP_AWCAP_OUTAMP) {
if (this->widgetcap & COP_AWCAP_AMPOV)
@@ -1556,11 +1576,13 @@ azalia_widget_init(widget_t *this, const codec_t *codec, nid_t nid)
COP_OUTPUT_AMPCAP, &this->outamp_cap);
else
this->outamp_cap = codec->w[codec->audiofunc].outamp_cap;
- DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
- (this->outamp_cap & COP_AMPCAP_MUTE) != 0,
- COP_AMPCAP_STEPSIZE(this->outamp_cap),
- COP_AMPCAP_NUMSTEPS(this->outamp_cap),
- COP_AMPCAP_OFFSET(this->outamp_cap)));
+ if ((this->widgetcap & COP_AWCAP_AMPOV) ||
+ (this->nid == codec->audiofunc))
+ DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
+ (this->outamp_cap & COP_AMPCAP_MUTE) != 0,
+ COP_AMPCAP_STEPSIZE(this->outamp_cap),
+ COP_AMPCAP_NUMSTEPS(this->outamp_cap),
+ COP_AMPCAP_OFFSET(this->outamp_cap)));
}
if (codec->init_widget != NULL)
codec->init_widget(codec, this, nid);
@@ -1605,7 +1627,8 @@ azalia_widget_init_audio(widget_t *this, const codec_t *codec)
codec->w[codec->audiofunc].d.audio.bits_rates;
}
#ifdef AZALIA_DEBUG
- azalia_widget_print_audio(this, "\t");
+ if (this->widgetcap & COP_AWCAP_FORMATOV)
+ azalia_widget_print_audio(this, "\t");
#endif
return 0;
}
@@ -1674,16 +1697,44 @@ azalia_widget_init_pin(widget_t *this, const codec_t *codec)
return 0;
}
-#define PINCAP_BITS "\20\021EAPD\07BALANCE\06INPUT" \
+#define PINCAP_BITS "\20\021EAPD\16VREF100\15VREF80" \
+ "\13VREFGND\12VREF50\11VREFHIZ\07BALANCE\06INPUT" \
"\05OUTPUT\04HEADPHONE\03PRESENCE\02TRIGGER\01IMPEDANCE"
int
azalia_widget_print_pin(const widget_t *this)
{
- DPRINTF(("\tpin config; device=%s color=%s assoc=%d seq=%d",
- pin_devices[this->d.pin.device], pin_colors[this->d.pin.color],
- this->d.pin.association, this->d.pin.sequence));
- DPRINTF((" cap=%b\n", this->d.pin.cap, PINCAP_BITS));
+ DPRINTF(("\tcap=%b\n", this->d.pin.cap, PINCAP_BITS));
+ DPRINTF(("\t[%2.2d/%2.2d] ", CORB_CD_ASSOCIATION(this->d.pin.config),
+ CORB_CD_SEQUENCE(this->d.pin.config)));
+ DPRINTF(("color=%s ", pin_colors[CORB_CD_COLOR(this->d.pin.config)]));
+ DPRINTF(("device=%s ", pin_devices[CORB_CD_DEVICE(this->d.pin.config)]));
+ DPRINTF(("conn=%s ", pin_conn[CORB_CD_PORT(this->d.pin.config)]));
+ DPRINTF(("conntype=%s\n", pin_conntype[CORB_CD_CONNECTION(this->d.pin.config)]));
+ DPRINTF(("\tlocation=%s ", pin_geo[CORB_CD_LOC_GEO(this->d.pin.config)]));
+ DPRINTF(("chassis=%s ", pin_chass[CORB_CD_LOC_CHASS(this->d.pin.config)]));
+ DPRINTF(("special="));
+ if (CORB_CD_LOC_GEO(this->d.pin.config) == CORB_CD_LOC_SPEC0) {
+ if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_EXTERNAL)
+ DPRINTF(("rear-panel"));
+ else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_INTERNAL)
+ DPRINTF(("riser"));
+ else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_LOC_OTHER)
+ DPRINTF(("mobile-lid-internal"));
+ } else if (CORB_CD_LOC_GEO(this->d.pin.config) == CORB_CD_LOC_SPEC1) {
+ if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_EXTERNAL)
+ DPRINTF(("drive-bay"));
+ else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_INTERNAL)
+ DPRINTF(("hdmi"));
+ else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_LOC_OTHER)
+ DPRINTF(("mobile-lid-external"));
+ } else if (CORB_CD_LOC_GEO(this->d.pin.config) == CORB_CD_LOC_SPEC2) {
+ if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_INTERNAL)
+ DPRINTF(("atapi"));
+ } else
+ DPRINTF(("none"));
+ DPRINTF(("\n"));
+
return 0;
}
diff --git a/sys/dev/pci/azalia.h b/sys/dev/pci/azalia.h
index 63be267fce3..e0339dcbc97 100644
--- a/sys/dev/pci/azalia.h
+++ b/sys/dev/pci/azalia.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: azalia.h,v 1.13 2007/09/10 05:39:07 deanna Exp $ */
+/* $OpenBSD: azalia.h,v 1.14 2007/10/10 03:39:21 deanna Exp $ */
/* $NetBSD: azalia.h,v 1.6 2006/01/16 14:15:26 kent Exp $ */
/*-
@@ -277,6 +277,11 @@
#define COP_SUPPORTED_POWER_STATES 0x0f
#define COP_PROCESSING_CAPABILITIES 0x10
#define COP_GPIO_COUNT 0x11
+#define COP_GPIO_GPIOS(x) (x & 0xff)
+#define COP_GPIO_GPOS(x) ((x >> 8) & 0xff)
+#define COP_GPIO_GPIS(x) ((x >> 16) & 0xff)
+#define COP_GPIO_UNSOL 0x40000000
+#define COP_GPIO_WAKE 0x80000000
#define COP_OUTPUT_AMPCAP 0x12
#define COP_VOLUME_KNOB_CAPABILITIES 0x13
#define COP_VKCAP_DELTA 0x00000080
@@ -408,6 +413,20 @@
#define CORB_CD_WHITE 0xe
#define CORB_CD_COLOR_OTHER 0xf
#define CORB_CD_CONNECTION_MASK 0x000f0000
+#define CORB_CD_CONNECTION(x) ((x >> 16) & 0xf)
+#define CORB_CD_CONN_UNKNOWN 0x0
+#define CORB_CD_18 0x1
+#define CORB_CD_14 0x2
+#define CORB_CD_ATAPI 0x3
+#define CORB_CD_RCA 0x4
+#define CORB_CD_OPTICAL 0x5
+#define CORB_CD_OTHER_DIG 0x6
+#define CORB_CD_OTHER_ANALOG 0x7
+#define CORB_CD_DIN 0x8
+#define CORB_CD_XLF 0x9
+#define CORB_CD_RJ11 0xa
+#define CORB_CD_CONN_COMB 0xb
+#define CORB_CD_CONN_OTHER 0xf
#define CORB_CD_DEVICE(x) ((x >> 20) & 0xf)
#define CORB_CD_LINEOUT 0x0
#define CORB_CD_SPEAKER 0x1
@@ -425,7 +444,28 @@
#define CORB_CD_DIGITALIN 0xd
#define CORB_CD_DEVICE_OTHER 0xf
#define CORB_CD_LOCATION_MASK 0x3f000000
+#define CORB_CD_LOC_GEO(x) ((x >> 24) & 0xf)
+#define CORB_CD_LOC_GEO_NA 0x0
+#define CORB_CD_REAR 0x1
+#define CORB_CD_FRONT 0x2
+#define CORB_CD_LEFT 0x3
+#define CORB_CD_RIGHT 0x4
+#define CORB_CD_TOP 0x5
+#define CORB_CD_BOTTOM 0x6
+#define CORB_CD_LOC_SPEC0 0x7
+#define CORB_CD_LOC_SPEC1 0x8
+#define CORB_CD_LOC_SPEC2 0x9
+#define CORB_CD_LOC_CHASS(x) ((x >> 28) & 0x3)
+#define CORB_CD_EXTERNAL 0x0
+#define CORB_CD_INTERNAL 0x1
+#define CORB_CD_SEPARATE 0x2
+#define CORB_CD_LOC_OTHER 0x3
#define CORB_CD_PORT_MASK 0xc0000000
+#define CORB_CD_PORT(x) ((x >> 30) & 0x3)
+#define CORB_CD_JACK 0x0
+#define CORB_CD_NONE 0x1
+#define CORB_CD_FIXED 0x2
+#define CORB_CD_BOTH 0x3
#define CORB_GET_STRIPE_CONTROL 0xf24
#define CORB_SET_STRIPE_CONTROL 0x720 /* XXX typo in the spec? */
#define CORB_EXECUTE_FUNCTION_RESET 0x7ff
diff --git a/sys/dev/pci/azalia_codec.c b/sys/dev/pci/azalia_codec.c
index 39573fd42ae..d498fddd508 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.38 2007/10/05 03:33:23 deanna Exp $ */
+/* $OpenBSD: azalia_codec.c,v 1.39 2007/10/10 03:39:21 deanna Exp $ */
/* $NetBSD: azalia_codec.c,v 1.8 2006/05/10 11:17:27 kent Exp $ */
/*-
@@ -243,7 +243,6 @@ azalia_generic_codec_init_dacgroup(codec_t *this)
}
/* find DACs which do not connect with any pins by default */
- DPRINTF(("%s: find non-connected DACs\n", __func__));
FOR_EACH_WIDGET(this, i) {
boolean_t found;
@@ -305,8 +304,6 @@ azalia_generic_codec_add_dacgroup(codec_t *this, int assoc, uint32_t digital)
if (j < n) /* this group already has <dac> */
continue;
this->dacs.groups[this->dacs.ngroups].conv[n++] = dac;
- DPRINTF(("%s: assoc=%d seq=%d ==> g=%d n=%d\n",
- __func__, assoc, seq, this->dacs.ngroups, n-1));
}
if (n <= 0) /* no such DACs */
return 0;
@@ -357,11 +354,8 @@ azalia_generic_codec_find_dac(const codec_t *this, int index, int depth)
int i, j, ret;
w = &this->w[index];
- if (w->type == COP_AWTYPE_AUDIO_OUTPUT) {
- DPRINTF(("%s: DAC: nid=0x%x index=%d\n",
- __func__, w->nid, index));
+ if (w->type == COP_AWTYPE_AUDIO_OUTPUT)
return index;
- }
if (++depth > 50) {
return -1;
}
@@ -369,11 +363,8 @@ azalia_generic_codec_find_dac(const codec_t *this, int index, int depth)
j = w->connections[w->selected];
if (VALID_WIDGET_NID(j, this)) {
ret = azalia_generic_codec_find_dac(this, j, depth);
- if (ret >= 0) {
- DPRINTF(("%s: DAC path: nid=0x%x index=%d\n",
- __func__, w->nid, index));
+ if (ret >= 0)
return ret;
- }
}
}
for (i = 0; i < w->nconnections; i++) {
@@ -381,11 +372,8 @@ azalia_generic_codec_find_dac(const codec_t *this, int index, int depth)
if (!VALID_WIDGET_NID(j, this))
continue;
ret = azalia_generic_codec_find_dac(this, j, depth);
- if (ret >= 0) {
- DPRINTF(("%s: DAC path: nid=0x%x index=%d\n",
- __func__, w->nid, index));
+ if (ret >= 0)
return ret;
- }
}
return -1;
}
@@ -417,7 +405,6 @@ azalia_generic_mixer_init(codec_t *this)
}
/* register classes */
- DPRINTF(("%s: register classes\n", __func__));
m = &this->mixers[AZ_CLASS_INPUT];
m->devinfo.index = AZ_CLASS_INPUT;
strlcpy(m->devinfo.label.name, AudioCinputs,
@@ -467,7 +454,6 @@ azalia_generic_mixer_init(codec_t *this)
/* selector */
if (w->type != COP_AWTYPE_AUDIO_MIXER && w->nconnections >= 2) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: selector %s\n", __func__, w->name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.source", w->name);
d->type = AUDIO_MIXER_ENUM;
@@ -481,8 +467,6 @@ azalia_generic_mixer_init(codec_t *this)
for (j = 0, k = 0; j < w->nconnections && k < 32; j++) {
if (!VALID_WIDGET_NID(w->connections[j], this))
continue;
- DPRINTF(("%s: selector %d=%s\n", __func__, j,
- this->w[w->connections[j]].name));
d->un.e.member[k].ord = j;
strlcpy(d->un.e.member[k].label.name,
this->w[w->connections[j]].name,
@@ -497,7 +481,6 @@ azalia_generic_mixer_init(codec_t *this)
if (w->widgetcap & COP_AWCAP_OUTAMP &&
w->outamp_cap & COP_AMPCAP_MUTE) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: output mute %s\n", __func__, w->name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.mute", w->name);
d->type = AUDIO_MIXER_ENUM;
@@ -524,7 +507,6 @@ azalia_generic_mixer_init(codec_t *this)
if (w->widgetcap & COP_AWCAP_OUTAMP
&& COP_AMPCAP_NUMSTEPS(w->outamp_cap)) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: output gain %s\n", __func__, w->name));
snprintf(d->label.name, sizeof(d->label.name),
"%s", w->name);
d->type = AUDIO_MIXER_VALUE;
@@ -552,7 +534,6 @@ azalia_generic_mixer_init(codec_t *this)
/* input mute */
if (w->widgetcap & COP_AWCAP_INAMP &&
w->inamp_cap & COP_AMPCAP_MUTE) {
- DPRINTF(("%s: input mute %s\n", __func__, w->name));
if (w->type != COP_AWTYPE_AUDIO_SELECTOR &&
w->type != COP_AWTYPE_AUDIO_MIXER) {
MIXER_REG_PROLOG;
@@ -579,8 +560,6 @@ azalia_generic_mixer_init(codec_t *this)
MIXER_REG_PROLOG;
if (!VALID_WIDGET_NID(w->connections[j], this))
continue;
- DPRINTF(("%s: input mute %s.%s\n", __func__,
- w->name, this->w[w->connections[j]].name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.%s.mute", w->name,
this->w[w->connections[j]].name);
@@ -607,7 +586,6 @@ azalia_generic_mixer_init(codec_t *this)
/* input gain */
if (w->widgetcap & COP_AWCAP_INAMP
&& COP_AMPCAP_NUMSTEPS(w->inamp_cap)) {
- DPRINTF(("%s: input gain %s\n", __func__, w->name));
if (w->type != COP_AWTYPE_AUDIO_SELECTOR &&
w->type != COP_AWTYPE_AUDIO_MIXER) {
MIXER_REG_PROLOG;
@@ -637,8 +615,6 @@ azalia_generic_mixer_init(codec_t *this)
MIXER_REG_PROLOG;
if (!VALID_WIDGET_NID(w->connections[j], this))
continue;
- DPRINTF(("%s: input gain %s.%s\n", __func__,
- w->name, this->w[w->connections[j]].name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.%s", w->name,
this->w[w->connections[j]].name);
@@ -670,7 +646,6 @@ azalia_generic_mixer_init(codec_t *this)
w->d.pin.cap & COP_PINCAP_OUTPUT &&
w->d.pin.cap & COP_PINCAP_INPUT) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: pin dir %s\n", __func__, w->name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.dir", w->name);
d->type = AUDIO_MIXER_ENUM;
@@ -690,7 +665,6 @@ azalia_generic_mixer_init(codec_t *this)
if (w->type == COP_AWTYPE_PIN_COMPLEX &&
w->d.pin.cap & COP_PINCAP_HEADPHONE) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: hpboost %s\n", __func__, w->name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.boost", w->name);
d->type = AUDIO_MIXER_ENUM;
@@ -709,7 +683,6 @@ azalia_generic_mixer_init(codec_t *this)
if (w->type == COP_AWTYPE_PIN_COMPLEX &&
w->d.pin.cap & COP_PINCAP_EAPD) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: eapd %s\n", __func__, w->name));
snprintf(d->label.name, sizeof(d->label.name),
"%s.eapd", w->name);
d->type = AUDIO_MIXER_ENUM;
@@ -729,7 +702,6 @@ azalia_generic_mixer_init(codec_t *this)
if (w->type == COP_AWTYPE_VOLUME_KNOB &&
w->d.volume.cap & COP_VKCAP_DELTA) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: volume knob %s\n", __func__, w->name));
strlcpy(d->label.name, w->name, sizeof(d->label.name));
d->type = AUDIO_MIXER_VALUE;
d->mixer_class = AZ_CLASS_OUTPUT;
@@ -745,7 +717,6 @@ azalia_generic_mixer_init(codec_t *this)
/* if the codec has multiple DAC groups, create "inputs.usingdac" */
if (this->dacs.ngroups > 1) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: create inputs.usingdac\n", __func__));
strlcpy(d->label.name, "usingdac", sizeof(d->label.name));
d->type = AUDIO_MIXER_ENUM;
d->mixer_class = AZ_CLASS_INPUT;
@@ -767,7 +738,6 @@ azalia_generic_mixer_init(codec_t *this)
/* if the codec has multiple ADC groups, create "record.usingadc" */
if (this->adcs.ngroups > 1) {
MIXER_REG_PROLOG;
- DPRINTF(("%s: create inputs.usingadc\n", __func__));
strlcpy(d->label.name, "usingadc", sizeof(d->label.name));
d->type = AUDIO_MIXER_ENUM;
d->mixer_class = AZ_CLASS_RECORD;
@@ -842,7 +812,6 @@ azalia_generic_mixer_default(codec_t *this)
int i;
mixer_item_t *m;
/* unmute all */
- DPRINTF(("%s: unmute\n", __func__));
for (i = 0; i < this->nmixers; i++) {
mixer_ctrl_t mc;
@@ -861,7 +830,6 @@ azalia_generic_mixer_default(codec_t *this)
/*
* For bidirectional pins, make the default `output'
*/
- DPRINTF(("%s: process bidirectional pins\n", __func__));
for (i = 0; i < this->nmixers; i++) {
mixer_ctrl_t mc;
@@ -875,7 +843,6 @@ azalia_generic_mixer_default(codec_t *this)
}
/* set unextreme volume */
- DPRINTF(("%s: set volume\n", __func__));
for (i = 0; i < this->nmixers; i++) {
mixer_ctrl_t mc;