All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ALSA: usb-audio: Carve out connector value checking into a helper
@ 2021-03-24 17:14 ` Kai-Heng Feng
  0 siblings, 0 replies; 8+ messages in thread
From: Kai-Heng Feng @ 2021-03-24 17:14 UTC (permalink / raw)
  To: tiwai
  Cc: Kai-Heng Feng, Jaroslav Kysela, Lars-Peter Clausen, Chris Chiu,
	Mark Brown, Joe Perches, Tom Yan, moderated list:SOUND,
	open list

This is preparation for next patch, no functional change intended.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 sound/usb/mixer.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index b004b2e63a5d..98f5417a70e4 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1446,13 +1446,11 @@ static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-/* get the connectors status and report it as boolean type */
-static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
-				   struct snd_ctl_elem_value *ucontrol)
+static int get_connector_value(struct usb_mixer_elem_info *cval,
+			       char *name, int *val)
 {
-	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	struct snd_usb_audio *chip = cval->head.mixer->chip;
-	int idx = 0, validx, ret, val;
+	int idx = 0, validx, ret;
 
 	validx = cval->control << 8 | 0;
 
@@ -1467,21 +1465,24 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
 		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
 				      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 				      validx, idx, &uac2_conn, sizeof(uac2_conn));
-		val = !!uac2_conn.bNrChannels;
+		if (val)
+			*val = !!uac2_conn.bNrChannels;
 	} else { /* UAC_VERSION_3 */
 		struct uac3_insertion_ctl_blk uac3_conn;
 
 		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
 				      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 				      validx, idx, &uac3_conn, sizeof(uac3_conn));
-		val = !!uac3_conn.bmConInserted;
+		if (val)
+			*val = !!uac3_conn.bmConInserted;
 	}
 
 	snd_usb_unlock_shutdown(chip);
 
 	if (ret < 0) {
-		if (strstr(kcontrol->id.name, "Speaker")) {
-			ucontrol->value.integer.value[0] = 1;
+		if (name && strstr(name, "Speaker")) {
+			if (val)
+				*val = 1;
 			return 0;
 		}
 error:
@@ -1491,6 +1492,21 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
 		return filter_error(cval, ret);
 	}
 
+	return ret;
+}
+
+/* get the connectors status and report it as boolean type */
+static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
+	int ret, val;
+
+	ret = get_connector_value(cval, kcontrol->id.name, &val);
+
+	if (ret)
+		return ret;
+
 	ucontrol->value.integer.value[0] = val;
 	return 0;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 1/2] ALSA: usb-audio: Carve out connector value checking into a helper
@ 2021-03-24 17:14 ` Kai-Heng Feng
  0 siblings, 0 replies; 8+ messages in thread
From: Kai-Heng Feng @ 2021-03-24 17:14 UTC (permalink / raw)
  To: tiwai
  Cc: Kai-Heng Feng, moderated list:SOUND, Lars-Peter Clausen,
	Chris Chiu, open list, Mark Brown, Joe Perches, Tom Yan

This is preparation for next patch, no functional change intended.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 sound/usb/mixer.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index b004b2e63a5d..98f5417a70e4 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1446,13 +1446,11 @@ static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-/* get the connectors status and report it as boolean type */
-static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
-				   struct snd_ctl_elem_value *ucontrol)
+static int get_connector_value(struct usb_mixer_elem_info *cval,
+			       char *name, int *val)
 {
-	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	struct snd_usb_audio *chip = cval->head.mixer->chip;
-	int idx = 0, validx, ret, val;
+	int idx = 0, validx, ret;
 
 	validx = cval->control << 8 | 0;
 
@@ -1467,21 +1465,24 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
 		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
 				      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 				      validx, idx, &uac2_conn, sizeof(uac2_conn));
