[alsa-devel] [PATCH - alsa-lib] tlv: Check dB range only within the control's volume range
Jaroslav Kysela
perex at perex.cz
Wed May 19 12:42:03 CEST 2010
On Wed, 19 May 2010, Peter Ujfalusi wrote:
> On Wednesday 19 May 2010 09:55:40 ext Jaroslav Kysela wrote:
>> On Wed, 19 May 2010, Peter Ujfalusi wrote:
>>> The DB_RANGE need to be used on some HW, since the gain on
>>> volume control is not continuous, and has to be divided into
>>> several sub DB_SCALE ranges.
>>> ASoC has a feature to override the HW default volume range,
>>> and in this case when the volume range is less than the
>>> HW maximum we do not need to go through the whole DB_RANGE,
>>> but we need to stop where the kcontrol's maximum tell us.
>>>
>>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi at nokia.com>
>>
>> Unfortunately, it does not look like a clean way in my eyes. If the driver
>> pushes some limits to the control (volume) range, it should do it also
>> for TLVs.
>
> My thinking was that the snd_tlv_get_dB_range SNDRV_CTL_TLVT_DB_RANGE case
> should obey the control's range provided by the driver, similarly how the
> SNDRV_CTL_TLVT_DB_SCALE is using the rangemax, rangemin.
> In case of SNDRV_CTL_TLVT_DB_RANGE, we should not go beyond the control's
> rangemax.
>
> In this way both of the following volume control is going to be handled
> correctly:
>
> 1.
> static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
>
> static const struct snd_kcontrol_new dac33_snd_controls[] = {
> SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
> DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
> 0, 0x7f, 1, dac_digivol_tlv),
> };
>
> Original range (127): -63.5 .. 0 dB
> Limited range (100): -63.5 .. -13.5 dB
>
> 2.
> static const unsigned int tpa6140_tlv[] = {
> TLV_DB_RANGE_HEAD(3),
> 0, 8, TLV_DB_SCALE_ITEM(-5900, 400, 0),
> 9, 16, TLV_DB_SCALE_ITEM(-2500, 200, 0),
> 17, 31, TLV_DB_SCALE_ITEM(-1000, 100, 0),
> };
>
> static const struct snd_kcontrol_new tpa6140a2_controls[] = {
> SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
> TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
> tpa6130a2_get_volsw, tpa6130a2_put_volsw,
> tpa6140_tlv),
> };
>
> Original range (31): -59 .. 4 dB
> Limited range (21): -59 .. -6 dB
> Limited range (16): -59 .. -11 dB
>
> In case of DB_SCALE in theory the maximum gain depends on the maximum volume
> possible on the control.
> When the gain is not linear, it has to divided into sub DB_SCALE sections to get
> accurate mapping.
> Now, if the kernel code for the limiting has to do more than changing the
> maximum volume, than it means that it _has_ to rewrite the TLV table in a clever
> way, or provide a new one which fits with the limited volume.
> Rewriting the TLV table taking into account all possible cases is not that safe,
> and I'm sure there could be still some corners, where it would fail.
>
> I think the patch provides uniform, and error prone way of handling this
> situation, while not breaking any existing parts.
I forgot that we carry the control value ranges in the DB_RANGE
container. I applied your patch to alsa-lib's GIT tree. Thanks for it and
for your detailed analysis.
Jaroslav
-----
Jaroslav Kysela <perex at perex.cz>
Linux Kernel Sound Maintainer
ALSA Project, Red Hat, Inc.
More information about the Alsa-devel
mailing list