From 023d8218ec0dfc30e11d4ec54f640e8f127d1fbe Mon Sep 17 00:00:00 2001 From: Hyungwon Hwang Date: Wed, 13 Apr 2016 09:27:39 +0900 Subject: ALSA: hda - Fix regression of monitor_present flag in eld proc file The commit [bd48128539ab: ALSA: hda - Fix forgotten HDMI monitor_present update] covered the missing update of monitor_present flag, but this caused a regression for devices without the i915 eld notifier. Since the old code supposed that pin_eld->monitor_present was updated by the caller side, the hdmi_present_sense_via_verbs() doesn't update the temporary eld->monitor_present but only pin_eld->monitor_present, which is now overridden in update_eld(). The fix is to update pin_eld->monitor_present as well before calling update_eld(). Note that this may still leave monitor_present flag in an inconsistent state when the driver repolls, but this is at least the old behavior. More proper fix will follow in the later patch. Fixes: bd48128539ab ('ALSA: hda - Fix forgotten HDMI monitor_present update') Signed-off-by: Hyungwon Hwang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci/hda/patch_hdmi.c') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 5af372d01834..9de114df270b 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1414,6 +1414,8 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, mutex_lock(&per_pin->lock); pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); + eld->monitor_present = pin_eld->monitor_present; + if (pin_eld->monitor_present) eld->eld_valid = !!(present & AC_PINSENSE_ELDV); else -- cgit From c44da62b55bb453052869ab095bcda7aa0bd6bba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Apr 2016 09:45:53 +0200 Subject: ALSA: hda - Fix inconsistent monitor_present state until repoll While the previous commit fixed the missing monitor_present flag update, it may be still in an inconsistent state while the driver repolls: the flag itself is updated, but the eld_valid flag and the contents don't follow until the repoll finishes (and may be repeated for a few times). The basic problem is that pin_eld->monitor_present is updated in the caller side. This should have been updated only in update_eld(). So, the proper fix is to avoid accessing pin_eld but only spec->temp_eld. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'sound/pci/hda/patch_hdmi.c') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 9de114df270b..c83c1a8d9742 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1396,7 +1396,6 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, struct hda_codec *codec = per_pin->codec; struct hdmi_spec *spec = codec->spec; struct hdmi_eld *eld = &spec->temp_eld; - struct hdmi_eld *pin_eld = &per_pin->sink_eld; hda_nid_t pin_nid = per_pin->pin_nid; /* * Always execute a GetPinSense verb here, even when called from @@ -1413,17 +1412,15 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, present = snd_hda_pin_sense(codec, pin_nid); mutex_lock(&per_pin->lock); - pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); - eld->monitor_present = pin_eld->monitor_present; - - if (pin_eld->monitor_present) + eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); + if (eld->monitor_present) eld->eld_valid = !!(present & AC_PINSENSE_ELDV); else eld->eld_valid = false; codec_dbg(codec, "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid); + codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); if (eld->eld_valid) { if (spec->ops.pin_get_eld(codec, pin_nid, eld->eld_buffer, @@ -1443,7 +1440,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, else update_eld(codec, per_pin, eld); - ret = !repoll || !pin_eld->monitor_present || pin_eld->eld_valid; + ret = !repoll || !eld->monitor_present || eld->eld_valid; jack = snd_hda_jack_tbl_get(codec, pin_nid); if (jack) -- cgit From ed0739b577f2ddd53835f1e20d014fccab195c42 Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Mon, 18 Apr 2016 09:16:28 +0800 Subject: ALSA - hda: hdmi check NULL pointer in hdmi_set_chmap Make sure per_pin is not NULL before using it. Fixes: 9b3dc8aa3fb1 ('ALSA: hda - Register chmap obj as priv data instead of codec') Signed-off-by: Libin Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci/hda/patch_hdmi.c') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index c83c1a8d9742..40933aa33afe 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1858,6 +1858,8 @@ static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx, struct hdmi_spec *spec = codec->spec; struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx); + if (!per_pin) + return; mutex_lock(&per_pin->lock); per_pin->chmap_set = true; memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap)); -- cgit From bb03ed216370cb021f377f923471e56d1de3ff5d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Apr 2016 16:39:17 +0200 Subject: ALSA: hda - Update BCLK also at hotplug for i915 HSW/BDW The recent bug report suggests that BCLK setup for i915 HSW/BDW needs to be updated at each HDMI hotplug, not only at initialization and resume. That is, we need to update HSW_EM4 and HSW_EM5 registers at ELD notification, too. Otherwise the HDMI audio may be out of sync and played in a wrong pitch. However, the HDA codec driver has no access to the controller registers, and currently the code managing these registers is in hda_intel.c, i.e. local to the controller driver. For allowing the explicit BCLK update from the codec driver, as in this patch, the former haswell_set_bclk() in hda_intel.c is moved to hdac_i915.c and exposed as snd_hdac_i915_set_bclk(). This is called from both the HDA controller driver and intel_pin_eld_notify() in HDMI codec driver. Along with this change, snd_hdac_get_display_clk() gets dropped as it's no longer used. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91410 Cc: # v4.5+ Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/hda/patch_hdmi.c') diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 40933aa33afe..1483f85999ec 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2232,6 +2232,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port) if (atomic_read(&(codec)->core.in_pm)) return; + snd_hdac_i915_set_bclk(&codec->bus->core); check_presence_and_report(codec, pin_nid); } -- cgit