aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/omap/am3517evm.c20
-rw-r--r--sound/soc/omap/mcbsp.c31
-rw-r--r--sound/soc/omap/mcbsp.h3
-rw-r--r--sound/soc/omap/omap-mcbsp.c106
-rw-r--r--sound/soc/omap/omap-mcbsp.h20
5 files changed, 101 insertions, 79 deletions
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 009533ab8d18..a997988af147 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -47,26 +47,10 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
47 /* Set the codec system clock for DAC and ADC */ 47 /* Set the codec system clock for DAC and ADC */
48 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 48 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
49 CODEC_CLOCK, SND_SOC_CLOCK_IN); 49 CODEC_CLOCK, SND_SOC_CLOCK_IN);
50 if (ret < 0) { 50 if (ret < 0)
51 printk(KERN_ERR "can't set codec system clock\n"); 51 printk(KERN_ERR "can't set codec system clock\n");
52 return ret;
53 }
54
55 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
56 SND_SOC_CLOCK_IN);
57 if (ret < 0) {
58 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
59 return ret;
60 }
61 52
62 snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, 53 return ret;
63 SND_SOC_CLOCK_IN);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
66 return ret;
67 }
68
69 return 0;
70} 54}
71 55
72static struct snd_soc_ops am3517evm_ops = { 56static struct snd_soc_ops am3517evm_ops = {
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 34835e8a9160..6afbc26cef70 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -24,6 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pm_runtime.h>
27 28
28#include <plat/mcbsp.h> 29#include <plat/mcbsp.h>
29 30
@@ -726,19 +727,39 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
726 727
727int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) 728int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
728{ 729{
730 struct clk *fck_src;
729 const char *src; 731 const char *src;
732 int r;
730 733
731 if (fck_src_id == MCBSP_CLKS_PAD_SRC) 734 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
732 src = "clks_ext"; 735 src = "pad_fck";
733 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) 736 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
734 src = "clks_fclk"; 737 src = "prcm_fck";
735 else 738 else
736 return -EINVAL; 739 return -EINVAL;
737 740
738 if (mcbsp->pdata->set_clk_src) 741 fck_src = clk_get(mcbsp->dev, src);
739 return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src); 742 if (IS_ERR(fck_src)) {
740 else 743 dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
741 return -EINVAL; 744 return -EINVAL;
745 }
746
747 pm_runtime_put_sync(mcbsp->dev);
748
749 r = clk_set_parent(mcbsp->fclk, fck_src);
750 if (r) {
751 dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
752 src);
753 clk_put(fck_src);
754 return r;
755 }
756
757 pm_runtime_get_sync(mcbsp->dev);
758
759 clk_put(fck_src);
760
761 return 0;
762
742} 763}
743 764
744int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) 765int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index 262a6152111f..49a67259ce5a 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -334,9 +334,6 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx);
334/* McBSP functional clock source changing function */ 334/* McBSP functional clock source changing function */
335int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); 335int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);
336 336
337/* McBSP signal muxing API */
338int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);
339
340/* Sidetone specific API */ 337/* Sidetone specific API */
341int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); 338int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
342int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); 339int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index acdd3ef14e08..d6de066ad7ea 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -26,6 +26,8 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/of.h>
30#include <linux/of_device.h>
29#include <sound/core.h> 31#include <sound/core.h>
30#include <sound/pcm.h> 32#include <sound/pcm.h>
31#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
@@ -398,12 +400,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
398 /* Generic McBSP register settings */ 400 /* Generic McBSP register settings */
399 regs->spcr2 |= XINTM(3) | FREE; 401 regs->spcr2 |= XINTM(3) | FREE;
400 regs->spcr1 |= RINTM(3); 402 regs->spcr1 |= RINTM(3);
401 /* RFIG and XFIG are not defined in 34xx */ 403 /* RFIG and XFIG are not defined in 2430 and on OMAP3+ */
402 if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { 404 if (!mcbsp->pdata->has_ccr) {
403 regs->rcr2 |= RFIG; 405 regs->rcr2 |= RFIG;
404 regs->xcr2 |= XFIG; 406 regs->xcr2 |= XFIG;
405 } 407 }
406 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { 408
409 /* Configure XCCR/RCCR only for revisions which have ccr registers */
410 if (mcbsp->pdata->has_ccr) {
407 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; 411 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
408 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; 412 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
409 } 413 }
@@ -516,21 +520,9 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
516 return -EBUSY; 520 return -EBUSY;
517 } 521 }
518 522
519 if (clk_id == OMAP_MCBSP_SYSCLK_CLK || 523 mcbsp->in_freq = freq;
520 clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK || 524 regs->srgr2 &= ~CLKSM;
521 clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT || 525 regs->pcr0 &= ~SCLKME;
522 clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT ||
523 clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) {
524 mcbsp->in_freq = freq;
525 regs->srgr2 &= ~CLKSM;
526 regs->pcr0 &= ~SCLKME;
527 } else if (cpu_class_is_omap1()) {
528 /*
529 * McBSP CLKR/FSR signal muxing functions are only available on
530 * OMAP2 or newer versions
531 */
532 return -EINVAL;
533 }
534 526
535 switch (clk_id) { 527 switch (clk_id) {
536 case OMAP_MCBSP_SYSCLK_CLK: 528 case OMAP_MCBSP_SYSCLK_CLK:
@@ -558,20 +550,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
558 case OMAP_MCBSP_SYSCLK_CLKR_EXT: 550 case OMAP_MCBSP_SYSCLK_CLKR_EXT:
559 regs->pcr0 |= SCLKME; 551 regs->pcr0 |= SCLKME;
560 break; 552 break;
561
562
563 case OMAP_MCBSP_CLKR_SRC_CLKR:
564 err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR);
565 break;
566 case OMAP_MCBSP_CLKR_SRC_CLKX:
567 err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX);
568 break;
569 case OMAP_MCBSP_FSR_SRC_FSR:
570 err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR);
571 break;
572 case OMAP_MCBSP_FSR_SRC_FSX:
573 err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX);
574 break;
575 default: 553 default:
576 err = -ENODEV; 554 err = -ENODEV;
577 } 555 }
@@ -761,13 +739,74 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
761} 739}
762EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); 740EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
763 741
742static struct omap_mcbsp_platform_data omap2420_pdata = {
743 .reg_step = 4,
744 .reg_size = 2,
745};
746
747static struct omap_mcbsp_platform_data omap2430_pdata = {
748 .reg_step = 4,
749 .reg_size = 4,
750 .has_ccr = true,
751};
752
753static struct omap_mcbsp_platform_data omap3_pdata = {
754 .reg_step = 4,
755 .reg_size = 4,
756 .has_ccr = true,
757 .has_wakeup = true,
758};
759
760static struct omap_mcbsp_platform_data omap4_pdata = {
761 .reg_step = 4,
762 .reg_size = 4,
763 .has_ccr = true,
764 .has_wakeup = true,
765};
766
767static const struct of_device_id omap_mcbsp_of_match[] = {
768 {
769 .compatible = "ti,omap2420-mcbsp",
770 .data = &omap2420_pdata,
771 },
772 {
773 .compatible = "ti,omap2430-mcbsp",
774 .data = &omap2430_pdata,
775 },
776 {
777 .compatible = "ti,omap3-mcbsp",
778 .data = &omap3_pdata,
779 },
780 {
781 .compatible = "ti,omap4-mcbsp",
782 .data = &omap4_pdata,
783 },
784 { },
785};
786MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match);
787
764static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) 788static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
765{ 789{
766 struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); 790 struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
767 struct omap_mcbsp *mcbsp; 791 struct omap_mcbsp *mcbsp;
792 const struct of_device_id *match;
768 int ret; 793 int ret;
769 794
770 if (!pdata) { 795 match = of_match_device(omap_mcbsp_of_match, &pdev->dev);
796 if (match) {
797 struct device_node *node = pdev->dev.of_node;
798 int buffer_size;
799
800 pdata = devm_kzalloc(&pdev->dev,
801 sizeof(struct omap_mcbsp_platform_data),
802 GFP_KERNEL);
803 if (!pdata)
804 return -ENOMEM;
805
806 memcpy(pdata, match->data, sizeof(*pdata));
807 if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size))
808 pdata->buffer_size = buffer_size;
809 } else if (!pdata) {
771 dev_err(&pdev->dev, "missing platform data.\n"); 810 dev_err(&pdev->dev, "missing platform data.\n");
772 return -EINVAL; 811 return -EINVAL;
773 } 812 }
@@ -809,6 +848,7 @@ static struct platform_driver asoc_mcbsp_driver = {
809 .driver = { 848 .driver = {
810 .name = "omap-mcbsp", 849 .name = "omap-mcbsp",
811 .owner = THIS_MODULE, 850 .owner = THIS_MODULE,
851 .of_match_table = omap_mcbsp_of_match,
812 }, 852 },
813 853
814 .probe = asoc_mcbsp_probe, 854 .probe = asoc_mcbsp_probe,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index f877b16f19c9..ba8386a0d8dc 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -32,10 +32,6 @@ enum omap_mcbsp_clksrg_clk {
32 OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ 32 OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */
33 OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ 33 OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */
34 OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ 34 OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */
35 OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */
36 OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */
37 OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */
38 OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */
39}; 35};
40 36
41/* McBSP dividers */ 37/* McBSP dividers */
@@ -43,22 +39,6 @@ enum omap_mcbsp_div {
43 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ 39 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
44}; 40};
45 41
46#if defined(CONFIG_SOC_OMAP2420)
47#define NUM_LINKS 2
48#endif
49#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
50#undef NUM_LINKS
51#define NUM_LINKS 3
52#endif
53#if defined(CONFIG_ARCH_OMAP4)
54#undef NUM_LINKS
55#define NUM_LINKS 4
56#endif
57#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430)
58#undef NUM_LINKS
59#define NUM_LINKS 5
60#endif
61
62int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); 42int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
63 43
64#endif 44#endif