Commit fcd274a3 authored by Lopez Cruz, Misael's avatar Lopez Cruz, Misael Committed by Mark Brown

ASoC: TWL4030: Add VDL analog bypass

This patch adds voice downlink analog bypass switch. It follows
the same approach as in other analog bypass switches.
DAC switch is moved from 'DAC Voice' to 'Analog Voice Playback Mixer',
that will also allow voice DAC to be powered in digital voice
loopback (sidetone).
Signed-off-by: default avatarMisael Lopez Cruz <x0052729@ti.com>
Acked-by: default avatarPeter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 4072604b
...@@ -468,6 +468,10 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control = ...@@ -468,6 +468,10 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control =
static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control =
SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0); SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0);
/* Analog bypass for Voice */
static const struct snd_kcontrol_new twl4030_dapm_abypassv_control =
SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0);
/* Digital bypass gain, 0 mutes the bypass */ /* Digital bypass gain, 0 mutes the bypass */
static const unsigned int twl4030_dapm_dbypass_tlv[] = { static const unsigned int twl4030_dapm_dbypass_tlv[] = {
TLV_DB_RANGE_HEAD(2), TLV_DB_RANGE_HEAD(2),
...@@ -585,7 +589,7 @@ static int bypass_event(struct snd_soc_dapm_widget *w, ...@@ -585,7 +589,7 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
struct soc_mixer_control *m = struct soc_mixer_control *m =
(struct soc_mixer_control *)w->kcontrols->private_value; (struct soc_mixer_control *)w->kcontrols->private_value;
struct twl4030_priv *twl4030 = w->codec->private_data; struct twl4030_priv *twl4030 = w->codec->private_data;
unsigned char reg; unsigned char reg, misc;
reg = twl4030_read_reg_cache(w->codec, m->reg); reg = twl4030_read_reg_cache(w->codec, m->reg);
...@@ -597,14 +601,28 @@ static int bypass_event(struct snd_soc_dapm_widget *w, ...@@ -597,14 +601,28 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
else else
twl4030->bypass_state &= twl4030->bypass_state &=
~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
} else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
/* Analog voice bypass */
if (reg & (1 << m->shift))
twl4030->bypass_state |= (1 << 4);
else
twl4030->bypass_state &= ~(1 << 4);
} else { } else {
/* Digital bypass */ /* Digital bypass */
if (reg & (0x7 << m->shift)) if (reg & (0x7 << m->shift))
twl4030->bypass_state |= (1 << (m->shift ? 5 : 4)); twl4030->bypass_state |= (1 << (m->shift ? 6 : 5));
else else
twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4)); twl4030->bypass_state &= ~(1 << (m->shift ? 6 : 5));
} }
/* Enable master analog loopback mode if any analog switch is enabled*/
misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
if (twl4030->bypass_state & 0x1F)
misc |= TWL4030_FMLOOP_EN;
else
misc &= ~TWL4030_FMLOOP_EN;
twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
if (twl4030->bypass_state) if (twl4030->bypass_state)
twl4030_codec_mute(w->codec, 0); twl4030_codec_mute(w->codec, 0);
...@@ -935,7 +953,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { ...@@ -935,7 +953,7 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
SND_SOC_NOPM, 0, 0), SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback", SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
TWL4030_REG_AVDAC_CTL, 4, 0), SND_SOC_NOPM, 0, 0),
/* Analog PGAs */ /* Analog PGAs */
SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
...@@ -962,6 +980,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { ...@@ -962,6 +980,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_abypassl2_control, &twl4030_dapm_abypassl2_control,
bypass_event, SND_SOC_DAPM_POST_REG), bypass_event, SND_SOC_DAPM_POST_REG),
SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_abypassv_control,
bypass_event, SND_SOC_DAPM_POST_REG),
/* Digital bypasses */ /* Digital bypasses */
SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
...@@ -979,6 +1000,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { ...@@ -979,6 +1000,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
2, 0, NULL, 0), 2, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
3, 0, NULL, 0), 3, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", TWL4030_REG_AVDAC_CTL,
4, 0, NULL, 0),
/* Output MIXER controls */ /* Output MIXER controls */
/* Earpiece */ /* Earpiece */
...@@ -1067,13 +1090,13 @@ static const struct snd_soc_dapm_route intercon[] = { ...@@ -1067,13 +1090,13 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Analog R1 Playback Mixer", NULL, "DAC Right1"}, {"Analog R1 Playback Mixer", NULL, "DAC Right1"},
{"Analog L2 Playback Mixer", NULL, "DAC Left2"}, {"Analog L2 Playback Mixer", NULL, "DAC Left2"},
{"Analog R2 Playback Mixer", NULL, "DAC Right2"}, {"Analog R2 Playback Mixer", NULL, "DAC Right2"},
{"Analog Voice Playback Mixer", NULL, "DAC Voice"},
{"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"}, {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"},
{"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"}, {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"},
{"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"},
{"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"},
{"VDL_APGA", NULL, "Analog Voice Playback Mixer"},
{"VDL_APGA", NULL, "DAC Voice"},
/* Internal playback routings */ /* Internal playback routings */
/* Earpiece */ /* Earpiece */
...@@ -1169,11 +1192,13 @@ static const struct snd_soc_dapm_route intercon[] = { ...@@ -1169,11 +1192,13 @@ static const struct snd_soc_dapm_route intercon[] = {
{"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"},
{"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"},
{"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"},
{"Voice Analog Loopback", "Switch", "Analog Left Capture Route"},
{"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
{"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
{"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
{"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"}, {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"},
{"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"},
/* Digital bypass routes */ /* Digital bypass routes */
{"Right Digital Loopback", "Volume", "TX1 Capture Route"}, {"Right Digital Loopback", "Volume", "TX1 Capture Route"},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment