aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320dac33.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320dac33.c')
-rw-r--r--sound/soc/codecs/tlv320dac33.c57
1 files changed, 42 insertions, 15 deletions
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index ccb267f4e968..776ac80cc1a8 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -315,8 +315,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
315 clock source = internal osc (?) */ 315 clock source = internal osc (?) */
316 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN); 316 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
317 317
318 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
319
320 /* Restore only selected registers (gains mostly) */ 318 /* Restore only selected registers (gains mostly) */
321 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL, 319 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
322 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL)); 320 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
@@ -356,6 +354,21 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
356 dac33_write(codec, DAC33_PWR_CTRL, reg); 354 dac33_write(codec, DAC33_PWR_CTRL, reg);
357} 355}
358 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
359static int dac33_hard_power(struct snd_soc_codec *codec, int power) 372static int dac33_hard_power(struct snd_soc_codec *codec, int power)
360{ 373{
361 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 374 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
@@ -404,7 +417,7 @@ exit:
404 return ret; 417 return ret;
405} 418}
406 419
407static int playback_event(struct snd_soc_dapm_widget *w, 420static int dac33_playback_event(struct snd_soc_dapm_widget *w,
408 struct snd_kcontrol *kcontrol, int event) 421 struct snd_kcontrol *kcontrol, int event)
409{ 422{
410 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec); 423 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
@@ -416,6 +429,9 @@ static int playback_event(struct snd_soc_dapm_widget *w,
416 dac33_prepare_chip(dac33->substream); 429 dac33_prepare_chip(dac33->substream);
417 } 430 }
418 break; 431 break;
432 case SND_SOC_DAPM_POST_PMD:
433 dac33_disable_digital(w->codec);
434 break;
419 } 435 }
420 return 0; 436 return 0;
421} 437}
@@ -592,8 +608,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
592 SND_SOC_DAPM_INPUT("LINEL"), 608 SND_SOC_DAPM_INPUT("LINEL"),
593 SND_SOC_DAPM_INPUT("LINER"), 609 SND_SOC_DAPM_INPUT("LINER"),
594 610
595 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0), 611 SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
596 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0), 612 SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
597 613
598 /* Analog bypass */ 614 /* Analog bypass */
599 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0, 615 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
@@ -601,12 +617,18 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
601 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0, 617 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
602 &dac33_dapm_abypassr_control), 618 &dac33_dapm_abypassr_control),
603 619
604 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power", 620 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
605 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 621 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
606 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 622 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
607 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 623 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
608 624
609 SND_SOC_DAPM_PRE("Prepare Playback", playback_event), 625 SND_SOC_DAPM_SUPPLY("Left DAC Power",
626 DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
627 SND_SOC_DAPM_SUPPLY("Right DAC Power",
628 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
629
630 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
631 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
610}; 632};
611 633
612static const struct snd_soc_dapm_route audio_map[] = { 634static const struct snd_soc_dapm_route audio_map[] = {
@@ -614,15 +636,18 @@ static const struct snd_soc_dapm_route audio_map[] = {
614 {"Analog Left Bypass", "Switch", "LINEL"}, 636 {"Analog Left Bypass", "Switch", "LINEL"},
615 {"Analog Right Bypass", "Switch", "LINER"}, 637 {"Analog Right Bypass", "Switch", "LINER"},
616 638
617 {"Output Left Amp Power", NULL, "DACL"}, 639 {"Output Left Amplifier", NULL, "DACL"},
618 {"Output Right Amp Power", NULL, "DACR"}, 640 {"Output Right Amplifier", NULL, "DACR"},
641
642 {"Output Left Amplifier", NULL, "Analog Left Bypass"},
643 {"Output Right Amplifier", NULL, "Analog Right Bypass"},
619 644
620 {"Output Left Amp Power", NULL, "Analog Left Bypass"}, 645 {"Output Left Amplifier", NULL, "Left DAC Power"},
621 {"Output Right Amp Power", NULL, "Analog Right Bypass"}, 646 {"Output Right Amplifier", NULL, "Right DAC Power"},
622 647
623 /* output */ 648 /* output */
624 {"LEFT_LO", NULL, "Output Left Amp Power"}, 649 {"LEFT_LO", NULL, "Output Left Amplifier"},
625 {"RIGHT_LO", NULL, "Output Right Amp Power"}, 650 {"RIGHT_LO", NULL, "Output Right Amplifier"},
626}; 651};
627 652
628static int dac33_add_widgets(struct snd_soc_codec *codec) 653static int dac33_add_widgets(struct snd_soc_codec *codec)
@@ -640,11 +665,13 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
640static int dac33_set_bias_level(struct snd_soc_codec *codec, 665static int dac33_set_bias_level(struct snd_soc_codec *codec,
641 enum snd_soc_bias_level level) 666 enum snd_soc_bias_level level)
642{ 667{
668 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
643 int ret; 669 int ret;
644 670
645 switch (level) { 671 switch (level) {
646 case SND_SOC_BIAS_ON: 672 case SND_SOC_BIAS_ON:
647 dac33_soft_power(codec, 1); 673 if (!dac33->substream)
674 dac33_soft_power(codec, 1);
648 break; 675 break;
649 case SND_SOC_BIAS_PREPARE: 676 case SND_SOC_BIAS_PREPARE:
650 break; 677 break;