Commit | Line | Data |
---|---|---|
78673bc8 EV |
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> | |
5a0e3ad6 | 19 | #include <linux/slab.h> |
78673bc8 | 20 | |
dd7667aa | 21 | #include <mach/irqs.h> |
ce491cf8 | 22 | #include <plat/dma.h> |
ce491cf8 TL |
23 | #include <plat/cpu.h> |
24 | #include <plat/mcbsp.h> | |
4814ced5 PW |
25 | |
26 | #include "control.h" | |
27 | ||
78673bc8 | 28 | |
cf4c87ab PW |
29 | /* McBSP internal signal muxing functions */ |
30 | ||
31 | void omap2_mcbsp1_mux_clkr_src(u8 mux) | |
32 | { | |
33 | u32 v; | |
34 | ||
35 | v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | |
36 | if (mux == CLKR_SRC_CLKR) | |
425925dd | 37 | v &= ~OMAP2_MCBSP1_CLKR_MASK; |
cf4c87ab PW |
38 | else if (mux == CLKR_SRC_CLKX) |
39 | v |= OMAP2_MCBSP1_CLKR_MASK; | |
40 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | |
41 | } | |
42 | EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src); | |
43 | ||
44 | void omap2_mcbsp1_mux_fsr_src(u8 mux) | |
45 | { | |
46 | u32 v; | |
47 | ||
48 | v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | |
49 | if (mux == FSR_SRC_FSR) | |
425925dd | 50 | v &= ~OMAP2_MCBSP1_FSR_MASK; |
cf4c87ab PW |
51 | else if (mux == FSR_SRC_FSX) |
52 | v |= OMAP2_MCBSP1_FSR_MASK; | |
53 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | |
54 | } | |
55 | EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); | |
56 | ||
d1358657 PW |
57 | /* McBSP CLKS source switching function */ |
58 | ||
59 | int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) | |
60 | { | |
61 | struct omap_mcbsp *mcbsp; | |
62 | struct clk *fck_src; | |
63 | char *fck_src_name; | |
64 | int r; | |
65 | ||
66 | if (!omap_mcbsp_check_valid_id(id)) { | |
67 | pr_err("%s: Invalid id (%d)\n", __func__, id + 1); | |
68 | return -EINVAL; | |
69 | } | |
70 | mcbsp = id_to_mcbsp_ptr(id); | |
71 | ||
72 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) | |
73 | fck_src_name = "pad_fck"; | |
74 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) | |
75 | fck_src_name = "prcm_fck"; | |
76 | else | |
77 | return -EINVAL; | |
78 | ||
79 | fck_src = clk_get(mcbsp->dev, fck_src_name); | |
80 | if (IS_ERR_OR_NULL(fck_src)) { | |
81 | pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks", | |
82 | fck_src_name); | |
83 | return -EINVAL; | |
84 | } | |
85 | ||
86 | clk_disable(mcbsp->fclk); | |
87 | ||
88 | r = clk_set_parent(mcbsp->fclk, fck_src); | |
89 | if (IS_ERR_VALUE(r)) { | |
90 | pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n", | |
91 | "clks", fck_src_name); | |
92 | clk_put(fck_src); | |
93 | return -EINVAL; | |
94 | } | |
95 | ||
96 | clk_enable(mcbsp->fclk); | |
97 | ||
98 | clk_put(fck_src); | |
99 | ||
100 | return 0; | |
101 | } | |
102 | EXPORT_SYMBOL(omap2_mcbsp_set_clks_src); | |
103 | ||
104 | ||
cf4c87ab | 105 | /* Platform data */ |
78673bc8 | 106 | |
05228c35 JN |
107 | #ifdef CONFIG_ARCH_OMAP2420 |
108 | static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { | |
78673bc8 | 109 | { |
65846909 | 110 | .phys_base = OMAP24XX_MCBSP1_BASE, |
78673bc8 EV |
111 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, |
112 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | |
113 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | |
114 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | |
78673bc8 EV |
115 | }, |
116 | { | |
65846909 | 117 | .phys_base = OMAP24XX_MCBSP2_BASE, |
78673bc8 EV |
118 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, |
119 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | |
120 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | |
121 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | |
78673bc8 EV |
122 | }, |
123 | }; | |
05228c35 | 124 | #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) |
c8c99699 | 125 | #define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) |
78673bc8 | 126 | #else |
05228c35 JN |
127 | #define omap2420_mcbsp_pdata NULL |
128 | #define OMAP2420_MCBSP_PDATA_SZ 0 | |
c8c99699 | 129 | #define OMAP2420_MCBSP_REG_NUM 0 |
05228c35 JN |
130 | #endif |
131 | ||
132 | #ifdef CONFIG_ARCH_OMAP2430 | |
133 | static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { | |
134 | { | |
135 | .phys_base = OMAP24XX_MCBSP1_BASE, | |
136 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | |
137 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | |
138 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | |
139 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | |
05228c35 JN |
140 | }, |
141 | { | |
142 | .phys_base = OMAP24XX_MCBSP2_BASE, | |
143 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | |
144 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | |
145 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | |
146 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | |
05228c35 JN |
147 | }, |
148 | { | |
149 | .phys_base = OMAP2430_MCBSP3_BASE, | |
150 | .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, | |
151 | .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, | |
152 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | |
153 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | |
05228c35 JN |
154 | }, |
155 | { | |
156 | .phys_base = OMAP2430_MCBSP4_BASE, | |
157 | .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, | |
158 | .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, | |
159 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | |
160 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | |
05228c35 JN |
161 | }, |
162 | { | |
163 | .phys_base = OMAP2430_MCBSP5_BASE, | |
164 | .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, | |
165 | .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, | |
166 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | |
167 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | |
05228c35 JN |
168 | }, |
169 | }; | |
170 | #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) | |
c8c99699 | 171 | #define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) |
05228c35 JN |
172 | #else |
173 | #define omap2430_mcbsp_pdata NULL | |
174 | #define OMAP2430_MCBSP_PDATA_SZ 0 | |
c8c99699 | 175 | #define OMAP2430_MCBSP_REG_NUM 0 |
78673bc8 EV |
176 | #endif |
177 | ||
a8eb7ca0 | 178 | #ifdef CONFIG_ARCH_OMAP3 |
78673bc8 EV |
179 | static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { |
180 | { | |
65846909 | 181 | .phys_base = OMAP34XX_MCBSP1_BASE, |
78673bc8 EV |
182 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, |
183 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | |
184 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | |
185 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | |
451fd82d | 186 | .buffer_size = 0x80, /* The FIFO has 128 locations */ |
78673bc8 EV |
187 | }, |
188 | { | |
65846909 | 189 | .phys_base = OMAP34XX_MCBSP2_BASE, |
d912fa92 | 190 | .phys_base_st = OMAP34XX_MCBSP2_ST_BASE, |
78673bc8 EV |
191 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, |
192 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | |
193 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | |
194 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | |
451fd82d | 195 | .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ |
78673bc8 | 196 | }, |
9c8e3a0f CS |
197 | { |
198 | .phys_base = OMAP34XX_MCBSP3_BASE, | |
d912fa92 | 199 | .phys_base_st = OMAP34XX_MCBSP3_ST_BASE, |
9c8e3a0f CS |
200 | .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, |
201 | .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, | |
202 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | |
203 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | |
451fd82d | 204 | .buffer_size = 0x80, /* The FIFO has 128 locations */ |
9c8e3a0f CS |
205 | }, |
206 | { | |
207 | .phys_base = OMAP34XX_MCBSP4_BASE, | |
208 | .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, | |
209 | .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, | |
210 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | |
211 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | |
451fd82d | 212 | .buffer_size = 0x80, /* The FIFO has 128 locations */ |
9c8e3a0f CS |
213 | }, |
214 | { | |
215 | .phys_base = OMAP34XX_MCBSP5_BASE, | |
216 | .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, | |
217 | .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, | |
218 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | |
219 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | |
451fd82d | 220 | .buffer_size = 0x80, /* The FIFO has 128 locations */ |
9c8e3a0f | 221 | }, |
78673bc8 EV |
222 | }; |
223 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | |
c8c99699 | 224 | #define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) |
78673bc8 EV |
225 | #else |
226 | #define omap34xx_mcbsp_pdata NULL | |
227 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | |
c8c99699 | 228 | #define OMAP34XX_MCBSP_REG_NUM 0 |
78673bc8 EV |
229 | #endif |
230 | ||
a5b92cc3 SR |
231 | static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { |
232 | { | |
233 | .phys_base = OMAP44XX_MCBSP1_BASE, | |
234 | .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, | |
235 | .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, | |
9319b9da | 236 | .tx_irq = OMAP44XX_IRQ_MCBSP1, |
a5b92cc3 SR |
237 | }, |
238 | { | |
239 | .phys_base = OMAP44XX_MCBSP2_BASE, | |
240 | .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, | |
241 | .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, | |
9319b9da | 242 | .tx_irq = OMAP44XX_IRQ_MCBSP2, |
a5b92cc3 SR |
243 | }, |
244 | { | |
245 | .phys_base = OMAP44XX_MCBSP3_BASE, | |
246 | .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, | |
247 | .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, | |
9319b9da | 248 | .tx_irq = OMAP44XX_IRQ_MCBSP3, |
a5b92cc3 SR |
249 | }, |
250 | { | |
251 | .phys_base = OMAP44XX_MCBSP4_BASE, | |
252 | .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, | |
253 | .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, | |
9319b9da | 254 | .tx_irq = OMAP44XX_IRQ_MCBSP4, |
a5b92cc3 SR |
255 | }, |
256 | }; | |
257 | #define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) | |
c8c99699 | 258 | #define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) |
a5b92cc3 | 259 | |
b4b58f58 | 260 | static int __init omap2_mcbsp_init(void) |
78673bc8 | 261 | { |
c8c99699 | 262 | if (cpu_is_omap2420()) { |
05228c35 | 263 | omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; |
c8c99699 JK |
264 | omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16); |
265 | } else if (cpu_is_omap2430()) { | |
05228c35 | 266 | omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; |
c8c99699 JK |
267 | omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32); |
268 | } else if (cpu_is_omap34xx()) { | |
b4b58f58 | 269 | omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; |
c8c99699 JK |
270 | omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32); |
271 | } else if (cpu_is_omap44xx()) { | |
a5b92cc3 | 272 | omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; |
c8c99699 JK |
273 | omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32); |
274 | } | |
b4b58f58 CS |
275 | |
276 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), | |
277 | GFP_KERNEL); | |
278 | if (!mcbsp_ptr) | |
279 | return -ENOMEM; | |
280 | ||
05228c35 JN |
281 | if (cpu_is_omap2420()) |
282 | omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, | |
283 | OMAP2420_MCBSP_PDATA_SZ); | |
284 | if (cpu_is_omap2430()) | |
285 | omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, | |
286 | OMAP2430_MCBSP_PDATA_SZ); | |
9c8e3a0f CS |
287 | if (cpu_is_omap34xx()) |
288 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | |
289 | OMAP34XX_MCBSP_PDATA_SZ); | |
a5b92cc3 SR |
290 | if (cpu_is_omap44xx()) |
291 | omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, | |
292 | OMAP44XX_MCBSP_PDATA_SZ); | |
78673bc8 | 293 | |
78673bc8 EV |
294 | return omap_mcbsp_init(); |
295 | } | |
296 | arch_initcall(omap2_mcbsp_init); |