From: Stephen Warren <swarren@wwwdotorg.org>
To: stable@vger.kernel.org
Cc: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>,
Anssi Hannula <anssi.hannula@iki.fi>,
alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org,
Stephen Warren <swarren@nvidia.com>
Subject: [PATCH 2/2] ALSA: hda/hdmi - allow PIN_OUT to be dynamically enabled
Date: Mon, 3 Feb 2014 16:54:04 -0700 [thread overview]
Message-ID: <1391471644-16256-2-git-send-email-swarren@wwwdotorg.org> (raw)
In-Reply-To: <1391471644-16256-1-git-send-email-swarren@wwwdotorg.org>
From: Stephen Warren <swarren@nvidia.com>
(This is upstream 75fae117a5db "ALSA: hda/hdmi - allow PIN_OUT to be
dynamically enabled", backported to stable 3.10 through 3.12. 3.13 and
later can take the original patch.)
Commit 384a48d71520 "ALSA: hda: HDMI: Support codecs with fewer cvts
than pins" dynamically enabled each pin widget's PIN_OUT only when the
pin was actively in use. This was required on certain NVIDIA CODECs for
correct operation. Specifically, if multiple pin widgets each had their
mux input select the same audio converter widget and each pin widget had
PIN_OUT enabled, then only one of the pin widgets would actually receive
the audio, and often not the one the user wanted!
However, this apparently broke some Intel systems, and commit
6169b673618b "ALSA: hda - Always turn on pins for HDMI/DP" reverted the
dynamic setting of PIN_OUT. This in turn broke the afore-mentioned NVIDIA
CODECs.
This change supports either dynamic or static handling of PIN_OUT,
selected by a flag set up during CODEC initialization. This flag is
enabled for all recent NVIDIA GPUs.
Reported-by: Uosis <uosisl@gmail.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
sound/pci/hda/patch_hdmi.c | 40 ++++++++++++++++++++++++++++++++++++----
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index aad73a1fc2cd..417e0fc2d119 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -88,6 +88,9 @@ struct hdmi_spec {
unsigned int channels_max; /* max over all cvts */
struct hdmi_eld temp_eld;
+
+ bool dyn_pin_out;
+
/*
* Non-generic ATI/NVIDIA specific
*/
@@ -452,15 +455,25 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
{
+ struct hdmi_spec *spec = codec->spec;
+ int pin_out;
+
/* Unmute */
if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
- /* Enable pin out: some machines with GM965 gets broken output when
- * the pin is disabled or changed while using with HDMI
- */
+
+ if (spec->dyn_pin_out)
+ /* Disable pin out until stream is active */
+ pin_out = 0;
+ else
+ /* Enable pin out: some machines with GM965 gets broken output
+ * when the pin is disabled or changed while using with HDMI
+ */
+ pin_out = PIN_OUT;
+
snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_out);
}
static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
@@ -1535,6 +1548,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
hda_nid_t pin_nid = per_pin->pin_nid;
bool non_pcm;
+ int pinctl;
non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
per_pin->channels = substream->runtime->channels;
@@ -1544,6 +1558,14 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
+ if (spec->dyn_pin_out) {
+ pinctl = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+ snd_hda_codec_write(codec, pin_nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ pinctl | PIN_OUT);
+ }
+
return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
}
@@ -1563,6 +1585,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
int cvt_idx, pin_idx;
struct hdmi_spec_per_cvt *per_cvt;
struct hdmi_spec_per_pin *per_pin;
+ int pinctl;
if (hinfo->nid) {
cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
@@ -1579,6 +1602,14 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
return -EINVAL;
per_pin = get_pin(spec, pin_idx);
+ if (spec->dyn_pin_out) {
+ pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+ snd_hda_codec_write(codec, per_pin->pin_nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ pinctl & ~PIN_OUT);
+ }
+
snd_hda_spdif_ctls_unassign(codec, pin_idx);
per_pin->chmap_set = false;
memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
@@ -2570,6 +2601,7 @@ static int patch_nvhdmi(struct hda_codec *codec)
return err;
spec = codec->spec;
+ spec->dyn_pin_out = true;
return 0;
}
--
1.8.1.5
next prev parent reply other threads:[~2014-02-03 23:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-03 23:54 [PATCH 1/2] ALSA: hda - hdmi: introduce patch_nvhdmi() Stephen Warren
2014-02-03 23:54 ` Stephen Warren [this message]
2014-02-05 11:11 ` Luis Henriques
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1391471644-16256-2-git-send-email-swarren@wwwdotorg.org \
--to=swarren@wwwdotorg.org \
--cc=alsa-devel@alsa-project.org \
--cc=anssi.hannula@iki.fi \
--cc=linux-kernel@vger.kernel.org \
--cc=perex@perex.cz \
--cc=stable@vger.kernel.org \
--cc=swarren@nvidia.com \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®