| From 827b0913a9d9d07a0c3e559dbb20ca4d6d285a54 Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Fri, 5 Nov 2021 10:09:25 +0100 |
| Subject: ASoC: DAPM: Cover regression by kctl change notification fix |
| |
| From: Takashi Iwai <tiwai@suse.de> |
| |
| commit 827b0913a9d9d07a0c3e559dbb20ca4d6d285a54 upstream. |
| |
| The recent fix for DAPM to correct the kctl change notification by the |
| commit 5af82c81b2c4 ("ASoC: DAPM: Fix missing kctl change |
| notifications") caused other regressions since it changed the behavior |
| of snd_soc_dapm_set_pin() that is called from several API functions. |
| Formerly it returned always 0 for success, but now it returns 0 or 1. |
| |
| This patch addresses it, restoring the old behavior of |
| snd_soc_dapm_set_pin() while keeping the fix in |
| snd_soc_dapm_put_pin_switch(). |
| |
| Fixes: 5af82c81b2c4 ("ASoC: DAPM: Fix missing kctl change notifications") |
| Reported-by: Yu-Hsuan Hsu <yuhsuan@chromium.org> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Link: https://lore.kernel.org/r/20211105090925.20575-1-tiwai@suse.de |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| sound/soc/soc-dapm.c | 29 +++++++++++++++++++++++------ |
| 1 file changed, 23 insertions(+), 6 deletions(-) |
| |
| --- a/sound/soc/soc-dapm.c |
| +++ b/sound/soc/soc-dapm.c |
| @@ -2406,8 +2406,13 @@ static struct snd_soc_dapm_widget *dapm_ |
| return NULL; |
| } |
| |
| -static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, |
| - const char *pin, int status) |
| +/* |
| + * set the DAPM pin status: |
| + * returns 1 when the value has been updated, 0 when unchanged, or a negative |
| + * error code; called from kcontrol put callback |
| + */ |
| +static int __snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, |
| + const char *pin, int status) |
| { |
| struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); |
| int ret = 0; |
| @@ -2433,6 +2438,18 @@ static int snd_soc_dapm_set_pin(struct s |
| return ret; |
| } |
| |
| +/* |
| + * similar as __snd_soc_dapm_set_pin(), but returns 0 when successful; |
| + * called from several API functions below |
| + */ |
| +static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, |
| + const char *pin, int status) |
| +{ |
| + int ret = __snd_soc_dapm_set_pin(dapm, pin, status); |
| + |
| + return ret < 0 ? ret : 0; |
| +} |
| + |
| /** |
| * snd_soc_dapm_sync_unlocked - scan and power dapm paths |
| * @dapm: DAPM context |
| @@ -3327,10 +3344,10 @@ int snd_soc_dapm_put_pin_switch(struct s |
| const char *pin = (const char *)kcontrol->private_value; |
| int ret; |
| |
| - if (ucontrol->value.integer.value[0]) |
| - ret = snd_soc_dapm_enable_pin(&card->dapm, pin); |
| - else |
| - ret = snd_soc_dapm_disable_pin(&card->dapm, pin); |
| + mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
| + ret = __snd_soc_dapm_set_pin(&card->dapm, pin, |
| + !!ucontrol->value.integer.value[0]); |
| + mutex_unlock(&card->dapm_mutex); |
| |
| snd_soc_dapm_sync(&card->dapm); |
| return ret; |