diff options
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 44 |
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 */ | ||
1894 | static 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 | ||
1923 | int 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); |