From 298082783a0d6d07109f8ce09ab410a1de12876d Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 3 Feb 2026 17:46:29 +0100 Subject: [PATCH] ASoC: rockchip: spdif: Add support for set mclk rate Allow setting the mclk rate from the machine driver. Signed-off-by: Sugar Zhang Signed-off-by: Sebastian Reichel Link: https://patch.msgid.link/20260203-rockchip-spdif-cleanup-and-bsp-sync-v2-7-4412016cf577@collabora.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_spdif.c | 34 +++++++++++++++++++---------- sound/soc/rockchip/rockchip_spdif.h | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index c1221ff00ed70..3b66d97f05829 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -86,12 +86,15 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); + unsigned int mclk_rate = clk_get_rate(spdif->mclk); unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE; - int srate, 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: @@ -107,14 +110,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 | @@ -177,7 +172,24 @@ 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; + + if (!freq) + return 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, .probe = rk_spdif_dai_probe, .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 d8be9aae5b195..fcc28b6c4f586 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) -- 2.47.3