aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/mcbsp.c51
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h11
-rw-r--r--arch/arm/plat-omap/mcbsp.c3
-rw-r--r--sound/soc/omap/omap-mcbsp.c69
4 files changed, 75 insertions, 59 deletions
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 4c9c999dfa4a..51abcedfde83 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -52,6 +52,54 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux)
52} 52}
53EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); 53EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
54 54
55/* McBSP CLKS source switching function */
56
57int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
58{
59 struct omap_mcbsp *mcbsp;
60 struct clk *fck_src;
61 char *fck_src_name;
62 int r;
63
64 if (!omap_mcbsp_check_valid_id(id)) {
65 pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
66 return -EINVAL;
67 }
68 mcbsp = id_to_mcbsp_ptr(id);
69
70 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
71 fck_src_name = "pad_fck";
72 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
73 fck_src_name = "prcm_fck";
74 else
75 return -EINVAL;
76
77 fck_src = clk_get(mcbsp->dev, fck_src_name);
78 if (IS_ERR_OR_NULL(fck_src)) {
79 pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
80 fck_src_name);
81 return -EINVAL;
82 }
83
84 clk_disable(mcbsp->fclk);
85
86 r = clk_set_parent(mcbsp->fclk, fck_src);
87 if (IS_ERR_VALUE(r)) {
88 pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
89 "clks", fck_src_name);
90 clk_put(fck_src);
91 return -EINVAL;
92 }
93
94 clk_enable(mcbsp->fclk);
95
96 clk_put(fck_src);
97
98 return 0;
99}
100EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
101
102
55/* Platform data */ 103/* Platform data */
56 104
57#ifdef CONFIG_ARCH_OMAP2420 105#ifdef CONFIG_ARCH_OMAP2420
@@ -190,18 +238,21 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
190 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, 238 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
191 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, 239 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
192 .tx_irq = OMAP44XX_IRQ_MCBSP2, 240 .tx_irq = OMAP44XX_IRQ_MCBSP2,
241 /* XXX .ops ? */
193 }, 242 },
194 { 243 {
195 .phys_base = OMAP44XX_MCBSP3_BASE, 244 .phys_base = OMAP44XX_MCBSP3_BASE,
196 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, 245 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
197 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, 246 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
198 .tx_irq = OMAP44XX_IRQ_MCBSP3, 247 .tx_irq = OMAP44XX_IRQ_MCBSP3,
248 /* XXX .ops ? */
199 }, 249 },
200 { 250 {
201 .phys_base = OMAP44XX_MCBSP4_BASE, 251 .phys_base = OMAP44XX_MCBSP4_BASE,
202 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, 252 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
203 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, 253 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
204 .tx_irq = OMAP44XX_IRQ_MCBSP4, 254 .tx_irq = OMAP44XX_IRQ_MCBSP4,
255 /* XXX .ops ? */
205 }, 256 },
206}; 257};
207#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) 258#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata)
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 886d0e610aa7..4da6f94ae8e8 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -320,6 +320,10 @@
320#define FSR_SRC_FSR 0 320#define FSR_SRC_FSR 0
321#define FSR_SRC_FSX 1 321#define FSR_SRC_FSX 1
322 322
323/* McBSP functional clock sources */
324#define MCBSP_CLKS_PAD_SRC 0
325#define MCBSP_CLKS_PRCM_SRC 1
326
323/* we don't do multichannel for now */ 327/* we don't do multichannel for now */
324struct omap_mcbsp_reg_cfg { 328struct omap_mcbsp_reg_cfg {
325 u16 spcr2; 329 u16 spcr2;
@@ -406,6 +410,7 @@ struct omap_mcbsp_spi_cfg {
406struct omap_mcbsp_ops { 410struct omap_mcbsp_ops {
407 void (*request)(unsigned int); 411 void (*request)(unsigned int);
408 void (*free)(unsigned int); 412 void (*free)(unsigned int);
413 int (*set_clks_src)(u8, u8);
409}; 414};
410 415
411struct omap_mcbsp_platform_data { 416struct omap_mcbsp_platform_data {
@@ -472,6 +477,9 @@ struct omap_mcbsp {
472extern struct omap_mcbsp **mcbsp_ptr; 477extern struct omap_mcbsp **mcbsp_ptr;
473extern int omap_mcbsp_count, omap_mcbsp_cache_size; 478extern int omap_mcbsp_count, omap_mcbsp_cache_size;
474 479
480#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
481#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
482
475int omap_mcbsp_init(void); 483int omap_mcbsp_init(void);
476void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, 484void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
477 int size); 485 int size);
@@ -509,6 +517,9 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
509int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word); 517int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
510int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word); 518int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
511 519
520
521/* McBSP functional clock source changing function */
522extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
512/* SPI specific API */ 523/* SPI specific API */
513void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg); 524void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
514 525
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 9836fb5dc013..09f8c2871334 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -81,9 +81,6 @@ static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
81#define MCBSP_READ_CACHE(mcbsp, reg) \ 81#define MCBSP_READ_CACHE(mcbsp, reg) \
82 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1) 82 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
83 83
84#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
85#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
86
87#define MCBSP_ST_READ(mcbsp, reg) \ 84#define MCBSP_ST_READ(mcbsp, reg) \
88 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg) 85 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
89#define MCBSP_ST_WRITE(mcbsp, reg, val) \ 86#define MCBSP_ST_WRITE(mcbsp, reg, val) \
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index f50a5abb470f..b59ad11466a9 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -31,7 +31,6 @@
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33 33
34#include <plat/control.h>
35#include <plat/dma.h> 34#include <plat/dma.h>
36#include <plat/mcbsp.h> 35#include <plat/mcbsp.h>
37#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
@@ -608,66 +607,12 @@ static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
608 return 0; 607 return 0;
609} 608}
610 609
611static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
612 int clk_id)
613{
614 int sel_bit;
615 u16 reg, reg_devconf1 = OMAP243X_CONTROL_DEVCONF1;
616
617 if (cpu_class_is_omap1()) {
618 /* OMAP1's can use only external source clock */
619 if (unlikely(clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK))
620 return -EINVAL;
621 else
622 return 0;
623 }
624
625 if (cpu_is_omap2420() && mcbsp_data->bus_id > 1)
626 return -EINVAL;
627
628 if (cpu_is_omap343x())
629 reg_devconf1 = OMAP343X_CONTROL_DEVCONF1;
630
631 switch (mcbsp_data->bus_id) {
632 case 0:
633 reg = OMAP2_CONTROL_DEVCONF0;
634 sel_bit = 2;
635 break;
636 case 1:
637 reg = OMAP2_CONTROL_DEVCONF0;
638 sel_bit = 6;
639 break;
640 case 2:
641 reg = reg_devconf1;
642 sel_bit = 0;
643 break;
644 case 3:
645 reg = reg_devconf1;
646 sel_bit = 2;
647 break;
648 case 4:
649 reg = reg_devconf1;
650 sel_bit = 4;
651 break;
652 default:
653 return -EINVAL;
654 }
655
656 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK)
657 omap_ctrl_writel(omap_ctrl_readl(reg) & ~(1 << sel_bit), reg);
658 else
659 omap_ctrl_writel(omap_ctrl_readl(reg) | (1 << sel_bit), reg);
660
661 return 0;
662}
663
664static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 610static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
665 int clk_id, unsigned int freq, 611 int clk_id, unsigned int freq,
666 int dir) 612 int dir)
667{ 613{
668 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 614 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
669 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 615 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
670 struct omap_mcbsp_platform_data *pdata = cpu_dai->dev->platform_data;
671 int err = 0; 616 int err = 0;
672 617
673 /* The McBSP signal muxing functions are only available on McBSP1 */ 618 /* The McBSP signal muxing functions are only available on McBSP1 */
@@ -685,8 +630,20 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
685 regs->srgr2 |= CLKSM; 630 regs->srgr2 |= CLKSM;
686 break; 631 break;
687 case OMAP_MCBSP_SYSCLK_CLKS_FCLK: 632 case OMAP_MCBSP_SYSCLK_CLKS_FCLK:
633 if (cpu_class_is_omap1()) {
634 err = -EINVAL;
635 break;
636 }
637 err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id,
638 MCBSP_CLKS_PRCM_SRC);
639 break;
688 case OMAP_MCBSP_SYSCLK_CLKS_EXT: 640 case OMAP_MCBSP_SYSCLK_CLKS_EXT:
689 err = omap_mcbsp_dai_set_clks_src(mcbsp_data, clk_id); 641 if (cpu_class_is_omap1()) {
642 err = 0;
643 break;
644 }
645 err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id,
646 MCBSP_CLKS_PAD_SRC);
690 break; 647 break;
691 648
692 case OMAP_MCBSP_SYSCLK_CLKX_EXT: 649 case OMAP_MCBSP_SYSCLK_CLKX_EXT: