aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Hsu <KCHSU0@nuvoton.com>2016-03-15 00:09:36 -0400
committerMark Brown <broonie@kernel.org>2016-05-30 11:17:44 -0400
commit407c71b69850aa789c70f7f7e54244739983d8d2 (patch)
tree89e366a4584052c8ac8e706d607f24a1f7c79869
parent70543c300902b35b6f8cfafa8fff857bd84e351f (diff)
ASoC: nau8825: improve FLL function for better performance
In FLL calculation, increase VCO/DCO frequency for better performance. Besides, have different register configuration according to fraction or not when apply FLL parameters. Signed-off-by: John Hsu <KCHSU0@nuvoton.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/nau8825.c47
-rw-r--r--sound/soc/codecs/nau8825.h13
2 files changed, 42 insertions, 18 deletions
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index b45ca8a32069..cb08a358b2a3 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -31,7 +31,7 @@
31#include "nau8825.h" 31#include "nau8825.h"
32 32
33#define NAU_FREF_MAX 13500000 33#define NAU_FREF_MAX 13500000
34#define NAU_FVCO_MAX 100000000 34#define NAU_FVCO_MAX 124000000
35#define NAU_FVCO_MIN 90000000 35#define NAU_FVCO_MIN 90000000
36 36
37struct nau8825_fll { 37struct nau8825_fll {
@@ -973,8 +973,8 @@ static int nau8825_codec_probe(struct snd_soc_codec *codec)
973static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs, 973static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
974 struct nau8825_fll *fll_param) 974 struct nau8825_fll *fll_param)
975{ 975{
976 u64 fvco; 976 u64 fvco, fvco_max;
977 unsigned int fref, i; 977 unsigned int fref, i, fvco_sel;
978 978
979 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing 979 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
980 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar. 980 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
@@ -999,18 +999,23 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
999 fll_param->ratio = fll_ratio[i].val; 999 fll_param->ratio = fll_ratio[i].val;
1000 1000
1001 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs. 1001 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
1002 * FDCO must be within the 90MHz - 100MHz or the FFL cannot be 1002 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be
1003 * guaranteed across the full range of operation. 1003 * guaranteed across the full range of operation.
1004 * FDCO = freq_out * 2 * mclk_src_scaling 1004 * FDCO = freq_out * 2 * mclk_src_scaling
1005 */ 1005 */
1006 fvco_max = 0;
1007 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
1006 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) { 1008 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
1007 fvco = 256 * fs * 2 * mclk_src_scaling[i].param; 1009 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
1008 if (NAU_FVCO_MIN < fvco && fvco < NAU_FVCO_MAX) 1010 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
1009 break; 1011 fvco_max < fvco) {
1012 fvco_max = fvco;
1013 fvco_sel = i;
1014 }
1010 } 1015 }
1011 if (i == ARRAY_SIZE(mclk_src_scaling)) 1016 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)
1012 return -EINVAL; 1017 return -EINVAL;
1013 fll_param->mclk_src = mclk_src_scaling[i].val; 1018 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
1014 1019
1015 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional 1020 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
1016 * input based on FDCO, FREF and FLL ratio. 1021 * input based on FDCO, FREF and FLL ratio.
@@ -1025,7 +1030,8 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
1025 struct nau8825_fll *fll_param) 1030 struct nau8825_fll *fll_param)
1026{ 1031{
1027 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, 1032 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
1028 NAU8825_CLK_MCLK_SRC_MASK, fll_param->mclk_src); 1033 NAU8825_CLK_SRC_MASK | NAU8825_CLK_MCLK_SRC_MASK,
1034 NAU8825_CLK_SRC_MCLK | fll_param->mclk_src);
1029 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1, 1035 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1,
1030 NAU8825_FLL_RATIO_MASK, fll_param->ratio); 1036 NAU8825_FLL_RATIO_MASK, fll_param->ratio);
1031 /* FLL 16-bit fractional input */ 1037 /* FLL 16-bit fractional input */
@@ -1038,10 +1044,25 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
1038 NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div); 1044 NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div);
1039 /* select divided VCO input */ 1045 /* select divided VCO input */
1040 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5, 1046 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
1041 NAU8825_FLL_FILTER_SW_MASK, 0x0000); 1047 NAU8825_FLL_CLK_SW_MASK, NAU8825_FLL_CLK_SW_REF);
1042 /* FLL sigma delta modulator enable */ 1048 /* Disable free-running mode */
1043 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6, 1049 regmap_update_bits(nau8825->regmap,
1044 NAU8825_SDM_EN_MASK, NAU8825_SDM_EN); 1050 NAU8825_REG_FLL6, NAU8825_DCO_EN, 0);
1051 if (fll_param->fll_frac) {
1052 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
1053 NAU8825_FLL_PDB_DAC_EN | NAU8825_FLL_LOOP_FTR_EN |
1054 NAU8825_FLL_FTR_SW_MASK,
1055 NAU8825_FLL_PDB_DAC_EN | NAU8825_FLL_LOOP_FTR_EN |
1056 NAU8825_FLL_FTR_SW_FILTER);
1057 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6,
1058 NAU8825_SDM_EN, NAU8825_SDM_EN);
1059 } else {
1060 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
1061 NAU8825_FLL_PDB_DAC_EN | NAU8825_FLL_LOOP_FTR_EN |
1062 NAU8825_FLL_FTR_SW_MASK, NAU8825_FLL_FTR_SW_ACCU);
1063 regmap_update_bits(nau8825->regmap,
1064 NAU8825_REG_FLL6, NAU8825_SDM_EN, 0);
1065 }
1045} 1066}
1046 1067
1047/* freq_out must be 256*Fs in order to achieve the best performance */ 1068/* freq_out must be 256*Fs in order to achieve the best performance */
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
index ed0d8f3df65f..5fe009dcfb3d 100644
--- a/sound/soc/codecs/nau8825.h
+++ b/sound/soc/codecs/nau8825.h
@@ -123,15 +123,18 @@
123#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10) 123#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10)
124 124
125/* FLL5 (0x08) */ 125/* FLL5 (0x08) */
126#define NAU8825_FLL_FILTER_SW_MASK (0x1 << 14) 126#define NAU8825_FLL_PDB_DAC_EN (0x1 << 15)
127#define NAU8825_FLL_LOOP_FTR_EN (0x1 << 14)
128#define NAU8825_FLL_CLK_SW_MASK (0x1 << 13)
129#define NAU8825_FLL_CLK_SW_N2 (0x1 << 13)
130#define NAU8825_FLL_CLK_SW_REF (0x0 << 13)
131#define NAU8825_FLL_FTR_SW_MASK (0x1 << 12)
132#define NAU8825_FLL_FTR_SW_ACCU (0x1 << 12)
133#define NAU8825_FLL_FTR_SW_FILTER (0x0 << 12)
127 134
128/* FLL6 (0x9) */ 135/* FLL6 (0x9) */
129#define NAU8825_DCO_EN_MASK (0x1 << 15)
130#define NAU8825_DCO_EN (0x1 << 15) 136#define NAU8825_DCO_EN (0x1 << 15)
131#define NAU8825_DCO_DIS (0x0 << 15)
132#define NAU8825_SDM_EN_MASK (0x1 << 14)
133#define NAU8825_SDM_EN (0x1 << 14) 137#define NAU8825_SDM_EN (0x1 << 14)
134#define NAU8825_SDM_DIS (0x0 << 14)
135 138
136/* HSD_CTRL (0xc) */ 139/* HSD_CTRL (0xc) */
137#define NAU8825_HSD_AUTO_MODE (1 << 6) 140#define NAU8825_HSD_AUTO_MODE (1 << 6)