From: Takashi Iwai tiwai@suse.de
commit 8dde723fcde4479f256441da03793e37181d9f21 upstream.
The recent fix for the resume on Lenovo machines seems causing a regression on others. It's because the change always triggers the connector selection no matter which widget node type is.
This patch addresses the regression by setting the resume callback selectively only for the connector widget.
Fixes: 44609fc01f28 ("ALSA: usb-audio: Check connector value on resume") Cc: stable@vger.kernel.org BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=213897 Link: https://lore.kernel.org/r/20210729185126.24432-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/mixer.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-)
--- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1816,6 +1816,15 @@ static void get_connector_control_name(s strlcat(name, " - Output Jack", name_size); }
+/* get connector value to "wake up" the USB audio */ +static int connector_mixer_resume(struct usb_mixer_elem_list *list) +{ + struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list); + + get_connector_value(cval, NULL, NULL); + return 0; +} + /* Build a mixer control for a UAC connector control (jack-detect) */ static void build_connector_control(struct usb_mixer_interface *mixer, const struct usbmix_name_map *imap, @@ -1833,6 +1842,10 @@ static void build_connector_control(stru if (!cval) return; snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id); + + /* set up a specific resume callback */ + cval->head.resume = connector_mixer_resume; + /* * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the * number of channels connected. @@ -3642,23 +3655,15 @@ static int restore_mixer_value(struct us 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); + int err;
- if (err < 0) - return err; + if (list->resume) { + err = list->resume(list); + if (err < 0) + return err; + } return restore_mixer_value(list); }
@@ -3697,7 +3702,7 @@ void snd_usb_mixer_elem_init_std(struct list->id = unitid; list->dump = snd_usb_mixer_dump_cval; #ifdef CONFIG_PM - list->resume = default_mixer_resume; + list->resume = NULL; list->reset_resume = default_mixer_reset_resume; #endif }