aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/ux500/mop500.c4
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c55
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h1
-rw-r--r--sound/soc/ux500/ux500_pcm.c19
-rw-r--r--sound/soc/ux500/ux500_pcm.h3
5 files changed, 58 insertions, 24 deletions
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 54f7e25b6f7d..651a52a95fd7 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -33,7 +33,7 @@ struct snd_soc_dai_link mop500_dai_links[] = {
33 .stream_name = "ab8500_0", 33 .stream_name = "ab8500_0",
34 .cpu_dai_name = "ux500-msp-i2s.1", 34 .cpu_dai_name = "ux500-msp-i2s.1",
35 .codec_dai_name = "ab8500-codec-dai.0", 35 .codec_dai_name = "ab8500-codec-dai.0",
36 .platform_name = "ux500-pcm.0", 36 .platform_name = "ux500-msp-i2s.1",
37 .codec_name = "ab8500-codec.0", 37 .codec_name = "ab8500-codec.0",
38 .init = mop500_ab8500_machine_init, 38 .init = mop500_ab8500_machine_init,
39 .ops = mop500_ab8500_ops, 39 .ops = mop500_ab8500_ops,
@@ -43,7 +43,7 @@ struct snd_soc_dai_link mop500_dai_links[] = {
43 .stream_name = "ab8500_1", 43 .stream_name = "ab8500_1",
44 .cpu_dai_name = "ux500-msp-i2s.3", 44 .cpu_dai_name = "ux500-msp-i2s.3",
45 .codec_dai_name = "ab8500-codec-dai.1", 45 .codec_dai_name = "ab8500-codec-dai.1",
46 .platform_name = "ux500-pcm.0", 46 .platform_name = "ux500-msp-i2s.3",
47 .codec_name = "ab8500-codec.0", 47 .codec_name = "ab8500-codec.0",
48 .init = NULL, 48 .init = NULL,
49 .ops = mop500_ab8500_ops, 49 .ops = mop500_ab8500_ops,
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index be94bf9bf94f..478b4b60e0cc 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -28,6 +28,7 @@
28 28
29#include "ux500_msp_i2s.h" 29#include "ux500_msp_i2s.h"
30#include "ux500_msp_dai.h" 30#include "ux500_msp_dai.h"
31#include "ux500_pcm.h"
31 32
32static int setup_pcm_multichan(struct snd_soc_dai *dai, 33static int setup_pcm_multichan(struct snd_soc_dai *dai,
33 struct ux500_msp_config *msp_config) 34 struct ux500_msp_config *msp_config)
@@ -398,11 +399,28 @@ static int ux500_msp_dai_startup(struct snd_pcm_substream *substream,
398 return ret; 399 return ret;
399 } 400 }
400 401
401 /* Enable clock */ 402 /* Prepare and enable clocks */
402 dev_dbg(dai->dev, "%s: Enabling MSP-clock.\n", __func__); 403 dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__);
403 clk_enable(drvdata->clk); 404 ret = clk_prepare_enable(drvdata->pclk);
405 if (ret) {
406 dev_err(drvdata->msp->dev,
407 "%s: Failed to prepare/enable pclk!\n", __func__);
408 goto err_pclk;
409 }
404 410
405 return 0; 411 ret = clk_prepare_enable(drvdata->clk);
412 if (ret) {
413 dev_err(drvdata->msp->dev,
414 "%s: Failed to prepare/enable clk!\n", __func__);
415 goto err_clk;
416 }
417
418 return ret;
419err_clk:
420 clk_disable_unprepare(drvdata->pclk);
421err_pclk:
422 regulator_disable(drvdata->reg_vape);
423 return ret;
406} 424}
407 425
408static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream, 426static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
@@ -428,8 +446,9 @@ static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
428 __func__, dai->id, snd_pcm_stream_str(substream)); 446 __func__, dai->id, snd_pcm_stream_str(substream));
429 } 447 }
430 448
431 /* Disable clock */ 449 /* Disable and unprepare clocks */
432 clk_disable(drvdata->clk); 450 clk_disable_unprepare(drvdata->clk);
451 clk_disable_unprepare(drvdata->pclk);
433 452
434 /* Disable regulator */ 453 /* Disable regulator */
435 ret = regulator_disable(drvdata->reg_vape); 454 ret = regulator_disable(drvdata->reg_vape);
@@ -780,6 +799,14 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
780 } 799 }
781 prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50); 800 prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50);
782 801
802 drvdata->pclk = clk_get(&pdev->dev, "apb_pclk");
803 if (IS_ERR(drvdata->pclk)) {
804 ret = (int)PTR_ERR(drvdata->pclk);
805 dev_err(&pdev->dev, "%s: ERROR: clk_get of pclk failed (%d)!\n",
806 __func__, ret);
807 goto err_pclk;
808 }
809
783 drvdata->clk = clk_get(&pdev->dev, NULL); 810 drvdata->clk = clk_get(&pdev->dev, NULL);
784 if (IS_ERR(drvdata->clk)) { 811 if (IS_ERR(drvdata->clk)) {
785 ret = (int)PTR_ERR(drvdata->clk); 812 ret = (int)PTR_ERR(drvdata->clk);
@@ -806,12 +833,23 @@ static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
806 goto err_init_msp; 833 goto err_init_msp;
807 } 834 }
808 835
836 ret = ux500_pcm_register_platform(pdev);
837 if (ret < 0) {
838 dev_err(&pdev->dev,
839 "Error: %s: Failed to register PCM platform device!\n",
840 __func__);
841 goto err_reg_plat;
842 }
843
809 return 0; 844 return 0;
810 845
846err_reg_plat:
847 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
811err_init_msp: 848err_init_msp:
812 clk_put(drvdata->clk); 849 clk_put(drvdata->clk);
813
814err_clk: 850err_clk:
851 clk_put(drvdata->pclk);
852err_pclk:
815 devm_regulator_put(drvdata->reg_vape); 853 devm_regulator_put(drvdata->reg_vape);
816 854
817 return ret; 855 return ret;
@@ -821,12 +859,15 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
821{ 859{
822 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 860 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
823 861
862 ux500_pcm_unregister_platform(pdev);
863
824 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); 864 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
825 865
826 devm_regulator_put(drvdata->reg_vape); 866 devm_regulator_put(drvdata->reg_vape);
827 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); 867 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
828 868
829 clk_put(drvdata->clk); 869 clk_put(drvdata->clk);
870 clk_put(drvdata->pclk);
830 871
831 ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp); 872 ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
832 873
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 98202a34a5dd..9c778d9c3838 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -69,6 +69,7 @@ struct ux500_msp_i2s_drvdata {
69 /* Clocks */ 69 /* Clocks */
70 unsigned int master_clk; 70 unsigned int master_clk;
71 struct clk *clk; 71 struct clk *clk;
72 struct clk *pclk;
72 73
73 /* Regulators */ 74 /* Regulators */
74 int vape_opp_constraint; 75 int vape_opp_constraint;
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 1a04e248453c..894c9f4bb9f6 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -282,7 +282,7 @@ static struct snd_soc_platform_driver ux500_pcm_soc_drv = {
282 .pcm_new = ux500_pcm_new, 282 .pcm_new = ux500_pcm_new,
283}; 283};
284 284
285static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev) 285int __devinit ux500_pcm_register_platform(struct platform_device *pdev)
286{ 286{
287 int ret; 287 int ret;
288 288
@@ -296,23 +296,12 @@ static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev)
296 296
297 return 0; 297 return 0;
298} 298}
299EXPORT_SYMBOL_GPL(ux500_pcm_register_platform);
299 300
300static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev) 301int __devexit ux500_pcm_unregister_platform(struct platform_device *pdev)
301{ 302{
302 snd_soc_unregister_platform(&pdev->dev); 303 snd_soc_unregister_platform(&pdev->dev);
303 304
304 return 0; 305 return 0;
305} 306}
306 307EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform);
307static struct platform_driver ux500_pcm_driver = {
308 .driver = {
309 .name = "ux500-pcm",
310 .owner = THIS_MODULE,
311 },
312
313 .probe = ux500_pcm_drv_probe,
314 .remove = __devexit_p(ux500_pcm_drv_remove),
315};
316module_platform_driver(ux500_pcm_driver);
317
318MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index 77ed44d371e9..76d344476afc 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -32,4 +32,7 @@
32#define UX500_PLATFORM_PERIODS_MAX 48 32#define UX500_PLATFORM_PERIODS_MAX 48
33#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) 33#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
34 34
35int ux500_pcm_register_platform(struct platform_device *pdev);
36int ux500_pcm_unregister_platform(struct platform_device *pdev);
37
35#endif 38#endif