Unverified Commit 57589f82 authored by Jack Yu's avatar Jack Yu Committed by Mark Brown
Browse files

ASoC: rt5682: move clk related code to rt5682_i2c_probe



The DAI clock is only used in I2S mode, to make it clear
and to fix clock resource release issue, we move CCF clock
related code to rt5682_i2c_probe to fix clock
register/unregister issue.

Signed-off-by: default avatarJack Yu <jack.yu@realtek.com>
Link: https://lore.kernel.org/r/20210929054344.12112-1-jack.yu@realtek.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2cbf90a6
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -139,6 +139,8 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,

	i2c_set_clientdata(i2c, rt5682);

	rt5682->i2c_dev = &i2c->dev;

	rt5682->pdata = i2s_default_platform_data;

	if (pdata)
@@ -276,6 +278,26 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
			dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
	}

#ifdef CONFIG_COMMON_CLK
	/* Check if MCLK provided */
	rt5682->mclk = devm_clk_get(&i2c->dev, "mclk");
	if (IS_ERR(rt5682->mclk)) {
		if (PTR_ERR(rt5682->mclk) != -ENOENT) {
			ret = PTR_ERR(rt5682->mclk);
			return ret;
		}
		rt5682->mclk = NULL;
	}

	/* Register CCF DAI clock control */
	ret = rt5682_register_dai_clks(rt5682);
	if (ret)
		return ret;

	/* Initial setup for CCF */
	rt5682->lrck[RT5682_AIF1] = 48000;
#endif

	return devm_snd_soc_register_component(&i2c->dev,
					       &rt5682_soc_component_dev,
					       rt5682_dai, ARRAY_SIZE(rt5682_dai));
