ALSA: hda - program ICT bits to support HBR audio
authorSriram Periyasamy <sriramx.periyasamy@intel.com>
Tue, 19 Sep 2017 22:25:05 +0000 (17:25 -0500)
committerTakashi Iwai <tiwai@suse.de>
Wed, 20 Sep 2017 10:01:01 +0000 (12:01 +0200)
On recent Intel platforms (Haswell, Broadwell, Skylake, ApolloLake,
KabyLake, ...), the IEC Coding Type (ICT) bitfield in the Digital
Converter Control #3 needs to be set explicitly for HDMI/DisplayPort
High Bit Rate (HBR) audio playback to work. This was not required in
earlier platforms when HBR was first introduced. The ICT bits are
defined in Section 7.3.3.9 of the HDaudio 1.0a specification.

Since the ICT bitfield was not specified for HDAudio 1.0 devices
(before 2009), we only program it on machines more recent than
Haswell.

We tested that this fix is not needed on Baytrail-I (MinnowBoard
Turbot) and believe by extension it also does not apply to Braswell.

[ Moved AC_VERB_SET_DIGI_CONVERT_3 definition to the right place
  by tiwai ]

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98797

Signed-off-by: Sriram Periyasamy <sriramx.periyasamy@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/hda_verbs.h
sound/pci/hda/patch_hdmi.c

index d0509db..f89cd5e 100644 (file)
@@ -95,6 +95,7 @@ enum {
 #define AC_VERB_SET_EAPD_BTLENABLE             0x70c
 #define AC_VERB_SET_DIGI_CONVERT_1             0x70d
 #define AC_VERB_SET_DIGI_CONVERT_2             0x70e
+#define AC_VERB_SET_DIGI_CONVERT_3             0x73e
 #define AC_VERB_SET_VOLUME_KNOB_CONTROL                0x70f
 #define AC_VERB_SET_GPIO_DATA                  0x715
 #define AC_VERB_SET_GPIO_MASK                  0x716
index 2b64fab..c19c81d 100644 (file)
@@ -906,6 +906,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
                              hda_nid_t pin_nid, u32 stream_tag, int format)
 {
        struct hdmi_spec *spec = codec->spec;
+       unsigned int param;
        int err;
 
        err = spec->ops.pin_hbr_setup(codec, pin_nid, is_hbr_format(format));
@@ -915,6 +916,26 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
                return err;
        }
 
+       if (is_haswell_plus(codec)) {
+
+               /*
+                * on recent platforms IEC Coding Type is required for HBR
+                * support, read current Digital Converter settings and set
+                * ICT bitfield if needed.
+                */
+               param = snd_hda_codec_read(codec, cvt_nid, 0,
+                                          AC_VERB_GET_DIGI_CONVERT_1, 0);
+
+               param = (param >> 16) & ~(AC_DIG3_ICT);
+
+               /* on recent platforms ICT mode is required for HBR support */
+               if (is_hbr_format(format))
+                       param |= 0x1;
+
+               snd_hda_codec_write(codec, cvt_nid, 0,
+                                   AC_VERB_SET_DIGI_CONVERT_3, param);
+       }
+
        snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
        return 0;
 }