]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: tas2562: Volume setting fixes
authorMark Brown <broonie@kernel.org>
Sun, 19 Jul 2026 21:06:01 +0000 (22:06 +0100)
committerMark Brown <broonie@kernel.org>
Sun, 19 Jul 2026 21:06:01 +0000 (22:06 +0100)
Mark Brown <broonie@kernel.org> says:

While reviewing another fix for the tas2562 volume control I noticed a
few issues with the put() operation, this series fixes them.

It's also a bit weird that the volume control is defined with twice as
many values as can actually be set, probably the best fix there is to
regnerate the table of volume values with the intermediate values.

Link: https://patch.msgid.link/20260715-asoc-tas2562-put-retval-v1-0-97bf467c924e@kernel.org
1  2 
sound/soc/codecs/tas2562.c

index cdd695c3807edbb7c3a0a03f5f799ce811c448ab,e5fba2195a2444c449f234712ea92982d3dae47c..0b8644ad74f13dbe1fc9c26107d8f576a7c401ab
@@@ -472,19 -471,23 +472,27 @@@ static int tas2562_volume_control_put(s
  {
        struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
        struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
-       int ret;
+       int ret, index;
        u32 reg_val;
  
-       reg_val = float_vol_db_lookup[ucontrol->value.integer.value[0]/2];
+       if (tas2562->volume_lvl == ucontrol->value.integer.value[0])
+               return 0;
+       index = ucontrol->value.integer.value[0] / 2;
+       if (index < 0 || index >= ARRAY_SIZE(float_vol_db_lookup))
+               return -EINVAL;
+       reg_val = float_vol_db_lookup[index];
 -      ret = snd_soc_component_write(component, TAS2562_DVC_CFG4,
 -                                    (reg_val & 0xff));
 -      if (ret)
 -              return ret;
 -      ret = snd_soc_component_write(component, TAS2562_DVC_CFG3,
 -                                    ((reg_val >> 8) & 0xff));
++
 +      /*
 +       * The device applies the 32-bit coefficient to the playback path on
 +       * the write to DVC_CFG4 (the LSB, book 0 page 2 reg 0x0F), so the
 +       * bytes must be written MSB first and DVC_CFG4 last. Writing CFG4
 +       * first latches a mix of the previous coefficient's upper bytes and
 +       * the new LSB instead of the requested value.
 +       */
 +      ret = snd_soc_component_write(component, TAS2562_DVC_CFG1,
 +                                    ((reg_val >> 24) & 0xff));
        if (ret)
                return ret;
        ret = snd_soc_component_write(component, TAS2562_DVC_CFG2,