-		val = !!uac2_conn.bNrChannels;
+		if (val)
+			*val = !!uac2_conn.bNrChannels;
 	} else { /* UAC_VERSION_3 */
 		struct uac3_insertion_ctl_blk uac3_conn;
 
 		ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
 				      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 				      validx, idx, &uac3_conn, sizeof(uac3_conn));
-		val = !!uac3_conn.bmConInserted;
+		if (val)
+			*val = !!uac3_conn.bmConInserted;
 	}
 
 	snd_usb_unlock_shutdown(chip);
 
 	if (ret < 0) {
-		if (strstr(kcontrol->id.name, "Speaker")) {
-			ucontrol->value.integer.value[0] = 1;
+		if (name && strstr(name, "Speaker")) {
+			if (val)
+				*val = 1;
 			return 0;
 		}
 error:
@@ -1491,6 +1492,21 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
 		return filter_error(cval, ret);
 	}
 
+	return ret;
+}
+
+/* get the connectors status and report it as boolean type */
+static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
+	int ret, val;
+
+	ret = get_connector_value(cval, kcontrol->id.name, &val);
+
+	if (ret)
+		return ret;
+
 	ucontrol->value.integer.value[0] = val;
 	return 0;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] ALSA: usb-audio: Check connector value on resume
  2021-03-24 17:14 ` Kai-Heng Feng
@ 2021-03-24 17:14   ` Kai-Heng Feng
  -1 siblings, 0 replies; 8+ messages in thread
From: Kai-Heng Feng @ 2021-03-24 17:14 UTC (permalink / raw)
  To: tiwai
  Cc: Kai-Heng Feng, Jaroslav Kysela, Lars-Peter Clausen, Chris Chiu,
	Joe Perches, Tom Yan, moderated list:SOUND, open list

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.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 sound/usb/mixer.c | 18 ++++++++++++++++++
 sound/usb/mixer.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 98f5417a70e4..6a553d891b0f 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -3631,11 +3631,28 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
 	return 0;
 }
 
+static int resume_connector(struct usb_mixer_elem_list *list)
+{
+	struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
+
+	if (cval->val_type != USB_MIXER_BOOLEAN || cval->channels != 1)
+		return 0;
+
+	return get_connector_value(cval, NULL, NULL);
+}
+
 int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
 {
 	struct usb_mixer_elem_list *list;
 	int id, err;
 
+	for (id = 0; id < MAX_ID_ELEMS; id++) {
+		for_each_mixer_elem(list, mixer, id) {
+			if (list->resume_connector)
+				list->resume_connector(list);
+		}
+	}
+
 	if (reset_resume) {
 		/* restore cached mixer values */
 		for (id = 0; id < MAX_ID_ELEMS; id++) {
@@ -3664,5 +3681,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
 	list->dump = snd_usb_mixer_dump_cval;
 #ifdef CONFIG_PM
 	list->resume = restore_mixer_value;
+	list->resume_connector = resume_connector;
 #endif
 }
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index c29e27ac43a7..843ccff0eea3 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 resume_connector;
 };
 
 /* iterate over mixer element list of the given unit id */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] ALSA: usb-audio: Check connector value on resume
