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 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)