aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci/davinci-evm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci/davinci-evm.c')
-rw-r--r--sound/soc/davinci/davinci-evm.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 70ff3772079f..621e9a997d4c 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -17,6 +17,7 @@
17#include <linux/platform_data/edma.h> 17#include <linux/platform_data/edma.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/of_platform.h> 19#include <linux/of_platform.h>
20#include <linux/clk.h>
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
22#include <sound/soc.h> 23#include <sound/soc.h>
@@ -30,9 +31,34 @@
30#include "davinci-i2s.h" 31#include "davinci-i2s.h"
31 32
32struct snd_soc_card_drvdata_davinci { 33struct snd_soc_card_drvdata_davinci {
34 struct clk *mclk;
33 unsigned sysclk; 35 unsigned sysclk;
34}; 36};
35 37
38static int evm_startup(struct snd_pcm_substream *substream)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_card *soc_card = rtd->codec->card;
42 struct snd_soc_card_drvdata_davinci *drvdata =
43 snd_soc_card_get_drvdata(soc_card);
44
45 if (drvdata->mclk)
46 return clk_prepare_enable(drvdata->mclk);
47
48 return 0;
49}
50
51static void evm_shutdown(struct snd_pcm_substream *substream)
52{
53 struct snd_soc_pcm_runtime *rtd = substream->private_data;
54 struct snd_soc_card *soc_card = rtd->codec->card;
55 struct snd_soc_card_drvdata_davinci *drvdata =
56 snd_soc_card_get_drvdata(soc_card);
57
58 if (drvdata->mclk)
59 clk_disable_unprepare(drvdata->mclk);
60}
61
36static int evm_hw_params(struct snd_pcm_substream *substream, 62static int evm_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params) 63 struct snd_pcm_hw_params *params)
38{ 64{
@@ -59,6 +85,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
59} 85}
60 86
61static struct snd_soc_ops evm_ops = { 87static struct snd_soc_ops evm_ops = {
88 .startup = evm_startup,
89 .shutdown = evm_shutdown,
62 .hw_params = evm_hw_params, 90 .hw_params = evm_hw_params,
63}; 91};
64 92
@@ -348,6 +376,7 @@ static int davinci_evm_probe(struct platform_device *pdev)
348 of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); 376 of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
349 struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data; 377 struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
350 struct snd_soc_card_drvdata_davinci *drvdata = NULL; 378 struct snd_soc_card_drvdata_davinci *drvdata = NULL;
379 struct clk *mclk;
351 int ret = 0; 380 int ret = 0;
352 381
353 evm_soc_card.dai_link = dai; 382 evm_soc_card.dai_link = dai;
@@ -367,13 +396,38 @@ static int davinci_evm_probe(struct platform_device *pdev)
367 if (ret) 396 if (ret)
368 return ret; 397 return ret;
369 398
399 mclk = devm_clk_get(&pdev->dev, "mclk");
400 if (PTR_ERR(mclk) == -EPROBE_DEFER) {
401 return -EPROBE_DEFER;
402 } else if (IS_ERR(mclk)) {
403 dev_dbg(&pdev->dev, "mclk not found.\n");
404 mclk = NULL;
405 }
406
370 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 407 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
371 if (!drvdata) 408 if (!drvdata)
372 return -ENOMEM; 409 return -ENOMEM;
373 410
411 drvdata->mclk = mclk;
412
374 ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk); 413 ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
375 if (ret < 0) 414
376 return -EINVAL; 415 if (ret < 0) {
416 if (!drvdata->mclk) {
417 dev_err(&pdev->dev,
418 "No clock or clock rate defined.\n");
419 return -EINVAL;
420 }
421 drvdata->sysclk = clk_get_rate(drvdata->mclk);
422 } else if (drvdata->mclk) {
423 unsigned int requestd_rate = drvdata->sysclk;
424 clk_set_rate(drvdata->mclk, drvdata->sysclk);
425 drvdata->sysclk = clk_get_rate(drvdata->mclk);
426 if (drvdata->sysclk != requestd_rate)
427 dev_warn(&pdev->dev,
428 "Could not get requested rate %u using %u.\n",
429 requestd_rate, drvdata->sysclk);
430 }
377 431
378 snd_soc_card_set_drvdata(&evm_soc_card, drvdata); 432 snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
379 ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card); 433 ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
@@ -399,6 +453,7 @@ static struct platform_driver davinci_evm_driver = {
399 .driver = { 453 .driver = {
400 .name = "davinci_evm", 454 .name = "davinci_evm",
401 .owner = THIS_MODULE, 455 .owner = THIS_MODULE,
456 .pm = &snd_soc_pm_ops,
402 .of_match_table = of_match_ptr(davinci_evm_dt_ids), 457 .of_match_table = of_match_ptr(davinci_evm_dt_ids),
403 }, 458 },
404}; 459};