diff options
author | Eduardo Valentin <eduardo.valentin@indt.org.br> | 2008-07-03 05:24:40 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2008-07-03 05:24:40 -0400 |
commit | 78673bc898c2db7f4fac4871ec702c3443642308 (patch) | |
tree | d8ac97b0120c79213ff40e719f959b9f3ad19e23 | |
parent | 44ec9a3371d5cab323b81c95a4c01d7b5a89cdda (diff) |
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>
-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); | ||