On 17/12/2025 14:06, Peter Ujfalusi wrote:
In 'normal' controls the mc->min is the minimum value the register can have, the mc->max is the maximum (the steps between are max - min).
SX types are defined differently: mc->min is the minimum value and the mc->max is the steps.
The max parameter of soc_mixer_reg_to_ctl() is the number of steps in either type.
To have correct register value range in clamp the maximum value that needs to be used is mc->min + max, which will be equal to mc->max for 'normal' controls and mc->min + mc->max for SX ones.
The original clamp broke SX controls and rendered some of them impossible to even set, like the cs42l43's Headphone Digital Volume, where the min is smaller than the max (min=283, max=229 - 229 steps starting from
when the min is bigger than the max, sorry, will resend with corrected message
val 283).
The soc_mixer_ctl_to_reg() correctly uses the max parameter instead of mc->max, so storing the value was correct.
Fixes: a0ce874cfaaa ("ASoC: ops: improve snd_soc_get_volsw") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com
sound/soc/soc-ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index ce86978c158d..6a18c56a9746 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -148,7 +148,7 @@ static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_v if (mc->sign_bit) val = sign_extend32(val, mc->sign_bit);
- val = clamp(val, mc->min, mc->max);
- val = clamp(val, mc->min, mc->min + max); val -= mc->min;
if (mc->invert)