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

ASoC: nau8540: Add pre-charge actions for input

Adding pre-charge mechanism to make FEPGA power stable faster. It
not only improved the recording quality at the beginning but also
meaningfully decreased the final adc delay time.

Signed-off-by: David Lin <CTLIN0@nuvoton.com>
Link: https://msgid.link/r/20240116024519.24569-1-CTLIN0@nuvoton.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

David Lin and committed by
Mark Brown
9423d7b9 90050b8d

+90 -35
+78 -34
sound/soc/codecs/nau8540.c
··· 26 26 #include <sound/tlv.h> 27 27 #include "nau8540.h" 28 28 29 - 30 29 #define NAU_FREF_MAX 13500000 31 30 #define NAU_FVCO_MAX 100000000 32 31 #define NAU_FVCO_MIN 90000000 ··· 229 230 static const struct snd_kcontrol_new digital_ch1_mux = 230 231 SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum); 231 232 233 + static int nau8540_fepga_event(struct snd_soc_dapm_widget *w, 234 + struct snd_kcontrol *k, int event) 235 + { 236 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 237 + struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); 238 + 239 + switch (event) { 240 + case SND_SOC_DAPM_POST_PMU: 241 + regmap_update_bits(nau8540->regmap, NAU8540_REG_FEPGA2, 242 + NAU8540_ACDC_CTL_MASK, NAU8540_ACDC_CTL_MIC1P_VREF | 243 + NAU8540_ACDC_CTL_MIC1N_VREF | NAU8540_ACDC_CTL_MIC2P_VREF | 244 + NAU8540_ACDC_CTL_MIC2N_VREF | NAU8540_ACDC_CTL_MIC3P_VREF | 245 + NAU8540_ACDC_CTL_MIC3N_VREF | NAU8540_ACDC_CTL_MIC4P_VREF | 246 + NAU8540_ACDC_CTL_MIC4N_VREF); 247 + break; 248 + default: 249 + break; 250 + } 251 + return 0; 252 + } 253 + 254 + static int nau8540_precharge_event(struct snd_soc_dapm_widget *w, 255 + struct snd_kcontrol *k, int event) 256 + { 257 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 258 + struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); 259 + 260 + switch (event) { 261 + case SND_SOC_DAPM_POST_PMU: 262 + regmap_update_bits(nau8540->regmap, NAU8540_REG_REFERENCE, 263 + NAU8540_DISCHRG_EN, NAU8540_DISCHRG_EN); 264 + msleep(40); 265 + regmap_update_bits(nau8540->regmap, NAU8540_REG_REFERENCE, 266 + NAU8540_DISCHRG_EN, 0); 267 + regmap_update_bits(nau8540->regmap, NAU8540_REG_FEPGA2, 268 + NAU8540_ACDC_CTL_MASK, 0); 269 + break; 270 + default: 271 + break; 272 + } 273 + return 0; 274 + } 275 + 232 276 static int adc_power_control(struct snd_soc_dapm_widget *w, 233 277 struct snd_kcontrol *k, int event) 234 278 { ··· 279 237 struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); 280 238 281 239 if (SND_SOC_DAPM_EVENT_ON(event)) { 282 - msleep(300); 240 + msleep(160); 283 241 /* DO12 and DO34 pad output enable */ 242 + regmap_update_bits(nau8540->regmap, NAU8540_REG_POWER_MANAGEMENT, 243 + NAU8540_ADC_ALL_EN, NAU8540_ADC_ALL_EN); 284 244 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, 285 245 NAU8540_I2S_DO12_TRI, 0); 286 246 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, ··· 292 248 NAU8540_I2S_DO12_TRI, NAU8540_I2S_DO12_TRI); 293 249 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, 294 250 NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI); 251 + regmap_update_bits(nau8540->regmap, NAU8540_REG_POWER_MANAGEMENT, 252 + NAU8540_ADC_ALL_EN, 0); 295 253 } 296 254 return 0; 297 255 } ··· 320 274 SND_SOC_DAPM_INPUT("MIC3"), 321 275 SND_SOC_DAPM_INPUT("MIC4"), 322 276 323 - SND_SOC_DAPM_PGA("Frontend PGA1", NAU8540_REG_PWR, 12, 0, NULL, 0), 324 - SND_SOC_DAPM_PGA("Frontend PGA2", NAU8540_REG_PWR, 13, 0, NULL, 0), 325 - SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0), 326 - SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0), 277 + SND_SOC_DAPM_PGA_S("Frontend PGA1", 0, NAU8540_REG_PWR, 12, 0, 278 + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), 279 + SND_SOC_DAPM_PGA_S("Frontend PGA2", 0, NAU8540_REG_PWR, 13, 0, 280 + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), 281 + SND_SOC_DAPM_PGA_S("Frontend PGA3", 0, NAU8540_REG_PWR, 14, 0, 282 + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), 283 + SND_SOC_DAPM_PGA_S("Frontend PGA4", 0, NAU8540_REG_PWR, 15, 0, 284 + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), 327 285 328 - SND_SOC_DAPM_ADC_E("ADC1", NULL, 329 - NAU8540_REG_POWER_MANAGEMENT, 0, 0, adc_power_control, 330 - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 331 - SND_SOC_DAPM_ADC_E("ADC2", NULL, 332 - NAU8540_REG_POWER_MANAGEMENT, 1, 0, adc_power_control, 333 - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 334 - SND_SOC_DAPM_ADC_E("ADC3", NULL, 335 - NAU8540_REG_POWER_MANAGEMENT, 2, 0, adc_power_control, 336 - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 337 - SND_SOC_DAPM_ADC_E("ADC4", NULL, 338 - NAU8540_REG_POWER_MANAGEMENT, 3, 0, adc_power_control, 339 - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 286 + SND_SOC_DAPM_PGA_S("Precharge", 1, SND_SOC_NOPM, 0, 0, 287 + nau8540_precharge_event, SND_SOC_DAPM_POST_PMU), 340 288 341 - SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0), 342 - SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0), 343 - SND_SOC_DAPM_PGA("ADC CH3", NAU8540_REG_ANALOG_PWR, 2, 0, NULL, 0), 344 - SND_SOC_DAPM_PGA("ADC CH4", NAU8540_REG_ANALOG_PWR, 3, 0, NULL, 0), 289 + SND_SOC_DAPM_PGA_S("ADC CH1", 2, NAU8540_REG_ANALOG_PWR, 0, 0, 290 + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 291 + SND_SOC_DAPM_PGA_S("ADC CH2", 2, NAU8540_REG_ANALOG_PWR, 1, 0, 292 + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 293 + SND_SOC_DAPM_PGA_S("ADC CH3", 2, NAU8540_REG_ANALOG_PWR, 2, 0, 294 + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 295 + SND_SOC_DAPM_PGA_S("ADC CH4", 2, NAU8540_REG_ANALOG_PWR, 3, 0, 296 + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 345 297 346 298 SND_SOC_DAPM_MUX("Digital CH4 Mux", 347 299 SND_SOC_NOPM, 0, 0, &digital_ch4_mux), ··· 360 316 {"Frontend PGA3", NULL, "MIC3"}, 361 317 {"Frontend PGA4", NULL, "MIC4"}, 362 318 363 - {"ADC1", NULL, "Frontend PGA1"}, 364 - {"ADC2", NULL, "Frontend PGA2"}, 365 - {"ADC3", NULL, "Frontend PGA3"}, 366 - {"ADC4", NULL, "Frontend PGA4"}, 319 + {"Precharge", NULL, "Frontend PGA1"}, 320 + {"Precharge", NULL, "Frontend PGA2"}, 321 + {"Precharge", NULL, "Frontend PGA3"}, 322 + {"Precharge", NULL, "Frontend PGA4"}, 367 323 368 - {"ADC CH1", NULL, "ADC1"}, 369 - {"ADC CH2", NULL, "ADC2"}, 370 - {"ADC CH3", NULL, "ADC3"}, 371 - {"ADC CH4", NULL, "ADC4"}, 324 + {"ADC CH1", NULL, "Precharge"}, 325 + {"ADC CH2", NULL, "Precharge"}, 326 + {"ADC CH3", NULL, "Precharge"}, 327 + {"ADC CH4", NULL, "Precharge"}, 372 328 373 - {"ADC1", NULL, "MICBIAS1"}, 374 - {"ADC2", NULL, "MICBIAS1"}, 375 - {"ADC3", NULL, "MICBIAS2"}, 376 - {"ADC4", NULL, "MICBIAS2"}, 329 + {"ADC CH1", NULL, "MICBIAS1"}, 330 + {"ADC CH2", NULL, "MICBIAS1"}, 331 + {"ADC CH3", NULL, "MICBIAS2"}, 332 + {"ADC CH4", NULL, "MICBIAS2"}, 377 333 378 334 {"Digital CH1 Mux", "ADC channel 1", "ADC CH1"}, 379 335 {"Digital CH1 Mux", "ADC channel 2", "ADC CH2"},
+12 -1
sound/soc/codecs/nau8540.h
··· 78 78 79 79 80 80 /* POWER_MANAGEMENT (0x01) */ 81 + #define NAU8540_ADC_ALL_EN 0xf 81 82 #define NAU8540_ADC4_EN (0x1 << 3) 82 83 #define NAU8540_ADC3_EN (0x1 << 2) 83 84 #define NAU8540_ADC2_EN (0x1 << 1) ··· 203 202 /* REFERENCE (0x68) */ 204 203 #define NAU8540_PRECHARGE_DIS (0x1 << 13) 205 204 #define NAU8540_GLOBAL_BIAS_EN (0x1 << 12) 205 + #define NAU8540_DISCHRG_EN (0x1 << 11) 206 206 207 207 /* FEPGA1 (0x69) */ 208 208 #define NAU8540_FEPGA1_MODCH2_SHT_SFT 7 ··· 216 214 #define NAU8540_FEPGA2_MODCH4_SHT (0x1 << NAU8540_FEPGA2_MODCH4_SHT_SFT) 217 215 #define NAU8540_FEPGA2_MODCH3_SHT_SFT 3 218 216 #define NAU8540_FEPGA2_MODCH3_SHT (0x1 << NAU8540_FEPGA2_MODCH3_SHT_SFT) 219 - 217 + #define NAU8540_ACDC_CTL_SFT 8 218 + #define NAU8540_ACDC_CTL_MASK (0xff << NAU8540_ACDC_CTL_SFT) 219 + #define NAU8540_ACDC_CTL_MIC4N_VREF (0x1 << 15) 220 + #define NAU8540_ACDC_CTL_MIC4P_VREF (0x1 << 14) 221 + #define NAU8540_ACDC_CTL_MIC3N_VREF (0x1 << 13) 222 + #define NAU8540_ACDC_CTL_MIC3P_VREF (0x1 << 12) 223 + #define NAU8540_ACDC_CTL_MIC2N_VREF (0x1 << 11) 224 + #define NAU8540_ACDC_CTL_MIC2P_VREF (0x1 << 10) 225 + #define NAU8540_ACDC_CTL_MIC1N_VREF (0x1 << 9) 226 + #define NAU8540_ACDC_CTL_MIC1P_VREF (0x1 << 8) 220 227 221 228 /* System Clock Source */ 222 229 enum {