diff options
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 64f0a5e73a25..5ef95034d041 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -132,6 +132,9 @@ struct hdmi_spec { | |||
| 132 | 132 | ||
| 133 | struct hdmi_eld temp_eld; | 133 | struct hdmi_eld temp_eld; |
| 134 | struct hdmi_ops ops; | 134 | struct hdmi_ops ops; |
| 135 | |||
| 136 | bool dyn_pin_out; | ||
| 137 | |||
| 135 | /* | 138 | /* |
| 136 | * Non-generic VIA/NVIDIA specific | 139 | * Non-generic VIA/NVIDIA specific |
| 137 | */ | 140 | */ |
| @@ -500,15 +503,25 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid, | |||
| 500 | 503 | ||
| 501 | static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid) | 504 | static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
| 502 | { | 505 | { |
| 506 | struct hdmi_spec *spec = codec->spec; | ||
| 507 | int pin_out; | ||
| 508 | |||
| 503 | /* Unmute */ | 509 | /* Unmute */ |
| 504 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) | 510 | if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) |
| 505 | snd_hda_codec_write(codec, pin_nid, 0, | 511 | snd_hda_codec_write(codec, pin_nid, 0, |
| 506 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 512 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); |
| 507 | /* Enable pin out: some machines with GM965 gets broken output when | 513 | |
| 508 | * the pin is disabled or changed while using with HDMI | 514 | if (spec->dyn_pin_out) |
| 509 | */ | 515 | /* Disable pin out until stream is active */ |
| 516 | pin_out = 0; | ||
| 517 | else | ||
| 518 | /* Enable pin out: some machines with GM965 gets broken output | ||
| 519 | * when the pin is disabled or changed while using with HDMI | ||
| 520 | */ | ||
| 521 | pin_out = PIN_OUT; | ||
| 522 | |||
| 510 | snd_hda_codec_write(codec, pin_nid, 0, | 523 | snd_hda_codec_write(codec, pin_nid, 0, |
| 511 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 524 | AC_VERB_SET_PIN_WIDGET_CONTROL, pin_out); |
| 512 | } | 525 | } |
| 513 | 526 | ||
| 514 | static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid) | 527 | static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid) |
| @@ -1735,6 +1748,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1735 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | 1748 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
| 1736 | hda_nid_t pin_nid = per_pin->pin_nid; | 1749 | hda_nid_t pin_nid = per_pin->pin_nid; |
| 1737 | bool non_pcm; | 1750 | bool non_pcm; |
| 1751 | int pinctl; | ||
| 1738 | 1752 | ||
| 1739 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | 1753 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); |
| 1740 | mutex_lock(&per_pin->lock); | 1754 | mutex_lock(&per_pin->lock); |
| @@ -1744,6 +1758,14 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1744 | hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); | 1758 | hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); |
| 1745 | mutex_unlock(&per_pin->lock); | 1759 | mutex_unlock(&per_pin->lock); |
| 1746 | 1760 | ||
| 1761 | if (spec->dyn_pin_out) { | ||
| 1762 | pinctl = snd_hda_codec_read(codec, pin_nid, 0, | ||
| 1763 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
| 1764 | snd_hda_codec_write(codec, pin_nid, 0, | ||
| 1765 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
| 1766 | pinctl | PIN_OUT); | ||
| 1767 | } | ||
| 1768 | |||
| 1747 | return spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); | 1769 | return spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); |
| 1748 | } | 1770 | } |
| 1749 | 1771 | ||
| @@ -1763,6 +1785,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
| 1763 | int cvt_idx, pin_idx; | 1785 | int cvt_idx, pin_idx; |
| 1764 | struct hdmi_spec_per_cvt *per_cvt; | 1786 | struct hdmi_spec_per_cvt *per_cvt; |
| 1765 | struct hdmi_spec_per_pin *per_pin; | 1787 | struct hdmi_spec_per_pin *per_pin; |
| 1788 | int pinctl; | ||
| 1766 | 1789 | ||
| 1767 | if (hinfo->nid) { | 1790 | if (hinfo->nid) { |
| 1768 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); | 1791 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); |
| @@ -1779,6 +1802,14 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
| 1779 | return -EINVAL; | 1802 | return -EINVAL; |
| 1780 | per_pin = get_pin(spec, pin_idx); | 1803 | per_pin = get_pin(spec, pin_idx); |
| 1781 | 1804 | ||
| 1805 | if (spec->dyn_pin_out) { | ||
| 1806 | pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0, | ||
| 1807 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
| 1808 | snd_hda_codec_write(codec, per_pin->pin_nid, 0, | ||
| 1809 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
| 1810 | pinctl & ~PIN_OUT); | ||
| 1811 | } | ||
| 1812 | |||
| 1782 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | 1813 | snd_hda_spdif_ctls_unassign(codec, pin_idx); |
| 1783 | 1814 | ||
| 1784 | mutex_lock(&per_pin->lock); | 1815 | mutex_lock(&per_pin->lock); |
| @@ -2840,6 +2871,7 @@ static int patch_nvhdmi(struct hda_codec *codec) | |||
| 2840 | return err; | 2871 | return err; |
| 2841 | 2872 | ||
| 2842 | spec = codec->spec; | 2873 | spec = codec->spec; |
| 2874 | spec->dyn_pin_out = true; | ||
| 2843 | 2875 | ||
| 2844 | spec->ops.chmap_cea_alloc_validate_get_type = | 2876 | spec->ops.chmap_cea_alloc_validate_get_type = |
| 2845 | nvhdmi_chmap_cea_alloc_validate_get_type; | 2877 | nvhdmi_chmap_cea_alloc_validate_get_type; |
