Skip to content

Commit 4846a67

Browse files
committed
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 <[email protected]>
1 parent 2c1c9b8 commit 4846a67

File tree

1 file changed

+50
-32
lines changed

1 file changed

+50
-32
lines changed

sound/pci/hda/patch_hdmi.c

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ struct hdmi_ops {
114114
int (*setup_stream)(struct hda_codec *codec, hda_nid_t cvt_nid,
115115
hda_nid_t pin_nid, u32 stream_tag, int format);
116116

117+
void (*pin_cvt_fixup)(struct hda_codec *codec,
118+
struct hdmi_spec_per_pin *per_pin,
119+
hda_nid_t cvt_nid);
117120
};
118121

119122
struct hdmi_pcm {
@@ -881,7 +884,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
881884
* of the pin.
882885
*/
883886
static 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)
885888
{
886889
struct hdmi_spec *spec = codec->spec;
887890
struct hdmi_spec_per_pin *per_pin;
@@ -922,8 +925,6 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
922925

923926
if (cvt_id)
924927
*cvt_id = cvt_idx;
925-
if (mux_id)
926-
*mux_id = mux_idx;
927928

928929
return 0;
929930
}
@@ -1016,9 +1017,6 @@ static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec,
10161017
int mux_idx;
10171018
struct hdmi_spec *spec = codec->spec;
10181019

1019-
if (!is_haswell_plus(codec) && !is_valleyview_plus(codec))
1020-
return;
1021-
10221020
/* On Intel platform, the mapping of converter nid to
10231021
* mux index of the pins are always the same.
10241022
* 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,
10291027
intel_not_share_assigned_cvt(codec, pin_nid, mux_idx);
10301028
}
10311029

1030+
/* skeleton caller of pin_cvt_fixup ops */
1031+
static 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+
10321041
/* called in hdmi_pcm_open when no pin is assigned to the PCM
10331042
* in dyn_pcm_assign mode.
10341043
*/
@@ -1046,15 +1055,15 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
10461055
if (pcm_idx < 0)
10471056
return -EINVAL;
10481057

1049-
err = hdmi_choose_cvt(codec, -1, &cvt_idx, NULL);
1058+
err = hdmi_choose_cvt(codec, -1, &cvt_idx);
10501059
if (err)
10511060
return err;
10521061

10531062
per_cvt = get_cvt(spec, cvt_idx);
10541063
per_cvt->assigned = 1;
10551064
hinfo->nid = per_cvt->cvt_nid;
10561065

1057-
intel_not_share_assigned_cvt_nid(codec, 0, per_cvt->cvt_nid);
1066+
pin_cvt_fixup(codec, NULL, per_cvt->cvt_nid);
10581067

10591068
set_bit(pcm_idx, &spec->pcm_in_use);
10601069
/* todo: setup spdif ctls assign */
@@ -1086,7 +1095,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
10861095
{
10871096
struct hdmi_spec *spec = codec->spec;
10881097
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;
10901099
struct hdmi_spec_per_pin *per_pin;
10911100
struct hdmi_eld *eld;
10921101
struct hdmi_spec_per_cvt *per_cvt = NULL;
@@ -1115,7 +1124,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
11151124
}
11161125
}
11171126

1118-
err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);
1127+
err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
11191128
if (err < 0) {
11201129
mutex_unlock(&spec->pcm_lock);
11211130
return err;
@@ -1132,11 +1141,10 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
11321141

11331142
snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
11341143
AC_VERB_SET_CONNECT_SEL,
1135-
mux_idx);
1144+
per_pin->mux_idx);
11361145

11371146
/* configure unused pins to choose other converters */
1138-
if (is_haswell_plus(codec) || is_valleyview_plus(codec))
1139-
intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);
1147+
pin_cvt_fixup(codec, per_pin, 0);
11401148

11411149
snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid);
11421150

@@ -1369,12 +1377,7 @@ static void update_eld(struct hda_codec *codec,
13691377
* and this can make HW reset converter selection on a pin.
13701378
*/
13711379
if (eld->eld_valid && !old_eld_valid && per_pin->setup) {
1372-
if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
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-
1380+
pin_cvt_fixup(codec, per_pin, 0);
13781381
hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
13791382
}
13801383

@@ -1709,7 +1712,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
17091712
* skip pin setup and return 0 to make audio playback
17101713
* be ongoing
17111714
*/
1712-
intel_not_share_assigned_cvt_nid(codec, 0, cvt_nid);
1715+
pin_cvt_fixup(codec, NULL, cvt_nid);
17131716
snd_hda_codec_setup_stream(codec, cvt_nid,
17141717
stream_tag, 0, format);
17151718
mutex_unlock(&spec->pcm_lock);
@@ -1722,18 +1725,16 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
17221725
}
17231726
per_pin = get_pin(spec, pin_idx);
17241727
pin_nid = per_pin->pin_nid;
1725-
if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
1726-
/* Verify pin:cvt selections to avoid silent audio after S3.
1727-
* After S3, the audio driver restores pin:cvt selections
1728-
* but this can happen before gfx is ready and such selection
1729-
* is overlooked by HW. Thus multiple pins can share a same
1730-
* default convertor and mute control will affect each other,
1731-
* which can cause a resumed audio playback become silent
1732-
* after S3.
1733-
*/
1734-
intel_verify_pin_cvt_connect(codec, per_pin);
1735-
intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx);
1736-
}
1728+
1729+
/* Verify pin:cvt selections to avoid silent audio after S3.
1730+
* After S3, the audio driver restores pin:cvt selections
1731+
* but this can happen before gfx is ready and such selection
1732+
* is overlooked by HW. Thus multiple pins can share a same
1733+
* default convertor and mute control will affect each other,
1734+
* which can cause a resumed audio playback become silent
1735+
* after S3.
1736+
*/
1737+
pin_cvt_fixup(codec, per_pin, 0);
17371738

17381739
/* Call sync_audio_rate to set the N/CTS/M manually if necessary */
17391740
/* 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,
23122313
return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
23132314
}
23142315

2316+
/* pin_cvt_fixup ops override for HSW+ and VLV+ */
2317+
static 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+
23152330
/* Intel Haswell and onwards; audio component with eld notifier */
23162331
static int patch_i915_hsw_hdmi(struct hda_codec *codec)
23172332
{
@@ -2344,6 +2359,7 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
23442359
codec->auto_runtime_pm = 1;
23452360

23462361
spec->ops.setup_stream = i915_hsw_setup_stream;
2362+
spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
23472363

23482364
err = hdmi_parse_codec(codec);
23492365
if (err < 0) {
@@ -2381,6 +2397,8 @@ static int patch_i915_byt_hdmi(struct hda_codec *codec)
23812397
codec->depop_delay = 0;
23822398
codec->auto_runtime_pm = 1;
23832399

2400+
spec->ops.pin_cvt_fixup = i915_pin_cvt_fixup;
2401+
23842402
err = hdmi_parse_codec(codec);
23852403
if (err < 0) {
23862404
generic_spec_free(codec);

0 commit comments

Comments
 (0)