ASoC: hdac_hdmi: Enable DP1.2 and all converters/pins
authorSubhransu S. Prusty <subhransu.s.prusty@intel.com>
Fri, 12 Feb 2016 02:16:03 +0000 (07:46 +0530)
committerMark Brown <broonie@kernel.org>
Mon, 15 Feb 2016 20:54:03 +0000 (20:54 +0000)
Skylake supports 3 pin and 3 converter widgets. But by default
only one converter and pin widget are enabled. In skylake
platform the DP port is on a different port which is not enabled
by default. To enable playback on DP port, enable all pin and
converter widget by sending a vendor VERB for a vendor widget to
set required bits.

As we are enabling the DP support enable the DP1.2 feature as well.

Enabling DP1.2 and all widget changes are copied from patch_hdmi.c.

Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/hdac_hdmi.c

index d22fa6b66c8056ba83a773005bcca57f460c73ab..b2e5e549b02230cf0f0ba67e0425a7f29e520841 100644 (file)
@@ -629,6 +629,46 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
        return 0;
 }
 
+#define INTEL_VENDOR_NID 0x08
+#define INTEL_GET_VENDOR_VERB 0xf81
+#define INTEL_SET_VENDOR_VERB 0x781
+#define INTEL_EN_DP12                  0x02 /* enable DP 1.2 features */
+#define INTEL_EN_ALL_PIN_CVTS  0x01 /* enable 2nd & 3rd pins and convertors */
+
+static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
+{
+       unsigned int vendor_param;
+
+       vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+                               INTEL_GET_VENDOR_VERB, 0);
+       if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
+               return;
+
+       vendor_param |= INTEL_EN_ALL_PIN_CVTS;
+       vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+                               INTEL_SET_VENDOR_VERB, vendor_param);
+       if (vendor_param == -1)
+               return;
+}
+
+static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
+{
+       unsigned int vendor_param;
+
+       vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+                               INTEL_GET_VENDOR_VERB, 0);
+       if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
+               return;
+
+       /* enable DP1.2 mode */
+       vendor_param |= INTEL_EN_DP12;
+       vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+                               INTEL_SET_VENDOR_VERB, vendor_param);
+       if (vendor_param == -1)
+               return;
+
+}
+
 /*
  * Parse all nodes and store the cvt/pin nids in array
  * Add one time initialization for pin and cvt widgets
@@ -641,6 +681,9 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
        struct hdac_hdmi_priv *hdmi = edev->private_data;
        int ret;
 
+       hdac_hdmi_skl_enable_all_pins(hdac);
+       hdac_hdmi_skl_enable_dp12(hdac);
+
        num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
        if (!nid || num_nodes <= 0) {
                dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");