/* Haswell needs to re-issue the vendor-specific verbs before turning to D0. *Otherwiseyoumaygetsevereh/wcommunicationerrors.
*/ staticvoid haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg, unsignedint power_state)
{ /* check codec->spec: it can be called before the probe gets called */ if (codec->spec) { if (power_state == AC_PWRST_D0) {
intel_haswell_enable_all_pins(codec, false);
intel_haswell_fixup_enable_dp12(codec);
}
}
/* *lookingforthepinnumberinthemappingtableandreturn *theindexwhichindicatetheportnumber
*/ for (i = 0; i < spec->port_num; i++) { if (pin_nid == spec->port_map[i]) return i;
}
codec_info(codec, "Can't find the HDMI/DP port for pin NID 0x%x\n", pin_nid); return -1;
}
if (!spec->port_num) { /* we assume only from port-B to port-D */ if (port < 1 || port > 3) return0; return port + intel_base_nid(codec) - 1;
}
if (port < 0 || port >= spec->port_num) return0; return spec->port_map[port];
}
staticvoid intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
{ struct hda_codec *codec = audio_ptr; int pin_nid; int dev_id = pipe;
pin_nid = intel_port2pin(codec, port); if (!pin_nid) return; /* skip notification during system suspend (but not in runtime PM); *thestatewillbeupdatedatresume
*/ if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) return;
spec->use_acomp_notifier = true;
spec->port2pin = intel_port2pin;
snd_hda_hdmi_setup_drm_audio_ops(codec, &intel_audio_ops);
snd_hdac_acomp_register_notifier(&codec->bus->core,
&spec->drm_audio_ops); /* no need for forcible resume for jack check thanks to notifier */
codec->relaxed_resume = 1;
}
/* For Haswell, the converter 1/2 may keep in D3 state after bootup, *thuspinscouldonlychooseconverter0foruse.Makesurethe *convertersareincorrectpowerstate
*/ if (!snd_hda_check_power_state(codec, cvt_nid, AC_PWRST_D0))
snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D0)) {
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
AC_PWRST_D0);
msleep(40);
pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0);
pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT;
codec_dbg(codec, "Haswell HDMI audio: Power for NID 0x%x is now D%d\n", nid, pwr);
}
}
/* Assure the pin select the right convetor */ staticvoid intel_verify_pin_cvt_connect(struct hda_codec *codec, struct hdmi_spec_per_pin *per_pin)
{
hda_nid_t pin_nid = per_pin->pin_nid; int mux_idx, curr;
/* get the mux index for the converter of the pins *converter'smuxindexisthesameforallpinsonIntelplatform
*/ staticint intel_cvt_id_to_mux_idx(struct hdmi_spec *spec,
hda_nid_t cvt_nid)
{ int i;
for (i = 0; i < spec->num_cvts; i++) if (spec->cvt_nids[i] == cvt_nid) return i; return -EINVAL;
}
/* Intel HDMI workaround to fix audio routing issue: *ForsomeInteldisplaycodecs,pinssharethesameconnectionlist. *Soaconvetercanbeselectedbymultiplepinsandplaybackonanyofthese *pinswillgeneratesoundontheexternaldisplay,becauseaudioflowsfrom *thesameconvertertothedisplaypipeline.Alsomutingonepinmaymake *otherpinshavenosoundoutput. *Sothisfunctionassuresthatanassignedconverterforapinisnotselected *byanyotherpins.
*/ staticvoid intel_not_share_assigned_cvt(struct hda_codec *codec,
hda_nid_t pin_nid, int dev_id, int mux_idx)
{ struct hdmi_spec *spec = codec->spec;
hda_nid_t nid; int cvt_idx, curr; struct hdmi_spec_per_cvt *per_cvt; struct hdmi_spec_per_pin *per_pin; int pin_idx;
/* configure the pins connections */ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { int dev_id_saved; int dev_num;
/* choose an unassigned converter. The conveters in the *connectionlistareinthesameorderasinthecodec.
*/ for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
per_cvt = get_cvt(spec, cvt_idx); if (!per_cvt->assigned) {
codec_dbg(codec, "choose cvt %d for pin NID 0x%x\n",
cvt_idx, nid);
snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_CONNECT_SEL,
cvt_idx); break;
}
}
snd_hda_set_dev_select(codec, nid, dev_id_saved);
}
}
/* A wrapper of intel_not_share_asigned_cvt() */ staticvoid intel_not_share_assigned_cvt_nid(struct hda_codec *codec,
hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid)
{ int mux_idx; struct hdmi_spec *spec = codec->spec;
/* On Intel platform, the mapping of converter nid to *muxindexofthepinsarealwaysthesame. *Thepinnidmaybe0,thismeansallpinswillnot *sharetheconverter.
*/
mux_idx = intel_cvt_id_to_mux_idx(spec, cvt_nid); if (mux_idx >= 0)
intel_not_share_assigned_cvt(codec, pin_nid, dev_id, mux_idx);
}
/* setup_stream ops override for HSW+ */ staticint i915_hsw_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
hda_nid_t pin_nid, int dev_id, u32 stream_tag, int format)
{ struct hdmi_spec *spec = codec->spec; int pin_idx = pin_id_to_pin_index(codec, pin_nid, dev_id); struct hdmi_spec_per_pin *per_pin; int res;
staticint probe_i915_adlp_hdmi(struct hda_codec *codec)
{ struct hdmi_spec *spec; int res;
res = probe_i915_tgl_hdmi(codec); if (!res) {
spec = codec->spec;
if (spec->silent_stream_type)
spec->silent_stream_type = SILENT_STREAM_KAE;
}
return res;
}
/* Intel Baytrail and Braswell; with eld notifier */ staticint probe_i915_byt_hdmi(struct hda_codec *codec)
{ struct hdmi_spec *spec;
spec = codec->spec;
/* For Valleyview/Cherryview, only the display codec is in the display *powerwellandcanuselink_poweropstorequest/releasethepower.
*/
codec->display_power_control = 1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.