Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: OMAP: McBSP: Add support for mcbsp on mach-omap2

This patch adds support for mach-omap2 based on current
mcbsp platform driver.

Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>
Signed-off-by: Tony Lindgren <tony@atomide.com>

authored by

Eduardo Valentin and committed by
Tony Lindgren
78673bc8 44ec9a33

+230 -10
+2
arch/arm/mach-omap2/Makefile
··· 6 6 obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ 7 7 devices.o serial.o gpmc.o timer-gp.o 8 8 9 + obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 10 + 9 11 # Functions loaded to SRAM 10 12 obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o 11 13 obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o
+20 -10
arch/arm/mach-omap2/clock34xx.h
··· 1365 1365 }; 1366 1366 1367 1367 static struct clk mcbsp5_fck = { 1368 - .name = "mcbsp5_fck", 1368 + .name = "mcbsp_fck", 1369 + .id = 5, 1369 1370 .init = &omap2_init_clksel_parent, 1370 1371 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1371 1372 .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, ··· 1378 1377 }; 1379 1378 1380 1379 static struct clk mcbsp1_fck = { 1381 - .name = "mcbsp1_fck", 1380 + .name = "mcbsp_fck", 1381 + .id = 1, 1382 1382 .init = &omap2_init_clksel_parent, 1383 1383 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1384 1384 .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, ··· 1791 1789 }; 1792 1790 1793 1791 static struct clk mcbsp5_ick = { 1794 - .name = "mcbsp5_ick", 1792 + .name = "mcbsp_ick", 1793 + .id = 5, 1795 1794 .parent = &core_l4_ick, 1796 1795 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), 1797 1796 .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, ··· 1801 1798 }; 1802 1799 1803 1800 static struct clk mcbsp1_ick = { 1804 - .name = "mcbsp1_ick", 1801 + .name = "mcbsp_ick", 1802 + .id = 1, 1805 1803 .parent = &core_l4_ick, 1806 1804 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), 1807 1805 .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, ··· 2545 2541 }; 2546 2542 2547 2543 static struct clk mcbsp2_ick = { 2548 - .name = "mcbsp2_ick", 2544 + .name = "mcbsp_ick", 2545 + .id = 2, 2549 2546 .parent = &per_l4_ick, 2550 2547 .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), 2551 2548 .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, ··· 2555 2550 }; 2556 2551 2557 2552 static struct clk mcbsp3_ick = { 2558 - .name = "mcbsp3_ick", 2553 + .name = "mcbsp_ick", 2554 + .id = 3, 2559 2555 .parent = &per_l4_ick, 2560 2556 .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), 2561 2557 .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, ··· 2565 2559 }; 2566 2560 2567 2561 static struct clk mcbsp4_ick = { 2568 - .name = "mcbsp4_ick", 2562 + .name = "mcbsp_ick", 2563 + .id = 4, 2569 2564 .parent = &per_l4_ick, 2570 2565 .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), 2571 2566 .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, ··· 2581 2574 }; 2582 2575 2583 2576 static struct clk mcbsp2_fck = { 2584 - .name = "mcbsp2_fck", 2577 + .name = "mcbsp_fck", 2578 + .id = 2, 2585 2579 .init = &omap2_init_clksel_parent, 2586 2580 .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), 2587 2581 .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, ··· 2594 2586 }; 2595 2587 2596 2588 static struct clk mcbsp3_fck = { 2597 - .name = "mcbsp3_fck", 2589 + .name = "mcbsp_fck", 2590 + .id = 3, 2598 2591 .init = &omap2_init_clksel_parent, 2599 2592 .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), 2600 2593 .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, ··· 2607 2598 }; 2608 2599 2609 2600 static struct clk mcbsp4_fck = { 2610 - .name = "mcbsp4_fck", 2601 + .name = "mcbsp_fck", 2602 + .id = 4, 2611 2603 .init = &omap2_init_clksel_parent, 2612 2604 .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), 2613 2605 .enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
+208
arch/arm/mach-omap2/mcbsp.c
··· 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);