Merge branch 'for-2.6.39' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[pandora-kernel.git] / arch / arm / mach-omap1 / mcbsp.c
1 /*
2  * linux/arch/arm/mach-omap1/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/ioport.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/clk.h>
17 #include <linux/err.h>
18 #include <linux/io.h>
19 #include <linux/platform_device.h>
20 #include <linux/slab.h>
21
22 #include <mach/irqs.h>
23 #include <plat/dma.h>
24 #include <plat/mux.h>
25 #include <plat/cpu.h>
26 #include <plat/mcbsp.h>
27
28 #define DPS_RSTCT2_PER_EN       (1 << 0)
29 #define DSP_RSTCT2_WD_PER_EN    (1 << 1)
30
31 static int dsp_use;
32 static struct clk *api_clk;
33 static struct clk *dsp_clk;
34
35 static void omap1_mcbsp_request(unsigned int id)
36 {
37         /*
38          * On 1510, 1610 and 1710, McBSP1 and McBSP3
39          * are DSP public peripherals.
40          */
41         if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
42                 if (dsp_use++ == 0) {
43                         api_clk = clk_get(NULL, "api_ck");
44                         dsp_clk = clk_get(NULL, "dsp_ck");
45                         if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
46                                 clk_enable(api_clk);
47                                 clk_enable(dsp_clk);
48
49                                 /*
50                                  * DSP external peripheral reset
51                                  * FIXME: This should be moved to dsp code
52                                  */
53                                 __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
54                                                 DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
55                         }
56                 }
57         }
58 }
59
60 static void omap1_mcbsp_free(unsigned int id)
61 {
62         if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
63                 if (--dsp_use == 0) {
64                         if (!IS_ERR(api_clk)) {
65                                 clk_disable(api_clk);
66                                 clk_put(api_clk);
67                         }
68                         if (!IS_ERR(dsp_clk)) {
69                                 clk_disable(dsp_clk);
70                                 clk_put(dsp_clk);
71                         }
72                 }
73         }
74 }
75
76 static struct omap_mcbsp_ops omap1_mcbsp_ops = {
77         .request        = omap1_mcbsp_request,
78         .free           = omap1_mcbsp_free,
79 };
80
81 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
82 struct resource omap7xx_mcbsp_res[][6] = {
83         {
84                 {
85                         .start = OMAP7XX_MCBSP1_BASE,
86                         .end   = OMAP7XX_MCBSP1_BASE + SZ_256,
87                         .flags = IORESOURCE_MEM,
88                 },
89                 {
90                         .name  = "rx",
91                         .start = INT_7XX_McBSP1RX,
92                         .flags = IORESOURCE_IRQ,
93                 },
94                 {
95                         .name  = "tx",
96                         .start = INT_7XX_McBSP1TX,
97                         .flags = IORESOURCE_IRQ,
98                 },
99                 {
100                         .name  = "rx",
101                         .start = OMAP_DMA_MCBSP1_RX,
102                         .flags = IORESOURCE_DMA,
103                 },
104                 {
105                         .name  = "tx",
106                         .start = OMAP_DMA_MCBSP1_TX,
107                         .flags = IORESOURCE_DMA,
108                 },
109         },
110         {
111                 {
112                         .start = OMAP7XX_MCBSP2_BASE,
113                         .end   = OMAP7XX_MCBSP2_BASE + SZ_256,
114                         .flags = IORESOURCE_MEM,
115                 },
116                 {
117                         .name  = "rx",
118                         .start = INT_7XX_McBSP2RX,
119                         .flags = IORESOURCE_IRQ,
120                 },
121                 {
122                         .name  = "tx",
123                         .start = INT_7XX_McBSP2TX,
124                         .flags = IORESOURCE_IRQ,
125                 },
126                 {
127                         .name  = "rx",
128                         .start = OMAP_DMA_MCBSP3_RX,
129                         .flags = IORESOURCE_DMA,
130                 },
131                 {
132                         .name  = "tx",
133                         .start = OMAP_DMA_MCBSP3_TX,
134                         .flags = IORESOURCE_DMA,
135                 },
136         },
137 };
138
139 #define omap7xx_mcbsp_res_0             omap7xx_mcbsp_res[0]
140
141 static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
142         {
143                 .ops            = &omap1_mcbsp_ops,
144         },
145         {
146                 .ops            = &omap1_mcbsp_ops,
147         },
148 };
149 #define OMAP7XX_MCBSP_RES_SZ            ARRAY_SIZE(omap7xx_mcbsp_res[1])
150 #define OMAP7XX_MCBSP_COUNT             ARRAY_SIZE(omap7xx_mcbsp_res)
151 #else
152 #define omap7xx_mcbsp_res_0             NULL
153 #define omap7xx_mcbsp_pdata             NULL
154 #define OMAP7XX_MCBSP_RES_SZ            0
155 #define OMAP7XX_MCBSP_COUNT             0
156 #endif
157
158 #ifdef CONFIG_ARCH_OMAP15XX
159 struct resource omap15xx_mcbsp_res[][6] = {
160         {
161                 {
162                         .start = OMAP1510_MCBSP1_BASE,
163                         .end   = OMAP1510_MCBSP1_BASE + SZ_256,
164                         .flags = IORESOURCE_MEM,
165                 },
166                 {
167                         .name  = "rx",
168                         .start = INT_McBSP1RX,
169                         .flags = IORESOURCE_IRQ,
170                 },
171                 {
172                         .name  = "tx",
173                         .start = INT_McBSP1TX,
174                         .flags = IORESOURCE_IRQ,
175                 },
176                 {
177                         .name  = "rx",
178                         .start = OMAP_DMA_MCBSP1_RX,
179                         .flags = IORESOURCE_DMA,
180                 },
181                 {
182                         .name  = "tx",
183                         .start = OMAP_DMA_MCBSP1_TX,
184                         .flags = IORESOURCE_DMA,
185                 },
186         },
187         {
188                 {
189                         .start = OMAP1510_MCBSP2_BASE,
190                         .end   = OMAP1510_MCBSP2_BASE + SZ_256,
191                         .flags = IORESOURCE_MEM,
192                 },
193                 {
194                         .name  = "rx",
195                         .start = INT_1510_SPI_RX,
196                         .flags = IORESOURCE_IRQ,
197                 },
198                 {
199                         .name  = "tx",
200                         .start = INT_1510_SPI_TX,
201                         .flags = IORESOURCE_IRQ,
202                 },
203                 {
204                         .name  = "rx",
205                         .start = OMAP_DMA_MCBSP2_RX,
206                         .flags = IORESOURCE_DMA,
207                 },
208                 {
209                         .name  = "tx",
210                         .start = OMAP_DMA_MCBSP2_TX,
211                         .flags = IORESOURCE_DMA,
212                 },
213         },
214         {
215                 {
216                         .start = OMAP1510_MCBSP3_BASE,
217                         .end   = OMAP1510_MCBSP3_BASE + SZ_256,
218                         .flags = IORESOURCE_MEM,
219                 },
220                 {
221                         .name  = "rx",
222                         .start = INT_McBSP3RX,
223                         .flags = IORESOURCE_IRQ,
224                 },
225                 {
226                         .name  = "tx",
227                         .start = INT_McBSP3TX,
228                         .flags = IORESOURCE_IRQ,
229                 },
230                 {
231                         .name  = "rx",
232                         .start = OMAP_DMA_MCBSP3_RX,
233                         .flags = IORESOURCE_DMA,
234                 },
235                 {
236                         .name  = "tx",
237                         .start = OMAP_DMA_MCBSP3_TX,
238                         .flags = IORESOURCE_DMA,
239                 },
240         },
241 };
242
243 #define omap15xx_mcbsp_res_0            omap15xx_mcbsp_res[0]
244
245 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
246         {
247                 .ops            = &omap1_mcbsp_ops,
248         },
249         {
250                 .ops            = &omap1_mcbsp_ops,
251         },
252         {
253                 .ops            = &omap1_mcbsp_ops,
254         },
255 };
256 #define OMAP15XX_MCBSP_RES_SZ           ARRAY_SIZE(omap15xx_mcbsp_res[1])
257 #define OMAP15XX_MCBSP_COUNT            ARRAY_SIZE(omap15xx_mcbsp_res)
258 #else
259 #define omap15xx_mcbsp_res_0            NULL
260 #define omap15xx_mcbsp_pdata            NULL
261 #define OMAP15XX_MCBSP_RES_SZ           0
262 #define OMAP15XX_MCBSP_COUNT            0
263 #endif
264
265 #ifdef CONFIG_ARCH_OMAP16XX
266 struct resource omap16xx_mcbsp_res[][6] = {
267         {
268                 {
269                         .start = OMAP1610_MCBSP1_BASE,
270                         .end   = OMAP1610_MCBSP1_BASE + SZ_256,
271                         .flags = IORESOURCE_MEM,
272                 },
273                 {
274                         .name  = "rx",
275                         .start = INT_McBSP1RX,
276                         .flags = IORESOURCE_IRQ,
277                 },
278                 {
279                         .name  = "tx",
280                         .start = INT_McBSP1TX,
281                         .flags = IORESOURCE_IRQ,
282                 },
283                 {
284                         .name  = "rx",
285                         .start = OMAP_DMA_MCBSP1_RX,
286                         .flags = IORESOURCE_DMA,
287                 },
288                 {
289                         .name  = "tx",
290                         .start = OMAP_DMA_MCBSP1_TX,
291                         .flags = IORESOURCE_DMA,
292                 },
293         },
294         {
295                 {
296                         .start = OMAP1610_MCBSP2_BASE,
297                         .end   = OMAP1610_MCBSP2_BASE + SZ_256,
298                         .flags = IORESOURCE_MEM,
299                 },
300                 {
301                         .name  = "rx",
302                         .start = INT_1610_McBSP2_RX,
303                         .flags = IORESOURCE_IRQ,
304                 },
305                 {
306                         .name  = "tx",
307                         .start = INT_1610_McBSP2_TX,
308                         .flags = IORESOURCE_IRQ,
309                 },
310                 {
311                         .name  = "rx",
312                         .start = OMAP_DMA_MCBSP2_RX,
313                         .flags = IORESOURCE_DMA,
314                 },
315                 {
316                         .name  = "tx",
317                         .start = OMAP_DMA_MCBSP2_TX,
318                         .flags = IORESOURCE_DMA,
319                 },
320         },
321         {
322                 {
323                         .start = OMAP1610_MCBSP3_BASE,
324                         .end   = OMAP1610_MCBSP3_BASE + SZ_256,
325                         .flags = IORESOURCE_MEM,
326                 },
327                 {
328                         .name  = "rx",
329                         .start = INT_McBSP3RX,
330                         .flags = IORESOURCE_IRQ,
331                 },
332                 {
333                         .name  = "tx",
334                         .start = INT_McBSP3TX,
335                         .flags = IORESOURCE_IRQ,
336                 },
337                 {
338                         .name  = "rx",
339                         .start = OMAP_DMA_MCBSP3_RX,
340                         .flags = IORESOURCE_DMA,
341                 },
342                 {
343                         .name  = "tx",
344                         .start = OMAP_DMA_MCBSP3_TX,
345                         .flags = IORESOURCE_DMA,
346                 },
347         },
348 };
349
350 #define omap16xx_mcbsp_res_0            omap16xx_mcbsp_res[0]
351
352 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
353         {
354                 .ops            = &omap1_mcbsp_ops,
355         },
356         {
357                 .ops            = &omap1_mcbsp_ops,
358         },
359         {
360                 .ops            = &omap1_mcbsp_ops,
361         },
362 };
363 #define OMAP16XX_MCBSP_RES_SZ           ARRAY_SIZE(omap16xx_mcbsp_res[1])
364 #define OMAP16XX_MCBSP_COUNT            ARRAY_SIZE(omap16xx_mcbsp_res)
365 #else
366 #define omap16xx_mcbsp_res_0            NULL
367 #define omap16xx_mcbsp_pdata            NULL
368 #define OMAP16XX_MCBSP_RES_SZ           0
369 #define OMAP16XX_MCBSP_COUNT            0
370 #endif
371
372 static int __init omap1_mcbsp_init(void)
373 {
374         if (!cpu_class_is_omap1())
375                 return -ENODEV;
376
377         if (cpu_is_omap7xx())
378                 omap_mcbsp_count = OMAP7XX_MCBSP_COUNT;
379         else if (cpu_is_omap15xx())
380                 omap_mcbsp_count = OMAP15XX_MCBSP_COUNT;
381         else if (cpu_is_omap16xx())
382                 omap_mcbsp_count = OMAP16XX_MCBSP_COUNT;
383
384         mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
385                                                                 GFP_KERNEL);
386         if (!mcbsp_ptr)
387                 return -ENOMEM;
388
389         if (cpu_is_omap7xx())
390                 omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
391                                         OMAP7XX_MCBSP_RES_SZ,
392                                         omap7xx_mcbsp_pdata,
393                                         OMAP7XX_MCBSP_COUNT);
394
395         if (cpu_is_omap15xx())
396                 omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
397                                         OMAP15XX_MCBSP_RES_SZ,
398                                         omap15xx_mcbsp_pdata,
399                                         OMAP15XX_MCBSP_COUNT);
400
401         if (cpu_is_omap16xx())
402                 omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
403                                         OMAP16XX_MCBSP_RES_SZ,
404                                         omap16xx_mcbsp_pdata,
405                                         OMAP16XX_MCBSP_COUNT);
406
407         return omap_mcbsp_init();
408 }
409
410 arch_initcall(omap1_mcbsp_init);