aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_hdmi.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 5361298be4d0..333d5338c15c 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -61,7 +61,6 @@ struct hdmi_spec_per_cvt {
61 u32 rates; 61 u32 rates;
62 u64 formats; 62 u64 formats;
63 unsigned int maxbps; 63 unsigned int maxbps;
64 bool non_pcm;
65}; 64};
66 65
67struct hdmi_spec_per_pin { 66struct hdmi_spec_per_pin {
@@ -73,6 +72,7 @@ struct hdmi_spec_per_pin {
73 struct hdmi_eld sink_eld; 72 struct hdmi_eld sink_eld;
74 struct delayed_work work; 73 struct delayed_work work;
75 int repoll_count; 74 int repoll_count;
75 bool non_pcm;
76}; 76};
77 77
78struct hdmi_spec { 78struct hdmi_spec {
@@ -550,7 +550,6 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
550 550
551static void hdmi_setup_channel_mapping(struct hda_codec *codec, 551static void hdmi_setup_channel_mapping(struct hda_codec *codec,
552 hda_nid_t pin_nid, 552 hda_nid_t pin_nid,
553 hda_nid_t cvt_nid,
554 bool non_pcm, 553 bool non_pcm,
555 int ca) 554 int ca)
556{ 555{
@@ -712,27 +711,16 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
712} 711}
713 712
714static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, 713static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
715 hda_nid_t cvt_nid, struct snd_pcm_substream *substream) 714 bool non_pcm,
715 struct snd_pcm_substream *substream)
716{ 716{
717 struct hdmi_spec *spec = codec->spec; 717 struct hdmi_spec *spec = codec->spec;
718 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 718 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
719 struct hdmi_spec_per_cvt *per_cvt;
720 struct hda_spdif_out *spdif;
721 hda_nid_t pin_nid = per_pin->pin_nid; 719 hda_nid_t pin_nid = per_pin->pin_nid;
722 int channels = substream->runtime->channels; 720 int channels = substream->runtime->channels;
723 struct hdmi_eld *eld; 721 struct hdmi_eld *eld;
724 int ca; 722 int ca;
725 int cvt_idx;
726 union audio_infoframe ai; 723 union audio_infoframe ai;
727 bool non_pcm = false;
728
729 cvt_idx = cvt_nid_to_cvt_index(spec, cvt_nid);
730 per_cvt = &spec->cvts[cvt_idx];
731
732 mutex_lock(&codec->spdif_mutex);
733 spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
734 non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
735 mutex_unlock(&codec->spdif_mutex);
736 724
737 eld = &spec->pins[pin_idx].sink_eld; 725 eld = &spec->pins[pin_idx].sink_eld;
738 if (!eld->monitor_present) 726 if (!eld->monitor_present)
@@ -775,7 +763,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
775 "pin=%d channels=%d\n", 763 "pin=%d channels=%d\n",
776 pin_nid, 764 pin_nid,
777 channels); 765 channels);
778 hdmi_setup_channel_mapping(codec, pin_nid, cvt_nid, non_pcm, ca); 766 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca);
779 hdmi_stop_infoframe_trans(codec, pin_nid); 767 hdmi_stop_infoframe_trans(codec, pin_nid);
780 hdmi_fill_audio_infoframe(codec, pin_nid, 768 hdmi_fill_audio_infoframe(codec, pin_nid,
781 ai.bytes, sizeof(ai)); 769 ai.bytes, sizeof(ai));
@@ -783,11 +771,11 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
783 } else { 771 } else {
784 /* For non-pcm audio switch, setup new channel mapping 772 /* For non-pcm audio switch, setup new channel mapping
785 * accordingly */ 773 * accordingly */
786 if (per_cvt->non_pcm != non_pcm) 774 if (per_pin->non_pcm != non_pcm)
787 hdmi_setup_channel_mapping(codec, pin_nid, cvt_nid, non_pcm, ca); 775 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca);
788 } 776 }
789 777
790 per_cvt->non_pcm = non_pcm; 778 per_pin->non_pcm = non_pcm;
791} 779}
792 780
793 781
@@ -1080,6 +1068,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1080 per_pin = &spec->pins[pin_idx]; 1068 per_pin = &spec->pins[pin_idx];
1081 1069
1082 per_pin->pin_nid = pin_nid; 1070 per_pin->pin_nid = pin_nid;
1071 per_pin->non_pcm = false;
1083 1072
1084 err = hdmi_read_pin_conn(codec, pin_idx); 1073 err = hdmi_read_pin_conn(codec, pin_idx);
1085 if (err < 0) 1074 if (err < 0)
@@ -1109,7 +1098,6 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1109 1098
1110 per_cvt->cvt_nid = cvt_nid; 1099 per_cvt->cvt_nid = cvt_nid;
1111 per_cvt->channels_min = 2; 1100 per_cvt->channels_min = 2;
1112 per_cvt->non_pcm = false;
1113 if (chans <= 16) 1101 if (chans <= 16)
1114 per_cvt->channels_max = chans; 1102 per_cvt->channels_max = chans;
1115 1103
@@ -1179,6 +1167,19 @@ static char *get_hdmi_pcm_name(int idx)
1179 return &names[idx][0]; 1167 return &names[idx][0];
1180} 1168}
1181 1169
1170static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1171{
1172 struct hda_spdif_out *spdif;
1173 bool non_pcm;
1174
1175 mutex_lock(&codec->spdif_mutex);
1176 spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
1177 non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
1178 mutex_unlock(&codec->spdif_mutex);
1179 return non_pcm;
1180}
1181
1182
1182/* 1183/*
1183 * HDMI callbacks 1184 * HDMI callbacks
1184 */ 1185 */
@@ -1194,10 +1195,13 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1194 int pin_idx = hinfo_to_pin_index(spec, hinfo); 1195 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1195 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; 1196 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
1196 int pinctl; 1197 int pinctl;
1198 bool non_pcm;
1199
1200 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1197 1201
1198 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); 1202 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1199 1203
1200 hdmi_setup_audio_infoframe(codec, pin_idx, cvt_nid, substream); 1204 hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
1201 1205
1202 pinctl = snd_hda_codec_read(codec, pin_nid, 0, 1206 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
1203 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 1207 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);