From patchwork Thu Apr 11 07:38:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Henningsson X-Patchwork-Id: 235597 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 5908A2C00C1 for ; Thu, 11 Apr 2013 17:38:11 +1000 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UQC50-000131-Cn; Thu, 11 Apr 2013 07:37:58 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1UQC4y-00012v-AU for kernel-team@lists.ubuntu.com; Thu, 11 Apr 2013 07:37:56 +0000 Received: from hd9483857.selulk5.dyn.perspektivbredband.net ([217.72.56.87] helo=[192.168.8.102]) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1UQC4y-0002aJ-4m for kernel-team@lists.ubuntu.com; Thu, 11 Apr 2013 07:37:56 +0000 Message-ID: <5166685B.9070207@canonical.com> Date: Thu, 11 Apr 2013 09:38:03 +0200 From: David Henningsson User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: kernel-team@lists.ubuntu.com Subject: [Raring PATCH] Ubuntu (no-up): ALSA: hda - fixup D3 pin and right channel mute on Haswell HDMI audio X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com BugLink: https://bugs.launchpad.net/bugs/1167270 This patch has been tested on two machines, and found to resolve one of the HDMI audio issues on Haswell. The root cause is lack of synchronisation between the video driver and the audio driver. Upstream wants to resolve this by adding synchronisation mechanisms, so they won't take this patch. But since kernel freeze is today, I wanted to ask you to accept this intermediate workaround, which at every playback start checks for the error and corrects it if found. From 37b4fbb88dc03160fd71d1ec11ba14e83e6a79dc Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 10 Apr 2013 12:26:07 +0200 Subject: [PATCH] ALSA: hda - fixup D3 pin and right channel mute on Haswell HDMI audio When graphics initializes the HDMI chip, sometimes this leads to pins going into D3 and right channel being muted. If the audio driver finishes initialization before the graphic driver does, this situation becomes permanent. This is a workaround that checks for this situation and corrects it on playback prepare. It has been verified working on at least one machine. BugLink: https://bugs.launchpad.net/bugs/1167270 Signed-off-by: David Henningsson --- sound/pci/hda/patch_hdmi.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index ede8215..32930e6 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1018,6 +1018,41 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) hdmi_non_intrinsic_event(codec, res); } +static void haswell_verify_pin_D0(struct hda_codec *codec, hda_nid_t nid) +{ + int pwr, lamp, ramp; + + pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); + pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT; + if (pwr != AC_PWRST_D0) { + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, + AC_PWRST_D0); + msleep(40); + pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); + pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT; + snd_printd("Haswell HDMI audio: Power for pin 0x%x is now D%d\n", nid, pwr); + } + + lamp = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT); + ramp = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT); + if (lamp != ramp) { + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT | lamp); + + lamp = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT); + ramp = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT); + snd_printd("Haswell HDMI audio: Mute after set on pin 0x%x: [0x%x 0x%x]\n", nid, lamp, ramp); + } +} + /* * Callbacks */ @@ -1032,6 +1067,9 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, int pinctl; int new_pinctl = 0; + if (codec->vendor_id == 0x80862807) + haswell_verify_pin_D0(codec, pin_nid); + if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) { pinctl = snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); -- 1.7.9.5