diff options
author | Mark Brown <broonie@kernel.org> | 2022-11-25 15:23:03 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-11-25 15:23:03 +0100 |
commit | 57405d8be4921956b8092b2e4516389bb30bdab5 (patch) | |
tree | f9760dac6d28d7acd3135aece7646da0ab52a9eb /sound | |
parent | ASoC: codecs: src4xxx-i2c: Convert to i2c's .probe_new() (diff) | |
parent | ASoC: wm_adsp: Return whether changed when writing controls (diff) | |
download | linux-57405d8be4921956b8092b2e4516389bb30bdab5.tar.xz linux-57405d8be4921956b8092b2e4516389bb30bdab5.zip |
ASoC: wm_adsp: Report when a control write changes the value
Merge series from Richard Fitzgerald <rf@opensource.cirrus.com>:
Writing a firmware control should be returning 1 if the control value
changed, so these two patches add that.
Though this is an ALSA requirement it is also useful for non-ALSA clients
of cs_dsp to know if the control value changed, so the main handling is
implemented in cs_dsp. TLV controls are specifically an ALSA thing so they
are handled specially in wm_adsp.
Simon Trimmer (2):
firmware: cs_dsp: cs_dsp_coeff_write_ctrl() should report changed
ASoC: wm_adsp: Return whether changed when writing controls
drivers/firmware/cirrus/cs_dsp.c | 17 ++++++++++++-----
sound/soc/codecs/wm_adsp.c | 27 ++++++++++++++++++---------
2 files changed, 30 insertions(+), 14 deletions(-)
--
2.30.2
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 34a94b011518..02fbffd73853 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; |