ALSA: hda: hdmi - fix port numbering for ICL and TGL platforms
[linux-2.6-block.git] / sound / pci / hda / patch_hdmi.c
index b72553710ffbd91eaeaf503fe601eff9d3789258..dec90f931baefad50c8ebb94f2dd8bd72ae51173 100644 (file)
@@ -37,23 +37,6 @@ static bool static_hdmi_pcm;
 module_param(static_hdmi_pcm, bool, 0644);
 MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
 
-#define is_haswell(codec)  ((codec)->core.vendor_id == 0x80862807)
-#define is_broadwell(codec)    ((codec)->core.vendor_id == 0x80862808)
-#define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
-#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
-#define is_kabylake(codec) ((codec)->core.vendor_id == 0x8086280b)
-#define is_geminilake(codec) (((codec)->core.vendor_id == 0x8086280d) || \
-                               ((codec)->core.vendor_id == 0x80862800))
-#define is_cannonlake(codec) ((codec)->core.vendor_id == 0x8086280c)
-#define is_icelake(codec) ((codec)->core.vendor_id == 0x8086280f)
-#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
-                               || is_skylake(codec) || is_broxton(codec) \
-                               || is_kabylake(codec) || is_geminilake(codec) \
-                               || is_cannonlake(codec) || is_icelake(codec))
-#define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
-#define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
-#define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec))
-
 struct hdmi_spec_per_cvt {
        hda_nid_t cvt_nid;
        int assigned;
@@ -160,6 +143,7 @@ struct hdmi_spec {
 
        bool dyn_pin_out;
        bool dyn_pcm_assign;
+       bool intel_hsw_fixup;   /* apply Intel platform-specific fixups */
        /*
         * Non-generic VIA/NVIDIA specific
         */
@@ -923,7 +907,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
                return err;
        }
 
-       if (is_haswell_plus(codec)) {
+       if (spec->intel_hsw_fixup) {
 
                /*
                 * on recent platforms IEC Coding Type is required for HBR
@@ -1707,7 +1691,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
         * To simplify the implementation, malloc all
         * the virtual pins in the initialization statically
         */
-       if (is_haswell_plus(codec)) {
+       if (spec->intel_hsw_fixup) {
                /*
                 * On Intel platforms, device entries number is
                 * changed dynamically. If there is a DP MST
@@ -1756,7 +1740,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
                per_pin->dev_id = i;
                per_pin->non_pcm = false;
                snd_hda_set_dev_select(codec, pin_nid, i);
-               if (is_haswell_plus(codec))
+               if (spec->intel_hsw_fixup)
                        intel_haswell_fixup_connect_list(codec, pin_nid);
                err = hdmi_read_pin_conn(codec, pin_idx);
                if (err < 0)
@@ -2073,15 +2057,24 @@ static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
 static int generic_hdmi_build_pcms(struct hda_codec *codec)
 {
        struct hdmi_spec *spec = codec->spec;
-       int idx;
+       int idx, pcm_num;
 
        /*
         * for non-mst mode, pcm number is the same as before
-        * for DP MST mode, pcm number is (nid number + dev_num - 1)
-        *  dev_num is the device entry number in a pin
-        *
+        * for DP MST mode without extra PCM, pcm number is same
+        * for DP MST mode with extra PCMs, pcm number is
+        *  (nid number + dev_num - 1)
+        * dev_num is the device entry number in a pin
         */
-       for (idx = 0; idx < spec->num_nids + spec->dev_num - 1; idx++) {
+
+       if (codec->mst_no_extra_pcms)
+               pcm_num = spec->num_nids;
+       else
+               pcm_num = spec->num_nids + spec->dev_num - 1;
+
+       codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+
+       for (idx = 0; idx < pcm_num; idx++) {
                struct hda_pcm *info;
                struct hda_pcm_stream *pstr;
 
@@ -2671,7 +2664,7 @@ static int intel_pin2port(void *audio_ptr, int pin_nid)
         */
        for (i = 0; i < spec->port_num; i++) {
                if (pin_nid == spec->port_map[i])
-                       return i + 1;
+                       return i;
        }
 
        /* return -1 if pin number exceeds our expectation */
@@ -2691,9 +2684,9 @@ static int intel_port2pin(struct hda_codec *codec, int port)
                return port + intel_base_nid(codec) - 1;
        }
 
-       if (port < 1 || port > spec->port_num)
+       if (port < 0 || port >= spec->port_num)
                return 0;
-       return spec->port_map[port - 1];
+       return spec->port_map[port];
 }
 
 static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
@@ -2814,6 +2807,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
        spec->vendor_nid = vendor_nid;
        spec->port_map = port_map;
        spec->port_num = port_num;
+       spec->intel_hsw_fixup = true;
 
        intel_haswell_enable_all_pins(codec, true);
        intel_haswell_fixup_enable_dp12(codec);
@@ -2844,13 +2838,25 @@ static int patch_i915_icl_hdmi(struct hda_codec *codec)
 {
        /*
         * pin to port mapping table where the value indicate the pin number and
-        * the index indicate the port number with 1 base.
+        * the index indicate the port number.
+        */
+       static const int map[] = {0x0, 0x4, 0x6, 0x8, 0xa, 0xb};
+
+       return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
+}
+
+static int patch_i915_tgl_hdmi(struct hda_codec *codec)
+{
+       /*
+        * pin to port mapping table where the value indicate the pin number and
+        * the index indicate the port number.
         */
-       static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb};
+       static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
 
        return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
 }
 
+
 /* Intel Baytrail and Braswell; with eld notifier */
 static int patch_i915_byt_hdmi(struct hda_codec *codec)
 {
@@ -4153,6 +4159,7 @@ HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI",      patch_i915_hsw_hdmi),
 HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI", patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI",    patch_i915_icl_hdmi),
+HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI",  patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",        patch_i915_byt_hdmi),
 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",   patch_i915_byt_hdmi),