ALSA controls should return 1 if the value in the control changed but the
control put operation micfil_quality_set() only returns 0 or a negative
error code, causing ALSA to not generate any change events.

Add a suitable check in the function before updating the quality variable.

Also enable pm runtime before calling the function micfil_set_quality()
to make the regmap cache data align with the value in hardware.

Fixes: bea1d61d5892 ("ASoC: fsl_micfil: rework quality setting")
Signed-off-by: Shengjiu Wang <[email protected]>
---
 sound/soc/fsl/fsl_micfil.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 983805bbaae2..2e887f1f1f36 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -289,10 +289,34 @@ static int micfil_quality_set(struct snd_kcontrol 
*kcontrol,
 {
        struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
        struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt);
+       int val = ucontrol->value.integer.value[0];
+       bool change = false;
+       int old_val;
+       int ret;
+
+       if (val < QUALITY_HIGH || val > QUALITY_VLOW2)
+               return -EINVAL;
+
+       if (micfil->quality != val) {
+               ret = pm_runtime_resume_and_get(cmpnt->dev);
+               if (ret)
+                       return ret;
+
+               old_val = micfil->quality;
+               micfil->quality = val;
+               ret = micfil_set_quality(micfil);
 
-       micfil->quality = ucontrol->value.integer.value[0];
+               pm_runtime_put_autosuspend(cmpnt->dev);
 
-       return micfil_set_quality(micfil);
+               if (ret) {
+                       micfil->quality = old_val;
+                       return ret;
+               }
+
+               change = true;
+       }
+
+       return change;
 }
 
 static const char * const micfil_hwvad_enable[] = {
-- 
2.34.1


Reply via email to