diff options
| -rw-r--r-- | arch/arm/mach-omap2/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clock34xx.h | 30 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 208 |
3 files changed, 230 insertions, 10 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index c2477428e351..93ee990618ef 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ | 6 | obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ |
| 7 | devices.o serial.o gpmc.o timer-gp.o | 7 | devices.o serial.o gpmc.o timer-gp.o |
| 8 | 8 | ||
| 9 | obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o | ||
| 10 | |||
| 9 | # Functions loaded to SRAM | 11 | # Functions loaded to SRAM |
| 10 | obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o | 12 | obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o |
| 11 | obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o | 13 | obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o |
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index c9c5972a2e25..73624dc04c97 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
| @@ -1365,7 +1365,8 @@ static const struct clksel mcbsp_15_clksel[] = { | |||
| 1365 | }; | 1365 | }; |
| 1366 | 1366 | ||
| 1367 | static struct clk mcbsp5_fck = { | 1367 | static struct clk mcbsp5_fck = { |
| 1368 | .name = "mcbsp5_fck", | 1368 | .name = "mcbsp_fck", |
| 1369 | .id = 5, | ||
| 1369 | .init = &omap2_init_clksel_parent, | 1370 | .init = &omap2_init_clksel_parent, |
| 1370 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1371 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
| 1371 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, | 1372 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, |
| @@ -1377,7 +1378,8 @@ static struct clk mcbsp5_fck = { | |||
| 1377 | }; | 1378 | }; |
| 1378 | 1379 | ||
| 1379 | static struct clk mcbsp1_fck = { | 1380 | static struct clk mcbsp1_fck = { |
| 1380 | .name = "mcbsp1_fck", | 1381 | .name = "mcbsp_fck", |
| 1382 | .id = 1, | ||
| 1381 | .init = &omap2_init_clksel_parent, | 1383 | .init = &omap2_init_clksel_parent, |
| 1382 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1384 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
| 1383 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, | 1385 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, |
| @@ -1789,7 +1791,8 @@ static struct clk gpt10_ick = { | |||
| 1789 | }; | 1791 | }; |
| 1790 | 1792 | ||
| 1791 | static struct clk mcbsp5_ick = { | 1793 | static struct clk mcbsp5_ick = { |
| 1792 | .name = "mcbsp5_ick", | 1794 | .name = "mcbsp_ick", |
| 1795 | .id = 5, | ||
| 1793 | .parent = &core_l4_ick, | 1796 | .parent = &core_l4_ick, |
| 1794 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1797 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
| 1795 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, | 1798 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, |
| @@ -1798,7 +1801,8 @@ static struct clk mcbsp5_ick = { | |||
| 1798 | }; | 1801 | }; |
| 1799 | 1802 | ||
| 1800 | static struct clk mcbsp1_ick = { | 1803 | static struct clk mcbsp1_ick = { |
| 1801 | .name = "mcbsp1_ick", | 1804 | .name = "mcbsp_ick", |
| 1805 | .id = 1, | ||
| 1802 | .parent = &core_l4_ick, | 1806 | .parent = &core_l4_ick, |
| 1803 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1807 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
| 1804 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, | 1808 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, |
| @@ -2541,7 +2545,8 @@ static struct clk gpt2_ick = { | |||
| 2541 | }; | 2545 | }; |
| 2542 | 2546 | ||
| 2543 | static struct clk mcbsp2_ick = { | 2547 | static struct clk mcbsp2_ick = { |
| 2544 | .name = "mcbsp2_ick", | 2548 | .name = "mcbsp_ick", |
| 2549 | .id = 2, | ||
| 2545 | .parent = &per_l4_ick, | 2550 | .parent = &per_l4_ick, |
| 2546 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), | 2551 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), |
| 2547 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, | 2552 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, |
| @@ -2550,7 +2555,8 @@ static struct clk mcbsp2_ick = { | |||
| 2550 | }; | 2555 | }; |
| 2551 | 2556 | ||
| 2552 | static struct clk mcbsp3_ick = { | 2557 | static struct clk mcbsp3_ick = { |
| 2553 | .name = "mcbsp3_ick", | 2558 | .name = "mcbsp_ick", |
| 2559 | .id = 3, | ||
| 2554 | .parent = &per_l4_ick, | 2560 | .parent = &per_l4_ick, |
| 2555 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), | 2561 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), |
| 2556 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, | 2562 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, |
| @@ -2559,7 +2565,8 @@ static struct clk mcbsp3_ick = { | |||
| 2559 | }; | 2565 | }; |
| 2560 | 2566 | ||
| 2561 | static struct clk mcbsp4_ick = { | 2567 | static struct clk mcbsp4_ick = { |
| 2562 | .name = "mcbsp4_ick", | 2568 | .name = "mcbsp_ick", |
| 2569 | .id = 4, | ||
| 2563 | .parent = &per_l4_ick, | 2570 | .parent = &per_l4_ick, |
| 2564 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), | 2571 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), |
| 2565 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, | 2572 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, |
| @@ -2574,7 +2581,8 @@ static const struct clksel mcbsp_234_clksel[] = { | |||
| 2574 | }; | 2581 | }; |
| 2575 | 2582 | ||
| 2576 | static struct clk mcbsp2_fck = { | 2583 | static struct clk mcbsp2_fck = { |
| 2577 | .name = "mcbsp2_fck", | 2584 | .name = "mcbsp_fck", |
| 2585 | .id = 2, | ||
| 2578 | .init = &omap2_init_clksel_parent, | 2586 | .init = &omap2_init_clksel_parent, |
| 2579 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2587 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
| 2580 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, | 2588 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, |
| @@ -2586,7 +2594,8 @@ static struct clk mcbsp2_fck = { | |||
| 2586 | }; | 2594 | }; |
| 2587 | 2595 | ||
| 2588 | static struct clk mcbsp3_fck = { | 2596 | static struct clk mcbsp3_fck = { |
| 2589 | .name = "mcbsp3_fck", | 2597 | .name = "mcbsp_fck", |
| 2598 | .id = 3, | ||
| 2590 | .init = &omap2_init_clksel_parent, | 2599 | .init = &omap2_init_clksel_parent, |
| 2591 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2600 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
| 2592 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, | 2601 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, |
| @@ -2598,7 +2607,8 @@ static struct clk mcbsp3_fck = { | |||
| 2598 | }; | 2607 | }; |
| 2599 | 2608 | ||
| 2600 | static struct clk mcbsp4_fck = { | 2609 | static struct clk mcbsp4_fck = { |
| 2601 | .name = "mcbsp4_fck", | 2610 | .name = "mcbsp_fck", |
| 2611 | .id = 4, | ||
| 2602 | .init = &omap2_init_clksel_parent, | 2612 | .init = &omap2_init_clksel_parent, |
| 2603 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2613 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
| 2604 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, | 2614 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, |
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c new file mode 100644 index 000000000000..17cf199d1130 --- /dev/null +++ b/arch/arm/mach-omap2/mcbsp.c | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-omap2/mcbsp.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Instituto Nokia de Tecnologia | ||
| 5 | * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * Multichannel mode not supported. | ||
| 12 | */ | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/clk.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | |||
| 20 | #include <asm/arch/dma.h> | ||
| 21 | #include <asm/arch/mux.h> | ||
| 22 | #include <asm/arch/cpu.h> | ||
| 23 | #include <asm/arch/mcbsp.h> | ||
| 24 | |||
| 25 | struct mcbsp_internal_clk { | ||
| 26 | struct clk clk; | ||
| 27 | struct clk **childs; | ||
| 28 | int n_childs; | ||
| 29 | }; | ||
| 30 | |||
| 31 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | ||
| 32 | static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) | ||
| 33 | { | ||
| 34 | const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; | ||
| 35 | int i; | ||
| 36 | |||
| 37 | mclk->n_childs = ARRAY_SIZE(clk_names); | ||
| 38 | mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), | ||
| 39 | GFP_KERNEL); | ||
| 40 | |||
| 41 | for (i = 0; i < mclk->n_childs; i++) { | ||
| 42 | /* We fake a platform device to get correct device id */ | ||
| 43 | struct platform_device pdev; | ||
| 44 | |||
| 45 | pdev.dev.bus = &platform_bus_type; | ||
| 46 | pdev.id = mclk->clk.id; | ||
| 47 | mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); | ||
| 48 | if (IS_ERR(mclk->childs[i])) | ||
| 49 | printk(KERN_ERR "Could not get clock %s (%d).\n", | ||
| 50 | clk_names[i], mclk->clk.id); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | static int omap_mcbsp_clk_enable(struct clk *clk) | ||
| 55 | { | ||
| 56 | struct mcbsp_internal_clk *mclk = container_of(clk, | ||
| 57 | struct mcbsp_internal_clk, clk); | ||
| 58 | int i; | ||
| 59 | |||
| 60 | for (i = 0; i < mclk->n_childs; i++) | ||
| 61 | clk_enable(mclk->childs[i]); | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static void omap_mcbsp_clk_disable(struct clk *clk) | ||
| 66 | { | ||
| 67 | struct mcbsp_internal_clk *mclk = container_of(clk, | ||
| 68 | struct mcbsp_internal_clk, clk); | ||
| 69 | int i; | ||
| 70 | |||
| 71 | for (i = 0; i < mclk->n_childs; i++) | ||
| 72 | clk_disable(mclk->childs[i]); | ||
| 73 | } | ||
| 74 | |||
| 75 | static struct mcbsp_internal_clk omap_mcbsp_clks[] = { | ||
| 76 | { | ||
| 77 | .clk = { | ||
| 78 | .name = "mcbsp_clk", | ||
| 79 | .id = 1, | ||
| 80 | .enable = omap_mcbsp_clk_enable, | ||
| 81 | .disable = omap_mcbsp_clk_disable, | ||
| 82 | }, | ||
| 83 | }, | ||
| 84 | { | ||
| 85 | .clk = { | ||
| 86 | .name = "mcbsp_clk", | ||
| 87 | .id = 2, | ||
| 88 | .enable = omap_mcbsp_clk_enable, | ||
| 89 | .disable = omap_mcbsp_clk_disable, | ||
| 90 | }, | ||
| 91 | }, | ||
| 92 | }; | ||
| 93 | |||
| 94 | #define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) | ||
| 95 | #else | ||
| 96 | #define omap_mcbsp_clks_size 0 | ||
| 97 | static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; | ||
| 98 | static inline void omap_mcbsp_clk_init(struct clk *clk) | ||
| 99 | { } | ||
| 100 | #endif | ||
| 101 | |||
| 102 | static void omap2_mcbsp2_mux_setup(void) | ||
| 103 | { | ||
| 104 | omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); | ||
| 105 | omap_cfg_reg(R14_24XX_MCBSP2_FSX); | ||
| 106 | omap_cfg_reg(W15_24XX_MCBSP2_DR); | ||
| 107 | omap_cfg_reg(V15_24XX_MCBSP2_DX); | ||
| 108 | omap_cfg_reg(V14_24XX_GPIO117); | ||
| 109 | /* | ||
| 110 | * TODO: Need to add MUX settings for OMAP 2430 SDP | ||
| 111 | */ | ||
| 112 | } | ||
| 113 | |||
| 114 | static void omap2_mcbsp_request(unsigned int id) | ||
| 115 | { | ||
| 116 | if (cpu_is_omap2420() && (id == OMAP_MCBSP2)) | ||
| 117 | omap2_mcbsp2_mux_setup(); | ||
| 118 | } | ||
| 119 | |||
| 120 | static int omap2_mcbsp_check(unsigned int id) | ||
| 121 | { | ||
| 122 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { | ||
| 123 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | ||
| 124 | return -ENODEV; | ||
| 125 | } | ||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | static struct omap_mcbsp_ops omap2_mcbsp_ops = { | ||
| 130 | .request = omap2_mcbsp_request, | ||
| 131 | .check = omap2_mcbsp_check, | ||
| 132 | }; | ||
| 133 | |||
| 134 | #ifdef CONFIG_ARCH_OMAP24XX | ||
| 135 | static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = { | ||
| 136 | { | ||
| 137 | .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), | ||
| 138 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
| 139 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
| 140 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
| 141 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
| 142 | .ops = &omap2_mcbsp_ops, | ||
| 143 | .clk_name = "mcbsp_clk", | ||
| 144 | }, | ||
| 145 | { | ||
| 146 | .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), | ||
| 147 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
| 148 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
| 149 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
| 150 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
| 151 | .ops = &omap2_mcbsp_ops, | ||
| 152 | .clk_name = "mcbsp_clk", | ||
| 153 | }, | ||
| 154 | }; | ||
| 155 | #define OMAP24XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap24xx_mcbsp_pdata) | ||
| 156 | #else | ||
| 157 | #define omap24xx_mcbsp_pdata NULL | ||
| 158 | #define OMAP24XX_MCBSP_PDATA_SZ 0 | ||
| 159 | #endif | ||
| 160 | |||
| 161 | #ifdef CONFIG_ARCH_OMAP34XX | ||
| 162 | static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | ||
| 163 | { | ||
| 164 | .virt_base = IO_ADDRESS(OMAP34XX_MCBSP1_BASE), | ||
| 165 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
| 166 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
| 167 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
| 168 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
| 169 | .ops = &omap2_mcbsp_ops, | ||
| 170 | .clk_name = "mcbsp_clk", | ||
| 171 | }, | ||
| 172 | { | ||
| 173 | .virt_base = IO_ADDRESS(OMAP34XX_MCBSP2_BASE), | ||
| 174 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
| 175 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
| 176 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
| 177 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
| 178 | .ops = &omap2_mcbsp_ops, | ||
| 179 | .clk_name = "mcbsp_clk", | ||
| 180 | }, | ||
| 181 | }; | ||
| 182 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | ||
| 183 | #else | ||
| 184 | #define omap34xx_mcbsp_pdata NULL | ||
| 185 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | ||
| 186 | #endif | ||
| 187 | |||
| 188 | int __init omap2_mcbsp_init(void) | ||
| 189 | { | ||
| 190 | int i; | ||
| 191 | |||
| 192 | for (i = 0; i < omap_mcbsp_clks_size; i++) { | ||
| 193 | /* Once we call clk_get inside init, we do not register it */ | ||
| 194 | omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); | ||
| 195 | clk_register(&omap_mcbsp_clks[i].clk); | ||
| 196 | } | ||
| 197 | |||
| 198 | if (cpu_is_omap24xx()) | ||
| 199 | omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata, | ||
| 200 | OMAP24XX_MCBSP_PDATA_SZ); | ||
| 201 | |||
| 202 | if (cpu_is_omap34xx()) | ||
| 203 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | ||
| 204 | OMAP34XX_MCBSP_PDATA_SZ); | ||
| 205 | |||
| 206 | return omap_mcbsp_init(); | ||
| 207 | } | ||
| 208 | arch_initcall(omap2_mcbsp_init); | ||
