diff options
-rw-r--r-- | sound/pci/hda/hda_codec.c | 44 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_atihdmi.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 14 |
9 files changed, 134 insertions, 14 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); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 39718d6cdadd..3505a670995f 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -148,6 +148,11 @@ struct hda_multi_out { | |||
148 | 148 | ||
149 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); | 149 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); |
150 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); | 150 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); |
151 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | ||
152 | struct hda_multi_out *mout, | ||
153 | unsigned int stream_tag, | ||
154 | unsigned int format, | ||
155 | struct snd_pcm_substream *substream); | ||
151 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, | 156 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, |
152 | struct snd_pcm_substream *substream); | 157 | struct snd_pcm_substream *substream); |
153 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, | 158 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 9c241ccf6907..fa194f21282f 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
192 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 192 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
193 | } | 193 | } |
194 | 194 | ||
195 | static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
196 | struct hda_codec *codec, | ||
197 | unsigned int stream_tag, | ||
198 | unsigned int format, | ||
199 | struct snd_pcm_substream *substream) | ||
200 | { | ||
201 | struct ad198x_spec *spec = codec->spec; | ||
202 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
203 | format, substream); | ||
204 | } | ||
205 | |||
195 | /* | 206 | /* |
196 | * Analog capture | 207 | * Analog capture |
197 | */ | 208 | */ |
@@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { | |||
250 | .nid = 0, /* fill later */ | 261 | .nid = 0, /* fill later */ |
251 | .ops = { | 262 | .ops = { |
252 | .open = ad198x_dig_playback_pcm_open, | 263 | .open = ad198x_dig_playback_pcm_open, |
253 | .close = ad198x_dig_playback_pcm_close | 264 | .close = ad198x_dig_playback_pcm_close, |
265 | .prepare = ad198x_dig_playback_pcm_prepare | ||
254 | }, | 266 | }, |
255 | }; | 267 | }; |
256 | 268 | ||
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 831469d3a923..b89db1be4a0f 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c | |||
@@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
94 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 94 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
95 | } | 95 | } |
96 | 96 | ||
97 | static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
98 | struct hda_codec *codec, | ||
99 | unsigned int stream_tag, | ||
100 | unsigned int format, | ||
101 | struct snd_pcm_substream *substream) | ||
102 | { | ||
103 | struct atihdmi_spec *spec = codec->spec; | ||
104 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
105 | format, substream); | ||
106 | } | ||
107 | |||
97 | static struct hda_pcm_stream atihdmi_pcm_digital_playback = { | 108 | static struct hda_pcm_stream atihdmi_pcm_digital_playback = { |
98 | .substreams = 1, | 109 | .substreams = 1, |
99 | .channels_min = 2, | 110 | .channels_min = 2, |
@@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { | |||
101 | .nid = 0x2, /* NID to query formats and rates and setup streams */ | 112 | .nid = 0x2, /* NID to query formats and rates and setup streams */ |
102 | .ops = { | 113 | .ops = { |
103 | .open = atihdmi_dig_playback_pcm_open, | 114 | .open = atihdmi_dig_playback_pcm_open, |
104 | .close = atihdmi_dig_playback_pcm_close | 115 | .close = atihdmi_dig_playback_pcm_close, |
116 | .prepare = atihdmi_dig_playback_pcm_prepare | ||
105 | }, | 117 | }, |
106 | }; | 118 | }; |
107 | 119 | ||
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 5b9d3a31a1ae..3c722e667bc8 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
497 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 497 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
498 | } | 498 | } |
499 | 499 | ||
500 | static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
501 | struct hda_codec *codec, | ||
502 | unsigned int stream_tag, | ||
503 | unsigned int format, | ||
504 | struct snd_pcm_substream *substream) | ||
505 | { | ||
506 | struct cmi_spec *spec = codec->spec; | ||
507 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, | ||
508 | format, substream); | ||
509 | } | ||
510 | |||
500 | /* | 511 | /* |
501 | * Analog capture | 512 | * Analog capture |
502 | */ | 513 | */ |
@@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { | |||
556 | /* NID is set in cmi9880_build_pcms */ | 567 | /* NID is set in cmi9880_build_pcms */ |
557 | .ops = { | 568 | .ops = { |
558 | .open = cmi9880_dig_playback_pcm_open, | 569 | .open = cmi9880_dig_playback_pcm_open, |
559 | .close = cmi9880_dig_playback_pcm_close | 570 | .close = cmi9880_dig_playback_pcm_close, |
571 | .prepare = cmi9880_dig_playback_pcm_prepare | ||
560 | }, | 572 | }, |
561 | }; | 573 | }; |
562 | 574 | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index efb95dc2d6db..2349b5eb5aaa 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
136 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 136 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
137 | } | 137 | } |
138 | 138 | ||
139 | static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
140 | struct hda_codec *codec, | ||
141 | unsigned int stream_tag, | ||
142 | unsigned int format, | ||
143 | struct snd_pcm_substream *substream) | ||
144 | { | ||
145 | struct conexant_spec *spec = codec->spec; | ||
146 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
147 | stream_tag, | ||
148 | format, substream); | ||
149 | } | ||
150 | |||
139 | /* | 151 | /* |
140 | * Analog capture | 152 | * Analog capture |
141 | */ | 153 | */ |
@@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { | |||
194 | .nid = 0, /* fill later */ | 206 | .nid = 0, /* fill later */ |
195 | .ops = { | 207 | .ops = { |
196 | .open = conexant_dig_playback_pcm_open, | 208 | .open = conexant_dig_playback_pcm_open, |
197 | .close = conexant_dig_playback_pcm_close | 209 | .close = conexant_dig_playback_pcm_close, |
210 | .prepare = conexant_dig_playback_pcm_prepare | ||
198 | }, | 211 | }, |
199 | }; | 212 | }; |
200 | 213 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4243c6b491fc..d3f7a3dab1c4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1916,6 +1916,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
1916 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | 1916 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
1920 | struct hda_codec *codec, | ||
1921 | unsigned int stream_tag, | ||
1922 | unsigned int format, | ||
1923 | struct snd_pcm_substream *substream) | ||
1924 | { | ||
1925 | struct alc_spec *spec = codec->spec; | ||
1926 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
1927 | stream_tag, format, substream); | ||
1928 | } | ||
1929 | |||
1919 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | 1930 | static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
1920 | struct hda_codec *codec, | 1931 | struct hda_codec *codec, |
1921 | struct snd_pcm_substream *substream) | 1932 | struct snd_pcm_substream *substream) |
@@ -1984,7 +1995,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { | |||
1984 | /* NID is set in alc_build_pcms */ | 1995 | /* NID is set in alc_build_pcms */ |
1985 | .ops = { | 1996 | .ops = { |
1986 | .open = alc880_dig_playback_pcm_open, | 1997 | .open = alc880_dig_playback_pcm_open, |
1987 | .close = alc880_dig_playback_pcm_close | 1998 | .close = alc880_dig_playback_pcm_close, |
1999 | .prepare = alc880_dig_playback_pcm_prepare | ||
1988 | }, | 2000 | }, |
1989 | }; | 2001 | }; |
1990 | 2002 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6dd4822dbec0..612d355b9e01 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -814,6 +814,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
814 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 814 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
815 | } | 815 | } |
816 | 816 | ||
817 | static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
818 | struct hda_codec *codec, | ||
819 | unsigned int stream_tag, | ||
820 | unsigned int format, | ||
821 | struct snd_pcm_substream *substream) | ||
822 | { | ||
823 | struct sigmatel_spec *spec = codec->spec; | ||
824 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
825 | stream_tag, format, substream); | ||
826 | } | ||
827 | |||
817 | 828 | ||
818 | /* | 829 | /* |
819 | * Analog capture callbacks | 830 | * Analog capture callbacks |
@@ -848,7 +859,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | |||
848 | /* NID is set in stac92xx_build_pcms */ | 859 | /* NID is set in stac92xx_build_pcms */ |
849 | .ops = { | 860 | .ops = { |
850 | .open = stac92xx_dig_playback_pcm_open, | 861 | .open = stac92xx_dig_playback_pcm_open, |
851 | .close = stac92xx_dig_playback_pcm_close | 862 | .close = stac92xx_dig_playback_pcm_close, |
863 | .prepare = stac92xx_dig_playback_pcm_prepare | ||
852 | }, | 864 | }, |
853 | }; | 865 | }; |
854 | 866 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 2b11ac8689b9..ba32d1e52cb8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, | |||
377 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 377 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
378 | } | 378 | } |
379 | 379 | ||
380 | static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
381 | struct hda_codec *codec, | ||
382 | unsigned int stream_tag, | ||
383 | unsigned int format, | ||
384 | struct snd_pcm_substream *substream) | ||
385 | { | ||
386 | struct via_spec *spec = codec->spec; | ||
387 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | ||
388 | stream_tag, format, substream); | ||
389 | } | ||
390 | |||
380 | /* | 391 | /* |
381 | * Analog capture | 392 | * Analog capture |
382 | */ | 393 | */ |
@@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { | |||
433 | /* NID is set in via_build_pcms */ | 444 | /* NID is set in via_build_pcms */ |
434 | .ops = { | 445 | .ops = { |
435 | .open = via_dig_playback_pcm_open, | 446 | .open = via_dig_playback_pcm_open, |
436 | .close = via_dig_playback_pcm_close | 447 | .close = via_dig_playback_pcm_close, |
448 | .prepare = via_dig_playback_pcm_prepare | ||
437 | }, | 449 | }, |
438 | }; | 450 | }; |
439 | 451 | ||