Skip to contentSkip to conversation

ASoC: adau17x1: Implemented safeload support

PATCH Superseded Robert Rosengren 3 participants 4 messages Aug 10, 2018

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ASoC: adau17x1: Implemented safeload support

From: Danny Smith <[email protected]>

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.

---
 sound/soc/codecs/adau17x1.c | 69 +++++++++++++++++++++++++++++++++++++++++++--
 sound/soc/codecs/adau17x1.h |  1 +
 2 files changed, 68 insertions(+), 2 deletions(-)
sound/soc/codecs/adau17x1.c +67 -2
index 57169b8ff14e..342ed0e04b1d 100644
@@ -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));
sound/soc/codecs/adau17x1.h +1 -0
index e6fe87beec07..8efa2df81c49 100644
@@ -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
Signature · 1 line
2.11.0
maintainer
#1 lore raw

sound/soc/codecs/adau17x1.c bool adau17x1_has_dsp(struct adau *adau) · line 343

Quoted 11 lines · Robert Rosengren
sound/soc/codecs/adau17x1.c +11 -0
+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?

#2 lore raw
Quoted 16 lines · Mark Brown

sound/soc/codecs/adau17x1.c bool adau17x1_has_dsp(struct adau *adau) · line 343

Quoted 11 lines · Robert Rosengren
sound/soc/codecs/adau17x1.c +11 -0
+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?

#3 lore raw
Quoted 19 lines · Robert Rosengren
Quoted 16 lines · Mark Brown

sound/soc/codecs/adau17x1.c bool adau17x1_has_dsp(struct adau *adau) · line 343

Quoted 11 lines · Robert Rosengren
sound/soc/codecs/adau17x1.c +11 -0
+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?

Quoted 1 line

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.