ASoC: rt5682: DAI wclk supports 44100 Hz output

DAI Wclk of rt5682 only supports 48000Hz output so far,
this patch lets it support 44100Hz.

Signed-off-by: derek.fang <derek.fang@realtek.com>
Link: https://lore.kernel.org/r/1591938925-1070-4-git-send-email-derek.fang@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
derek.fang 2020-06-12 13:15:24 +08:00 committed by Mark Brown
parent d54348fbef
commit fde418b61d
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -2463,8 +2463,8 @@ static int rt5682_set_bias_level(struct snd_soc_component *component,
#ifdef CONFIG_COMMON_CLK #ifdef CONFIG_COMMON_CLK
#define CLK_PLL2_FIN 48000000 #define CLK_PLL2_FIN 48000000
#define CLK_PLL2_FOUT 24576000
#define CLK_48 48000 #define CLK_48 48000
#define CLK_44 44100
static bool rt5682_clk_check(struct rt5682_priv *rt5682) static bool rt5682_clk_check(struct rt5682_priv *rt5682)
{ {
@ -2534,13 +2534,22 @@ static unsigned long rt5682_wclk_recalc_rate(struct clk_hw *hw,
struct rt5682_priv *rt5682 = struct rt5682_priv *rt5682 =
container_of(hw, struct rt5682_priv, container_of(hw, struct rt5682_priv,
dai_clks_hw[RT5682_DAI_WCLK_IDX]); dai_clks_hw[RT5682_DAI_WCLK_IDX]);
struct snd_soc_component *component = rt5682->component;
const char * const clk_name = __clk_get_name(hw->clk);
if (!rt5682_clk_check(rt5682)) if (!rt5682_clk_check(rt5682))
return 0; return 0;
/* /*
* Only accept to set wclk rate to 48kHz temporarily. * Only accept to set wclk rate to 44.1k or 48kHz.
*/ */
return CLK_48; if (rt5682->lrck[RT5682_AIF1] != CLK_48 &&
rt5682->lrck[RT5682_AIF1] != CLK_44) {
dev_warn(component->dev, "%s: clk %s only support %d or %d Hz output\n",
__func__, clk_name, CLK_44, CLK_48);
return 0;
}
return rt5682->lrck[RT5682_AIF1];
} }
static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate, static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate,
@ -2549,13 +2558,22 @@ static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate,
struct rt5682_priv *rt5682 = struct rt5682_priv *rt5682 =
container_of(hw, struct rt5682_priv, container_of(hw, struct rt5682_priv,
dai_clks_hw[RT5682_DAI_WCLK_IDX]); dai_clks_hw[RT5682_DAI_WCLK_IDX]);
struct snd_soc_component *component = rt5682->component;
const char * const clk_name = __clk_get_name(hw->clk);
if (!rt5682_clk_check(rt5682)) if (!rt5682_clk_check(rt5682))
return -EINVAL; return -EINVAL;
/* /*
* Only accept to set wclk rate to 48kHz temporarily. * Only accept to set wclk rate to 44.1k or 48kHz.
* It will force to 48kHz if not both.
*/ */
return CLK_48; if (rate != CLK_48 && rate != CLK_44) {
dev_warn(component->dev, "%s: clk %s only support %d or %d Hz output\n",
__func__, clk_name, CLK_44, CLK_48);
rate = CLK_48;
}
return rate;
} }
static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate, static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
@ -2568,6 +2586,7 @@ static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk *parent_clk; struct clk *parent_clk;
const char * const clk_name = __clk_get_name(hw->clk); const char * const clk_name = __clk_get_name(hw->clk);
int pre_div; int pre_div;
unsigned int clk_pll2_out;
if (!rt5682_clk_check(rt5682)) if (!rt5682_clk_check(rt5682))
return -EINVAL; return -EINVAL;
@ -2590,23 +2609,17 @@ static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
clk_name, CLK_PLL2_FIN); clk_name, CLK_PLL2_FIN);
/* /*
* It's a temporary limitation. Only accept to set wclk rate to 48kHz. * To achieve the rate conversion from 48MHz to 44.1k or 48kHz,
* It will force wclk to 48kHz even it's not. * PLL2 is needed.
*/
if (rate != CLK_48) {
dev_warn(component->dev, "clk %s only support %d Hz output\n",
clk_name, CLK_48);
rate = CLK_48;
}
/*
* To achieve the rate conversion from 48MHz to 48kHz, PLL2 is needed.
*/ */
clk_pll2_out = rate * 512;
rt5682_set_component_pll(component, RT5682_PLL2, RT5682_PLL2_S_MCLK, rt5682_set_component_pll(component, RT5682_PLL2, RT5682_PLL2_S_MCLK,
CLK_PLL2_FIN, CLK_PLL2_FOUT); CLK_PLL2_FIN, clk_pll2_out);
rt5682_set_component_sysclk(component, RT5682_SCLK_S_PLL2, 0, rt5682_set_component_sysclk(component, RT5682_SCLK_S_PLL2, 0,
CLK_PLL2_FOUT, SND_SOC_CLOCK_IN); clk_pll2_out, SND_SOC_CLOCK_IN);
rt5682->lrck[RT5682_AIF1] = rate;
pre_div = rl6231_get_clk_info(rt5682->sysclk, rate); pre_div = rl6231_get_clk_info(rt5682->sysclk, rate);