On 17/12/2025 15:42, Charles Keepax wrote:
On Wed, Dec 17, 2025 at 03:13:45PM +0200, Péter Ujfalusi wrote:
On 17/12/2025 14:47, Charles Keepax wrote:
On Wed, Dec 17, 2025 at 02:06:23PM +0200, Peter Ujfalusi wrote:
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);
This won't work, for an SX control it is perfectly valid for the value read from the register to be smaller than the minimum value specified in the control.
Hrm, so an SX control returns sort of rand() and the value have no correlation to min or max?
lol, yes exactly :-) arn't they great
The value can wrap at any random value to 0 and continue from 0 up to some value, which is the max?
Mostly correct, not any random value it wraps at the mask.
How this is in practice for the cs42l43' Headphone Digital Volume? SOC_DOUBLE_SX_TLV("Headphone Digital Volume", CS42L43_HPPATHVOL, CS42L43_AMP3_PATH_VOL_SHIFT, CS42L43_AMP4_PATH_VOL_SHIFT, 0x11B, 229, cs42l43_headphone_tlv),
min=283 max=229 shifts: 0 and 16 masks are 0x1ff
if you step 229 from 283 then you reach 0x1ff, this is the max the mask can cover.
Not quite your maths is off by one, 229 + 283 = 512 = 0x200, which is then &ed with the mask to get 0x0. Which on the cs42l43 headphones a value of 0x0->0dB. Stepping 1 back from that would give you 0x1FF->-0.5dB.
I often think of it in terms of a 2's compliement number with an implicit sign bit.
I see, but why???
Mostly because hardware people love to wind me up, I assume. But more seriously, imagine an 4-bit signed number volume control with 5 values:
0xE -> -2 -> -2dB 0xF -> -1 -> -1dB 0x0 -> 0 -> 0dB 0x1 -> 1 -> 1dB 0x2 -> 2 -> 2dB
Super, a very sensible control, but wait being a good hardware engineer you realise you don't need 4 bits to represent 5 values you can get away with 3 bits for that and save like 2 gates resulting in an ice cream and a plaque from your manager. So you drop the sign bit giving you:
0x6 -> -2dB 0x7 -> -1dB 0x0 -> 0dB 0x1 -> 1dB 0x2 -> 2dB
I must say, wow. Being a SW guy I would probably done this differently: 0x0 -> -2dB 0x1 -> -1dB 0x2 -> 0dB 0x3 -> 1dB 0x4 -> 2dB
This then results in an SX control with a minimum of 0x6 and a mask of 0x7.
then the comment at info() is hard to match still.
static const DECLARE_TLV_DB_RANGE(sx_thing, 6, 7, TLV_DB_SCALE_ITEM(-2000, -1000, 0), 0, 2, TLV_DB_SCALE_ITEM(0, 1000, 0) };
is sort of the same, no?
Thanks for the explanation, fascinating!
On Wed, Dec 17, 2025 at 04:31:37PM +0200, Péter Ujfalusi wrote:
On 17/12/2025 15:42, Charles Keepax wrote:
On Wed, Dec 17, 2025 at 03:13:45PM +0200, Péter Ujfalusi wrote:
On 17/12/2025 14:47, Charles Keepax wrote:
On Wed, Dec 17, 2025 at 02:06:23PM +0200, Peter Ujfalusi wrote:
you drop the sign bit giving you:
0x6 -> -2dB 0x7 -> -1dB 0x0 -> 0dB 0x1 -> 1dB 0x2 -> 2dB
I must say, wow. Being a SW guy I would probably done this differently: 0x0 -> -2dB 0x1 -> -1dB 0x2 -> 0dB 0x3 -> 1dB 0x4 -> 2dB
Yes that is exactly what I would have done too :-) but then that is probably why we arn't hardware guys, would make life too easy for the software guys.
This then results in an SX control with a minimum of 0x6 and a mask of 0x7.
then the comment at info() is hard to match still.
Yeah I think the wording "min is the minimum register value" is perhaps slightly misleading. It is the register value that equates to the lowest volume, but that isn't necessarily the minimum value that can be written into the register.
If I can find a spare minute I will ping up a patch to tweak that.
static const DECLARE_TLV_DB_RANGE(sx_thing, 6, 7, TLV_DB_SCALE_ITEM(-2000, -1000, 0), 0, 2, TLV_DB_SCALE_ITEM(0, 1000, 0) };
is sort of the same, no?
Similar but some issues, I think it would let you write values that arn't valid. The control would be fairly confusing to a manual user, as the values are not strictly increasing. And I would imagine it blows up most user-space stuff, which likely also assumes all values are valid and strictly increasing.
Thanks for the explanation, fascinating!
No problem, I would be a rich man if I had a pound for each minute I have spent chasing SX control gremlins.
Thanks, Charles
linux-stable-mirror@lists.linaro.org