ASoC: rt5682: Enable PLL2 function
Enable RT5682 PLL2 function to implement the more complex frequency conversion. Signed-off-by: derek.fang <derek.fang@realtek.com> Link: https://lore.kernel.org/r/1581577510-1807-1-git-send-email-derek.fang@realtek.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
ff0035e4c2
Коммит
0c48a65394
|
@ -64,9 +64,9 @@ struct rt5682_priv {
|
|||
int bclk[RT5682_AIFS];
|
||||
int master[RT5682_AIFS];
|
||||
|
||||
int pll_src;
|
||||
int pll_in;
|
||||
int pll_out;
|
||||
int pll_src[RT5682_PLLS];
|
||||
int pll_in[RT5682_PLLS];
|
||||
int pll_out[RT5682_PLLS];
|
||||
|
||||
int jack_type;
|
||||
};
|
||||
|
@ -75,6 +75,7 @@ static const struct reg_sequence patch_list[] = {
|
|||
{RT5682_HP_IMP_SENS_CTRL_19, 0x1000},
|
||||
{RT5682_DAC_ADC_DIG_VOL1, 0xa020},
|
||||
{RT5682_I2C_CTRL, 0x000f},
|
||||
{RT5682_PLL2_INTERNAL, 0x8266},
|
||||
};
|
||||
|
||||
static const struct reg_default rt5682_reg[] = {
|
||||
|
@ -222,7 +223,7 @@ static const struct reg_default rt5682_reg[] = {
|
|||
{0x0148, 0x0000},
|
||||
{0x0149, 0x0000},
|
||||
{0x0150, 0x79a1},
|
||||
{0x0151, 0x0000},
|
||||
{0x0156, 0xaaaa},
|
||||
{0x0160, 0x4ec0},
|
||||
{0x0161, 0x0080},
|
||||
{0x0162, 0x0200},
|
||||
|
@ -928,10 +929,10 @@ static int rt5682_headset_detect(struct snd_soc_component *component,
|
|||
RT5682_PWR_VREF2 | RT5682_PWR_MB,
|
||||
RT5682_PWR_VREF2 | RT5682_PWR_MB);
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0);
|
||||
RT5682_PWR_ANLG_1, RT5682_PWR_FV2, 0);
|
||||
usleep_range(15000, 20000);
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2);
|
||||
RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2);
|
||||
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3,
|
||||
RT5682_PWR_CBJ, RT5682_PWR_CBJ);
|
||||
|
||||
|
@ -1298,6 +1299,21 @@ static int is_sys_clk_from_pll1(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int is_sys_clk_from_pll2(struct snd_soc_dapm_widget *w,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
unsigned int val;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
|
||||
val = snd_soc_component_read32(component, RT5682_GLB_CLK);
|
||||
val &= RT5682_SCLK_SRC_MASK;
|
||||
if (val == RT5682_SCLK_SRC_PLL2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_using_asrc(struct snd_soc_dapm_widget *w,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
|
@ -1612,9 +1628,11 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_SUPPLY("PLL2B", RT5682_PWR_ANLG_3, RT5682_PWR_PLL2B_BIT,
|
||||
0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL2F", RT5682_PWR_ANLG_3, RT5682_PWR_PLL2F_BIT,
|
||||
0, NULL, 0),
|
||||
0, set_filter_clk, SND_SOC_DAPM_PRE_PMU),
|
||||
SND_SOC_DAPM_SUPPLY("Vref1", RT5682_PWR_ANLG_1, RT5682_PWR_VREF1_BIT, 0,
|
||||
rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_SUPPLY("Vref2", RT5682_PWR_ANLG_1, RT5682_PWR_VREF2_BIT, 0,
|
||||
NULL, 0),
|
||||
|
||||
/* ASRC */
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5682_PLL_TRACK_1,
|
||||
|
@ -1796,7 +1814,11 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = {
|
|||
static const struct snd_soc_dapm_route rt5682_dapm_routes[] = {
|
||||
/*PLL*/
|
||||
{"ADC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1},
|
||||
{"ADC Stereo1 Filter", NULL, "PLL2B", is_sys_clk_from_pll2},
|
||||
{"ADC Stereo1 Filter", NULL, "PLL2F", is_sys_clk_from_pll2},
|
||||
{"DAC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1},
|
||||
{"DAC Stereo1 Filter", NULL, "PLL2B", is_sys_clk_from_pll2},
|
||||
{"DAC Stereo1 Filter", NULL, "PLL2F", is_sys_clk_from_pll2},
|
||||
|
||||
/*ASRC*/
|
||||
{"ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc},
|
||||
|
@ -2053,8 +2075,10 @@ static int rt5682_hw_params(struct snd_pcm_substream *substream,
|
|||
RT5682_I2S1_DL_MASK, len_1);
|
||||
if (rt5682->master[RT5682_AIF1]) {
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_ADDA_CLK_1, RT5682_I2S_M_DIV_MASK,
|
||||
pre_div << RT5682_I2S_M_DIV_SFT);
|
||||
RT5682_ADDA_CLK_1, RT5682_I2S_M_DIV_MASK |
|
||||
RT5682_I2S_CLK_SRC_MASK,
|
||||
pre_div << RT5682_I2S_M_DIV_SFT |
|
||||
(rt5682->sysclk_src) << RT5682_I2S_CLK_SRC_SFT);
|
||||
}
|
||||
if (params_channels(params) == 1) /* mono mode */
|
||||
snd_soc_component_update_bits(component,
|
||||
|
@ -2227,61 +2251,157 @@ static int rt5682_set_component_pll(struct snd_soc_component *component,
|
|||
unsigned int freq_out)
|
||||
{
|
||||
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
|
||||
struct rl6231_pll_code pll_code;
|
||||
struct rl6231_pll_code pll_code, pll2f_code, pll2b_code;
|
||||
unsigned int pll2_fout1;
|
||||
int ret;
|
||||
|
||||
if (source == rt5682->pll_src && freq_in == rt5682->pll_in &&
|
||||
freq_out == rt5682->pll_out)
|
||||
if (source == rt5682->pll_src[pll_id] &&
|
||||
freq_in == rt5682->pll_in[pll_id] &&
|
||||
freq_out == rt5682->pll_out[pll_id])
|
||||
return 0;
|
||||
|
||||
if (!freq_in || !freq_out) {
|
||||
dev_dbg(component->dev, "PLL disabled\n");
|
||||
|
||||
rt5682->pll_in = 0;
|
||||
rt5682->pll_out = 0;
|
||||
rt5682->pll_in[pll_id] = 0;
|
||||
rt5682->pll_out[pll_id] = 0;
|
||||
snd_soc_component_update_bits(component, RT5682_GLB_CLK,
|
||||
RT5682_SCLK_SRC_MASK, RT5682_SCLK_SRC_MCLK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (source) {
|
||||
case RT5682_PLL1_S_MCLK:
|
||||
snd_soc_component_update_bits(component, RT5682_GLB_CLK,
|
||||
RT5682_PLL1_SRC_MASK, RT5682_PLL1_SRC_MCLK);
|
||||
break;
|
||||
case RT5682_PLL1_S_BCLK1:
|
||||
snd_soc_component_update_bits(component, RT5682_GLB_CLK,
|
||||
RT5682_PLL1_SRC_MASK, RT5682_PLL1_SRC_BCLK1);
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Unknown PLL Source %d\n", source);
|
||||
return -EINVAL;
|
||||
if (pll_id == RT5682_PLL2) {
|
||||
switch (source) {
|
||||
case RT5682_PLL2_S_MCLK:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_GLB_CLK, RT5682_PLL2_SRC_MASK,
|
||||
RT5682_PLL2_SRC_MCLK);
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Unknown PLL2 Source %d\n",
|
||||
source);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* PLL2 concatenates 2 PLL units.
|
||||
* We suggest the Fout of the front PLL is 3.84MHz.
|
||||
*/
|
||||
pll2_fout1 = 3840000;
|
||||
ret = rl6231_pll_calc(freq_in, pll2_fout1, &pll2f_code);
|
||||
if (ret < 0) {
|
||||
dev_err(component->dev, "Unsupport input clock %d\n",
|
||||
freq_in);
|
||||
return ret;
|
||||
}
|
||||
dev_dbg(component->dev, "PLL2F: fin=%d fout=%d bypass=%d m=%d n=%d k=%d\n",
|
||||
freq_in, pll2_fout1,
|
||||
pll2f_code.m_bp,
|
||||
(pll2f_code.m_bp ? 0 : pll2f_code.m_code),
|
||||
pll2f_code.n_code, pll2f_code.k_code);
|
||||
|
||||
ret = rl6231_pll_calc(pll2_fout1, freq_out, &pll2b_code);
|
||||
if (ret < 0) {
|
||||
dev_err(component->dev, "Unsupport input clock %d\n",
|
||||
pll2_fout1);
|
||||
return ret;
|
||||
}
|
||||
dev_dbg(component->dev, "PLL2B: fin=%d fout=%d bypass=%d m=%d n=%d k=%d\n",
|
||||
pll2_fout1, freq_out,
|
||||
pll2b_code.m_bp,
|
||||
(pll2b_code.m_bp ? 0 : pll2b_code.m_code),
|
||||
pll2b_code.n_code, pll2b_code.k_code);
|
||||
|
||||
snd_soc_component_write(component, RT5682_PLL2_CTRL_1,
|
||||
pll2f_code.k_code << RT5682_PLL2F_K_SFT |
|
||||
pll2b_code.k_code << RT5682_PLL2B_K_SFT |
|
||||
pll2b_code.m_code);
|
||||
snd_soc_component_write(component, RT5682_PLL2_CTRL_2,
|
||||
pll2f_code.m_code << RT5682_PLL2F_M_SFT |
|
||||
pll2b_code.n_code);
|
||||
snd_soc_component_write(component, RT5682_PLL2_CTRL_3,
|
||||
pll2f_code.n_code << RT5682_PLL2F_N_SFT);
|
||||
snd_soc_component_update_bits(component, RT5682_PLL2_CTRL_4,
|
||||
RT5682_PLL2B_M_BP_MASK | RT5682_PLL2F_M_BP_MASK | 0xf,
|
||||
(pll2b_code.m_bp ? 1 : 0) << RT5682_PLL2B_M_BP_SFT |
|
||||
(pll2f_code.m_bp ? 1 : 0) << RT5682_PLL2F_M_BP_SFT |
|
||||
0xf);
|
||||
} else {
|
||||
switch (source) {
|
||||
case RT5682_PLL1_S_MCLK:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_GLB_CLK, RT5682_PLL1_SRC_MASK,
|
||||
RT5682_PLL1_SRC_MCLK);
|
||||
break;
|
||||
case RT5682_PLL1_S_BCLK1:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_GLB_CLK, RT5682_PLL1_SRC_MASK,
|
||||
RT5682_PLL1_SRC_BCLK1);
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Unknown PLL1 Source %d\n",
|
||||
source);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
|
||||
if (ret < 0) {
|
||||
dev_err(component->dev, "Unsupport input clock %d\n",
|
||||
freq_in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
|
||||
pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
|
||||
pll_code.n_code, pll_code.k_code);
|
||||
|
||||
snd_soc_component_write(component, RT5682_PLL_CTRL_1,
|
||||
pll_code.n_code << RT5682_PLL_N_SFT | pll_code.k_code);
|
||||
snd_soc_component_write(component, RT5682_PLL_CTRL_2,
|
||||
(pll_code.m_bp ? 0 : pll_code.m_code) << RT5682_PLL_M_SFT |
|
||||
pll_code.m_bp << RT5682_PLL_M_BP_SFT | RT5682_PLL_RST);
|
||||
}
|
||||
|
||||
ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
|
||||
if (ret < 0) {
|
||||
dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
|
||||
pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
|
||||
pll_code.n_code, pll_code.k_code);
|
||||
|
||||
snd_soc_component_write(component, RT5682_PLL_CTRL_1,
|
||||
pll_code.n_code << RT5682_PLL_N_SFT | pll_code.k_code);
|
||||
snd_soc_component_write(component, RT5682_PLL_CTRL_2,
|
||||
(pll_code.m_bp ? 0 : pll_code.m_code) << RT5682_PLL_M_SFT |
|
||||
pll_code.m_bp << RT5682_PLL_M_BP_SFT | RT5682_PLL_RST);
|
||||
|
||||
rt5682->pll_in = freq_in;
|
||||
rt5682->pll_out = freq_out;
|
||||
rt5682->pll_src = source;
|
||||
rt5682->pll_in[pll_id] = freq_in;
|
||||
rt5682->pll_out[pll_id] = freq_out;
|
||||
rt5682->pll_src[pll_id] = source;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt5682_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
|
||||
static int rt5682_set_bclk1_ratio(struct snd_soc_dai *dai, unsigned int ratio)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
rt5682->bclk[dai->id] = ratio;
|
||||
|
||||
switch (ratio) {
|
||||
case 256:
|
||||
snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL,
|
||||
RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_256);
|
||||
break;
|
||||
case 128:
|
||||
snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL,
|
||||
RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_128);
|
||||
break;
|
||||
case 64:
|
||||
snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL,
|
||||
RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_64);
|
||||
break;
|
||||
case 32:
|
||||
snd_soc_component_update_bits(component, RT5682_TDM_TCON_CTRL,
|
||||
RT5682_TDM_BCLK_MS1_MASK, RT5682_TDM_BCLK_MS1_32);
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "Invalid bclk1 ratio %d\n", ratio);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt5682_set_bclk2_ratio(struct snd_soc_dai *dai, unsigned int ratio)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
|
||||
|
@ -2300,7 +2420,7 @@ static int rt5682_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
|
|||
RT5682_I2S2_BCLK_MS2_32);
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "Invalid bclk ratio %d\n", ratio);
|
||||
dev_err(dai->dev, "Invalid bclk2 ratio %d\n", ratio);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -2389,12 +2509,13 @@ static const struct snd_soc_dai_ops rt5682_aif1_dai_ops = {
|
|||
.hw_params = rt5682_hw_params,
|
||||
.set_fmt = rt5682_set_dai_fmt,
|
||||
.set_tdm_slot = rt5682_set_tdm_slot,
|
||||
.set_bclk_ratio = rt5682_set_bclk1_ratio,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops rt5682_aif2_dai_ops = {
|
||||
.hw_params = rt5682_hw_params,
|
||||
.set_fmt = rt5682_set_dai_fmt,
|
||||
.set_bclk_ratio = rt5682_set_bclk_ratio,
|
||||
.set_bclk_ratio = rt5682_set_bclk2_ratio,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver rt5682_dai[] = {
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
#define RT5682_TEST_MODE_CTRL_4 0x0148
|
||||
#define RT5682_TEST_MODE_CTRL_5 0x0149
|
||||
#define RT5682_PLL1_INTERNAL 0x0150
|
||||
#define RT5682_PLL2_INTERNAL 0x0151
|
||||
#define RT5682_PLL2_INTERNAL 0x0156
|
||||
#define RT5682_STO_NG2_CTRL_1 0x0160
|
||||
#define RT5682_STO_NG2_CTRL_2 0x0161
|
||||
#define RT5682_STO_NG2_CTRL_3 0x0162
|
||||
|
@ -738,7 +738,7 @@
|
|||
#define RT5682_ADC_OSR_D_24 (0x7 << 12)
|
||||
#define RT5682_ADC_OSR_D_32 (0x8 << 12)
|
||||
#define RT5682_ADC_OSR_D_48 (0x9 << 12)
|
||||
#define RT5682_I2S_M_DIV_MASK (0xf << 12)
|
||||
#define RT5682_I2S_M_DIV_MASK (0xf << 8)
|
||||
#define RT5682_I2S_M_DIV_SFT 8
|
||||
#define RT5682_I2S_M_D_1 (0x0 << 8)
|
||||
#define RT5682_I2S_M_D_2 (0x1 << 8)
|
||||
|
@ -820,6 +820,12 @@
|
|||
#define RT5682_TDM_DF_PCM_B (0x3 << 11)
|
||||
#define RT5682_TDM_DF_PCM_A_N (0x6 << 11)
|
||||
#define RT5682_TDM_DF_PCM_B_N (0x7 << 11)
|
||||
#define RT5682_TDM_BCLK_MS1_MASK (0x3 << 9)
|
||||
#define RT5682_TDM_BCLK_MS1_SFT 9
|
||||
#define RT5682_TDM_BCLK_MS1_32 (0x0 << 9)
|
||||
#define RT5682_TDM_BCLK_MS1_64 (0x1 << 9)
|
||||
#define RT5682_TDM_BCLK_MS1_128 (0x2 << 9)
|
||||
#define RT5682_TDM_BCLK_MS1_256 (0x3 << 9)
|
||||
#define RT5682_TDM_CL_MASK (0x3 << 4)
|
||||
#define RT5682_TDM_CL_16 (0x0 << 4)
|
||||
#define RT5682_TDM_CL_20 (0x1 << 4)
|
||||
|
@ -1049,6 +1055,28 @@
|
|||
#define RT5682_PWR_CLK1M_PD (0x0 << 8)
|
||||
#define RT5682_PWR_CLK1M_PU (0x1 << 8)
|
||||
|
||||
/* PLL2 M/N/K Code Control 1 (0x009b) */
|
||||
#define RT5682_PLL2F_K_MASK (0x1f << 8)
|
||||
#define RT5682_PLL2F_K_SFT 8
|
||||
#define RT5682_PLL2B_K_MASK (0xf << 4)
|
||||
#define RT5682_PLL2B_K_SFT 4
|
||||
#define RT5682_PLL2B_M_MASK (0xf << 0)
|
||||
|
||||
/* PLL2 M/N/K Code Control 2 (0x009c) */
|
||||
#define RT5682_PLL2F_M_MASK (0x3f << 8)
|
||||
#define RT5682_PLL2F_M_SFT 8
|
||||
#define RT5682_PLL2B_N_MASK (0x3f << 0)
|
||||
|
||||
/* PLL2 M/N/K Code Control 2 (0x009d) */
|
||||
#define RT5682_PLL2F_N_MASK (0x7f << 8)
|
||||
#define RT5682_PLL2F_N_SFT 8
|
||||
|
||||
/* PLL2 M/N/K Code Control 2 (0x009e) */
|
||||
#define RT5682_PLL2B_M_BP_MASK (0x1 << 11)
|
||||
#define RT5682_PLL2B_M_BP_SFT 11
|
||||
#define RT5682_PLL2F_M_BP_MASK (0x1 << 7)
|
||||
#define RT5682_PLL2F_M_BP_SFT 7
|
||||
|
||||
/* RC Clock Control (0x009f) */
|
||||
#define RT5682_POW_IRQ (0x1 << 15)
|
||||
#define RT5682_POW_JDH (0x1 << 14)
|
||||
|
@ -1315,6 +1343,13 @@ enum {
|
|||
RT5682_PLL1_S_MCLK,
|
||||
RT5682_PLL1_S_BCLK1,
|
||||
RT5682_PLL1_S_RCCLK,
|
||||
RT5682_PLL2_S_MCLK,
|
||||
};
|
||||
|
||||
enum {
|
||||
RT5682_PLL1,
|
||||
RT5682_PLL2,
|
||||
RT5682_PLLS,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
Загрузка…
Ссылка в новой задаче