ASoC: snd_soc_info_volsw and platfrom_max
Srinivas Kandagatla
srinivas.kandagatla at linaro.org
Tue Aug 16 15:44:47 CEST 2022
On 16/08/2022 14:11, Mark Brown wrote:
> On Mon, Aug 15, 2022 at 10:22:37AM +0100, Srinivas Kandagatla wrote:
>
>> before this patch the controls max value was calculated considering the min
>> value, but with this patch this calculation has changed resulting in low
>> volume on most of the codecs that are using SOC_SINGLE_S8_TLV.
>
> Right, the whole situation is unclear. At various points the code
> hasn't agreed with itself ragarding what the platform_max is relative
> to, if it's taken into account and all both within individual control
> types and also between control types.
>
>> snd_soc_put_volsw does the right thing by considering mc->min, but
>> info_volsw does it differently.
>
>> Below change fixes the issue for me, but I am bit confused with the first
>> line of this function that calculates max value as max = mc->max - mc->min
>> and then limits it to platform_max.
>
> The issue is that it's not clear if the platform_max value should be a
> value for the register or a value for the control. For some reason
> (which frankly is the source of a lot of the problems here) the controls
> adjust the user visible range to be zero based even though the ABI would
> be totally fine with any range. There were out of tree patches that
> changed things for some of the control types too.
Only Instances where platform_max is set are via kcontrol builder
macros, which then always sets this to xmax.
And none of these macros have provision to pass platform_max these are
always assumed to be xmax. Which am not sure is always correct.
>
>> diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
>> index bd88de056358..49fb34609202 100644
>> --- a/sound/soc/soc-ops.c
>> +++ b/sound/soc/soc-ops.c
>> @@ -196,7 +196,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
>>
>> uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
>> uinfo->value.integer.min = 0;
>> - uinfo->value.integer.max = max;
>> + uinfo->value.integer.max = max - mc->min;
>
> That'll then break anything that doesn't set platform_max since we'll
> apply mc->min twice, you'd need to do the adjustment at the point where
Yes, I agree.
something like this might work.
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index bd88de056358..cc3b12ace295 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -179,7 +179,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
const char *vol_string = NULL;
int max;
- max = uinfo->value.integer.max = mc->max - mc->min;
+ max = uinfo->value.integer.max = mc->max;
if (mc->platform_max && mc->platform_max < max)
max = mc->platform_max;
@@ -196,7 +196,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
uinfo->value.integer.min = 0;
- uinfo->value.integer.max = max;
+ uinfo->value.integer.max = max - mc->min;
return 0;
}
> we apply the platform_max override. Keeping platform_max a register
> value is *probably* the least bad thing here.
platform_max being a max register value seems more sensible.
But again if agree on that.
Current state of platform_max which is never set correctly if we use any
helper macros is confusing.
Do you think having an explicit macros that take platform_max argument
from drivers makes sense?
This will also bring in some clarity.
--srini
>
>> return 0;
>> }
>>
>>
>> Or should we fix the macro to set platform_max to be max - min.
>
> We shouldn't be changing the static data at all, that's one of the
> problems.
More information about the Alsa-devel
mailing list