ASoC: Add info callback for SX_TLV controls
Subsystems (3)
PATCH 1/1 ASoC: Add info callback for SX_TLV controls
SX_TLV controls are intended for situations where the register behind the control has some non-zero value indicating the minimum gain and then gains increasing from there and eventually overflowing through zero.
Currently every CODEC implementing these controls specifies the minimum as the non-zero value for the minimum and the maximum as the number of gain settings available.
This means when the info callback subtracts the minimum value from the maximum value to calculate the number of gain levels available it is actually under reporting the available levels. This patch fixes this issue by adding a new snd_soc_info_volsw_sx callback that does not subtract the minimum value.
--- include/sound/soc.h | 6 ++++-- sound/soc/soc-ops.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-)
include/sound/soc.h +4 -2
@@ -86,7 +86,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .tlv.p = (tlv_array),\ - .info = snd_soc_info_volsw, \ + .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx,\ .put = snd_soc_put_volsw_sx, \ .private_value = (unsigned long)&(struct soc_mixer_control) \
@@ -156,7 +156,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, \ + .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx, \ .put = snd_soc_put_volsw_sx, \ .private_value = (unsigned long)&(struct soc_mixer_control) \
@@ -593,6 +593,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);int snd_soc_info_volsw (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo); +int snd_soc_info_volsw_sx (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo);#define snd_soc_info_bool_ext snd_ctl_boolean_mono_infoint snd_soc_get_volsw (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol);
sound/soc/soc-ops.c +28 -0
@@ -207,6 +207,34 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,EXPORT_SYMBOL_GPL (snd_soc_info_volsw);/** +* snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls +* @kcontrol: mixer control +* @uinfo: control element information +* +* Callback to provide information about a single mixer control, or a double +* mixer control that spans 2 registers of the SX TLV type. SX TLV controls +* have a range that represents both positive and negative values either side +* of zero but without a sign bit. +* +* Returns 0 for success. +*/ +int snd_soc_info_volsw_sx (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ +struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + +snd_soc_info_volsw (kcontrol, uinfo); +/* Max represents the number of levels in an SX control not the +* maximum value, so add the minimum value back on +*/ + uinfo->value.integer.max += mc->min; + +return 0 ; +} +EXPORT_SYMBOL_GPL (snd_soc_info_volsw_sx); + +/** * snd_soc_get_volsw - single mixer get callback * @kcontrol: mixer control * @ucontrol: control element information
Signature · 1 line
1.7.2.5
Quoted 15 lines · Charles Keepax
SX_TLVcontrols are intended for situations where the register behind the control has some non-zero value indicating the minimum gain and then gains increasing from there and eventually overflowing through zero.Currently every CODEC implementing these controls specifies the minimum as the non-zero value for the minimum and the maximum as the number of gain settings available.
This means when the info callback subtracts the minimum value from the maximum value to calculate the number of gain levels available it is actually under reporting the available levels. This patch fixes this issue by adding a new
snd_soc_info_volsw_sxcallback that does not subtract the minimum value.
Quoted 3 lines
Fixes 1d99f2436d0d ("ASoC: core: Rework SOC_DOUBLE_R_SX_TLV add SOC_SINGLE_SX_TLV")Signed-off-by Charles Keepax <[email protected]>---
Thank you sir!
Quoted 15 lines
SX_TLVcontrols are intended for situations where the register behind the control has some non-zero value indicating the minimum gain and then gains increasing from there and eventually overflowing through zero.Currently every CODEC implementing these controls specifies the minimum as the non-zero value for the minimum and the maximum as the number of gain settings available.
This means when the info callback subtracts the minimum value from the maximum value to calculate the number of gain levels available it is actually under reporting the available levels. This patch fixes this issue by adding a new
snd_soc_info_volsw_sxcallback that does not subtract the minimum value.
Quoted 3 lines
Fixes 1d99f2436d0d ("ASoC: core: Rework SOC_DOUBLE_R_SX_TLV add SOC_SINGLE_SX_TLV")Signed-off-by Charles Keepax <[email protected]>---
Scales correctly on CS42L73 'Headphone Analog Playback Volume'
Mark Brown
maintainerApplied "ASoC: Add info callback for SX_TLV controls" to the asoc tree
In reply to Charles KeepaxThe patch
ASoC: Add info callback for SX_TLV controls
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
34198710f55b5f359f43e67d9a08fe5aadfbca1bMon Sep 17 00:00:00 2001
From: Charles Keepax <[email protected]>
Date: Wed, 14 Oct 2015 13:31:24 +0100
Subject: [PATCH] ASoC: Add info callback for SX_TLV controls
SX_TLV controls are intended for situations where the register behind the control has some non-zero value indicating the minimum gain and then gains increasing from there and eventually overflowing through zero.
Currently every CODEC implementing these controls specifies the minimum as the non-zero value for the minimum and the maximum as the number of gain settings available.
This means when the info callback subtracts the minimum value from the maximum value to calculate the number of gain levels available it is actually under reporting the available levels. This patch fixes this issue by adding a new snd_soc_info_volsw_sx callback that does not subtract the minimum value.
--- include/sound/soc.h | 6 ++++-- sound/soc/soc-ops.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-)
include/sound/soc.h +4 -2
@@ -86,7 +86,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .tlv.p = (tlv_array),\ - .info = snd_soc_info_volsw, \ + .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx,\ .put = snd_soc_put_volsw_sx, \ .private_value = (unsigned long)&(struct soc_mixer_control) \
@@ -156,7 +156,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ SNDRV_CTL_ELEM_ACCESS_READWRITE, \ .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, \ + .info = snd_soc_info_volsw_sx, \ .get = snd_soc_get_volsw_sx, \ .put = snd_soc_put_volsw_sx, \ .private_value = (unsigned long)&(struct soc_mixer_control) \
@@ -574,6 +574,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);int snd_soc_info_volsw (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo); +int snd_soc_info_volsw_sx (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo);#define snd_soc_info_bool_ext snd_ctl_boolean_mono_infoint snd_soc_get_volsw (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol);
sound/soc/soc-ops.c +28 -0
@@ -207,6 +207,34 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,EXPORT_SYMBOL_GPL (snd_soc_info_volsw);/** +* snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls +* @kcontrol: mixer control +* @uinfo: control element information +* +* Callback to provide information about a single mixer control, or a double +* mixer control that spans 2 registers of the SX TLV type. SX TLV controls +* have a range that represents both positive and negative values either side +* of zero but without a sign bit. +* +* Returns 0 for success. +*/ +int snd_soc_info_volsw_sx (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_info *uinfo) +{ +struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + +snd_soc_info_volsw (kcontrol, uinfo); +/* Max represents the number of levels in an SX control not the +* maximum value, so add the minimum value back on +*/ + uinfo->value.integer.max += mc->min; + +return 0 ; +} +EXPORT_SYMBOL_GPL (snd_soc_info_volsw_sx); + +/** * snd_soc_get_volsw - single mixer get callback * @kcontrol: mixer control * @ucontrol: control element information
Signature · 1 line
2.6.1