aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_codec.c44
-rw-r--r--sound/pci/hda/hda_local.h5
-rw-r--r--sound/pci/hda/patch_analog.c14
-rw-r--r--sound/pci/hda/patch_atihdmi.c14
-rw-r--r--sound/pci/hda/patch_cmedia.c14
-rw-r--r--sound/pci/hda/patch_conexant.c15
-rw-r--r--sound/pci/hda/patch_realtek.c14
-rw-r--r--sound/pci/hda/patch_sigmatel.c14
-rw-r--r--sound/pci/hda/patch_via.c14
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 */
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);
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
149int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); 149int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
150int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); 150int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
151int 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);
151int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, 156int 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);
153int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, 158int 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
195static 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
97static 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
97static struct hda_pcm_stream atihdmi_pcm_digital_playback = { 108static 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
500static 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
139static 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
1919static 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
1919static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 1930static 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
817static 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
380static 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