[alsa-devel] [PATCH] ASoC: ti: davinci-mcasp: Improve the sysclk selection
When McASP is master the bclk can be generated from two main source: AUXCLK: functional clock for McASP or AHCLK: from external source or internal mux in dra7x family
With this patch it is possible to select between the two source. The patch is not breaking existing machine drivers since historically the clk_id was ignored and left as 0 in all cases.
When output clock is configured - which can be only the AHCLK, we select the AUXCLK as source for the internal HCLK. In this case the HCLK rate is the same as the output clock.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/ti/davinci-mcasp.c | 35 ++++++++++++++++++++++++++++------- sound/soc/ti/davinci-mcasp.h | 4 ++++ 2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index 8e5371801d88..e1e937eb1dc1 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -664,18 +664,39 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
pm_runtime_get_sync(mcasp->dev); - if (dir == SND_SOC_CLOCK_OUT) { + + if (dir == SND_SOC_CLOCK_IN) { + switch (clk_id) { + case MCASP_CLK_HCLK_AHCLK: + mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, + AHCLKXE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, + AHCLKRE); + clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); + break; + case MCASP_CLK_HCLK_AUXCLK: + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, + AHCLKXE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, + AHCLKRE); + set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); + break; + default: + dev_err(mcasp->dev, "Invalid clk id: %d\n", clk_id); + goto out; + } + } else { + /* Select AUXCLK as HCLK */ mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); - } else { - mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); - clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); } - + /* + * When AHCLK X/R is selected to be output it means that the HCLK is + * the same clock - coming via AUXCLK. + */ mcasp->sysclk_freq = freq; - +out: pm_runtime_put(mcasp->dev); return 0; } diff --git a/sound/soc/ti/davinci-mcasp.h b/sound/soc/ti/davinci-mcasp.h index bc705d6ca48b..5de2b8a31061 100644 --- a/sound/soc/ti/davinci-mcasp.h +++ b/sound/soc/ti/davinci-mcasp.h @@ -295,6 +295,10 @@ #define NUMEVT(x) (((x) & 0xFF) << 8) #define NUMDMA_MASK (0xFF)
+/* Source of High-frequency transmit/receive clock */ +#define MCASP_CLK_HCLK_AHCLK 0 /* AHCLKX/R */ +#define MCASP_CLK_HCLK_AUXCLK 1 /* Internal functional clock */ + /* clock divider IDs */ #define MCASP_CLKDIV_AUXCLK 0 /* HCLK divider from AUXCLK */ #define MCASP_CLKDIV_BCLK 1 /* BCLK divider from HCLK */
The patch
ASoC: ti: davinci-mcasp: Improve the sysclk selection
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 253f584a0699d12a90bde9d524d499a921cc7827 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi peter.ujfalusi@ti.com Date: Wed, 4 Dec 2019 21:20:05 +0200 Subject: [PATCH] ASoC: ti: davinci-mcasp: Improve the sysclk selection
When McASP is master the bclk can be generated from two main source: AUXCLK: functional clock for McASP or AHCLK: from external source or internal mux in dra7x family
With this patch it is possible to select between the two source. The patch is not breaking existing machine drivers since historically the clk_id was ignored and left as 0 in all cases.
When output clock is configured - which can be only the AHCLK, we select the AUXCLK as source for the internal HCLK. In this case the HCLK rate is the same as the output clock.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Link: https://lore.kernel.org/r/20191204192005.31210-1-peter.ujfalusi@ti.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/ti/davinci-mcasp.c | 35 ++++++++++++++++++++++++++++------- sound/soc/ti/davinci-mcasp.h | 4 ++++ 2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index 8e5371801d88..e1e937eb1dc1 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -664,18 +664,39 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
pm_runtime_get_sync(mcasp->dev); - if (dir == SND_SOC_CLOCK_OUT) { + + if (dir == SND_SOC_CLOCK_IN) { + switch (clk_id) { + case MCASP_CLK_HCLK_AHCLK: + mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, + AHCLKXE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, + AHCLKRE); + clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); + break; + case MCASP_CLK_HCLK_AUXCLK: + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, + AHCLKXE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, + AHCLKRE); + set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); + break; + default: + dev_err(mcasp->dev, "Invalid clk id: %d\n", clk_id); + goto out; + } + } else { + /* Select AUXCLK as HCLK */ mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); set_bit(PIN_BIT_AHCLKX, &mcasp->pdir); - } else { - mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); - clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir); } - + /* + * When AHCLK X/R is selected to be output it means that the HCLK is + * the same clock - coming via AUXCLK. + */ mcasp->sysclk_freq = freq; - +out: pm_runtime_put(mcasp->dev); return 0; } diff --git a/sound/soc/ti/davinci-mcasp.h b/sound/soc/ti/davinci-mcasp.h index bc705d6ca48b..5de2b8a31061 100644 --- a/sound/soc/ti/davinci-mcasp.h +++ b/sound/soc/ti/davinci-mcasp.h @@ -295,6 +295,10 @@ #define NUMEVT(x) (((x) & 0xFF) << 8) #define NUMDMA_MASK (0xFF)
+/* Source of High-frequency transmit/receive clock */ +#define MCASP_CLK_HCLK_AHCLK 0 /* AHCLKX/R */ +#define MCASP_CLK_HCLK_AUXCLK 1 /* Internal functional clock */ + /* clock divider IDs */ #define MCASP_CLKDIV_AUXCLK 0 /* HCLK divider from AUXCLK */ #define MCASP_CLKDIV_BCLK 1 /* BCLK divider from HCLK */
participants (2)
-
Mark Brown
-
Peter Ujfalusi