aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/arizona.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-15 12:27:22 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-03-03 22:01:01 -0500
commitddbce97cd1798ba4661e33662c659b168e9f51ed (patch)
tree71d0238f92143a022c973f52ba8ba9f1ca536a83 /sound/soc/codecs/arizona.c
parentf3f1163d19ebd5aa374e5df5372a8f932f2bd5f9 (diff)
ASoC: arizona: Only allow input volume updates when inputs are enabled
Since we are automatically managing the mutes we may as well also manage the volume update bits, disabling volume updates while none of the inputs are active. Since we are doing this we may as well allow the volumes to ramp together so only enable volume updates once at the end of power up. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/arizona.c')
-rw-r--r--sound/soc/codecs/arizona.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 6837863b582d..debd184cc706 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/delay.h>
13#include <linux/gcd.h> 14#include <linux/gcd.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
@@ -332,9 +333,27 @@ const struct soc_enum arizona_ng_hold =
332 4, arizona_ng_hold_text); 333 4, arizona_ng_hold_text);
333EXPORT_SYMBOL_GPL(arizona_ng_hold); 334EXPORT_SYMBOL_GPL(arizona_ng_hold);
334 335
336static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
337{
338 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
339 unsigned int val;
340 int i;
341
342 if (ena)
343 val = ARIZONA_IN_VU;
344 else
345 val = 0;
346
347 for (i = 0; i < priv->num_inputs; i++)
348 snd_soc_update_bits(codec,
349 ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
350 ARIZONA_IN_VU, val);
351}
352
335int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 353int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
336 int event) 354 int event)
337{ 355{
356 struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
338 unsigned int reg; 357 unsigned int reg;
339 358
340 if (w->shift % 2) 359 if (w->shift % 2)
@@ -343,13 +362,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); 362 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
344 363
345 switch (event) { 364 switch (event) {
365 case SND_SOC_DAPM_PRE_PMU:
366 priv->in_pending++;
367 break;
346 case SND_SOC_DAPM_POST_PMU: 368 case SND_SOC_DAPM_POST_PMU:
347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); 369 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
370
371 /* If this is the last input pending then allow VU */
372 priv->in_pending--;
373 if (priv->in_pending == 0) {
374 msleep(1);
375 arizona_in_set_vu(w->codec, 1);
376 }
348 break; 377 break;
349 case SND_SOC_DAPM_PRE_PMD: 378 case SND_SOC_DAPM_PRE_PMD:
350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 379 snd_soc_update_bits(w->codec, reg,
351 ARIZONA_IN1L_MUTE); 380 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
381 ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
352 break; 382 break;
383 case SND_SOC_DAPM_POST_PMD:
384 /* Disable volume updates if no inputs are enabled */
385 reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
386 if (reg == 0)
387 arizona_in_set_vu(w->codec, 0);
353 } 388 }
354 389
355 return 0; 390 return 0;