diff options
author | Harald Welte <HaraldWelte@viatech.com> | 2008-09-15 10:42:26 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-09-23 02:18:13 -0400 |
commit | 5691ec7fc302ecffddfa21b19477aaaa4386d002 (patch) | |
tree | 652d20e798a9b0f97a779eee36966b32f5ceb747 /sound/pci | |
parent | f8fdd4958b6c7af9abf630f06d43db4ddcd532f6 (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')
-rw-r--r-- | sound/pci/hda/patch_via.c | 75 |
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 | ||
659 | static 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 */ |
671 | static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid, | 659 | static 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 | ||
685 | static int via_extra_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 673 | static 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 | ||
945 | static hda_nid_t slave_dig_outs[] = { | ||
946 | 0, | ||
947 | }; | ||
948 | |||
960 | static int via_init(struct hda_codec *codec) | 949 | static 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 | ||
2513 | static struct hda_pcm_stream vt1708S_pcm_digital_playback = { | 2506 | static 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 | ||
2525 | static 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 */ |
2536 | static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, | 2519 | static 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 | ||
2929 | static struct hda_pcm_stream vt1702_pcm_digital_playback = { | 2910 | static 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 | ||
2941 | static 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 */ |
2952 | static int vt1702_auto_fill_dac_nids(struct via_spec *spec, | 2923 | static 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; |