This is a note to let you know that I've just added the patch titled ALSA: hda/hdmi - allow PIN_OUT to be dynamically enabled to the 3.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: alsa-hda-hdmi-allow-pin_out-to-be-dynamically-enabled.patch and it can be found in the queue-3.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From swarren@xxxxxxxxxxxxx Tue Feb 4 09:58:00 2014 From: Stephen Warren <swarren@xxxxxxxxxxxxx> Date: Mon, 3 Feb 2014 16:54:04 -0700 Subject: ALSA: hda/hdmi - allow PIN_OUT to be dynamically enabled To: stable@xxxxxxxxxxxxxxx Cc: Jaroslav Kysela <perex@xxxxxxxx>, Takashi Iwai <tiwai@xxxxxxx>, Anssi Hannula <anssi.hannula@xxxxxx>, alsa-devel@xxxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, Stephen Warren <swarren@xxxxxxxxxx> Message-ID: <1391471644-16256-2-git-send-email-swarren@xxxxxxxxxxxxx> From: Stephen Warren <swarren@xxxxxxxxxx> (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@xxxxxxxxx> Signed-off-by: Stephen Warren <swarren@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- sound/pci/hda/patch_hdmi.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -86,6 +86,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 */ @@ -450,15 +453,25 @@ static void hdmi_write_dip_byte(struct h 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) @@ -1473,6 +1486,7 @@ static int generic_hdmi_playback_pcm_pre 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; @@ -1482,6 +1496,14 @@ static int generic_hdmi_playback_pcm_pre 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); } @@ -1501,6 +1523,7 @@ static int hdmi_pcm_close(struct hda_pcm 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); @@ -1517,6 +1540,14 @@ static int hdmi_pcm_close(struct hda_pcm 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)); @@ -2486,6 +2517,7 @@ static int patch_nvhdmi(struct hda_codec return err; spec = codec->spec; + spec->dyn_pin_out = true; return 0; } Patches currently in stable-queue which might be from swarren@xxxxxxxxxxxxx are queue-3.10/alsa-hda-hdmi-introduce-patch_nvhdmi.patch queue-3.10/lib-decompressors-fix-no-limit-output-buffer-length.patch queue-3.10/alsa-hda-hdmi-allow-pin_out-to-be-dynamically-enabled.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html