[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cdi-devel] [PATCH 4/9] hdaudio: Debug output for every widget
Even for non-output widgets, gather some data and print it in debug
mode.
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
hdaudio/device.h | 25 +++++++++++++++++
hdaudio/main.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/hdaudio/device.h b/hdaudio/device.h
index 6af4ddc..eb4746c 100644
--- a/hdaudio/device.h
+++ b/hdaudio/device.h
@@ -177,19 +177,44 @@ enum codec_verbs {
VERB_GET_PARAMETER = 0xf0000,
VERB_SET_STREAM_CHANNEL = 0x70600,
VERB_SET_FORMAT = 0x20000,
+ VERB_GET_AMP_GAIN_MUTE = 0xb0000,
VERB_SET_AMP_GAIN_MUTE = 0x30000,
+ VERB_GET_CONN_LIST = 0xf0200,
+ VERB_GET_CONN_SELECT = 0xf0100,
+ VERB_GET_EAPD_BTL = 0xf0c00,
};
enum codec_parameters {
PARAM_NODE_COUNT = 0x04,
PARAM_FN_GROUP_TYPE = 0x05,
PARAM_AUDIO_WID_CAP = 0x09,
+ PARAM_CONN_LIST_LEN = 0x0e,
+ PARAM_OUT_AMP_CAP = 0x12,
};
enum fn_group_type {
FN_GROUP_AUDIO = 0x01,
};
+enum widget_type {
+ WIDGET_OUTPUT = 0x0,
+ WIDGET_INPUT = 0x1,
+ WIDGET_MIXER = 0x2,
+ WIDGET_SELECTOR = 0x3,
+ WIDGET_PIN = 0x4,
+ WIDGET_POWER = 0x5,
+ WIDGET_VOLUME_KNOB = 0x6,
+ WIDGET_BEEP_GEN = 0x7,
+ WIDGET_VENDOR_DEFINED = 0xf,
+};
+
+enum widget_capabilities {
+ WIDGET_CAP_POWER_CNTRL = (1 << 10),
+
+ WIDGET_CAP_TYPE_SHIFT = 20,
+ WIDGET_CAP_TYPE_MASK = (0xf << 20),
+};
+
enum sample_format {
SR_48_KHZ = 0,
SR_44_KHZ = (1 << 14),
diff --git a/hdaudio/main.c b/hdaudio/main.c
index 313f59b..416aa80 100644
--- a/hdaudio/main.c
+++ b/hdaudio/main.c
@@ -215,6 +215,53 @@ static void init_output_widget(struct hda_device* hda)
configure_output_widget(hda);
}
+#ifdef DEBUG
+static void widget_dump_connections(struct hda_device* hda, int codec, int nid)
+{
+ uint32_t num_conn;
+ uint32_t sel;
+ int i;
+
+ num_conn = codec_query(hda, codec, nid,
+ VERB_GET_PARAMETER | PARAM_CONN_LIST_LEN);
+ if (!num_conn) {
+ return;
+ }
+
+ DPRINTF(" conn:");
+
+ for (i = 0; i < (num_conn & 0x7f); i++) {
+ uint32_t conn;
+ bool range;
+ int idx, shift;
+
+ if (num_conn & 0x80) {
+ idx = i & ~3;
+ shift = 8 * (i & 3);
+ } else {
+ idx = i & ~1;
+ shift = 8 * (i & 1);
+ }
+
+ conn = codec_query(hda, codec, nid, VERB_GET_CONN_LIST | idx);
+ conn >>= shift;
+
+ if (num_conn & 0x80) {
+ range = conn & 0x8000;
+ conn &= 0x7fff;
+ } else {
+ range = conn & 0x80;
+ conn &= 0x7f;
+ }
+
+ printf("%c%d", range ? '-' : ' ', conn);
+ }
+
+ sel = codec_query(hda, codec, nid, VERB_GET_CONN_SELECT);
+ printf(" [current: %d]\n", sel);
+}
+#endif
+
static void widget_init(struct hda_device* hda, int codec, int nid)
{
uint32_t widget_cap;
@@ -225,8 +272,42 @@ static void widget_init(struct hda_device* hda, int codec, int nid)
return;
}
+#ifdef DEBUG
+ enum widget_type type;
+ uint32_t eapd_btl;
+ uint32_t amp_gain;
+ uint32_t amp_cap;
+ const char* s;
+
+ type = (widget_cap & WIDGET_CAP_TYPE_MASK) >> WIDGET_CAP_TYPE_SHIFT;
+
+ switch (type) {
+ case 0: s = "output"; break;
+ case 1: s = "input"; break;
+ case 2: s = "mixer"; break;
+ case 3: s = "selector"; break;
+ case 4: s = "pin complex"; break;
+ case 5: s = "power"; break;
+ case 6: s = "volume knob"; break;
+ case 7: s = "beep generator"; break;
+ case 15: s = "vendor defined"; break;
+ default: s = "unknown"; break;
+ }
+
+ amp_gain = codec_query(hda, codec, nid,
+ VERB_GET_AMP_GAIN_MUTE | 0x8000) << 8;
+ amp_gain |= codec_query(hda, codec, nid, VERB_GET_AMP_GAIN_MUTE | 0xa000);
+ amp_cap = codec_query(hda, codec, nid,
+ VERB_GET_PARAMETER | PARAM_OUT_AMP_CAP);
+ eapd_btl = codec_query(hda, codec, nid, VERB_GET_EAPD_BTL);
+
+ DPRINTF(" %s at ID %d; cap %x, eapd %x, amp %x/%x\n",
+ s, nid, widget_cap, eapd_btl, amp_gain, amp_cap);
+
+ widget_dump_connections(hda, codec, nid);
+#endif
+
if ((widget_cap & 0xf00000) == 0) {
- DPRINTF(" Audio output at ID %d!\n", nid);
if (!hda->output.nid) {
DPRINTF(" * Using output at ID %d!\n", nid);
hda->output.codec = codec;
@@ -270,6 +351,7 @@ static int codec_enumerate_widgets(struct hda_device* hda, int codec)
for (j = 0; j < num_widgets; j++) {
widget_init(hda, codec, widgets_start + j);
}
+ DPRINTF("\n");
}
return hda->output.nid ? 0 : -1;
--
2.1.4