MERGE-master-patchset-edits
[linux-2.6/openmoko-kernel.git] / arch / arm / mach-omap1 / mcbsp.c
blobca7a0cc1707c29779bf3b6d9c279da4d558682c7
1 /*
2 * linux/arch/arm/mach-omap1/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>
17 #include <linux/io.h>
18 #include <linux/platform_device.h>
20 #include <mach/irqs.h>
21 #include <mach/dma.h>
22 #include <mach/irqs.h>
23 #include <mach/mux.h>
24 #include <mach/cpu.h>
25 #include <mach/mcbsp.h>
26 #include <mach/dsp_common.h>
28 #define DPS_RSTCT2_PER_EN (1 << 0)
29 #define DSP_RSTCT2_WD_PER_EN (1 << 1)
31 struct mcbsp_internal_clk {
32 struct clk clk;
33 struct clk **childs;
34 int n_childs;
37 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
38 static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
40 const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
41 int i;
43 mclk->n_childs = ARRAY_SIZE(clk_names);
44 mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *),
45 GFP_KERNEL);
47 for (i = 0; i < mclk->n_childs; i++) {
48 /* We fake a platform device to get correct device id */
49 struct platform_device pdev;
51 pdev.dev.bus = &platform_bus_type;
52 pdev.id = mclk->clk.id;
53 mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]);
54 if (IS_ERR(mclk->childs[i]))
55 printk(KERN_ERR "Could not get clock %s (%d).\n",
56 clk_names[i], mclk->clk.id);
60 static int omap_mcbsp_clk_enable(struct clk *clk)
62 struct mcbsp_internal_clk *mclk = container_of(clk,
63 struct mcbsp_internal_clk, clk);
64 int i;
66 for (i = 0; i < mclk->n_childs; i++)
67 clk_enable(mclk->childs[i]);
68 return 0;
71 static void omap_mcbsp_clk_disable(struct clk *clk)
73 struct mcbsp_internal_clk *mclk = container_of(clk,
74 struct mcbsp_internal_clk, clk);
75 int i;
77 for (i = 0; i < mclk->n_childs; i++)
78 clk_disable(mclk->childs[i]);
81 static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
83 .clk = {
84 .name = "mcbsp_clk",
85 .id = 1,
86 .enable = omap_mcbsp_clk_enable,
87 .disable = omap_mcbsp_clk_disable,
91 .clk = {
92 .name = "mcbsp_clk",
93 .id = 3,
94 .enable = omap_mcbsp_clk_enable,
95 .disable = omap_mcbsp_clk_disable,
100 #define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks)
101 #else
102 #define omap_mcbsp_clks_size 0
103 static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks;
104 static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
106 #endif
108 static void omap1_mcbsp_request(unsigned int id)
111 * On 1510, 1610 and 1710, McBSP1 and McBSP3
112 * are DSP public peripherals.
114 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
115 omap_dsp_request_mem();
117 * DSP external peripheral reset
118 * FIXME: This should be moved to dsp code
120 __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
121 DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
125 static void omap1_mcbsp_free(unsigned int id)
127 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
128 omap_dsp_release_mem();
131 static struct omap_mcbsp_ops omap1_mcbsp_ops = {
132 .request = omap1_mcbsp_request,
133 .free = omap1_mcbsp_free,
136 #ifdef CONFIG_ARCH_OMAP730
137 static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
139 .phys_base = OMAP730_MCBSP1_BASE,
140 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
141 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
142 .rx_irq = INT_730_McBSP1RX,
143 .tx_irq = INT_730_McBSP1TX,
144 .ops = &omap1_mcbsp_ops,
147 .phys_base = OMAP730_MCBSP2_BASE,
148 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
149 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
150 .rx_irq = INT_730_McBSP2RX,
151 .tx_irq = INT_730_McBSP2TX,
152 .ops = &omap1_mcbsp_ops,
155 #define OMAP730_MCBSP_PDATA_SZ ARRAY_SIZE(omap730_mcbsp_pdata)
156 #else
157 #define omap730_mcbsp_pdata NULL
158 #define OMAP730_MCBSP_PDATA_SZ 0
159 #endif
161 #ifdef CONFIG_ARCH_OMAP15XX
162 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
164 .phys_base = OMAP1510_MCBSP1_BASE,
165 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
166 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
167 .rx_irq = INT_McBSP1RX,
168 .tx_irq = INT_McBSP1TX,
169 .ops = &omap1_mcbsp_ops,
170 .clk_name = "mcbsp_clk",
173 .phys_base = OMAP1510_MCBSP2_BASE,
174 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
175 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
176 .rx_irq = INT_1510_SPI_RX,
177 .tx_irq = INT_1510_SPI_TX,
178 .ops = &omap1_mcbsp_ops,
181 .phys_base = OMAP1510_MCBSP3_BASE,
182 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
183 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
184 .rx_irq = INT_McBSP3RX,
185 .tx_irq = INT_McBSP3TX,
186 .ops = &omap1_mcbsp_ops,
187 .clk_name = "mcbsp_clk",
190 #define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata)
191 #else
192 #define omap15xx_mcbsp_pdata NULL
193 #define OMAP15XX_MCBSP_PDATA_SZ 0
194 #endif
196 #ifdef CONFIG_ARCH_OMAP16XX
197 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
199 .phys_base = OMAP1610_MCBSP1_BASE,
200 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
201 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
202 .rx_irq = INT_McBSP1RX,
203 .tx_irq = INT_McBSP1TX,
204 .ops = &omap1_mcbsp_ops,
205 .clk_name = "mcbsp_clk",
208 .phys_base = OMAP1610_MCBSP2_BASE,
209 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
210 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
211 .rx_irq = INT_1610_McBSP2_RX,
212 .tx_irq = INT_1610_McBSP2_TX,
213 .ops = &omap1_mcbsp_ops,
216 .phys_base = OMAP1610_MCBSP3_BASE,
217 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
218 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
219 .rx_irq = INT_McBSP3RX,
220 .tx_irq = INT_McBSP3TX,
221 .ops = &omap1_mcbsp_ops,
222 .clk_name = "mcbsp_clk",
225 #define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata)
226 #else
227 #define omap16xx_mcbsp_pdata NULL
228 #define OMAP16XX_MCBSP_PDATA_SZ 0
229 #endif
231 int __init omap1_mcbsp_init(void)
233 int i;
235 for (i = 0; i < omap_mcbsp_clks_size; i++) {
236 if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
237 omap_mcbsp_clk_init(&omap_mcbsp_clks[i]);
238 clk_register(&omap_mcbsp_clks[i].clk);
242 if (cpu_is_omap730())
243 omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ;
244 if (cpu_is_omap15xx())
245 omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ;
246 if (cpu_is_omap16xx())
247 omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ;
249 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
250 GFP_KERNEL);
251 if (!mcbsp_ptr)
252 return -ENOMEM;
254 if (cpu_is_omap730())
255 omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata,
256 OMAP730_MCBSP_PDATA_SZ);
258 if (cpu_is_omap15xx())
259 omap_mcbsp_register_board_cfg(omap15xx_mcbsp_pdata,
260 OMAP15XX_MCBSP_PDATA_SZ);
262 if (cpu_is_omap16xx())
263 omap_mcbsp_register_board_cfg(omap16xx_mcbsp_pdata,
264 OMAP16XX_MCBSP_PDATA_SZ);
266 return omap_mcbsp_init();
269 arch_initcall(omap1_mcbsp_init);