Message ID | 20191025130528.3556-1-peter.ujfalusi@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] ASoC: ti: omap-mcpdm: Add support for pdmclk clock handling | expand |
Hi, * Peter Ujfalusi <peter.ujfalusi@ti.com> [191025 13:05]: > McPDM module receives it's functional clock from external source. This > clock is the pdmclk provided by the twl6040 audio IC. If the clock is not > available all register accesses to McPDM fails and the module is not > operational. > > this has been lurking in my next-wip branch for some time... > It might not needed anymore as I have not heard about issues with McPDM for a > while. > > It was dropped back then because some core parts were not picked in time and > this caused some issues, but can not find the exact reason Yes it's a strange solution to clock the internal mcpdm module externally :) AFAIK it's now already handled properly by ti-sysc. We have a common omap4-mcpdm.dtsi configure mcpdm clock forthe module, then ti-sysc driver defers probe until the mcpdm clock is available. And for omap5 we have omap5-board-common.dtsi configure it. So probably the only thing omap-mcpdm.c driver needs to do is to call PM runtime functions, maybe it's already doing that. Regards, Tony
On 10/25/19 8:17 PM, Tony Lindgren wrote: > Hi, > > * Peter Ujfalusi <peter.ujfalusi@ti.com> [191025 13:05]: >> McPDM module receives it's functional clock from external source. This >> clock is the pdmclk provided by the twl6040 audio IC. If the clock is not >> available all register accesses to McPDM fails and the module is not >> operational. >> >> this has been lurking in my next-wip branch for some time... >> It might not needed anymore as I have not heard about issues with McPDM for a >> while. >> >> It was dropped back then because some core parts were not picked in time and >> this caused some issues, but can not find the exact reason > > Yes it's a strange solution to clock the internal mcpdm module > externally :) Strange is a bit of understatement ;) > AFAIK it's now already handled properly by ti-sysc. We have a common > omap4-mcpdm.dtsi configure mcpdm clock forthe module, then ti-sysc > driver defers probe until the mcpdm clock is available. And for omap5 > we have omap5-board-common.dtsi configure it. I see that the clocks = <&twl6040>; clock-names = "pdmclk"; are added to the mcpdm node (some patch from me, some new). But the McPDM driver itself never requests this clock w/o this patch. > So probably the only thing omap-mcpdm.c driver needs to do is to > call PM runtime functions, maybe it's already doing that. Yes, it has support for pm_runtime. Looking at ti-sci I think I know why it works. ti-sci will get the 'pdmclk' as a clock for the device and going to manage it because the SYSC_QUIRK_EXT_OPT_CLOCK is set for McPDM. So pm_runtime is going to handle the clock coming from twl6040. And now I remember to test these ti-sci changes :o I wonder why I have not dropped this patch back then from my wip branch. Let's just ignore this patch. - Peter Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
diff --git a/sound/soc/ti/omap-mcpdm.c b/sound/soc/ti/omap-mcpdm.c index b8c8290265c7..2c536947b69f 100644 --- a/sound/soc/ti/omap-mcpdm.c +++ b/sound/soc/ti/omap-mcpdm.c @@ -17,6 +17,7 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/clk.h> #include <linux/slab.h> #include <linux/pm_runtime.h> #include <linux/of_device.h> @@ -42,6 +43,7 @@ struct omap_mcpdm { int irq; struct pm_qos_request pm_qos_req; int latency[2]; + struct clk *pdmclk; struct mutex mutex; @@ -416,6 +418,10 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); int ret; + ret = clk_prepare_enable(mcpdm->pdmclk); + if (ret) + return ret; + pm_runtime_enable(mcpdm->dev); /* Disable lines while request is ongoing */ @@ -454,6 +460,7 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) if (pm_qos_request_active(&mcpdm->pm_qos_req)) pm_qos_remove_request(&mcpdm->pm_qos_req); + clk_disable_unprepare(mcpdm->pdmclk); return 0; } @@ -473,12 +480,19 @@ static int omap_mcpdm_suspend(struct snd_soc_dai *dai) mcpdm->pm_active_count++; } + clk_disable_unprepare(mcpdm->pdmclk); + return 0; } static int omap_mcpdm_resume(struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = clk_prepare_enable(mcpdm->pdmclk); + if (ret) + return ret; if (mcpdm->pm_active_count) { while (mcpdm->pm_active_count--) @@ -573,6 +587,15 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dev = &pdev->dev; + mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk"); + if (IS_ERR(mcpdm->pdmclk)) { + if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n", + PTR_ERR(mcpdm->pdmclk)); + mcpdm->pdmclk = NULL; + } + ret = devm_snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, &omap_mcpdm_dai, 1);