[PATCH] ASoC: codecs: ak4458: only perform reset if any bits actually changed

Martin Pietryka martin.pietryka at streamunlimited.com
Wed Sep 14 16:11:46 CEST 2022


This reduces the amount of small audio artifacts that happen when a reset
is performed as documented in the data-sheet.

Signed-off-by: Martin Pietryka <martin.pietryka at streamunlimited.com>
---
 sound/soc/codecs/ak4458.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index ea33cc83c86c..741c2b69d238 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -349,6 +349,7 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
 	int pcm_width = max(params_physical_width(params), ak4458->slot_width);
 	u8 format, dsdsel0, dsdsel1, dchn;
 	int nfs1, dsd_bclk, ret, channels, channels_max;
+	int needs_reset = 0;
 
 	nfs1 = params_rate(params);
 	ak4458->fs = nfs1;
@@ -391,15 +392,16 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
 			return -EINVAL;
 		}
 
-		snd_soc_component_update_bits(component, AK4458_06_DSD1,
-					      AK4458_DSDSEL_MASK, dsdsel0);
-		snd_soc_component_update_bits(component, AK4458_09_DSD2,
-					      AK4458_DSDSEL_MASK, dsdsel1);
+		needs_reset |= snd_soc_component_update_bits(component, AK4458_06_DSD1,
+							     AK4458_DSDSEL_MASK, dsdsel0);
+		needs_reset |= snd_soc_component_update_bits(component, AK4458_09_DSD2,
+							     AK4458_DSDSEL_MASK, dsdsel1);
 		break;
 	}
 
 	/* Master Clock Frequency Auto Setting Mode Enable */
-	snd_soc_component_update_bits(component, AK4458_00_CONTROL1, 0x80, 0x80);
+	needs_reset |= snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+						     0x80, 0x80);
 
 	switch (pcm_width) {
 	case 16:
@@ -433,8 +435,8 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
-			    AK4458_DIF_MASK, format);
+	needs_reset |= snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+						     AK4458_DIF_MASK, format);
 
 	/*
 	 * Enable/disable Daisy Chain if in TDM mode and the number of played
@@ -444,16 +446,18 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
 		(ak4458->fmt == SND_SOC_DAIFMT_DSP_B) &&
 		(channels > channels_max) ? AK4458_DCHAIN_MASK : 0;
 
-	snd_soc_component_update_bits(component, AK4458_0B_CONTROL7,
-				      AK4458_DCHAIN_MASK, dchn);
+	needs_reset |= snd_soc_component_update_bits(component, AK4458_0B_CONTROL7,
+						     AK4458_DCHAIN_MASK, dchn);
 
-	ret = ak4458_rstn_control(component, 0);
-	if (ret)
-		return ret;
+	if (needs_reset) {
+		ret = ak4458_rstn_control(component, 0);
+		if (ret)
+			return ret;
 
-	ret = ak4458_rstn_control(component, 1);
-	if (ret)
-		return ret;
+		ret = ak4458_rstn_control(component, 1);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
-- 
2.37.3



More information about the Alsa-devel mailing list