Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: max98090: Fix sequencing when starting additional routes

Enforce correct device sequencing when configuring a new
audio route when there is an existing active audio route(s).

This patch fixed recording noise issue while playback is active.

We have some registers which require the device to be in full shutdown
or to enter full shutdown before the register settings will take effect.
Currently the driver is not shutting down the device when a new audio
route is created. If a new audio route is made active while there is
already an active audio route, then the required register sequencing is
violated. A hardware shutdown toggle when creating a new audio route
corrects the sequencing error. The device must remain in hardware
shutdown for 40ms to allow the internal hardware core to fully shutdown.

Signed-off-by: Fang, Yang A <yang.a.fang@intel.com>
Signed-off-by: Sathyanarayana Nujella <sathyanarayana.nujella@intel.com>
Acked-by: Anish Kumar <anish.kumar@maximintegrated.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Fang, Yang A and committed by
Mark Brown
e5b94083 bc0195aa

+41 -6
+40 -6
sound/soc/codecs/max98090.c
··· 850 850 return 0; 851 851 } 852 852 853 + static int max98090_shdn_event(struct snd_soc_dapm_widget *w, 854 + struct snd_kcontrol *kcontrol, int event) 855 + { 856 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 857 + struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); 858 + 859 + if (event & SND_SOC_DAPM_POST_PMU) 860 + max98090->shdn_pending = true; 861 + 862 + return 0; 863 + 864 + } 865 + 853 866 static const char *mic1_mux_text[] = { "IN12", "IN56" }; 854 867 855 868 static SOC_ENUM_SINGLE_DECL(mic1_mux_enum, ··· 1171 1158 SND_SOC_DAPM_SUPPLY("SDOEN", M98090_REG_IO_CONFIGURATION, 1172 1159 M98090_SDOEN_SHIFT, 0, NULL, 0), 1173 1160 SND_SOC_DAPM_SUPPLY("DMICL_ENA", M98090_REG_DIGITAL_MIC_ENABLE, 1174 - M98090_DIGMICL_SHIFT, 0, NULL, 0), 1161 + M98090_DIGMICL_SHIFT, 0, max98090_shdn_event, 1162 + SND_SOC_DAPM_POST_PMU), 1175 1163 SND_SOC_DAPM_SUPPLY("DMICR_ENA", M98090_REG_DIGITAL_MIC_ENABLE, 1176 - M98090_DIGMICR_SHIFT, 0, NULL, 0), 1164 + M98090_DIGMICR_SHIFT, 0, max98090_shdn_event, 1165 + SND_SOC_DAPM_POST_PMU), 1177 1166 SND_SOC_DAPM_SUPPLY("AHPF", M98090_REG_FILTER_CONFIG, 1178 1167 M98090_AHPF_SHIFT, 0, NULL, 0), 1179 1168 ··· 1220 1205 &max98090_right_adc_mixer_controls[0], 1221 1206 ARRAY_SIZE(max98090_right_adc_mixer_controls)), 1222 1207 1223 - SND_SOC_DAPM_ADC("ADCL", NULL, M98090_REG_INPUT_ENABLE, 1224 - M98090_ADLEN_SHIFT, 0), 1225 - SND_SOC_DAPM_ADC("ADCR", NULL, M98090_REG_INPUT_ENABLE, 1226 - M98090_ADREN_SHIFT, 0), 1208 + SND_SOC_DAPM_ADC_E("ADCL", NULL, M98090_REG_INPUT_ENABLE, 1209 + M98090_ADLEN_SHIFT, 0, max98090_shdn_event, 1210 + SND_SOC_DAPM_POST_PMU), 1211 + SND_SOC_DAPM_ADC_E("ADCR", NULL, M98090_REG_INPUT_ENABLE, 1212 + M98090_ADREN_SHIFT, 0, max98090_shdn_event, 1213 + SND_SOC_DAPM_POST_PMU), 1227 1214 1228 1215 SND_SOC_DAPM_AIF_OUT("AIFOUTL", "HiFi Capture", 0, 1229 1216 SND_SOC_NOPM, 0, 0), ··· 2553 2536 return 0; 2554 2537 } 2555 2538 2539 + static void max98090_seq_notifier(struct snd_soc_dapm_context *dapm, 2540 + enum snd_soc_dapm_type event, int subseq) 2541 + { 2542 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); 2543 + struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); 2544 + 2545 + if (max98090->shdn_pending) { 2546 + snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, 2547 + M98090_SHDNN_MASK, 0); 2548 + msleep(40); 2549 + snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, 2550 + M98090_SHDNN_MASK, M98090_SHDNN_MASK); 2551 + max98090->shdn_pending = false; 2552 + } 2553 + } 2554 + 2556 2555 static struct snd_soc_codec_driver soc_codec_dev_max98090 = { 2557 2556 .probe = max98090_probe, 2558 2557 .remove = max98090_remove, 2558 + .seq_notifier = max98090_seq_notifier, 2559 2559 .set_bias_level = max98090_set_bias_level, 2560 2560 }; 2561 2561
+1
sound/soc/codecs/max98090.h
··· 1543 1543 unsigned int pa2en; 1544 1544 unsigned int sidetone; 1545 1545 bool master; 1546 + bool shdn_pending; 1546 1547 }; 1547 1548 1548 1549 int max98090_mic_detect(struct snd_soc_codec *codec,