Commit 37768e39 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mark Brown

ASoC: ssm2602: Fix ADC powerup sequencing

According to the ssm2603 data sheet (control register sequencing), the
digital core should be activated only after all necessary bits in the
power register are enabled, and a delay determined by the decoupling
capacitor on the VMID pin has passed. If the digital core is activated
too early, or even before the ADC is powered up, audible artifacts
appear at the beginning of the recorded signal.

The digital core is also needed for playback, so when recording starts
it may already be enabled. This means we cannot get the power sequence
correct when we want to be able to start recording after playback.

As a workaround put the MIC mute switch into the DAPM routes. This
way we can keep the recording disabled until the MIC Bias has settled
and thus get rid of audible artifacts.
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
m.felsch@pengutronix.de: adapt commit message
m.felsch@pengutronix.de: drop of configuration as mentioned by Mark:
			 https://patchwork.kernel.org/patch/10407449/Signed-off-by: default avatarMarco Felsch <m.felsch@pengutronix.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent cf17a5ff
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -111,7 +112,6 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1, ...@@ -111,7 +112,6 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1,
SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0), SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0), SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0),
SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
}; };
/* Output Mixer */ /* Output Mixer */
...@@ -121,10 +121,31 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0), ...@@ -121,10 +121,31 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0), SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
}; };
static const struct snd_kcontrol_new mic_ctl =
SOC_DAPM_SINGLE("Switch", SSM2602_APANA, 1, 1, 1);
/* Input mux */ /* Input mux */
static const struct snd_kcontrol_new ssm2602_input_mux_controls = static const struct snd_kcontrol_new ssm2602_input_mux_controls =
SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]); SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
static int ssm2602_mic_switch_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
/*
* According to the ssm2603 data sheet (control register sequencing),
* the digital core should be activated only after all necessary bits
* in the power register are enabled, and a delay determined by the
* decoupling capacitor on the VMID pin has passed. If the digital core
* is activated too early, or even before the ADC is powered up, audible
* artifacts appear at the beginning and end of the recorded signal.
*
* In practice, audible artifacts disappear well over 500 ms.
*/
msleep(500);
return 0;
}
static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = { static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = {
SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1), SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
...@@ -146,6 +167,9 @@ SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1, ...@@ -146,6 +167,9 @@ SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls), SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1), SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
SND_SOC_DAPM_SWITCH_E("Mic Switch", SSM2602_APANA, 1, 1, &mic_ctl,
ssm2602_mic_switch_event, SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_OUTPUT("LHPOUT"), SND_SOC_DAPM_OUTPUT("LHPOUT"),
SND_SOC_DAPM_OUTPUT("RHPOUT"), SND_SOC_DAPM_OUTPUT("RHPOUT"),
SND_SOC_DAPM_INPUT("MICIN"), SND_SOC_DAPM_INPUT("MICIN"),
...@@ -178,9 +202,11 @@ static const struct snd_soc_dapm_route ssm2602_routes[] = { ...@@ -178,9 +202,11 @@ static const struct snd_soc_dapm_route ssm2602_routes[] = {
{"LHPOUT", NULL, "Output Mixer"}, {"LHPOUT", NULL, "Output Mixer"},
{"Input Mux", "Line", "Line Input"}, {"Input Mux", "Line", "Line Input"},
{"Input Mux", "Mic", "Mic Bias"}, {"Input Mux", "Mic", "Mic Switch"},
{"ADC", NULL, "Input Mux"}, {"ADC", NULL, "Input Mux"},
{"Mic Switch", NULL, "Mic Bias"},
{"Mic Bias", NULL, "MICIN"}, {"Mic Bias", NULL, "MICIN"},
}; };
......
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