aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_hdmi.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-03-21 07:56:46 -0400
committerTakashi Iwai <tiwai@suse.de>2016-03-28 03:38:40 -0400
commit4846a67eb5a1d7cac76e1b22f66e88a8cbbdff3f (patch)
treef3bf49c5505ad27b375f13595dfc46271e0f0e66 /sound/pci/hda/patch_hdmi.c
parent2c1c9b86c6b22dc0cbac3f4ca2c8272c472dc463 (diff)
ALSA: hda - Introduce pin_cvt_fixup() ops to hdmi parser
For reducing the splat of is_haswell_plus() or such macros, this patch introduces pin_cvt_fixup() ops to hdmi_spec. For HSW+ and VLV+ codecs, set this ops so that the driver can call the Intel-specific workarounds appropriately. A gratis bonus that we can remove the mux_id argument from hdmi_choose_cvt(), too, since the fixup function always refers the mux_idx from the given per_pin object. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r--sound/pci/hda/patch_hdmi.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 985518891b99..3481b43476dc 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -114,6 +114,9 @@ struct hdmi_ops {
114 int (*setup_stream)(struct hda_codec *codec, hda_nid_t cvt_nid, 114 int (*setup_stream)(struct hda_codec *codec, hda_nid_t cvt_nid,
115 hda_nid_t pin_nid, u32 stream_tag, int format); 115 hda_nid_t pin_nid, u32 stream_tag, int format);
116 116
117 void (*pin_cvt_fixup)(struct hda_codec *codec,
118 struct hdmi_spec_per_pin *per_pin,
119 hda_nid_t cvt_nid);
117}; 120};
118 121
119struct hdmi_pcm { 122struct hdmi_pcm {
@@ -881,7 +884,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
881 * of the pin. 884 * of the pin.
882 */ 885 */
883static int hdmi_choose_cvt(struct hda_codec *codec, 886static int hdmi_choose_cvt(struct hda_codec *codec,
884 int pin_idx, int *cvt_id, int *mux_id) 887 int pin_idx, int *cvt_id)
885{ 888{
886 struct hdmi_spec *spec = codec->spec; 889 struct hdmi_spec *spec = codec->spec;
887 struct hdmi_spec_per_pin *per_pin; 890 struct hdmi_spec_per_pin *per_pin;
@@ -922,8 +925,6 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
922 925
923 if (cvt_id) 926 if (cvt_id)
924 *cvt_id = cvt_idx; 927 *cvt_id = cvt_idx;
925 if (mux_id)
926 *mux_id = mux_idx;
927 928
928 return 0; 929 return 0;
929} 930}
@@ -1016,9 +1017,6 @@ static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec,
1016 int mux_idx; 1017 int mux_idx;
1017 struct hdmi_spec *spec = codec->spec; 1018 struct hdmi_spec *spec = codec->spec;
1018 1019
1019 if (!is_haswell_plus(codec) && !is_valleyview_plus(codec))
1020 return;
1021
1022 /* On Intel platform, the mapping of converter nid to 1020 /* On Intel platform, the mapping of converter nid to
1023 * mux index of the pins are always the same. 1021 * mux index of the pins are always the same.
1024 * The pin nid may be 0, this means all pins will not 1022 * The pin nid may be 0, this means all pins will not
@@ -1029,6 +1027,17 @@ static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec,
1029 intel_not_share_assigned_cvt(codec, pin_nid, mux_idx); 1027 intel_not_share_assigned_cvt(codec, pin_nid, mux_idx);
1030} 1028}
1031 1029
1030/* skeleton caller of pin_cvt_fixup ops */
1031static void pin_cvt_fixup(struct hda_codec *codec,
1032 struct hdmi_spec_per_pin *per_pin,
1033 hda_nid_t cvt_nid)
1034{
1035 struct hdmi_spec *spec = codec->spec;
1036
1037 if (spec->ops.pin_cvt_fixup)
1038 spec->ops.pin_cvt_fixup(codec, per_pin, cvt_nid);
1039}
1040
1032/* called in hdmi_pcm_open when no pin is assigned to the PCM 1041/* called in hdmi_pcm_open when no pin is assigned to the PCM
1033 * in dyn_pcm_assign mode. 1042 * in dyn_pcm_assign mode.
1034 */ 1043 */
@@ -1046,7 +1055,7 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
1046 if (pcm_idx < 0) 1055 if (pcm_idx < 0)
1047 return -EINVAL; 1056 return -EINVAL;
1048 1057
1049 err = hdmi_choose_cvt(codec, -1, &cvt_idx, NULL); 1058 err = hdmi_choose_cvt(codec, -1, &cvt_idx);
1050 if (err) 1059 if (err)
1051 return err; 1060 return err;
1052 1061
@@ -1054,7 +1063,7 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
1054 per_cvt->assigned = 1; 1063 per_cvt->assigned = 1;
1055 hinfo->nid = per_cvt->cvt_nid; 1064 hinfo->nid = per_cvt->cvt_nid;
1056 1065
1057 intel_not_share_assigned_cvt_nid(codec, 0, per_cvt->cvt_nid); 1066 pin_cvt_fixup(codec, NULL, per_cvt->cvt_nid);
1058 1067
1059 set_bit(pcm_idx, &spec->pcm_in_use); 1068 set_bit(pcm_idx, &spec->pcm_in_use);
1060 /* todo: setup spdif ctls assign */ 1069 /* todo: setup spdif ctls assign */
@@ -1086,7 +1095,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1086{ 1095{
1087 struct hdmi_spec *spec = codec->spec; 1096 struct hdmi_spec *spec = codec->spec;
1088 struct snd_pcm_runtime *runtime = substream->runtime; 1097 struct snd_pcm_runtime *runtime = substream->runtime;
1089 int pin_idx, cvt_idx, pcm_idx, mux_idx = 0; 1098 int pin_idx, cvt_idx, pcm_idx;
1090 struct hdmi_spec_per_pin *per_pin; 1099 struct hdmi_spec_per_pin *per_pin;
1091 struct hdmi_eld *eld; 1100 struct hdmi_eld *eld;
1092 struct hdmi_spec_per_cvt *per_cvt = NULL; 1101 struct hdmi_spec_per_cvt *per_cvt = NULL;
@@ -1115,7 +1124,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1115 } 1124 }
1116 } 1125 }
1117 1126
1118 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx); 1127 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
1119 if (err < 0) { 1128 if (err < 0) {
1120 mutex_unlock(&spec->pcm_lock); 1129 mutex_unlock(&spec->pcm_lock);
1121 return err; 1130 return err;
@@ -1132,11 +1141,10 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1132 1141
1133 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, 1142 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
1134 AC_VERB_SET_CONNECT_SEL, 1143 AC_VERB_SET_CONNECT_SEL,
1135 mux_idx); 1144 per_pin->mux_idx);
1136 1145
1137 /* configure unused pins to choose other converters */ 1146 /* configure unused pins to choose other converters */
1138 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) 1147 pin_cvt_fixup(codec, per_pin, 0);
1139 intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);
1140 1148
1141 snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid); 1149 snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid);
1142 1150
@@ -1369,12 +1377,7 @@ static void update_eld(struct hda_codec *codec,
1369 * and this can make HW reset converter selection on a pin. 1377 * and this can make HW reset converter selection on a pin.
1370 */ 1378 */
1371 if (eld->eld_valid && !old_eld_valid && per_pin->setup) { 1379 if (eld->eld_valid && !old_eld_valid && per_pin->setup) {
1372 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { 1380 pin_cvt_fixup(codec, per_pin, 0);
1373 intel_verify_pin_cvt_connect(codec, per_pin);
1374 intel_not_share_assigned_cvt(codec, per_pin->pin_nid,
1375 per_pin->mux_idx);
1376 }
1377
1378 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); 1381 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1379 } 1382 }
1380 1383
@@ -1709,7 +1712,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1709 * skip pin setup and return 0 to make audio playback 1712 * skip pin setup and return 0 to make audio playback
1710 * be ongoing 1713 * be ongoing
1711 */ 1714 */
1712 intel_not_share_assigned_cvt_nid(codec, 0, cvt_nid); 1715 pin_cvt_fixup(codec, NULL, cvt_nid);
1713 snd_hda_codec_setup_stream(codec, cvt_nid, 1716 snd_hda_codec_setup_stream(codec, cvt_nid,
1714 stream_tag, 0, format); 1717 stream_tag, 0, format);
1715 mutex_unlock(&spec->pcm_lock); 1718 mutex_unlock(&spec->pcm_lock);
@@ -1722,18 +1725,16 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1722 } 1725 }
1723 per_pin = get_pin(spec, pin_idx); 1726 per_pin = get_pin(spec, pin_idx);
1724 pin_nid = per_pin->pin_nid; 1727 pin_nid = per_pin->pin_nid;
1725 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { 1728
1726 /* Verify pin:cvt selections to avoid silent audio after S3. 1729 /* Verify pin:cvt selections to avoid silent audio after S3.
1727 * After S3, the audio driver restores pin:cvt selections 1730 * After S3, the audio driver restores pin:cvt selections
1728 * but this can happen before gfx is ready and such selection 1731 * but this can happen before gfx is ready and such selection
1729 * is overlooked by HW. Thus multiple pins can share a same 1732 * is overlooked by HW. Thus multiple pins can share a same
1730 * default convertor and mute control will affect each other, 1733 * default convertor and mute control will affect each other,
1731 * which can cause a resumed audio playback become silent 1734 * which can cause a resumed audio playback become silent
1732 * after S3. 1735 * after S3.
1733 */ 1736 */
1734 intel_verify_pin_cvt_connect(codec, per_pin); 1737 pin_cvt_fixup(codec, per_pin, 0);
1735 intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx);
1736 }
1737 1738
1738 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */ 1739 /* Call sync_audio_rate to set the N/CTS/M manually if necessary */
1739 /* Todo: add DP1.2 MST audio support later */ 1740 /* Todo: add DP1.2 MST audio support later */
@@ -2312,6 +2313,20 @@ static int i915_hsw_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
2312 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); 2313 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
2313} 2314}
2314 2315
2316/* pin_cvt_fixup ops override for HSW+ and VLV+ */
2317static void i915_pin_cvt_fixup(struct hda_codec *codec,
2318 struct hdmi_spec_per_pin *per_pin,
2319 hda_nid_t cvt_nid)
2320{
2321 if (per_pin) {
2322 intel_verify_pin_cvt_connect(codec, per_pin);
2323 intel_not_share_assigned_cvt(codec, per_pin->pin_nid,
2324 per_pin->mux_idx);
2325 } else {
2326 intel_not_share_assigned_cvt_nid(codec, 0, cvt_nid);
2327 }
2328}
2329
2315/* Intel Haswell and onwards; audio component with eld notifier */ 2330/* Intel Haswell and onwards; audio component with eld notifier */
2316static int patch_i915_hsw_hdmi(struct hda_codec *codec) 2331static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2317{ 2332{
@@ -2344,6 +2359,7 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2344 codec->auto_runtime_pm = 1; 2359 codec->auto_runtime_pm = 1;
2345 2360
2346 spec->ops.setup_stream = i915_hsw_setup_stream; 2361 spec->ops.setup_stream = i915_hsw_setup_stream;
2362 spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
2347 2363
2348 err = hdmi_parse_codec(codec); 2364 err = hdmi_parse_codec(codec);
2349 if (err < 0) { 2365 if (err < 0) {
@@ -2381,6 +2397,8 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec)
2381 codec->depop_delay = 0; 2397 codec->depop_delay = 0;
2382 codec->auto_runtime_pm = 1; 2398 codec->auto_runtime_pm = 1;
2383 2399
2400 spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
2401
2384 err = hdmi_parse_codec(codec); 2402 err = hdmi_parse_codec(codec);
2385 if (err < 0) { 2403 if (err < 0) {
2386 generic_spec_free(codec); 2404 generic_spec_free(codec);