[alsa-devel] [PATCH] ALSA: hda/hdmi - Don't report Jack event if no need to do that

Hui Wang hui.wang at canonical.com
Fri May 3 06:05:09 CEST 2019


On 2019/5/2 下午11:49, Takashi Iwai wrote:
> On Thu, 02 May 2019 04:52:46 +0200,
> Hui Wang wrote:
>>
>> On 2019/4/30 下午5:02, Takashi Iwai wrote:
>>> On Tue, 30 Apr 2019 10:42:55 +0200,
>>> Hui Wang wrote:
>>>> On 2019/4/30 下午3:35, Takashi Iwai wrote:
>>>>> On Tue, 30 Apr 2019 08:57:11 +0200,
>>>>> Hui Wang wrote:
>>>>>> On the machines with AMD GPU or Nvidia GPU, we often meet this issues:
>>>>>> after s3, there are 4 HDMI/DP audio devices in the gnome-sound-setting
>>>>>> even there is no any monitors plugged.
>>>>>>
>>>>>> When this problem happens, we check the /proc/asound/cardX/eld#N.M, we
>>>>>> will find the monitor_present=1, eld_valid=0.
>>>>>>

>>>>>>
>>>>>> So the fix is putting your change and my change together like below?
> Well, removing "!repoll" should be treated as a separate patch, and
> I'm not sure whether we want to get rid of it.
>
> The "!repoll" check is a bit misleading.  This condition indicates
> that the jack status sync is required, e.g. it's the case where
> polling goes to timeout or at the beginning of the probe.  For
> example, in the case of resume, it starts with repoll=1.  If an
> incomplete state (monitor=1, eld_valid=0) is seen at this point, the
> code schedules for the retry at a later point.  And if it reaches to
> the max count, it clears to repoll=0 and try the last attempt, which
> won't schedule any longer.
>
> So, at this point, we *have to* notify the result no matter whether
> it's satisfying or not.
>
>
> thanks,
>
> Takashi

So let us do sth in the hda_jack.c, adding two members check_eld and 
eld_valid in the struct hda_jack_tbl{},

When building new jacks, since there is no eld_data yet, just follow old 
rules (only checking AC_PINSENSE_PRESENCE)

After building new jacks, if it is not a phantom one, set check_eld to 1

every time we get eld (via verbs or acomp), we will sync jack->eld_valid 
to eld->eld_valid.

in the report_sync(), we will check check_eld and eld_valid, not depends 
on AC_PINSENSE_PRESENCE only.

No matter interrupt, s3 or poll,  the jack->eld_valid will be synced and 
the report_sync() will report jack state depeneds on both 
AC_PINSENSE_PRESENCE and eld_valid

Does it sound good?

Thanks,

Hui.

diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 74b46952fc98..4bdf842bd915 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -341,7 +341,8 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
                                 continue;
                         state = jack->button_state;
                         if (get_jack_plug_state(jack->pin_sense))
-                               state |= jack->type;
+                               if (!jack->check_eld || jack->eld_valid)
+                                       state |= jack->type;
                         snd_jack_report(jack->jack, state);
                         if (jack->button_state) {
                                 snd_jack_report(jack->jack,
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 1d713201c160..57d7245b8961 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -40,6 +40,8 @@ struct hda_jack_tbl {
         unsigned int jack_dirty:1;      /* needs to update? */
         unsigned int phantom_jack:1;    /* a fixed, always present port? */
         unsigned int block_report:1;    /* in a transitional state - do 
not report to userspace */
+       unsigned int check_eld:1;       /* check eld flag when deciding 
pin presence */
+       unsigned int eld_valid:1;       /* eld data valid or not */
         hda_nid_t gating_jack;          /* valid when gating jack 
plugged */
         hda_nid_t gated_jack;           /* gated is dependent on this 
jack */
         int type;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8b3ac690efa3..56357e17d17d 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1551,8 +1551,10 @@ static bool hdmi_present_sense_via_verbs(struct 
hdmi_spec_per_pin *per_pin,
         ret = !repoll || !eld->monitor_present || eld->eld_valid;

         jack = snd_hda_jack_tbl_get(codec, pin_nid);
-       if (jack)
+       if (jack) {
                 jack->block_report = !ret;
+               jack->eld_valid = eld->eld_valid;
+       }

         mutex_unlock(&per_pin->lock);
         return ret;
@@ -1593,6 +1595,7 @@ static void sync_eld_via_acomp(struct hda_codec 
*codec,
         struct hdmi_spec *spec = codec->spec;
         struct hdmi_eld *eld = &spec->temp_eld;
         struct snd_jack *jack = NULL;
+       struct hda_jack_tbl *jack_tbl;
         int size;

         mutex_lock(&per_pin->lock);
@@ -1615,6 +1618,10 @@ static void sync_eld_via_acomp(struct hda_codec 
*codec,
                 eld->eld_size = 0;
         }

+       jack_tbl = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);
+       if (jack_tbl)
+               jack_tbl->eld_valid = eld->eld_valid;
+
         /* pcm_idx >=0 before update_eld() means it is in monitor
          * disconnected event. Jack must be fetched before update_eld()
          */
@@ -1625,7 +1632,7 @@ static void sync_eld_via_acomp(struct hda_codec 
*codec,
         if (jack == NULL)
                 goto unlock;
         snd_jack_report(jack,
-                       eld->monitor_present ? SND_JACK_AVOUT : 0);
+                       (eld->monitor_present && eld->eld_valid) ? 
SND_JACK_AVOUT : 0);
   unlock:
         mutex_unlock(&per_pin->lock);
  }
@@ -2163,6 +2170,8 @@ static int generic_hdmi_build_jack(struct 
hda_codec *codec, int pcm_idx)
          * align with dyn_pcm_assign mode
          */
         spec->pcm_rec[pcm_idx].jack = jack->jack;
+       if (!jack->phantom_jack)
+               jack->check_eld = 1;
         return 0;
  }

>
>> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
>> index 8b3ac690efa3..14b799a85873 100644
>> --- a/sound/pci/hda/patch_hdmi.c
>> +++ b/sound/pci/hda/patch_hdmi.c
>>
>>
>>> thanks,
>>>
>>> Takashi
>>> _______________________________________________
>>> Alsa-devel mailing list
>>> Alsa-devel at alsa-project.org
>>> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel


More information about the Alsa-devel mailing list