aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorHarald Welte <HaraldWelte@viatech.com>2008-09-15 10:42:26 -0400
committerJaroslav Kysela <perex@perex.cz>2008-09-23 02:18:13 -0400
commit5691ec7fc302ecffddfa21b19477aaaa4386d002 (patch)
tree652d20e798a9b0f97a779eee36966b32f5ceb747 /sound/pci/hda
parentf8fdd4958b6c7af9abf630f06d43db4ddcd532f6 (diff)
ALSA: HDA VIA: Fix 2nd S/PDIF out function
As it seems, the recently-sent patch for the 2nd S/PDIF (HDMI) output is not working with alsa-kernel 1.0.18rc3. This patch makes it work by * activating the second S/PDIF output pin in the pin config * consolidating the dig_playback_pcm_prepare() with extra_dig_pcm_prepare() functions * remove the need for an extra hda_pcm_stream structure and rather represents the second digital output as substream within the primary S/PDIF digital out stream. Signed-off-by: Logan Li <LoganLi@viatech.com.cn> Signed-off-by: Harald Welte <HaraldWelte@viatech.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_via.c75
1 files changed, 22 insertions, 53 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 43fb96538b80..59a173e88128 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -123,7 +123,6 @@ struct via_spec {
123 char *stream_name_digital; 123 char *stream_name_digital;
124 struct hda_pcm_stream *stream_digital_playback; 124 struct hda_pcm_stream *stream_digital_playback;
125 struct hda_pcm_stream *stream_digital_capture; 125 struct hda_pcm_stream *stream_digital_capture;
126 struct hda_pcm_stream *stream_extra_digital_playback;
127 126
128 /* playback */ 127 /* playback */
129 struct hda_multi_out multiout; 128 struct hda_multi_out multiout;
@@ -656,17 +655,6 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
656 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 655 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
657} 656}
658 657
659static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
660 struct hda_codec *codec,
661 unsigned int stream_tag,
662 unsigned int format,
663 struct snd_pcm_substream *substream)
664{
665 struct via_spec *spec = codec->spec;
666 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
667 stream_tag, format, substream);
668}
669
670/* setup SPDIF output stream */ 658/* setup SPDIF output stream */
671static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid, 659static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
672 unsigned int stream_tag, unsigned int format) 660 unsigned int stream_tag, unsigned int format)
@@ -682,17 +670,25 @@ static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid,
682 codec->spdif_ctls & 0xff); 670 codec->spdif_ctls & 0xff);
683} 671}
684 672
685static int via_extra_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 673static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
686 struct hda_codec *codec, 674 struct hda_codec *codec,
687 unsigned int stream_tag, 675 unsigned int stream_tag,
688 unsigned int format, 676 unsigned int format,
689 struct snd_pcm_substream *substream) 677 struct snd_pcm_substream *substream)
690{ 678{
691 struct via_spec *spec = codec->spec; 679 struct via_spec *spec = codec->spec;
680 hda_nid_t nid;
681
682 /* 1st or 2nd S/PDIF */
683 if (substream->number == 0)
684 nid = spec->multiout.dig_out_nid;
685 else if (substream->number == 1)
686 nid = spec->extra_dig_out_nid;
687 else
688 return -1;
692 689
693 mutex_lock(&codec->spdif_mutex); 690 mutex_lock(&codec->spdif_mutex);
694 setup_dig_playback_stream(codec, spec->extra_dig_out_nid, stream_tag, 691 setup_dig_playback_stream(codec, nid, stream_tag, format);
695 format);
696 mutex_unlock(&codec->spdif_mutex); 692 mutex_unlock(&codec->spdif_mutex);
697 return 0; 693 return 0;
698} 694}
@@ -854,17 +850,6 @@ static int via_build_pcms(struct hda_codec *codec)
854 } 850 }
855 } 851 }
856 852
857 if (spec->extra_dig_out_nid) {
858 codec->num_pcms++;
859 info++;
860 info->name = spec->stream_name_digital;
861 info->pcm_type = HDA_PCM_TYPE_HDMI;
862 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
863 *(spec->stream_extra_digital_playback);
864 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
865 spec->extra_dig_out_nid;
866 }
867
868 return 0; 853 return 0;
869} 854}
870 855
@@ -957,6 +942,10 @@ static void via_unsol_event(struct hda_codec *codec,
957 via_gpio_control(codec); 942 via_gpio_control(codec);
958} 943}
959 944
945static hda_nid_t slave_dig_outs[] = {
946 0,
947};
948
960static int via_init(struct hda_codec *codec) 949static int via_init(struct hda_codec *codec)
961{ 950{
962 struct via_spec *spec = codec->spec; 951 struct via_spec *spec = codec->spec;
@@ -991,6 +980,9 @@ static int via_init(struct hda_codec *codec)
991 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, 980 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
992 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); 981 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
993 982
983 /* no slave outs */
984 codec->slave_dig_outs = slave_dig_outs;
985
994 return 0; 986 return 0;
995} 987}
996 988
@@ -2477,8 +2469,9 @@ static struct hda_verb vt1708S_volume_init_verbs[] = {
2477 2469
2478 /* Setup default input of PW4 to MW0 */ 2470 /* Setup default input of PW4 to MW0 */
2479 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, 2471 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2480 /* PW9 Output enable */ 2472 /* PW9, PW10 Output enable */
2481 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 2473 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2474 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2482 { } 2475 { }
2483}; 2476};
2484 2477
@@ -2511,7 +2504,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
2511}; 2504};
2512 2505
2513static struct hda_pcm_stream vt1708S_pcm_digital_playback = { 2506static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
2514 .substreams = 1, 2507 .substreams = 2,
2515 .channels_min = 2, 2508 .channels_min = 2,
2516 .channels_max = 2, 2509 .channels_max = 2,
2517 /* NID is set in via_build_pcms */ 2510 /* NID is set in via_build_pcms */
@@ -2522,16 +2515,6 @@ static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
2522 }, 2515 },
2523}; 2516};
2524 2517
2525static struct hda_pcm_stream vt1708S_pcm_extra_digital_playback = {
2526 .substreams = 1,
2527 .channels_min = 2,
2528 .channels_max = 2,
2529 /* NID is set in via_build_pcms */
2530 .ops = {
2531 .prepare = via_extra_dig_playback_pcm_prepare
2532 },
2533};
2534
2535/* fill in the dac_nids table from the parsed pin configuration */ 2518/* fill in the dac_nids table from the parsed pin configuration */
2536static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, 2519static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
2537 const struct auto_pin_cfg *cfg) 2520 const struct auto_pin_cfg *cfg)
@@ -2822,8 +2805,6 @@ static int patch_vt1708S(struct hda_codec *codec)
2822 2805
2823 spec->stream_name_digital = "VT1708S Digital"; 2806 spec->stream_name_digital = "VT1708S Digital";
2824 spec->stream_digital_playback = &vt1708S_pcm_digital_playback; 2807 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
2825 spec->stream_extra_digital_playback =
2826 &vt1708S_pcm_extra_digital_playback;
2827 2808
2828 if (!spec->adc_nids && spec->input_mux) { 2809 if (!spec->adc_nids && spec->input_mux) {
2829 spec->adc_nids = vt1708S_adc_nids; 2810 spec->adc_nids = vt1708S_adc_nids;
@@ -2927,7 +2908,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = {
2927}; 2908};
2928 2909
2929static struct hda_pcm_stream vt1702_pcm_digital_playback = { 2910static struct hda_pcm_stream vt1702_pcm_digital_playback = {
2930 .substreams = 1, 2911 .substreams = 2,
2931 .channels_min = 2, 2912 .channels_min = 2,
2932 .channels_max = 2, 2913 .channels_max = 2,
2933 /* NID is set in via_build_pcms */ 2914 /* NID is set in via_build_pcms */
@@ -2938,16 +2919,6 @@ static struct hda_pcm_stream vt1702_pcm_digital_playback = {
2938 }, 2919 },
2939}; 2920};
2940 2921
2941static struct hda_pcm_stream vt1702_pcm_extra_digital_playback = {
2942 .substreams = 1,
2943 .channels_min = 2,
2944 .channels_max = 2,
2945 /* NID is set in via_build_pcms */
2946 .ops = {
2947 .prepare = via_extra_dig_playback_pcm_prepare
2948 },
2949};
2950
2951/* fill in the dac_nids table from the parsed pin configuration */ 2922/* fill in the dac_nids table from the parsed pin configuration */
2952static int vt1702_auto_fill_dac_nids(struct via_spec *spec, 2923static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
2953 const struct auto_pin_cfg *cfg) 2924 const struct auto_pin_cfg *cfg)
@@ -3155,8 +3126,6 @@ static int patch_vt1702(struct hda_codec *codec)
3155 3126
3156 spec->stream_name_digital = "VT1702 Digital"; 3127 spec->stream_name_digital = "VT1702 Digital";
3157 spec->stream_digital_playback = &vt1702_pcm_digital_playback; 3128 spec->stream_digital_playback = &vt1702_pcm_digital_playback;
3158 spec->stream_extra_digital_playback =
3159 &vt1702_pcm_extra_digital_playback;
3160 3129
3161 if (!spec->adc_nids && spec->input_mux) { 3130 if (!spec->adc_nids && spec->input_mux) {
3162 spec->adc_nids = vt1702_adc_nids; 3131 spec->adc_nids = vt1702_adc_nids;