From: Hui Wang <hui.wang@canonical.com>
To: Takashi Iwai <tiwai@suse.de>
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH] ALSA: hda/hdmi - Don't report Jack event if no need to do that
Date: Sat, 4 May 2019 10:45:36 +0800 [thread overview]
Message-ID: <a1c69f75-da2b-8ac0-9dfa-34958cdb5fd8@canonical.com> (raw)
In-Reply-To: <s5himurr0no.wl-tiwai@suse.de>
On 2019/5/3 下午11:57, Takashi Iwai wrote:
> On Fri, 03 May 2019 06:05:09 +0200,
> Hui Wang wrote:
>>
>> 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?
> OK, I was confused -- I overlooked the fact that hda_jack.c updates
> the pin sense locally. And thanks for the suggestion, we're heading
> to the right direction.
>
> One thing that doesn't fit is introducing HDMI-specific things like
> eld_valid and check_eld. Basically this is about the falsely reported
> jack detection, after all. So, what we need is the correction of the
> incorrect jack detection -- or a way to override the value.
>
> Actually, for HDMI, there is no reason to read the pin sense at all.
> All we need is already provided by the HDMI codec driver (monitor
> present and eld valid).
>
> Then I can think of adding a new flag hda_jack_tbl.manual_pin_sense,
> for example, indicating that the pin sense is updated by the driver.
> That's a change something like below.
>
Looks like the hdmi_present_sense_via_verbs() still has some issue. At
the entry of this function, it calls snd_hda_pin_sense() and read the
eld_data depending on the return value, here it expects reading the pin
sense register, after applying your change, this function returns a
shadow value instead of a register value, if we set the pin_sense to 0,
then it is possible that the pin_get_eld() will not be called anymore.
And inspired by your change, maybe we just make this change, then it is
enough to fix the falsely report issue here.
@@ -1551,8 +1551,11 @@ 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->pin_sense = (eld->monitor_present && eld->eld_valid) ?
+ AC_PINSENSE_PRESENCE : 0;
+ }
because in the snd_hda_pin_sense(), the jack_dirty is set to 0, then we
change the jack->pin_sense, and in the report_sync() it will decide the
jack state according to the jack->pin_sense we changed.
Thanks,
Hui.
> thanks,
>
> Takashi
>
> --- a/sound/pci/hda/hda_jack.c
> +++ b/sound/pci/hda/hda_jack.c
> @@ -189,7 +189,7 @@ void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
> int i;
>
> for (i = 0; i < codec->jacktbl.used; i++, jack++)
> - if (jack->nid)
> + if (jack->nid && !jack->manual_pin_sense)
> jack->jack_dirty = 1;
> }
> EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all);
> @@ -568,7 +568,8 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
> event = snd_hda_jack_tbl_get_from_tag(codec, tag);
> if (!event)
> return;
> - event->jack_dirty = 1;
> + if (!event->manual_pin_sense)
> + event->jack_dirty = 1;
>
> call_jack_callback(codec, res, event);
> snd_hda_jack_report_sync(codec);
> --- a/sound/pci/hda/hda_jack.h
> +++ b/sound/pci/hda/hda_jack.h
> @@ -40,6 +40,7 @@ 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 manual_pin_sense:1; /* pin_sense is updated by codec driver */
> hda_nid_t gating_jack; /* valid when gating jack plugged */
> hda_nid_t gated_jack; /* gated is dependent on this jack */
> int type;
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -170,6 +170,7 @@ struct hdmi_spec {
>
> bool dyn_pin_out;
> bool dyn_pcm_assign;
> + bool use_pin_sense;
> /*
> * Non-generic VIA/NVIDIA specific
> */
> @@ -797,7 +798,6 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
> jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
> if (!jack)
> return;
> - jack->jack_dirty = 1;
>
> codec_dbg(codec,
> "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
> @@ -1551,8 +1551,11 @@ 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->pin_sense = (eld->monitor_present && eld->eld_valid) ?
> + AC_PINSENSE_PRESENCE : 0;
> + }
>
> mutex_unlock(&per_pin->lock);
> return ret;
> @@ -2163,6 +2166,7 @@ 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;
> + jack->manual_pin_sense = !spec->use_pin_sense;
> return 0;
> }
>
> @@ -2972,6 +2976,7 @@ static int patch_simple_hdmi(struct hda_codec *codec,
> spec->multiout.dig_out_nid = cvt_nid;
> spec->num_cvts = 1;
> spec->num_pins = 1;
> + spec->use_pin_sense = true;
> per_pin = snd_array_new(&spec->pins);
> per_cvt = snd_array_new(&spec->cvts);
> if (!per_pin || !per_cvt) {
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
next prev parent reply other threads:[~2019-05-04 2:45 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-30 6:57 [PATCH] ALSA: hda/hdmi - Don't report Jack event if no need to do that Hui Wang
2019-04-30 7:35 ` Takashi Iwai
2019-04-30 8:42 ` Hui Wang
2019-04-30 9:02 ` Takashi Iwai
2019-05-02 2:52 ` Hui Wang
2019-05-02 15:49 ` Takashi Iwai
2019-05-03 4:05 ` Hui Wang
2019-05-03 15:57 ` Takashi Iwai
2019-05-04 2:45 ` Hui Wang [this message]
2019-05-04 7:18 ` Takashi Iwai
2019-05-04 9:25 ` Hui Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a1c69f75-da2b-8ac0-9dfa-34958cdb5fd8@canonical.com \
--to=hui.wang@canonical.com \
--cc=alsa-devel@alsa-project.org \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox