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: |
