[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cdi-devel] [PATCH 5/9] hdaudio: Enable output pins



While enumerating widgets, don't only consider output widgets (i.e.
DACs), but also output pins (i.e. the jack or internal device wherer the
sound actually goes). We need to enable the output there.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 hdaudio/device.h | 13 +++++++++++++
 hdaudio/main.c   | 47 +++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/hdaudio/device.h b/hdaudio/device.h
index eb4746c..b9cedb6 100644
--- a/hdaudio/device.h
+++ b/hdaudio/device.h
@@ -179,8 +179,11 @@ enum codec_verbs {
     VERB_SET_FORMAT         = 0x20000,
     VERB_GET_AMP_GAIN_MUTE  = 0xb0000,
     VERB_SET_AMP_GAIN_MUTE  = 0x30000,
+    VERB_GET_CONFIG_DEFAULT = 0xf1c00,
     VERB_GET_CONN_LIST      = 0xf0200,
     VERB_GET_CONN_SELECT    = 0xf0100,
+    VERB_GET_PIN_CONTROL    = 0xf0700,
+    VERB_SET_PIN_CONTROL    = 0x70700,
     VERB_GET_EAPD_BTL       = 0xf0c00,
 };
 
@@ -188,6 +191,7 @@ enum codec_parameters {
     PARAM_NODE_COUNT        = 0x04,
     PARAM_FN_GROUP_TYPE     = 0x05,
     PARAM_AUDIO_WID_CAP     = 0x09,
+    PARAM_PIN_CAP           = 0x0c,
     PARAM_CONN_LIST_LEN     = 0x0e,
     PARAM_OUT_AMP_CAP       = 0x12,
 };
@@ -215,6 +219,15 @@ enum widget_capabilities {
     WIDGET_CAP_TYPE_MASK    = (0xf << 20),
 };
 
+enum pin_capabilities {
+    PIN_CAP_OUTPUT          = (1 << 4),
+    PIN_CAP_INPUT           = (1 << 5),
+};
+
+enum pin_ctl_flags {
+    PIN_CTL_ENABLE_OUTPUT   = (1 << 6),
+};
+
 enum sample_format {
     SR_48_KHZ               = 0,
     SR_44_KHZ               = (1 << 14),
diff --git a/hdaudio/main.c b/hdaudio/main.c
index 416aa80..5bc0e54 100644
--- a/hdaudio/main.c
+++ b/hdaudio/main.c
@@ -265,6 +265,7 @@ static void widget_dump_connections(struct hda_device* hda, int codec, int nid)
 static void widget_init(struct hda_device* hda, int codec, int nid)
 {
     uint32_t widget_cap;
+    enum widget_type type;
 
     widget_cap = codec_query(hda, codec, nid,
                              VERB_GET_PARAMETER | PARAM_AUDIO_WID_CAP);
@@ -272,15 +273,14 @@ static void widget_init(struct hda_device* hda, int codec, int nid)
         return;
     }
 
+    type = (widget_cap & WIDGET_CAP_TYPE_MASK) >> WIDGET_CAP_TYPE_SHIFT;
+
 #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;
@@ -307,12 +307,43 @@ static void widget_init(struct hda_device* hda, int codec, int nid)
     widget_dump_connections(hda, codec, nid);
 #endif
 
-    if ((widget_cap & 0xf00000) == 0) {
-        if (!hda->output.nid) {
-            DPRINTF("    * Using output at ID %d!\n", nid);
-            hda->output.codec = codec;
-            hda->output.nid = nid;
+    switch (type) {
+        case WIDGET_PIN:
+        {
+            uint32_t pin_cap, ctl;
+
+#ifdef DEBUG
+            uint32_t conf = codec_query(hda, codec, nid,
+                                        VERB_GET_CONFIG_DEFAULT);
+            DPRINTF("        pin config: %x\n", conf);
+#endif
+
+            pin_cap = codec_query(hda, codec, nid,
+                                  VERB_GET_PARAMETER | PARAM_PIN_CAP);
+            if ((pin_cap & PIN_CAP_OUTPUT) == 0) {
+                return;
+            }
+
+            ctl = codec_query(hda, codec, nid, VERB_GET_PIN_CONTROL);
+            DPRINTF("        ctl: %x\n", ctl);
+
+            ctl |= PIN_CTL_ENABLE_OUTPUT;
+            codec_query(hda, codec, nid, VERB_SET_PIN_CONTROL | ctl);
+            break;
         }
+
+        case WIDGET_OUTPUT:
+        {
+            if (!hda->output.nid) {
+                DPRINTF("    * Using output at ID %d!\n", nid);
+                hda->output.codec = codec;
+                hda->output.nid = nid;
+            }
+            break;
+        }
+
+        default:
+            return;
     }
 }
 
-- 
2.1.4