summaryrefslogtreecommitdiffstats
path: root/sound/soc/ti/davinci-mcasp.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2019-12-04 21:20:05 +0200
committerMark Brown <broonie@kernel.org>2019-12-09 18:35:37 +0000
commit253f584a0699d12a90bde9d524d499a921cc7827 (patch)
tree9602decdb31094a1ba8600cc81b076ee86297741 /sound/soc/ti/davinci-mcasp.c
parentabe3b6727b653307c27870a2d4ecbf9de4e914a5 (diff)
downloadlinux-253f584a0699d12a90bde9d524d499a921cc7827.tar.bz2
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>
Diffstat (limited to 'sound/soc/ti/davinci-mcasp.c')
-rw-r--r--sound/soc/ti/davinci-mcasp.c35
1 files changed, 28 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;
}