diff options
author | Danny Smith <dannys@axis.com> | 2018-04-09 15:13:35 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-04-13 11:39:16 +0100 |
commit | d0f8b9c5a350ca6fa842b52bfb88b77b34ee485b (patch) | |
tree | 2ef9c5ec2e63a2b6c9737de30662ffcae84e4458 /sound/soc/codecs/adau17x1.c | |
parent | 65030ff305bc9c51cb75705483bdaac7813778f0 (diff) | |
download | linux-d0f8b9c5a350ca6fa842b52bfb88b77b34ee485b.tar.gz |
ASoC: adau17x1: Handling of DSP_RUN register during fw setup
DSP_RUN needs to be disabled during firmware write otherwise
we can end up with undefined behavior if writing to a dsp which
is already running firmware.
Signed-off-by: Danny Smith <dannys@axis.com>
Signed-off-by: Robert Rosengren <robert.rosengren@axis.com>
Acked-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/adau17x1.c')
-rw-r--r-- | sound/soc/codecs/adau17x1.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 80c2a06285bb..12bf24c26818 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -502,7 +502,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream, } if (adau->sigmadsp) { - ret = adau17x1_setup_firmware(adau, params_rate(params)); + ret = adau17x1_setup_firmware(component, params_rate(params)); if (ret < 0) return ret; } @@ -835,26 +835,40 @@ bool adau17x1_volatile_register(struct device *dev, unsigned int reg) } EXPORT_SYMBOL_GPL(adau17x1_volatile_register); -int adau17x1_setup_firmware(struct adau *adau, unsigned int rate) +int adau17x1_setup_firmware(struct snd_soc_component *component, + unsigned int rate) { int ret; - int dspsr; + int dspsr, dsp_run; + struct adau *adau = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + + snd_soc_dapm_mutex_lock(dapm); ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr); if (ret) - return ret; + goto err; + + ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run); + if (ret) + goto err; regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1); regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf); + regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0); ret = sigmadsp_setup(adau->sigmadsp, rate); if (ret) { regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0); - return ret; + goto err; } regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr); + regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run); - return 0; +err: + snd_soc_dapm_mutex_unlock(dapm); + + return ret; } EXPORT_SYMBOL_GPL(adau17x1_setup_firmware); |