summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2016-05-18 09:46:36 -0400
committerMark Brown <broonie@kernel.org>2016-05-30 11:19:17 -0400
commit65aca64d05b5eaa5ce15e18b458a8d338ddbd478 (patch)
tree542ac7ca09adcc1acf2fb533bd8f7520cfe93816
parent4a5c83744feb7608422e6c23fa4cce85569b678c (diff)
ASoC: omap-mcpdm: Add support for pdmclk clock handling
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. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/omap-mcpdm.txt10
-rw-r--r--sound/soc/omap/omap-mcpdm.c17
2 files changed, 27 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/omap-mcpdm.txt b/Documentation/devicetree/bindings/sound/omap-mcpdm.txt
index 0741dff048dd..6f6c2f8e908d 100644
--- a/Documentation/devicetree/bindings/sound/omap-mcpdm.txt
+++ b/Documentation/devicetree/bindings/sound/omap-mcpdm.txt
@@ -8,6 +8,8 @@ Required properties:
8- interrupts: Interrupt number for McPDM 8- interrupts: Interrupt number for McPDM
9- interrupt-parent: The parent interrupt controller 9- interrupt-parent: The parent interrupt controller
10- ti,hwmods: Name of the hwmod associated to the McPDM 10- ti,hwmods: Name of the hwmod associated to the McPDM
11- clocks: phandle for the pdmclk provider, likely <&twl6040>
12- clock-names: Must be "pdmclk"
11 13
12Example: 14Example:
13 15
@@ -19,3 +21,11 @@ mcpdm: mcpdm@40132000 {
19 interrupt-parent = <&gic>; 21 interrupt-parent = <&gic>;
20 ti,hwmods = "mcpdm"; 22 ti,hwmods = "mcpdm";
21}; 23};
24
25In board DTS file the pdmclk needs to be added:
26
27&mcpdm {
28 clocks = <&twl6040>;
29 clock-names = "pdmclk";
30 status = "okay";
31};
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 74d6e6fdcfd0..e7cdc51fd806 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -31,6 +31,7 @@
31#include <linux/err.h> 31#include <linux/err.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/clk.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
36#include <linux/of_device.h> 37#include <linux/of_device.h>
@@ -54,6 +55,7 @@ struct omap_mcpdm {
54 unsigned long phys_base; 55 unsigned long phys_base;
55 void __iomem *io_base; 56 void __iomem *io_base;
56 int irq; 57 int irq;
58 struct clk *pdmclk;
57 59
58 struct mutex mutex; 60 struct mutex mutex;
59 61
@@ -388,6 +390,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
388 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 390 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
389 int ret; 391 int ret;
390 392
393 clk_prepare_enable(mcpdm->pdmclk);
391 pm_runtime_enable(mcpdm->dev); 394 pm_runtime_enable(mcpdm->dev);
392 395
393 /* Disable lines while request is ongoing */ 396 /* Disable lines while request is ongoing */
@@ -422,6 +425,7 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
422 425
423 pm_runtime_disable(mcpdm->dev); 426 pm_runtime_disable(mcpdm->dev);
424 427
428 clk_disable_unprepare(mcpdm->pdmclk);
425 return 0; 429 return 0;
426} 430}
427 431
@@ -441,6 +445,8 @@ static int omap_mcpdm_suspend(struct snd_soc_dai *dai)
441 mcpdm->pm_active_count++; 445 mcpdm->pm_active_count++;
442 } 446 }
443 447
448 clk_disable_unprepare(mcpdm->pdmclk);
449
444 return 0; 450 return 0;
445} 451}
446 452
@@ -448,6 +454,8 @@ static int omap_mcpdm_resume(struct snd_soc_dai *dai)
448{ 454{
449 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 455 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
450 456
457 clk_prepare_enable(mcpdm->pdmclk);
458
451 if (mcpdm->pm_active_count) { 459 if (mcpdm->pm_active_count) {
452 while (mcpdm->pm_active_count--) 460 while (mcpdm->pm_active_count--)
453 pm_runtime_get_sync(mcpdm->dev); 461 pm_runtime_get_sync(mcpdm->dev);
@@ -541,6 +549,15 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
541 549
542 mcpdm->dev = &pdev->dev; 550 mcpdm->dev = &pdev->dev;
543 551
552 mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk");
553 if (IS_ERR(mcpdm->pdmclk)) {
554 if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER)
555 return -EPROBE_DEFER;
556 dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n",
557 PTR_ERR(mcpdm->pdmclk));
558 mcpdm->pdmclk = NULL;
559 }
560
544 ret = devm_snd_soc_register_component(&pdev->dev, 561 ret = devm_snd_soc_register_component(&pdev->dev,
545 &omap_mcpdm_component, 562 &omap_mcpdm_component,
546 &omap_mcpdm_dai, 1); 563 &omap_mcpdm_dai, 1);