@ 2021-03-24 17:14   ` Kai-Heng Feng
  0 siblings, 0 replies; 8+ messages in thread
From: Kai-Heng Feng @ 2021-03-24 17:14 UTC (permalink / raw)
  To: tiwai
  Cc: moderated list:SOUND, Lars-Peter Clausen, Chris Chiu, open list,
	Tom Yan, Kai-Heng Feng, Joe Perches

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.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 sound/usb/mixer.c | 18 ++++++++++++++++++
 sound/usb/mixer.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 98f5417a70e4..6a553d891b0f 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -3631,11 +3631,28 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
 	return 0;
 }
 
+static int resume_connector(struct usb_mixer_elem_list *list)
+{
+	struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
+
+	if (cval->val_type != USB_MIXER_BOOLEAN || cval->channels != 1)
+		return 0;
+
+	return get_connector_value(cval, NULL, NULL);
+}
+
 int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
 {
 	struct usb_mixer_elem_list *list;
 	int id, err;
 
+	for (id = 0; id < MAX_ID_ELEMS; id++) {
+		for_each_mixer_elem(list, mixer, id) {
+			if (list->resume_connector)
+				list->resume_connector(list);
+		}
+	}
+
 	if (reset_resume) {
 		/* restore cached mixer values */
 		for (id = 0; id < MAX_ID_ELEMS; id++) {
@@ -3664,5 +3681,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
 	list->dump = snd_usb_mixer_dump_cval;
 #ifdef CONFIG_PM
 	list->resume = restore_mixer_value;
+	list->resume_connector = resume_connector;
 #endif
 }
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index c29e27ac43a7..843ccff0eea3 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 resume_connector;
 };
 
 /* iterate over mixer element list of the given unit id */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] ALSA: usb-audio: Check connector value on resume
  2021-03-24 17:14   ` Kai-Heng Feng
@ 2021-03-25  7:19     ` Takashi Iwai
  -1 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2021-03-25  7:19 UTC (permalink / raw)
  To: Kai-Heng Feng
  Cc: tiwai, Jaroslav Kysela, Lars-Peter Clausen, Chris Chiu,
	Joe Perches, Tom Yan, moderated list:SOUND, open list

On Wed, 24 Mar 2021 18:14:08 +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.
> 
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>

Just to be sure: this workaround is always needed no matter whether
reset_resume is set or not?  If so, it's better to change the resume
callback to take reset_resume argument and call it always.  The
resume_connector() can be folded into there.


thanks,

Takashi

> ---
>  sound/usb/mixer.c | 18 ++++++++++++++++++
>  sound/usb/mixer.h |  1 +
>  2 files changed, 19 insertions(+)
> 
> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> index 98f5417a70e4..6a553d891b0f 100644
> --- a/sound/usb/mixer.c
> +++ b/sound/usb/mixer.c
> @@ -3631,11 +3631,28 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
>  	return 0;
>  }
>  
> +static int resume_connector(struct usb_mixer_elem_list *list)
> +{
> +	struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
> +
> +	if (cval->val_type != USB_MIXER_BOOLEAN || cval->channels != 1)
> +		return 0;
> +
> +	return get_connector_value(cval, NULL, NULL);
> +}
> +
>  int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
>  {
>  	struct usb_mixer_elem_list *list;
>  	int id, err;
>  
> +	for (id = 0; id < MAX_ID_ELEMS; id++) {
> +		for_each_mixer_elem(list, mixer, id) {
> +			if (list->resume_connector)
> +				list->resume_connector(list);
> +		}
> +	}
> +
>  	if (reset_resume) {
>  		/* restore cached mixer values */
>  		for (id = 0; id < MAX_ID_ELEMS; id++) {
> @@ -3664,5 +3681,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
>  	list->dump = snd_usb_mixer_dump_cval;
>  #ifdef CONFIG_PM
>  	list->resume = restore_mixer_value;
> +	list->resume_connector = resume_connector;
>  #endif
>  }
> diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
> index c29e27ac43a7..843ccff0eea3 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 resume_connector;
>  };
>  
>  /* iterate over mixer element list of the given unit id */
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] ALSA: usb-audio: Check connector value on resume
@ 2021-03-25  7:19     ` Takashi Iwai
  0 siblings, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2021-03-25  7:19 UTC (permalink / raw)
  To: Kai-Heng Feng
  Cc: moderated list:SOUND, Lars-Peter Clausen, open list, Chris Chiu,
	tiwai, Tom Yan, Joe Perches

On Wed, 24 Mar 2021 18:14:08 +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.
> 
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>

Just to be sure: this workaround is always needed no matter whether
reset_resume is set or not?  If so, it's better to change the resume
callback to take reset_resume argument and call it always.  The
resume_connector() can be folded into there.


thanks,

