diff options
author | Simon Trimmer <simont@opensource.cirrus.com> | 2022-11-23 16:58:11 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-11-23 17:03:10 +0000 |
commit | 7406bdbc4fb8b99cf0150cb2056a585c95ceafe7 (patch) | |
tree | 8341ab9a91a2b4972e21c50970b9176cba3b6d34 /sound | |
parent | c56f4b2442d33bd94c418697f753271099384bee (diff) |
ASoC: wm_adsp: Return whether changed when writing controls
Functions that update cs_dsp controls need to handle return codes that
indicate whether the control value changed. A return code of 1 indicates
a change, 0 indicates no-change and a negative value is an error
condition.
Acked controls implicitly change value when written so a successful
write shall always report that the value changed.
Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20221123165811.3014472-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 8a2e9771bb50..9f77f5a241ab 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -19,6 +19,7 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> +#include <linux/vmalloc.h> #include <linux/workqueue.h> #include <linux/debugfs.h> #include <sound/core.h> @@ -419,16 +420,21 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, (struct soc_bytes_ext *)kctl->private_value; struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + void *scratch; int ret = 0; - mutex_lock(&cs_ctl->dsp->pwr_lock); + scratch = vmalloc(size); + if (!scratch) + return -ENOMEM; - if (copy_from_user(cs_ctl->cache, bytes, size)) + if (copy_from_user(scratch, bytes, size)) { ret = -EFAULT; - else - ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, cs_ctl->cache, size); - - mutex_unlock(&cs_ctl->dsp->pwr_lock); + } else { + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, scratch, size); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + } + vfree(scratch); return ret; } @@ -455,7 +461,10 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl, mutex_unlock(&cs_ctl->dsp->pwr_lock); - return ret; + if (ret < 0) + return ret; + + return 1; } static int wm_coeff_get(struct snd_kcontrol *kctl, @@ -682,10 +691,10 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, int ret; ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); - if (ret) + if (ret < 0) return ret; - if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + if (ret == 0 || (cs_ctl->flags & WMFW_CTL_FLAG_SYS)) return 0; ctl = cs_ctl->priv; |