From patchwork Sun Aug 4 09:59:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim Gardner X-Patchwork-Id: 264509 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 E0FF92C0084 for ; Sun, 4 Aug 2013 20:00:17 +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 1V5v6O-0005Vl-E5; Sun, 04 Aug 2013 09:59:52 +0000 Received: from mail.tpi.com ([74.45.170.26]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1V5v6C-0005Tb-CX for kernel-team@lists.ubuntu.com; Sun, 04 Aug 2013 09:59:40 +0000 Received: from salmon.rtg.net (mail.tpi.com [10.0.0.205]) by mail.tpi.com (Postfix) with ESMTP id ADB673407A7; Sun, 4 Aug 2013 02:59:39 -0700 (PDT) Received: by salmon.rtg.net (Postfix, from userid 1000) id 6DD5322D00; Sun, 4 Aug 2013 03:59:39 -0600 (MDT) From: Tim Gardner To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/3 Raring SRU] ALSA: hda - Yet another fix for broken HSW HDMI pin connections Date: Sun, 4 Aug 2013 03:59:28 -0600 Message-Id: <1375610369-16225-2-git-send-email-tim.gardner@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1375610369-16225-1-git-send-email-tim.gardner@canonical.com> References: <1375610369-16225-1-git-send-email-tim.gardner@canonical.com> Cc: Takashi Iwai , Mengdong Lin 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: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Takashi Iwai BugLink: http://bugs.launchpad.net/bugs/1183125 A Haswell test machine showed that the invalid connection list, but this time it has only a single pin on the codec, thus the former fixup code doesn't work as it assumes the three pins blindly. This patch splits the former fixup code to two parts: - Enable eDP 1.2 for Haswell codec - Fix the connection list of pins on Haswell codec; the converter list is recorded dynamically in hdmi_add_cvt(), and applied in hdmi_add_pin() Signed-off-by: Mengdong Lin Signed-off-by: Takashi Iwai (cherry picked from commit c88d4e84e639df9a9640ecff71de2501a84d1f48) Signed-off-by: Tim Gardner --- sound/pci/hda/patch_hdmi.c | 56 +++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 7e1b7d9..c635fa5 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -83,6 +83,7 @@ struct hdmi_spec { struct hda_gen_spec gen; int num_cvts; struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS]; + hda_nid_t cvt_nids[MAX_HDMI_CVTS]; int num_pins; struct hdmi_spec_per_pin pins[MAX_HDMI_PINS]; @@ -1235,6 +1236,9 @@ static void hdmi_repoll_eld(struct work_struct *work) hdmi_present_sense(per_pin, per_pin->repoll_count); } +static void intel_haswell_fixup_connect_list(struct hda_codec *codec, + hda_nid_t nid); + static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) { struct hdmi_spec *spec = codec->spec; @@ -1254,6 +1258,9 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS)) return -E2BIG; + if (codec->vendor_id == 0x80862807) + intel_haswell_fixup_connect_list(codec, pin_nid); + pin_idx = spec->num_pins; per_pin = &spec->pins[pin_idx]; @@ -1301,7 +1308,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) if (err < 0) return err; - spec->num_cvts++; + spec->cvt_nids[spec->num_cvts++] = cvt_nid; return 0; } @@ -1732,27 +1739,22 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = { .unsol_event = hdmi_unsol_event, }; -static void intel_haswell_fixup_connect_list(struct hda_codec *codec) -{ - unsigned int vendor_param; - hda_nid_t list[3] = {0x2, 0x3, 0x4}; - vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0); - if (vendor_param == -1 || vendor_param & 0x02) - return; - - /* enable DP1.2 mode */ - vendor_param |= 0x02; - snd_hda_codec_read(codec, 0x08, 0, 0x781, vendor_param); +static void intel_haswell_fixup_connect_list(struct hda_codec *codec, + hda_nid_t nid) +{ + struct hdmi_spec *spec = codec->spec; + hda_nid_t conns[4]; + int nconns; - vendor_param = snd_hda_codec_read(codec, 0x08, 0, 0xf81, 0); - if (vendor_param == -1 || !(vendor_param & 0x02)) + nconns = snd_hda_get_connections(codec, nid, conns, ARRAY_SIZE(conns)); + if (nconns == spec->num_cvts && + !memcmp(conns, spec->cvt_nids, spec->num_cvts * sizeof(hda_nid_t))) return; - /* override 3 pins connection list */ - snd_hda_override_conn_list(codec, 0x05, 3, list); - snd_hda_override_conn_list(codec, 0x06, 3, list); - snd_hda_override_conn_list(codec, 0x07, 3, list); + /* override pins connection list */ + snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid); + snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids); } #define INTEL_VENDOR_NID 0x08 @@ -1783,6 +1785,22 @@ static void intel_haswell_enable_all_pins(struct hda_codec *codec, return; } +static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec) +{ + unsigned int vendor_param; + + vendor_param = snd_hda_codec_read(codec, 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; + snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0, + INTEL_SET_VENDOR_VERB, vendor_param); +} + + /* available models for fixup */ enum { @@ -1821,7 +1839,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); if (codec->vendor_id == 0x80862807) - intel_haswell_fixup_connect_list(codec); + intel_haswell_fixup_enable_dp12(codec); if (hdmi_parse_codec(codec) < 0) { codec->spec = NULL;