forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/codecs/nau8810.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * nau8810.c -- NAU8810 ALSA Soc Audio driver
34 *
....@@ -6,10 +7,6 @@
67 * Author: David Lin <ctlin0@nuvoton.com>
78 *
89 * Based on WM8974.c
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License version 2 as
12
- * published by the Free Software Foundation.
1310 */
1411
1512 #include <linux/module.h>
....@@ -358,6 +355,8 @@
358355
359356 /* Speaker Output Mixer */
360357 static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
358
+ SOC_DAPM_SINGLE("AUX Bypass Switch", NAU8810_REG_SPKMIX,
359
+ NAU8810_AUXSPK_SFT, 1, 0),
361360 SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX,
362361 NAU8810_BYPSPK_SFT, 1, 0),
363362 SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX,
....@@ -366,6 +365,8 @@
366365
367366 /* Mono Output Mixer */
368367 static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
368
+ SOC_DAPM_SINGLE("AUX Bypass Switch", NAU8810_REG_MONOMIX,
369
+ NAU8810_AUXMOUT_SFT, 1, 0),
369370 SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX,
370371 NAU8810_BYPMOUT_SFT, 1, 0),
371372 SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX,
....@@ -374,6 +375,8 @@
374375
375376 /* PGA Mute */
376377 static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = {
378
+ SOC_DAPM_SINGLE("AUX PGA Switch", NAU8810_REG_ADCBOOST,
379
+ NAU8810_AUXBSTGAIN_SFT, 0x7, 0),
377380 SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
378381 NAU8810_PGAMT_SFT, 1, 1),
379382 SOC_DAPM_SINGLE("PMIC PGA Switch", NAU8810_REG_ADCBOOST,
....@@ -382,6 +385,8 @@
382385
383386 /* Input PGA */
384387 static const struct snd_kcontrol_new nau8810_inpga[] = {
388
+ SOC_DAPM_SINGLE("AUX Switch", NAU8810_REG_INPUT_SIGNAL,
389
+ NAU8810_AUXPGA_SFT, 1, 0),
385390 SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL,
386391 NAU8810_NMICPGA_SFT, 1, 0),
387392 SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL,
....@@ -402,6 +407,23 @@
402407
403408 regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &value);
404409 return (value & NAU8810_CLKM_MASK);
410
+}
411
+
412
+static int check_mic_enabled(struct snd_soc_dapm_widget *source,
413
+ struct snd_soc_dapm_widget *sink)
414
+{
415
+ struct snd_soc_component *component =
416
+ snd_soc_dapm_to_component(source->dapm);
417
+ struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
418
+ unsigned int value;
419
+
420
+ regmap_read(nau8810->regmap, NAU8810_REG_INPUT_SIGNAL, &value);
421
+ if (value & NAU8810_PMICPGA_EN || value & NAU8810_NMICPGA_EN)
422
+ return 1;
423
+ regmap_read(nau8810->regmap, NAU8810_REG_ADCBOOST, &value);
424
+ if (value & NAU8810_PMICBSTGAIN_MASK)
425
+ return 1;
426
+ return 0;
405427 }
406428
407429 static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
....@@ -428,6 +450,8 @@
428450 SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
429451 NAU8810_BST_EN_SFT, 0, nau8810_pgaboost_mixer_controls,
430452 ARRAY_SIZE(nau8810_pgaboost_mixer_controls)),
453
+ SND_SOC_DAPM_PGA("AUX Input", NAU8810_REG_POWER1,
454
+ NAU8810_AUX_EN_SFT, 0, NULL, 0),
431455
432456 SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
433457 NAU8810_MICBIAS_EN_SFT, 0, NULL, 0),
....@@ -437,6 +461,7 @@
437461 SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
438462 &nau8810_loopback),
439463
464
+ SND_SOC_DAPM_INPUT("AUX"),
440465 SND_SOC_DAPM_INPUT("MICN"),
441466 SND_SOC_DAPM_INPUT("MICP"),
442467 SND_SOC_DAPM_OUTPUT("MONOOUT"),
....@@ -448,10 +473,12 @@
448473 {"DAC", NULL, "PLL", check_mclk_select_pll},
449474
450475 /* Mono output mixer */
476
+ {"Mono Mixer", "AUX Bypass Switch", "AUX Input"},
451477 {"Mono Mixer", "PCM Playback Switch", "DAC"},
452478 {"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"},
453479
454480 /* Speaker output mixer */
481
+ {"Speaker Mixer", "AUX Bypass Switch", "AUX Input"},
455482 {"Speaker Mixer", "PCM Playback Switch", "DAC"},
456483 {"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"},
457484
....@@ -466,13 +493,16 @@
466493 /* Input Boost Stage */
467494 {"ADC", NULL, "Input Boost Stage"},
468495 {"ADC", NULL, "PLL", check_mclk_select_pll},
496
+ {"Input Boost Stage", "AUX PGA Switch", "AUX Input"},
469497 {"Input Boost Stage", "PGA Mute Switch", "Input PGA"},
470498 {"Input Boost Stage", "PMIC PGA Switch", "MICP"},
471499
472500 /* Input PGA */
473
- {"Input PGA", NULL, "Mic Bias"},
501
+ {"Input PGA", NULL, "Mic Bias", check_mic_enabled},
502
+ {"Input PGA", "AUX Switch", "AUX Input"},
474503 {"Input PGA", "MicN Switch", "MICN"},
475504 {"Input PGA", "MicP Switch", "MICP"},
505
+ {"AUX Input", NULL, "AUX"},
476506
477507 /* Digital Looptack */
478508 {"Digital Loopback", "Switch", "ADC"},
....@@ -493,7 +523,7 @@
493523 return 0;
494524 }
495525
496
-static int nau88l0_calc_pll(unsigned int pll_in,
526
+static int nau8810_calc_pll(unsigned int pll_in,
497527 unsigned int fs, struct nau8810_pll *pll_param)
498528 {
499529 u64 f2, f2_max, pll_ratio;
....@@ -505,7 +535,8 @@
505535 f2_max = 0;
506536 scal_sel = ARRAY_SIZE(nau8810_mclk_scaler);
507537 for (i = 0; i < ARRAY_SIZE(nau8810_mclk_scaler); i++) {
508
- f2 = 256 * fs * 4 * nau8810_mclk_scaler[i] / 10;
538
+ f2 = 256ULL * fs * 4 * nau8810_mclk_scaler[i];
539
+ f2 = div_u64(f2, 10);
509540 if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX &&
510541 f2_max < f2) {
511542 f2_max = f2;
....@@ -542,7 +573,7 @@
542573 int ret, fs;
543574
544575 fs = freq_out / 256;
545
- ret = nau88l0_calc_pll(freq_in, fs, pll_param);
576
+ ret = nau8810_calc_pll(freq_in, fs, pll_param);
546577 if (ret < 0) {
547578 dev_err(nau8810->dev, "Unsupported input clock %d\n", freq_in);
548579 return ret;
....@@ -667,6 +698,24 @@
667698 struct snd_soc_component *component = dai->component;
668699 struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
669700 int val_len = 0, val_rate = 0, ret = 0;
701
+ unsigned int ctrl_val, bclk_fs, bclk_div;
702
+
703
+ /* Select BCLK configuration if the codec as master. */
704
+ regmap_read(nau8810->regmap, NAU8810_REG_CLOCK, &ctrl_val);
705
+ if (ctrl_val & NAU8810_CLKIO_MASTER) {
706
+ /* get the bclk and fs ratio */
707
+ bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params);
708
+ if (bclk_fs <= 32)
709
+ bclk_div = NAU8810_BCLKDIV_8;
710
+ else if (bclk_fs <= 64)
711
+ bclk_div = NAU8810_BCLKDIV_4;
712
+ else if (bclk_fs <= 128)
713
+ bclk_div = NAU8810_BCLKDIV_2;
714
+ else
715
+ return -EINVAL;
716
+ regmap_update_bits(nau8810->regmap, NAU8810_REG_CLOCK,
717
+ NAU8810_BCLKSEL_MASK, bclk_div);
718
+ }
670719
671720 switch (params_width(params)) {
672721 case 16:
....@@ -846,6 +895,8 @@
846895
847896 static const struct i2c_device_id nau8810_i2c_id[] = {
848897 { "nau8810", 0 },
898
+ { "nau8812", 0 },
899
+ { "nau8814", 0 },
849900 { }
850901 };
851902 MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
....@@ -853,6 +904,8 @@
853904 #ifdef CONFIG_OF
854905 static const struct of_device_id nau8810_of_match[] = {
855906 { .compatible = "nuvoton,nau8810", },
907
+ { .compatible = "nuvoton,nau8812", },
908
+ { .compatible = "nuvoton,nau8814", },
856909 { }
857910 };
858911 MODULE_DEVICE_TABLE(of, nau8810_of_match);