diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/omap-mcpdm.txt | 10 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcpdm.c | 17 |
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 | ||
12 | Example: | 14 | Example: |
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 | |||
25 | In 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); |