From a0ae2bdfc0088f2f136c27e504403993f8b0a5b8 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Thu, 5 Jan 2023 17:14:43 +0800 Subject: [PATCH] Revert "ASoC: codecs: rv1106_codec: use interface set_sysclk to set clk" This reverts commit 59f45fdccdff18d97df9a9cc18e08c2fc1617ba2. The reason for revert this patch is that mclk_acodec_tx usually keeps div1 and follows the same value as mclk_i2s0_8ch_tx. If the DUT is just powered on, the current acodec clk is usually an uninitialized value (such as 12MHz). At this time, an audio with a sampling rate of 16kHz needs to be played, and mclk needs 4.096MHz. The codec set_sysclk() is configured before cpu i2s_sysclk(), set a div 3 based on target freq 4.096MHz, and then set cpu i2s_sysclk() to correct the frequency division ratio of parent clock according to target freq 4.096MHz, and getting the wrong results: - mclk_i2s0_8ch_tx = 4096000kHz - mclk_acodec_tx = 1365334kHz Before: pll_gpll 1 1 0 1188000000 0 0 50000 gpll 11 11 0 1188000000 0 0 50000 clk_i2s0_8ch_tx_src 1 1 0 594000000 0 0 50000 clk_i2s0_8ch_tx_frac 1 1 0 4096000 0 0 50000 clk_i2s0_8ch_tx 1 1 0 4096000 0 0 50000 mclk_i2s0_8ch_tx 2 2 0 4096000 0 0 50000 mclk_sai 0 0 0 4096000 0 0 50000 mclk_dsm 0 0 0 4096000 0 0 50000 mclk_acodec_tx 1 1 0 1365334 0 0 50000 Fixed: pll_gpll 1 1 0 1188000000 0 0 50000 gpll 11 11 0 1188000000 0 0 50000 clk_i2s0_8ch_tx_src 1 1 0 594000000 0 0 50000 clk_i2s0_8ch_tx_frac 1 1 0 4096000 0 0 50000 clk_i2s0_8ch_tx 1 1 0 4096000 0 0 50000 mclk_i2s0_8ch_tx 2 2 0 4096000 0 0 50000 mclk_sai 0 0 0 4096000 0 0 50000 mclk_dsm 0 0 0 4096000 0 0 50000 mclk_acodec_tx 1 1 0 4096000 0 0 50000 Therefore, we only need to set_sysclk() once on the rockchip i2s driver. Change-Id: I8e3d32ec1061166faa8188e6288934867880ab48 Signed-off-by: Xing Zheng --- sound/soc/codecs/rv1106_codec.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/rv1106_codec.c b/sound/soc/codecs/rv1106_codec.c index 3714bdcf0199..7c767e7ece8a 100644 --- a/sound/soc/codecs/rv1106_codec.c +++ b/sound/soc/codecs/rv1106_codec.c @@ -75,6 +75,7 @@ struct rv1106_codec_priv { struct regmap *grf; struct clk *pclk_acodec; struct clk *mclk_acodec; + struct clk *mclk_cpu; struct gpio_desc *pa_ctl_gpio; struct snd_soc_component *component; @@ -1613,29 +1614,11 @@ static void rv1106_pcm_shutdown(struct snd_pcm_substream *substream, regcache_sync(rv1106->regmap); } -static int rv1106_set_sysclk(struct snd_soc_dai *dai, int clk_id, - unsigned int freq, int dir) -{ - struct snd_soc_component *component = dai->component; - struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); - int ret; - - if (!freq) - return 0; - - ret = clk_set_rate(rv1106->mclk_acodec, freq); - if (ret) - dev_err(&rv1106->dev, "Failed to set mclk %d\n", ret); - - return ret; -} - static const struct snd_soc_dai_ops rv1106_dai_ops = { .hw_params = rv1106_hw_params, .set_fmt = rv1106_set_dai_fmt, .mute_stream = rv1106_mute_stream, .shutdown = rv1106_pcm_shutdown, - .set_sysclk = rv1106_set_sysclk, }; static struct snd_soc_dai_driver rv1106_dai[] = { @@ -2145,6 +2128,11 @@ static int rv1106_platform_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(rv1106->mclk_acodec), "Can't get acodec mclk_acodec\n"); + rv1106->mclk_cpu = devm_clk_get(&pdev->dev, "mclk_cpu"); + if (IS_ERR(rv1106->mclk_cpu)) + return dev_err_probe(&pdev->dev, PTR_ERR(rv1106->mclk_cpu), + "Can't get acodec mclk_cpu\n"); + ret = rv1106_codec_sysfs_init(pdev, rv1106); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "Sysfs init failed\n"); @@ -2171,6 +2159,15 @@ static int rv1106_platform_probe(struct platform_device *pdev) goto failed_1; } + /** + * In PERICRU_PERICLKSEL_CON08, the mclk_acodec_t/rx_div are div 4 + * by default, we need to calibrate once, make the div is 1 and keep + * the rate of mclk_acodec is the same with mclk_i2s. + * + * FIXME: need to handle div dynamically if the DSMAUDIO is enabled. + */ + clk_set_rate(rv1106->mclk_acodec, clk_get_rate(rv1106->mclk_cpu)); + rv1106_codec_check_micbias(rv1106, np); ret = rv1106_codec_adc_i2s_route(rv1106);