From 873b86c8a45dc6cd66c7523d42562639cceabb40 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Sun, 15 Oct 2023 11:26:32 +0800 Subject: [PATCH] ASoC: rockchip: pdm: Add support for CLK-ALWAYS-ON quirks This patch add support for keeping PDM-CLK always on. Signed-off-by: Sugar Zhang Change-Id: Ibe5f660b52de6dba493a0046f89e4b2af1b379bb --- sound/soc/rockchip/rockchip_pdm.c | 44 +++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index bb4f1e2504dd..ad5e8b706c2c 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -31,8 +31,10 @@ #define PDM_FILTER_DELAY_MS_MIN (20) #define PDM_FILTER_DELAY_MS_MAX (1000) #define PDM_CLK_SHIFT_PPM_MAX (1000000) /* 1 ppm */ -#define CLK_PPM_MIN (-1000) -#define CLK_PPM_MAX (1000) +#define CLK_PPM_MIN (-1000) +#define CLK_PPM_MAX (1000) + +#define QUIRK_ALWAYS_ON BIT(0) enum rk_pdm_version { RK_PDM_RK3229, @@ -56,6 +58,7 @@ struct rk_pdm_dev { enum rk_pdm_version version; unsigned int clk_root_rate; unsigned int clk_root_initial_rate; + unsigned int quirks; int clk_ppm; bool clk_calibrate; }; @@ -97,6 +100,16 @@ static struct rk_pdm_ds_ratio ds_ratio[] = { { 4, 8000 }, }; +static const struct pdm_of_quirks { + char *quirk; + int id; +} of_quirks[] = { + { + .quirk = "rockchip,always-on", + .id = QUIRK_ALWAYS_ON, + }, +}; + static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr, unsigned int *clk_src, unsigned int *clk_out, unsigned int signoff) @@ -957,6 +970,29 @@ static int rockchip_pdm_path_parse(struct rk_pdm_dev *pdm, struct device_node *n return 0; } +static int rockchip_pdm_keep_clk_always_on(struct rk_pdm_dev *pdm) +{ + pm_runtime_forbid(pdm->dev); + + dev_info(pdm->dev, "CLK-ALWAYS-ON: samplerate: %d\n", PDM_DEFAULT_RATE); + + return 0; +} + +static int rockchip_pdm_parse_quirks(struct rk_pdm_dev *pdm) +{ + int ret = 0, i = 0; + + for (i = 0; i < ARRAY_SIZE(of_quirks); i++) + if (device_property_read_bool(pdm->dev, of_quirks[i].quirk)) + pdm->quirks |= of_quirks[i].id; + + if (pdm->quirks & QUIRK_ALWAYS_ON) + ret = rockchip_pdm_keep_clk_always_on(pdm); + + return ret; +} + static int rockchip_pdm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -1038,6 +1074,10 @@ static int rockchip_pdm_probe(struct platform_device *pdev) if (ret != 0 && ret != -ENOENT) goto err_clk; + ret = rockchip_pdm_parse_quirks(pdm); + if (ret) + goto err_clk; + /* * MUST: after pm_runtime_enable step, any register R/W * should be wrapped with pm_runtime_get_sync/put.