From b12cc7fd5303bdad5e29bef7c877fccb38afc5aa Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 4 Jan 2022 14:49:27 +0800 Subject: [PATCH] ASoC: rockchip: spdif: Add support for set mclk rate This patch allow to set mclk rate from machine driver. Signed-off-by: Sugar Zhang Change-Id: Id1e713c7021cb644eeb32fb98d384a6fd320f31d --- sound/soc/rockchip/rockchip_spdif.c | 31 +++++++++++++++++++---------- sound/soc/rockchip/rockchip_spdif.h | 2 +- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index f7173614446a..55bccb806e82 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -112,11 +112,14 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, { struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE; - int srate, mclk; + unsigned int mclk_rate = clk_get_rate(spdif->mclk); + int bmc, div; int ret; - srate = params_rate(params); - mclk = srate * 128; + /* bmc = 128fs */ + bmc = 128 * params_rate(params); + div = DIV_ROUND_CLOSEST(mclk_rate, bmc); + val |= SPDIF_CFGR_CLK_DIV(div); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -132,14 +135,6 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* Set clock and calculate divider */ - ret = clk_set_rate(spdif->mclk, mclk); - if (ret != 0) { - dev_err(spdif->dev, "Failed to set module clock rate: %d\n", - ret); - return ret; - } - ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE | @@ -202,7 +197,21 @@ static int rk_spdif_dai_probe(struct snd_soc_dai *dai) return 0; } +static int rk_spdif_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + ret = clk_set_rate(spdif->mclk, freq); + if (ret) + dev_err(spdif->dev, "Failed to set mclk: %d\n", ret); + + return ret; +} + static const struct snd_soc_dai_ops rk_spdif_dai_ops = { + .set_sysclk = rk_spdif_set_sysclk, .hw_params = rk_spdif_hw_params, .trigger = rk_spdif_trigger, }; diff --git a/sound/soc/rockchip/rockchip_spdif.h b/sound/soc/rockchip/rockchip_spdif.h index d8be9aae5b19..762d570b5326 100644 --- a/sound/soc/rockchip/rockchip_spdif.h +++ b/sound/soc/rockchip/rockchip_spdif.h @@ -15,7 +15,7 @@ */ #define SPDIF_CFGR_CLK_DIV_SHIFT (16) #define SPDIF_CFGR_CLK_DIV_MASK (0xff << SPDIF_CFGR_CLK_DIV_SHIFT) -#define SPDIF_CFGR_CLK_DIV(x) (x << SPDIF_CFGR_CLK_DIV_SHIFT) +#define SPDIF_CFGR_CLK_DIV(x) ((x - 1) << SPDIF_CFGR_CLK_DIV_SHIFT) #define SPDIF_CFGR_HALFWORD_SHIFT 2 #define SPDIF_CFGR_HALFWORD_DISABLE (0 << SPDIF_CFGR_HALFWORD_SHIFT)