ALSA: hda/hdmi: Move ELD parse and jack reporting into update_eld()
authorTakashi Iwai <tiwai@suse.de>
Thu, 6 Feb 2020 16:28:04 +0000 (17:28 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 10 Feb 2020 07:24:11 +0000 (08:24 +0100)
This is a final step of the cleanup series: move the HDMI ELD parser
call into update_eld() function so that we can unify the calls.
The ELD validity check is unified in update_eld(), too.

Along with it, the repoll scheduling is moved to update_eld() as well,
where sync_eld_via_acomp() just passes 0 for skipping it.

Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Nikhil Mahale <nmahale@nvidia.com>
Link: https://lore.kernel.org/r/20200206162804.4734-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/patch_hdmi.c

index 4371772..bb287a9 100644 (file)
@@ -1466,21 +1466,60 @@ static void hdmi_pcm_reset_pin(struct hdmi_spec *spec,
        per_pin->channels = 0;
 }
 
+static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
+                                           struct hdmi_spec_per_pin *per_pin)
+{
+       struct hdmi_spec *spec = codec->spec;
+
+       if (per_pin->pcm_idx >= 0)
+               return spec->pcm_rec[per_pin->pcm_idx].jack;
+       else
+               return NULL;
+}
+
 /* update per_pin ELD from the given new ELD;
  * setup info frame and notification accordingly
+ * also notify ELD kctl and report jack status changes
  */
-static bool update_eld(struct hda_codec *codec,
+static void update_eld(struct hda_codec *codec,
                       struct hdmi_spec_per_pin *per_pin,
-                      struct hdmi_eld *eld)
+                      struct hdmi_eld *eld,
+                      int repoll)
 {
        struct hdmi_eld *pin_eld = &per_pin->sink_eld;
        struct hdmi_spec *spec = codec->spec;
+       struct snd_jack *pcm_jack;
        bool old_eld_valid = pin_eld->eld_valid;
        bool eld_changed;
        int pcm_idx;
 
+       if (eld->eld_valid) {
+               if (eld->eld_size <= 0 ||
+                   snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
+                                      eld->eld_size) < 0) {
+                       eld->eld_valid = false;
+                       if (repoll) {
+                               schedule_delayed_work(&per_pin->work,
+                                                     msecs_to_jiffies(300));
+                               return;
+                       }
+               }
+       }
+
+       if (!eld->eld_valid || eld->eld_size <= 0) {
+               eld->eld_valid = false;
+               eld->eld_size = 0;
+       }
+
        /* for monitor disconnection, save pcm_idx firstly */
        pcm_idx = per_pin->pcm_idx;
+
+       /*
+        * pcm_idx >=0 before update_eld() means it is in monitor
+        * disconnected event. Jack must be fetched before update_eld().
+        */
+       pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+
        if (spec->dyn_pcm_assign) {
                if (eld->eld_valid) {
                        hdmi_attach_hda_pcm(spec, per_pin);
@@ -1495,6 +1534,8 @@ static bool update_eld(struct hda_codec *codec,
         */
        if (pcm_idx == -1)
                pcm_idx = per_pin->pcm_idx;
+       if (!pcm_jack)
+               pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
 
        if (eld->eld_valid)
                snd_hdmi_show_eld(codec, &eld->info);
@@ -1533,36 +1574,8 @@ static bool update_eld(struct hda_codec *codec,
                               SNDRV_CTL_EVENT_MASK_VALUE |
                               SNDRV_CTL_EVENT_MASK_INFO,
                               &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
-       return eld_changed;
-}
-
-static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
-                                           struct hdmi_spec_per_pin *per_pin)
-{
-       struct hdmi_spec *spec = codec->spec;
 
-       if (per_pin->pcm_idx >= 0)
-               return spec->pcm_rec[per_pin->pcm_idx].jack;
-       else
-               return NULL;
-}
-
-static void do_update_eld(struct hda_codec *codec,
-                         struct hdmi_spec_per_pin *per_pin,
-                         struct hdmi_eld *eld)
-{
-       struct snd_jack *pcm_jack;
-       bool changed;
-
-       /*
-        * pcm_idx >=0 before update_eld() means it is in monitor
-        * disconnected event. Jack must be fetched before update_eld().
-        */
-       pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
-       changed = update_eld(codec, per_pin, eld);
-       if (!pcm_jack)
-               pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
-       if (changed && pcm_jack)
+       if (eld_changed && pcm_jack)
                snd_jack_report(pcm_jack,
                                (eld->monitor_present && eld->eld_valid) ?
                                SND_JACK_AVOUT : 0);
@@ -1586,7 +1599,6 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
         * the unsolicited response to avoid custom WARs.
         */
        int present;
-       bool do_repoll = false;
        int ret;
 
        ret = snd_hda_power_up_pm(codec);
@@ -1610,20 +1622,9 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
                if (spec->ops.pin_get_eld(codec, pin_nid, dev_id,
                                          eld->eld_buffer, &eld->eld_size) < 0)
                        eld->eld_valid = false;
-               else {
-                       if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
-                                                   eld->eld_size) < 0)
-                               eld->eld_valid = false;
-               }
-               if (!eld->eld_valid && repoll)
-                       do_repoll = true;
        }
 
-       if (do_repoll)
-               schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300));
-       else
-               do_update_eld(codec, per_pin, eld);
-
+       update_eld(codec, per_pin, eld, repoll);
        mutex_unlock(&per_pin->lock);
  out:
        snd_hda_power_down_pm(codec);
@@ -1635,29 +1636,14 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
 {
        struct hdmi_spec *spec = codec->spec;
        struct hdmi_eld *eld = &spec->temp_eld;
-       int size;
 
        mutex_lock(&per_pin->lock);
        eld->monitor_present = false;
-       size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
+       eld->eld_size = snd_hdac_acomp_get_eld(&codec->core, per_pin->pin_nid,
                                      per_pin->dev_id, &eld->monitor_present,
                                      eld->eld_buffer, ELD_MAX_SIZE);
-       if (size > 0) {
-               size = min(size, ELD_MAX_SIZE);
-               if (snd_hdmi_parse_eld(codec, &eld->info,
-                                      eld->eld_buffer, size) < 0)
-                       size = -EINVAL;
-       }
-
-       if (size > 0) {
-               eld->eld_valid = true;
-               eld->eld_size = size;
-       } else {
-               eld->eld_valid = false;
-               eld->eld_size = 0;
-       }
-
-       do_update_eld(codec, per_pin, eld);
+       eld->eld_valid = (eld->eld_size > 0);
+       update_eld(codec, per_pin, eld, 0);
        mutex_unlock(&per_pin->lock);
 }