[alsa-devel] [PATCH] ASoC: adau17x1: Implemented safeload support
From: Danny Smith dannys@axis.com
Safeload support has been implemented which is used when updating for instance filter parameters using alsa controls. Without safeload support audio can become distorted during update.
Signed-off-by: Danny Smith dannys@axis.com Signed-off-by: Robert Rosengren robertr@axis.com --- sound/soc/codecs/adau17x1.c | 69 +++++++++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/adau17x1.h | 1 + 2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 57169b8ff14e..342ed0e04b1d 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -26,6 +26,10 @@ #include "adau17x1.h" #include "adau-utils.h"
+#define ADAU17X1_SAFELOAD_TARGET_ADDRESS 0x0006 +#define ADAU17X1_SAFELOAD_TRIGGER 0x0007 +#define ADAU17X1_SAFELOAD_DATA(i) (0x0001 + (i)) + static const char * const adau17x1_capture_mixer_boost_text[] = { "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3", }; @@ -326,6 +330,18 @@ bool adau17x1_has_dsp(struct adau *adau) } EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
+bool adau17x1_has_safeload(struct adau *adau) +{ + switch (adau->type) { + case ADAU1761: + case ADAU1781: + return true; + default: + return false; + } +} +EXPORT_SYMBOL_GPL(adau17x1_has_safeload); + static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { @@ -957,6 +973,50 @@ int adau17x1_resume(struct snd_soc_component *component) } EXPORT_SYMBOL_GPL(adau17x1_resume);
+static int adau17x1_safeload(struct sigmadsp *sigmadsp, unsigned int addr, + const uint8_t bytes[], size_t len) +{ + uint8_t buf[4]; + unsigned int i; + int ret; + + /* target address is offset by 1 */ + unsigned int addr_offset = addr - 1; + + /* write safeload addresses */ + for (i = 0; i < len / 4; i++) { + memcpy(buf, bytes + i * 4, 4); + ret = regmap_raw_write(sigmadsp->control_data, + ADAU17X1_SAFELOAD_DATA(i), buf, 4); + if (ret < 0) + return ret; + } + + /* write target address */ + buf[0] = (addr_offset >> 24) & 0xff; + buf[1] = (addr_offset >> 16) & 0xff; + buf[2] = (addr_offset >> 8) & 0xff; + buf[3] = (addr_offset) & 0xff; + ret = regmap_raw_write(sigmadsp->control_data, + ADAU17X1_SAFELOAD_TARGET_ADDRESS, buf, 4); + if (ret < 0) + return ret; + + /* write nbr of words to trigger address */ + buf[0] = 0x00; + buf[1] = 0x00; + buf[2] = 0x00; + buf[3] = i & 0xff; + ret = regmap_raw_write(sigmadsp->control_data, + ADAU17X1_SAFELOAD_TRIGGER, buf, 4); + + return ret; +} + +static const struct sigmadsp_ops adau17x1_sigmadsp_ops = { + .safeload = adau17x1_safeload, +}; + int adau17x1_probe(struct device *dev, struct regmap *regmap, enum adau17x1_type type, void (*switch_mode)(struct device *dev), const char *firmware_name) @@ -1002,8 +1062,13 @@ int adau17x1_probe(struct device *dev, struct regmap *regmap, dev_set_drvdata(dev, adau);
if (firmware_name) { - adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap, NULL, - firmware_name); + if (adau17x1_has_safeload(adau)) { + adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap, + &adau17x1_sigmadsp_ops, firmware_name); + } else { + adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap, + NULL, firmware_name); + } if (IS_ERR(adau->sigmadsp)) { dev_warn(dev, "Could not find firmware file: %ld\n", PTR_ERR(adau->sigmadsp)); diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index e6fe87beec07..8efa2df81c49 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h @@ -71,6 +71,7 @@ extern const struct snd_soc_dai_ops adau17x1_dai_ops; int adau17x1_setup_firmware(struct snd_soc_component *component, unsigned int rate); bool adau17x1_has_dsp(struct adau *adau); +bool adau17x1_has_safeload(struct adau *adau);
#define ADAU17X1_CLOCK_CONTROL 0x4000 #define ADAU17X1_PLL_CONTROL 0x4002
On Fri, Aug 10, 2018 at 08:07:56AM +0200, Robert Rosengren wrote:
+bool adau17x1_has_safeload(struct adau *adau) +{
- switch (adau->type) {
- case ADAU1761:
- case ADAU1781:
return true;
- default:
return false;
- }
+} +EXPORT_SYMBOL_GPL(adau17x1_has_safeload);
Why is this exported - what are the intended users?
On 08/10/2018 12:55 PM, Mark Brown wrote:
On Fri, Aug 10, 2018 at 08:07:56AM +0200, Robert Rosengren wrote:
+bool adau17x1_has_safeload(struct adau *adau) +{
- switch (adau->type) {
- case ADAU1761:
- case ADAU1781:
return true;
- default:
return false;
- }
+} +EXPORT_SYMBOL_GPL(adau17x1_has_safeload);
Why is this exported - what are the intended users?
Just followed pattern for adau17x1_has_dsp and adau17x1_setup_firmware, but can't find any code using those methods either. So maybe go for static function, and provide another patch making existing two functions also static and not exported?
On 08/10/2018 01:37 PM, Robert Rosengren wrote:
On 08/10/2018 12:55 PM, Mark Brown wrote:
On Fri, Aug 10, 2018 at 08:07:56AM +0200, Robert Rosengren wrote:
+bool adau17x1_has_safeload(struct adau *adau) +{
- switch (adau->type) {
- case ADAU1761:
- case ADAU1781:
return true;
- default:
return false;
- }
+} +EXPORT_SYMBOL_GPL(adau17x1_has_safeload);
Why is this exported - what are the intended users?
Just followed pattern for adau17x1_has_dsp and adau17x1_setup_firmware, but can't find any code using those methods either. So maybe go for static function, and provide another patch making existing two functions also static and not exported?
I believe those might have been used in either adau1761.c or adau1781.c at some point. But if they are not used any longer they should be made static and none exported.
participants (3)
-
Lars-Peter Clausen
-
Mark Brown
-
Robert Rosengren