The patch ASoC: madera: Enable clocks for input pins when used for the FLL has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.6 All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 3863857dd5ca3e60685c6b49a7873fda727ff233 Mon Sep 17 00:00:00 2001 From: Charles Keepax <ckeepax@xxxxxxxxxxxxxxxxxxxxx> Date: Mon, 30 Dec 2019 14:35:17 +0000 Subject: [PATCH] ASoC: madera: Enable clocks for input pins when used for the FLL When one of the MCLK pins is used to supply the FLL enable that clock source. Signed-off-by: Charles Keepax <ckeepax@xxxxxxxxxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/20191230143517.21005-2-ckeepax@xxxxxxxxxxxxxxxxxxxxx Signed-off-by: Mark Brown <broonie@xxxxxxxxxx> --- sound/soc/codecs/madera.c | 109 ++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index 9b4b4c52b9e4..12dc468ae6bf 100644 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -3858,11 +3858,75 @@ static bool madera_set_fll_phase_integrator(struct madera_fll *fll, return reg_change; } +static int madera_set_fll_clks_reg(struct madera_fll *fll, bool ena, + unsigned int reg, unsigned int mask, + unsigned int shift) +{ + struct madera *madera = fll->madera; + unsigned int src; + struct clk *clk; + int ret; + + ret = regmap_read(madera->regmap, reg, &src); + if (ret != 0) { + madera_fll_err(fll, "Failed to read current source: %d\n", + ret); + return ret; + } + + src = (src & mask) >> shift; + + switch (src) { + case MADERA_FLL_SRC_MCLK1: + clk = madera->mclk[MADERA_MCLK1].clk; + break; + case MADERA_FLL_SRC_MCLK2: + clk = madera->mclk[MADERA_MCLK2].clk; + break; + case MADERA_FLL_SRC_MCLK3: + clk = madera->mclk[MADERA_MCLK3].clk; + break; + default: + return 0; + } + + if (ena) { + return clk_prepare_enable(clk); + } else { + clk_disable_unprepare(clk); + return 0; + } +} + +static inline int madera_set_fll_clks(struct madera_fll *fll, int base, bool ena) +{ + return madera_set_fll_clks_reg(fll, ena, + base + MADERA_FLL_CONTROL_6_OFFS, + MADERA_FLL1_REFCLK_SRC_MASK, + MADERA_FLL1_REFCLK_DIV_SHIFT); +} + +static inline int madera_set_fllao_clks(struct madera_fll *fll, int base, bool ena) +{ + return madera_set_fll_clks_reg(fll, ena, + base + MADERA_FLLAO_CONTROL_6_OFFS, + MADERA_FLL_AO_REFCLK_SRC_MASK, + MADERA_FLL_AO_REFCLK_SRC_SHIFT); +} + +static inline int madera_set_fllhj_clks(struct madera_fll *fll, int base, bool ena) +{ + return madera_set_fll_clks_reg(fll, ena, + base + MADERA_FLL_CONTROL_1_OFFS, + CS47L92_FLL1_REFCLK_SRC_MASK, + CS47L92_FLL1_REFCLK_SRC_SHIFT); +} + static void madera_disable_fll(struct madera_fll *fll) { struct madera *madera = fll->madera; unsigned int sync_base; - bool change; + bool ref_change, sync_change; switch (madera->type) { case CS47L35: @@ -3880,18 +3944,23 @@ static void madera_disable_fll(struct madera_fll *fll) MADERA_FLL1_FREERUN, MADERA_FLL1_FREERUN); regmap_update_bits_check(madera->regmap, fll->base + MADERA_FLL_CONTROL_1_OFFS, - MADERA_FLL1_ENA, 0, &change); - regmap_update_bits(madera->regmap, - sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS, - MADERA_FLL1_SYNC_ENA, 0); + MADERA_FLL1_ENA, 0, &ref_change); + regmap_update_bits_check(madera->regmap, + sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS, + MADERA_FLL1_SYNC_ENA, 0, &sync_change); regmap_update_bits(madera->regmap, fll->base + MADERA_FLL_CONTROL_1_OFFS, MADERA_FLL1_FREERUN, 0); madera_wait_for_fll(fll, false); - if (change) + if (sync_change) + madera_set_fll_clks(fll, sync_base, false); + + if (ref_change) { + madera_set_fll_clks(fll, fll->base, false); pm_runtime_put_autosuspend(madera->dev); + } } static int madera_enable_fll(struct madera_fll *fll) @@ -3947,6 +4016,10 @@ static int madera_enable_fll(struct madera_fll *fll) regmap_update_bits(fll->madera->regmap, fll->base + MADERA_FLL_CONTROL_7_OFFS, MADERA_FLL1_GAIN_MASK, 0); + + if (sync_enabled > 0) + madera_set_fll_clks(fll, sync_base, false); + madera_set_fll_clks(fll, fll->base, false); } /* Apply SYNCCLK setting */ @@ -4025,11 +4098,15 @@ static int madera_enable_fll(struct madera_fll *fll) if (!already_enabled) pm_runtime_get_sync(madera->dev); - if (have_sync) + if (have_sync) { + madera_set_fll_clks(fll, sync_base, true); regmap_update_bits(madera->regmap, sync_base + MADERA_FLL_SYNCHRONISER_1_OFFS, MADERA_FLL1_SYNC_ENA, MADERA_FLL1_SYNC_ENA); + } + + madera_set_fll_clks(fll, fll->base, true); regmap_update_bits(madera->regmap, fll->base + MADERA_FLL_CONTROL_1_OFFS, MADERA_FLL1_ENA, MADERA_FLL1_ENA); @@ -4201,6 +4278,9 @@ static int madera_enable_fll_ao(struct madera_fll *fll, fll->base + MADERA_FLLAO_CONTROL_1_OFFS, MADERA_FLL_AO_HOLD, MADERA_FLL_AO_HOLD); + if (already_enabled) + madera_set_fllao_clks(fll, fll->base, false); + for (i = 0; i < patch_size; i++) { val = patch[i].def; @@ -4214,6 +4294,8 @@ static int madera_enable_fll_ao(struct madera_fll *fll, regmap_write(madera->regmap, patch[i].reg, val); } + madera_set_fllao_clks(fll, fll->base, true); + regmap_update_bits(madera->regmap, fll->base + MADERA_FLLAO_CONTROL_1_OFFS, MADERA_FLL_AO_ENA, MADERA_FLL_AO_ENA); @@ -4257,8 +4339,10 @@ static int madera_disable_fll_ao(struct madera_fll *fll) fll->base + MADERA_FLLAO_CONTROL_2_OFFS, MADERA_FLL_AO_CTRL_UPD_MASK, 0); - if (change) + if (change) { + madera_set_fllao_clks(fll, fll->base, false); pm_runtime_put_autosuspend(madera->dev); + } return 0; } @@ -4344,8 +4428,10 @@ static int madera_fllhj_disable(struct madera_fll *fll) fll->base + MADERA_FLL_CONTROL_2_OFFS, MADERA_FLL1_CTRL_UPD_MASK, 0); - if (change) + if (change) { + madera_set_fllhj_clks(fll, fll->base, false); pm_runtime_put_autosuspend(madera->dev); + } return 0; } @@ -4517,6 +4603,9 @@ static int madera_fllhj_enable(struct madera_fll *fll) MADERA_FLL1_HOLD_MASK, MADERA_FLL1_HOLD_MASK); + if (already_enabled) + madera_set_fllhj_clks(fll, fll->base, false); + /* Apply refclk */ ret = madera_fllhj_apply(fll, fll->ref_freq); if (ret) { @@ -4528,6 +4617,8 @@ static int madera_fllhj_enable(struct madera_fll *fll) CS47L92_FLL1_REFCLK_SRC_MASK, fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT); + madera_set_fllhj_clks(fll, fll->base, true); + regmap_update_bits(madera->regmap, fll->base + MADERA_FLL_CONTROL_1_OFFS, MADERA_FLL1_ENA_MASK, -- 2.20.1 _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx https://mailman.alsa-project.org/mailman/listinfo/alsa-devel