|
@@ -315,8 +315,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
|
|
clock source = internal osc (?) */
|
|
clock source = internal osc (?) */
|
|
dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
|
|
dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
|
|
|
|
|
|
- dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
|
|
|
|
-
|
|
|
|
/* Restore only selected registers (gains mostly) */
|
|
/* Restore only selected registers (gains mostly) */
|
|
dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
|
|
dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
|
|
dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
|
|
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)
|
|
dac33_write(codec, DAC33_PWR_CTRL, reg);
|
|
dac33_write(codec, DAC33_PWR_CTRL, reg);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void dac33_disable_digital(struct snd_soc_codec *codec)
|
|
|
|
+{
|
|
|
|
+ u8 reg;
|
|
|
|
+
|
|
|
|
+ /* Stop the DAI clock */
|
|
|
|
+ reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
|
|
|
|
+ reg &= ~DAC33_BCLKON;
|
|
|
|
+ dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
|
|
|
|
+
|
|
|
|
+ /* Power down the Oscillator, and DACs */
|
|
|
|
+ reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
|
|
|
|
+ reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
|
|
|
|
+ dac33_write(codec, DAC33_PWR_CTRL, reg);
|
|
|
|
+}
|
|
|
|
+
|
|
static int dac33_hard_power(struct snd_soc_codec *codec, int power)
|
|
static int dac33_hard_power(struct snd_soc_codec *codec, int power)
|
|
{
|
|
{
|
|
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
|
|
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
|
|
@@ -404,7 +417,7 @@ exit:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static int playback_event(struct snd_soc_dapm_widget *w,
|
|
|
|
|
|
+static int dac33_playback_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *kcontrol, int event)
|
|
struct snd_kcontrol *kcontrol, int event)
|
|
{
|
|
{
|
|
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
|
|
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,
|
|
dac33_prepare_chip(dac33->substream);
|
|
dac33_prepare_chip(dac33->substream);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case SND_SOC_DAPM_POST_PMD:
|
|
|
|
+ dac33_disable_digital(w->codec);
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -592,8 +608,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
|
|
SND_SOC_DAPM_INPUT("LINEL"),
|
|
SND_SOC_DAPM_INPUT("LINEL"),
|
|
SND_SOC_DAPM_INPUT("LINER"),
|
|
SND_SOC_DAPM_INPUT("LINER"),
|
|
|
|
|
|
- SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
|
|
|
|
- SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
|
|
|
|
|
|
+ SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
|
|
|
|
+ SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
|
|
|
|
|
|
/* Analog bypass */
|
|
/* Analog bypass */
|
|
SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
|
|
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[] = {
|
|
SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
|
|
SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
|
|
&dac33_dapm_abypassr_control),
|
|
&dac33_dapm_abypassr_control),
|
|
|
|
|
|
- SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
|
|
|
|
|
|
+ SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
|
|
DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
|
|
DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
|
|
- SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
|
|
|
|
|
|
+ SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
|
|
DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
|
|
DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
|
|
|
|
|
|
- SND_SOC_DAPM_PRE("Prepare Playback", playback_event),
|
|
|
|
|
|
+ SND_SOC_DAPM_SUPPLY("Left DAC Power",
|
|
|
|
+ DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
|
|
|
|
+ SND_SOC_DAPM_SUPPLY("Right DAC Power",
|
|
|
|
+ DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
|
|
|
|
+
|
|
|
|
+ SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
|
|
|
|
+ SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
|
|
};
|
|
};
|
|
|
|
|
|
static const struct snd_soc_dapm_route audio_map[] = {
|
|
static const struct snd_soc_dapm_route audio_map[] = {
|
|
@@ -614,15 +636,18 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|
{"Analog Left Bypass", "Switch", "LINEL"},
|
|
{"Analog Left Bypass", "Switch", "LINEL"},
|
|
{"Analog Right Bypass", "Switch", "LINER"},
|
|
{"Analog Right Bypass", "Switch", "LINER"},
|
|
|
|
|
|
- {"Output Left Amp Power", NULL, "DACL"},
|
|
|
|
- {"Output Right Amp Power", NULL, "DACR"},
|
|
|
|
|
|
+ {"Output Left Amplifier", NULL, "DACL"},
|
|
|
|
+ {"Output Right Amplifier", NULL, "DACR"},
|
|
|
|
+
|
|
|
|
+ {"Output Left Amplifier", NULL, "Analog Left Bypass"},
|
|
|
|
+ {"Output Right Amplifier", NULL, "Analog Right Bypass"},
|
|
|
|
|
|
- {"Output Left Amp Power", NULL, "Analog Left Bypass"},
|
|
|
|
- {"Output Right Amp Power", NULL, "Analog Right Bypass"},
|
|
|
|
|
|
+ {"Output Left Amplifier", NULL, "Left DAC Power"},
|
|
|
|
+ {"Output Right Amplifier", NULL, "Right DAC Power"},
|
|
|
|
|
|
/* output */
|
|
/* output */
|
|
- {"LEFT_LO", NULL, "Output Left Amp Power"},
|
|
|
|
- {"RIGHT_LO", NULL, "Output Right Amp Power"},
|
|
|
|
|
|
+ {"LEFT_LO", NULL, "Output Left Amplifier"},
|
|
|
|
+ {"RIGHT_LO", NULL, "Output Right Amplifier"},
|
|
};
|
|
};
|
|
|
|
|
|
static int dac33_add_widgets(struct snd_soc_codec *codec)
|
|
static int dac33_add_widgets(struct snd_soc_codec *codec)
|
|
@@ -640,11 +665,13 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
|
|
static int dac33_set_bias_level(struct snd_soc_codec *codec,
|
|
static int dac33_set_bias_level(struct snd_soc_codec *codec,
|
|
enum snd_soc_bias_level level)
|
|
enum snd_soc_bias_level level)
|
|
{
|
|
{
|
|
|
|
+ struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
switch (level) {
|
|
switch (level) {
|
|
case SND_SOC_BIAS_ON:
|
|
case SND_SOC_BIAS_ON:
|
|
- dac33_soft_power(codec, 1);
|
|
|
|
|
|
+ if (!dac33->substream)
|
|
|
|
+ dac33_soft_power(codec, 1);
|
|
break;
|
|
break;
|
|
case SND_SOC_BIAS_PREPARE:
|
|
case SND_SOC_BIAS_PREPARE:
|
|
break;
|
|
break;
|