aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2010-05-10 07:39:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-11 04:34:11 -0400
commitd11bb4a925613fa814ed4ae350440eb24ebff336 (patch)
tree45332b4ea11ef84f6f33a7eb5a7957453de379a7 /sound/soc/soc-core.c
parent896060c76bdfd8a45eb33b3dd1a8307fe37f6c04 (diff)
ASoC: core: Fix for the volume limiting when invert is in use
If the register for the volume needs invert, than the inversion need to be done from the chip maximum, and not from the platform dependent limit. Introduce soc_mixer_control.platform_max value, which initially equals to chip maximum. The snd_soc_limit_volume function only modify the platform_max, all volsw_info call returns this as well. The .max value holds the chip default (maximum), and it is used for the inversion, if it is needed. Additional check in the volsw_info call has been added to check the validity of the platform_max in case, when custom macros used by codec drivers are not initializing it correctly. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 34f71bf60140..e1043f644730 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2017,18 +2017,22 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
2017{ 2017{
2018 struct soc_mixer_control *mc = 2018 struct soc_mixer_control *mc =
2019 (struct soc_mixer_control *)kcontrol->private_value; 2019 (struct soc_mixer_control *)kcontrol->private_value;
2020 int max = mc->max; 2020 int platform_max;
2021 unsigned int shift = mc->shift; 2021 unsigned int shift = mc->shift;
2022 unsigned int rshift = mc->rshift; 2022 unsigned int rshift = mc->rshift;
2023 2023
2024 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) 2024 if (!mc->platform_max)
2025 mc->platform_max = mc->max;
2026 platform_max = mc->platform_max;
2027
2028 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
2025 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2029 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2026 else 2030 else
2027 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2031 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2028 2032
2029 uinfo->count = shift == rshift ? 1 : 2; 2033 uinfo->count = shift == rshift ? 1 : 2;
2030 uinfo->value.integer.min = 0; 2034 uinfo->value.integer.min = 0;
2031 uinfo->value.integer.max = max; 2035 uinfo->value.integer.max = platform_max;
2032 return 0; 2036 return 0;
2033} 2037}
2034EXPORT_SYMBOL_GPL(snd_soc_info_volsw); 2038EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
@@ -2126,16 +2130,20 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
2126{ 2130{
2127 struct soc_mixer_control *mc = 2131 struct soc_mixer_control *mc =
2128 (struct soc_mixer_control *)kcontrol->private_value; 2132 (struct soc_mixer_control *)kcontrol->private_value;
2129 int max = mc->max; 2133 int platform_max;
2130 2134
2131 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) 2135 if (!mc->platform_max)
2136 mc->platform_max = mc->max;
2137 platform_max = mc->platform_max;
2138
2139 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
2132 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2140 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2133 else 2141 else
2134 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2142 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2135 2143
2136 uinfo->count = 2; 2144 uinfo->count = 2;
2137 uinfo->value.integer.min = 0; 2145 uinfo->value.integer.min = 0;
2138 uinfo->value.integer.max = max; 2146 uinfo->value.integer.max = platform_max;
2139 return 0; 2147 return 0;
2140} 2148}
2141EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); 2149EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
@@ -2236,13 +2244,17 @@ int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
2236{ 2244{
2237 struct soc_mixer_control *mc = 2245 struct soc_mixer_control *mc =
2238 (struct soc_mixer_control *)kcontrol->private_value; 2246 (struct soc_mixer_control *)kcontrol->private_value;
2239 int max = mc->max; 2247 int platform_max;
2240 int min = mc->min; 2248 int min = mc->min;
2241 2249
2250 if (!mc->platform_max)
2251 mc->platform_max = mc->max;
2252 platform_max = mc->platform_max;
2253
2242 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2254 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2243 uinfo->count = 2; 2255 uinfo->count = 2;
2244 uinfo->value.integer.min = 0; 2256 uinfo->value.integer.min = 0;
2245 uinfo->value.integer.max = max-min; 2257 uinfo->value.integer.max = platform_max - min;
2246 return 0; 2258 return 0;
2247} 2259}
2248EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); 2260EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
@@ -2331,7 +2343,7 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
2331 if (found) { 2343 if (found) {
2332 mc = (struct soc_mixer_control *)kctl->private_value; 2344 mc = (struct soc_mixer_control *)kctl->private_value;
2333 if (max <= mc->max) { 2345 if (max <= mc->max) {
2334 mc->max = max; 2346 mc->platform_max = max;
2335 ret = 0; 2347 ret = 0;
2336 } 2348 }
2337 } 2349 }