]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: SDCA: Improve mapping of Q7.8 SDCA volumes
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Wed, 25 Feb 2026 14:01:17 +0000 (14:01 +0000)
committerMark Brown <broonie@kernel.org>
Thu, 26 Feb 2026 19:16:47 +0000 (19:16 +0000)
SDCA measures volumes in 256ths of a dB, whereas ALSA measures
volumes in 100ths of a dB. Currently the SDCA volume controls are
mapped to ALSA controls by mapping the step size and working out
the number of steps for this mapped step size. Due to quantization
of the step size this means the number of steps in the ALSA
control will rarely match the number of steps in the SDCA control,
leading to skipped values and multiple values that map to the
same volume. This is not a huge problem, the volume is still
increasing and the differences will be small but it is not really
desirable.

It is simpler and more accurate to count the number of steps based on
the SDCA volume levels. This gives a 1-to-1 mapping between control
values and register volumes. The TLV is based on a minimum and maximum
volume so still accurately specifies the volume range.

Tested-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260225140118.402695-4-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sdca/sdca_asoc.c
sound/soc/soc-ops.c

index b6536eeecf58f626fc7451b04512bb431f179897..e6f7c2778bec5e4599c5ecb2def3db8bf032c5ab 100644 (file)
@@ -841,10 +841,8 @@ static int control_limit_kctl(struct device *dev,
        tlv[2] = (min * 100) >> 8;
        tlv[3] = (max * 100) >> 8;
 
-       step = (step * 100) >> 8;
-
-       mc->min = ((int)tlv[2] / step);
-       mc->max = ((int)tlv[3] / step);
+       mc->min = min / step;
+       mc->max = max / step;
        mc->shift = step;
        mc->sign_bit = 15;
        mc->sdca_q78 = 1;
index f966d4e13c7fc38b8711a44b2e188c8d377dcef3..8ae6609ca961818d7d2ae9668b31de974ceebb6e 100644 (file)
@@ -120,25 +120,17 @@ static int sdca_soc_q78_reg_to_ctl(struct soc_mixer_control *mc, unsigned int re
                return -EINVAL;
 
        val = sign_extend32(val, mc->sign_bit);
-       val = (((val * 100) >> 8) / (int)mc->shift);
-       val -= mc->min;
 
-       return val & mask;
+       return ((val / mc->shift) - mc->min) & mask;
 }
 
 static unsigned int sdca_soc_q78_ctl_to_reg(struct soc_mixer_control *mc, int val,
                                         unsigned int mask, unsigned int shift, int max)
 {
-       unsigned int ret_val;
-       int reg_val;
-
        if (WARN_ON(!mc->shift))
                return -EINVAL;
 
-       reg_val = val + mc->min;
-       ret_val = (int)((reg_val * mc->shift) << 8) / 100;
-
-       return ret_val & mask;
+       return ((val + mc->min) * mc->shift) & mask;
 }
 
 static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_val,