Takashi

> ---
>  sound/usb/mixer.c | 18 ++++++++++++++++++
>  sound/usb/mixer.h |  1 +
>  2 files changed, 19 insertions(+)
> 
> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> index 98f5417a70e4..6a553d891b0f 100644
> --- a/sound/usb/mixer.c
> +++ b/sound/usb/mixer.c
> @@ -3631,11 +3631,28 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
>  	return 0;
>  }
>  
> +static int resume_connector(struct usb_mixer_elem_list *list)
> +{
> +	struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
> +
> +	if (cval->val_type != USB_MIXER_BOOLEAN || cval->channels != 1)
> +		return 0;
> +
> +	return get_connector_value(cval, NULL, NULL);
> +}
> +
>  int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
>  {
>  	struct usb_mixer_elem_list *list;
>  	int id, err;
>  
> +	for (id = 0; id < MAX_ID_ELEMS; id++) {
> +		for_each_mixer_elem(list, mixer, id) {
> +			if (list->resume_connector)
> +				list->resume_connector(list);
> +		}
> +	}
> +
>  	if (reset_resume) {
>  		/* restore cached mixer values */
>  		for (id = 0; id < MAX_ID_ELEMS; id++) {
> @@ -3664,5 +3681,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
>  	list->dump = snd_usb_mixer_dump_cval;
>  #ifdef CONFIG_PM
>  	list->resume = restore_mixer_value;
> +	list->resume_connector = resume_connector;
>  #endif
>  }
> diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
> index c29e27ac43a7..843ccff0eea3 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 resume_connector;
>  };
>  
>  /* iterate over mixer element list of the given unit id */
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] ALSA: usb-audio: Check connector value on resume
  2021-03-25  7:19     ` Takashi Iwai
@ 2021-03-25  7:26       ` Kai-Heng Feng
  -1 siblings, 0 replies; 8+ messages in thread
From: Kai-Heng Feng @ 2021-03-25  7:26 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Takashi Iwai, Jaroslav Kysela, Lars-Peter Clausen, Chris Chiu,
	Joe Perches, Tom Yan, moderated list:SOUND, open list

On Thu, Mar 25, 2021 at 3:19 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Wed, 24 Mar 2021 18:14:08 +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.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
>
> Just to be sure: this workaround is always needed no matter whether
> reset_resume is set or not?

Yes, reset_resume is irrelevant for this issue. Getting connector
status is the key.

> If so, it's better to change the resume
> callback to take reset_resume argument and call it always.  The
> resume_connector() can be folded into there.

OK, will send V2.

Kai-Heng

