[PATCH] ASoC: codecs: ak4458: only perform reset if any bits actually changed
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@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; }
participants (2)
-
Mark Brown
-
Martin Pietryka