GNU Linux-libre 6.1.90-gnu
[releases.git] / arch / arm / mach-omap1 / mcbsp.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * linux/arch/arm/mach-omap1/mcbsp.c
4  *
5  * Copyright (C) 2008 Instituto Nokia de Tecnologia
6  * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
7  *
8  * Multichannel mode not supported.
9  */
10 #include <linux/ioport.h>
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/clk.h>
14 #include <linux/err.h>
15 #include <linux/io.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18 #include <linux/omap-dma.h>
19 #include <linux/soc/ti/omap1-io.h>
20 #include <linux/platform_data/asoc-ti-mcbsp.h>
21
22 #include "mux.h"
23 #include "soc.h"
24 #include "irqs.h"
25 #include "iomap.h"
26
27 #define DPS_RSTCT2_PER_EN       (1 << 0)
28 #define DSP_RSTCT2_WD_PER_EN    (1 << 1)
29
30 static int dsp_use;
31 static struct clk *api_clk;
32 static struct clk *dsp_clk;
33 static struct platform_device **omap_mcbsp_devices;
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 == 0 || id == 2) {
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_prepare_enable(api_clk);
47                                 clk_prepare_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 == 0 || id == 2) {
63                 if (--dsp_use == 0) {
64                         if (!IS_ERR(api_clk)) {
65                                 clk_disable_unprepare(api_clk);
66                                 clk_put(api_clk);
67                         }
68                         if (!IS_ERR(dsp_clk)) {
69                                 clk_disable_unprepare(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 #define OMAP7XX_MCBSP1_BASE     0xfffb1000
82 #define OMAP7XX_MCBSP2_BASE     0xfffb1800
83
84 #define OMAP1510_MCBSP1_BASE    0xe1011800
85 #define OMAP1510_MCBSP2_BASE    0xfffb1000
86 #define OMAP1510_MCBSP3_BASE    0xe1017000
87
88 #define OMAP1610_MCBSP1_BASE    0xe1011800
89 #define OMAP1610_MCBSP2_BASE    0xfffb1000
90 #define OMAP1610_MCBSP3_BASE    0xe1017000
91
92 struct resource omap7xx_mcbsp_res[][6] = {
93         {
94                 {
95                         .start = OMAP7XX_MCBSP1_BASE,
96                         .end   = OMAP7XX_MCBSP1_BASE + SZ_256,
97                         .flags = IORESOURCE_MEM,
98                 },
99                 {
100                         .name  = "rx",
101                         .start = INT_7XX_McBSP1RX,
102                         .flags = IORESOURCE_IRQ,
103                 },
104                 {
105                         .name  = "tx",
106                         .start = INT_7XX_McBSP1TX,
107                         .flags = IORESOURCE_IRQ,
108                 },
109                 {
110                         .name  = "rx",
111                         .start = 9,
112                         .flags = IORESOURCE_DMA,
113                 },
114                 {
115                         .name  = "tx",
116                         .start = 8,
117                         .flags = IORESOURCE_DMA,
118                 },
119         },
120         {
121                 {
122                         .start = OMAP7XX_MCBSP2_BASE,
123                         .end   = OMAP7XX_MCBSP2_BASE + SZ_256,
124                         .flags = IORESOURCE_MEM,
125                 },
126                 {
127                         .name  = "rx",
128                         .start = INT_7XX_McBSP2RX,
129                         .flags = IORESOURCE_IRQ,
130                 },
131                 {
132                         .name  = "tx",
133                         .start = INT_7XX_McBSP2TX,
134                         .flags = IORESOURCE_IRQ,
135                 },
136                 {
137                         .name  = "rx",
138                         .start = 11,
139                         .flags = IORESOURCE_DMA,
140                 },
141                 {
142                         .name  = "tx",
143                         .start = 10,
144                         .flags = IORESOURCE_DMA,
145                 },
146         },
147 };
148
149 #define omap7xx_mcbsp_res_0             omap7xx_mcbsp_res[0]
150
151 static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
152         {
153                 .ops            = &omap1_mcbsp_ops,
154         },
155         {
156                 .ops            = &omap1_mcbsp_ops,
157         },
158 };
159 #define OMAP7XX_MCBSP_RES_SZ            ARRAY_SIZE(omap7xx_mcbsp_res[1])
160 #define OMAP7XX_MCBSP_COUNT             ARRAY_SIZE(omap7xx_mcbsp_res)
161
162 struct resource omap15xx_mcbsp_res[][6] = {
163         {
164                 {
165                         .start = OMAP1510_MCBSP1_BASE,
166                         .end   = OMAP1510_MCBSP1_BASE + SZ_256,
167                         .flags = IORESOURCE_MEM,
168                 },
169                 {
170                         .name  = "rx",
171                         .start = INT_McBSP1RX,
172                         .flags = IORESOURCE_IRQ,
173                 },
174                 {
175                         .name  = "tx",
176                         .start = INT_McBSP1TX,
177                         .flags = IORESOURCE_IRQ,
178                 },
179                 {
180                         .name  = "rx",
181                         .start = 9,
182                         .flags = IORESOURCE_DMA,
183                 },
184                 {
185                         .name  = "tx",
186                         .start = 8,
187                         .flags = IORESOURCE_DMA,
188                 },
189         },
190         {
191                 {
192                         .start = OMAP1510_MCBSP2_BASE,
193                         .end   = OMAP1510_MCBSP2_BASE + SZ_256,
194                         .flags = IORESOURCE_MEM,
195                 },
196                 {
197                         .name  = "rx",
198                         .start = INT_1510_SPI_RX,
199                         .flags = IORESOURCE_IRQ,
200                 },
201                 {
202                         .name  = "tx",
203                         .start = INT_1510_SPI_TX,
204                         .flags = IORESOURCE_IRQ,
205                 },
206                 {
207                         .name  = "rx",
208                         .start = 17,
209                         .flags = IORESOURCE_DMA,
210                 },
211                 {
212                         .name  = "tx",
213                         .start = 16,
214                         .flags = IORESOURCE_DMA,
215                 },
216         },
217         {
218                 {
219                         .start = OMAP1510_MCBSP3_BASE,
220                         .end   = OMAP1510_MCBSP3_BASE + SZ_256,
221                         .flags = IORESOURCE_MEM,
222                 },
223                 {
224                         .name  = "rx",
225                         .start = INT_McBSP3RX,
226                         .flags = IORESOURCE_IRQ,
227                 },
228                 {
229                         .name  = "tx",
230                         .start = INT_McBSP3TX,
231                         .flags = IORESOURCE_IRQ,
232                 },
233                 {
234                         .name  = "rx",
235                         .start = 11,
236                         .flags = IORESOURCE_DMA,
237                 },
238                 {
239                         .name  = "tx",
240                         .start = 10,
241                         .flags = IORESOURCE_DMA,
242                 },
243         },
244 };
245
246 #define omap15xx_mcbsp_res_0            omap15xx_mcbsp_res[0]
247
248 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
249         {
250                 .ops            = &omap1_mcbsp_ops,
251         },
252         {
253                 .ops            = &omap1_mcbsp_ops,
254         },
255         {
256                 .ops            = &omap1_mcbsp_ops,
257         },
258 };
259 #define OMAP15XX_MCBSP_RES_SZ           ARRAY_SIZE(omap15xx_mcbsp_res[1])
260 #define OMAP15XX_MCBSP_COUNT            ARRAY_SIZE(omap15xx_mcbsp_res)
261
262 struct resource omap16xx_mcbsp_res[][6] = {
263         {
264                 {
265                         .start = OMAP1610_MCBSP1_BASE,
266                         .end   = OMAP1610_MCBSP1_BASE + SZ_256,
267                         .flags = IORESOURCE_MEM,
268                 },
269                 {
270                         .name  = "rx",
271                         .start = INT_McBSP1RX,
272                         .flags = IORESOURCE_IRQ,
273                 },
274                 {
275                         .name  = "tx",
276                         .start = INT_McBSP1TX,
277                         .flags = IORESOURCE_IRQ,
278                 },
279                 {
280                         .name  = "rx",
281                         .start = 9,
282                         .flags = IORESOURCE_DMA,
283                 },
284                 {
285                         .name  = "tx",
286                         .start = 8,
287                         .flags = IORESOURCE_DMA,
288                 },
289         },
290         {
291                 {
292                         .start = OMAP1610_MCBSP2_BASE,
293                         .end   = OMAP1610_MCBSP2_BASE + SZ_256,
294                         .flags = IORESOURCE_MEM,
295                 },
296                 {
297                         .name  = "rx",
298                         .start = INT_1610_McBSP2_RX,
299                         .flags = IORESOURCE_IRQ,
300                 },
301                 {
302                         .name  = "tx",
303                         .start = INT_1610_McBSP2_TX,
304                         .flags = IORESOURCE_IRQ,
305                 },
306                 {
307                         .name  = "rx",
308                         .start = 17,
309                         .flags = IORESOURCE_DMA,
310                 },
311                 {
312                         .name  = "tx",
313                         .start = 16,
314                         .flags = IORESOURCE_DMA,
315                 },
316         },
317         {
318                 {
319                         .start = OMAP1610_MCBSP3_BASE,
320                         .end   = OMAP1610_MCBSP3_BASE + SZ_256,
321                         .flags = IORESOURCE_MEM,
322                 },
323                 {
324                         .name  = "rx",
325                         .start = INT_McBSP3RX,
326                         .flags = IORESOURCE_IRQ,
327                 },
328                 {
329                         .name  = "tx",
330                         .start = INT_McBSP3TX,
331                         .flags = IORESOURCE_IRQ,
332                 },
333                 {
334                         .name  = "rx",
335                         .start = 11,
336                         .flags = IORESOURCE_DMA,
337                 },
338                 {
339                         .name  = "tx",
340                         .start = 10,
341                         .flags = IORESOURCE_DMA,
342                 },
343         },
344 };
345
346 #define omap16xx_mcbsp_res_0            omap16xx_mcbsp_res[0]
347
348 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
349         {
350                 .ops            = &omap1_mcbsp_ops,
351         },
352         {
353                 .ops            = &omap1_mcbsp_ops,
354         },
355         {
356                 .ops            = &omap1_mcbsp_ops,
357         },
358 };
359 #define OMAP16XX_MCBSP_RES_SZ           ARRAY_SIZE(omap16xx_mcbsp_res[1])
360 #define OMAP16XX_MCBSP_COUNT            ARRAY_SIZE(omap16xx_mcbsp_res)
361
362 static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
363                         struct omap_mcbsp_platform_data *config, int size)
364 {
365         int i;
366
367         omap_mcbsp_devices = kcalloc(size, sizeof(struct platform_device *),
368                                      GFP_KERNEL);
369         if (!omap_mcbsp_devices) {
370                 printk(KERN_ERR "Could not register McBSP devices\n");
371                 return;
372         }
373
374         for (i = 0; i < size; i++) {
375                 struct platform_device *new_mcbsp;
376                 int ret;
377
378                 new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
379                 if (!new_mcbsp)
380                         continue;
381                 platform_device_add_resources(new_mcbsp, &res[i * res_count],
382                                         res_count);
383                 config[i].reg_size = 2;
384                 config[i].reg_step = 2;
385                 new_mcbsp->dev.platform_data = &config[i];
386                 ret = platform_device_add(new_mcbsp);
387                 if (ret) {
388                         platform_device_put(new_mcbsp);
389                         continue;
390                 }
391                 omap_mcbsp_devices[i] = new_mcbsp;
392         }
393 }
394
395 static int __init omap1_mcbsp_init(void)
396 {
397         if (!cpu_class_is_omap1())
398                 return -ENODEV;
399
400         if (cpu_is_omap7xx())
401                 omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
402                                         OMAP7XX_MCBSP_RES_SZ,
403                                         omap7xx_mcbsp_pdata,
404                                         OMAP7XX_MCBSP_COUNT);
405
406         if (cpu_is_omap15xx())
407                 omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
408                                         OMAP15XX_MCBSP_RES_SZ,
409                                         omap15xx_mcbsp_pdata,
410                                         OMAP15XX_MCBSP_COUNT);
411
412         if (cpu_is_omap16xx())
413                 omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
414                                         OMAP16XX_MCBSP_RES_SZ,
415                                         omap16xx_mcbsp_pdata,
416                                         OMAP16XX_MCBSP_COUNT);
417
418         return 0;
419 }
420
421 arch_initcall(omap1_mcbsp_init);