>
>
> thanks,
>
> Takashi
>
> > ---
> >  sound/usb/mixer.c | 18 ++++++++++++++++++
> >  sound/usb/mixer.h |  1 +
> >  2 files changed, 19 insertions(+)
> >
> > diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> > index 98f5417a70e4..6a553d891b0f 100644
> > --- a/sound/usb/mixer.c
> > +++ b/sound/usb/mixer.c
> > @@ -3631,11 +3631,28 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
> >       return 0;
> >  }
> >
> > +static int resume_connector(struct usb_mixer_elem_list *list)
> > +{
> > +     struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
> > +
> > +     if (cval->val_type != USB_MIXER_BOOLEAN || cval->channels != 1)
> > +             return 0;
> > +
> > +     return get_connector_value(cval, NULL, NULL);
> > +}
> > +
> >  int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
> >  {
> >       struct usb_mixer_elem_list *list;
> >       int id, err;
> >
> > +     for (id = 0; id < MAX_ID_ELEMS; id++) {
> > +             for_each_mixer_elem(list, mixer, id) {
> > +                     if (list->resume_connector)
> > +                             list->resume_connector(list);
> > +             }
> > +     }
> > +
> >       if (reset_resume) {
> >               /* restore cached mixer values */
> >               for (id = 0; id < MAX_ID_ELEMS; id++) {
> > @@ -3664,5 +3681,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
> >       list->dump = snd_usb_mixer_dump_cval;
> >  #ifdef CONFIG_PM
> >       list->resume = restore_mixer_value;
> > +     list->resume_connector = resume_connector;
> >  #endif
> >  }
> > diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
> > index c29e27ac43a7..843ccff0eea3 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 resume_connector;
> >  };
> >
> >  /* iterate over mixer element list of the given unit id */
> > --
> > 2.30.2
> >

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] ALSA: usb-audio: Check connector value on resume
@ 2021-03-25  7:26       ` Kai-Heng Feng
  0 siblings, 0 replies; 8+ messages in thread
From: Kai-Heng Feng @ 2021-03-25  7:26 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: moderated list:SOUND, Lars-Peter Clausen, open list, Chris Chiu,
	Takashi Iwai, Tom Yan, Joe Perches

On Thu, Mar 25, 2021 at 3:19 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Wed, 24 Mar 2021 18:14:08 +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.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
>
> Just to be sure: this workaround is always needed no matter whether
> reset_resume is set or not?

Yes, reset_resume is irrelevant for this issue. Getting connector
status is the key.

> If so, it's better to change the resume
> callback to take reset_resume argument and call it always.  The
> resume_connector() can be folded into there.

OK, will send V2.

Kai-Heng

>
>
> thanks,
>
> Takashi
>
> > ---
> >  sound/usb/mixer.c | 18 ++++++++++++++++++
> >  sound/usb/mixer.h |  1 +
> >  2 files changed, 19 insertions(+)
> >
> > diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> > index 98f5417a70e4..6a553d891b0f 100644
> > --- a/sound/usb/mixer.c
> > +++ b/sound/usb/mixer.c
> > @@ -3631,11 +3631,28 @@ static int restore_mixer_value(struct usb_mixer_elem_list *list)
> >       return 0;
> >  }
> >
> > +static int resume_connector(struct usb_mixer_elem_list *list)
> > +{
> > +     struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
> > +
> > +     if (cval->val_type != USB_MIXER_BOOLEAN || cval->channels != 1)
> > +             return 0;
> > +
> > +     return get_connector_value(cval, NULL, NULL);
> > +}
> > +
> >  int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
> >  {
> >       struct usb_mixer_elem_list *list;
> >       int id, err;
> >
> > +     for (id = 0; id < MAX_ID_ELEMS; id++) {
> > +             for_each_mixer_elem(list, mixer, id) {
> > +                     if (list->resume_connector)
> > +                             list->resume_connector(list);
> > +             }
> > +     }
> > +
> >       if (reset_resume) {
> >               /* restore cached mixer values */
> >               for (id = 0; id < MAX_ID_ELEMS; id++) {
> > @@ -3664,5 +3681,6 @@ void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
> >       list->dump = snd_usb_mixer_dump_cval;
> >  #ifdef CONFIG_PM
> >       list->resume = restore_mixer_value;
> > +     list->resume_connector = resume_connector;
> >  #endif
> >  }
> > diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
> > index c29e27ac43a7..843ccff0eea3 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 resume_connector;
> >  };
> >
> >  /* iterate over mixer element list of the given unit id */
> > --
> > 2.30.2
> >

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-03-25  7:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-24 17:14 [PATCH 1/2] ALSA: usb-audio: Carve out connector value checking into a helper Kai-Heng Feng
2021-03-24 17:14 ` Kai-Heng Feng
2021-03-24 17:14 ` [PATCH 2/2] ALSA: usb-audio: Check connector value on resume Kai-Heng Feng
2021-03-24 17:14   ` Kai-Heng Feng
2021-03-25  7:19   ` Takashi Iwai
2021-03-25  7:19     ` Takashi Iwai
2021-03-25  7:26     ` Kai-Heng Feng
2021-03-25  7:26       ` Kai-Heng Feng

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.