All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kai-Heng Feng <kai.heng.feng@canonical.com>
To: Takashi Iwai <tiwai@suse.de>
Cc: Takashi Iwai <tiwai@suse.com>, Jaroslav Kysela <perex@perex.cz>,
	Pavel Skripkin <paskripkin@gmail.com>,
	Chris Chiu <chiu@endlessm.com>, Mark Brown <broonie@kernel.org>,
	Lars-Peter Clausen <lars@metafoo.de>,
	Tom Yan <tom.ty89@gmail.com>, Joe Perches <joe@perches.com>,
	"moderated list:SOUND" <alsa-devel@alsa-project.org>,
	open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 2/2] ALSA: usb-audio: Check connector value on resume
Date: Thu, 25 Mar 2021 21:55:06 +0800	[thread overview]
Message-ID: <CAAd53p79HSpNKu69ZM7vRGWQT+9ydf59hGH-yNMT=Ymbg2NebA@mail.gmail.com> (raw)
In-Reply-To: <s5hczvnmju0.wl-tiwai@suse.de>

On Thu, Mar 25, 2021 at 9:41 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Thu, 25 Mar 2021 13:12:48 +0100,
> Kai-Heng Feng wrote:
> >
> > Rear Mic on Lenovo P620 cannot record after S3, despite that there's no
> > error and the other two functions of the USB audio, Line In and Line
> > Out, work just fine.
> >
> > The mic starts to work again after running userspace app like "alsactl
> > store". Following the lead, the evidence shows that as soon as connector
> > status is queried, the mic can work again.
> >
> > So also check connector value on resume to "wake up" the USB audio to
> > make it functional.
> >
> > This can be device specific, however I think this generic approach may
> > benefit more than one device.
> >
> > While at it, also remove reset-resume path to consolidate mixer resume
> > path.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> > ---
> > v2:
> >  - Remove reset-resume.
> >  - Fold the connector checking to the mixer resume callback.
>
> That's not what I meant exactly...  I meant to put both into the
> single resume callback, but handle each part conditionally depending
> on reset_resume argument.

OK, I get what you mean now.

>
> But this turned out to need more changes in mixer_quirks.c
> unnecessarily.  Maybe adding the two resume functions is a better
> approach in the end, but not for the specific connection thing but
> generically both resume and reset_resume callbacks.  Something like
> below.

This approach looks good. Let me send another one.

Kai-Heng

