aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e768187465e3..2c2fcdc72fcf 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1114,10 +1114,14 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn
1114 change = codec->spdif_ctls != val; 1114 change = codec->spdif_ctls != val;
1115 if (change || codec->in_resume) { 1115 if (change || codec->in_resume) {
1116 codec->spdif_ctls = val; 1116 codec->spdif_ctls = val;
1117 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); 1117 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
1118 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1118 val & 0xff);
1119 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | 1119 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
1120 AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); 1120 snd_hda_codec_write(codec, nid, 0,
1121 AC_VERB_SET_AMP_GAIN_MUTE,
1122 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
1123 AC_AMP_SET_OUTPUT |
1124 ((val & 1) ? 0 : 0x80));
1121 } 1125 }
1122 mutex_unlock(&codec->spdif_mutex); 1126 mutex_unlock(&codec->spdif_mutex);
1123 return change; 1127 return change;
@@ -1886,6 +1890,21 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
1886 * Multi-channel / digital-out PCM helper functions 1890 * Multi-channel / digital-out PCM helper functions
1887 */ 1891 */
1888 1892
1893/* setup SPDIF output stream */
1894static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
1895 unsigned int stream_tag, unsigned int format)
1896{
1897 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1898 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1899 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
1900 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
1901 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
1902 /* turn on again (if needed) */
1903 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1904 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
1905 codec->spdif_ctls & 0xff);
1906}
1907
1889/* 1908/*
1890 * open the digital out in the exclusive mode 1909 * open the digital out in the exclusive mode
1891 */ 1910 */
@@ -1901,6 +1920,18 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mo
1901 return 0; 1920 return 0;
1902} 1921}
1903 1922
1923int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
1924 struct hda_multi_out *mout,
1925 unsigned int stream_tag,
1926 unsigned int format,
1927 struct snd_pcm_substream *substream)
1928{
1929 mutex_lock(&codec->spdif_mutex);
1930 setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
1931 mutex_unlock(&codec->spdif_mutex);
1932 return 0;
1933}
1934
1904/* 1935/*
1905 * release the digital out 1936 * release the digital out
1906 */ 1937 */
@@ -1942,9 +1973,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
1942 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && 1973 snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
1943 ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1974 ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1944 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1975 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1945 /* setup digital receiver */ 1976 setup_dig_out_stream(codec, mout->dig_out_nid,
1946 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1977 stream_tag, format);
1947 stream_tag, 0, format);
1948 } else { 1978 } else {
1949 mout->dig_out_used = 0; 1979 mout->dig_out_used = 0;
1950 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); 1980 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);