aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320dac33.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>2010-12-10 06:26:31 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-12-10 17:50:12 -0500
commita6cea9655bfa821dbf53c6fffb9b2b99fe77367c (patch)
tree3124cf31d0952b1a773dbc64999d2e6fa23b84c8 /sound/soc/codecs/tlv320dac33.c
parent23ac3b61331137355064d8b22a3624fe1cd8527a (diff)
ASoC: tlv320dac33: Power down digital parts, when not needed
If the following scenario has been followed: 1. Enable analog bypass amixer sset 'Analog Left Bypass' on amixer sset 'Analog Right Bypass' on 2. Start playback aplay -fdat -d3 /dev/zero After the playback stopped (3 sec), and the soc timeout (5 sec), the digital parts of the codec will remain powered up. This means that the DAI clocks are continue to run, the oscillator remain operational, etc. Use the SND_SOC_DAPM_POST_PMD widget to get notification about the stopped stream, and power down the digital part of the codec. If the analog bypass is enabled, than the codec will remain in BIAS_ON level, and things will work correctly. In case, if the bypass is disabled, than the codec will fall to BIAS_STANDBY than to BIAS_OFF level, as it used to. The digital part of DAC33 is initialized at every stream start (DAPM_PRE:PRE_PMU event), so subsequent streams (within 5 sec) will have working DAI. When the codec is coming out from BIAS_OFF, the full power-up sequence followed by the same DAPM_PRE widget event will power up the digital part. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/tlv320dac33.c')
-rw-r--r--sound/soc/codecs/tlv320dac33.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index b3445b362e96..776ac80cc1a8 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -354,6 +354,21 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
354 dac33_write(codec, DAC33_PWR_CTRL, reg); 354 dac33_write(codec, DAC33_PWR_CTRL, reg);
355} 355}
356 356
357static inline void dac33_disable_digital(struct snd_soc_codec *codec)
358{
359 u8 reg;
360
361 /* Stop the DAI clock */
362 reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
363 reg &= ~DAC33_BCLKON;
364 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
365
366 /* Power down the Oscillator, and DACs */
367 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
368 reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
369 dac33_write(codec, DAC33_PWR_CTRL, reg);
370}
371
357static int dac33_hard_power(struct snd_soc_codec *codec, int power) 372static int dac33_hard_power(struct snd_soc_codec *codec, int power)
358{ 373{
359 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 374 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
@@ -402,7 +417,7 @@ exit:
402 return ret; 417 return ret;
403} 418}
404 419
405static int playback_event(struct snd_soc_dapm_widget *w, 420static int dac33_playback_event(struct snd_soc_dapm_widget *w,
406 struct snd_kcontrol *kcontrol, int event) 421 struct snd_kcontrol *kcontrol, int event)
407{ 422{
408 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec); 423 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
@@ -414,6 +429,9 @@ static int playback_event(struct snd_soc_dapm_widget *w,
414 dac33_prepare_chip(dac33->substream); 429 dac33_prepare_chip(dac33->substream);
415 } 430 }
416 break; 431 break;
432 case SND_SOC_DAPM_POST_PMD:
433 dac33_disable_digital(w->codec);
434 break;
417 } 435 }
418 return 0; 436 return 0;
419} 437}
@@ -609,7 +627,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
609 SND_SOC_DAPM_SUPPLY("Right DAC Power", 627 SND_SOC_DAPM_SUPPLY("Right DAC Power",
610 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0), 628 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
611 629
612 SND_SOC_DAPM_PRE("Prepare Playback", playback_event), 630 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
631 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
613}; 632};
614 633
615static const struct snd_soc_dapm_route audio_map[] = { 634static const struct snd_soc_dapm_route audio_map[] = {