···11+To support DP MST audio, HD Audio hdmi codec driver introduces virtual pin22+and dynamic pcm assignment.33+44+Virtual pin is an extension of per_pin. The most difference of DP MST55+from legacy is that DP MST introduces device entry. Each pin can contain66+several device entries. Each device entry behaves as a pin.77+88+As each pin may contain several device entries and each codec may contain99+several pins, if we use one pcm per per_pin, there will be many PCMs.1010+The new solution is to create a few PCMs and to dynamically bind pcm to1111+per_pin. Driver uses spec->dyn_pcm_assign flag to indicate whether to use1212+the new solution.1313+1414+PCM1515+===1616+To be added1717+1818+1919+Jack2020+====2121+2222+Presume:2323+ - MST must be dyn_pcm_assign, and it is acomp (for Intel scenario);2424+ - NON-MST may or may not be dyn_pcm_assign, it can be acomp or !acomp;2525+2626+So there are the following scenarios:2727+ a. MST (&& dyn_pcm_assign && acomp)2828+ b. NON-MST && dyn_pcm_assign && acomp2929+ c. NON-MST && !dyn_pcm_assign && !acomp3030+3131+Below discussion will ignore MST and NON-MST difference as it doesn't3232+impact on jack handling too much.3333+3434+Driver uses struct hdmi_pcm pcm[] array in hdmi_spec and snd_jack is3535+a member of hdmi_pcm. Each pin has one struct hdmi_pcm * pcm pointer.3636+3737+For !dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n] statically.3838+3939+For dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n]4040+when monitor is hotplugged.4141+4242+4343+Build Jack4444+----------4545+4646+- dyn_pcm_assign4747+Will not use hda_jack but use snd_jack in spec->pcm_rec[pcm_idx].jack directly.4848+4949+- !dyn_pcm_assign5050+Use hda_jack and assign spec->pcm_rec[pcm_idx].jack = jack->jack statically.5151+5252+5353+Unsolicited Event Enabling5454+--------------------------5555+Enable unsolicited event if !acomp.5656+5757+5858+Monitor Hotplug Event Handling5959+------------------------------6060+- acomp6161+pin_eld_notify() -> check_presence_and_report() -> hdmi_present_sense() ->6262+sync_eld_via_acomp().6363+Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for6464+both dyn_pcm_assign and !dyn_pcm_assign6565+6666+- !acomp6767+Hdmi_unsol_event() -> hdmi_intrinsic_event() -> check_presence_and_report() ->6868+hdmi_present_sense() -> hdmi_prepsent_sense_via_verbs()6969+Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for dyn_pcm_assign.7070+Use hda_jack mechanism to handle jack events.7171+7272+7373+Others to be added later7474+========================
+489-73
sound/pci/hda/patch_hdmi.c
···75757676struct hdmi_spec_per_pin {7777 hda_nid_t pin_nid;7878+ /* pin idx, different device entries on the same pin use the same idx */7979+ int pin_nid_idx;7880 int num_mux_nids;7981 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];8082 int mux_idx;···8785 struct mutex lock;8886 struct delayed_work work;8987 struct snd_kcontrol *eld_ctl;9090- struct snd_jack *acomp_jack; /* jack via audio component */8888+ struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/8989+ int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */9190 int repoll_count;9291 bool setup; /* the stream has been set up by prepare callback */9392 int channels; /* current number of channels */···133130 int (*chmap_validate)(int ca, int channels, unsigned char *chmap);134131};135132133133+struct hdmi_pcm {134134+ struct hda_pcm *pcm;135135+ struct snd_jack *jack;136136+};137137+136138struct hdmi_spec {137139 int num_cvts;138140 struct snd_array cvts; /* struct hdmi_spec_per_cvt */···145137146138 int num_pins;147139 struct snd_array pins; /* struct hdmi_spec_per_pin */148148- struct hda_pcm *pcm_rec[16];140140+ struct hdmi_pcm pcm_rec[16];141141+ struct mutex pcm_lock;142142+ /* pcm_bitmap means which pcms have been assigned to pins*/143143+ unsigned long pcm_bitmap;144144+ int pcm_used; /* counter of pcm_rec[] */145145+ /* bitmap shows whether the pcm is opened in user space146146+ * bit 0 means the first playback PCM (PCM3);147147+ * bit 1 means the second playback PCM, and so on.148148+ */149149+ unsigned long pcm_in_use;149150 unsigned int channels_max; /* max over all cvts */150151151152 struct hdmi_eld temp_eld;152153 struct hdmi_ops ops;153154154155 bool dyn_pin_out;155155-156156+ bool dyn_pcm_assign;156157 /*157158 * Non-generic VIA/NVIDIA specific158159 */···387370 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))388371#define get_cvt(spec, idx) \389372 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))390390-#define get_pcm_rec(spec, idx) ((spec)->pcm_rec[idx])373373+/* obtain hdmi_pcm object assigned to idx */374374+#define get_hdmi_pcm(spec, idx) (&(spec)->pcm_rec[idx])375375+/* obtain hda_pcm object assigned to idx */376376+#define get_pcm_rec(spec, idx) (get_hdmi_pcm(spec, idx)->pcm)391377392378static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid)393379{···405385 return -EINVAL;406386}407387388388+static int hinfo_to_pcm_index(struct hda_codec *codec,389389+ struct hda_pcm_stream *hinfo)390390+{391391+ struct hdmi_spec *spec = codec->spec;392392+ int pcm_idx;393393+394394+ for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++)395395+ if (get_pcm_rec(spec, pcm_idx)->stream == hinfo)396396+ return pcm_idx;397397+398398+ codec_warn(codec, "HDMI: hinfo %p not registered\n", hinfo);399399+ return -EINVAL;400400+}401401+408402static int hinfo_to_pin_index(struct hda_codec *codec,409403 struct hda_pcm_stream *hinfo)410404{411405 struct hdmi_spec *spec = codec->spec;406406+ struct hdmi_spec_per_pin *per_pin;412407 int pin_idx;413408414414- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)415415- if (get_pcm_rec(spec, pin_idx)->stream == hinfo)409409+ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {410410+ per_pin = get_pin(spec, pin_idx);411411+ if (per_pin->pcm &&412412+ per_pin->pcm->pcm->stream == hinfo)416413 return pin_idx;414414+ }417415418418- codec_warn(codec, "HDMI: hinfo %p not registered\n", hinfo);416416+ codec_dbg(codec, "HDMI: hinfo %p not registered\n", hinfo);419417 return -EINVAL;418418+}419419+420420+static struct hdmi_spec_per_pin *pcm_idx_to_pin(struct hdmi_spec *spec,421421+ int pcm_idx)422422+{423423+ int i;424424+ struct hdmi_spec_per_pin *per_pin;425425+426426+ for (i = 0; i < spec->num_pins; i++) {427427+ per_pin = get_pin(spec, i);428428+ if (per_pin->pcm_idx == pcm_idx)429429+ return per_pin;430430+ }431431+ return NULL;420432}421433422434static int cvt_nid_to_cvt_index(struct hda_codec *codec, hda_nid_t cvt_nid)···13901338 return 0;13911339}1392134013411341+/* Try to find an available converter13421342+ * If pin_idx is less then zero, just try to find an available converter.13431343+ * Otherwise, try to find an available converter and get the cvt mux index13441344+ * of the pin.13451345+ */13931346static int hdmi_choose_cvt(struct hda_codec *codec,13941347 int pin_idx, int *cvt_id, int *mux_id)13951348{···14031346 struct hdmi_spec_per_cvt *per_cvt = NULL;14041347 int cvt_idx, mux_idx = 0;1405134814061406- per_pin = get_pin(spec, pin_idx);13491349+ /* pin_idx < 0 means no pin will be bound to the converter */13501350+ if (pin_idx < 0)13511351+ per_pin = NULL;13521352+ else13531353+ per_pin = get_pin(spec, pin_idx);1407135414081355 /* Dynamically assign converter to stream */14091356 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {···14161355 /* Must not already be assigned */14171356 if (per_cvt->assigned)14181357 continue;13581358+ if (per_pin == NULL)13591359+ break;14191360 /* Must be in pin's mux's list of converters */14201361 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)14211362 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)···1430136714311368 /* No free converters */14321369 if (cvt_idx == spec->num_cvts)14331433- return -ENODEV;13701370+ return -EBUSY;1434137114351435- per_pin->mux_idx = mux_idx;13721372+ if (per_pin != NULL)13731373+ per_pin->mux_idx = mux_idx;1436137414371375 if (cvt_id)14381376 *cvt_id = cvt_idx;···14571393 snd_hda_codec_write_cache(codec, pin_nid, 0,14581394 AC_VERB_SET_CONNECT_SEL,14591395 mux_idx);13961396+}13971397+13981398+/* get the mux index for the converter of the pins13991399+ * converter's mux index is the same for all pins on Intel platform14001400+ */14011401+static int intel_cvt_id_to_mux_idx(struct hdmi_spec *spec,14021402+ hda_nid_t cvt_nid)14031403+{14041404+ int i;14051405+14061406+ for (i = 0; i < spec->num_cvts; i++)14071407+ if (spec->cvt_nids[i] == cvt_nid)14081408+ return i;14091409+ return -EINVAL;14601410}1461141114621412/* Intel HDMI workaround to fix audio routing issue:···15241446 }15251447}1526144814491449+/* A wrapper of intel_not_share_asigned_cvt() */14501450+static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec,14511451+ hda_nid_t pin_nid, hda_nid_t cvt_nid)14521452+{14531453+ int mux_idx;14541454+ struct hdmi_spec *spec = codec->spec;14551455+14561456+ if (!is_haswell_plus(codec) && !is_valleyview_plus(codec))14571457+ return;14581458+14591459+ /* On Intel platform, the mapping of converter nid to14601460+ * mux index of the pins are always the same.14611461+ * The pin nid may be 0, this means all pins will not14621462+ * share the converter.14631463+ */14641464+ mux_idx = intel_cvt_id_to_mux_idx(spec, cvt_nid);14651465+ if (mux_idx >= 0)14661466+ intel_not_share_assigned_cvt(codec, pin_nid, mux_idx);14671467+}14681468+14691469+/* called in hdmi_pcm_open when no pin is assigned to the PCM14701470+ * in dyn_pcm_assign mode.14711471+ */14721472+static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,14731473+ struct hda_codec *codec,14741474+ struct snd_pcm_substream *substream)14751475+{14761476+ struct hdmi_spec *spec = codec->spec;14771477+ struct snd_pcm_runtime *runtime = substream->runtime;14781478+ int cvt_idx, pcm_idx;14791479+ struct hdmi_spec_per_cvt *per_cvt = NULL;14801480+ int err;14811481+14821482+ pcm_idx = hinfo_to_pcm_index(codec, hinfo);14831483+ if (pcm_idx < 0)14841484+ return -EINVAL;14851485+14861486+ err = hdmi_choose_cvt(codec, -1, &cvt_idx, NULL);14871487+ if (err)14881488+ return err;14891489+14901490+ per_cvt = get_cvt(spec, cvt_idx);14911491+ per_cvt->assigned = 1;14921492+ hinfo->nid = per_cvt->cvt_nid;14931493+14941494+ intel_not_share_assigned_cvt_nid(codec, 0, per_cvt->cvt_nid);14951495+14961496+ set_bit(pcm_idx, &spec->pcm_in_use);14971497+ /* todo: setup spdif ctls assign */14981498+14991499+ /* Initially set the converter's capabilities */15001500+ hinfo->channels_min = per_cvt->channels_min;15011501+ hinfo->channels_max = per_cvt->channels_max;15021502+ hinfo->rates = per_cvt->rates;15031503+ hinfo->formats = per_cvt->formats;15041504+ hinfo->maxbps = per_cvt->maxbps;15051505+15061506+ /* Store the updated parameters */15071507+ runtime->hw.channels_min = hinfo->channels_min;15081508+ runtime->hw.channels_max = hinfo->channels_max;15091509+ runtime->hw.formats = hinfo->formats;15101510+ runtime->hw.rates = hinfo->rates;15111511+15121512+ snd_pcm_hw_constraint_step(substream->runtime, 0,15131513+ SNDRV_PCM_HW_PARAM_CHANNELS, 2);15141514+ return 0;15151515+}15161516+15271517/*15281518 * HDA PCM callbacks15291519 */···16011455{16021456 struct hdmi_spec *spec = codec->spec;16031457 struct snd_pcm_runtime *runtime = substream->runtime;16041604- int pin_idx, cvt_idx, mux_idx = 0;14581458+ int pin_idx, cvt_idx, pcm_idx, mux_idx = 0;16051459 struct hdmi_spec_per_pin *per_pin;16061460 struct hdmi_eld *eld;16071461 struct hdmi_spec_per_cvt *per_cvt = NULL;16081462 int err;1609146316101464 /* Validate hinfo */16111611- pin_idx = hinfo_to_pin_index(codec, hinfo);16121612- if (snd_BUG_ON(pin_idx < 0))14651465+ pcm_idx = hinfo_to_pcm_index(codec, hinfo);14661466+ if (pcm_idx < 0)16131467 return -EINVAL;16141614- per_pin = get_pin(spec, pin_idx);16151615- eld = &per_pin->sink_eld;14681468+14691469+ mutex_lock(&spec->pcm_lock);14701470+ pin_idx = hinfo_to_pin_index(codec, hinfo);14711471+ if (!spec->dyn_pcm_assign) {14721472+ if (snd_BUG_ON(pin_idx < 0)) {14731473+ mutex_unlock(&spec->pcm_lock);14741474+ return -EINVAL;14751475+ }14761476+ } else {14771477+ /* no pin is assigned to the PCM14781478+ * PA need pcm open successfully when probe14791479+ */14801480+ if (pin_idx < 0) {14811481+ err = hdmi_pcm_open_no_pin(hinfo, codec, substream);14821482+ mutex_unlock(&spec->pcm_lock);14831483+ return err;14841484+ }14851485+ }1616148616171487 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);16181618- if (err < 0)14881488+ if (err < 0) {14891489+ mutex_unlock(&spec->pcm_lock);16191490 return err;14911491+ }1620149216211493 per_cvt = get_cvt(spec, cvt_idx);16221494 /* Claim converter */16231495 per_cvt->assigned = 1;14961496+14971497+ set_bit(pcm_idx, &spec->pcm_in_use);14981498+ per_pin = get_pin(spec, pin_idx);16241499 per_pin->cvt_nid = per_cvt->cvt_nid;16251500 hinfo->nid = per_cvt->cvt_nid;16261501···16531486 if (is_haswell_plus(codec) || is_valleyview_plus(codec))16541487 intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);1655148816561656- snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);14891489+ snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid);1657149016581491 /* Initially set the converter's capabilities */16591492 hinfo->channels_min = per_cvt->channels_min;···16621495 hinfo->formats = per_cvt->formats;16631496 hinfo->maxbps = per_cvt->maxbps;1664149714981498+ eld = &per_pin->sink_eld;16651499 /* Restrict capabilities by ELD if this isn't disabled */16661500 if (!static_hdmi_pcm && eld->eld_valid) {16671501 snd_hdmi_eld_update_pcm_info(&eld->info, hinfo);···16701502 !hinfo->rates || !hinfo->formats) {16711503 per_cvt->assigned = 0;16721504 hinfo->nid = 0;16731673- snd_hda_spdif_ctls_unassign(codec, pin_idx);15051505+ snd_hda_spdif_ctls_unassign(codec, pcm_idx);15061506+ mutex_unlock(&spec->pcm_lock);16741507 return -ENODEV;16751508 }16761509 }1677151015111511+ mutex_unlock(&spec->pcm_lock);16781512 /* Store the updated parameters */16791513 runtime->hw.channels_min = hinfo->channels_min;16801514 runtime->hw.channels_max = hinfo->channels_max;···17111541 return 0;17121542}1713154315441544+static int hdmi_find_pcm_slot(struct hdmi_spec *spec,15451545+ struct hdmi_spec_per_pin *per_pin)15461546+{15471547+ int i;15481548+15491549+ /* try the prefer PCM */15501550+ if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))15511551+ return per_pin->pin_nid_idx;15521552+15531553+ /* have a second try; check the "reserved area" over num_pins */15541554+ for (i = spec->num_pins; i < spec->pcm_used; i++) {15551555+ if (!test_bit(i, &spec->pcm_bitmap))15561556+ return i;15571557+ }15581558+15591559+ /* the last try; check the empty slots in pins */15601560+ for (i = 0; i < spec->num_pins; i++) {15611561+ if (!test_bit(i, &spec->pcm_bitmap))15621562+ return i;15631563+ }15641564+ return -EBUSY;15651565+}15661566+15671567+static void hdmi_attach_hda_pcm(struct hdmi_spec *spec,15681568+ struct hdmi_spec_per_pin *per_pin)15691569+{15701570+ int idx;15711571+15721572+ /* pcm already be attached to the pin */15731573+ if (per_pin->pcm)15741574+ return;15751575+ idx = hdmi_find_pcm_slot(spec, per_pin);15761576+ if (idx == -ENODEV)15771577+ return;15781578+ per_pin->pcm_idx = idx;15791579+ per_pin->pcm = get_hdmi_pcm(spec, idx);15801580+ set_bit(idx, &spec->pcm_bitmap);15811581+}15821582+15831583+static void hdmi_detach_hda_pcm(struct hdmi_spec *spec,15841584+ struct hdmi_spec_per_pin *per_pin)15851585+{15861586+ int idx;15871587+15881588+ /* pcm already be detached from the pin */15891589+ if (!per_pin->pcm)15901590+ return;15911591+ idx = per_pin->pcm_idx;15921592+ per_pin->pcm_idx = -1;15931593+ per_pin->pcm = NULL;15941594+ if (idx >= 0 && idx < spec->pcm_used)15951595+ clear_bit(idx, &spec->pcm_bitmap);15961596+}15971597+15981598+static int hdmi_get_pin_cvt_mux(struct hdmi_spec *spec,15991599+ struct hdmi_spec_per_pin *per_pin, hda_nid_t cvt_nid)16001600+{16011601+ int mux_idx;16021602+16031603+ for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)16041604+ if (per_pin->mux_nids[mux_idx] == cvt_nid)16051605+ break;16061606+ return mux_idx;16071607+}16081608+16091609+static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid);16101610+16111611+static void hdmi_pcm_setup_pin(struct hdmi_spec *spec,16121612+ struct hdmi_spec_per_pin *per_pin)16131613+{16141614+ struct hda_codec *codec = per_pin->codec;16151615+ struct hda_pcm *pcm;16161616+ struct hda_pcm_stream *hinfo;16171617+ struct snd_pcm_substream *substream;16181618+ int mux_idx;16191619+ bool non_pcm;16201620+16211621+ if (per_pin->pcm_idx >= 0 && per_pin->pcm_idx < spec->pcm_used)16221622+ pcm = get_pcm_rec(spec, per_pin->pcm_idx);16231623+ else16241624+ return;16251625+ if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))16261626+ return;16271627+16281628+ /* hdmi audio only uses playback and one substream */16291629+ hinfo = pcm->stream;16301630+ substream = pcm->pcm->streams[0].substream;16311631+16321632+ per_pin->cvt_nid = hinfo->nid;16331633+16341634+ mux_idx = hdmi_get_pin_cvt_mux(spec, per_pin, hinfo->nid);16351635+ if (mux_idx < per_pin->num_mux_nids)16361636+ snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,16371637+ AC_VERB_SET_CONNECT_SEL,16381638+ mux_idx);16391639+ snd_hda_spdif_ctls_assign(codec, per_pin->pcm_idx, hinfo->nid);16401640+16411641+ non_pcm = check_non_pcm_per_cvt(codec, hinfo->nid);16421642+ if (substream->runtime)16431643+ per_pin->channels = substream->runtime->channels;16441644+ per_pin->setup = true;16451645+ per_pin->mux_idx = mux_idx;16461646+16471647+ hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);16481648+}16491649+16501650+static void hdmi_pcm_reset_pin(struct hdmi_spec *spec,16511651+ struct hdmi_spec_per_pin *per_pin)16521652+{16531653+ if (per_pin->pcm_idx >= 0 && per_pin->pcm_idx < spec->pcm_used)16541654+ snd_hda_spdif_ctls_unassign(per_pin->codec, per_pin->pcm_idx);16551655+16561656+ per_pin->chmap_set = false;16571657+ memset(per_pin->chmap, 0, sizeof(per_pin->chmap));16581658+16591659+ per_pin->setup = false;16601660+ per_pin->channels = 0;16611661+}16621662+17141663/* update per_pin ELD from the given new ELD;17151664 * setup info frame and notification accordingly17161665 */···18381549 struct hdmi_eld *eld)18391550{18401551 struct hdmi_eld *pin_eld = &per_pin->sink_eld;15521552+ struct hdmi_spec *spec = codec->spec;18411553 bool old_eld_valid = pin_eld->eld_valid;18421554 bool eld_changed;15551555+15561556+ if (spec->dyn_pcm_assign) {15571557+ if (eld->eld_valid) {15581558+ hdmi_attach_hda_pcm(spec, per_pin);15591559+ hdmi_pcm_setup_pin(spec, per_pin);15601560+ } else {15611561+ hdmi_pcm_reset_pin(spec, per_pin);15621562+ hdmi_detach_hda_pcm(spec, per_pin);15631563+ }15641564+ }1843156518441566 if (eld->eld_valid)18451567 snd_hdmi_show_eld(codec, &eld->info);···19621662{19631663 struct hdmi_spec *spec = codec->spec;19641664 struct hdmi_eld *eld = &spec->temp_eld;16651665+ struct snd_jack *jack = NULL;19651666 int size;1966166719671668 mutex_lock(&per_pin->lock);···19861685 eld->eld_size = 0;19871686 }1988168716881688+ /* pcm_idx >=0 before update_eld() means it is in monitor16891689+ * disconnected event. Jack must be fetched before update_eld()16901690+ */16911691+ if (per_pin->pcm_idx >= 0)16921692+ jack = spec->pcm_rec[per_pin->pcm_idx].jack;19891693 update_eld(codec, per_pin, eld);19901990- snd_jack_report(per_pin->acomp_jack,16941694+ if (jack == NULL && per_pin->pcm_idx >= 0)16951695+ jack = spec->pcm_rec[per_pin->pcm_idx].jack;16961696+ if (jack == NULL)16971697+ goto unlock;16981698+ snd_jack_report(jack,19911699 eld->monitor_present ? SND_JACK_AVOUT : 0);19921700 unlock:19931701 mutex_unlock(&per_pin->lock);···20051695static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)20061696{20071697 struct hda_codec *codec = per_pin->codec;16981698+ struct hdmi_spec *spec = codec->spec;16991699+ int ret;2008170017011701+ mutex_lock(&spec->pcm_lock);20091702 if (codec_has_acomp(codec)) {20101703 sync_eld_via_acomp(codec, per_pin);20112011- return false; /* don't call snd_hda_jack_report_sync() */17041704+ ret = false; /* don't call snd_hda_jack_report_sync() */20121705 } else {20132013- return hdmi_present_sense_via_verbs(per_pin, repoll);17061706+ ret = hdmi_present_sense_via_verbs(per_pin, repoll);20141707 }17081708+ mutex_unlock(&spec->pcm_lock);17091709+17101710+ return ret;20151711}2016171220171713static void hdmi_repoll_eld(struct work_struct *work)···2061174520621746 per_pin->pin_nid = pin_nid;20631747 per_pin->non_pcm = false;17481748+ if (spec->dyn_pcm_assign)17491749+ per_pin->pcm_idx = -1;17501750+ else {17511751+ per_pin->pcm = get_hdmi_pcm(spec, pin_idx);17521752+ per_pin->pcm_idx = pin_idx;17531753+ }17541754+ per_pin->pin_nid_idx = pin_idx;2064175520651756 err = hdmi_read_pin_conn(codec, pin_idx);20661757 if (err < 0)···21741851{21751852 hda_nid_t cvt_nid = hinfo->nid;21761853 struct hdmi_spec *spec = codec->spec;21772177- int pin_idx = hinfo_to_pin_index(codec, hinfo);21782178- struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);21792179- hda_nid_t pin_nid = per_pin->pin_nid;18541854+ int pin_idx;18551855+ struct hdmi_spec_per_pin *per_pin;18561856+ hda_nid_t pin_nid;21801857 struct snd_pcm_runtime *runtime = substream->runtime;21811858 bool non_pcm;21821859 int pinctl;18601860+ int err;2183186118621862+ mutex_lock(&spec->pcm_lock);18631863+ pin_idx = hinfo_to_pin_index(codec, hinfo);18641864+ if (spec->dyn_pcm_assign && pin_idx < 0) {18651865+ /* when dyn_pcm_assign and pcm is not bound to a pin18661866+ * skip pin setup and return 0 to make audio playback18671867+ * be ongoing18681868+ */18691869+ intel_not_share_assigned_cvt_nid(codec, 0, cvt_nid);18701870+ snd_hda_codec_setup_stream(codec, cvt_nid,18711871+ stream_tag, 0, format);18721872+ mutex_unlock(&spec->pcm_lock);18731873+ return 0;18741874+ }18751875+18761876+ if (snd_BUG_ON(pin_idx < 0)) {18771877+ mutex_unlock(&spec->pcm_lock);18781878+ return -EINVAL;18791879+ }18801880+ per_pin = get_pin(spec, pin_idx);18811881+ pin_nid = per_pin->pin_nid;21841882 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {21851883 /* Verify pin:cvt selections to avoid silent audio after S3.21861884 * After S3, the audio driver restores pin:cvt selections···2226188222271883 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);22281884 mutex_unlock(&per_pin->lock);22292229-22301885 if (spec->dyn_pin_out) {22311886 pinctl = snd_hda_codec_read(codec, pin_nid, 0,22321887 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);···22341891 pinctl | PIN_OUT);22351892 }2236189322372237- return spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);18941894+ err = spec->ops.setup_stream(codec, cvt_nid, pin_nid,18951895+ stream_tag, format);18961896+ mutex_unlock(&spec->pcm_lock);18971897+ return err;22381898}2239189922401900static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,···22531907 struct snd_pcm_substream *substream)22541908{22551909 struct hdmi_spec *spec = codec->spec;22562256- int cvt_idx, pin_idx;19101910+ int cvt_idx, pin_idx, pcm_idx;22571911 struct hdmi_spec_per_cvt *per_cvt;22581912 struct hdmi_spec_per_pin *per_pin;22591913 int pinctl;2260191422611915 if (hinfo->nid) {19161916+ pcm_idx = hinfo_to_pcm_index(codec, hinfo);19171917+ if (snd_BUG_ON(pcm_idx < 0))19181918+ return -EINVAL;22621919 cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid);22631920 if (snd_BUG_ON(cvt_idx < 0))22641921 return -EINVAL;···22711922 per_cvt->assigned = 0;22721923 hinfo->nid = 0;2273192419251925+ mutex_lock(&spec->pcm_lock);19261926+ snd_hda_spdif_ctls_unassign(codec, pcm_idx);19271927+ clear_bit(pcm_idx, &spec->pcm_in_use);22741928 pin_idx = hinfo_to_pin_index(codec, hinfo);22752275- if (snd_BUG_ON(pin_idx < 0))19291929+ if (spec->dyn_pcm_assign && pin_idx < 0) {19301930+ mutex_unlock(&spec->pcm_lock);19311931+ return 0;19321932+ }19331933+19341934+ if (snd_BUG_ON(pin_idx < 0)) {19351935+ mutex_unlock(&spec->pcm_lock);22761936 return -EINVAL;19371937+ }22771938 per_pin = get_pin(spec, pin_idx);2278193922791940 if (spec->dyn_pin_out) {···22941935 pinctl & ~PIN_OUT);22951936 }2296193722972297- snd_hda_spdif_ctls_unassign(codec, pin_idx);22982298-22991938 mutex_lock(&per_pin->lock);23001939 per_pin->chmap_set = false;23011940 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));···23011944 per_pin->setup = false;23021945 per_pin->channels = 0;23031946 mutex_unlock(&per_pin->lock);19471947+ mutex_unlock(&spec->pcm_lock);23041948 }2305194923061950 return 0;···24132055 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);24142056 struct hda_codec *codec = info->private_data;24152057 struct hdmi_spec *spec = codec->spec;24162416- int pin_idx = kcontrol->private_value;24172417- struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);20582058+ int pcm_idx = kcontrol->private_value;20592059+ struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);24182060 int i;20612061+20622062+ if (!per_pin) {20632063+ for (i = 0; i < spec->channels_max; i++)20642064+ ucontrol->value.integer.value[i] = 0;20652065+ return 0;20662066+ }2419206724202068 for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++)24212069 ucontrol->value.integer.value[i] = per_pin->chmap[i];···24342070 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);24352071 struct hda_codec *codec = info->private_data;24362072 struct hdmi_spec *spec = codec->spec;24372437- int pin_idx = kcontrol->private_value;24382438- struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);20732073+ int pcm_idx = kcontrol->private_value;20742074+ struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);24392075 unsigned int ctl_idx;24402076 struct snd_pcm_substream *substream;24412077 unsigned char chmap[8];24422078 int i, err, ca, prepared = 0;20792079+20802080+ /* No monitor is connected in dyn_pcm_assign.20812081+ * It's invalid to setup the chmap20822082+ */20832083+ if (!per_pin)20842084+ return 0;2443208524442086 ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);24452087 substream = snd_pcm_chmap_substream(info, ctl_idx);···24962126 info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx);24972127 if (!info)24982128 return -ENOMEM;24992499- spec->pcm_rec[pin_idx] = info;21292129+21302130+ spec->pcm_rec[pin_idx].pcm = info;21312131+ spec->pcm_used++;25002132 info->pcm_type = HDA_PCM_TYPE_HDMI;25012133 info->own_chmap = true;25022134···25112139 return 0;25122140}2513214125142514-static void free_acomp_jack_priv(struct snd_jack *jack)21422142+static void free_hdmi_jack_priv(struct snd_jack *jack)25152143{25162516- struct hdmi_spec_per_pin *per_pin = jack->private_data;21442144+ struct hdmi_pcm *pcm = jack->private_data;2517214525182518- per_pin->acomp_jack = NULL;21462146+ pcm->jack = NULL;25192147}2520214825212521-static int add_acomp_jack_kctl(struct hda_codec *codec,25222522- struct hdmi_spec_per_pin *per_pin,21492149+static int add_hdmi_jack_kctl(struct hda_codec *codec,21502150+ struct hdmi_spec *spec,21512151+ int pcm_idx,25232152 const char *name)25242153{25252154 struct snd_jack *jack;···25302157 true, false);25312158 if (err < 0)25322159 return err;25332533- per_pin->acomp_jack = jack;25342534- jack->private_data = per_pin;25352535- jack->private_free = free_acomp_jack_priv;21602160+21612161+ spec->pcm_rec[pcm_idx].jack = jack;21622162+ jack->private_data = &spec->pcm_rec[pcm_idx];21632163+ jack->private_free = free_hdmi_jack_priv;25362164 return 0;25372165}2538216625392539-static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)21672167+static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)25402168{25412169 char hdmi_str[32] = "HDMI/DP";25422170 struct hdmi_spec *spec = codec->spec;25432543- struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);25442544- int pcmdev = get_pcm_rec(spec, pin_idx)->device;21712171+ struct hdmi_spec_per_pin *per_pin;21722172+ struct hda_jack_tbl *jack;21732173+ int pcmdev = get_pcm_rec(spec, pcm_idx)->device;25452174 bool phantom_jack;21752175+ int ret;2546217625472177 if (pcmdev > 0)25482178 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);25492549- if (codec_has_acomp(codec))25502550- return add_acomp_jack_kctl(codec, per_pin, hdmi_str);21792179+21802180+ if (spec->dyn_pcm_assign)21812181+ return add_hdmi_jack_kctl(codec, spec, pcm_idx, hdmi_str);21822182+21832183+ /* for !dyn_pcm_assign, we still use hda_jack for compatibility */21842184+ /* if !dyn_pcm_assign, it must be non-MST mode.21852185+ * This means pcms and pins are statically mapped.21862186+ * And pcm_idx is pin_idx.21872187+ */21882188+ per_pin = get_pin(spec, pcm_idx);25512189 phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid);25522190 if (phantom_jack)25532191 strncat(hdmi_str, " Phantom",25542192 sizeof(hdmi_str) - strlen(hdmi_str) - 1);25552555-25562556- return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,25572557- phantom_jack);21932193+ ret = snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,21942194+ phantom_jack);21952195+ if (ret < 0)21962196+ return ret;21972197+ jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);21982198+ if (jack == NULL)21992199+ return 0;22002200+ /* assign jack->jack to pcm_rec[].jack to22012201+ * align with dyn_pcm_assign mode22022202+ */22032203+ spec->pcm_rec[pcm_idx].jack = jack->jack;22042204+ return 0;25582205}2559220625602207static int generic_hdmi_build_controls(struct hda_codec *codec)25612208{25622209 struct hdmi_spec *spec = codec->spec;25632210 int err;25642564- int pin_idx;22112211+ int pin_idx, pcm_idx;22122212+22132213+22142214+ for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {22152215+ err = generic_hdmi_build_jack(codec, pcm_idx);22162216+ if (err < 0)22172217+ return err;22182218+22192219+ /* create the spdif for each pcm22202220+ * pin will be bound when monitor is connected22212221+ */22222222+ if (spec->dyn_pcm_assign)22232223+ err = snd_hda_create_dig_out_ctls(codec,22242224+ 0, spec->cvt_nids[0],22252225+ HDA_PCM_TYPE_HDMI);22262226+ else {22272227+ struct hdmi_spec_per_pin *per_pin =22282228+ get_pin(spec, pcm_idx);22292229+ err = snd_hda_create_dig_out_ctls(codec,22302230+ per_pin->pin_nid,22312231+ per_pin->mux_nids[0],22322232+ HDA_PCM_TYPE_HDMI);22332233+ }22342234+ if (err < 0)22352235+ return err;22362236+ snd_hda_spdif_ctls_unassign(codec, pcm_idx);22372237+ }2565223825662239 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {25672240 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);2568224125692569- err = generic_hdmi_build_jack(codec, pin_idx);25702570- if (err < 0)25712571- return err;25722572-25732573- err = snd_hda_create_dig_out_ctls(codec,25742574- per_pin->pin_nid,25752575- per_pin->mux_nids[0],25762576- HDA_PCM_TYPE_HDMI);25772577- if (err < 0)25782578- return err;25792579- snd_hda_spdif_ctls_unassign(codec, pin_idx);25802580-25812242 /* add control for ELD Bytes */25822243 err = hdmi_create_eld_ctl(codec, pin_idx,25832583- get_pcm_rec(spec, pin_idx)->device);22442244+ get_pcm_rec(spec, pin_idx)->device);2584224525852246 if (err < 0)25862247 return err;···26232216 }2624221726252218 /* add channel maps */26262626- for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {22192219+ for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {26272220 struct hda_pcm *pcm;26282221 struct snd_pcm_chmap *chmap;26292222 struct snd_kcontrol *kctl;26302223 int i;2631222426322632- pcm = spec->pcm_rec[pin_idx];22252225+ pcm = get_pcm_rec(spec, pcm_idx);26332226 if (!pcm || !pcm->pcm)26342227 break;26352228 err = snd_pcm_add_chmap_ctls(pcm->pcm,26362229 SNDRV_PCM_STREAM_PLAYBACK,26372637- NULL, 0, pin_idx, &chmap);22302230+ NULL, 0, pcm_idx, &chmap);26382231 if (err < 0)26392232 return err;26402233 /* override handlers */···27002293static void generic_hdmi_free(struct hda_codec *codec)27012294{27022295 struct hdmi_spec *spec = codec->spec;27032703- int pin_idx;22962296+ int pin_idx, pcm_idx;2704229727052298 if (codec_has_acomp(codec))27062299 snd_hdac_i915_register_notifier(NULL);2707230027082301 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {27092302 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);27102710-27112303 cancel_delayed_work_sync(&per_pin->work);27122304 eld_proc_free(per_pin);27132713- if (per_pin->acomp_jack)27142714- snd_device_free(codec->card, per_pin->acomp_jack);23052305+ }23062306+23072307+ for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {23082308+ if (spec->pcm_rec[pcm_idx].jack == NULL)23092309+ continue;23102310+ if (spec->dyn_pcm_assign)23112311+ snd_device_free(codec->card,23122312+ spec->pcm_rec[pcm_idx].jack);23132313+ else23142314+ spec->pcm_rec[pcm_idx].jack = NULL;27152315 }2716231627172317 if (spec->i915_bound)···28672453 return -ENOMEM;2868245428692455 spec->ops = generic_standard_hdmi_ops;24562456+ mutex_init(&spec->pcm_lock);28702457 codec->spec = spec;28712458 hdmi_array_init(spec, 4);28722459···2920250529212506 init_channel_allocations();2922250725082508+ WARN_ON(spec->dyn_pcm_assign && !codec_has_acomp(codec));29232509 return 0;29242510}29252511···29432527 info = snd_hda_codec_pcm_new(codec, "HDMI 0");29442528 if (!info)29452529 return -ENOMEM;29462946- spec->pcm_rec[0] = info;25302530+ spec->pcm_rec[0].pcm = info;29472531 info->pcm_type = HDA_PCM_TYPE_HDMI;29482532 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];29492533 *pstr = spec->pcm_playback;