+26 −44
Original line number Diff line number Diff line
@@ -2510,7 +2510,7 @@ static int rt5682_set_bias_level(struct snd_soc_component *component,
static bool rt5682_clk_check(struct rt5682_priv *rt5682)
{
	if (!rt5682->master[RT5682_AIF1]) {
		dev_dbg(rt5682->component->dev, "sysclk/dai not set correctly\n");
		dev_dbg(rt5682->i2c_dev, "sysclk/dai not set correctly\n");
		return false;
	}
	return true;
@@ -2521,13 +2521,15 @@ static int rt5682_wclk_prepare(struct clk_hw *hw)
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_WCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	struct snd_soc_dapm_context *dapm =
			snd_soc_component_get_dapm(component);
	struct snd_soc_component *component;
	struct snd_soc_dapm_context *dapm;

	if (!rt5682_clk_check(rt5682))
		return -EINVAL;

	component = rt5682->component;
	dapm = snd_soc_component_get_dapm(component);

	snd_soc_dapm_mutex_lock(dapm);

	snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS");
@@ -2557,13 +2559,15 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw)
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_WCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	struct snd_soc_dapm_context *dapm =
			snd_soc_component_get_dapm(component);
	struct snd_soc_component *component;
	struct snd_soc_dapm_context *dapm;

	if (!rt5682_clk_check(rt5682))
		return;

	component = rt5682->component;
	dapm = snd_soc_component_get_dapm(component);

	snd_soc_dapm_mutex_lock(dapm);

	snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS");
@@ -2587,7 +2591,6 @@ static unsigned long rt5682_wclk_recalc_rate(struct clk_hw *hw,
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_WCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	const char * const clk_name = clk_hw_get_name(hw);

	if (!rt5682_clk_check(rt5682))
@@ -2597,7 +2600,7 @@ static unsigned long rt5682_wclk_recalc_rate(struct clk_hw *hw,
	 */
	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",
		dev_warn(rt5682->i2c_dev, "%s: clk %s only support %d or %d Hz output\n",
			__func__, clk_name, CLK_44, CLK_48);
		return 0;
	}
@@ -2611,7 +2614,6 @@ static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate,
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_WCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	const char * const clk_name = clk_hw_get_name(hw);

	if (!rt5682_clk_check(rt5682))
@@ -2621,7 +2623,7 @@ static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate,
	 * It will force to 48kHz if not both.
	 */
	if (rate != CLK_48 && rate != CLK_44) {
		dev_warn(component->dev, "%s: clk %s only support %d or %d Hz output\n",
		dev_warn(rt5682->i2c_dev, "%s: clk %s only support %d or %d Hz output\n",
			__func__, clk_name, CLK_44, CLK_48);
		rate = CLK_48;
	}
@@ -2635,7 +2637,7 @@ static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_WCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	struct snd_soc_component *component;
	struct clk_hw *parent_hw;
	const char * const clk_name = clk_hw_get_name(hw);
	int pre_div;
@@ -2644,6 +2646,8 @@ static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
	if (!rt5682_clk_check(rt5682))
		return -EINVAL;

	component = rt5682->component;

	/*
	 * Whether the wclk's parent clk (mclk) exists or not, please ensure
	 * it is fixed or set to 48MHz before setting wclk rate. It's a
@@ -2653,12 +2657,12 @@ static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
	 */
	parent_hw = clk_hw_get_parent(hw);
	if (!parent_hw)
		dev_warn(component->dev,
		dev_warn(rt5682->i2c_dev,
			"Parent mclk of wclk not acquired in driver. Please ensure mclk was provided as %d Hz.\n",
			CLK_PLL2_FIN);

	if (parent_rate != CLK_PLL2_FIN)
		dev_warn(component->dev, "clk %s only support %d Hz input\n",
		dev_warn(rt5682->i2c_dev, "clk %s only support %d Hz input\n",
			clk_name, CLK_PLL2_FIN);

	/*
@@ -2690,10 +2694,9 @@ static unsigned long rt5682_bclk_recalc_rate(struct clk_hw *hw,
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_BCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	unsigned int bclks_per_wclk;

	bclks_per_wclk = snd_soc_component_read(component, RT5682_TDM_TCON_CTRL);
	regmap_read(rt5682->regmap, RT5682_TDM_TCON_CTRL, &bclks_per_wclk);

	switch (bclks_per_wclk & RT5682_TDM_BCLK_MS1_MASK) {
	case RT5682_TDM_BCLK_MS1_256:
@@ -2754,20 +2757,22 @@ static int rt5682_bclk_set_rate(struct clk_hw *hw, unsigned long rate,
	struct rt5682_priv *rt5682 =
		container_of(hw, struct rt5682_priv,
			     dai_clks_hw[RT5682_DAI_BCLK_IDX]);
	struct snd_soc_component *component = rt5682->component;
	struct snd_soc_component *component;
	struct snd_soc_dai *dai;
	unsigned long factor;

	if (!rt5682_clk_check(rt5682))
		return -EINVAL;

	component = rt5682->component;

	factor = rt5682_bclk_get_factor(rate, parent_rate);

	for_each_component_dais(component, dai)
		if (dai->id == RT5682_AIF1)
			break;
	if (!dai) {
		dev_err(component->dev, "dai %d not found in component\n",
		dev_err(rt5682->i2c_dev, "dai %d not found in component\n",
			RT5682_AIF1);
		return -ENODEV;
	}
@@ -2790,10 +2795,9 @@ static const struct clk_ops rt5682_dai_clk_ops[RT5682_DAI_NUM_CLKS] = {
	},
};

static int rt5682_register_dai_clks(struct snd_soc_component *component)
int rt5682_register_dai_clks(struct rt5682_priv *rt5682)
{
	struct device *dev = component->dev;
	struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
	struct device *dev = rt5682->i2c_dev;
	struct rt5682_platform_data *pdata = &rt5682->pdata;
	struct clk_hw *dai_clk_hw;
	int i, ret;
@@ -2851,6 +2855,7 @@ static int rt5682_register_dai_clks(struct snd_soc_component *component)

	return 0;
}
EXPORT_SYMBOL_GPL(rt5682_register_dai_clks);
#endif /* CONFIG_COMMON_CLK */

static int rt5682_probe(struct snd_soc_component *component)
@@ -2860,9 +2865,6 @@ static int rt5682_probe(struct snd_soc_component *component)
	unsigned long time;
	struct snd_soc_dapm_context *dapm = &component->dapm;

#ifdef CONFIG_COMMON_CLK
	int ret;
#endif
	rt5682->component = component;

	if (rt5682->is_sdw) {
@@ -2874,26 +2876,6 @@ static int rt5682_probe(struct snd_soc_component *component)
			dev_err(&slave->dev, "Initialization not complete, timed out\n");
			return -ETIMEDOUT;
		}
	} else {
#ifdef CONFIG_COMMON_CLK
		/* Check if MCLK provided */
		rt5682->mclk = devm_clk_get(component->dev, "mclk");
		if (IS_ERR(rt5682->mclk)) {
			if (PTR_ERR(rt5682->mclk) != -ENOENT) {
				ret = PTR_ERR(rt5682->mclk);
				return ret;
			}
			rt5682->mclk = NULL;
		}

		/* Register CCF DAI clock control */
		ret = rt5682_register_dai_clks(component);
		if (ret)
			return ret;

		/* Initial setup for CCF */
		rt5682->lrck[RT5682_AIF1] = CLK_48;
#endif
	}

	snd_soc_dapm_disable_pin(dapm, "MICBIAS");
+3 −0
Original line number Diff line number Diff line
@@ -1408,6 +1408,7 @@ enum {

struct rt5682_priv {
	struct snd_soc_component *component;
	struct device *i2c_dev;
	struct rt5682_platform_data pdata;
	struct regmap *regmap;
	struct regmap *sdw_regmap;
@@ -1462,6 +1463,8 @@ void rt5682_calibrate(struct rt5682_priv *rt5682);
void rt5682_reset(struct rt5682_priv *rt5682);
int rt5682_parse_dt(struct rt5682_priv *rt5682, struct device *dev);

int rt5682_register_dai_clks(struct rt5682_priv *rt5682);

#define RT5682_REG_NUM 318
extern const struct reg_default rt5682_reg[RT5682_REG_NUM];