diff options
-rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 51 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/mcbsp.h | 11 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 3 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcbsp.c | 69 |
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 | } |
53 | EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); | 53 | EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); |
54 | 54 | ||
55 | /* McBSP CLKS source switching function */ | ||
56 | |||
57 | int 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 | } | ||
100 | EXPORT_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 */ |
324 | struct omap_mcbsp_reg_cfg { | 328 | struct omap_mcbsp_reg_cfg { |
325 | u16 spcr2; | 329 | u16 spcr2; |
@@ -406,6 +410,7 @@ struct omap_mcbsp_spi_cfg { | |||
406 | struct omap_mcbsp_ops { | 410 | struct 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 | ||
411 | struct omap_mcbsp_platform_data { | 416 | struct omap_mcbsp_platform_data { |
@@ -472,6 +477,9 @@ struct omap_mcbsp { | |||
472 | extern struct omap_mcbsp **mcbsp_ptr; | 477 | extern struct omap_mcbsp **mcbsp_ptr; |
473 | extern int omap_mcbsp_count, omap_mcbsp_cache_size; | 478 | extern 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 | |||
475 | int omap_mcbsp_init(void); | 483 | int omap_mcbsp_init(void); |
476 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, | 484 | void 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 | |||
509 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word); | 517 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word); |
510 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word); | 518 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word); |
511 | 519 | ||
520 | |||
521 | /* McBSP functional clock source changing function */ | ||
522 | extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id); | ||
512 | /* SPI specific API */ | 523 | /* SPI specific API */ |
513 | void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg); | 524 | void 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 | ||
611 | static 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 | |||
664 | static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | 610 | static 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: |