2 * linux/arch/arm/mach-omap2/mcbsp.c
4 * Copyright (C) 2008 Instituto Nokia de Tecnologia
5 * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
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.
11 * Multichannel mode not supported.
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
18 #include <linux/platform_device.h>
21 #include <mach/irqs.h>
24 #include <mach/mcbsp.h>
26 struct mcbsp_internal_clk {
32 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
33 static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
35 const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
38 mclk->n_childs = ARRAY_SIZE(clk_names);
39 mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *),
42 for (i = 0; i < mclk->n_childs; i++) {
43 /* We fake a platform device to get correct device id */
44 struct platform_device pdev;
46 pdev.dev.bus = &platform_bus_type;
47 pdev.id = mclk->clk.id;
48 mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]);
49 if (IS_ERR(mclk->childs[i]))
50 printk(KERN_ERR "Could not get clock %s (%d).\n",
51 clk_names[i], mclk->clk.id);
55 static int omap_mcbsp_clk_enable(struct clk *clk)
57 struct mcbsp_internal_clk *mclk = container_of(clk,
58 struct mcbsp_internal_clk, clk);
61 for (i = 0; i < mclk->n_childs; i++)
62 clk_enable(mclk->childs[i]);
66 static void omap_mcbsp_clk_disable(struct clk *clk)
68 struct mcbsp_internal_clk *mclk = container_of(clk,
69 struct mcbsp_internal_clk, clk);
72 for (i = 0; i < mclk->n_childs; i++)
73 clk_disable(mclk->childs[i]);
76 static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
81 .enable = omap_mcbsp_clk_enable,
82 .disable = omap_mcbsp_clk_disable,
89 .enable = omap_mcbsp_clk_enable,
90 .disable = omap_mcbsp_clk_disable,
97 .enable = omap_mcbsp_clk_enable,
98 .disable = omap_mcbsp_clk_disable,
105 .enable = omap_mcbsp_clk_enable,
106 .disable = omap_mcbsp_clk_disable,
113 .enable = omap_mcbsp_clk_enable,
114 .disable = omap_mcbsp_clk_disable,
119 #define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks)
121 #define omap_mcbsp_clks_size 0
122 static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks;
123 static inline void omap_mcbsp_clk_init(struct clk *clk)
127 static void omap2_mcbsp2_mux_setup(void)
129 omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
130 omap_cfg_reg(R14_24XX_MCBSP2_FSX);
131 omap_cfg_reg(W15_24XX_MCBSP2_DR);
132 omap_cfg_reg(V15_24XX_MCBSP2_DX);
133 omap_cfg_reg(V14_24XX_GPIO117);
135 * TODO: Need to add MUX settings for OMAP 2430 SDP
139 static void omap2_mcbsp_request(unsigned int id)
141 if (cpu_is_omap2420() && (id == OMAP_MCBSP2))
142 omap2_mcbsp2_mux_setup();
145 static struct omap_mcbsp_ops omap2_mcbsp_ops = {
146 .request = omap2_mcbsp_request,
149 #ifdef CONFIG_ARCH_OMAP2420
150 static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
152 .phys_base = OMAP24XX_MCBSP1_BASE,
153 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
154 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
155 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
156 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
157 .ops = &omap2_mcbsp_ops,
158 .clk_name = "mcbsp_clk",
161 .phys_base = OMAP24XX_MCBSP2_BASE,
162 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
163 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
164 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
165 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
166 .ops = &omap2_mcbsp_ops,
167 .clk_name = "mcbsp_clk",
170 #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
172 #define omap2420_mcbsp_pdata NULL
173 #define OMAP2420_MCBSP_PDATA_SZ 0
176 #ifdef CONFIG_ARCH_OMAP2430
177 static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
179 .phys_base = OMAP24XX_MCBSP1_BASE,
180 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
181 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
182 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
183 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
184 .ops = &omap2_mcbsp_ops,
185 .clk_name = "mcbsp_clk",
188 .phys_base = OMAP24XX_MCBSP2_BASE,
189 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
190 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
191 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
192 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
193 .ops = &omap2_mcbsp_ops,
194 .clk_name = "mcbsp_clk",
197 .phys_base = OMAP2430_MCBSP3_BASE,
198 .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
199 .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
200 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
201 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
202 .ops = &omap2_mcbsp_ops,
203 .clk_name = "mcbsp_clk",
206 .phys_base = OMAP2430_MCBSP4_BASE,
207 .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
208 .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
209 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
210 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
211 .ops = &omap2_mcbsp_ops,
212 .clk_name = "mcbsp_clk",
215 .phys_base = OMAP2430_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,
220 .ops = &omap2_mcbsp_ops,
221 .clk_name = "mcbsp_clk",
224 #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
226 #define omap2430_mcbsp_pdata NULL
227 #define OMAP2430_MCBSP_PDATA_SZ 0
230 #ifdef CONFIG_ARCH_OMAP34XX
231 static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
233 .phys_base = OMAP34XX_MCBSP1_BASE,
234 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
235 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
236 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
237 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
238 .ops = &omap2_mcbsp_ops,
239 .clk_name = "mcbsp_clk",
242 .phys_base = OMAP34XX_MCBSP2_BASE,
243 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
244 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
245 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
246 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
247 .ops = &omap2_mcbsp_ops,
248 .clk_name = "mcbsp_clk",
251 .phys_base = OMAP34XX_MCBSP3_BASE,
252 .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
253 .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
254 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
255 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
256 .ops = &omap2_mcbsp_ops,
257 .clk_name = "mcbsp_clk",
260 .phys_base = OMAP34XX_MCBSP4_BASE,
261 .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
262 .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
263 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
264 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
265 .ops = &omap2_mcbsp_ops,
266 .clk_name = "mcbsp_clk",
269 .phys_base = OMAP34XX_MCBSP5_BASE,
270 .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
271 .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
272 .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
273 .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
274 .ops = &omap2_mcbsp_ops,
275 .clk_name = "mcbsp_clk",
278 #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
280 #define omap34xx_mcbsp_pdata NULL
281 #define OMAP34XX_MCBSP_PDATA_SZ 0
284 static int __init omap2_mcbsp_init(void)
288 for (i = 0; i < omap_mcbsp_clks_size; i++) {
289 /* Once we call clk_get inside init, we do not register it */
290 omap_mcbsp_clk_init(&omap_mcbsp_clks[i]);
291 clk_register(&omap_mcbsp_clks[i].clk);
294 if (cpu_is_omap2420())
295 omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
296 if (cpu_is_omap2430())
297 omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
298 if (cpu_is_omap34xx())
299 omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
301 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
306 if (cpu_is_omap2420())
307 omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
308 OMAP2420_MCBSP_PDATA_SZ);
309 if (cpu_is_omap2430())
310 omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
311 OMAP2430_MCBSP_PDATA_SZ);
312 if (cpu_is_omap34xx())
313 omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
314 OMAP34XX_MCBSP_PDATA_SZ);
316 return omap_mcbsp_init();
318 arch_initcall(omap2_mcbsp_init);