>
>
> thanks,
>
> Takashi
>
>
> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> index b004b2e63a5d..1dab281bb269 100644
> --- a/sound/usb/mixer.c
> +++ b/sound/usb/mixer.c
> @@ -3615,20 +3615,43 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
>         return 0;
>  }
>
> +static int default_mixer_resume(struct usb_mixer_elem_list *list)
> +{
> +       struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
> +
> +       /* get connector value to "wake up" the USB audio */
> +       if (cval->val_type == USB_MIXER_BOOLEAN && cval->channels == 1)
> +               get_connector_value(cval, NULL, NULL);
> +
> +       return 0;
> +}
> +
> +static int default_mixer_reset_resume(struct usb_mixer_elem_list *list)
> +{
> +       int err = default_mixer_resume(list);
> +
> +       if (err < 0)
> +               return err;
> +       return restore_mixer_value(list);
> +}
> +
>  int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
>  {
>         struct usb_mixer_elem_list *list;
> +       usb_mixer_elem_resume_func_t f;
>         int id, err;
>
> -       if (reset_resume) {
> -               /* restore cached mixer values */
> -               for (id = 0; id < MAX_ID_ELEMS; id++) {
> -                       for_each_mixer_elem(list, mixer, id) {
> -                               if (list->resume) {
> -                                       err = list->resume(list);
> -                                       if (err < 0)
> -                                               return err;
> -                               }
> +       /* restore cached mixer values */
> +       for (id = 0; id < MAX_ID_ELEMS; id++) {
> +               for_each_mixer_elem(list, mixer, id) {
> +                       if (reset_resume)
> +                               f = list->reset_resume;
> +                       else
> +                               f = list->resume;
> +                       if (f) {
> +                               err = list->resume(list);
> +                               if (err < 0)
> +                                       return err;
>                         }
>                 }
>         }
> @@ -3647,6 +3670,7 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
>         list->id = unitid;
>         list->dump = snd_usb_mixer_dump_cval;
>  #ifdef CONFIG_PM
> -       list->resume = restore_mixer_value;
> +       list->resume = default_mixer_resume;
> +       list->reset_resume = default_mixer_reset_resume;
>  #endif
>  }
> diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
> index c29e27ac43a7..e5a01f17bf3c 100644
> --- a/sound/usb/mixer.h
> +++ b/sound/usb/mixer.h
> @@ -69,6 +69,7 @@ struct usb_mixer_elem_list {
>         bool is_std_info;
>         usb_mixer_elem_dump_func_t dump;
>         usb_mixer_elem_resume_func_t resume;
> +       usb_mixer_elem_resume_func_t reset_resume;
>  };
>
>  /* iterate over mixer element list of the given unit id */
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index ffd922327ae4..b7f9c2fded05 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -151,7 +151,7 @@ static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
>                 *listp = list;
>         list->mixer = mixer;
>         list->id = id;
> -       list->resume = resume;
> +       list->reset_resume = resume;
>         kctl = snd_ctl_new1(knew, list);
>         if (!kctl) {
>                 kfree(list);

WARNING: multiple messages have this Message-ID (diff)
From: Kai-Heng Feng <kai.heng.feng@canonical.com>
To: Takashi Iwai <tiwai@suse.de>
Cc: "moderated list:SOUND" <alsa-devel@alsa-project.org>,
	Lars-Peter Clausen <lars@metafoo.de>,
	Pavel Skripkin <paskripkin@gmail.com>,
	Chris Chiu <chiu@endlessm.com>, Takashi Iwai <tiwai@suse.com>,
	Mark Brown <broonie@kernel.org>, Joe Perches <joe@perches.com>,
	Tom Yan <tom.ty89@gmail.com>,
	open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 2/2] ALSA: usb-audio: Check connector value on resume
Date: Thu, 25 Mar 2021 21:55:06 +0800	[thread overview]
Message-ID: <CAAd53p79HSpNKu69ZM7vRGWQT+9ydf59hGH-yNMT=Ymbg2NebA@mail.gmail.com> (raw)
In-Reply-To: <s5hczvnmju0.wl-tiwai@suse.de>

On Thu, Mar 25, 2021 at 9:41 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Thu, 25 Mar 2021 13:12:48 +0100,
> Kai-Heng Feng wrote:
> >
> > Rear Mic on Lenovo P620 cannot record after S3, despite that there's no
> > error and the other two functions of the USB audio, Line In and Line
> > Out, work just fine.
> >
> > The mic starts to work again after running userspace app like "alsactl
> > store". Following the lead, the evidence shows that as soon as connector
> > status is queried, the mic can work again.
> >
> > So also check connector value on resume to "wake up" the USB audio to
> > make it functional.
> >
> > This can be device specific, however I think this generic approach may
> > benefit more than one device.
> >
> > While at it, also remove reset-resume path to consolidate mixer resume
> > path.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> > ---
> > v2:
> >  - Remove reset-resume.
> >  - Fold the connector checking to the mixer resume callback.
>
> That's not what I meant exactly...  I meant to put both into the
> single resume callback, but handle each part conditionally depending
> on reset_resume argument.

OK, I get what you mean now.

>
> But this turned out to need more changes in mixer_quirks.c
> unnecessarily.  Maybe adding the two resume functions is a better
> approach in the end, but not for the specific connection thing but
> generically both resume and reset_resume callbacks.  Something like
> below.

This approach looks good. Let me send another one.

Kai-Heng

>
>
> thanks,
>
> Takashi
>
>
> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> index b004b2e63a5d..1dab281bb269 100644
> --- a/sound/usb/mixer.c
> +++ b/sound/usb/mixer.c
> @@ -3615,20 +3615,43 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
>         return 0;
>  }
>
> +static int default_mixer_resume(struct usb_mixer_elem_list *list)
> +{
> +       struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
> +
> +       /* get connector value to "wake up" the USB audio */
> +       if (cval->val_type == USB_MIXER_BOOLEAN && cval->channels == 1)
> +               get_connector_value(cval, NULL, NULL);
> +
> +       return 0;
> +}
> +
> +static int default_mixer_reset_resume(struct usb_mixer_elem_list *list)
> +{
> +       int err = default_mixer_resume(list);
> +
> +       if (err < 0)
> +               return err;
> +       return restore_mixer_value(list);
> +}
> +
>  int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
>  {
>         struct usb_mixer_elem_list *list;
> +       usb_mixer_elem_resume_func_t f;
>         int id, err;
>
> -       if (reset_resume) {
> -               /* restore cached mixer values */
> -               for (id = 0; id < MAX_ID_ELEMS; id++) {
> -                       for_each_mixer_elem(list, mixer, id) {
> -                               if (list->resume) {
> -                                       err = list->resume(list);
> -                                       if (err < 0)
> -                                               return err;
> -                               }
> +       /* restore cached mixer values */
> +       for (id = 0; id < MAX_ID_ELEMS; id++) {
> +               for_each_mixer_elem(list, mixer, id) {
> +                       if (reset_resume)
> +                               f = list->reset_resume;
> +                       else
> +                               f = list->resume;
> +                       if (f) {
> +                               err = list->resume(list);
> +                               if (err < 0)
> +                                       return err;
>                         }
>                 }
>         }
> @@ -3647,6 +3670,7 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
>         list->id = unitid;
>         list->dump = snd_usb_mixer_dump_cval;
>  #ifdef CONFIG_PM
> -       list->resume = restore_mixer_value;
> +       list->resume = default_mixer_resume;
> +       list->reset_resume = default_mixer_reset_resume;
>  #endif
>  }
> diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
> index c29e27ac43a7..e5a01f17bf3c 100644
> --- a/sound/usb/mixer.h
> +++ b/sound/usb/mixer.h
> @@ -69,6 +69,7 @@ struct usb_mixer_elem_list {
>         bool is_std_info;
>         usb_mixer_elem_dump_func_t dump;
>         usb_mixer_elem_resume_func_t resume;
> +       usb_mixer_elem_resume_func_t reset_resume;
>  };
>
>  /* iterate over mixer element list of the given unit id */
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index ffd922327ae4..b7f9c2fded05 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -151,7 +151,7 @@ static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
>                 *listp = list;
>         list->mixer = mixer;
>         list->id = id;
> -       list->resume = resume;
> +       list->reset_resume = resume;
>         kctl = snd_ctl_new1(knew, list);
>         if (!kctl) {
>                 kfree(list);

  reply	other threads:[~2021-03-25 13:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-25 12:12 [PATCH v2 1/2] ALSA: usb-audio: Carve out connector value checking into a helper Kai-Heng Feng
2021-03-25 12:12 ` Kai-Heng Feng
2021-03-25 12:12 ` [PATCH v2 2/2] ALSA: usb-audio: Check connector value on resume Kai-Heng Feng
2021-03-25 12:12   ` Kai-Heng Feng
2021-03-25 13:41   ` Takashi Iwai
2021-03-25 13:41     ` Takashi Iwai
2021-03-25 13:55     ` Kai-Heng Feng [this message]
2021-03-25 13:55       ` Kai-Heng Feng
2021-03-25 14:24       ` Kai-Heng Feng
2021-03-25 14:24         ` Kai-Heng Feng
2021-03-25 14:30         ` Takashi Iwai
2021-03-25 14:30           ` Takashi Iwai

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='CAAd53p79HSpNKu69ZM7vRGWQT+9ydf59hGH-yNMT=Ymbg2NebA@mail.gmail.com' \
    --to=kai.heng.feng@canonical.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=chiu@endlessm.com \
    --cc=joe@perches.com \
    --cc=lars@metafoo.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paskripkin@gmail.com \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    --cc=tiwai@suse.de \
    --cc=tom.ty89@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.